blob: bd4371e876f5cffe41780cc7f42e1369b402478d [file] [log] [blame]
The Android Open Source Project52d4c302009-03-03 19:29:09 -08001//
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 */
29class DeviceManager {
30public:
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 */
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 */
78 bool IsRunning(void) const {
79 if (mThread != NULL)
80 return mThread->IsRunning();
81 return false;
82 }
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(KeyCode 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
118private:
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:
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 {}
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
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:
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 {}
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 */
215 wxWindow* GetWindow(void) const { return mDisplayWindow; }
216
217 /* get our shared memory key */
218 int GetShmemKey(void) const { return mShmemKey; }
219
220 int GetWidth(void) const { return mWidth; }
221 int GetHeight(void) const { return mHeight; }
222 android::PixelFormat GetFormat(void) const { return mFormat; }
223 int GetRefresh(void) const { return mRefresh; }
224
225 private:
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
252 Display* GetDisplay(int dispNum) { return &mDisplay[dispNum]; }
253
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