Home | History | Annotate | Download | only in app
      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