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 */ 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(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: 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 285