• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2005 The Android Open Source Project
3 //
4 // Class that manages the simulated device.
5 //
6 #ifndef _SIM_DEVICE_MANAGER_H
7 #define _SIM_DEVICE_MANAGER_H
8 
9 #include "UserEvent.h"
10 
11 #include "Shmem.h"
12 #include "MessageStream.h"
13 #include "SimRuntime.h"
14 
15 #include "ui/PixelFormat.h"
16 #include "ui/KeycodeLabels.h"
17 
18 #include <sys/stat.h>
19 
20 /*
21  * Manage the simulated device.  This includes starting/stopping as well
22  * as sending messages to it and receiving events from it.
23  *
24  * The object may span multiple invocations of a specific device.  If
25  * the simulator is reconfigured to use a device with different
26  * characteristics, the object should be destroyed and recreated (which
27  * guarantees that the runtime is restarted).
28  */
29 class DeviceManager {
30 public:
31     DeviceManager(void);
32     virtual ~DeviceManager(void);
33 
34     /*
35      * Initialize the object.  Call this once.
36      *
37      * "numDisplays" is the number of displays that the simulated hardware
38      * supports.  The displays themselves are configured with separate calls.
39      *
40      * "statusWindow" should be the main frame.  Messages indicating runtime
41      * startup/shutdown are sent, as well as error messages that should be
42      * displayed in message boxes.
43      */
44     bool Init(int numDisplays, wxWindow* statusWindow);
45     bool IsInitialized(void) const;
46 
47     /*
48      * Tell the device manager that the windows used to display its output
49      * are closing down.
50      */
51     void WindowsClosing(void);
52 
53     /*
54      * "displayWindow" is the window to notify when a new frame of graphics
55      * data is available.  This can be set independently for each display.
56      */
57     bool SetDisplayConfig(int displayIndex, wxWindow* window,
58         int width, int height, android::PixelFormat format, int refresh);
59 
60     /*
61      * set the key map
62      */
63     bool SetKeyboardConfig(const char *keymap);
64 
65     /*
66      * Return the number of displays we're configured for.
67      */
GetNumDisplays(void)68     int GetNumDisplays(void) const { return mNumDisplays; }
69 
70     /*
71      * Return the shmem key for the Nth display.
72      */
73     //int GetShmemKey(int displayIndex);
74 
75     /*
76      * Is the runtime process still running?
77      */
IsRunning(void)78     bool IsRunning(void) const {
79         if (mThread != NULL)
80             return mThread->IsRunning();
81         return false;
82     }
IsKillable(void)83     bool IsKillable(void) const {
84         return true;
85     }
86 
87     // (Re-)configure the device, e.g. when #of displays changes because
88     // a different phone model has been selected.  Call this before doing
89     // any display-specific setup.  DO NOT call this if the runtime is active.
90 //    void Configure(int numDisplays);
91 
92     // start the runtime, acting as parent
93     bool StartRuntime(void);
94     // start the runtime, acting as peer
95     bool StartRuntime(android::Pipe* reader, android::Pipe* writer);
96     // politely ask the runtime to stop
97     bool StopRuntime(void);
98     // kill the runtime with extreme prejudice
99     void KillRuntime(void);
100 
101 #if 0
102     // Returns if the executable is new
103     bool RefreshRuntime(void);
104     // Update the time of the current runtime because the user cancelled a
105     // refresh
106     void UserCancelledRefresh(void);
107 #endif
108 
109     // send a key-up or key-down event to the runtime
110     void SendKeyEvent(int32_t keyCode, bool down);
111     // send touch-screen events
112     void SendTouchEvent(android::Simulator::TouchMode mode, int x, int y);
113 
114     wxBitmap* GetImageData(int displayIndex);
115 
116     void BroadcastEvent(UserEvent &userEvent);
117 
118 private:
119     /*
120      * Threads in wxWidgets use sub-classing to define interfaces and
121      * entry points.  We use this to create the thread that interacts
122      * with the runtime.
123      *
124      * The "reader" and "writer" arguments may be NULL.  If they are,
125      * we will launch the runtime ourselves.  If not, we will use them
126      * to speak with an externally-launched runtime process.  The thread
127      * will own the pipes, shutting them down when it exits.
128      */
129     class DeviceThread : public wxThread {
130     public:
DeviceThread(DeviceManager * pDM,wxWindow * pStatusWindow,android::Pipe * reader,android::Pipe * writer)131         DeviceThread(DeviceManager* pDM, wxWindow* pStatusWindow,
132             android::Pipe* reader, android::Pipe* writer)
133             : wxThread(wxTHREAD_JOINABLE), mpStatusWindow(pStatusWindow),
134               mReader(reader), mWriter(writer),
135               mpDeviceManager(pDM), /*mTerminalFollowsChild(false),
136               mSlowExit(false), mIsExternal(false), mLastModified(0),*/
137               mRuntimeProcessGroup(0)
138             {}
~DeviceThread(void)139         virtual ~DeviceThread(void) {
140             delete mReader;
141             delete mWriter;
142         }
143 
144         /* thread entry point */
145         virtual void* Entry(void);
146 
147         // wxThread class supplies an IsRunning() method
148 
149         /*
150          * This kills the runtime process to force this thread to exit.
151          * If the thread doesn't exit after a short period of time, it
152          * is forcibly terminated.
153          */
154         void KillChildProcesses(void);
155 
156 #if 0
157         /*
158          * Return if the runtime executable is new
159          */
160         bool IsRuntimeNew(void);
161 
162         void UpdateLastModified(void);
163 #endif
164 
GetStream(void)165         android::MessageStream* GetStream(void) { return &mStream; }
166 
167         static bool LaunchProcess(wxWindow* statusWindow);
168 
169     private:
170         void WaitForDeath(int delay);
171         void ResetProperties(void);
172 
173         android::MessageStream  mStream;
174         wxWindow*       mpStatusWindow;
175         android::Pipe*  mReader;
176         android::Pipe*  mWriter;
177         DeviceManager*  mpDeviceManager;
178         pid_t           mRuntimeProcessGroup;
179         //time_t          mLastModified;
180         wxString        mRuntimeExe;
181     };
182 
183     friend class DeviceThread;
184 
185     /*
186      * We need one of these for each display on the device.  Most devices
187      * only have one, but some flip phones have two.
188      */
189     class Display {
190     public:
Display(void)191         Display(void)
192             : mDisplayWindow(NULL), mpShmem(NULL), mShmemKey(0),
193               mImageData(NULL), mDisplayNum(-1), mWidth(-1), mHeight(-1),
194               mFormat(android::PIXEL_FORMAT_UNKNOWN), mRefresh(0)
195             {}
~Display()196         ~Display() {
197             delete mpShmem;
198             delete[] mImageData;
199         }
200 
201         /* initialize goodies */
202         bool Create(int displayNum, wxWindow* window, int width, int height,
203             android::PixelFormat format, int refresh);
204 
205         /* call this if we're shutting down soon */
206         void Uncreate(void);
207 
208         /* copy & convert data from shared memory */
209         void CopyFromShared(void);
210 
211         /* get image data in the form of a 24bpp bitmap */
212         wxBitmap* GetImageData(void);
213 
214         /* get a pointer to our display window */
GetWindow(void)215         wxWindow* GetWindow(void) const { return mDisplayWindow; }
216 
217         /* get our shared memory key */
GetShmemKey(void)218         int GetShmemKey(void) const { return mShmemKey; }
219 
GetWidth(void)220         int GetWidth(void) const { return mWidth; }
GetHeight(void)221         int GetHeight(void) const { return mHeight; }
GetFormat(void)222         android::PixelFormat GetFormat(void) const { return mFormat; }
GetRefresh(void)223         int GetRefresh(void) const { return mRefresh; }
224 
225     private:
GenerateKey(int displayNum)226         int GenerateKey(int displayNum) {
227             return 0x41544d00 | displayNum;
228         }
229 
230         // control access to image data shared between runtime mgr and UI
231         wxMutex         mImageDataLock;
232         // we send an event here when we get stuff to display
233         wxWindow*       mDisplayWindow;
234 
235         // shared memory segment
236         android::Shmem* mpShmem;
237         int             mShmemKey;
238 
239         // local copy of data from shared mem, converted to 24bpp
240         unsigned char*  mImageData;
241 
242         // mainly for debugging -- which display are we?
243         int             mDisplayNum;
244 
245         // display characteristics
246         int             mWidth;
247         int             mHeight;
248         android::PixelFormat mFormat;
249         int             mRefresh;       // fps
250     };
251 
GetDisplay(int dispNum)252     Display* GetDisplay(int dispNum) { return &mDisplay[dispNum]; }
253 
GetKeyMap()254     const char* GetKeyMap() { return mKeyMap ? mKeyMap : "qwerty"; }
255 
256     void ShowFrame(int displayIndex);
257 
258     void Vibrate(int vibrateOn);
259 
260     // get the message stream from the device thread
261     android::MessageStream* GetStream(void);
262 
263     // send a request to set the visible layers
264     void SendSetVisibleLayers(void);
265 
266     // points at the runtime's thread (while it's running)
267     DeviceThread*   mThread;
268 
269     // array of Displays, one per display on the device
270     Display*        mDisplay;
271     int             mNumDisplays;
272 
273     // the key map
274     const char * mKeyMap;
275 
276     // which graphics layers are visible?
277     int             mVisibleLayers;
278 
279     // where to send status messages
280     wxWindow*       mpStatusWindow;
281 
282 };
283 
284 #endif // _SIM_DEVICE_MANAGER_H
285