285 lines
8.5 KiB
C++
285 lines
8.5 KiB
C++
//
|
|
// Copyright 2005 The Android Open Source Project
|
|
//
|
|
// Class that manages the simulated device.
|
|
//
|
|
#ifndef _SIM_DEVICE_MANAGER_H
|
|
#define _SIM_DEVICE_MANAGER_H
|
|
|
|
#include "UserEvent.h"
|
|
|
|
#include "Shmem.h"
|
|
#include "MessageStream.h"
|
|
#include "SimRuntime.h"
|
|
|
|
#include "ui/PixelFormat.h"
|
|
#include "ui/KeycodeLabels.h"
|
|
|
|
#include <sys/stat.h>
|
|
|
|
/*
|
|
* Manage the simulated device. This includes starting/stopping as well
|
|
* as sending messages to it and receiving events from it.
|
|
*
|
|
* The object may span multiple invocations of a specific device. If
|
|
* the simulator is reconfigured to use a device with different
|
|
* characteristics, the object should be destroyed and recreated (which
|
|
* guarantees that the runtime is restarted).
|
|
*/
|
|
class DeviceManager {
|
|
public:
|
|
DeviceManager(void);
|
|
virtual ~DeviceManager(void);
|
|
|
|
/*
|
|
* Initialize the object. Call this once.
|
|
*
|
|
* "numDisplays" is the number of displays that the simulated hardware
|
|
* supports. The displays themselves are configured with separate calls.
|
|
*
|
|
* "statusWindow" should be the main frame. Messages indicating runtime
|
|
* startup/shutdown are sent, as well as error messages that should be
|
|
* displayed in message boxes.
|
|
*/
|
|
bool Init(int numDisplays, wxWindow* statusWindow);
|
|
bool IsInitialized(void) const;
|
|
|
|
/*
|
|
* Tell the device manager that the windows used to display its output
|
|
* are closing down.
|
|
*/
|
|
void WindowsClosing(void);
|
|
|
|
/*
|
|
* "displayWindow" is the window to notify when a new frame of graphics
|
|
* data is available. This can be set independently for each display.
|
|
*/
|
|
bool SetDisplayConfig(int displayIndex, wxWindow* window,
|
|
int width, int height, android::PixelFormat format, int refresh);
|
|
|
|
/*
|
|
* set the key map
|
|
*/
|
|
bool SetKeyboardConfig(const char *keymap);
|
|
|
|
/*
|
|
* Return the number of displays we're configured for.
|
|
*/
|
|
int GetNumDisplays(void) const { return mNumDisplays; }
|
|
|
|
/*
|
|
* Return the shmem key for the Nth display.
|
|
*/
|
|
//int GetShmemKey(int displayIndex);
|
|
|
|
/*
|
|
* Is the runtime process still running?
|
|
*/
|
|
bool IsRunning(void) const {
|
|
if (mThread != NULL)
|
|
return mThread->IsRunning();
|
|
return false;
|
|
}
|
|
bool IsKillable(void) const {
|
|
return true;
|
|
}
|
|
|
|
// (Re-)configure the device, e.g. when #of displays changes because
|
|
// a different phone model has been selected. Call this before doing
|
|
// any display-specific setup. DO NOT call this if the runtime is active.
|
|
// void Configure(int numDisplays);
|
|
|
|
// start the runtime, acting as parent
|
|
bool StartRuntime(void);
|
|
// start the runtime, acting as peer
|
|
bool StartRuntime(android::Pipe* reader, android::Pipe* writer);
|
|
// politely ask the runtime to stop
|
|
bool StopRuntime(void);
|
|
// kill the runtime with extreme prejudice
|
|
void KillRuntime(void);
|
|
|
|
#if 0
|
|
// Returns if the executable is new
|
|
bool RefreshRuntime(void);
|
|
// Update the time of the current runtime because the user cancelled a
|
|
// refresh
|
|
void UserCancelledRefresh(void);
|
|
#endif
|
|
|
|
// send a key-up or key-down event to the runtime
|
|
void SendKeyEvent(KeyCode keyCode, bool down);
|
|
// send touch-screen events
|
|
void SendTouchEvent(android::Simulator::TouchMode mode, int x, int y);
|
|
|
|
wxBitmap* GetImageData(int displayIndex);
|
|
|
|
void BroadcastEvent(UserEvent &userEvent);
|
|
|
|
private:
|
|
/*
|
|
* Threads in wxWidgets use sub-classing to define interfaces and
|
|
* entry points. We use this to create the thread that interacts
|
|
* with the runtime.
|
|
*
|
|
* The "reader" and "writer" arguments may be NULL. If they are,
|
|
* we will launch the runtime ourselves. If not, we will use them
|
|
* to speak with an externally-launched runtime process. The thread
|
|
* will own the pipes, shutting them down when it exits.
|
|
*/
|
|
class DeviceThread : public wxThread {
|
|
public:
|
|
DeviceThread(DeviceManager* pDM, wxWindow* pStatusWindow,
|
|
android::Pipe* reader, android::Pipe* writer)
|
|
: wxThread(wxTHREAD_JOINABLE), mpStatusWindow(pStatusWindow),
|
|
mReader(reader), mWriter(writer),
|
|
mpDeviceManager(pDM), /*mTerminalFollowsChild(false),
|
|
mSlowExit(false), mIsExternal(false), mLastModified(0),*/
|
|
mRuntimeProcessGroup(0)
|
|
{}
|
|
virtual ~DeviceThread(void) {
|
|
delete mReader;
|
|
delete mWriter;
|
|
}
|
|
|
|
/* thread entry point */
|
|
virtual void* Entry(void);
|
|
|
|
// wxThread class supplies an IsRunning() method
|
|
|
|
/*
|
|
* This kills the runtime process to force this thread to exit.
|
|
* If the thread doesn't exit after a short period of time, it
|
|
* is forcibly terminated.
|
|
*/
|
|
void KillChildProcesses(void);
|
|
|
|
#if 0
|
|
/*
|
|
* Return if the runtime executable is new
|
|
*/
|
|
bool IsRuntimeNew(void);
|
|
|
|
void UpdateLastModified(void);
|
|
#endif
|
|
|
|
android::MessageStream* GetStream(void) { return &mStream; }
|
|
|
|
static bool LaunchProcess(wxWindow* statusWindow);
|
|
|
|
private:
|
|
void WaitForDeath(int delay);
|
|
void ResetProperties(void);
|
|
|
|
android::MessageStream mStream;
|
|
wxWindow* mpStatusWindow;
|
|
android::Pipe* mReader;
|
|
android::Pipe* mWriter;
|
|
DeviceManager* mpDeviceManager;
|
|
pid_t mRuntimeProcessGroup;
|
|
//time_t mLastModified;
|
|
wxString mRuntimeExe;
|
|
};
|
|
|
|
friend class DeviceThread;
|
|
|
|
/*
|
|
* We need one of these for each display on the device. Most devices
|
|
* only have one, but some flip phones have two.
|
|
*/
|
|
class Display {
|
|
public:
|
|
Display(void)
|
|
: mDisplayWindow(NULL), mpShmem(NULL), mShmemKey(0),
|
|
mImageData(NULL), mDisplayNum(-1), mWidth(-1), mHeight(-1),
|
|
mFormat(android::PIXEL_FORMAT_UNKNOWN), mRefresh(0)
|
|
{}
|
|
~Display() {
|
|
delete mpShmem;
|
|
delete[] mImageData;
|
|
}
|
|
|
|
/* initialize goodies */
|
|
bool Create(int displayNum, wxWindow* window, int width, int height,
|
|
android::PixelFormat format, int refresh);
|
|
|
|
/* call this if we're shutting down soon */
|
|
void Uncreate(void);
|
|
|
|
/* copy & convert data from shared memory */
|
|
void CopyFromShared(void);
|
|
|
|
/* get image data in the form of a 24bpp bitmap */
|
|
wxBitmap* GetImageData(void);
|
|
|
|
/* get a pointer to our display window */
|
|
wxWindow* GetWindow(void) const { return mDisplayWindow; }
|
|
|
|
/* get our shared memory key */
|
|
int GetShmemKey(void) const { return mShmemKey; }
|
|
|
|
int GetWidth(void) const { return mWidth; }
|
|
int GetHeight(void) const { return mHeight; }
|
|
android::PixelFormat GetFormat(void) const { return mFormat; }
|
|
int GetRefresh(void) const { return mRefresh; }
|
|
|
|
private:
|
|
int GenerateKey(int displayNum) {
|
|
return 0x41544d00 | displayNum;
|
|
}
|
|
|
|
// control access to image data shared between runtime mgr and UI
|
|
wxMutex mImageDataLock;
|
|
// we send an event here when we get stuff to display
|
|
wxWindow* mDisplayWindow;
|
|
|
|
// shared memory segment
|
|
android::Shmem* mpShmem;
|
|
int mShmemKey;
|
|
|
|
// local copy of data from shared mem, converted to 24bpp
|
|
unsigned char* mImageData;
|
|
|
|
// mainly for debugging -- which display are we?
|
|
int mDisplayNum;
|
|
|
|
// display characteristics
|
|
int mWidth;
|
|
int mHeight;
|
|
android::PixelFormat mFormat;
|
|
int mRefresh; // fps
|
|
};
|
|
|
|
Display* GetDisplay(int dispNum) { return &mDisplay[dispNum]; }
|
|
|
|
const char* GetKeyMap() { return mKeyMap ? mKeyMap : "qwerty"; }
|
|
|
|
void ShowFrame(int displayIndex);
|
|
|
|
void Vibrate(int vibrateOn);
|
|
|
|
// get the message stream from the device thread
|
|
android::MessageStream* GetStream(void);
|
|
|
|
// send a request to set the visible layers
|
|
void SendSetVisibleLayers(void);
|
|
|
|
// points at the runtime's thread (while it's running)
|
|
DeviceThread* mThread;
|
|
|
|
// array of Displays, one per display on the device
|
|
Display* mDisplay;
|
|
int mNumDisplays;
|
|
|
|
// the key map
|
|
const char * mKeyMap;
|
|
|
|
// which graphics layers are visible?
|
|
int mVisibleLayers;
|
|
|
|
// where to send status messages
|
|
wxWindow* mpStatusWindow;
|
|
|
|
};
|
|
|
|
#endif // _SIM_DEVICE_MANAGER_H
|