diff options
| author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:16 -0800 |
|---|---|---|
| committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:16 -0800 |
| commit | d4aee0c0caa00aa02d4c50ed28151591ac0456b5 (patch) | |
| tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /simulator | |
| parent | d2f2b1d7b77d06bce8cf9340171cf6c25cd720c4 (diff) | |
| download | android_development-d4aee0c0caa00aa02d4c50ed28151591ac0456b5.tar.gz android_development-d4aee0c0caa00aa02d4c50ed28151591ac0456b5.tar.bz2 android_development-d4aee0c0caa00aa02d4c50ed28151591ac0456b5.zip | |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'simulator')
214 files changed, 0 insertions, 19711 deletions
diff --git a/simulator/app/Android.mk b/simulator/app/Android.mk deleted file mode 100644 index c6e1d1440..000000000 --- a/simulator/app/Android.mk +++ /dev/null @@ -1,130 +0,0 @@ -# Copyright 2005 The Android Open Source Project -# - -ifeq ($(TARGET_SIMULATOR),true) - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - DeviceManager.cpp \ - DeviceWindow.cpp \ - ExternalRuntime.cpp \ - LoadableImage.cpp \ - LocalBiChannel.cpp \ - LogMessage.cpp \ - LogPool.cpp \ - LogPrefsDialog.cpp \ - LogWindow.cpp \ - MainFrame.cpp \ - MessageStream.cpp \ - MyApp.cpp \ - PhoneButton.cpp \ - PhoneCollection.cpp \ - PhoneData.cpp \ - PhoneWindow.cpp \ - Preferences.cpp \ - PrefsDialog.cpp \ - PropertyServer.cpp \ - Semaphore.cpp \ - Shmem.cpp \ - UserEvent.cpp - -LOCAL_STATIC_LIBRARIES := \ - libtinyxml -LOCAL_WHOLE_STATIC_LIBRARIES := \ - libutils\ - libcutils -LOCAL_MODULE := simulator - -LOCAL_LDLIBS += -lpthread - -LOCAL_CFLAGS := -UNDEBUG -#LOCAL_LDFLAGS := - -LOCAL_C_INCLUDES += \ - external/tinyxml \ - commands/runtime - -# wxWidgets defines -LOCAL_C_INCLUDES += \ - /usr/include/wx-2.6 \ - /usr/lib/wx/include/gtk2-unicode-release-2.6 - -ifeq ($(HOST_OS),linux) - # You can install wxWidgets with "sudo apt-get libwxgtk2.6-dev" - LOCAL_LDFLAGS += -lwx_baseu-2.6 \ - -lwx_baseu_net-2.6 \ - -lwx_baseu_xml-2.6 \ - -lwx_gtk2u_adv-2.6 \ - -lwx_gtk2u_core-2.6 \ - -lwx_gtk2u_html-2.6 \ - -lwx_gtk2u_qa-2.6 \ - -lwx_gtk2u_xrc-2.6 - - # this next line makes the simulator able to find its shared libraries - # without us explicitly setting the LD_LIBRARY_PATH environment variable - LOCAL_LDLIBS += -Wl,-z,origin - LOCAL_CFLAGS += -DGTK_NO_CHECK_CASTS -D__WXGTK__ -D_FILE_OFFSET_BITS=64 \ - -D_LARGE_FILES -D_LARGEFILE_SOURCE=1 - LOCAL_LDLIBS += -lrt -endif -ifeq ($(HOST_OS),darwin) - # NOTE: OS X is no longer supported - LOCAL_C_INCLUDES += prebuilt/$(HOST_PREBUILT_TAG)/wxwidgets - LOCAL_LDLIBS += \ - -framework QuickTime \ - -framework IOKit \ - -framework Carbon \ - -framework Cocoa \ - -framework System \ - -lwx_mac_xrc-2.6 \ - -lwx_mac_qa-2.6 \ - -lwx_mac_html-2.6 \ - -lwx_mac_adv-2.6 \ - -lwx_mac_core-2.6 \ - -lwx_base_carbon_xml-2.6 \ - -lwx_base_carbon_net-2.6 \ - -lwx_base_carbon-2.6 \ - -lwxexpat-2.6 \ - -lwxtiff-2.6 \ - -lwxjpeg-2.6 \ - -lwxpng-2.6 \ - -lz \ - -lpthread \ - -liconv - LOCAL_CFLAGS += \ - -D__WXMAC__ \ - -D_FILE_OFFSET_BITS=64 \ - -D_LARGE_FILES \ - -DNO_GCC_PRAGMA -endif - - -include $(BUILD_HOST_EXECUTABLE) - -ifeq ($(HOST_OS),darwin) -# Add the carbon resources to the executable. -$(LOCAL_BUILT_MODULE): PRIVATE_POST_PROCESS_COMMAND := \ - /Developer/Tools/Rez -d __DARWIN__ -t APPL \ - -d __WXMAC__ -o $(LOCAL_BUILT_MODULE) Carbon.r -endif - -# also, we need to copy our assets. We place these by hand now, because -# I'd like to clean this up as part of some pdk cleanup I want to do. - -asset_files := $(addprefix $(LOCAL_PATH)/assets/,$(call find-subdir-assets,$(LOCAL_PATH)/assets)) -asset_target := $(HOST_COMMON_OUT_ROOT)/sim-assets/simulator$(COMMON_PACKAGE_SUFFIX) -$(asset_target): PRIVATE_ASSET_ROOT := $(LOCAL_PATH)/assets - -$(asset_target) : $(asset_files) $(AAPT) - @echo host Package $@ - $(hide) mkdir -p $(dir $@) - $(hide) $(AAPT) package -u -A $(PRIVATE_ASSET_ROOT) -F $@ - -$(LOCAL_INSTALLED_MODULE): | $(asset_target) - -ALL_DEFAULT_INSTALLED_MODULES += $(asset_target) - -endif # $(TARGET_SIMULATOR) == true diff --git a/simulator/app/AssetStream.h b/simulator/app/AssetStream.h deleted file mode 100644 index 0ab2d12c9..000000000 --- a/simulator/app/AssetStream.h +++ /dev/null @@ -1,102 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Provide a wxInputStream subclass based on the Android Asset class. -// This is necessary because some wxWidgets functions require either a -// filename or a wxInputStream (e.g. wxImage). -// -#ifndef _SIM_ASSETSTREAM_H -#define _SIM_ASSETSTREAM_H - -#include "wx/stream.h" -#include <utils/Asset.h> - -/* - * There is no sample code or concrete documentation about providing - * input streams, but it seems straightforward. The PNG loading code - * uses the following: - * OnSysTell() - * OnSysSeek() - * Read() - * - * The AssetStream takes ownership of the Asset. - */ -class AssetStream : public wxInputStream { -public: - AssetStream(android::Asset* pAsset) - : mpAsset(pAsset) - {} - virtual ~AssetStream(void) { - delete mpAsset; - } - - virtual wxFileOffset GetLength() const { - //printf("## GetLength --> %ld\n", (long) mpAsset->getLength()); - return mpAsset->getLength(); - } - virtual size_t GetSize() const { - //printf("## GetSize --> %ld\n", (long) mpAsset->getLength()); - return mpAsset->getLength(); - } - virtual bool IsSeekable() const { return true; } - - virtual bool Eof() const { - //printf("## Eof\n"); - return (mpAsset->seek(0, SEEK_CUR) == mpAsset->getLength()); - } - - virtual bool CanRead() const { - //printf("## CanRead\n"); - return !Eof(); - } - - virtual wxInputStream& Read(void* buffer, size_t size) { - OnSysRead(buffer, size); - - return *this; - } - -protected: - /* read data, return number of bytes or 0 if EOF reached */ - virtual size_t OnSysRead(void* buffer, size_t size) { - ssize_t actual = mpAsset->read(buffer, size); - if (actual < 0) { - // TODO: flag error - actual = 0; - } - //printf("## OnSysRead(%p %u) --> %d\n", buffer, size, actual); - return actual; - } - - /* seek, using wxWidgets-defined values for "whence" */ - virtual wxFileOffset OnSysSeek(wxFileOffset seek, wxSeekMode mode) { - int whence; - off_t newPosn; - - if (mode == wxFromStart) - whence = SEEK_SET; - else if (mode == wxFromEnd) - whence = SEEK_END; - else - whence = SEEK_CUR; - newPosn = mpAsset->seek(seek, whence); - //printf("## OnSysSeek(%ld %d) --> %ld\n", - // (long) seek, mode, (long) newPosn); - if (newPosn == (off_t) -1) - return wxInvalidOffset; - else - return newPosn; - } - - virtual wxFileOffset OnSysTell() const { - //printf("## OnSysTell() --> %ld\n", (long) mpAsset->seek(0, SEEK_CUR)); - return mpAsset->seek(0, SEEK_CUR); - } - -private: - android::Asset* mpAsset; - - DECLARE_NO_COPY_CLASS(AssetStream); // private copy-ctor and op= -}; - -#endif // _SIM_ASSETSTREAM_H diff --git a/simulator/app/DeviceManager.cpp b/simulator/app/DeviceManager.cpp deleted file mode 100644 index a859c63f1..000000000 --- a/simulator/app/DeviceManager.cpp +++ /dev/null @@ -1,1220 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Management of the simulated device. -// - -// For compilers that support precompilation, include "wx/wx.h". -#include "wx/wxprec.h" - -// Otherwise, include all standard headers -#ifndef WX_PRECOMP -# include "wx/wx.h" -#endif -#include "wx/image.h" - -#include "DeviceManager.h" -#include "MyApp.h" -#include "DeviceWindow.h" -#include "LogWindow.h" -#include "UserEvent.h" -#include "UserEventMessage.h" - -#include "SimRuntime.h" -#include "utils.h" - -#include <unistd.h> -#include <signal.h> -#include <errno.h> - -#if !defined(SIGKILL) // doesn't exist in MinGW -# if defined(SIGBREAK) -# define SIGKILL SIGBREAK // intended for Ctrl-Break -# else -# define SIGKILL SIGABRT -# endif -#endif - - -/* - * Constructor. - */ -DeviceManager::DeviceManager(void) - : mThread(NULL), mDisplay(NULL), mNumDisplays(0), mKeyMap(NULL), - mpStatusWindow(NULL) -{ - //printf("--- DeviceManager constructor\n"); -} - -/* - * Destructor. Snuff the thread if it's still kicking. - */ -DeviceManager::~DeviceManager(void) -{ - //printf("--- DeviceManager destructor\n"); - - if (mThread != NULL && mThread->IsRunning()) { - mThread->KillChildProcesses(); - } - if (mThread != NULL) { - wxThread::ExitCode code; - - printf("Sim: Waiting for old runtime thread..."); fflush(stdout); - code = mThread->Wait(); // join the old thread - printf("done (code=%ld)\n", (long) code); - } - delete mThread; - mThread = NULL; - - delete[] mDisplay; - free((void*)mKeyMap); -} - -/* - * Initialize the device configuration. - * - * "statusWindow" is where message boxes with failure messages go, usually - * the main frame. - */ -bool DeviceManager::Init(int numDisplays, wxWindow* statusWindow) -{ - //if (IsRunning()) { - // fprintf(stderr, "ERROR: tried to Configure device while running\n"); - // return false; - //} - assert(mDisplay == NULL); - assert(numDisplays > 0); - - //if (mDisplay != NULL) - // delete[] mDisplay; - - mDisplay = new Display[numDisplays]; - mNumDisplays = numDisplays; - - mpStatusWindow = statusWindow; - - return true; -} - -/* - * Have we been initialized already? - */ -bool DeviceManager::IsInitialized(void) const -{ - return (mDisplay != NULL); -} - -#if 0 -/* - * Return the Nth display. - */ -int DeviceManager::GetShmemKey(int displayIndex) -{ - assert(displayIndex >= 0 && displayIndex < mNumDisplays); - return mDisplay[displayIndex].GetShmemKey(); -} -#endif - -/* - * Define mapping between the device's display and a wxWidgets window. - */ -bool DeviceManager::SetDisplayConfig(int displayIndex, wxWindow* window, - int width, int height, android::PixelFormat format, int refresh) -{ - assert(displayIndex >= 0 && displayIndex < mNumDisplays); - - if (!mDisplay[displayIndex].Create(displayIndex, window, width, height, - format, refresh)) - { - fprintf(stderr, "Sim: ERROR: unable to configure display %d\n", - displayIndex); - return false; - } else { - printf("Sim: configured display %d (w=%d h=%d f=%d re=%d)\n", - displayIndex, width, height, format, refresh); - return true; - } -} - -/* - * Define the keyboard - */ -bool DeviceManager::SetKeyboardConfig(const char *keymap) { - free((void*)mKeyMap); - mKeyMap = strdup(keymap); - return true; -} - -/* - * Called before the phone window dialog destroys itself. The goal here - * is to prevent the runtime thread from trying to draw after the phone - * window has closed for business but before the device manager destructor - * gets called. - */ -void DeviceManager::WindowsClosing(void) -{ - int i; - - for (i = 0; i < mNumDisplays; i++) - mDisplay[i].Uncreate(); -} - -/* - * Launch a new runtime process. If there is an existing device manager - * thread, we assume that it is in the process of shutting down. - */ -bool DeviceManager::StartRuntime(void) -{ - return DeviceManager::DeviceThread::LaunchProcess(mpStatusWindow); -} - -/* - * Start the runtime management thread when a runtime connects to us. If - * there is an existing thread, we assume that it is in the process of - * shutting down. - */ -bool DeviceManager::StartRuntime(android::Pipe* reader, android::Pipe* writer) -{ - if (mThread != NULL) { - wxThread::ExitCode code; - - if (mThread->IsRunning()) { - fprintf(stderr, - "Sim: ERROR: start requested, but thread running\n"); - return false; - } - - // clean up old thread - printf("Sim: Waiting for old runtime thread..."); fflush(stdout); - code = mThread->Wait(); // join the old thread - printf("done (code=%ld)\n", (long) code); - - delete mThread; - mThread = NULL; - } - - assert(mpStatusWindow != NULL); - mThread = new DeviceThread(this, mpStatusWindow, reader, writer); - if (mThread->Create() != wxTHREAD_NO_ERROR) { - fprintf(stderr, "Sim: ERROR: can't create thread\n"); - return false; - } - mThread->Run(); - - return true; -} - -/* - * Get the message stream. Returns NULL if it doesn't exist. - */ -android::MessageStream* DeviceManager::GetStream(void) -{ - if (!IsRunning()) { - fprintf(stderr, "Sim: ERROR: runtime thread not active\n"); - return NULL; - } - - assert(mThread != NULL); - android::MessageStream* pStream = mThread->GetStream(); - assert(pStream != NULL); - - if (!pStream->isReady()) { - fprintf(stderr, "Sim: NOTE: connection to runtime not ready\n"); - return NULL; - } - - return pStream; -} - -/* - * Stop the runtime, politely. - * - * We don't clean up the thread here, because it might not exit immediately. - */ -bool DeviceManager::StopRuntime(void) -{ - android::MessageStream* pStream = GetStream(); - if (pStream == NULL) - return false; - - printf("Sim: Sending quit command\n"); - - android::Message msg; - msg.setCommand(android::Simulator::kCommandQuit, 0); - pStream->send(&msg); - return true; -} - -/* - * Kill the runtime as efficiently as possible. - */ -void DeviceManager::KillRuntime(void) -{ - if (mThread != NULL && mThread->IsRunning()) - mThread->KillChildProcesses(); -} - -#if 0 -/* - * Check if the modified time is newer than mLastModified - */ -bool DeviceManager::RefreshRuntime(void) -{ - return (IsRunning() && mThread->IsRuntimeNew()); -} - -/* - * Tells the device manager that the user does not want to update - * the runtime - */ -void DeviceManager::UserCancelledRefresh(void) -{ - mThread->UpdateLastModified(); -} -#endif - -/* - * Send an event to the runtime. - * - * The events are defined in display_device.h. - */ -void DeviceManager::SendKeyEvent(KeyCode keyCode, bool down) -{ - android::MessageStream* pStream = GetStream(); - if (pStream == NULL) - return; - - int event = down ? android::Simulator::kCommandKeyDown : - android::Simulator::kCommandKeyUp; - - //printf("Sim: sending key-%s %d\n", down ? "down" : "up", keyCode); - - android::Message msg; - msg.setCommand(event, keyCode); - pStream->send(&msg); -} - -/* - * Send a "touch screen" event to the runtime. - * - * "mode" can be "down" (we're pressing), "up" (we're lifting our finger - * off) or "drag". - */ -void DeviceManager::SendTouchEvent(android::Simulator::TouchMode mode, - int x, int y) -{ - android::MessageStream* pStream = GetStream(); - if (pStream == NULL) - return; - - //printf("Sim: sending touch-%d x=%d y=%d\n", (int) mode, x, y); - - android::Message msg; - msg.setCommandExt(android::Simulator::kCommandTouch, mode, x, y); - pStream->send(&msg); -} - -/* - * The runtime has sent us a new frame of stuff to display. - * - * NOTE: we're still in the runtime management thread. We have to pass the - * bitmap through AddPendingEvent to get it over to the main thread. - * - * We have to make a copy of the data from the runtime; the easiest - * way to do that is to convert it to a bitmap here. However, X11 gets - * all worked up about calls being made from multiple threads, so we're - * better off just copying it into a buffer. - * - * Because we're decoupled from the runtime, there is a chance that we - * could drop frames. Buffering them up is probably worse, since it - * creates the possibility that we could stall and run out of memory. - * We could save a copy by handing the runtime a pointer to our buffer, - * but then we'd have to mutex the runtime against the simulator window - * Paint function. - */ -void DeviceManager::ShowFrame(int displayIndex) -{ - assert(displayIndex >= 0 && displayIndex < mNumDisplays); - - // copy the data to local storage and convert - mDisplay[displayIndex].CopyFromShared(); - - // create a user event and send it to the window - UserEvent uev(0, (void*) displayIndex); - - wxWindow* pEventWindow = mDisplay[displayIndex].GetWindow(); - if (pEventWindow != NULL) { - //printf("runtime has image, passing up\n"); - pEventWindow->AddPendingEvent(uev); - } else { - fprintf(stderr, "NOTE: runtime has image, display not available\n"); - } -} - -void DeviceManager::Vibrate(int vibrateOn) -{ - ((MyApp*)wxTheApp)->Vibrate(vibrateOn); -} - -/* - * Get the display data from the specified display. - */ -wxBitmap* DeviceManager::GetImageData(int displayIndex) -{ - assert(displayIndex >= 0 && displayIndex < mNumDisplays); - return mDisplay[displayIndex].GetImageData(); -} - -/* - * Send an event to all device windows - */ -void DeviceManager::BroadcastEvent(UserEvent& userEvent) { - int numDisplays = GetNumDisplays(); - for (int i = 0; i < numDisplays; i++) { - wxWindow* pEventWindow = mDisplay[i].GetWindow(); - if (pEventWindow != NULL) { - pEventWindow->AddPendingEvent(userEvent); - } - } -} - - -/* - * =========================================================================== - * DeviceManager::Display - * =========================================================================== - */ - -/* - * Fill out the various interesting fields based on the parameters. - */ -bool DeviceManager::Display::Create(int displayNum, wxWindow* window, - int width, int height, android::PixelFormat format, int refresh) -{ - //printf("DeviceManager::Display constructor\n"); - - assert(window != NULL); - if (mImageData != NULL) { - assert(false); // no re-init - return false; - } - - mDisplayNum = displayNum; - mDisplayWindow = window; - mWidth = width; - mHeight = height; - mFormat = format; - mRefresh = refresh; - - // use a fixed key for now - mShmemKey = GenerateKey(displayNum); - // allocate 24bpp for now - mpShmem = new android::Shmem; - if (!mpShmem->create(mShmemKey, width * height * 3, true)) - return false; - //printf("--- CREATED shmem, key=0x%08x addr=%p\n", - // mShmemKey, mpShmem->getAddr()); - - mImageData = new unsigned char[width * height * 3]; - if (mImageData == NULL) - return false; - - return true; -} - -/* - * The UI components are starting to shut down. We need to do away with - * our wxWindow pointer so that the runtime management thread doesn't try - * to send it display update events. - * - * We also need to let go of our side of the shared memory, because a - * new DeviceManager may get started up before our destructor gets called, - * and we may be re-using the key. - */ -void DeviceManager::Display::Uncreate(void) -{ - wxMutexLocker locker(mImageDataLock); - - //printf("--- Uncreate\n"); - - mDisplayWindow = NULL; - - // the "locker" mutex keeps this from hosing CopyFromShared() - if (mpShmem != NULL) { - //printf("--- DELETING shmem, addr=%p\n", mpShmem->getAddr()); - delete mpShmem; - mpShmem = NULL; - } -} - -/* - * Make a local copy of the image data. The UI grabs this data from a - * different thread, so we have to mutex it. - */ -void DeviceManager::Display::CopyFromShared(void) -{ - wxMutexLocker locker(mImageDataLock); - - if (mpShmem == NULL) { - //printf("Sim: SKIP CopyFromShared\n"); - return; - } - - //printf("Display %d: copying data from %p to %p\n", - // mDisplayNum, mpShmem->getAddr(), mImageData); - - /* data is always 24bpp RGB */ - mpShmem->lock(); // avoid tearing - memcpy(mImageData, mpShmem->getAddr(), mWidth * mHeight * 3); - mpShmem->unlock(); -} - -/* - * Get the image data in the form of a newly-allocated bitmap. - * - * This MUST be called from the UI thread. Creating wxBitmaps in the - * runtime management thread will cause X11 failures (e.g. - * "Xlib: unexpected async reply"). - */ -wxBitmap* DeviceManager::Display::GetImageData(void) -{ - wxMutexLocker locker(mImageDataLock); - - assert(mImageData != NULL); - - //printf("HEY: creating tmpImage, w=%d h=%d data=%p\n", - // mWidth, mHeight, mImageData); - - /* create a temporary wxImage; it does not own the data */ - wxImage tmpImage(mWidth, mHeight, (unsigned char*) mImageData, true); - - /* return a new bitmap with the converted-for-display data */ - return new wxBitmap(tmpImage); -} - - -/* - * =========================================================================== - * DeviceManager::DeviceThread - * =========================================================================== - */ - -/* - * Some notes on process management under Linux/Mac OS X: - * - * We want to put the runtime into its own process group. That way we - * can send SIGKILL to the entire group to guarantee that we kill it and - * all of its children. Simply killing the sim's direct descendant doesn't - * do what we want. If it's a debugger, we will just orphan the runtime - * without killing it. Even if the runtime is our child, the children of - * the runtime might outlive it. - * - * We want to be able to run the child under GDB or Valgrind, both - * of which take input from the tty. They need to be in the "foreground" - * process group. We might be debugging or valgrinding the simulator, - * or operating in a command-line-only "headless" mode, so in that case - * the sim front-end should actually be in the foreground group. - * - * Putting the runtime in the background group means it can't read input - * from the tty (not an issue) and will generate SIGTTOU signals when it - * writes output to the tty (easy to ignore). The trick, then, is to - * have the simulator and gdb/valgrind in the foreground pgrp while the - * runtime itself is in a different group. This group needs to be known - * to the simulator so that it can send signals to the appropriate place. - * - * The solution is to have the runtime process change its process group - * after it starts but before it creates any new processes, and then send - * the process group ID back to the simulator. The sim can then send - * signals to the pgrp to ensure that we don't end up with zombies. Any - * "pre-launch" processes, like GDB, stay in the sim's pgrp. This also - * allows a consistent API for platforms that don't have fork/exec - * (e.g. MinGW). - * - * This doesn't help us with interactive valgrind (e.g. --db-attach=yes), - * because valgrind is an LD_PRELOAD shared library rather than a - * separate process. For that, we actually need to use termios(3) to - * change the terminal's pgrp, or the interactive stuff just doesn't work. - * We don't want to do that every time or attempting to debug the simulator - * front-end will have difficulties. - * - * Making this even more entertaining is the fact that the simulator - * front-end could itself be launched in the background. It's essential - * that we be careful about assigning a process group to the foreground, - * and that we don't restore ourselves unless we were in the foreground to - * begin with. - * - * - * Some notes on process management under Windows (Cygwin, MinGW): - * - * Signals cannot be caught or ignored under MinGW. All signals are fatal. - * - * Signals can be ignored under Cygwin, but not caught. - * - * Windows has some process group stuff (e.g. CREATE_NEW_PROCESS_GROUP flag - * and GenerateConsoleCtrlEvent()). Need to explore. - * - * - * UPDATE: we've abandoned Mac OS and MinGW, so we now launch the runtime in - * a separate xterm. This avoids all tty work on our side. We still need - * to learn the pgrp from the child during the initial communication - * handshake so we can do necessary cleanup. - */ - - -/* - * Convert a space-delimited string into an argument vector. - * - * "arg" is the current arg offset. - */ -static int stringToArgv(char* mangle, const char** argv, int arg, int maxArgs) -{ - bool first = true; - - while (*mangle != '\0') { - assert(arg < maxArgs); - if (first) { - argv[arg++] = mangle; - first = false; - } - if (*mangle == ' ') { - *mangle = '\0'; - first = true; - } - mangle++; - } - - return arg; -} - -/* - * Launch the runtime process in its own terminal window. Start by setting - * up the argument vector to the runtime process. - * - * The last entry in the vector will be a NULL pointer. - * - * This is awkward and annoying because the wxWidgets strings are current - * configured for UNICODE. - */ -/*static*/ bool DeviceManager::DeviceThread::LaunchProcess(wxWindow* statusWindow) -{ - static const char* kLaunchWrapper = "launch-wrapper"; - const int kMaxArgs = 64; - Preferences* pPrefs; - wxString errMsg; - wxString runtimeExe; - wxString debuggerExe; - wxString debuggerScript; - wxString valgrinderExe; - wxString launchWrapperExe; - wxString launchWrapperArgs; - wxString javaAppName; - wxString termCmd; - wxString tmpStr; - char gammaVal[8]; - //bool bval; - double dval; - bool result = false; - bool doDebug, doValgrind, doCheckJni, doEnableSound, doEnableFakeCamera; - const char** argv = NULL; - int arg; - wxCharBuffer runtimeExeTmp; - wxCharBuffer debuggerExeTmp; - wxCharBuffer debuggerScriptTmp; - wxCharBuffer javaAppNameTmp; - wxCharBuffer valgrinderExeTmp; - wxCharBuffer termCmdTmp; - wxCharBuffer launchWrapperExeTmp; - wxCharBuffer launchWrapperArgsTmp; - - pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - if (pPrefs == NULL) { - errMsg = wxT("Preferences were not loaded."); - goto bail; - } - - /* - * Set environment variables. This stuff should be passed through as - * arguments, but the runtime binary currently has a disconnect - * between main() and the VM initilization. - * - * TODO: remove this in favor of system properties - */ -#if 0 - // TODO: restore this - doCheckJni = false; - pPrefs->GetBool("check-jni", &doCheckJni); -#endif - - tmpStr.Empty(); - pPrefs->GetString("ld-assume-kernel", /*ref*/ tmpStr); - if (tmpStr.IsEmpty()) { - unsetenv("LD_ASSUME_KERNEL"); - } else { - setenv("LD_ASSUME_KERNEL", tmpStr.ToAscii(), 1); - } - - doEnableSound = false; - pPrefs->GetBool("enable-sound", &doEnableSound); - if (doEnableSound) - setenv("ANDROIDSOUND", "1", 1); - - doEnableFakeCamera = false; - pPrefs->GetBool("enable-fake-camera", &doEnableFakeCamera); - if (doEnableFakeCamera) - setenv("ANDROIDFAKECAMERA", "1", 1); - - /* - * Set the Dalvik bootstrap class path. Normally this is set by "init". - */ - setenv("BOOTCLASSPATH", - "/system/framework/core.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar", - 1); - - /* - * Figure out where the "runtime" binary lives. - */ - runtimeExe = ((MyApp*)wxTheApp)->GetRuntimeExe(); - assert(!runtimeExe.IsEmpty()); - - //UpdateLastModified(); - - /* - * Initialize argv. - */ - argv = new const char*[kMaxArgs]; - if (argv == NULL) - goto bail; - arg = 0; - - /* - * We want to launch the runtime in its own terminal window so we don't - * have to fight over who gets access to the controlling tty. We allow - * the user to specify the command they want to use to perform the - * launch. Here we cut it into pieces for argv. - * - * To make life easier here, we require that the launch command be - * all one piece, i.e. it's not "xterm -e <stuff> -geom blah" with our - * stuff in the middle. - */ - termCmd.Empty(); - pPrefs->GetString("launch-command", /*ref*/ termCmd); - if (termCmd.IsEmpty()) { - fprintf(stderr, "Sim: WARNING: launch-command is empty\n"); - } else { - termCmdTmp = termCmd.ToAscii(); - char* mangle = strdup(termCmdTmp); - arg = stringToArgv(mangle, argv, arg, kMaxArgs); - } - - /* - * The "launch-wrapper" binary lives in the same place as the runtime. - * This sets up LD_PRELOAD and some other environment variables. - */ - int charIdx; - - charIdx = runtimeExe.Find('/', true); - if (charIdx == -1) { - launchWrapperExe = wxString::FromAscii(kLaunchWrapper); - } else { - launchWrapperExe = runtimeExe.Mid(0, charIdx+1); - launchWrapperExe.Append(wxString::FromAscii(kLaunchWrapper)); - } - printf("Sim launch wrapper: %s\n", (const char*)launchWrapperExe.ToAscii()); - - argv[arg++] = launchWrapperExeTmp = launchWrapperExe.ToAscii(); - - launchWrapperArgs.Empty(); - pPrefs->GetString("launch-wrapper-args", /*ref*/ launchWrapperArgs); - if (!launchWrapperArgs.IsEmpty()) { - launchWrapperArgsTmp = launchWrapperArgs.ToAscii(); - char* mangle = strdup(launchWrapperArgsTmp); - arg = stringToArgv(mangle, argv, arg, kMaxArgs); - } - - /* - * If we're launching under GDB or valgrind, set that up. - */ - doDebug = doValgrind = false; - pPrefs->GetBool("debug", &doDebug); - if (((MyApp*)wxTheApp)->GetDebuggerOption()) { - doDebug = true; - } - debuggerScript = ((MyApp*)wxTheApp)->GetDebuggerScript(); - - pPrefs->GetBool("valgrind", &doValgrind); - if (doDebug || doValgrind) { - - pPrefs->GetString("debugger", /*ref*/ debuggerExe); - pPrefs->GetString("valgrinder", /*ref*/ valgrinderExe); - - // check for empty or undefined preferences - if (doDebug && debuggerExe.IsEmpty()) { - errMsg = wxT("Debugger not defined."); - goto bail; - } - if (doValgrind && valgrinderExe.IsEmpty()) { - errMsg = wxT("Valgrinder not defined."); - goto bail; - } - - if (doValgrind) { - argv[arg++] = valgrinderExeTmp = valgrinderExe.ToAscii(); - //argv[arg++] = "--tool=callgrind"; - argv[arg++] = "--tool=memcheck"; - argv[arg++] = "--leak-check=yes"; // check for leaks too - argv[arg++] = "--leak-resolution=med"; // increase from 2 to 4 - argv[arg++] = "--num-callers=8"; // reduce from 12 to 8 - //argv[arg++] = "--show-reachable=yes"; // show still-reachable - if (doDebug) { - //mTerminalFollowsChild = true; // interactive - argv[arg++] = "--db-attach=yes"; - } - //mSlowExit = true; - } else /*doDebug*/ { - argv[arg++] = debuggerExeTmp = debuggerExe.ToAscii(); - if (!debuggerScript.IsEmpty()) { - argv[arg++] = "-x"; - argv[arg++] = debuggerScriptTmp = debuggerScript.ToAscii(); - } - argv[arg++] = runtimeExeTmp = runtimeExe.ToAscii(); - argv[arg++] = "--args"; - } - } - - /* - * Get runtime args. - */ - - argv[arg++] = runtimeExeTmp = (const char*) runtimeExe.ToAscii(); - - javaAppName = ((MyApp*)wxTheApp)->GetAutoRunApp(); - if (javaAppName.IsEmpty()) { - if (!pPrefs->GetString("java-app-name", /*ref*/ javaAppName)) { - javaAppName = wxT(""); - } - } - - if (!javaAppName.IsEmpty()) - { - argv[arg++] = "-j"; - argv[arg++] = javaAppNameTmp = (const char*) javaAppName.ToAscii(); - } - - if (pPrefs->GetDouble("gamma", &dval) && dval != 1.0) { - snprintf(gammaVal, sizeof(gammaVal), "%.3f", dval); - argv[arg++] = "-g"; - argv[arg++] = gammaVal; - } - - /* finish arg set */ - argv[arg++] = NULL; - - assert(arg <= kMaxArgs); - -#if 1 - printf("ARGS:\n"); - for (int i = 0; i < arg; i++) - printf(" %d: '%s'\n", i, argv[i]); -#endif - - if (fork() == 0) { - execvp(argv[0], (char* const*) argv); - fprintf(stderr, "execvp '%s' failed: %s\n", argv[0], strerror(errno)); - exit(1); - } - - /* - * We assume success; if it didn't succeed we'll just sort of hang - * out waiting for a connection. There are ways to fix this (create - * a non-close-on-exec pipe and watch to see if the other side closes), - * but at this stage it's not worthwhile. - */ - result = true; - - tmpStr = wxT("=== launched "); - tmpStr += runtimeExe; - LogWindow::PostLogMsg(tmpStr); - - assert(errMsg.IsEmpty()); - -bail: - if (!errMsg.IsEmpty()) { - assert(result == false); - - UserEventMessage* pUem = new UserEventMessage; - pUem->CreateErrorMessage(errMsg); - - UserEvent uev(0, (void*) pUem); - - assert(statusWindow != NULL); - statusWindow->AddPendingEvent(uev); - } - delete[] argv; - return result; -} - -/* - * This is the entry point for the device thread. The thread launches the - * runtime process and monitors it. When the runtime exits, the thread - * exits. - * - * Because this isn't running in the UI thread, any user interaction has - * to be channeled through "user events" to the appropriate window. - */ -void* DeviceManager::DeviceThread::Entry(void) -{ - //android::MessageStream stream; - android::Message msg; - wxString errMsg; - char statusBuf[64] = "(no status)"; - int result = 1; - - /* print this so we can make sense of log messages */ - LOG(LOG_DEBUG, "", "Sim: device management thread starting (pid=%d)\n", - getpid()); - - assert(mReader != NULL && mWriter != NULL); - - /* - * Tell the main thread that we're running. If something fails here, - * we'll send them a "stopped running" immediately afterward. - */ - { - UserEventMessage* pUem = new UserEventMessage; - pUem->CreateRuntimeStarted(); - - UserEvent uev(0, (void*) pUem); - - assert(mpStatusWindow != NULL); - mpStatusWindow->AddPendingEvent(uev); - } - LogWindow::PostLogMsg( - "=============================================================="); - LogWindow::PostLogMsg("=== runtime starting"); - - /* - * Establish contact with runtime. - */ - if (!mStream.init(mReader, mWriter, true)) { - errMsg = wxT("ERROR: Unable to establish communication with runtime.\n"); - goto bail; - } - - /* - * Tell the runtime to put itself into a new process group and set - * itself up as the foreground process. The latter is only really - * necessary to make valgrind+gdb work. - */ - msg.setCommand(android::Simulator::kCommandNewPGroup, true); - mStream.send(&msg); - - printf("Sim: Sending hardware configuration\n"); - - /* - * Send display config. - * - * Right now we're just shipping a big binary blob over. - */ - assert(android::Simulator::kValuesPerDisplay >= 5); - int buf[1 + 1 + mpDeviceManager->GetNumDisplays() * - android::Simulator::kValuesPerDisplay]; - buf[0] = android::Simulator::kDisplayConfigMagic; - buf[1] = mpDeviceManager->GetNumDisplays(); - for (int i = 0; i < mpDeviceManager->GetNumDisplays(); i++) { - DeviceManager::Display* pDisplay = mpDeviceManager->GetDisplay(i); - int* pBuf = &buf[2 + android::Simulator::kValuesPerDisplay * i]; - - pBuf[0] = pDisplay->GetWidth(); - pBuf[1] = pDisplay->GetHeight(); - pBuf[2] = pDisplay->GetFormat(); - pBuf[3] = pDisplay->GetRefresh(); - pBuf[4] = pDisplay->GetShmemKey(); - } - msg.setRaw((const unsigned char*)buf, sizeof(buf), - android::Message::kCleanupNoDelete); - mStream.send(&msg); - - /* - * Send other hardware config. - * - * Examples: - * - Available input devices. - * - Set of buttons on device. - * - External devices (Bluetooth, etc). - * - Initial mode (e.g. "flipped open" vs. "flipped closed"). - */ - - msg.setConfig("keycharmap", mpDeviceManager->GetKeyMap()); - mStream.send(&msg); - - /* - * Done with config. - */ - msg.setCommand(android::Simulator::kCommandConfigDone, 0); - mStream.send(&msg); - - /* - * Sit forever, waiting for messages from the runtime process. - */ - while (1) { - if (!mStream.recv(&msg, true)) { - /* - * The read failed. This usually means the child has died. - */ - printf("Sim: runtime process has probably died\n"); - break; - } - - if (msg.getType() == android::Message::kTypeCommand) { - int cmd, arg; - - if (!msg.getCommand(&cmd, &arg)) { - fprintf(stderr, "Sim: Warning: failed unpacking command\n"); - /* keep going? */ - } else { - switch (cmd) { - case android::Simulator::kCommandNewPGroupCreated: - // runtime has moved into a separate process group - // (not expected for external) - printf("Sim: child says it's now in pgrp %d\n", arg); - mRuntimeProcessGroup = arg; - break; - case android::Simulator::kCommandRuntimeReady: - // sim is up and running, do late init - break; - case android::Simulator::kCommandUpdateDisplay: - // new frame of graphics is ready - //printf("RCVD display update %d\n", arg); - mpDeviceManager->ShowFrame(arg); - break; - case android::Simulator::kCommandVibrate: - // vibrator on or off - //printf("RCVD vibrator update %d\n", arg); - mpDeviceManager->Vibrate(arg); - break; - default: - printf("Sim: got unknown command %d/%d\n", cmd, arg); - break; - } - } - } else if (msg.getType() == android::Message::kTypeLogBundle) { - android_LogBundle bundle; - - if (!msg.getLogBundle(&bundle)) { - fprintf(stderr, "Sim: Warning: failed unpacking logBundle\n"); - /* keep going? */ - } else { - LogWindow::PostLogMsg(&bundle); - } - } else { - printf("Sim: got unknown message type=%d\n", msg.getType()); - } - } - - result = 0; - -bail: - printf("Sim: DeviceManager thread preparing to exit\n"); - - /* kill the comm channel; should encourage runtime to die */ - mStream.close(); - delete mReader; - delete mWriter; - mReader = mWriter = NULL; - - /* - * We never really did get a "friendly death" working, so just slam - * the thing if we have the process group. - */ - if (mRuntimeProcessGroup != 0) { - /* kill the group, not our immediate child */ - printf("Sim: killing pgrp %d\n", (int) mRuntimeProcessGroup); - kill(-mRuntimeProcessGroup, 9); - } - - if (!errMsg.IsEmpty()) { - UserEventMessage* pUem = new UserEventMessage; - pUem->CreateErrorMessage(errMsg); - - UserEvent uev(0, (void*) pUem); - mpStatusWindow->AddPendingEvent(uev); - } - - /* notify the main window that the runtime has stopped */ - { - UserEventMessage* pUem = new UserEventMessage; - pUem->CreateRuntimeStopped(); - - UserEvent uev(0, (void*) pUem); - mpStatusWindow->AddPendingEvent(uev); - } - - /* show exit status in log file */ - wxString exitMsg; - exitMsg.Printf(wxT("=== runtime exiting - %s"), statusBuf); - LogWindow::PostLogMsg(exitMsg); - LogWindow::PostLogMsg( - "==============================================================\n"); - - /* - * Reset system properties for future runs. - */ - ResetProperties(); - - return (void*) result; -} - - -/* - * Wait for a little bit to see if the thread will exit. - * - * "delay" is in 0.1s increments. - */ -void DeviceManager::DeviceThread::WaitForDeath(int delay) -{ - const int kDelayUnit = 100000; - int i; - - for (i = 0; i < delay; i++) { - if (!IsRunning()) - return; - usleep(kDelayUnit); - } -} - - -/* - * Kill the runtime process. The goal is to cause our local runtime - * management thread to exit. If it doesn't, this will kill the thread - * before it returns. - */ -void DeviceManager::DeviceThread::KillChildProcesses(void) -{ - if (!this->IsRunning()) - return; - - /* clear "slow exit" flag -- we're forcefully killing this thing */ - //this->mSlowExit = false; - - /* - * Use the ChildProcess object in the thread to send signals. There's - * a risk that the DeviceThread will exit and destroy the object while - * we're using it. Using a mutex here gets a little awkward because - * we can't put it in DeviceThread. It's easier to make a copy of - * ChildProcess and operate on the copy, but we have to do that very - * carefully to avoid interfering with the communcation pipes. - * - * For now, we just hope for the best. FIX this someday. - * - * We broadcast to the process group, which will ordinarily kill - * everything. If we're running with valgrind+GDB everything is in our - * pgrp and we can't do the broadcast; if GDB alone, then only GDB is - * in our pgrp, so the broadcast will hit everything except it. We - * hit the group and then hit our child for good measure. - */ - if (mRuntimeProcessGroup != 0) { - /* kill the group, not our immediate child */ - printf("Sim: killing pgrp %d\n", (int) mRuntimeProcessGroup); - kill(-mRuntimeProcessGroup, 9); - WaitForDeath(15); - } - - /* - * Close the communication channel. This should cause our thread - * to snap out of its blocking read and the runtime thread to bail - * out the next time it tries to interact with us. We should only - * get here if somebody other than our direct descendant has the - * comm channel open and our broadcast didn't work, which should - * no longer be possible. - */ - if (this->IsRunning()) { - printf("Sim: killing comm channel\n"); - mStream.close(); - delete mReader; - delete mWriter; - mReader = mWriter = NULL; - WaitForDeath(15); - } - - /* - * At this point it's possible that our DeviceThread is just wedged. - * Kill it. - * - * Using the thread Kill() function can orphan resources, including - * locks and semaphores. There is some risk that the simulator will - * be hosed after this. - */ - if (this->IsRunning()) { - fprintf(stderr, "Sim: WARNING: killing runtime thread (%ld)\n", - (long) GetId()); - this->Kill(); - WaitForDeath(15); - } - - /* - * Now I'm scared. - */ - if (this->IsRunning()) { - fprintf(stderr, "Sim: thread won't die!\n"); - } -} - - -/* - * Configure system properties for the simulated device. - * - * Property requests can arrive *before* the full connection to the - * simulator is established, so we want to reset these during cleanup. - */ -void DeviceManager::DeviceThread::ResetProperties(void) -{ - wxWindow* mainFrame = ((MyApp*)wxTheApp)->GetMainFrame(); - PropertyServer* props = ((MainFrame*)mainFrame)->GetPropertyServer(); - - props->ClearProperties(); - props->SetDefaultProperties(); -} - - -#if 0 -/* - * Return true if the executable found is newer than - * what is currently running - */ -bool DeviceManager::DeviceThread::IsRuntimeNew(void) -{ - if (mLastModified == 0) { - /* - * Haven't called UpdateLastModified yet, or called it but - * couldn't stat() the executable. - */ - return false; - } - - struct stat status; - if (stat(mRuntimeExe.ToAscii(), &status) == 0) { - return (status.st_mtime > mLastModified); - } else { - // doesn't exist, so it can't be newer - fprintf(stderr, "Sim: unable to stat '%s': %s\n", - (const char*) mRuntimeExe.ToAscii(), strerror(errno)); - return false; - } -} - -/* - * Updates mLastModified to reflect the current executables mtime - */ -void DeviceManager::DeviceThread::UpdateLastModified(void) -{ - struct stat status; - if (stat(mRuntimeExe.ToAscii(), &status) == 0) { - mLastModified = status.st_mtime; - } else { - fprintf(stderr, "Sim: unable to stat '%s': %s\n", - (const char*) mRuntimeExe.ToAscii(), strerror(errno)); - mLastModified = 0; - } -} -#endif - diff --git a/simulator/app/DeviceManager.h b/simulator/app/DeviceManager.h deleted file mode 100644 index bd4371e87..000000000 --- a/simulator/app/DeviceManager.h +++ /dev/null @@ -1,284 +0,0 @@ -// -// 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 diff --git a/simulator/app/DeviceWindow.cpp b/simulator/app/DeviceWindow.cpp deleted file mode 100644 index a15b03ba1..000000000 --- a/simulator/app/DeviceWindow.cpp +++ /dev/null @@ -1,264 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Displays output from the device. -// - -// For compilers that support precompilation, include "wx/wx.h". -#include "wx/wxprec.h" - -// Otherwise, include all standard headers -#ifndef WX_PRECOMP -# include "wx/wx.h" -#endif -#include "wx/image.h" // needed for Windows build -#include "wx/dcbuffer.h" - -#include "AssetStream.h" -#include "DeviceWindow.h" -#include "MyApp.h" -#include "Preferences.h" - -BEGIN_EVENT_TABLE(DeviceWindow, wxWindow) - EVT_SIZE(DeviceWindow::OnSize) - EVT_ERASE_BACKGROUND(DeviceWindow::OnErase) - EVT_PAINT(DeviceWindow::OnPaint) - EVT_KEY_DOWN(DeviceWindow::OnKeyDown) - EVT_KEY_UP(DeviceWindow::OnKeyUp) - - EVT_LEFT_DOWN(DeviceWindow::OnMouseLeftDown) - EVT_LEFT_DCLICK(DeviceWindow::OnMouseLeftDown) - EVT_LEFT_UP(DeviceWindow::OnMouseLeftUp) - EVT_RIGHT_DOWN(DeviceWindow::OnMouseRightDown) - EVT_RIGHT_DCLICK(DeviceWindow::OnMouseRightDown) - EVT_RIGHT_UP(DeviceWindow::OnMouseRightUp) - EVT_MOTION(DeviceWindow::OnMouseMotion) - - EVT_USER_EVENT(DeviceWindow::OnUserEvent) -END_EVENT_TABLE() - - -/* - * Create a new DeviceWindow. This should be a child of PhoneWindow. - * - * Note the DeviceManager may not be fully initialized yet. - */ -DeviceWindow::DeviceWindow(wxWindow* parent, DeviceManager* pDM) - : wxWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, - wxNO_BORDER | wxWANTS_CHARS), - mpDeviceManager(pDM) -{ - //printf("DW: created (parent=%p DM=%p)\n", parent, pDM); - - SetBackgroundStyle(wxBG_STYLE_CUSTOM); - - // create a trivial bitmap so we have something allocated - mBitmap.Create(1, 1); - -} - -/* - * Destructor. - */ -DeviceWindow::~DeviceWindow(void) -{ -} - -/* - * We don't want to trap key or mouse events here. - * - * event.Skip() didn't seem to do the trick, so we call AddPendingEvent() - * to add it to the parent's input queue. - */ -void DeviceWindow::OnKeyDown(wxKeyEvent& event) -{ - //printf("DW: down: %d\n", event.GetKeyCode()); - GetParent()->AddPendingEvent(event); -} -void DeviceWindow::OnKeyUp(wxKeyEvent& event) -{ - //printf("DW: up: %d\n", event.GetKeyCode()); - GetParent()->AddPendingEvent(event); -} - -/* - * Handle mouse events. We want to pass these up to the PhoneWindow, since - * that's where the "touch screen" code is. - */ -void DeviceWindow::OnMouseLeftDown(wxMouseEvent& event) -{ - ClampMouse(&event); - GetParent()->AddPendingEvent(event); -} -void DeviceWindow::OnMouseLeftUp(wxMouseEvent& event) -{ - ClampMouse(&event); - GetParent()->AddPendingEvent(event); -} -void DeviceWindow::OnMouseRightDown(wxMouseEvent& event) -{ - ClampMouse(&event); - GetParent()->AddPendingEvent(event); -} -void DeviceWindow::OnMouseRightUp(wxMouseEvent& event) -{ - ClampMouse(&event); - GetParent()->AddPendingEvent(event); -} -void DeviceWindow::OnMouseMotion(wxMouseEvent& event) -{ - ClampMouse(&event); - GetParent()->AddPendingEvent(event); -} - -/* - * Clamp the mouse movement to the window bounds. - */ -void DeviceWindow::ClampMouse(wxMouseEvent* pEvent) -{ - wxWindow* pEventWindow = (wxWindow*) pEvent->GetEventObject(); - int width, height; - - pEventWindow->GetSize(&width, &height); - if (pEvent->m_x < 0) - pEvent->m_x = 0; - else if (pEvent->m_x >= width) - pEvent->m_x = width-1; - - if (pEvent->m_y < 0) - pEvent->m_y = 0; - else if (pEvent->m_y >= height) - pEvent->m_y = height-1; -} - - -/* - * Handle a "user event". We get these when the runtime wants us to - * know that it has a new frame of graphics to display. - * - */ -void DeviceWindow::OnUserEvent(UserEvent& event) -{ - wxBitmap* pBitmap; - long displayIndex; - - displayIndex = (long) event.GetData(); - - //printf("GOT UAE %d\n", displayIndex); - - // a displayIndex of -1 means just update the onion skin - if (displayIndex >= 0) { - /* get a newly-allocated bitmap with converted image data */ - pBitmap = mpDeviceManager->GetImageData(displayIndex); - - /* do a ptr/refcount assignment to hold the data */ - mBitmap = *pBitmap; - /* delete the temporary object; does not delete the bitmap storage */ - delete pBitmap; - } - - if (displayIndex >= -1) { - mHasOnionSkinBitmap = false; - - Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - assert(pPrefs != NULL); - - bool overlayOnionSkin; - char* onionSkinFileName = NULL; - - bool overlayOnionSkinExists = pPrefs->GetBool("overlay-onion-skin", &overlayOnionSkin); - if (overlayOnionSkinExists && overlayOnionSkin) { - bool fileNameExists = pPrefs->GetString("onion-skin-file-name", &onionSkinFileName); - if (fileNameExists && *onionSkinFileName) { - wxImage onionSkinImage(wxString::FromAscii(onionSkinFileName)); - onionSkinImage.SetAlpha(NULL); - bool hasAlpha = onionSkinImage.HasAlpha(); - int width = onionSkinImage.GetWidth(); - int height = onionSkinImage.GetHeight(); - if (hasAlpha) { - unsigned char *alpha = onionSkinImage.GetAlpha(); - int alphaVal = 127; - pPrefs->GetInt("onion-skin-alpha-value", &alphaVal); - for (int i = (width * height) - 1; i >= 0; i--) { - alpha[i] = alphaVal; - } - } - mOnionSkinBitmap = wxBitmap(onionSkinImage); - mHasOnionSkinBitmap = true; - } - } - } - - /* induce an update */ - Refresh(); -} - -/* - * Window has been moved or resized. - * - * We get this when the model of phone is changed. - * - * FIX: in the future this only happens when the phone is rotated 90deg. - */ -void DeviceWindow::OnSize(wxSizeEvent& WXUNUSED(event)) -{ - int width, height; - - GetClientSize(&width, &height); - printf("Sim: device window resize: %dx%d\n", width, height); - - mBitmap.Create(width, height); - - wxMemoryDC memDC; - memDC.SelectObject(mBitmap); - - wxColour backColor(96, 122, 121); - memDC.SetBrush(wxBrush(backColor)); - memDC.SetPen(wxPen(backColor, 1)); - wxRect windowRect(wxPoint(0, 0), GetClientSize()); - memDC.DrawRectangle(windowRect); -} - -/* - * No need to erase the background. - */ -void DeviceWindow::OnErase(wxEraseEvent& WXUNUSED(event)) -{ - //printf("erase device\n"); -} - -/* - * Repaint the simulator output. - */ -void DeviceWindow::OnPaint(wxPaintEvent& WXUNUSED(event)) -{ - wxPaintDC dc(this); - - /* draw background image */ - dc.DrawBitmap(mBitmap, 0, 0, TRUE); - - /* If necessary, draw onion skin image on top */ - if (mHasOnionSkinBitmap) { - dc.DrawBitmap(mOnionSkinBitmap, 0, 0, TRUE); - } - -#if 0 - // debug - draw the corners - int xoff = 0; - int yoff = 0; - int width; - int height; - GetClientSize(&width, &height); - - dc.SetPen(*wxGREEN_PEN); - dc.DrawLine(xoff, yoff+9, xoff, yoff); - dc.DrawLine(xoff, yoff, xoff+10, yoff); - dc.DrawLine(xoff+width-10, yoff, xoff+width, yoff); - dc.DrawLine(xoff+width-1, yoff, xoff+width-1, yoff+10); - dc.DrawLine(xoff, yoff+height-10, xoff, yoff+height); - dc.DrawLine(xoff, yoff+height-1, xoff+10, yoff+height-1); - dc.DrawLine(xoff+width-1, yoff+height-10, xoff+width-1, yoff+height); - dc.DrawLine(xoff+width-1, yoff+height-1, xoff+width-11, yoff+height-1); -#endif -} - diff --git a/simulator/app/DeviceWindow.h b/simulator/app/DeviceWindow.h deleted file mode 100644 index 4548fc3b9..000000000 --- a/simulator/app/DeviceWindow.h +++ /dev/null @@ -1,70 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Window with simulated phone. -// -#ifndef _SIM_DEVICE_WINDOW_H -#define _SIM_DEVICE_WINDOW_H - -#include "UserEvent.h" -#include "DeviceManager.h" - -/* - * This window displays the device output. - */ -class DeviceWindow : public wxWindow { -public: - DeviceWindow(wxWindow* parent, DeviceManager* pDM); - virtual ~DeviceWindow(void); - -#if 0 // can't work -- can't create bitmaps in other threads - /* this gets tucked into a user event */ - class FrameData { - public: - FrameData(void) - : mDisplayIndex(-1), mpBitmap(NULL) - {} - ~FrameData(void) { - delete mpBitmap; - } - - void Create(int displayIndex, wxBitmap* pBitmap) { - mDisplayIndex = displayIndex; - mpBitmap = pBitmap; - } - - int GetDisplayIndex(void) const { return mDisplayIndex; } - wxBitmap* GetBitmap(void) const { return mpBitmap; } - - private: - int mDisplayIndex; - wxBitmap* mpBitmap; - }; -#endif - - void DeviceManagerClosing(void) { mpDeviceManager = NULL; } - -private: - void OnKeyDown(wxKeyEvent& event); - void OnKeyUp(wxKeyEvent& event); - void OnMouseLeftDown(wxMouseEvent& event); - void OnMouseLeftUp(wxMouseEvent& event); - void OnMouseRightDown(wxMouseEvent& event); - void OnMouseRightUp(wxMouseEvent& event); - void OnMouseMotion(wxMouseEvent& event); - void OnSize(wxSizeEvent& WXUNUSED(event)); - void OnErase(wxEraseEvent& event); - void OnPaint(wxPaintEvent& WXUNUSED(event)); - void OnUserEvent(UserEvent& event); - - void ClampMouse(wxMouseEvent* pEvent); - - DeviceManager* mpDeviceManager; - wxBitmap mBitmap; - wxBitmap mOnionSkinBitmap; - bool mHasOnionSkinBitmap; - - DECLARE_EVENT_TABLE() -}; - -#endif // _SIM_DEVICE_WINDOW_H diff --git a/simulator/app/ExternalRuntime.cpp b/simulator/app/ExternalRuntime.cpp deleted file mode 100644 index 9f2cc5e31..000000000 --- a/simulator/app/ExternalRuntime.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Management of the simulated device. -// - -// For compilers that support precompilation, include "wx/wx.h". -#include "wx/wxprec.h" - -// Otherwise, include all standard headers -#ifndef WX_PRECOMP -# include "wx/wx.h" -#endif -#include "wx/image.h" - -#include "ExternalRuntime.h" -#include "MyApp.h" -#include "UserEvent.h" -#include "UserEventMessage.h" - -#include "SimRuntime.h" -#include "LocalBiChannel.h" -#include "utils.h" - - -using namespace android; - -/* - * Destructor. - */ -ExternalRuntime::~ExternalRuntime(void) -{ - if (IsRunning()) { - // TODO: cause thread to stop, then Wait for it - } - printf("Sim: in ~ExternalRuntime()\n"); -} - -/* - * Create and run the thread. - */ -bool ExternalRuntime::StartThread(void) -{ - if (Create() != wxTHREAD_NO_ERROR) { - fprintf(stderr, "Sim: ERROR: can't create ExternalRuntime thread\n"); - return false; - } - - Run(); - return true; -} - -/* - * Thread entry point. - * - * This just sits and waits for a new connection. It hands it off to the - * main thread and then goes back to waiting. - * - * There is currently no "polite" way to shut this down. - */ -void* ExternalRuntime::Entry(void) -{ - LocalBiChannel lbic; - Pipe* reader; - Pipe* writer; - - reader = writer = NULL; - - if (!lbic.create(ANDROID_PIPE_NAME)) { - fprintf(stderr, "Sim: failed creating named pipe '%s'\n", - ANDROID_PIPE_NAME); - return NULL; - } - - while (lbic.listen(&reader, &writer)) { - /* - * Throw it over the wall. - */ - wxWindow* pMainFrame = ((MyApp*)wxTheApp)->GetMainFrame(); - - UserEventMessage* pUem = new UserEventMessage; - pUem->CreateExternalRuntime(reader, writer); - - UserEvent uev(0, (void*) pUem); - pMainFrame->AddPendingEvent(uev); - - reader = writer = NULL; - } - - printf("Sim: ExternalRuntime thread wants to bail\n"); - - return NULL; -} - diff --git a/simulator/app/ExternalRuntime.h b/simulator/app/ExternalRuntime.h deleted file mode 100644 index 774a2cd98..000000000 --- a/simulator/app/ExternalRuntime.h +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Class that manages the simulated device. -// -#ifndef _SIM_EXTERNAL_RUNTIME_H -#define _SIM_EXTERNAL_RUNTIME_H - -/* - * Define a thread that listens for the launch of an external runtime. - * When we spot one we notify the main thread, which can choose to - * accept or reject it. - */ -class ExternalRuntime : public wxThread { -public: - ExternalRuntime(void) {} - virtual ~ExternalRuntime(void); - - /* start the thread running */ - bool StartThread(void); - - /* thread entry point */ - virtual void* Entry(void); -}; - -#endif // _SIM_EXTERNAL_RUNTIME_H diff --git a/simulator/app/LinuxKeys.h b/simulator/app/LinuxKeys.h deleted file mode 100644 index 6382de9e4..000000000 --- a/simulator/app/LinuxKeys.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef _SIM_LINUXKEYS_H -#define _SIM_LINUXKEYS_H - -#include <linux/input.h> - -/* ubuntu has these, goobuntu doesn't */ -#ifndef KEY_SWITCHVIDEOMODE -# define KEY_SWITCHVIDEOMODE 227 -#endif -#ifndef KEY_KBDILLUMTOGGLE -# define KEY_KBDILLUMTOGGLE 228 -#endif -#ifndef KEY_KBDILLUMUP -# define KEY_KBDILLUMUP 230 -#endif -#ifndef KEY_REPLY -# define KEY_REPLY 232 -#endif - -#endif /*_SIM_LINUXKEYS_H*/ diff --git a/simulator/app/LoadableImage.cpp b/simulator/app/LoadableImage.cpp deleted file mode 100644 index e5bd0f3e2..000000000 --- a/simulator/app/LoadableImage.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Simple class to hold an image that can be loaded and unloaded. -// - -// For compilers that support precompilation, include "wx/wx.h". -#include "wx/wxprec.h" - -// Otherwise, include all standard headers -#ifndef WX_PRECOMP -# include "wx/wx.h" -#endif -#include "wx/image.h" // needed for Windows build - -#include "LoadableImage.h" -#include "AssetStream.h" -#include "MyApp.h" - -#include <utils.h> - -#include <stdio.h> - - -/* - * Load the image. - */ -bool LoadableImage::Create(const char* fileName, int x, int y) -{ - if (fileName == NULL || x < 0 || y < 0) { - fprintf(stderr, "bad params to %s\n", __PRETTY_FUNCTION__); - return false; - } - - delete[] mName; - mName = android::strdupNew(fileName); - - mX = x; - mY = y; - - return true; -} - -/* - * Load the bitmap. - */ -bool LoadableImage::LoadResources(void) -{ - if (mName == NULL) - return false; - - if (mpBitmap != NULL) // already loaded? - return true; - - //printf("LoadResources: '%s'\n", (const char*) mName); -#ifdef BEFORE_ASSET - wxImage img(mName); -#else - android::AssetManager* pAssetMgr = ((MyApp*)wxTheApp)->GetAssetManager(); - android::Asset* pAsset; - - pAsset = pAssetMgr->open(mName, android::Asset::ACCESS_RANDOM); - if (pAsset == NULL) { - fprintf(stderr, "ERROR: unable to load '%s'\n", mName); - return false; - } else { - //printf("--- opened asset '%s'\n", - // (const char*) pAsset->getAssetSource()); - } - AssetStream astr(pAsset); - - wxImage img(astr); -#endif - - mWidth = img.GetWidth(); - mHeight = img.GetHeight(); - if (mWidth <= 0 || mHeight <= 0) { - /* image failed to load or decode */ - fprintf(stderr, "ERROR: unable to load/decode '%s'\n", mName); - //delete img; - return false; - } - - mpBitmap = new wxBitmap(img); - - //delete img; - - return true; -} - -/* - * Unload the bitmap. - */ -bool LoadableImage::UnloadResources(void) -{ - delete mpBitmap; - mpBitmap = NULL; - return true; -} - diff --git a/simulator/app/LoadableImage.h b/simulator/app/LoadableImage.h deleted file mode 100644 index 368d520bf..000000000 --- a/simulator/app/LoadableImage.h +++ /dev/null @@ -1,73 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Simulated device definition. -// -#ifndef _SIM_LOADABLE_IMAGE_H -#define _SIM_LOADABLE_IMAGE_H - -#include "utils.h" - -/* - * Holds an image that may or may not be loaded at present. The image - * has an (x,y) offset. - */ -class LoadableImage { -public: - LoadableImage(void) - : mName(NULL), mpBitmap(NULL), mX(-1), mY(-1), mWidth(-1), mHeight(-1) - {} - virtual ~LoadableImage(void) { - delete[] mName; - delete mpBitmap; - } - LoadableImage(const LoadableImage& src) - : mName(NULL), mpBitmap(NULL) - { - CopyMembers(src); - } - LoadableImage& operator=(const LoadableImage& src) { - if (this != &src) // self-assignment - CopyMembers(src); - return *this; - } - void CopyMembers(const LoadableImage& src) { - // Need to delete resources in case we're using operator= and - // assigning into an object that already holds some. - delete mName; - delete mpBitmap; - mName = android::strdupNew(src.mName); - if (src.mpBitmap == NULL) - mpBitmap = NULL; - else - mpBitmap = new wxBitmap(*(src.mpBitmap)); - mX = src.mX; - mY = src.mY; - mWidth = src.mWidth; - mHeight = src.mHeight; - } - - virtual bool Create(const char* fileName, int x, int y); - - // load or unload the bitmap - bool LoadResources(void); - bool UnloadResources(void); - - // accessors - int GetX(void) const { return mX; } - int GetY(void) const { return mY; } - int GetWidth(void) const { return mWidth; } - int GetHeight(void) const { return mHeight; } - wxBitmap* GetBitmap(void) const { return mpBitmap; } - -private: - char* mName; - wxBitmap* mpBitmap; - - int mX; // position relative to phone image - int mY; - int mWidth; // from image (cached values) - int mHeight; -}; - -#endif // _SIM_LOADABLE_IMAGE_H diff --git a/simulator/app/LocalBiChannel.cpp b/simulator/app/LocalBiChannel.cpp deleted file mode 100644 index 93a997d45..000000000 --- a/simulator/app/LocalBiChannel.cpp +++ /dev/null @@ -1,444 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Local named bi-directional communication channel. -// -#include "LocalBiChannel.h" -#include "utils/Log.h" - -#if defined(HAVE_WIN32_IPC) -# define _WIN32_WINNT 0x0500 -# include <windows.h> -#else -# include <sys/types.h> -# include <sys/socket.h> -# include <sys/stat.h> -# include <sys/un.h> -#endif - -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <assert.h> - -#ifndef SUN_LEN -/* - * Our current set of ARM header files don't define this. - */ -# define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \ - + strlen ((ptr)->sun_path)) -#endif - -using namespace android; - -const unsigned long kInvalidHandle = (unsigned long) -1; - -/* - * Initialize data fields. - */ -LocalBiChannel::LocalBiChannel(void) - : mFileName(NULL), mIsListener(false), mHandle(kInvalidHandle) -{ -} - -#if defined(HAVE_WIN32_IPC) -/* - * Implementation for Win32, using named pipes. - * - * Cygwin actually supports UNIX-domain sockets, but we want to stuff - * the file handles into a Pipe, which uses HANDLE under Win32. - */ - -const int kPipeSize = 4096; - -/* - * Destructor. If we're the server side, we may need to clean up after - * ourselves. - */ -LocalBiChannel::~LocalBiChannel(void) -{ - if (mHandle != kInvalidHandle) - CloseHandle((HANDLE)mHandle); - - delete[] mFileName; -} - -/* - * Construct the full path. The caller must delete[] the return value. - */ -static char* makeFilename(const char* name) -{ - static const char* kBasePath = "\\\\.\\pipe\\android-"; - char* fileName; - - assert(name != NULL && name[0] != '\0'); - - fileName = new char[strlen(kBasePath) + strlen(name) + 1]; - strcpy(fileName, kBasePath); - strcat(fileName, name); - - return fileName; -} - -/* - * Create a named pipe, so the client has something to connect to. - */ -bool LocalBiChannel::create(const char* name) -{ - delete[] mFileName; - mFileName = makeFilename(name); - -#if 0 - HANDLE hPipe; - - hPipe = CreateNamedPipe( - mFileName, // unique pipe name - PIPE_ACCESS_DUPLEX | // open mode - FILE_FLAG_FIRST_PIPE_INSTANCE, - 0, // pipe mode (byte, blocking) - 1, // max instances - kPipeSize, // output buffer - kPipeSize, // input buffer - NMPWAIT_USE_DEFAULT_WAIT, // client time-out - NULL); // security - - if (hPipe == 0) { - LOG(LOG_ERROR, "lbicomm", - "CreateNamedPipe failed (err=%ld)\n", GetLastError()); - return false; - } - - mHandle = (unsigned long) hPipe; -#endif - - return true; -} - -/* - * Attach to an existing named pipe. - */ -bool LocalBiChannel::attach(const char* name, Pipe** ppReadPipe, - Pipe** ppWritePipe) -{ - HANDLE hPipe, dupHandle; - - delete[] mFileName; - mFileName = makeFilename(name); - - hPipe = CreateFile( - mFileName, // filename - GENERIC_READ | GENERIC_WRITE, // access - 0, // no sharing - NULL, // security - OPEN_EXISTING, // don't create - 0, // attributes - NULL); // template - if (hPipe == INVALID_HANDLE_VALUE) { - LOG(LOG_ERROR, "lbicomm", - "CreateFile on pipe '%s' failed (err=%ld)\n", name, GetLastError()); - return false; - } - - assert(mHandle == kInvalidHandle); - - /* - * Set up the pipes. Use the new handle for one, and a duplicate - * of it for the other, in case we decide to only close one side. - */ - *ppReadPipe = new Pipe(); - (*ppReadPipe)->createReader((unsigned long) hPipe); - - DuplicateHandle( - GetCurrentProcess(), - hPipe, - GetCurrentProcess(), - &dupHandle, - 0, - FALSE, - DUPLICATE_SAME_ACCESS); - *ppWritePipe = new Pipe(); - (*ppWritePipe)->createWriter((unsigned long) dupHandle); - - return true; -} - -/* - * Listen for a new connection, discarding any existing connection. - */ -bool LocalBiChannel::listen(Pipe** ppReadPipe, Pipe** ppWritePipe) -{ - BOOL connected; - HANDLE hPipe; - - /* - * Create up to 3 instances of the named pipe: - * - currently active connection - * - connection currently being rejected because one is already active - * - a new listener to wait for the next round - */ - hPipe = CreateNamedPipe( - mFileName, // unique pipe name - PIPE_ACCESS_DUPLEX // open mode - /*| FILE_FLAG_FIRST_PIPE_INSTANCE*/, - 0, // pipe mode (byte, blocking) - 3, // max instances - kPipeSize, // output buffer - kPipeSize, // input buffer - NMPWAIT_USE_DEFAULT_WAIT, // client time-out - NULL); // security - - if (hPipe == 0) { - LOG(LOG_ERROR, "lbicomm", - "CreateNamedPipe failed (err=%ld)\n", GetLastError()); - return false; - } - - /* - * If a client is already connected to us, this fails with - * ERROR_PIPE_CONNECTED. It returns success if we had to wait - * a little bit before the connection happens. - */ - connected = ConnectNamedPipe(hPipe, NULL) ? - TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); - - if (connected) { - /* - * Create the pipes. Give one a duplicated handle so that, - * when one closes, we don't lose both. - */ - HANDLE dupHandle; - - *ppReadPipe = new Pipe(); - (*ppReadPipe)->createReader((unsigned long) hPipe); - - DuplicateHandle( - GetCurrentProcess(), - hPipe, - GetCurrentProcess(), - &dupHandle, - 0, - FALSE, - DUPLICATE_SAME_ACCESS); - *ppWritePipe = new Pipe(); - (*ppWritePipe)->createWriter((unsigned long) dupHandle); - - return true; - } else { - LOG(LOG_WARN, "lbicomm", - "ConnectNamedPipe failed (err=%ld)\n", GetLastError()); -#ifdef HAVE_WIN32_THREADS - Sleep(500); /* 500 ms */ -#else - usleep(500000); // DEBUG DEBUG -#endif - return false; - } -} - -#else - -/* - * Implementation for Linux and Darwin, using UNIX-domain sockets. - */ - -/* - * Destructor. If we're the server side, blow away the socket file. - */ -LocalBiChannel::~LocalBiChannel(void) -{ - if (mHandle != kInvalidHandle) - close((int) mHandle); - - if (mIsListener && mFileName != NULL) { - LOG(LOG_DEBUG, "lbicomm", "Removing '%s'\n", mFileName); - (void) unlink(mFileName); - } - delete[] mFileName; -} - -/* - * Construct the full path. The caller must delete[] the return value. - */ -static char* makeFilename(const char* name) -{ - static const char* kBasePath = "/tmp/android-"; - char* fileName; - - assert(name != NULL && name[0] != '\0'); - - fileName = new char[strlen(kBasePath) + strlen(name) + 1]; - strcpy(fileName, kBasePath); - strcat(fileName, name); - - return fileName; -} - -/* - * Create a UNIX domain socket, carefully removing it if it already - * exists. - */ -bool LocalBiChannel::create(const char* name) -{ - struct stat sb; - bool result = false; - int sock = -1; - int cc; - - delete[] mFileName; - mFileName = makeFilename(name); - - cc = stat(mFileName, &sb); - if (cc < 0) { - if (errno != ENOENT) { - LOG(LOG_ERROR, "lbicomm", - "Unable to stat '%s' (errno=%d)\n", mFileName, errno); - goto bail; - } - } else { - /* don't touch it if it's not a socket */ - if (!(S_ISSOCK(sb.st_mode))) { - LOG(LOG_ERROR, "lbicomm", - "File '%s' exists and is not a socket\n", mFileName); - goto bail; - } - - /* remove the cruft */ - if (unlink(mFileName) < 0) { - LOG(LOG_ERROR, "lbicomm", - "Unable to remove '%s' (errno=%d)\n", mFileName, errno); - goto bail; - } - } - - struct sockaddr_un addr; - - sock = ::socket(AF_UNIX, SOCK_STREAM, 0); - if (sock < 0) { - LOG(LOG_ERROR, "lbicomm", - "UNIX domain socket create failed (errno=%d)\n", errno); - goto bail; - } - - /* bind the socket; this creates the file on disk */ - strcpy(addr.sun_path, mFileName); // max 108 bytes - addr.sun_family = AF_UNIX; - cc = ::bind(sock, (struct sockaddr*) &addr, SUN_LEN(&addr)); - if (cc < 0) { - LOG(LOG_ERROR, "lbicomm", - "AF_UNIX bind failed for '%s' (errno=%d)\n", mFileName, errno); - goto bail; - } - - mHandle = (unsigned long) sock; - sock = -1; - mIsListener = true; - result = true; - -bail: - if (sock >= 0) - close(sock); - return result; -} - -/* - * Attach to an existing UNIX domain socket. - */ -bool LocalBiChannel::attach(const char* name, Pipe** ppReadPipe, - Pipe** ppWritePipe) -{ - bool result = false; - int sock = -1; - int cc; - - assert(ppReadPipe != NULL); - assert(ppWritePipe != NULL); - - delete[] mFileName; - mFileName = makeFilename(name); - - struct sockaddr_un addr; - - sock = ::socket(AF_UNIX, SOCK_STREAM, 0); - if (sock < 0) { - LOG(LOG_ERROR, "lbicomm", - "UNIX domain socket create failed (errno=%d)\n", errno); - goto bail; - } - - /* connect to socket; fails if file doesn't exist */ - strcpy(addr.sun_path, mFileName); // max 108 bytes - addr.sun_family = AF_UNIX; - cc = ::connect(sock, (struct sockaddr*) &addr, SUN_LEN(&addr)); - if (cc < 0) { - // ENOENT means socket file doesn't exist - // ECONNREFUSED means socket exists but nobody is listening - LOG(LOG_ERROR, "lbicomm", - "AF_UNIX connect failed for '%s': %s\n", mFileName,strerror(errno)); - goto bail; - } - - /* - * Create the two halves. We dup() the sock so that closing one side - * does not hose the other. - */ - *ppReadPipe = new Pipe(); - (*ppReadPipe)->createReader(sock); - *ppWritePipe = new Pipe(); - (*ppWritePipe)->createWriter(dup(sock)); - - assert(mHandle == kInvalidHandle); - sock = -1; - mIsListener = false; - - result = true; - -bail: - if (sock >= 0) - close(sock); - return result; -} - -/* - * Listen for a new connection. - */ -bool LocalBiChannel::listen(Pipe** ppReadPipe, Pipe** ppWritePipe) -{ - bool result = false; - struct sockaddr_un from; - socklen_t fromlen; - int sock, lsock; - int cc; - - assert(mHandle != kInvalidHandle); - lsock = (int) mHandle; - - LOG(LOG_DEBUG, "lbicomm", "AF_UNIX listening\n"); - cc = ::listen(lsock, 5); - if (cc < 0) { - LOG(LOG_ERROR, "lbicomm", "AF_UNIX listen failed (errno=%d)\n", errno); - goto bail; - } - - fromlen = sizeof(from); // not SUN_LEN() - sock = ::accept(lsock, (struct sockaddr*) &from, &fromlen); - if (sock < 0) { - LOG(LOG_WARN, "lbicomm", "AF_UNIX accept failed (errno=%d)\n", errno); - goto bail; - } - - /* - * Create the two halves. We dup() the sock so that closing one side - * does not hose the other. - */ - *ppReadPipe = new Pipe(); - (*ppReadPipe)->createReader(sock); - *ppWritePipe = new Pipe(); - (*ppWritePipe)->createWriter(dup(sock)); - result = true; - -bail: - return result; -} - -#endif diff --git a/simulator/app/LocalBiChannel.h b/simulator/app/LocalBiChannel.h deleted file mode 100644 index ce04bc0e0..000000000 --- a/simulator/app/LocalBiChannel.h +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Create or attach to a named bi-directional channel on the local machine. -// -#ifndef __LIBS_LOCALBICHANNEL_H -#define __LIBS_LOCALBICHANNEL_H - -#ifdef HAVE_ANDROID_OS -#error DO NOT USE THIS FILE IN THE DEVICE BUILD -#endif - -#include <utils/Pipe.h> - -namespace android { - -/* - * This is essentially a wrapper class for UNIX-domain sockets. The - * idea is to set one up with create() or attach to one with attach() - * and then extract the unidirectional read/write Pipes. These can - * be used directly or stuffed into a MessageStream. - * - * The name for the pipe should be a short filename made up of alphanumeric - * characters. Depending on the implementation, we may create a file in - * /tmp with the specified name, removing any existing copy. - */ -class LocalBiChannel { -public: - LocalBiChannel(void); - ~LocalBiChannel(void); - - /* create the "listen" side */ - bool create(const char* name); - - /* - * Listen for a connection. When we get one, we create unidirectional - * read/write pipes and return them. - */ - bool listen(Pipe** ppReadPipe, Pipe** ppWritePipe); - - /* - * Attach to a channel created by somebody else. Returns pipes. - */ - bool attach(const char* name, Pipe** ppReadPipe, Pipe** ppWritePipe); - -private: - char* mFileName; - bool mIsListener; - unsigned long mHandle; -}; - -}; // namespace android - -#endif // __LIBS_LOCALBICHANNEL_H diff --git a/simulator/app/LogBundle.h b/simulator/app/LogBundle.h deleted file mode 100644 index 2cba97bc5..000000000 --- a/simulator/app/LogBundle.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef _SIM_LOG_BUNDLE_H -#define _SIM_LOG_BUNDLE_H - -#ifdef HAVE_PTHREADS -#include <pthread.h> -#endif -#include <cutils/logd.h> // for android_LogPriority. - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct android_LogBundle { - time_t when; - android_LogPriority priority; - pid_t pid; -#ifndef HAVE_PTHREADS - unsigned tid; -#else - pthread_t tid; -#endif - const char* tag; - const struct iovec* msgVec; - size_t msgCount; - int fd; -} android_LogBundle; - -#ifdef __cplusplus -} -#endif - -#endif // _SIM_LOG_BUNDLE_H diff --git a/simulator/app/LogMessage.cpp b/simulator/app/LogMessage.cpp deleted file mode 100644 index 63cb76445..000000000 --- a/simulator/app/LogMessage.cpp +++ /dev/null @@ -1,98 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Hold a single log message. -// -#include "LogMessage.h" -#include <assert.h> - -/* - * Constructor. - * - * Initializers here aren't necessary, since we can only create one of - * these through Create(), which touches every field. - */ -LogMessage::LogMessage(void) -{ -} - -/* - * Destructor. - */ -LogMessage::~LogMessage(void) -{ - delete[] mTag; - delete[] mMsg; -} - -/* - * Create a new LogMessage object, and populate it with the contents of - * "*pBundle". - */ -/*static*/ LogMessage* LogMessage::Create(const android_LogBundle* pBundle) -{ - LogMessage* newMsg = new LogMessage; - - if (newMsg == NULL) - return NULL; - assert(pBundle != NULL); - - newMsg->mWhen = pBundle->when; - newMsg->mPriority = pBundle->priority; - newMsg->mPid = pBundle->pid; - newMsg->mTag = android::strdupNew(pBundle->tag); - - size_t len = 0; - size_t i; - for (i=0; i<pBundle->msgCount; i++) len += pBundle->msgVec[i].iov_len; - newMsg->mMsg = new char[len+1]; - char* p = newMsg->mMsg; - for (i=0; i<pBundle->msgCount; i++) { - memcpy(p, pBundle->msgVec[i].iov_base, pBundle->msgVec[i].iov_len); - p += pBundle->msgVec[i].iov_len; - } - *p = 0; - - newMsg->mRefCnt = 1; - newMsg->mInternal = false; - newMsg->mFootprint = 8 * sizeof(int) + strlen(newMsg->mTag) + - strlen(newMsg->mMsg) + 4; - newMsg->mTextCtrlLen = 0; - newMsg->mpPrev = NULL; - newMsg->mpNext = NULL; - - return newMsg; -} - -/* - * Create a new LogMessage object, with a simple message in it. - * - * Sets "mInternal" so we display it appropriately. - */ -/*static*/ LogMessage* LogMessage::Create(const char* msg) -{ - LogMessage* newMsg; - android_LogBundle bundle; - - assert(msg != NULL); - - memset(&bundle, 0, sizeof(bundle)); - bundle.when = time(NULL); - bundle.priority = ANDROID_LOG_ERROR; - bundle.pid = getpid(); - bundle.tag = "-"; - iovec iov; - iov.iov_base = (void*)msg; - iov.iov_len = strlen(msg); - bundle.msgVec = &iov; - bundle.msgCount = 1; - - newMsg = Create(&bundle); - - if (newMsg != NULL) { - newMsg->mInternal = true; - } - - return newMsg; -} - diff --git a/simulator/app/LogMessage.h b/simulator/app/LogMessage.h deleted file mode 100644 index fe77dc0aa..000000000 --- a/simulator/app/LogMessage.h +++ /dev/null @@ -1,73 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Class to hold a single log message. Not thread safe. -// -#ifndef _SIM_LOG_MESSAGE_H -#define _SIM_LOG_MESSAGE_H - -#include "utils.h" -#include "LogBundle.h" - -/* - * Hold a single log message. - * - * To reduce malloc strain we could over-allocate the object and tuck the - * message text into the object storage. On this off chance this becomes - * important, the implementation keeps its constructor private. - */ -class LogMessage { -public: - ~LogMessage(void); - - static LogMessage* Create(const android_LogBundle* pBundle); - static LogMessage* Create(const char* msg); - - /* the total length of text added to the text ctrl */ - int GetTextCtrlLen(void) const { return mTextCtrlLen; } - void SetTextCtrlLen(int len) { mTextCtrlLen = len; } - - /* log pool */ - LogMessage* GetPrev(void) const { return mpPrev; } - void SetPrev(LogMessage* pPrev) { mpPrev = pPrev; } - LogMessage* GetNext(void) const { return mpNext; } - void SetNext(LogMessage* pNext) { mpNext = pNext; } - int GetFootprint(void) const { return mFootprint; } - - /* message contents */ - time_t GetWhen(void) const { return mWhen; } - android_LogPriority GetPriority(void) const { return mPriority; } - pid_t GetPid(void) const { return mPid; } - const char* GetTag(void) const { return mTag; } - const char* GetMsg(void) const { return mMsg; } - - bool GetInternal(void) const { return mInternal; } - - void Acquire(void) { mRefCnt++; } - void Release(void) { - if (!--mRefCnt) - delete this; - } - -private: - LogMessage(void); - LogMessage(const LogMessage& src); // not implemented - LogMessage& operator=(const LogMessage& src); // not implemented - - /* log message contents */ - time_t mWhen; - android_LogPriority mPriority; - pid_t mPid; - char* mTag; - char* mMsg; - - /* additional goodies */ - int mRefCnt; // reference count - bool mInternal; // message generated internally by us? - int mFootprint; // approx. size of this object in memory - int mTextCtrlLen; // #of characters req'd in text ctrl - LogMessage* mpPrev; // link to previous item in log pool - LogMessage* mpNext; // link to next item in log pool -}; - -#endif // _SIM_LOG_MESSAGE_H diff --git a/simulator/app/LogPool.cpp b/simulator/app/LogPool.cpp deleted file mode 100644 index 43bf4be7f..000000000 --- a/simulator/app/LogPool.cpp +++ /dev/null @@ -1,90 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Hold a collection of log messages, limiting ourselves to a certain -// fixed maximum amount of memory. -// -#include "LogPool.h" -#include <assert.h> - - -/* - * Add a message at the head of the pool. - */ -void LogPool::Add(LogMessage* pLogMessage) -{ - pLogMessage->Acquire(); // bump up the ref count - - assert(pLogMessage->GetPrev() == NULL); - assert(pLogMessage->GetNext() == NULL); - - if (mpHead == NULL) { - assert(mpTail == NULL); - mpTail = mpHead = pLogMessage; - } else { - assert(mpHead->GetPrev() == NULL); - mpHead->SetPrev(pLogMessage); - pLogMessage->SetNext(mpHead); - mpHead = pLogMessage; - } - - /* update the pool size, and remove old entries if necessary */ - mCurrentSize += pLogMessage->GetFootprint(); - - while (mCurrentSize > mMaxSize) - RemoveOldest(); -} - -/* - * Remove the oldest message (from the tail of the list). - */ -void LogPool::RemoveOldest(void) -{ - LogMessage* pPrev; - - if (mpTail == NULL) { - fprintf(stderr, "HEY: nothing left to remove (cur=%ld)\n", - mCurrentSize); - assert(false); - return; - } - - if (mpTail == mpBookmark) - mpBookmark = NULL; - - //printf("--- removing oldest, size %ld->%ld (%s)\n", - // mCurrentSize, mCurrentSize - mpTail->GetFootprint(),mpTail->GetMsg()); - mCurrentSize -= mpTail->GetFootprint(); - - pPrev = mpTail->GetPrev(); - mpTail->Release(); - mpTail = pPrev; - if (mpTail == NULL) { - //printf("--- pool is now empty (size=%ld)\n", mCurrentSize); - mpHead = NULL; - } else { - mpTail->SetNext(NULL); - } -} - -/* - * Resize the log pool. - */ -void LogPool::Resize(long maxSize) -{ - assert(maxSize >= 0); - - mMaxSize = maxSize; - while (mCurrentSize > mMaxSize) - RemoveOldest(); -} - -/* - * Remove all entries. - */ -void LogPool::Clear(void) -{ - while (mpTail != NULL) - RemoveOldest(); -} - diff --git a/simulator/app/LogPool.h b/simulator/app/LogPool.h deleted file mode 100644 index b824fec1c..000000000 --- a/simulator/app/LogPool.h +++ /dev/null @@ -1,56 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Pool of log messages. Not thread safe -- operations on the log pool -// should only happen in the main UI thread. -// -#ifndef _SIM_LOG_POOL_H -#define _SIM_LOG_POOL_H - -#include "LogMessage.h" - -/* - * This contains the pool of log messages. The messages themselves are - * allocated individually and reference counted. We add new messages to - * the head and, when the total "footprint" exceeds our stated max, we - * delete one or more from the tail. - * - * To support pause/resume, we allow a "bookmark" to be set. This is - * just a pointer to a message in the pool. If the bookmarked message - * is deleted, we discard the bookmark. - */ -class LogPool { -public: - LogPool(void) - : mpHead(NULL), mpTail(NULL), mpBookmark(NULL), - mCurrentSize(0), mMaxSize(10240) - {} - ~LogPool(void) { Clear(); } - - void Clear(void); - - /* add a new message to the pool */ - void Add(LogMessage* pLogMessage); - - /* resize the pool, removing excess messages */ - void Resize(long maxSize); - - /* return the current limit, in bytes */ - long GetMaxSize(void) const { return mMaxSize; } - - LogMessage* GetHead(void) const { return mpHead; } - - void SetBookmark(void) { mpBookmark = mpHead; } - LogMessage* GetBookmark(void) const { return mpBookmark; } - -private: - void RemoveOldest(void); - - LogMessage* mpHead; - LogMessage* mpTail; - LogMessage* mpBookmark; - long mCurrentSize; // current size, in bytes - long mMaxSize; // maximum size, in bytes -}; - -#endif // _SIM_LOG_POOL_H diff --git a/simulator/app/LogPrefsDialog.cpp b/simulator/app/LogPrefsDialog.cpp deleted file mode 100644 index dc3e07c5f..000000000 --- a/simulator/app/LogPrefsDialog.cpp +++ /dev/null @@ -1,404 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Log preferences modal dialog. -// - -// For compilers that support precompilation, include "wx/wx.h". -#include "wx/wxprec.h" -// Otherwise, include all standard headers -#ifndef WX_PRECOMP -# include "wx/wx.h" -#endif - -#include "LogPrefsDialog.h" -#include "Preferences.h" -#include "Resource.h" -#include "utils.h" - -BEGIN_EVENT_TABLE(LogPrefsDialog, wxDialog) - EVT_CHECKBOX(IDC_LOG_PREFS_WRITE_FILE, LogPrefsDialog::OnWriteFile) -END_EVENT_TABLE() - -static const wxString gSpacerChoices[] = { - wxT("0"), wxT("1"), wxT("2") -}; -static const wxString gPointSizes[] = { - wxT("4"), wxT("6"), wxT("8"), wxT("10"), wxT("12"), wxT("14"), wxT("16") -}; - - -/* - * Constructor. - */ -LogPrefsDialog::LogPrefsDialog(wxWindow* parent) - : wxDialog(parent, IDD_LOG_PREFS, wxT("Log Preferences"), wxDefaultPosition, - wxDefaultSize, wxDEFAULT_DIALOG_STYLE), - mHeaderFormat(kHFFull), mSingleLine(false), mExtraSpacing(0), - mUseColor(false), mFontMonospace(false), mDisplayMax(0), mPoolSizeKB(0) -{ - CreateControls(); -} - - -/* - * Destructor. Not much to do. - */ -LogPrefsDialog::~LogPrefsDialog(void) -{ -} - -/* - * Create all of the pages and add them to the notebook. - */ -void LogPrefsDialog::CreateControls(void) -{ - wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL); - wxBoxSizer* okCancelSizer = new wxBoxSizer(wxHORIZONTAL); - mNotebook.Create(this, wxID_ANY); - wxPanel* page; - - page = CreateFormatPage(&mNotebook); - mNotebook.AddPage(page, wxT("Format"), true); - page = CreateLimitsPage(&mNotebook); - mNotebook.AddPage(page, wxT("Limits"), false); - page = CreateFilesPage(&mNotebook); - mNotebook.AddPage(page, wxT("Files"), false); - - // note to self: could use CreateButtonSizer here? - wxButton* cancel = new wxButton(this, wxID_CANCEL, wxT("&Cancel"), - wxDefaultPosition, wxDefaultSize, 0); - okCancelSizer->Add(cancel, 0, wxALL, kInterSpacing); - - wxButton* ok = new wxButton(this, wxID_OK, wxT("&OK"), - wxDefaultPosition, wxDefaultSize, 0); - okCancelSizer->Add(ok, 0, wxALL, kInterSpacing); - - mainSizer->Add(&mNotebook); - mainSizer->Add(okCancelSizer, 0, wxALIGN_RIGHT); - - SetSizer(mainSizer); - - mainSizer->Fit(this); // shrink-to-fit - mainSizer->SetSizeHints(this); // define minimum size -} - -/* - * Transfer data from our members to the window controls. - */ -bool LogPrefsDialog::TransferDataToWindow(void) -{ - /* - * Do standard dialog setup. - */ - wxRadioButton* fmtFull = (wxRadioButton*) FindWindow(IDC_LOG_PREFS_FMT_FULL); - wxRadioButton* fmtBrief = (wxRadioButton*) FindWindow(IDC_LOG_PREFS_FMT_BRIEF); - wxRadioButton* fmtMinimal = (wxRadioButton*) FindWindow(IDC_LOG_PREFS_FMT_MINIMAL); - wxCheckBox* singleLine = (wxCheckBox*) FindWindow(IDC_LOG_PREFS_SINGLE_LINE); - wxComboBox* extraSpacing = (wxComboBox*) FindWindow(IDC_LOG_PREFS_EXTRA_SPACING); - wxComboBox* pointSize = (wxComboBox*) FindWindow(IDC_LOG_PREFS_POINT_SIZE); - wxCheckBox* useColor = (wxCheckBox*) FindWindow(IDC_LOG_PREFS_USE_COLOR); - wxCheckBox* fontMono = (wxCheckBox*) FindWindow(IDC_LOG_PREFS_FONT_MONO); - // - - wxTextCtrl* displayMax = (wxTextCtrl*) FindWindow(IDC_LOG_PREFS_DISPLAY_MAX); - wxTextCtrl* poolSize = (wxTextCtrl*) FindWindow(IDC_LOG_PREFS_POOL_SIZE); - // - - wxCheckBox* writeFile = (wxCheckBox*) FindWindow(IDC_LOG_PREFS_WRITE_FILE); - wxTextCtrl* fileName = (wxTextCtrl*) FindWindow(IDC_LOG_PREFS_FILENAME); - wxCheckBox* truncateOld = (wxCheckBox*) FindWindow(IDC_LOG_PREFS_TRUNCATE_OLD); - // - - - fmtFull->SetValue(mHeaderFormat == kHFFull); - fmtBrief->SetValue(mHeaderFormat == kHFBrief); - fmtMinimal->SetValue(mHeaderFormat == kHFMinimal); - singleLine->SetValue(mSingleLine); - if (mExtraSpacing < 0 || mExtraSpacing > NELEM(gSpacerChoices)) - mExtraSpacing = 0; - extraSpacing->SetSelection(mExtraSpacing); - - pointSize->SetSelection(0); - for (int i = 0; i < NELEM(gPointSizes); i++) { - if (atoi(gPointSizes[i].ToAscii()) == mPointSize) { - pointSize->SetSelection(i); - break; - } - } - useColor->SetValue(mUseColor); - fontMono->SetValue(mFontMonospace); - - wxString tmpStr; - tmpStr.Printf(wxT("%d"), mDisplayMax); - displayMax->SetValue(tmpStr); - tmpStr.Printf(wxT("%d"), mPoolSizeKB); - poolSize->SetValue(tmpStr); - - writeFile->SetValue(mWriteFile); - fileName->SetValue(mFileName); - truncateOld->SetValue(mTruncateOld); - - EnableFileControls(mWriteFile); - - return true; -} - -/* - * Convert a string to a number. The number is expected to be unsigned. - * Returns < 0 on failure. - */ -static long ConvertUnsigned(const wxString& str) -{ - long val; - if (!str.ToLong(&val)) - return -1; - return val; -} - -/* - * Transfer and validate data from the window controls. - * - * This doesn't get called if the user cancels out of the dialog. - */ -bool LogPrefsDialog::TransferDataFromWindow(void) -{ - /* - * Do standard dialog export. - */ - //wxRadioButton* fmtFull = (wxRadioButton*) FindWindow(IDC_LOG_PREFS_FMT_FULL); - wxRadioButton* fmtBrief = (wxRadioButton*) FindWindow(IDC_LOG_PREFS_FMT_BRIEF); - wxRadioButton* fmtMinimal = (wxRadioButton*) FindWindow(IDC_LOG_PREFS_FMT_MINIMAL); - wxCheckBox* singleLine = (wxCheckBox*) FindWindow(IDC_LOG_PREFS_SINGLE_LINE); - wxComboBox* extraSpacing = (wxComboBox*) FindWindow(IDC_LOG_PREFS_EXTRA_SPACING); - wxComboBox* pointSize = (wxComboBox*) FindWindow(IDC_LOG_PREFS_POINT_SIZE); - wxCheckBox* useColor = (wxCheckBox*) FindWindow(IDC_LOG_PREFS_USE_COLOR); - wxCheckBox* fontMono = (wxCheckBox*) FindWindow(IDC_LOG_PREFS_FONT_MONO); - // - - wxTextCtrl* displayMax = (wxTextCtrl*) FindWindow(IDC_LOG_PREFS_DISPLAY_MAX); - wxTextCtrl* poolSize = (wxTextCtrl*) FindWindow(IDC_LOG_PREFS_POOL_SIZE); - // - - wxCheckBox* writeFile = (wxCheckBox*) FindWindow(IDC_LOG_PREFS_WRITE_FILE); - wxTextCtrl* fileName = (wxTextCtrl*) FindWindow(IDC_LOG_PREFS_FILENAME); - wxCheckBox* truncateOld = (wxCheckBox*) FindWindow(IDC_LOG_PREFS_TRUNCATE_OLD); - // - - - mHeaderFormat = kHFFull; - if (fmtBrief->GetValue()) - mHeaderFormat = kHFBrief; - else if (fmtMinimal->GetValue()) - mHeaderFormat = kHFMinimal; - - wxString tmpStr; - - mSingleLine = (singleLine->GetValue() != 0); - mExtraSpacing = extraSpacing->GetSelection(); - mPointSize = ConvertUnsigned(pointSize->GetValue()); - mUseColor = useColor->GetValue(); - mFontMonospace = fontMono->GetValue(); - - tmpStr = displayMax->GetValue(); - mDisplayMax = ConvertUnsigned(tmpStr); - if (mDisplayMax <= 0 || mDisplayMax > 1000 * 1000) { - wxMessageBox(wxT("Bad value for display max -- must be > 0 and <= 1,000,000"), - wxT("Hoser"), wxOK, this); - return false; - } - - tmpStr = poolSize->GetValue(); - mPoolSizeKB = ConvertUnsigned(tmpStr); - if (mDisplayMax <= 0 || mDisplayMax > 1048576) { - wxMessageBox(wxT("Bad value for pool size -- must be > 0 and <= 1048576"), - wxT("Hoser"), wxOK, this); - return false; - } - - mWriteFile = (writeFile->GetValue() != 0); - mFileName = fileName->GetValue(); - mTruncateOld = (truncateOld->GetValue() != 0); - if (mWriteFile && mFileName.IsEmpty()) { - wxMessageBox(wxT("Log filename may not be blank"), - wxT("Hoser"), wxOK, this); - return false; - } - - return true; -} - - -/* - * Create the log Format page. - */ -wxPanel* LogPrefsDialog::CreateFormatPage(wxBookCtrlBase* parent) -{ - wxPanel* panel = new wxPanel(parent); - - wxStaticBoxSizer* headerOpts = new wxStaticBoxSizer(wxVERTICAL, panel, - wxT("Header")); - headerOpts->Add(new wxRadioButton(panel, IDC_LOG_PREFS_FMT_FULL, - wxT("Full header"), wxDefaultPosition, wxDefaultSize, - wxRB_GROUP)); - headerOpts->Add(new wxRadioButton(panel, IDC_LOG_PREFS_FMT_BRIEF, - wxT("Brief header"))); - headerOpts->Add(new wxRadioButton(panel, IDC_LOG_PREFS_FMT_MINIMAL, - wxT("Minimal, integrated header"))); - - wxCheckBox* singleLine = new wxCheckBox(panel, IDC_LOG_PREFS_SINGLE_LINE, - wxT("Put headers and message on same line")); - - wxStaticText* extraSpacingDescr = new wxStaticText(panel, wxID_STATIC, - wxT("Extra line spacing:")); - wxComboBox* extraSpacing = new wxComboBox(panel, - IDC_LOG_PREFS_EXTRA_SPACING, wxT("blah"), - wxDefaultPosition, wxDefaultSize, NELEM(gSpacerChoices), - gSpacerChoices, wxCB_READONLY); - wxBoxSizer* extraSpacingSizer = new wxBoxSizer(wxHORIZONTAL); - extraSpacingSizer->Add(extraSpacingDescr, 0, wxALIGN_CENTER_VERTICAL); - extraSpacingSizer->AddSpacer(kInterSpacing); - extraSpacingSizer->Add(extraSpacing); - - wxStaticBoxSizer* textOpts = new wxStaticBoxSizer(wxVERTICAL, panel, - wxT("Text")); - textOpts->Add( - new wxStaticText(panel, wxID_STATIC, wxT("Point size:")) ); - textOpts->AddSpacer(kInterSpacing); - textOpts->Add( - new wxComboBox(panel, - IDC_LOG_PREFS_POINT_SIZE, wxT("blah"), - wxDefaultPosition, wxDefaultSize, NELEM(gPointSizes), - gPointSizes, wxCB_READONLY) ); - textOpts->AddSpacer(kInterSpacing); - textOpts->Add( - new wxCheckBox(panel, IDC_LOG_PREFS_USE_COLOR, - wxT("Colorful messages")) ); - textOpts->AddSpacer(kInterSpacing); - textOpts->Add( - new wxCheckBox(panel, IDC_LOG_PREFS_FONT_MONO, - wxT("Use monospace font")) ); - - - wxBoxSizer* sizerPanel = new wxBoxSizer(wxVERTICAL); - sizerPanel->Add(kMinWidth, kEdgeSpacing); // forces minimum width - sizerPanel->Add(headerOpts); - sizerPanel->AddSpacer(kInterSpacing); - sizerPanel->Add(singleLine); - sizerPanel->AddSpacer(kInterSpacing); - sizerPanel->Add(extraSpacingSizer); - sizerPanel->AddSpacer(kInterSpacing); - sizerPanel->Add(textOpts); - sizerPanel->AddSpacer(kInterSpacing); - - wxBoxSizer* horizIndent = new wxBoxSizer(wxHORIZONTAL); - horizIndent->AddSpacer(kEdgeSpacing); - horizIndent->Add(sizerPanel); - horizIndent->AddSpacer(kEdgeSpacing); - panel->SetSizer(horizIndent); - - return panel; -} - -/* - * Create the log Limits page. - */ -wxPanel* LogPrefsDialog::CreateLimitsPage(wxBookCtrlBase* parent) -{ - wxPanel* panel = new wxPanel(parent); - - wxBoxSizer* displayMaxSizer = new wxBoxSizer(wxHORIZONTAL); - displayMaxSizer->Add( - new wxStaticText(panel, wxID_ANY, - wxT("Maximum entries in log window:"), - wxDefaultPosition, wxDefaultSize, - wxALIGN_LEFT), - 0, wxALIGN_CENTER_VERTICAL); - displayMaxSizer->AddSpacer(kInterSpacing); - displayMaxSizer->Add( - new wxTextCtrl(panel, IDC_LOG_PREFS_DISPLAY_MAX)); - - wxBoxSizer* poolSizeSizer = new wxBoxSizer(wxHORIZONTAL); - poolSizeSizer->Add( - new wxStaticText(panel, wxID_ANY, - wxT("Size of the log pool (KB):"), - wxDefaultPosition, wxDefaultSize, - wxALIGN_LEFT), - 0, wxALIGN_CENTER_VERTICAL); - poolSizeSizer->AddSpacer(kInterSpacing); - poolSizeSizer->Add( - new wxTextCtrl(panel, IDC_LOG_PREFS_POOL_SIZE)); - - - wxBoxSizer* sizerPanel = new wxBoxSizer(wxVERTICAL); - sizerPanel->Add(kMinWidth, kEdgeSpacing); // forces minimum width - sizerPanel->Add(displayMaxSizer); - sizerPanel->AddSpacer(kInterSpacing); - sizerPanel->Add(poolSizeSizer); - sizerPanel->AddSpacer(kInterSpacing); - - wxBoxSizer* horizIndent = new wxBoxSizer(wxHORIZONTAL); - horizIndent->AddSpacer(kEdgeSpacing); - horizIndent->Add(sizerPanel); - horizIndent->AddSpacer(kEdgeSpacing); - panel->SetSizer(horizIndent); - - return panel; -} - -/* - * Create the log Files page. - */ -wxPanel* LogPrefsDialog::CreateFilesPage(wxBookCtrlBase* parent) -{ - wxPanel* panel = new wxPanel(parent); - wxStaticBoxSizer* logOpts = new wxStaticBoxSizer(wxVERTICAL, panel, - wxT("Log File")); - - wxCheckBox* writeCopy = - new wxCheckBox(panel, IDC_LOG_PREFS_WRITE_FILE, - wxT("Write a copy of log output to a file")); - - logOpts->AddSpacer(kInterSpacing); - logOpts->Add( - new wxStaticText(panel, wxID_ANY, - wxT("Filename:"), - wxDefaultPosition, wxDefaultSize, - wxALIGN_LEFT)); - logOpts->AddSpacer(kInterSpacing); - logOpts->Add( - new wxTextCtrl(panel, IDC_LOG_PREFS_FILENAME), 0, wxEXPAND); - logOpts->AddSpacer(kInterSpacing); - logOpts->Add( - new wxCheckBox(panel, IDC_LOG_PREFS_TRUNCATE_OLD, - wxT("Truncate the file if more than 8 hours old ")) ); - - - wxBoxSizer* sizerPanel = new wxBoxSizer(wxVERTICAL); - sizerPanel->Add(kMinWidth, kEdgeSpacing); // forces minimum width - sizerPanel->Add(writeCopy); - sizerPanel->AddSpacer(kInterSpacing); - sizerPanel->Add(logOpts); - sizerPanel->AddSpacer(kInterSpacing); - - wxBoxSizer* horizIndent = new wxBoxSizer(wxHORIZONTAL); - horizIndent->AddSpacer(kEdgeSpacing); - horizIndent->Add(sizerPanel); - horizIndent->AddSpacer(kEdgeSpacing); - panel->SetSizer(horizIndent); - - return panel; -} - - -/* - * Handle clicks on the "write file" checkbox. - */ -void LogPrefsDialog::OnWriteFile(wxCommandEvent& event) -{ - EnableFileControls(event.GetInt()); -} - -/* - * Enable or disable some of the controls on the "file" page. - */ -void LogPrefsDialog::EnableFileControls(bool enable) -{ - FindWindow(IDC_LOG_PREFS_FILENAME)->Enable(enable); - FindWindow(IDC_LOG_PREFS_TRUNCATE_OLD)->Enable(enable); -} - diff --git a/simulator/app/LogPrefsDialog.h b/simulator/app/LogPrefsDialog.h deleted file mode 100644 index 17a73a33c..000000000 --- a/simulator/app/LogPrefsDialog.h +++ /dev/null @@ -1,70 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Log preferences modal dialog. -// -#ifndef _SIM_LOG_PREFS_DIALOG_H -#define _SIM_LOG_PREFS_DIALOG_H - -/* - * Declaration of log preferences dialog. This class defines the outer - * wrapper as well as all of the pages. - */ -class LogPrefsDialog : public wxDialog { - DECLARE_EVENT_TABLE() - -public: - LogPrefsDialog(wxWindow* parent); - virtual ~LogPrefsDialog(void); - - void CreateControls(void); - - /* these correspond to radio buttons */ - typedef enum HeaderFormat { - kHFFull = 0, - kHFBrief, - kHFMinimal, - kHFInternal, // special -- used for internally generated msgs - }; - - /* - * Values edited in the preference pages. By Windows convention, - * these are public. - */ - /* format options */ - HeaderFormat mHeaderFormat; - bool mSingleLine; // put whole message on one line? - int mExtraSpacing; // double/triple-space messages? - int mPointSize; // text size - bool mUseColor; // colorful messages? - bool mFontMonospace; // use monospace font? - - /* limit options */ - int mDisplayMax; - int mPoolSizeKB; - - /* file options */ - bool mWriteFile; - wxString mFileName; - bool mTruncateOld; - -private: - bool TransferDataToWindow(void); - bool TransferDataFromWindow(void); - - wxPanel* CreateFormatPage(wxBookCtrlBase* parent); - wxPanel* CreateLimitsPage(wxBookCtrlBase* parent); - wxPanel* CreateFilesPage(wxBookCtrlBase* parent); - - void OnWriteFile(wxCommandEvent& event); - void EnableFileControls(bool enable); - - /* main notebook; for aesthetic reasons we may want a Choicebook */ - wxNotebook mNotebook; - - enum { - kMinWidth = 300, // minimum prefs dialog width, in pixels - }; -}; - -#endif // _SIM_LOG_PREFS_DIALOG_H diff --git a/simulator/app/LogWindow.cpp b/simulator/app/LogWindow.cpp deleted file mode 100644 index b19debbea..000000000 --- a/simulator/app/LogWindow.cpp +++ /dev/null @@ -1,1156 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Display runtime log output. -// - -// For compilers that support precompilation, include "wx/wx.h". -#include "wx/wxprec.h" - -// Otherwise, include all standard headers -#ifndef WX_PRECOMP -# include "wx/wx.h" -#endif -#include "wx/image.h" // needed for Windows build -#include "wx/dcbuffer.h" - -#include "LogWindow.h" -#include "LogMessage.h" -#include "LogPrefsDialog.h" -#include "MyApp.h" -#include "Preferences.h" -#include "Resource.h" -#include "UserEventMessage.h" - -#include <errno.h> - -static int android_snprintfBuffer(char** pBuf, int bufLen, const char* format, ...); -static int android_vsnprintfBuffer(char** pBuf, int bufLen, const char* format, va_list args); - - -using namespace android; - -#if 0 // experiment -- works on Win32, but not with GTK -class MyTextCtrl : public wxTextCtrl { -public: - MyTextCtrl(wxWindow* parent, wxWindowID id, const wxString& value, - const wxPoint& pos, const wxSize& size, int style = 0) - : wxTextCtrl(parent, id, value, pos, size, style) - { - printf("***************** MyTextCtrl!\n"); - } - - void OnScroll(wxScrollWinEvent& event); - void OnScrollBottom(wxScrollWinEvent& event); - -private: - DECLARE_EVENT_TABLE() -}; - -BEGIN_EVENT_TABLE(MyTextCtrl, wxTextCtrl) - EVT_SCROLLWIN(MyTextCtrl::OnScroll) - EVT_SCROLLWIN_BOTTOM(MyTextCtrl::OnScrollBottom) -END_EVENT_TABLE() - -void MyTextCtrl::OnScroll(wxScrollWinEvent& event) -{ - printf("OnScroll!\n"); -} - -void MyTextCtrl::OnScrollBottom(wxScrollWinEvent& event) -{ - printf("OnScrollBottom!\n"); -} -#endif - - -BEGIN_EVENT_TABLE(LogWindow, wxDialog) - EVT_CLOSE(LogWindow::OnClose) - EVT_MOVE(LogWindow::OnMove) - EVT_COMBOBOX(IDC_LOG_LEVEL, LogWindow::OnLogLevel) - EVT_BUTTON(IDC_LOG_CLEAR, LogWindow::OnLogClear) - EVT_BUTTON(IDC_LOG_PAUSE, LogWindow::OnLogPause) - EVT_BUTTON(IDC_LOG_PREFS, LogWindow::OnLogPrefs) -END_EVENT_TABLE() - -/* - * Information about log levels. - * - * Each entry here corresponds to an entry in the combo box. The first - * letter of each name should be unique. - */ -static const struct { - wxString name; - android_LogPriority priority; -} gLogLevels[] = { - { wxT("Verbose"), ANDROID_LOG_VERBOSE }, - { wxT("Debug"), ANDROID_LOG_DEBUG }, - { wxT("Info"), ANDROID_LOG_INFO }, - { wxT("Warn"), ANDROID_LOG_WARN }, - { wxT("Error"), ANDROID_LOG_ERROR } -}; - - -/* - * Create a new LogWindow. This should be a child of the main frame. - */ -LogWindow::LogWindow(wxWindow* parent) - : wxDialog(parent, wxID_ANY, wxT("Log Output"), wxDefaultPosition, - wxDefaultSize, - wxCAPTION | wxSYSTEM_MENU | wxCLOSE_BOX | wxRESIZE_BORDER), - mDisplayArray(NULL), mMaxDisplayMsgs(0), mPaused(false), - mMinPriority(ANDROID_LOG_VERBOSE), - mHeaderFormat(LogPrefsDialog::kHFFull), - mSingleLine(false), mExtraSpacing(0), mPointSize(10), mUseColor(true), - mFontMonospace(true), mWriteFile(false), mTruncateOld(true), mLogFp(NULL), - mNewlyShown(false), mLastPosition(wxDefaultPosition), mVisible(false) -{ - ConstructControls(); - - Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - - int poolSize = 10240; // 10MB - pPrefs->GetInt("log-pool-size-kbytes", &poolSize); - assert(poolSize > 0); - mPool.Resize(poolSize * 1024); - - mMaxDisplayMsgs = 1000; - pPrefs->GetInt("log-display-msg-count", &mMaxDisplayMsgs); - assert(mMaxDisplayMsgs > 0); - mDisplayArray = new LogMessage*[mMaxDisplayMsgs]; - memset(mDisplayArray, 0, sizeof(LogMessage*) * mMaxDisplayMsgs); - mTopPtr = -1; - mNextPtr = 0; - - int tmpInt = (int) mHeaderFormat; - pPrefs->GetInt("log-header-format", &tmpInt); - mHeaderFormat = (LogPrefsDialog::HeaderFormat) tmpInt; - pPrefs->GetBool("log-single-line", &mSingleLine); - pPrefs->GetInt("log-extra-spacing", &mExtraSpacing); - pPrefs->GetInt("log-point-size", &mPointSize); - pPrefs->GetBool("log-use-color", &mUseColor); - pPrefs->SetBool("log-font-monospace", &mFontMonospace); - SetTextStyle(); - - mFileName = wxT("/tmp/android-log.txt"); - pPrefs->GetBool("log-write-file", &mWriteFile); - pPrefs->GetString("log-filename", /*ref*/mFileName); - pPrefs->GetBool("log-truncate-old", &mTruncateOld); - - PrepareLogFile(); -} - -/* - * Destroy everything we own. - */ -LogWindow::~LogWindow(void) -{ - ClearDisplay(); - delete[] mDisplayArray; - - if (mLogFp != NULL) - fclose(mLogFp); -} - -/* - * Set the text style, based on our preferences. - */ -void LogWindow::SetTextStyle(void) -{ - wxTextCtrl* pTextCtrl; - pTextCtrl = (wxTextCtrl*) FindWindow(IDC_LOG_TEXT); - wxTextAttr style; - style = pTextCtrl->GetDefaultStyle(); - - if (mFontMonospace) { - wxFont font(mPointSize, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, - wxFONTWEIGHT_NORMAL); - style.SetFont(font); - } else { - wxFont font(mPointSize, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, - wxFONTWEIGHT_NORMAL); - style.SetFont(font); - } - - pTextCtrl->SetDefaultStyle(style); -} - -/* - * Set up the goodies in the window. - * - * Also initializes mMinPriority. - */ -void LogWindow::ConstructControls(void) -{ - Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - wxPanel* base = new wxPanel(this, wxID_ANY); - wxBoxSizer* masterSizer = new wxBoxSizer(wxVERTICAL); - wxBoxSizer* indentSizer = new wxBoxSizer(wxHORIZONTAL); - wxBoxSizer* configPrioritySizer = new wxBoxSizer(wxHORIZONTAL); - wxGridSizer* configSizer = new wxGridSizer(4, 1); - - /* - * Configure log level combo box. - */ - wxComboBox* logLevel; - int defaultLogLevel = 1; - pPrefs->GetInt("log-display-level", &defaultLogLevel); - logLevel = new wxComboBox(base, IDC_LOG_LEVEL, wxT(""), - wxDefaultPosition, wxDefaultSize, 0, NULL, - wxCB_READONLY /*| wxSUNKEN_BORDER*/); - for (int i = 0; i < NELEM(gLogLevels); i++) { - logLevel->Append(gLogLevels[i].name); - logLevel->SetClientData(i, (void*) gLogLevels[i].priority); - } - logLevel->SetSelection(defaultLogLevel); - mMinPriority = gLogLevels[defaultLogLevel].priority; - - /* - * Set up stuff at the bottom, starting with the options - * at the bottom left. - */ - configPrioritySizer->Add(new wxStaticText(base, wxID_ANY, wxT("Log level:"), - wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT), - 0, wxALIGN_CENTER_VERTICAL); - configPrioritySizer->AddSpacer(kInterSpacing); - configPrioritySizer->Add(logLevel); - - wxButton* clear = new wxButton(base, IDC_LOG_CLEAR, wxT("&Clear"), - wxDefaultPosition, wxDefaultSize, 0); - wxButton* pause = new wxButton(base, IDC_LOG_PAUSE, wxT("&Pause"), - wxDefaultPosition, wxDefaultSize, 0); - wxButton* prefs = new wxButton(base, IDC_LOG_PREFS, wxT("C&onfigure"), - wxDefaultPosition, wxDefaultSize, 0); - - configSizer->Add(configPrioritySizer, 0, wxALIGN_LEFT); - configSizer->Add(clear, 0, wxALIGN_CENTER); - configSizer->Add(pause, 0, wxALIGN_CENTER); - configSizer->Add(prefs, 0, wxALIGN_RIGHT); - - /* - * Create text ctrl. - */ - wxTextCtrl* pTextCtrl; - pTextCtrl = new wxTextCtrl(base, IDC_LOG_TEXT, wxT(""), - wxDefaultPosition, wxDefaultSize, - wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH2 | wxTE_NOHIDESEL | - wxHSCROLL); - - /* - * Add components to master sizer. - */ - masterSizer->AddSpacer(kEdgeSpacing); - masterSizer->Add(pTextCtrl, 1, wxEXPAND); - masterSizer->AddSpacer(kInterSpacing); - masterSizer->Add(configSizer, 0, wxEXPAND); - masterSizer->AddSpacer(kEdgeSpacing); - - /* - * Indent from sides. - */ - indentSizer->AddSpacer(kEdgeSpacing); - indentSizer->Add(masterSizer, 1, wxEXPAND); - indentSizer->AddSpacer(kEdgeSpacing); - - base->SetSizer(indentSizer); - - indentSizer->Fit(this); // shrink-to-fit - indentSizer->SetSizeHints(this); // define minimum size -} - -/* - * In some cases, this means the user has clicked on our "close" button. - * We don't really even want one, but both WinXP and KDE put one on our - * window whether we want it or not. So, we make it work as a "hide" - * button instead. - * - * This also gets called when the app is shutting down, and we do want - * to destroy ourselves then, saving various information about our state. - */ -void LogWindow::OnClose(wxCloseEvent& event) -{ - /* just hide the window, unless we're shutting down */ - if (event.CanVeto()) { - event.Veto(); - Show(false); - return; - } - - /* - * Save some preferences. - */ - SaveWindowPrefs(); - - /* if we can't veto the Close(), destroy ourselves */ - Destroy(); -} - -/* - * Save all of our preferences to the config file. - */ -void LogWindow::SaveWindowPrefs(void) -{ - Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - - /* - * Save shown/hidden state. - */ - pPrefs->SetBool("window-log-show", IsShown()); - - /* - * Limits and formatting prefs. - */ - pPrefs->SetInt("log-display-msg-count", mMaxDisplayMsgs); - pPrefs->SetInt("log-pool-size-kbytes", mPool.GetMaxSize() / 1024); - - pPrefs->SetInt("log-header-format", mHeaderFormat); - pPrefs->SetBool("log-single-line", mSingleLine); - pPrefs->SetInt("log-extra-spacing", mExtraSpacing); - pPrefs->SetInt("log-point-size", mPointSize); - pPrefs->SetBool("log-use-color", mUseColor); - pPrefs->SetBool("log-font-monospace", mFontMonospace); - - pPrefs->SetBool("log-write-file", mWriteFile); - pPrefs->SetString("log-filename", mFileName.ToAscii()); - pPrefs->SetBool("log-truncate-old", mTruncateOld); - - /* - * Save window size and position. - */ - wxPoint posn; - wxSize size; - - assert(pPrefs != NULL); - - posn = GetPosition(); - size = GetSize(); - - pPrefs->SetInt("window-log-x", posn.x); - pPrefs->SetInt("window-log-y", posn.y); - pPrefs->SetInt("window-log-width", size.GetWidth()); - pPrefs->SetInt("window-log-height", size.GetHeight()); - - /* - * Save current setting of debug level combo box. - */ - wxComboBox* pCombo; - int selection; - pCombo = (wxComboBox*) FindWindow(IDC_LOG_LEVEL); - selection = pCombo->GetSelection(); - pPrefs->SetInt("log-display-level", selection); -} - -/* - * Return the desired position and size. - */ -/*static*/ wxRect LogWindow::GetPrefWindowRect(void) -{ - Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - int x, y, width, height; - - assert(pPrefs != NULL); - - x = y = 10; - width = 500; - height = 200; - - /* these don't modify the arg if the pref doesn't exist */ - pPrefs->GetInt("window-log-x", &x); - pPrefs->GetInt("window-log-y", &y); - pPrefs->GetInt("window-log-width", &width); - pPrefs->GetInt("window-log-height", &height); - - return wxRect(x, y, width, height); -} - -/* - * Under Linux+GTK, the first time you show the window, it appears where - * it's supposed to. If you then hide it and show it again, it gets - * moved on top of the parent window. After that, you can reposition it - * and it remembers its position across hide/show. - * - * To counter this annoyance, we save the position when we hide, and - * reset the position after a show. The "newly shown" flag ensures that - * we only reposition the window as the result of a Show(true) call. - * - * Sometimes, something helpful will shift the window over if it's - * partially straddling a seam between two monitors. I don't see an easy - * way to block this, and I'm not sure I want to anyway. - */ -void LogWindow::OnMove(wxMoveEvent& event) -{ - wxPoint point; - point = event.GetPosition(); - //printf("Sim: log window is at (%d,%d) (new=%d)\n", point.x, point.y, - // mNewlyShown); - - if (mNewlyShown) { - if (mLastPosition == wxDefaultPosition) { - //printf("Sim: no last position established\n"); - } else { - Move(mLastPosition); - } - - mNewlyShown = false; - } -} - -/* - * Set the "newly shown" flag. - */ -bool LogWindow::Show(bool show) -{ - if (show) { - mNewlyShown = true; - Redisplay(); - } else { - mLastPosition = GetPosition(); - } - - mVisible = show; - return wxDialog::Show(show); -} - -/* - * User has adjusted the log level. Update the display appropriately. - * - * This is a wxEVT_COMMAND_COMBOBOX_SELECTED event. - */ -void LogWindow::OnLogLevel(wxCommandEvent& event) -{ - int selection; - android_LogPriority priority; - - selection = event.GetInt(); - wxComboBox* pCombo = (wxComboBox*) FindWindow(IDC_LOG_LEVEL); - priority = (android_LogPriority) (long)pCombo->GetClientData(event.GetInt()); - - printf("Sim: log level selected: %d (%s)\n", (int) priority, - (const char*) gLogLevels[selection].name.ToAscii()); - mMinPriority = priority; - Redisplay(); -} - -/* - * Clear out the log. - */ -void LogWindow::OnLogClear(wxCommandEvent& event) -{ - ClearDisplay(); - mPool.Clear(); -} - -/* - * Handle the pause/resume button. - * - * If we're un-pausing, we need to get caught up. - */ -void LogWindow::OnLogPause(wxCommandEvent& event) -{ - mPaused = !mPaused; - - wxButton* pButton = (wxButton*) FindWindow(IDC_LOG_PAUSE); - if (mPaused) { - pButton->SetLabel(wxT("&Resume")); - - mPool.SetBookmark(); - } else { - pButton->SetLabel(wxT("&Pause")); - - LogMessage* pMsg = mPool.GetBookmark(); - if (pMsg == NULL) { - /* bookmarked item fell out of pool */ - printf("--- bookmark was lost, redisplaying\n"); - Redisplay(); - } else { - /* - * The bookmark points to the last item added to the display. - * We want to chase its "prev" pointer to walk toward the head - * of the list, adding items from oldest to newest. - */ - pMsg = pMsg->GetPrev(); - while (pMsg != NULL) { - if (FilterMatches(pMsg)) - AddToDisplay(pMsg); - pMsg = pMsg->GetPrev(); - } - } - } -} - -/* - * Open log preferences dialog. - */ -void LogWindow::OnLogPrefs(wxCommandEvent& event) -{ - LogPrefsDialog dialog(this); - - /* - * Set up the dialog. - */ - dialog.mHeaderFormat = mHeaderFormat; - dialog.mSingleLine = mSingleLine; - dialog.mExtraSpacing = mExtraSpacing; - dialog.mPointSize = mPointSize; - dialog.mUseColor = mUseColor; - dialog.mFontMonospace = mFontMonospace; - - dialog.mDisplayMax = mMaxDisplayMsgs; - dialog.mPoolSizeKB = mPool.GetMaxSize() / 1024; - - dialog.mWriteFile = mWriteFile; - dialog.mFileName = mFileName; - dialog.mTruncateOld = mTruncateOld; - - /* - * Show it. If they hit "OK", copy the updated values out, and - * re-display the log output. - */ - if (dialog.ShowModal() == wxID_OK) { - /* discard old display arra */ - ClearDisplay(); - delete[] mDisplayArray; - - mHeaderFormat = dialog.mHeaderFormat; - mSingleLine = dialog.mSingleLine; - mExtraSpacing = dialog.mExtraSpacing; - mPointSize = dialog.mPointSize; - mUseColor = dialog.mUseColor; - mFontMonospace = dialog.mFontMonospace; - - assert(dialog.mDisplayMax > 0); - assert(dialog.mPoolSizeKB > 0); - mMaxDisplayMsgs = dialog.mDisplayMax; - mPool.Resize(dialog.mPoolSizeKB * 1024); - - mWriteFile = dialog.mWriteFile; - if (mLogFp != NULL && mFileName != dialog.mFileName) { - printf("--- log file name changed, closing\n"); - fclose(mLogFp); - mLogFp = NULL; - } - mFileName = dialog.mFileName; - mTruncateOld = dialog.mTruncateOld; - - mDisplayArray = new LogMessage*[mMaxDisplayMsgs]; - memset(mDisplayArray, 0, sizeof(LogMessage*) * mMaxDisplayMsgs); - Redisplay(); - - PrepareLogFile(); - } -} - -/* - * Handle a log message "user event". This should only be called in - * the main UI thread. - * - * We take ownership of "*pLogMessage". - */ -void LogWindow::AddLogMessage(LogMessage* pLogMessage) -{ - mPool.Add(pLogMessage); - - if (!mPaused && mVisible && FilterMatches(pLogMessage)) { - /* - * Thought: keep a reference to the previous message. If it - * matches in most fields (all except timestamp?), hold it and - * increment a counter. If we get a message that doesn't match, - * or a timer elapses, synthesize a "previous message repeated N - * times" string. - */ - AddToDisplay(pLogMessage); - } - - // release the initial ref caused by allocation - pLogMessage->Release(); - - if (mLogFp != NULL) - LogToFile(pLogMessage); -} - -/* - * Clear out the display, releasing any log messages held in the display - * array. - */ -void LogWindow::ClearDisplay(void) -{ - wxTextCtrl* pTextCtrl; - pTextCtrl = (wxTextCtrl*) FindWindow(IDC_LOG_TEXT); - pTextCtrl->Clear(); - - /* - * Just run through the entire array. - */ - for (int i = 0; i < mMaxDisplayMsgs; i++) { - if (mDisplayArray[i] != NULL) { - mDisplayArray[i]->Release(); - mDisplayArray[i] = NULL; - } - } - mTopPtr = -1; - mNextPtr = 0; -} - -/* - * Clear the current display and regenerate it from the log pool. We need - * to do this whenever we change filters or log message formatting. - */ -void LogWindow::Redisplay(void) -{ - /* - * Freeze output rendering so it doesn't flash during update. Doesn't - * seem to help for GTK, and it leaves garbage on the screen in WinXP, - * so I'm leaving it commented out. - */ - //wxTextCtrl* pText = (wxTextCtrl*) FindWindow(IDC_LOG_TEXT); - //pText->Freeze(); - - //printf("--- redisplay\n"); - ClearDisplay(); - - /* - * Set up the default wxWidgets text style stuff. - */ - SetTextStyle(); - - /* - * Here's the plan: - * - Start at the head of the pool (where the most recently added - * items are). - * - Check to see if the current item passes our filter. If it does, - * increment the "found count". - * - Continue in this manner until we run out of pool or have - * sufficient items to fill the screen. - * - Starting from the current position, walk back toward the head, - * adding the items that meet the current filter criteria. - * - * Don't forget that the log pool could be empty. - */ - LogMessage* pMsg = mPool.GetHead(); - - if (pMsg != NULL) { - int foundCount = 0; - - // note this stops before it runs off the end - while (pMsg->GetNext() != NULL && foundCount < mMaxDisplayMsgs) { - if (FilterMatches(pMsg)) - foundCount++; - pMsg = pMsg->GetNext(); - } - - while (pMsg != NULL) { - if (FilterMatches(pMsg)) - AddToDisplay(pMsg); - pMsg = pMsg->GetPrev(); - } - } - - //pText->Thaw(); -} - - -/* - * Returns "true" if the currently specified filters would allow this - * message to be shown. - */ -bool LogWindow::FilterMatches(const LogMessage* pLogMessage) -{ - if (pLogMessage->GetPriority() >= mMinPriority) - return true; - else - return false; -} - -/* - * Realloc the array of pointers, and remove anything from the display - * that should no longer be there. - */ -void LogWindow::SetMaxDisplayMsgs(int max) -{ - Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - - pPrefs->SetInt("log-display-msg-count", max); -} - -/* - * Add the message to the display array and to the screen. - */ -void LogWindow::AddToDisplay(LogMessage* pLogMessage) -{ - wxTextCtrl* pTextCtrl; - pTextCtrl = (wxTextCtrl*) FindWindow(IDC_LOG_TEXT); - - if (mNextPtr == mTopPtr) { - /* - * The display array is full. - * - * We need to eliminate the topmost entry. This requires removing - * it from the array and removing the text from the wxTextCtrl. - */ - pTextCtrl->Remove(0, mDisplayArray[mTopPtr]->GetTextCtrlLen()); - mDisplayArray[mTopPtr]->Release(); - mTopPtr = (mTopPtr + 1) % mMaxDisplayMsgs; - } - - /* - * Add formatted text to the text ctrl. Track how much actual space - * is required. The space may be different on Win32 (CRLF-based) vs. - * GTK (LF-based), so we need to measure it, not compute it from the - * text string. - */ - long lastBefore, lastAfter; - //long insertBefore; - //insertBefore = pTextCtrl->GetInsertionPoint(); - lastBefore = pTextCtrl->GetLastPosition(); - FormatMessage(pLogMessage, pTextCtrl); - lastAfter = pTextCtrl->GetLastPosition(); - pLogMessage->SetTextCtrlLen(lastAfter - lastBefore); - - /* - * If we restore the old insertion point, we will be glued to where - * we were. This is okay until we start deleting text from the top, - * at which point we need to adjust it to retain our position. - * - * If we set the insertion point to the bottom, we effectively - * implement "scroll to bottom on output". - * - * If we don't set it at all, we get slightly strange behavior out - * of GTK, which seems to be par for the course here. - */ - //pTextCtrl->SetInsertionPoint(insertBefore); // restore insertion pt - pTextCtrl->SetInsertionPoint(lastAfter); - - /* add it to array, claim ownership */ - mDisplayArray[mNextPtr] = pLogMessage; - pLogMessage->Acquire(); - - /* adjust pointers */ - if (mTopPtr < 0) // first time only - mTopPtr = 0; - mNextPtr = (mNextPtr + 1) % mMaxDisplayMsgs; -} - - -/* - * Return a human-readable string for the priority level. Always returns - * a valid string. - */ -static const wxCharBuffer GetPriorityString(android_LogPriority priority) -{ - int idx; - - idx = (int) priority - (int) ANDROID_LOG_VERBOSE; - if (idx < 0 || idx >= NELEM(gLogLevels)) - return "?unknown?"; - return gLogLevels[idx].name.ToAscii(); -} - -/* - * Format a message and write it to the text control. - */ -void LogWindow::FormatMessage(const LogMessage* pLogMessage, - wxTextCtrl* pTextCtrl) -{ -#if defined(HAVE_LOCALTIME_R) - struct tm tmBuf; -#endif - struct tm* ptm; - char timeBuf[32]; - char msgBuf[256]; - int msgLen = 0; - char* outBuf; - char priChar; - LogPrefsDialog::HeaderFormat headerFmt; - - headerFmt = mHeaderFormat; - if (pLogMessage->GetInternal()) - headerFmt = LogPrefsDialog::kHFInternal; - - priChar = ((const char*)GetPriorityString(pLogMessage->GetPriority()))[0]; - - /* - * Get the current date/time in pretty form - * - * It's often useful when examining a log with "less" to jump to - * a specific point in the file by searching for the date/time stamp. - * For this reason it's very annoying to have regexp meta characters - * in the time stamp. Don't use forward slashes, parenthesis, - * brackets, asterisks, or other special chars here. - */ - time_t when = pLogMessage->GetWhen(); - const char* fmt = NULL; -#if defined(HAVE_LOCALTIME_R) - ptm = localtime_r(&when, &tmBuf); -#else - ptm = localtime(&when); -#endif - switch (headerFmt) { - case LogPrefsDialog::kHFFull: - case LogPrefsDialog::kHFInternal: - fmt = "%m-%d %H:%M:%S"; - break; - case LogPrefsDialog::kHFBrief: - case LogPrefsDialog::kHFMinimal: - fmt = "%H:%M:%S"; - break; - default: - break; - } - if (fmt != NULL) - strftime(timeBuf, sizeof(timeBuf), fmt, ptm); - else - strcpy(timeBuf, "-"); - - const int kMaxExtraNewlines = 2; - char hdrNewline[2]; - char finalNewlines[kMaxExtraNewlines+1 +1]; - - if (mSingleLine) - hdrNewline[0] = ' '; - else - hdrNewline[0] = '\n'; - hdrNewline[1] = '\0'; - - assert(mExtraSpacing <= kMaxExtraNewlines); - int i; - for (i = 0; i < mExtraSpacing+1; i++) - finalNewlines[i] = '\n'; - finalNewlines[i] = '\0'; - - wxTextAttr msgColor; - switch (pLogMessage->GetPriority()) { - case ANDROID_LOG_WARN: - msgColor.SetTextColour(*wxBLUE); - break; - case ANDROID_LOG_ERROR: - msgColor.SetTextColour(*wxRED); - break; - case ANDROID_LOG_VERBOSE: - case ANDROID_LOG_DEBUG: - case ANDROID_LOG_INFO: - default: - msgColor.SetTextColour(*wxBLACK); - break; - } - if (pLogMessage->GetInternal()) - msgColor.SetTextColour(*wxGREEN); - - /* - * Construct a buffer containing the log header. - */ - bool splitHeader = true; - outBuf = msgBuf; - switch (headerFmt) { - case LogPrefsDialog::kHFFull: - splitHeader = true; - msgLen = android_snprintfBuffer(&outBuf, sizeof(msgBuf), - "[ %s %5d %c/%-6.6s]%s", - timeBuf, pLogMessage->GetPid(), priChar, - pLogMessage->GetTag(), hdrNewline); - break; - case LogPrefsDialog::kHFBrief: - splitHeader = true; - msgLen = android_snprintfBuffer(&outBuf, sizeof(msgBuf), - "[%s %5d]%s", - timeBuf, pLogMessage->GetPid(), hdrNewline); - break; - case LogPrefsDialog::kHFMinimal: - splitHeader = false; - msgLen = android_snprintfBuffer(&outBuf, sizeof(msgBuf), - "%s %5d- %s", - timeBuf, pLogMessage->GetPid(), pLogMessage->GetMsg()); - break; - case LogPrefsDialog::kHFInternal: - splitHeader = false; - msgLen = android_snprintfBuffer(&outBuf, sizeof(msgBuf), - "[%s] %s", timeBuf, pLogMessage->GetMsg()); - break; - default: - fprintf(stderr, "Sim: unexpected header format %d\n", headerFmt); - assert(false); - break; - } - - if (msgLen < 0) { - fprintf(stderr, "WHOOPS\n"); - assert(outBuf == msgBuf); - return; - } - - if (splitHeader) { - if (mUseColor) - pTextCtrl->SetDefaultStyle(wxTextAttr(*wxLIGHT_GREY)); - pTextCtrl->AppendText(wxString::FromAscii(outBuf)); - if (mUseColor) - pTextCtrl->SetDefaultStyle(msgColor); - pTextCtrl->AppendText(wxString::FromAscii(pLogMessage->GetMsg())); - if (mUseColor) - pTextCtrl->SetDefaultStyle(*wxBLACK); - pTextCtrl->AppendText(wxString::FromAscii(finalNewlines)); - } else { - if (mUseColor) - pTextCtrl->SetDefaultStyle(msgColor); - pTextCtrl->AppendText(wxString::FromAscii(outBuf)); - if (mUseColor) - pTextCtrl->SetDefaultStyle(*wxBLACK); - pTextCtrl->AppendText(wxString::FromAscii(finalNewlines)); - } - - /* if we allocated storage for this message, free it */ - if (outBuf != msgBuf) - free(outBuf); -} - -/* - * Write the message to the log file. - * - * We can't just do this in FormatMessage(), because that re-writes all - * messages on the display whenever the output format or filter changes. - * - * Use a one-log-per-line format here to make "grep" useful. - */ -void LogWindow::LogToFile(const LogMessage* pLogMessage) -{ -#if defined(HAVE_LOCALTIME_R) - struct tm tmBuf; -#endif - struct tm* ptm; - char timeBuf[32]; - char msgBuf[256]; - int msgLen; - char* outBuf; - char priChar; - - assert(mLogFp != NULL); - - time_t when = pLogMessage->GetWhen(); -#if defined(HAVE_LOCALTIME_R) - ptm = localtime_r(&when, &tmBuf); -#else - ptm = localtime(&when); -#endif - - strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm); - priChar = ((const char*)GetPriorityString(pLogMessage->GetPriority()))[0]; - - outBuf = msgBuf; - if (pLogMessage->GetInternal()) { - msgLen = android_snprintfBuffer(&outBuf, sizeof(msgBuf), - "[%s %5d *] %s\n", - timeBuf, pLogMessage->GetPid(), pLogMessage->GetMsg()); - } else { - msgLen = android_snprintfBuffer(&outBuf, sizeof(msgBuf), - "[%s %5d %c] %s)\n", - timeBuf, pLogMessage->GetPid(), priChar, - pLogMessage->GetMsg()); - } - if (fwrite(outBuf, msgLen, 1, mLogFp) != 1) - fprintf(stderr, "Sim: WARNING: partial log write\n"); - fflush(mLogFp); - - /* if we allocated storage for this message, free it */ - if (outBuf != msgBuf) - free(outBuf); -} - -/* - * Get the modification date of a file. - */ -static bool GetFileModDate(const char* fileName, time_t* pModWhen) -{ - struct stat sb; - - if (stat(fileName, &sb) < 0) - return false; - - *pModWhen = sb.st_mtime; - return true; -} - -/* - * Open or close the log file as appropriate. - */ -void LogWindow::PrepareLogFile(void) -{ - const int kLogFileMaxAge = 8 * 60 * 60; // 8 hours - - if (!mWriteFile && mLogFp != NULL) { - printf("Sim: closing log file\n"); - fclose(mLogFp); - mLogFp = NULL; - } else if (mWriteFile && mLogFp == NULL) { - printf("Sim: opening log file '%s'\n", (const char*)mFileName.ToAscii()); - time_t now, modWhen = 0; - const char* openFlags; - - now = time(NULL); - if (!mTruncateOld || - (GetFileModDate(mFileName.ToAscii(), &modWhen) && - modWhen + kLogFileMaxAge > now)) - { - if (modWhen != 0) { - printf("--- log file is %.3f hours old, appending\n", - (now - modWhen) / 3600.0); - } - openFlags = "a"; // open for append (text mode) - } else { - if (modWhen != 0) { - printf("--- log file is %.3f hours old, truncating\n", - (now - modWhen) / 3600.0); - } - openFlags = "w"; // open for writing, truncate (text mode) - } - - mLogFp = fopen(mFileName.ToAscii(), openFlags); - if (mLogFp == NULL) { - fprintf(stderr, "Sim: failed opening log file '%s': %s\n", - (const char*) mFileName.ToAscii(), strerror(errno)); - } else { - fprintf(mLogFp, "\n\n"); - fflush(mLogFp); - } - } -} - -/* - * Add a new log message. - * - * This function can be called from any thread. It makes a copy of the - * stuff in "*pBundle" and sends it to the main UI thread. - */ -/*static*/ void LogWindow::PostLogMsg(const android_LogBundle* pBundle) -{ - LogMessage* pNewMessage = LogMessage::Create(pBundle); - - SendToWindow(pNewMessage); -} - -/* - * Post a simple string to the log. - */ -/*static*/ void LogWindow::PostLogMsg(const char* msg) -{ - LogMessage* pNewMessage = LogMessage::Create(msg); - - SendToWindow(pNewMessage); -} - -/* - * Post a simple wxString to the log. - */ -/*static*/ void LogWindow::PostLogMsg(const wxString& msg) -{ - LogMessage* pNewMessage = LogMessage::Create(msg.ToAscii()); - - SendToWindow(pNewMessage); -} - -/* - * Send a log message to the log window. - */ -/*static*/ void LogWindow::SendToWindow(LogMessage* pMessage) -{ - if (pMessage != NULL) { - wxWindow* pMainFrame = ((MyApp*)wxTheApp)->GetMainFrame(); - UserEventMessage* pUem = new UserEventMessage; - pUem->CreateLogMessage(pMessage); - - UserEvent uev(0, (void*) pUem); - - pMainFrame->AddPendingEvent(uev); - } else { - fprintf(stderr, "Sim: failed to add new log message\n"); - } -} - - -/* - * This is a sanity check. We need to stop somewhere to avoid trashing - * the system on bad input. - */ -#define kMaxLen 65536 - -#define VSNPRINTF vsnprintf // used to worry about _vsnprintf - - -/* - * Print a formatted message into a buffer. Pass in a buffer to try to use. - * - * If the buffer isn't big enough to hold the message, allocate storage - * with malloc() and return that instead. The caller is responsible for - * freeing the storage. - * - * Returns the length of the string, or -1 if the printf call failed. - */ -static int android_vsnprintfBuffer(char** pBuf, int bufLen, const char* format, va_list args) -{ - int charsOut; - char* localBuf = NULL; - - assert(pBuf != NULL && *pBuf != NULL); - assert(bufLen > 0); - assert(format != NULL); - - while (1) { - /* - * In some versions of libc, vsnprintf only returns 0 or -1, where - * -1 indicates the the buffer wasn't big enough. In glibc 2.1 - * and later, it returns the actual size needed. - * - * MinGW is just returning -1, so we have to retry there. - */ - char* newBuf; - - charsOut = VSNPRINTF(*pBuf, bufLen, format, args); - - if (charsOut >= 0 && charsOut < bufLen) - break; - - //fprintf(stderr, "EXCEED: %d vs %d\n", charsOut, bufLen); - if (charsOut < 0) { - /* exact size not known, double previous size */ - bufLen *= 2; - if (bufLen > kMaxLen) - goto fail; - } else { - /* exact size known, just use that */ - - bufLen = charsOut + 1; - } - //fprintf(stderr, "RETRY at %d\n", bufLen); - - newBuf = (char*) realloc(localBuf, bufLen); - if (newBuf == NULL) - goto fail; - *pBuf = localBuf = newBuf; - } - - // On platforms where snprintf() doesn't return the number of - // characters output, we would need to call strlen() here. - - return charsOut; - -fail: - if (localBuf != NULL) { - free(localBuf); - *pBuf = NULL; - } - return -1; -} - -/* - * Variable-arg form of the above. - */ -static int android_snprintfBuffer(char** pBuf, int bufLen, const char* format, ...) -{ - va_list args; - int result; - - va_start(args, format); - result = android_vsnprintfBuffer(pBuf, bufLen, format, args); - va_end(args); - - return result; -} - - diff --git a/simulator/app/LogWindow.h b/simulator/app/LogWindow.h deleted file mode 100644 index ca9f133e4..000000000 --- a/simulator/app/LogWindow.h +++ /dev/null @@ -1,127 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Window with log output. -// -#ifndef _SIM_LOG_WINDOW_H -#define _SIM_LOG_WINDOW_H - -#include "PhoneData.h" -#include "UserEvent.h" -#include "LogMessage.h" -#include "LogPool.h" -#include "LogPrefsDialog.h" - - -/* - * Display log output from runtime process. - * - * We receive the messages broken into components (date, log level, tag, - * function name, etc.) and do the formatting ourselves. We receive all - * messages regardless of log level, and provide filter controls in the - * window. - * - * Messages are stored in a "log pool", which has a fixed memory footprint. - * The messages that are currently visible in the log output window are - * also pointed at from a fixed-size display array. Changes to output - * format cause us to clear the display and re-show everything in the - * display array, while changes to the output filter cause us to - * re-evaluate the contents of the display pool. - */ -class LogWindow : public wxDialog { -public: - LogWindow(wxWindow* parent); - virtual ~LogWindow(void); - - /* we override this, to cope with annoying GTK behavior */ - virtual bool Show(bool show = true); - - /* return preferred size and position */ - static wxRect GetPrefWindowRect(void); - - /* handle a log message "user event" */ - void AddLogMessage(LogMessage* pLogMessage); - - /* resize the display messages array */ - void SetMaxDisplayMsgs(int max); - - /* post a message to the log; may be called from non-main thread */ - static void PostLogMsg(const android_LogBundle* pBundle); - static void PostLogMsg(const wxString& msg); - static void PostLogMsg(const char* msg); - -private: - void OnMove(wxMoveEvent& event); - void OnClose(wxCloseEvent& event); - void OnLogLevel(wxCommandEvent& event); - void OnLogClear(wxCommandEvent& event); - void OnLogPause(wxCommandEvent& event); - void OnLogPrefs(wxCommandEvent& event); - - /* handle incoming log message */ - void OnUserEvent(UserEvent& event); - - void SaveWindowPrefs(void); - void ConstructControls(void); - - void AddToDisplay(LogMessage* pLogMessage); - void ClearDisplay(void); - void Redisplay(void); - void SetTextStyle(void); - - bool FilterMatches(const LogMessage* pLogMessage); - - void FormatMessage(const LogMessage* pLogMessage, - wxTextCtrl* pTextCtrl); - - void LogToFile(const LogMessage* pLogMessage); - void PrepareLogFile(void); - static void SendToWindow(LogMessage* pMessage); - - /* - * Message pool. - */ - LogPool mPool; - - /* - * Display array. This is a fixed-size circular array that holds - * pointers to the log messages currently displayed on screen. - */ - LogMessage** mDisplayArray; // ptrs to messages currently displayed - int mMaxDisplayMsgs; // max #of messages - int mTopPtr; // index of top message - int mNextPtr; // index of next empty slot - - bool mPaused; // is output paused for review? - - /* - * Current filter. - */ - android_LogPriority mMinPriority; // messages at or above are shown - - /* format options */ - LogPrefsDialog::HeaderFormat mHeaderFormat; - bool mSingleLine; // put whole message on one line? - int mExtraSpacing; // double/triple-space messages? - int mPointSize; // text point size; - bool mUseColor; // colorful messages? - bool mFontMonospace; // use monospace font? - - /* log file options */ - bool mWriteFile; - wxString mFileName; - bool mTruncateOld; - - FILE* mLogFp; - - /* - * Window position stuff. - */ - bool mNewlyShown; - wxPoint mLastPosition; - bool mVisible; - - DECLARE_EVENT_TABLE() -}; - -#endif // _SIM_LOG_WINDOW_H diff --git a/simulator/app/MainFrame.cpp b/simulator/app/MainFrame.cpp deleted file mode 100644 index b13caab2d..000000000 --- a/simulator/app/MainFrame.cpp +++ /dev/null @@ -1,1462 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Main window, menu bar, and associated goodies. -// - -// For compilers that support precompilation, include "wx/wx.h". -#include "wx/wxprec.h" - -// Otherwise, include all standard headers -#ifndef WX_PRECOMP -# include "wx/wx.h" -#endif -#include "wx/button.h" -#include "wx/help.h" -#include "wx/filedlg.h" -#include "wx/slider.h" -#include "wx/textctrl.h" - -#include "MainFrame.h" -#include "MyApp.h" -#include "Resource.h" -#include "PhoneCollection.h" -#include "PhoneData.h" -#include "PhoneWindow.h" -#include "DeviceWindow.h" -#include "UserEventMessage.h" -#include "PrefsDialog.h" - -#include "SimRuntime.h" - - -static wxString kStatusNotRunning = wxT("Idle"); -static wxString kStatusRunning = wxT("Run"); - -static wxString kDeviceMenuString = wxT("&Device"); - -static const wxString gStdJavaApps[] = { - wxT(""), - wxT("com.android.testharness.TestList"), - wxT("com.android.apps.contacts.ContactsList"), - wxT("mikeapp") -}; - - -BEGIN_EVENT_TABLE(MainFrame::MainFrame, wxFrame) - EVT_CLOSE(MainFrame::OnClose) - EVT_TIMER(kHalfSecondTimerId, MainFrame::OnTimer) - //EVT_IDLE(MainFrame::OnIdle) - - EVT_ACTIVATE(MainFrame::OnActivate) - EVT_ACTIVATE_APP(MainFrame::OnActivate) - EVT_COMBOBOX(IDC_MODE_SELECT, MainFrame::OnComboBox) - EVT_COMBOBOX(IDC_JAVA_VM, MainFrame::OnComboBox) - EVT_CHECKBOX(IDC_USE_GDB, MainFrame::OnCheckBox) - EVT_CHECKBOX(IDC_USE_VALGRIND, MainFrame::OnCheckBox) - EVT_CHECKBOX(IDC_CHECK_JNI, MainFrame::OnCheckBox) - EVT_CHECKBOX(IDC_OVERLAY_ONION_SKIN, MainFrame::OnCheckBox) - EVT_TEXT(IDC_JAVA_APP_NAME, MainFrame::OnText) - EVT_TEXT_ENTER(IDC_ONION_SKIN_FILE_NAME, MainFrame::OnTextEnter) - EVT_BUTTON(IDC_ONION_SKIN_BUTTON, MainFrame::OnButton) - EVT_COMMAND_SCROLL(IDC_ONION_SKIN_ALPHA_VAL, MainFrame::OnSliderChange) - - EVT_MENU(IDM_FILE_PREFERENCES, MainFrame::OnFilePreferences) - EVT_MENU(IDM_FILE_EXIT, MainFrame::OnFileExit) - EVT_MENU(IDM_RUNTIME_START, MainFrame::OnSimStart) - EVT_UPDATE_UI(IDM_RUNTIME_START, MainFrame::OnUpdateSimStart) - EVT_MENU(IDM_RUNTIME_STOP, MainFrame::OnSimStop) - EVT_UPDATE_UI(IDM_RUNTIME_STOP, MainFrame::OnUpdateSimStop) - EVT_MENU(IDM_RUNTIME_RESTART, MainFrame::OnSimRestart) - EVT_UPDATE_UI(IDM_RUNTIME_RESTART, MainFrame::OnUpdateSimRestart) - EVT_MENU(IDM_RUNTIME_KILL, MainFrame::OnSimKill) - EVT_UPDATE_UI(IDM_RUNTIME_KILL, MainFrame::OnUpdateSimKill) - EVT_MENU_RANGE(IDM_DEVICE_SEL0, IDM_DEVICE_SELN, - MainFrame::OnDeviceSelected) - EVT_MENU(IDM_DEVICE_RESCAN, MainFrame::OnDeviceRescan) - EVT_UPDATE_UI(IDM_DEBUG_SHOW_LOG, MainFrame::OnUpdateDebugShowLog) - EVT_MENU(IDM_DEBUG_SHOW_LOG, MainFrame::OnDebugShowLog) - EVT_MENU(IDM_HELP_CONTENTS, MainFrame::OnHelpContents) - EVT_MENU(IDM_HELP_ABOUT, MainFrame::OnHelpAbout) - - EVT_USER_EVENT(MainFrame::OnUserEvent) -END_EVENT_TABLE() - - -/* - * Main window constructor. - * - * Creates menus and status bar. - */ -MainFrame::MainFrame(const wxString& title, const wxPoint& pos, - const wxSize& size, long style) - : wxFrame((wxFrame *)NULL, -1, title, pos, size, style), - mSimRunning(false), - mRestartRequested(false), - mpPhoneWindow(NULL), - mPhoneWindowPosn(wxDefaultPosition), - mTimer(this, kHalfSecondTimerId) -{ - mSimAssetPath = ((MyApp*)wxTheApp)->GetSimAssetPath(); - mSimAssetPath += wxT("/simulator/default/default"); - - Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - int val; - - val = mPhoneWindowPosn.x; - pPrefs->GetInt("window-device-x", &val); - mPhoneWindowPosn.x = val; - val = mPhoneWindowPosn.y; - pPrefs->GetInt("window-device-y", &val); - mPhoneWindowPosn.y = val; - - /* - * Create main menu. - */ - ConstructMenu(); - - /* - * Create the status bar. - */ - int widths[2] = { -1, 50 }; - CreateStatusBar(2, wxFULL_REPAINT_ON_RESIZE); // no wxST_SIZEGRIP - SetStatusWidths(2, widths); - SetStatusText(wxT("Ready")); - SetStatusText(kStatusNotRunning, 1); - - /* - * Create main window controls. - */ - ConstructControls(); - -#if 0 - /* - * Use the standard window color for the main frame (which usually - * has a darker color). This has a dramatic effect under Windows. - */ - wxColour color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); - SetOwnBackgroundColour(color); -#endif - - /* - * Create the log window. - */ - wxRect layout = LogWindow::GetPrefWindowRect(); - mpLogWindow = new LogWindow(this); - mpLogWindow->Move(layout.GetTopLeft()); - mpLogWindow->SetSize(layout.GetSize()); - bool showLogWindow = true; - pPrefs->GetBool("window-log-show", &showLogWindow); - if (showLogWindow) - mpLogWindow->Show(); - - /* - * Set up a frequent timer. We use this to keep our "run/idle" - * display up to date. (Ideally this will go away.) - */ - mTimer.Start(400); // arg is delay in ms - - /* - * Handle auto-power-on by sending ourselves an event. That way it - * gets handled after window initialization finishes. - */ - bool autoPowerOn = false; - pPrefs->GetBool("auto-power-on", &autoPowerOn); - if (autoPowerOn) { - printf("Sim: Auto power-up\n"); - wxCommandEvent startEvent(wxEVT_COMMAND_MENU_SELECTED, IDM_RUNTIME_START); - this->AddPendingEvent(startEvent); - } - - /* - * wxThread wants these to be on the heap -- it will call delete on the - * object when the thread exits. - */ - mExternalRuntimeThread = new ExternalRuntime(); - mExternalRuntimeThread->StartThread(); - mPropertyServerThread = new PropertyServer(); - mPropertyServerThread->StartThread(); -} - -/* - * Construct the main menu. Called from the constructor. - */ -void MainFrame::ConstructMenu(void) -{ - Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - - /* - * Scan for available phones. - */ - PhoneCollection* pCollection = PhoneCollection::GetInstance(); - pCollection->ScanForPhones(mSimAssetPath.ToAscii()); - - /* - * Create the "File" menu. - */ - wxMenu* menuFile = new wxMenu; - - menuFile->Append(IDM_FILE_PREFERENCES, wxT("&Preferences..."), - wxT("Edit simulator preferences")); - menuFile->AppendSeparator(); - menuFile->Append(IDM_FILE_EXIT, wxT("E&xit\tCtrl-Q"), - wxT("Stop simulator and exit")); - - /* - * Create the "Runtime" menu. - */ - wxMenu* menuRuntime = new wxMenu; - menuRuntime->Append(IDM_RUNTIME_START, wxT("&Power On\tCtrl-G"), - wxT("Start the device")); -// menuRuntime->Append(IDM_RUNTIME_STOP, wxT("Power &Off"), -// wxT("Stop the device")); - menuRuntime->AppendSeparator(); -// menuRuntime->Append(IDM_RUNTIME_RESTART, wxT("&Restart"), -// wxT("Restart the device")); - menuRuntime->Append(IDM_RUNTIME_KILL, wxT("&Kill\tCtrl-K"), - wxT("Kill the runtime processes")); - - /* - * Create "Device" menu. - */ - wxString defaultDevice = wxT("Sooner"); - pPrefs->GetString("default-device", /*ref*/ defaultDevice); - wxMenu* menuDevice = CreateDeviceMenu(defaultDevice.ToAscii()); - - /* - * Create "Debug" menu. - */ - wxMenu* menuDebug = new wxMenu; - menuDebug->AppendCheckItem(IDM_DEBUG_SHOW_LOG, wxT("View &Log Output"), - wxT("View log output window")); - - /* - * Create the "Help" menu. - */ - wxMenu* menuHelp = new wxMenu; - menuHelp->Append(IDM_HELP_CONTENTS, wxT("&Contents...\tF1"), - wxT("Simulator help")); - menuHelp->AppendSeparator(); - menuHelp->Append(IDM_HELP_ABOUT, wxT("&About..."), - wxT("See the fabulous 'about' box")); - - /* - * Create the menu bar. - */ - wxMenuBar *menuBar = new wxMenuBar; - menuBar->Append(menuFile, wxT("&File")); - menuBar->Append(menuDevice, kDeviceMenuString); - menuBar->Append(menuRuntime, wxT("&Runtime")); - menuBar->Append(menuDebug, wxT("&Debug")); - menuBar->Append(menuHelp, wxT("&Help")); - - SetMenuBar(menuBar); - -} - -/* - * Construct the "device" menu from our phone collection. - */ -wxMenu* MainFrame::CreateDeviceMenu(const char* defaultItemName) -{ - wxMenu* menuDevice = new wxMenu; - PhoneCollection* pCollection = PhoneCollection::GetInstance(); - int defaultModel = 0; - - for (int i = 0; i < pCollection->GetPhoneCount(); i++) { - PhoneData* pPhoneData = pCollection->GetPhoneData(i); - assert(pPhoneData != NULL); - - menuDevice->AppendRadioItem(IDM_DEVICE_SEL0 + i, - wxString::FromAscii(pPhoneData->GetTitle())); - - // use this one as default if the string matches - if (strcasecmp(pPhoneData->GetName(), defaultItemName) == 0) - defaultModel = i; - } - - menuDevice->Check(IDM_DEVICE_SEL0 + defaultModel, true); - - menuDevice->AppendSeparator(); - menuDevice->Append(IDM_DEVICE_RESCAN, wxT("Re-scan")); - - return menuDevice; -} - -/* - * Create some controls in the main window. - * - * The main frame doesn't use the normal background color that you find - * in dialog windows, so we create a "panel" and put all the controls - * on that. - */ -void MainFrame::ConstructControls(void) -{ - Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - wxPanel* base = new wxPanel(this, wxID_ANY); - wxBoxSizer* masterSizer = new wxBoxSizer(wxVERTICAL); - wxBoxSizer* tmpSizer; - wxStaticBoxSizer* displayOptSizer; - wxStaticBoxSizer* runtimeOptSizer; - wxStaticBoxSizer* onionSkinOptSizer; - wxComboBox* pModeSelection; - wxCheckBox* pUseGDB; - wxCheckBox* pUseValgrind; - wxCheckBox* pCheckJni; - wxCheckBox* pOverlayOnionSkin; - - displayOptSizer = new wxStaticBoxSizer(wxHORIZONTAL, base, - wxT("Configuration")); - runtimeOptSizer = new wxStaticBoxSizer(wxVERTICAL, base, - wxT("Runtime Options")); - onionSkinOptSizer = new wxStaticBoxSizer(wxVERTICAL, base, - wxT("Onion Skin Options")); - - /* - * Set up the configuration sizer (nee "display options"). - */ - tmpSizer = new wxBoxSizer(wxHORIZONTAL); - displayOptSizer->Add(tmpSizer); - tmpSizer->Add( - new wxStaticText(base, wxID_ANY, wxT("Device mode:"), - wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT), 0, wxALIGN_CENTER_VERTICAL); - pModeSelection = new wxComboBox(base, IDC_MODE_SELECT, wxT(""), - wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY); - tmpSizer->AddSpacer(kInterSpacing); - tmpSizer->Add(pModeSelection); - - displayOptSizer->AddSpacer(kInterSpacing); - - /* - * Configure the runtime options sizer. - */ - wxComboBox* pJavaAppName; - tmpSizer = new wxBoxSizer(wxHORIZONTAL); - pUseGDB = new wxCheckBox(base, IDC_USE_GDB, wxT("Use &debugger")); - tmpSizer->Add(pUseGDB); - tmpSizer->AddSpacer(kInterSpacing); - pUseValgrind = new wxCheckBox(base, IDC_USE_VALGRIND, wxT("Use &valgrind")); - tmpSizer->Add(pUseValgrind); - tmpSizer->AddSpacer(kInterSpacing); - pCheckJni = new wxCheckBox(base, IDC_CHECK_JNI, wxT("Check &JNI")); - tmpSizer->Add(pCheckJni); - - pJavaAppName = new wxComboBox(base, IDC_JAVA_APP_NAME, wxT(""), - wxDefaultPosition, wxSize(320, -1), NELEM(gStdJavaApps), gStdJavaApps, - wxCB_DROPDOWN); - wxBoxSizer* javaAppSizer = new wxBoxSizer(wxHORIZONTAL); - javaAppSizer->Add( - new wxStaticText(base, wxID_ANY, - wxT("Java app:"), - wxDefaultPosition, wxDefaultSize, - wxALIGN_LEFT), - 0, wxALIGN_CENTER_VERTICAL); - javaAppSizer->AddSpacer(kInterSpacing); - javaAppSizer->Add(pJavaAppName); - - runtimeOptSizer->Add(tmpSizer); - - runtimeOptSizer->AddSpacer(kInterSpacing); - runtimeOptSizer->Add(javaAppSizer); - runtimeOptSizer->AddSpacer(kInterSpacing); - - wxString tmpStr; - SetCheckFromPref(pUseGDB, "debug", false); - SetCheckFromPref(pUseValgrind, "valgrind", false); - SetCheckFromPref(pCheckJni, "check-jni", false); - if (pPrefs->GetString("java-app-name", /*ref*/ tmpStr)) - pJavaAppName->SetValue(tmpStr); - - /* - * Configure the onion skin options sizer. - */ - wxTextCtrl* pOnionSkinFileNameText; - wxButton* pOnionSkinFileButton; - wxSlider* pOnionSkinAlphaSlider; - tmpSizer = new wxBoxSizer(wxHORIZONTAL); - pOverlayOnionSkin = new wxCheckBox(base, - IDC_OVERLAY_ONION_SKIN, wxT("Overlay &onion skin")); - tmpSizer->Add(pOverlayOnionSkin); - - pOnionSkinFileNameText = new wxTextCtrl(base, - IDC_ONION_SKIN_FILE_NAME, wxT(""), - wxDefaultPosition, wxSize(250, -1), - wxTE_PROCESS_ENTER); - pOnionSkinFileButton = new wxButton(base, IDC_ONION_SKIN_BUTTON, - wxT("Choose")); - - wxBoxSizer* onionSkinFileNameSizer = new wxBoxSizer(wxHORIZONTAL); - onionSkinFileNameSizer->Add( - new wxStaticText(base, wxID_ANY, - wxT("Filename:"), - wxDefaultPosition, wxDefaultSize, - wxALIGN_LEFT), - 0, wxALIGN_CENTER_VERTICAL); - onionSkinFileNameSizer->AddSpacer(kInterSpacing); - onionSkinFileNameSizer->Add(pOnionSkinFileNameText); - onionSkinFileNameSizer->Add(pOnionSkinFileButton); - - wxBoxSizer * onionSkinAlphaSizer = new wxBoxSizer(wxHORIZONTAL); - int initialAlphaVal = 127; - pPrefs->GetInt("onion-skin-alpha-value", &initialAlphaVal); - pOnionSkinAlphaSlider = new wxSlider(base, IDC_ONION_SKIN_ALPHA_VAL, - initialAlphaVal, 0, 255, wxDefaultPosition, wxSize(150, 20)); - onionSkinAlphaSizer->Add( - new wxStaticText(base, wxID_ANY, - wxT("Transparency:"), - wxDefaultPosition, wxDefaultSize, - wxALIGN_LEFT), - 0, wxALIGN_CENTER_VERTICAL); - onionSkinAlphaSizer->AddSpacer(kInterSpacing); - onionSkinAlphaSizer->Add(pOnionSkinAlphaSlider, 1, wxCENTRE | wxALL, 5); - - onionSkinOptSizer->Add(tmpSizer); - onionSkinOptSizer->AddSpacer(kInterSpacing); - onionSkinOptSizer->Add(onionSkinFileNameSizer); - onionSkinOptSizer->Add(onionSkinAlphaSizer); - - wxString tmpStr2; - SetCheckFromPref(pOverlayOnionSkin, "overlay-onion-skin", false); - if (pPrefs->GetString("onion-skin-file-name", /*ref*/ tmpStr2)) - pOnionSkinFileNameText->SetValue(tmpStr2); - - /* - * Add the various components to the master sizer. - */ - masterSizer->Add(displayOptSizer); - masterSizer->AddSpacer(kInterSpacing * 2); - masterSizer->Add(runtimeOptSizer); - masterSizer->AddSpacer(kInterSpacing * 2); - masterSizer->Add(onionSkinOptSizer); - //masterSizer->AddSpacer(kInterSpacing); - - /* - * I don't see a way to guarantee that the window is wide enough to - * show the entire menu bar, so just throw some pixels at it. - */ - wxBoxSizer* minWidthSizer = new wxBoxSizer(wxVERTICAL); - minWidthSizer->Add(300, kEdgeSpacing); // forces minimum width - minWidthSizer->Add(masterSizer); - minWidthSizer->AddSpacer(kInterSpacing * 2); - - /* move us a few pixels in from the left */ - wxBoxSizer* indentSizer = new wxBoxSizer(wxHORIZONTAL); - indentSizer->AddSpacer(kEdgeSpacing); - indentSizer->Add(minWidthSizer); - indentSizer->AddSpacer(kEdgeSpacing); - - base->SetSizer(indentSizer); - - indentSizer->Fit(this); - indentSizer->SetSizeHints(this); -} - -/* - * Set the value of a checkbox based on a value from the config file. - */ -void MainFrame::SetCheckFromPref(wxCheckBox* pControl, const char* prefStr, - bool defaultVal) -{ - Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - assert(pPrefs != NULL); - - bool val = defaultVal; - pPrefs->GetBool(prefStr, &val); - - pControl->SetValue(val); -} - -/* - * Destructor. - */ -MainFrame::~MainFrame(void) -{ - PhoneCollection::DestroyInstance(); - - delete mExternalRuntimeThread; - delete mPropertyServerThread; - - // don't touch mpModeSelection -- child of window -} - -/* - * File->Quit or click on close box. - * - * If we want an "are you sure you want to quit" box, add it here. - */ -void MainFrame::OnClose(wxCloseEvent& event) -{ - Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - -/* - if (event.CanVeto()) - printf("Closing (can veto)\n"); - else - printf("Closing (mandatory)\n"); -*/ - - /* - * Generally speaking, Close() is not guaranteed to close the window. - * However, we want to use it here because (a) our windows are - * guaranteed to close, and (b) it provides our windows an opportunity - * to tell others that they are about to vanish. - */ - if (mpPhoneWindow != NULL) - mpPhoneWindow->Close(true); - - /* save position of main window */ - wxPoint pos = GetPosition(); - pPrefs->SetInt("window-main-x", pos.x); - pPrefs->SetInt("window-main-y", pos.y); - - /* save default device selection */ - int idx = GetSelectedDeviceIndex(); - if (idx >= 0) { - PhoneCollection* pCollection = PhoneCollection::GetInstance(); - PhoneData* pPhoneData = pCollection->GetPhoneData(idx); - pPrefs->SetString("default-device", pPhoneData->GetName()); - } - - if (mpLogWindow != NULL) - mpLogWindow->Close(true); - Destroy(); -} - -/* - * File->Preferences - */ -void MainFrame::OnFilePreferences(wxCommandEvent& WXUNUSED(event)) -{ - Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - PrefsDialog dialog(this); - int result; - - result = dialog.ShowModal(); - if (result == wxID_OK) { - /* - * The dialog handles writing changes to Preferences, so all we - * need to deal with here are changes that have an immediate - * impact on us. (which is currently nothing) - */ - } -} - -/* - * File->Exit - */ -void MainFrame::OnFileExit(wxCommandEvent& WXUNUSED(event)) -{ - Close(FALSE); // false means "allow veto" -} - -/* - * Decide whether Simulator->Start should be enabled. - */ -void MainFrame::OnUpdateSimStart(wxUpdateUIEvent& event) -{ - if (IsRuntimeRunning()) - event.Enable(FALSE); - else - event.Enable(TRUE); -} - -/* - * Simulator->Start - */ -void MainFrame::OnSimStart(wxCommandEvent& WXUNUSED(event)) -{ - // keyboard equivalents can still get here even if menu item disabled - if (IsRuntimeRunning()) - return; - - int id = GetSelectedDeviceIndex(); - if (id < 0) { - fprintf(stderr, "Sim: could not identify currently selected device\n"); - return; - } - -#if 0 - static int foo = 0; - foo++; - if (foo == 2) { - Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - - pPrefs->SetBool("debug", true); - } -#endif - - SetupPhoneUI(id, NULL); - if (mpPhoneWindow != NULL) - mpPhoneWindow->GetDeviceManager()->StartRuntime(); -} - -/* - * Decide whether Simulator->Stop should be enabled. - */ -void MainFrame::OnUpdateSimStop(wxUpdateUIEvent& event) -{ - if (IsRuntimeRunning()) - event.Enable(TRUE); - else - event.Enable(FALSE); -} - -/* - * Simulator->Stop - */ -void MainFrame::OnSimStop(wxCommandEvent& WXUNUSED(event)) -{ - if (!IsRuntimeRunning()) - return; - assert(mpPhoneWindow != NULL); - mpPhoneWindow->GetDeviceManager()->StopRuntime(); -} - -/* - * Decide whether Simulator->Restart should be enabled. - */ -void MainFrame::OnUpdateSimRestart(wxUpdateUIEvent& event) -{ - if (IsRuntimeRunning()) - event.Enable(TRUE); - else - event.Enable(FALSE); -} - -/* - * Simulator->Restart - stop then start the device runtime. - */ -void MainFrame::OnSimRestart(wxCommandEvent& WXUNUSED(event)) -{ - if (!IsRuntimeRunning()) - return; - - printf("Restart requested\n"); - mpPhoneWindow->GetDeviceManager()->StopRuntime(); - - mRestartRequested = true; -} - -/* - * Decide whether Simulator->Kill should be enabled. - */ -void MainFrame::OnUpdateSimKill(wxUpdateUIEvent& event) -{ - if (IsRuntimeKillable()) - event.Enable(TRUE); - else - event.Enable(FALSE); -} - -/* - * Simulator->Kill - */ -void MainFrame::OnSimKill(wxCommandEvent& WXUNUSED(event)) -{ - if (!IsRuntimeKillable()) - return; - assert(mpPhoneWindow != NULL); - mpPhoneWindow->GetDeviceManager()->KillRuntime(); -} - - -/* - * Device->[select] - */ -void MainFrame::OnDeviceSelected(wxCommandEvent& event) -{ - wxBusyCursor busyc; - int id = event.GetId() - IDM_DEVICE_SEL0; - - SetupPhoneUI(id, NULL); -} - -/* - * Device->Rescan - */ -void MainFrame::OnDeviceRescan(wxCommandEvent& event) -{ - wxBusyCursor busyc; - wxMenuBar* pMenuBar; - PhoneCollection* pCollection; - wxMenu* pOldMenu; - wxMenu* pNewMenu; - const char* curDevName = NULL; - int idx; - - /* figure out the current device name */ - pCollection = PhoneCollection::GetInstance(); - idx = GetSelectedDeviceIndex(); - if (idx >= 0) { - PhoneData* pPhoneData; - - pPhoneData = pCollection->GetPhoneData(idx); - curDevName = pPhoneData->GetName(); - printf("--- device name is '%s'\n", (const char*) curDevName); - } - - /* reconstruct device menu with new data */ -#ifdef BEFORE_ASSET - pCollection->ScanForPhones(mSimAssetPath); -#else - pCollection->ScanForPhones(NULL); -#endif - - pMenuBar = GetMenuBar(); - idx = pMenuBar->FindMenu(kDeviceMenuString); - if (idx == wxNOT_FOUND) { - fprintf(stderr, "Sim: couldn't find %s menu\n", (const char*) kDeviceMenuString.ToAscii()); - return; - } - - pNewMenu = CreateDeviceMenu(curDevName); - - pOldMenu = pMenuBar->Replace(idx, pNewMenu, kDeviceMenuString); - delete pOldMenu; - - /* tell the PhoneWindow about it; may cause runtime to exit */ - if (mpPhoneWindow != NULL) - mpPhoneWindow->DevicesRescanned(); -} - -/* - * Set checkbox on menu item. - */ -void MainFrame::OnUpdateDebugShowLog(wxUpdateUIEvent& event) -{ - if (mpLogWindow == NULL) { - event.Enable(false); - } else { - event.Enable(true); - event.Check(mpLogWindow->IsShown()); - } -} - -/* - * Debug->ShowLog toggle. - */ -void MainFrame::OnDebugShowLog(wxCommandEvent& WXUNUSED(event)) -{ - mpLogWindow->Show(!mpLogWindow->IsShown()); -} - -/* - * Help->Contents - */ -void MainFrame::OnHelpContents(wxCommandEvent& WXUNUSED(event)) -{ - ((MyApp*)wxTheApp)->GetHelpController()->DisplayContents(); -} - -/* - * Help->About - */ -void MainFrame::OnHelpAbout(wxCommandEvent& WXUNUSED(event)) -{ - wxMessageBox(wxT("Android Simulator v0.1\n" - "Copyright 2006 The Android Open Source Project"), - wxT("About..."), wxOK | wxICON_INFORMATION, this); -} - -/* - * Sent from phonewindow or when activated - */ -void MainFrame::OnActivate(wxActivateEvent& event) -{ -#if 0 - if (event.GetActive()) - { - if (mpPhoneWindow != NULL && - mpPhoneWindow->GetDeviceManager()->RefreshRuntime()) - { - wxString msg; - int sel; - - msg = wxT("Newer runtime executable found. Would you like to reload the device?"); - - sel = wxMessageBox(msg, wxT("Android Safety Patrol"), - wxYES | wxNO | wxICON_QUESTION, mpPhoneWindow); - //printf("BUTTON was %d (yes=%d)\n", sel, wxYES); - if (sel == wxYES) - { - mpPhoneWindow->GetDeviceManager()->StopRuntime(); - mpPhoneWindow->Close(); - mpPhoneWindow = NULL; - mRestartRequested = true; - } - else - { - mpPhoneWindow->GetDeviceManager()->UserCancelledRefresh(); - } - } - } -#endif - - // let wxWidgets do whatever it needs to do - event.Skip(); -} - - -/* - * Device mode selection box. - */ -void MainFrame::OnComboBox(wxCommandEvent& event) -{ - const char* pref; - Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - assert(pPrefs != NULL); - - if (IDC_MODE_SELECT == event.GetId()) - { - int id = GetSelectedDeviceIndex(); - if (id < 0) - return; - //printf("--- mode selected: '%s'\n", (const char*) event.GetString().ToAscii()); - - /* - * Call the phone window's setup function. Don't call our SetupPhoneUI - * function from here -- updating the combo box from a combo box callback - * could cause problems. - */ - if (mpPhoneWindow != NULL) { - mpPhoneWindow->SetCurrentMode(event.GetString()); - mpPhoneWindow->Setup(id); - } - } else if (event.GetId() == IDC_JAVA_VM) { - wxComboBox* pBox = (wxComboBox*) FindWindow(IDC_JAVA_VM); - pPrefs->SetString("java-vm", pBox->GetValue().ToAscii()); - } -} - -/* - * One of our option checkboxes has been changed. - * - * We update the prefs database so that the settings are retained when - * the simulator is next used. - */ -void MainFrame::OnCheckBox(wxCommandEvent& event) -{ - const char* pref; - - switch (event.GetId()) { - case IDC_USE_GDB: pref = "debug"; break; - case IDC_USE_VALGRIND: pref = "valgrind"; break; - case IDC_CHECK_JNI: pref = "check-jni"; break; - case IDC_OVERLAY_ONION_SKIN: pref = "overlay-onion-skin"; break; - default: - printf("Sim: unrecognized checkbox %d in OnCheckBox\n", event.GetId()); - return; - } - - Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - assert(pPrefs != NULL); - - pPrefs->SetBool(pref, (bool) event.GetInt()); - //printf("--- set pref '%s' to %d\n", pref, (bool) event.GetInt()); - if (event.GetId() == IDC_OVERLAY_ONION_SKIN) { - BroadcastOnionSkinUpdate(); - } - if (event.GetId() == IDC_CHECK_JNI) { - const char* val = "0"; - if ((bool) event.GetInt()) - val = "1"; - mPropertyServerThread->SetProperty(PropertyServer::kPropCheckJni, val); - - } -} - -void MainFrame::BroadcastOnionSkinUpdate() { - if (mpPhoneWindow != NULL) { - // broadcast a user event indicating an onion skin update - UserEvent uev(0, (void*) -1); - mpPhoneWindow->GetDeviceManager()->BroadcastEvent(uev); - } -} - -/* - * A text control on the main page is being updated. - * - * The current implementation updates the preferences database on every - * change, which is a bit silly but is easy to do. - */ -void MainFrame::OnText(wxCommandEvent& event) -{ - const char* pref; - - switch (event.GetId()) { - case IDC_JAVA_APP_NAME: pref = "java-app-name"; break; - default: - printf("Sim: unrecognized textctrl %d in OnText\n", event.GetId()); - return; - } - - Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - assert(pPrefs != NULL); - - // event.GetString() does not work on Mac -- always blank - //pPrefs->SetString(pref, event.GetString()); - assert(event.GetId() == IDC_JAVA_APP_NAME); // fix if we add more - wxComboBox* pBox; - pBox = (wxComboBox*) FindWindow(IDC_JAVA_APP_NAME); - pPrefs->SetString(pref, pBox->GetValue().ToAscii()); - //printf("--- set pref '%s' to '%s'\n", pref,(const char*)pBox->GetValue()); -} - -/* - * A user pressed enter in a text control on the main page. - * - * The current implementation updates the preferences database on every - * change, which is a bit silly but is easy to do. - */ -void MainFrame::OnTextEnter(wxCommandEvent& event) -{ - const char* pref; - - switch (event.GetId()) { - case IDC_ONION_SKIN_FILE_NAME: - pref = "onion-skin-file-name"; - break; - default: - printf("Sim: unrecognized textctrl %d in OnTextEnter\n", event.GetId()); - return; - } - - Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - assert(pPrefs != NULL); - - assert(event.GetId() == IDC_ONION_SKIN_FILE_NAME); // fix if we add more - wxTextCtrl* pTextCtrl; - pTextCtrl = (wxTextCtrl*) FindWindow(IDC_ONION_SKIN_FILE_NAME); - wxString onionSkinFileNameWxString = pTextCtrl->GetValue(); - char* onionSkinFileName = ""; - if (onionSkinFileNameWxString.Len() > 0) { - onionSkinFileName = android::strdupNew(onionSkinFileNameWxString.ToAscii()); - } - pPrefs->SetString(pref, onionSkinFileName); - BroadcastOnionSkinUpdate(); -} - -/* - * A user pressed a button on the main page - * - */ - void MainFrame::OnButton(wxCommandEvent& event) - { - wxWindow* base; - wxFileDialog* pOnionSkinFileChooser; - int retVal; - switch (event.GetId()) { - case IDC_ONION_SKIN_BUTTON: - base = FindWindow(IDC_ONION_SKIN_BUTTON)->GetParent(); - pOnionSkinFileChooser = new wxFileDialog(base, - wxT("Choose the onion skin image file."), - wxT(""), wxT(""), wxT("*.*"), - wxOPEN | wxFILE_MUST_EXIST); - retVal = pOnionSkinFileChooser->ShowModal(); - if (retVal == pOnionSkinFileChooser->GetAffirmativeId()) { - Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - assert(pPrefs != NULL); - wxString fileNameWxString = pOnionSkinFileChooser->GetPath(); - const char* fileName = android::strdupNew(fileNameWxString.ToAscii()); - wxTextCtrl* fileTextCtrl = (wxTextCtrl*) FindWindow(IDC_ONION_SKIN_FILE_NAME); - fileTextCtrl->SetValue(fileNameWxString); - pPrefs->SetString("onion-skin-file-name", fileName); - BroadcastOnionSkinUpdate(); - } - break; - default: - printf("Sim: unrecognized button %d in OnButton\n", event.GetId()); - return; - } - } - - /* - * The user moved a slider on the main page - */ - void MainFrame::OnSliderChange(wxScrollEvent& event) - { - wxSlider* pSlider; - Preferences* pPrefs; - switch (event.GetId()) { - case IDC_ONION_SKIN_ALPHA_VAL: - pSlider = (wxSlider*) FindWindow(IDC_ONION_SKIN_ALPHA_VAL); - pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - assert(pPrefs != NULL); - pPrefs->SetInt("onion-skin-alpha-value", pSlider->GetValue()); - BroadcastOnionSkinUpdate(); - break; - default: - printf("Sim: unrecognized scroller or slider %d in OnSliderChange\n", event.GetId()); - return; - } - } - -#if 0 -/* - * Idle processing. Under wxWidgets this only called once after UI - * activity unless you call event.RequestMore(). - */ -void MainFrame::OnIdle(wxIdleEvent& event) -{ - event.Skip(); // let base class handler do stuff -} -#endif - -/* - * Handle the timer. - * - * This is being called in the main thread, so multithreading with the - * rest of MainFrame isn't a concern here. - */ -void MainFrame::OnTimer(wxTimerEvent& event) -{ - bool status; - - /* - * Check to see if the runtime died without telling us. This can only - * happen if we forcibly kill our thread. We shouldn't really be - * doing that anymore, but keep this in for now just in case. - */ - status = IsRuntimeRunning(); - - if (mSimRunning != status) { - if (!status) { - printf("Sim: fixed mSimRunning=%d actual=%d\n", - mSimRunning, status); - mSimRunning = status; - - if (!status) - HandleRuntimeStop(); - } else { - /* - * This was happening when we were shutting down but the - * device management thread hadn't completely gone away. The - * simple IsRunning test passes, so we get a false positive. - * Ignore it. - */ - } - } - - if (gWantToKill) { - if (IsRuntimeRunning()) { - printf("Sim: handling kill request\n"); - mpPhoneWindow->GetDeviceManager()->KillRuntime(); - } - gWantToKill = false; - - /* see if Ctrl-C should kill us too */ - Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - bool die = false; - - pPrefs->GetBool("trap-sigint-suicide", &die); - if (die) { - printf("Sim: goodbye cruel world!\n"); - exit(0); - } - } -} - -/* - * Determine whether or not the simulator is running. - */ -bool MainFrame::IsRuntimeRunning(void) -{ - bool result; - - if (mpPhoneWindow == NULL) - result = false; - else if (!mpPhoneWindow->IsReady()) - result = false; - else - result = mpPhoneWindow->GetDeviceManager()->IsRunning(); - - return result; -} - -/* - * Determine whether or not the runtime can be killed. - */ -bool MainFrame::IsRuntimeKillable(void) -{ - bool result; - - result = IsRuntimeRunning(); - if (result) - result = mpPhoneWindow->GetDeviceManager()->IsKillable(); - - return result; -} - -/* - * Determine whether two devices are sufficiently compatible. - */ -bool MainFrame::CompatibleDevices(PhoneData* pData1, PhoneData* pData2) -{ - int displayCount; - - displayCount = pData1->GetNumDisplays(); - if (pData2->GetNumDisplays() != displayCount) - return false; - - for (int i = 0; i < displayCount; i++) { - PhoneDisplay* pDisplay1 = pData1->GetPhoneDisplay(i); - PhoneDisplay* pDisplay2 = pData2->GetPhoneDisplay(i); - - if (!PhoneDisplay::IsCompatible(pDisplay1, pDisplay2)) - return false; - } - - return true; -} - -/* - * (Re-)arrange the UI for the currently selected phone model. - * - * If the simulator is running, and the set of displays for the current - * device are incompatible with the new device, we need to restart the - * runtime. We need to ask for permission first though. - */ -void MainFrame::SetupPhoneUI(int idx, const char* defaultMode) -{ - PhoneCollection* pCollection; - PhoneData* pPhoneData; - wxString* choices = NULL; - int numChoices = 0; - int numKeyboards = 0; - bool haveDefaultMode = false; - wxCharBuffer currentMode; - int i; - - pCollection = PhoneCollection::GetInstance(); - pPhoneData = pCollection->GetPhoneData(idx); - if (pPhoneData == NULL) { - fprintf(stderr, "ERROR: device index %d not valid\n", idx); - goto bail; - } - - /* - * We have a window up. If the displays aren't compatible, we'll - * need to recreate it. - */ - if (mpPhoneWindow != NULL) { - PhoneData* pCurData = mpPhoneWindow->GetPhoneData(); - - if (!CompatibleDevices(pCurData, pPhoneData)) { - /* - * We need to trash the window. This will also kill the - * runtime. If it's running, ask permission. - */ - if (IsRuntimeRunning()) { - wxString msg; - int sel; - - msg = wxT("Switching to the new device requires restarting the"); - msg += wxT(" runtime. Continue?"); - - sel = wxMessageBox(msg, wxT("Android Safety Patrol"), - wxOK | wxCANCEL | wxICON_QUESTION, this); - printf("BUTTON was %d (ok=%d)\n", sel, wxOK); - if (sel == wxCANCEL) - goto bail; - - /* shut it down (politely), ask for an eventual restart */ - mpPhoneWindow->GetDeviceManager()->StopRuntime(); - mpPhoneWindow->Close(); - mpPhoneWindow = NULL; - mRestartRequested = true; - goto bail; - } else { - /* not running, just trash the window and continue */ - mpPhoneWindow->Close(); - mpPhoneWindow = NULL; - } - } - } - - /* - * Figure out the set of available modes. - */ - - numChoices = pPhoneData->GetNumModes(); - if (numChoices > 0) { - choices = new wxString[numChoices]; - for (i = 0; i < numChoices; i++) { - PhoneMode* pPhoneMode; - pPhoneMode = pPhoneData->GetPhoneMode(i); - choices[i] = wxString::FromAscii(pPhoneMode->GetName()); - if (defaultMode != NULL && - strcmp(defaultMode, pPhoneMode->GetName()) == 0) - { - haveDefaultMode = true; - } - } - } - - if (choices == NULL) { - /* had a failure earlier; configure UI with default stuff */ - choices = new wxString[1]; - choices[0] = wxT("(none)"); - } - - if (!haveDefaultMode) { - /* - * Default mode wasn't found. If we specify it as the default - * in the wxComboBox create call it shows up in the combo box - * under Linux, even if it doesn't exist in the list. So, we - * make sure that it doesn't get used if we can't find it. - */ - if (defaultMode != NULL) { - printf("Sim: HEY: default mode '%s' not found in list\n", - defaultMode); - } - currentMode = choices[0].ToAscii(); - } else { - currentMode = defaultMode; - } - - - /* - * Create the window if necessary. - */ - if (mpPhoneWindow == NULL) { - // create, setup, and then show window - mpPhoneWindow = new PhoneWindow(this, mPhoneWindowPosn); - mpPhoneWindow->SetCurrentMode((const char*)currentMode); - if (!mpPhoneWindow->Setup(idx)) { - delete mpPhoneWindow; - mpPhoneWindow = NULL; - } - if (mpPhoneWindow != NULL) { - mpPhoneWindow->Show(); - //mpPhoneWindow->CheckPlacement(); - } - } else { - // just set up for new device - mpPhoneWindow->SetCurrentMode((const char*)currentMode); - if (!mpPhoneWindow->Setup(idx)) { - // it's in an uncertain state, blow it away - delete mpPhoneWindow; - mpPhoneWindow = NULL; - } - } - - /* - * Reconfigure mode selection box. - */ - wxComboBox* pModeSelection; - pModeSelection = (wxComboBox*)FindWindow(IDC_MODE_SELECT); - pModeSelection->Clear(); - for (i = 0; i < numChoices; i++) - pModeSelection->Append(choices[i]); - pModeSelection->SetSelection(0); - pModeSelection->Enable(numChoices > 1); - - /* - * configure qwerty keyboard attribute - */ - numKeyboards = pPhoneData->GetNumKeyboards(); - if (numKeyboards > 0) { - // only use the first keyboard for now - PhoneKeyboard* pPhoneKeyboard; - pPhoneKeyboard = pPhoneData->GetPhoneKeyboard(0); - if (pPhoneKeyboard->getQwerty()) { - printf("Sim: set 'qwerty' env\n"); - setenv("qwerty", "true", true); - } - } - -bail: - delete[] choices; -} - -/* - * Figure out which device is currently selected. - * - * The easiest way to do this is just run down the list of possible IDs - * and stop when something claims to be checked. - * - * Returns -1 if it can't find a checked item (which can happen if no - * device layouts were found). - */ -int MainFrame::GetSelectedDeviceIndex(void) -{ - wxMenuBar* pMenuBar; - wxMenu* pMenu; - int idx; - - pMenuBar = GetMenuBar(); - idx = pMenuBar->FindMenu(kDeviceMenuString); - if (idx == wxNOT_FOUND) { - fprintf(stderr, "Sim: couldn't find %s menu\n", (const char*) kDeviceMenuString.ToAscii()); - return -1; - } - - pMenu = pMenuBar->GetMenu(idx); - - //printf("Menu.MenuItemCount = %d\n", pMenu->GetMenuItemCount()); - for (int j = pMenu->GetMenuItemCount() -1; j >= 0; j--) { - wxMenuItem* pItem; - - pItem = pMenu->FindItemByPosition(j); - //printf("ITEM %d: %s\n", j, (const char*) pItem->GetLabel()); - if (pItem->IsChecked()) { - printf("Sim: selected device is '%s'\n", - (const char*) pItem->GetLabel().ToAscii()); - return j; - } - } - - return -1; -} - -/* - * Receive a status message from the runtime thread. - */ -void MainFrame::OnUserEvent(UserEvent& event) -{ - UserEventMessage* pUem; - - pUem = (UserEventMessage*) event.GetData(); - assert(pUem != NULL); - - switch (pUem->GetType()) { - case UserEventMessage::kRuntimeStarted: - printf("Sim: runtime thread started!\n"); - HandleRuntimeStart(); - break; - case UserEventMessage::kRuntimeStopped: - printf("Sim: runtime thread stopped!\n"); - HandleRuntimeStop(); - break; - case UserEventMessage::kErrorMessage: - { - wxString msg = pUem->GetString(); - wxMessageBox(msg, wxT("Android Runtime Error"), - wxOK | wxICON_WARNING, this); - } - break; - case UserEventMessage::kLogMessage: - mpLogWindow->AddLogMessage(pUem->GetLogMessage()); - break; - case UserEventMessage::kExternalRuntime: - HandleExternalRuntime(pUem->GetReader(), pUem->GetWriter()); - break; - default: - printf("Sim: MESSAGE: unknown UserEventMessage rcvd (type=%d)\n", - pUem->GetType()); - break; - } - - delete pUem; -} - -/* - * The device management thread is up, so the runtime should be fully - * running shortly. - */ -void MainFrame::HandleRuntimeStart(void) -{ - mSimRunning = true; - - SetStatusText(kStatusRunning, 1); -} - -/* - * The device management thread is exiting, so the runtime must be dead. - */ -void MainFrame::HandleRuntimeStop(void) -{ - mSimRunning = false; - - SetStatusText(kStatusNotRunning, 1); - - if (mRestartRequested) { - printf("Sim: restarting runtime\n"); - mRestartRequested = false; - SetupPhoneUI(GetSelectedDeviceIndex(), NULL); - if (mpPhoneWindow != NULL) - mpPhoneWindow->GetDeviceManager()->StartRuntime(); - } -} - -/* - * Handle a connection from an external runtime. - */ -void MainFrame::HandleExternalRuntime(android::Pipe* reader, - android::Pipe* writer) -{ - android::MessageStream msgStream; - android::Message msg; - - if (IsRuntimeRunning()) { - /* - * Tell the new guy to go away. - */ - if (!msgStream.init(reader, writer, true)) { - fprintf(stderr, "Sim: WARNING: unable to talk to remote runtime\n"); - goto bail; - } - - printf("Sim: telling external runtime to go away\n"); - msg.setCommand(android::Simulator::kCommandGoAway, 0); - msgStream.send(&msg); - } else { - printf("Sim: new external runtime wants to talk to us\n"); - - /* - * Launch the pieces necessary to talk to this guy. - */ - int id = GetSelectedDeviceIndex(); - if (id < 0) { - fprintf(stderr, - "Sim: could not identify currently selected device\n"); - goto bail; - } - - /* kill existing window, so it pops up and reclaims focus */ - if (mpPhoneWindow != NULL) { - Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - bool okay; - - if (pPrefs->GetBool("refocus-on-restart", &okay) && okay) { - printf("Sim: inducing phone window refocus\n"); - mpPhoneWindow->Close(TRUE); // no veto - mpPhoneWindow = NULL; - } - } - - SetupPhoneUI(id, NULL); - if (mpPhoneWindow != NULL) { - mpPhoneWindow->GetDeviceManager()->StartRuntime(reader, writer); - } else { - fprintf(stderr, "Sim: ERROR: unable to get runtime going\n"); - goto bail; - } - - // we don't own these anymore - reader = writer = NULL; - } - -bail: - delete reader; - delete writer; -} - -/* - * The phone window is about to destroy itself. Get rid of our pointer - * to it, and record its last position so we can create the new one in - * the same place. - */ -void MainFrame::PhoneWindowClosing(int x, int y) -{ - Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - - mpPhoneWindow = NULL; - - mPhoneWindowPosn.x = x; - mPhoneWindowPosn.y = y; - - pPrefs->SetInt("window-device-x", x); - pPrefs->SetInt("window-device-y", y); -} - diff --git a/simulator/app/MainFrame.h b/simulator/app/MainFrame.h deleted file mode 100644 index 817a1820c..000000000 --- a/simulator/app/MainFrame.h +++ /dev/null @@ -1,115 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Main window declaration. -// -#ifndef _SIM_MAINFRAME_H -#define _SIM_MAINFRAME_H - -#include "PhoneWindow.h" -#include "DeviceWindow.h" -#include "LogWindow.h" -#include "ExternalRuntime.h" -#include "PropertyServer.h" - -/* - * Main window. - */ -class MainFrame : public wxFrame { -public: - /* define a constructor so we can set up menus */ - MainFrame(const wxString& title, const wxPoint& pos, const wxSize& size, - long style); - virtual ~MainFrame(void); - - /* called by modeless phone window dialog when it closes */ - void PhoneWindowClosing(int x, int y); - - void Vibrate(int vibrateOn) { mpPhoneWindow->Vibrate(vibrateOn); } - - PropertyServer* GetPropertyServer(void) { return mPropertyServerThread; } - -private: - void ConstructMenu(void); - void ConstructControls(void); - - void OnClose(wxCloseEvent& event); - void OnTimer(wxTimerEvent& event); - //void OnIdle(wxIdleEvent& event); - void OnActivate(wxActivateEvent& event); - void OnButton(wxCommandEvent& event); - void OnComboBox(wxCommandEvent& event); - void OnCheckBox(wxCommandEvent& event); - void OnText(wxCommandEvent& event); - void OnTextEnter(wxCommandEvent& event); - void OnUserEvent(UserEvent& event); - void OnSliderChange(wxScrollEvent& event); - - void OnFilePreferences(wxCommandEvent& event); - void OnFileExit(wxCommandEvent& event); - void OnUpdateSimStart(wxUpdateUIEvent& event); - void OnSimStart(wxCommandEvent& event); - void OnUpdateSimStop(wxUpdateUIEvent& event); - void OnSimStop(wxCommandEvent& event); - void OnUpdateSimReload(wxUpdateUIEvent& event); - void OnSimReload(wxCommandEvent& event); - void OnUpdateSimRestart(wxUpdateUIEvent& event); - void OnSimRestart(wxCommandEvent& event); - void OnUpdateSimKill(wxUpdateUIEvent& event); - void OnSimKill(wxCommandEvent& event); - void OnDeviceSelected(wxCommandEvent& event); - void OnDeviceRescan(wxCommandEvent& event); - void OnUpdateDebugShowLog(wxUpdateUIEvent& event); - void OnDebugShowLog(wxCommandEvent& event); - void OnHelpContents(wxCommandEvent& event); - void OnHelpAbout(wxCommandEvent& event); - - wxMenu* CreateDeviceMenu(const char* defaultItemName); - void SetCheckFromPref(wxCheckBox* pControl, const char* prefStr, - bool defaultVal); - - void UpdateRuntimeExeStr(void); - - /* prep the phone UI; "defaultMode" may be NULL */ - void SetupPhoneUI(int idx, const char* defaultMode); - - bool CompatibleDevices(PhoneData* pData1, PhoneData* pData2); - - void HandleRuntimeStart(void); - void HandleRuntimeStop(void); - void HandleExternalRuntime(android::Pipe* reader, android::Pipe* writer); - - int GetSelectedDeviceIndex(void); - bool IsRuntimeRunning(void); - bool IsRuntimeKillable(void); - - void BroadcastOnionSkinUpdate(void); - - bool mSimRunning; - bool mRestartRequested; - - enum { kHalfSecondTimerId = 1000 }; - - wxString mSimAssetPath; - - /* if we have a phone running, this points to its state */ - PhoneWindow* mpPhoneWindow; - - /* phone window position */ - wxPoint mPhoneWindowPosn; - - /* window that captures log output */ - LogWindow* mpLogWindow; - - wxTimer mTimer; - - /* watches for connection from runtime */ - ExternalRuntime* mExternalRuntimeThread; - - /* serve up system properties */ - PropertyServer* mPropertyServerThread; - - DECLARE_EVENT_TABLE() -}; - -#endif // _SIM_MAINFRAME_H diff --git a/simulator/app/MessageStream.cpp b/simulator/app/MessageStream.cpp deleted file mode 100644 index 2397c63be..000000000 --- a/simulator/app/MessageStream.cpp +++ /dev/null @@ -1,402 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Message stream abstraction. -// -#include "MessageStream.h" -#include "LogBundle.h" - -#include "utils/Log.h" - -#include <string.h> -#include <assert.h> - -using namespace android; - -/* - * =========================================================================== - * Message - * =========================================================================== - */ - -/* - * Send a blob of raw data. - */ -void Message::setRaw(const unsigned char* data, int len, Cleanup cleanup) -{ - reset(); - - mData = const_cast<unsigned char*>(data); - mLength = len; - mCleanup = cleanup; - mType = kTypeRaw; -} - -/* - * Send a "name=value" config pair. - */ -void Message::setConfig(const char* name, const char* value) -{ - reset(); - - assert(name != NULL && value != NULL); - - int nlen = strlen(name) +1; - int vlen = strlen(value) +1; - mData = new unsigned char[nlen+vlen]; - mCleanup = kCleanupDelete; - mLength = nlen + vlen; - mType = kTypeConfig; - - memcpy(mData, name, nlen); - memcpy(mData + nlen, value, vlen); -} - -/* - * Try to return the contents of the message as if it were a name/value pair. - */ -bool Message::getConfig(const char** pName, const char** pValue) -{ - if (mLength < 2) - return false; - assert(mData != NULL); - - *pName = (const char*) mData; - *pValue = (const char*) (mData + strlen((char*)mData) +1); - return true; -} - -/* - * Send a command/arg pair. - */ -void Message::setCommand(int cmd, int arg) -{ - reset(); - - mData = new unsigned char[sizeof(int) * 2]; - mCleanup = kCleanupDelete; - mLength = sizeof(int) * 2; - mType = kTypeCommand; - - int* pInt = (int*) mData; - pInt[0] = cmd; - pInt[1] = arg; -} - -/* - * Send a command with 3 args instead of just one. - */ -void Message::setCommandExt(int cmd, int arg0, int arg1, int arg2) -{ - reset(); - - mData = new unsigned char[sizeof(int) * 4]; - mCleanup = kCleanupDelete; - mLength = sizeof(int) * 4; - mType = kTypeCommandExt; - - int* pInt = (int*) mData; - pInt[0] = cmd; - pInt[1] = arg0; - pInt[2] = arg1; - pInt[3] = arg2; -} - -/* - * Try to return the contents of the message as if it were a "command". - */ -bool Message::getCommand(int* pCmd, int* pArg) -{ - if (mLength != sizeof(int) * 2) { - LOG(LOG_WARN, "", "type is %d, len is %d\n", mType, mLength); - return false; - } - assert(mData != NULL); - - const int* pInt = (const int*) mData; - *pCmd = pInt[0]; - *pArg = pInt[1]; - - return true; -} - -/* - * Serialize a log message. - * - * DO NOT call LOG() from here. - */ -void Message::setLogBundle(const android_LogBundle* pBundle) -{ - reset(); - - /* get string lengths; we add one here to include the '\0' */ - int tagLen, msgLen; - tagLen = strlen(pBundle->tag) + 1; - size_t i; - msgLen = 0; - for (i=0; i<pBundle->msgCount; i++) msgLen += pBundle->msgVec[i].iov_len; - msgLen += 1; - - /* set up the structure */ - mCleanup = kCleanupDelete; - mLength = sizeof(pBundle->when) + - sizeof(pBundle->priority) + - sizeof(pBundle->pid) + - tagLen + - msgLen; - mData = new unsigned char[mLength]; - mType = kTypeLogBundle; - - unsigned char* pCur = mData; - - /* copy the stuff over */ - *((time_t*)pCur) = pBundle->when; - pCur += sizeof(pBundle->when); - *((android_LogPriority*)pCur) = pBundle->priority; - pCur += sizeof(pBundle->priority); - *((pid_t*)pCur) = pBundle->pid; - pCur += sizeof(pBundle->pid); - memcpy(pCur, pBundle->tag, tagLen); - pCur += tagLen; - for (i=0; i<pBundle->msgCount; i++) { - memcpy(pCur, pBundle->msgVec[i].iov_base, pBundle->msgVec[i].iov_len); - pCur += pBundle->msgVec[i].iov_len; - } - *pCur++ = 0; - - assert(pCur - mData == mLength); -} - -/* - * Extract the components of a log bundle. - * - * We're just returning points inside the message buffer, so the caller - * will need to copy them out before the next reset(). - */ -bool Message::getLogBundle(android_LogBundle* pBundle) -{ - if (mLength < (int)(sizeof(time_t) + sizeof(int)*2 + 4)) { - LOG(LOG_WARN, "", "type is %d, len is %d, too small\n", - mType, mLength); - return false; - } - assert(mData != NULL); - - unsigned char* pCur = mData; - - pBundle->when = *((time_t*) pCur); - pCur += sizeof(pBundle->when); - pBundle->priority = *((android_LogPriority*) pCur); - pCur += sizeof(pBundle->priority); - pBundle->pid = *((pid_t*) pCur); - pCur += sizeof(pBundle->pid); - pBundle->tag = (const char*) pCur; - pCur += strlen((const char*) pCur) +1; - mVec.iov_base = (char*) pCur; - mVec.iov_len = strlen((const char*) pCur); - pBundle->msgVec = &mVec; - pBundle->msgCount = 1; - pCur += mVec.iov_len +1; - - if (pCur - mData != mLength) { - LOG(LOG_WARN, "", "log bundle rcvd %d, used %d\n", mLength, - (int) (pCur - mData)); - return false; - } - - return true; -} - -/* - * Read the next event from the pipe. - * - * This is not expected to work well when multiple threads are reading. - */ -bool Message::read(Pipe* pPipe, bool wait) -{ - if (pPipe == NULL) - return false; - assert(pPipe->isCreated()); - - if (!wait) { - if (!pPipe->readReady()) - return false; - } - - reset(); - - unsigned char header[4]; - if (pPipe->read(header, 4) != 4) - return false; - - mType = (MessageType) header[2]; - mLength = header[0] | header[1] << 8; - mLength -= 2; // we already read two of them in the header - - if (mLength > 0) { - int actual; - - mData = new unsigned char[mLength]; - if (mData == NULL) { - LOG(LOG_ERROR, "", "alloc failed\n"); - return false; - } - mCleanup = kCleanupDelete; - - actual = pPipe->read(mData, mLength); - if (actual != mLength) { - LOG(LOG_WARN, "", "failed reading message body (%d of %d bytes)\n", - actual, mLength); - return false; - } - } - - return true; -} - -/* - * Write this event to a pipe. - * - * It would be easiest to write the header and message body with two - * separate calls, but that will occasionally fail on multithreaded - * systems when the writes are interleaved. We have to allocate a - * temporary buffer, copy the data, and write it all at once. This - * would be easier with writev(), but we can't rely on having that. - * - * DO NOT call LOG() from here, as we could be in the process of sending - * a log message. - */ -bool Message::write(Pipe* pPipe) const -{ - char tmpBuf[128]; - char* writeBuf = tmpBuf; - bool result = false; - int kHeaderLen = 4; - - if (pPipe == NULL) - return false; - assert(pPipe->isCreated()); - - if (mData == NULL || mLength < 0) - return false; - - /* if it doesn't fit in stack buffer, allocate space */ - if (mLength + kHeaderLen > (int) sizeof(tmpBuf)) { - writeBuf = new char[mLength + kHeaderLen]; - if (writeBuf == NULL) - goto bail; - } - - /* - * The current value of "mLength" does not include the 4-byte header. - * Two of the 4 header bytes are included in the length we output - * (the type byte and the pad byte), so we adjust mLength. - */ - writeBuf[0] = (unsigned char) (mLength + kHeaderLen -2); - writeBuf[1] = (unsigned char) ((mLength + kHeaderLen -2) >> 8); - writeBuf[2] = (unsigned char) mType; - writeBuf[3] = 0; - if (mLength > 0) - memcpy(writeBuf + kHeaderLen, mData, mLength); - - int actual; - - actual = pPipe->write(writeBuf, mLength + kHeaderLen); - if (actual != mLength + kHeaderLen) { - fprintf(stderr, - "Message::write failed writing message body (%d of %d bytes)\n", - actual, mLength + kHeaderLen); - goto bail; - } - - result = true; - -bail: - if (writeBuf != tmpBuf) - delete[] writeBuf; - return result; -} - - -/* - * =========================================================================== - * MessageStream - * =========================================================================== - */ - -/* - * Get ready to go. - */ -bool MessageStream::init(Pipe* readPipe, Pipe* writePipe, bool initiateHello) -{ - assert(mReadPipe == NULL && mWritePipe == NULL); // only once - - /* - * Swap "hello" messages. - * - * In a more robust implementation, this would include version numbers - * and capability flags. - */ - if (initiateHello) { - long data = kHelloMsg; - Message msg; - - /* send hello */ - msg.setRaw((unsigned char*) &data, sizeof(data), - Message::kCleanupNoDelete); - if (!msg.write(writePipe)) { - LOG(LOG_WARN, "", "hello write failed in stream init\n"); - return false; - } - - LOG(LOG_DEBUG, "", "waiting for peer to ack my hello\n"); - - /* wait for the ack */ - if (!msg.read(readPipe, true)) { - LOG(LOG_WARN, "", "hello ack read failed in stream init\n"); - return false; - } - - const long* pAck; - pAck = (const long*) msg.getData(); - if (pAck == NULL || *pAck != kHelloAckMsg) { - LOG(LOG_WARN, "", "hello ack was bad\n"); - return false; - } - } else { - long data = kHelloAckMsg; - Message msg; - - LOG(LOG_DEBUG, "", "waiting for hello from peer\n"); - - /* wait for the hello */ - if (!msg.read(readPipe, true)) { - LOG(LOG_WARN, "", "hello read failed in stream init\n"); - return false; - } - - const long* pAck; - pAck = (const long*) msg.getData(); - if (pAck == NULL || *pAck != kHelloMsg) { - LOG(LOG_WARN, "", "hello was bad\n"); - return false; - } - - /* send hello ack */ - msg.setRaw((unsigned char*) &data, sizeof(data), - Message::kCleanupNoDelete); - if (!msg.write(writePipe)) { - LOG(LOG_WARN, "", "hello ack write failed in stream init\n"); - return false; - } - } - - /* success, set up our local stuff */ - mReadPipe = readPipe; - mWritePipe = writePipe; - - //LOG(LOG_DEBUG, "", "init success\n"); - - return true; -} - diff --git a/simulator/app/MessageStream.h b/simulator/app/MessageStream.h deleted file mode 100644 index de9c39848..000000000 --- a/simulator/app/MessageStream.h +++ /dev/null @@ -1,190 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// High-level message stream that sits on top of a pair of Pipes. Useful -// for inter-process communication, e.g. between "simulator" and "runtime". -// -// All messages are sent in packets: -// +00 16-bit length (of everything that follows), little-endian -// +02 8-bit message type -// +03 (reserved, must be zero) -// +04 message body -// -#ifndef _LIBS_UTILS_MESSAGE_STREAM_H -#define _LIBS_UTILS_MESSAGE_STREAM_H - -#ifdef HAVE_ANDROID_OS -#error DO NOT USE THIS FILE IN THE DEVICE BUILD -#endif - -#include <utils/Pipe.h> -#include <stdlib.h> -#include <cutils/uio.h> - -// Defined in LogBundle.h. -struct android_LogBundle; - -namespace android { - -/* - * A single message, which can be filled out and sent, or filled with - * received data. - * - * Message objects are reusable. - */ -class Message { -public: - Message(void) - : mCleanup(kCleanupUnknown) - { reset(); } - ~Message(void) { reset(); } - - /* values for message type byte */ - typedef enum MessageType { - kTypeUnknown = 0, - kTypeRaw, // chunk of raw data - kTypeConfig, // send a name=value pair to peer - kTypeCommand, // simple command w/arg - kTypeCommandExt, // slightly more complicated command - kTypeLogBundle, // multi-part log message - } MessageType; - - /* what to do with data when we're done */ - typedef enum Cleanup { - kCleanupUnknown = 0, - kCleanupNoDelete, // do not delete data when object destroyed - kCleanupDelete, // delete with "delete[]" - } Cleanup; - - /* - * Stuff raw data into the object. The caller can use the "cleanup" - * parameter to decide whether or not the Message object owns the data. - */ - void setRaw(const unsigned char* data, int len, Cleanup cleanup); - - /* - * Send a "name=value" pair. - */ - void setConfig(const char* name, const char* value); - - /* - * Send a command/arg pair. - */ - void setCommand(int cmd, int arg); - void setCommandExt(int cmd, int arg0, int arg1, int arg2); - - /* - * Send a multi-part log message. - */ - void setLogBundle(const android_LogBundle* pBundle); - - /* - * Simple accessors. - */ - MessageType getType(void) const { return mType; } - const unsigned char* getData(void) const { return mData; } - int getLength(void) const { return mLength; } - - /* - * Not-so-simple accessors. These coerce the raw data into an object. - * - * The data returned by these may not outlive the Message, so make - * copies if you plan to use them long-term. - */ - bool getConfig(const char** pName, const char** pValue); - bool getCommand(int* pCmd, int* pArg); - bool getLogBundle(android_LogBundle* pBundle); - - /* - * Read or write this message on the specified pipe. - * - * If "wait" is true, read() blocks until a message arrives. Only - * one thread should be reading at a time. - */ - bool read(Pipe* pPipe, bool wait); - bool write(Pipe* pPipe) const; - -private: - Message& operator=(const Message&); // not defined - Message(const Message&); // not defined - - void reset(void) { - if (mCleanup == kCleanupDelete) - delete[] mData; - - mType = kTypeUnknown; - mCleanup = kCleanupNoDelete; - mData = NULL; - mLength = -1; - } - - MessageType mType; - Cleanup mCleanup; - unsigned char* mData; - int mLength; - struct iovec mVec; -}; - - -/* - * Abstraction of higher-level communication channel. - * - * This may be used from multiple threads simultaneously. Blocking on - * the read pipe from multiple threads will have unpredictable behavior. - * - * Does not take ownership of the pipes passed in to init(). - */ -class MessageStream { -public: - MessageStream(void) - : mReadPipe(NULL), mWritePipe(NULL) - {} - ~MessageStream(void) {} - - /* - * Initialize object and exchange greetings. "initateHello" determines - * whether we send "Hello" or block waiting for it to arrive. Usually - * the "parent" initiates. - */ - bool init(Pipe* readPipe, Pipe* writePipe, bool initiateHello); - - bool isReady(void) const { return mReadPipe != NULL && mWritePipe != NULL; } - - /* - * Send a message immediately. - */ - bool send(const Message* pMsg) { return pMsg->write(mWritePipe); } - - /* - * Receive a message. - */ - bool recv(Message* pMsg, bool wait) { return pMsg->read(mReadPipe, wait); } - - /* - * Close communication pipes. Further attempts to send or receive - * will fail. Note this doesn't actually "close" the pipes, because - * we don't own them. - */ - void close(void) { mReadPipe = mWritePipe = NULL; } - - /* - * Get our incoming traffic pipe. This is useful on Linux systems - * because it allows access to the file descriptor which can be used - * in a select() call. - */ - Pipe* getReadPipe(void) { return mReadPipe; } - -private: - enum { - kHelloMsg = 0x4e303047, // 'N00G' - kHelloAckMsg = 0x31455221, // '1ER!' - }; - - /* communication pipes; note we don't own these */ - Pipe* mReadPipe; - Pipe* mWritePipe; -}; - -}; // namespace android - -#endif // _LIBS_UTILS_MESSAGE_STREAM_H diff --git a/simulator/app/MyApp.cpp b/simulator/app/MyApp.cpp deleted file mode 100644 index 313e44d80..000000000 --- a/simulator/app/MyApp.cpp +++ /dev/null @@ -1,547 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Application entry point. -// - -// For compilers that support precompilation, include "wx/wx.h". -#include "wx/wxprec.h" - -// Otherwise, include all standard headers -#ifndef WX_PRECOMP -# include "wx/wx.h" -#endif -#include "wx/image.h" // needed for Windows build -#include "wx/fs_zip.h" - -#include "MainFrame.h" -#include "MyApp.h" -#include <utils/executablepath.h> - -#include <stdio.h> -#include <unistd.h> -#include <getopt.h> -#include <signal.h> - -#if defined(HAVE_WINDOWS_PATHS) -# include <windows.h> -#endif - - -/* the name of our config file */ -static wxString kConfigFileName = wxT(".android.cf"); - -#ifdef HAVE_WINDOWS_PATHS -static wxString kExeSuffix = wxT(".exe"); -#else -static wxString kExeSuffix = wxT(""); -#endif - -/* do we want to kill the runtime? */ -bool gWantToKill = false; - -/* - * Signal handler for Ctrl-C. Under Linux we seem to get hit twice, - * possibly once for each thread. - * - * Avoid using LOG here -- it's not reentrant. Actually, just avoid doing - * anything here. - * - * Cygwin will ignore the signal but doesn't seem to call the signal - * handler. MinGW just kills the process. - */ -static void SignalHandler(int sigNum) -{ - printf("Sim: received signal %d (%s)\n", sigNum, - sigNum == SIGINT ? "SIGINT" : "???"); - gWantToKill = true; -} - - -/* wxWidgets magic; creates appropriate main entry function */ -IMPLEMENT_APP(MyApp) - -/* - * Application entry point. - */ -bool MyApp::OnInit() -{ - static wxString helpFilePath = wxT("simulator/help/unnamed.htb"); - - /* - * Parse args. - */ - - SetDefaults(); - - char** cargv = (char**)malloc(argc * sizeof(char*)); - for (int i=0; i<argc; i++) { - wxCharBuffer tmp = wxString(argv[i]).ToAscii(); - cargv[i] = tmp.release(); - } - if (!ParseArgs(argc, cargv)) { - for (int i=0; i<argc; i++) - free(cargv[i]); - free(cargv); - return FALSE; - } - for (int i=0; i<argc; i++) - free(cargv[i]); - free(cargv); - - if (!ProcessConfigFile()) - return FALSE; - - /* - * (Try to) catch SIGINT (Ctrl-C). - */ - bool trapInt = false; - mPrefs.GetBool("trap-sigint", &trapInt); - if (trapInt) { - printf("Sim: catching SIGINT\n"); - signal(SIGINT, SignalHandler); - } - - signal(SIGPIPE, SIG_IGN); - - /* - * Set stdout to unbuffered. This is needed for MinGW/MSYS. - * Set stderr while we're at it. - */ - setvbuf(stdout, NULL, _IONBF, 0); - setvbuf(stderr, NULL, _IONBF, 0); - - /* - * Initialize asset manager. - */ - mpAssetManager = NULL; - printf("Sim: looking in '%s' for my assets\n", (const char*) mSimAssetPath.ToAscii()); - ChangeAssetDirectory(mSimAssetPath); - - /* - * Add JPEG and PNG image handlers. - */ - ::wxInitAllImageHandlers(); - - /* - * Set up the help file browser. We're using wxHtmlHelpController - * because it seems to be the only "portable" version other than - * the "use external browser" version. - */ - wxFileSystem::AddHandler(new wxZipFSHandler); - mHelpController = new wxHtmlHelpController; - - wxString helpFileName; - helpFileName = mSimAssetPath; - helpFileName += '/'; - helpFileName += helpFilePath; - mHelpController->Initialize(helpFileName); - - /* - * Create the main window, which just holds some of our UI. - */ - wxPoint pos(wxDefaultPosition); - mPrefs.GetInt("window-main-x", &pos.x); - mPrefs.GetInt("window-main-y", &pos.y); - mpMainFrame = new MainFrame(wxT("Android Simulator"), pos, wxDefaultSize, - wxDEFAULT_FRAME_STYLE); - mpMainFrame->Show(TRUE); - SetTopWindow(mpMainFrame); - - return TRUE; -} - -/* - * Change our asset directory. This requires deleting the existing - * AssetManager and creating a new one. Note that any open Assets will - * still be valid. - */ -void MyApp::ChangeAssetDirectory(const wxString& dir) -{ - delete mpAssetManager; - mpAssetManager = new android::AssetManager; - android::String8 path(dir.ToAscii()); - path.appendPath("simulator.zip"); - mpAssetManager->addAssetPath(path, NULL); - // mpAssetManager->setLocale(xxx); - mpAssetManager->setVendor("google"); -} - - -/* - * App is shutting down. Save the config file. - */ -int MyApp::OnExit(void) -{ - if (mPrefs.GetDirty()) { - printf("Sim: writing config file to '%s'\n", - (const char*) mConfigFile.ToAscii()); - if (!mPrefs.Save(mConfigFile.ToAscii())) { - fprintf(stderr, "Sim: ERROR: prefs save to '%s' failed\n", - (const char*) mConfigFile.ToAscii()); - } - } - - return 0; -} - -static ssize_t -find_last_slash(const wxString& s) -{ - int slash = s.Last('/'); - if (slash < 0) { - slash = s.Last('\\'); - } - return slash; -} - - -/* - * Set some default parameters - */ -void MyApp::SetDefaults() -{ - mDebuggerOption = false; - - /* Get the path to this executable, which should - * end in something like "/host/linux-x86/bin/simulator". - * (The full path may begin with something like "out" - * or "out/debug".) - */ - char exepath[PATH_MAX]; - executablepath(exepath); - wxString out = wxString::FromAscii(exepath); - - /* Get the path to the root host directory; e.g., "out/host". - * We can do this by removing the last three slashes - * and everything after/between them ("/linux-x86/bin/simulator"). - */ - for (int i = 0; i < 3; i++) { - int slash = find_last_slash(out); - assert(slash >= 0); - out.Truncate(slash); - } - - /* Get the location of the assets directory; something like - * "out/host/common/sim-assets" - */ - mSimAssetPath = out; - mSimAssetPath.Append(wxT("/common/sim-assets")); - - /* Get the location of the simulated device filesystem. - * We can't reliably predict this based on the executable - * location, so try to get it from the environment. - */ - char *envOut = getenv("ANDROID_PRODUCT_OUT"); - if (envOut == NULL) { - fprintf(stderr, - "WARNING: $ANDROID_PRODUCT_OUT not set in environment\n"); - envOut = ""; - } - - // the root of the android stuff - mAndroidRoot = wxString::FromAscii(envOut); - mAndroidRoot.Append(wxT("/system")); - - // where runtime is - mRuntimeExe = mAndroidRoot; - mRuntimeExe.Append(wxT("/bin/runtime")); - mRuntimeExe.Append(kExeSuffix); - - printf("mAndroidRoot='%s'\n", (const char*) mAndroidRoot.ToAscii()); - printf("mSimAssetPath='%s'\n", (const char*) mSimAssetPath.ToAscii()); -} - - -/* - * Parse command-line arguments. - * - * Returns "false" if we have a parsing error. - */ -bool MyApp::ParseArgs(int argc, char** argv) -{ - int ic; - - opterr = 0; // don't complain about unrecognized options - - if (false) { - printf("MyApp args:\n"); - for (int i = 0; i < argc; i++) - printf(" %2d: '%s'\n", i, (const char*) argv[i]); - } - - while (1) { - ic = getopt(argc, argv, "tj:da:f:rx:"); - if (ic < 0) - break; - - switch (ic) { - case 'j': - mAutoRunApp = wxString::FromAscii(optarg); - break; - case 't': - mAutoRunApp = wxT("com.android.testharness.RunAll"); - break; - case 'd': - mDebuggerOption = true; - break; - case 'x': - mDebuggerScript = wxString::FromAscii(optarg); - mDebuggerOption = true; // force debug if a script is being used - break; - case 'a': // simulator asset dir - mSimAssetPath = wxString::FromAscii(optarg); - break; - case 'f': // simulator config file - mConfigFile = wxString::FromAscii(optarg); - break; - case 'r': // reset path-based options to defaults - mResetPaths = true; - break; - default: - fprintf(stderr, "WARNING: unknown sim option '%c'\n", ic); - break; - } - } - - return true; -} - - -/* - * Convert a path to absolute form, if needed. - * - * String manipulation would be more efficient than system calls, but - * less reliable. - * - * We need to use GetCurrentDirectory() under Windows because, under - * Cygwin, some wxWidgets features require "C:" paths rather than - * local-rooted paths. Probably needed for stand-alone MinGW too. - */ -void MyApp::AbsifyPath(wxString& dir) -{ - char oldDir[512], newDir[512]; - wxString newDirStr; - - // We still need to do this under Cygwin even if the path is - // already absolute. - //if (dir[0] == '/' || dir[0] == '\\') - // return; - - if (getcwd(oldDir, sizeof(oldDir)) == NULL) { - fprintf(stderr, "getcwd() failed\n"); - return; - } - - if (chdir(dir.ToAscii()) == 0) { -#if defined(HAVE_WINDOWS_PATHS) - DWORD dwRet; - dwRet = GetCurrentDirectory(sizeof(newDir), newDir); - if (dwRet == 0 || dwRet > sizeof(newDir)) - sprintf(newDir, "GET_DIR_FAILED %lu", dwRet); -#else - if (getcwd(newDir, sizeof(newDir)) == NULL) - strcpy(newDir, "GET_DIR_FAILED"); -#endif - newDirStr = wxString::FromAscii(newDir); - chdir(oldDir); - } else { - fprintf(stderr, "WARNING: unable to chdir to '%s' from '%s'\n", - (const char*) dir.ToAscii(), oldDir); - newDirStr = dir; - } - - //dir = "c:/dev/cygwin"; - //dir += newDirStr; - dir = newDirStr; -} - - -/* - * Load and process our configuration file. - */ -bool MyApp::ProcessConfigFile(void) -{ - wxString homeConfig; - bool configLoaded = false; - - if (getenv("HOME") != NULL) { - homeConfig = wxString::FromAscii(getenv("HOME")); - homeConfig += '/'; - homeConfig += kConfigFileName; - } else { - homeConfig = wxT("./"); - homeConfig += kConfigFileName; - } - - /* - * Part 1: read the config file. - */ - - if (mConfigFile.Length() > 0) { - /* - * Read from specified config file. We absolutify the path - * first so that we're guaranteed to be hitting the same file - * even if the cwd changes. - */ - if (access(mConfigFile.ToAscii(), R_OK) != 0) { - fprintf(stderr, "ERROR: unable to open '%s'\n", - (const char*) mConfigFile.ToAscii()); - return false; - } - if (!mPrefs.Load(mConfigFile.ToAscii())) { - fprintf(stderr, "Failed loading config file '%s'\n", - (const char*) mConfigFile.ToAscii()); - return false; - } else { - configLoaded = true; - } - } else { - /* - * Try ./android.cf, then $HOME/android.cf. If we find one and - * read it successfully, save the name in mConfigFile. - */ - { - wxString fileName; - - fileName = wxT("."); - AbsifyPath(fileName); - fileName += wxT("/"); - fileName += kConfigFileName; - - if (access(fileName.ToAscii(), R_OK) == 0) { - if (mPrefs.Load(fileName.ToAscii())) { - mConfigFile = fileName; - configLoaded = true; - } else { - /* damaged config files are always fatal */ - fprintf(stderr, "Failed loading config file '%s'\n", - (const char*) fileName.ToAscii()); - return false; - } - } - } - if (!configLoaded) { - if (homeConfig.Length() > 0) { - if (access(homeConfig.ToAscii(), R_OK) == 0) { - if (mPrefs.Load(homeConfig.ToAscii())) { - mConfigFile = homeConfig; - configLoaded = true; - } else { - /* damaged config files are always fatal */ - fprintf(stderr, "Failed loading config file '%s'\n", - (const char*) homeConfig.ToAscii()); - return false; - } - } - } - } - - } - - /* if we couldn't find one to load, create a new one in $HOME */ - if (!configLoaded) { - mConfigFile = homeConfig; - if (!mPrefs.Create()) { - fprintf(stderr, "prefs creation failed\n"); - return false; - } - } - - /* - * Part 2: reset some entries if requested. - * - * If you want to reset local items (like paths to binaries) without - * disrupting other options, specifying the "reset" flag will cause - * some entries to be removed, and new defaults generated below. - */ - - if (mResetPaths) { - if (mPrefs.RemovePref("debugger")) - printf(" removed pref 'debugger'\n"); - if (mPrefs.RemovePref("valgrinder")) - printf(" removed pref 'valgrinder'\n"); - } - - /* - * Find GDB. - */ - if (!mPrefs.Exists("debugger")) { - static wxString paths[] = { - wxT("/bin"), wxT("/usr/bin"), wxString() - }; - wxString gdbPath; - - FindExe(wxT("gdb"), paths, wxT("/usr/bin/gdb"), &gdbPath); - mPrefs.SetString("debugger", gdbPath.ToAscii()); - } - - - /* - * Find Valgrind. It currently only exists in Linux, and is installed - * in /usr/bin/valgrind by default on our systems. The default version - * is old and sometimes fails, so look for a newer version. - */ - if (!mPrefs.Exists("valgrinder")) { - static wxString paths[] = { - wxT("/home/fadden/local/bin"), wxT("/usr/bin"), wxString() - }; - wxString valgrindPath; - - FindExe(wxT("valgrind"), paths, wxT("/usr/bin/valgrind"), &valgrindPath); - mPrefs.SetString("valgrinder", valgrindPath.ToAscii()); - } - - /* - * Set misc options. - */ - if (!mPrefs.Exists("auto-power-on")) - mPrefs.SetBool("auto-power-on", true); - if (!mPrefs.Exists("gamma")) - mPrefs.SetDouble("gamma", 1.0); - - if (mPrefs.GetDirty()) { - printf("Sim: writing config file to '%s'\n", - (const char*) mConfigFile.ToAscii()); - if (!mPrefs.Save(mConfigFile.ToAscii())) { - fprintf(stderr, "Sim: ERROR: prefs save to '%s' failed\n", - (const char*) mConfigFile.ToAscii()); - } - } - - return true; -} - -/* - * Find an executable by searching in several places. - */ -/*static*/ void MyApp::FindExe(const wxString& exeName, const wxString paths[], - const wxString& defaultPath, wxString* pOut) -{ - wxString exePath; - wxString slashExe; - - slashExe = wxT("/"); - slashExe += exeName; - slashExe += kExeSuffix; - - while (!(*paths).IsNull()) { - wxString tmp; - - tmp = *paths; - tmp += slashExe; - if (access(tmp.ToAscii(), X_OK) == 0) { - printf("Sim: Found '%s' in '%s'\n", (const char*) exeName.ToAscii(), - (const char*) tmp.ToAscii()); - *pOut = tmp; - return; - } - - paths++; - } - - printf("Sim: Couldn't find '%s', defaulting to '%s'\n", - (const char*) exeName.ToAscii(), (const char*) defaultPath.ToAscii()); - *pOut = defaultPath; -} - diff --git a/simulator/app/MyApp.h b/simulator/app/MyApp.h deleted file mode 100644 index d18368dd0..000000000 --- a/simulator/app/MyApp.h +++ /dev/null @@ -1,93 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Application class. -// -#ifndef _SIM_APPMAIN_H -#define _SIM_APPMAIN_H - -#include "wx/help.h" -#include "wx/html/helpctrl.h" - -#include "MainFrame.h" -#include "DeviceManager.h" -#include "Preferences.h" - -#include <utils/AssetManager.h> - -/* flag set from signal handler */ -extern bool gWantToKill; - -/* - * Class representing the application. - */ -class MyApp : public wxApp { -public: - MyApp(void) - : mHelpController(NULL), mpMainFrame(NULL), mpAssetManager(NULL), - mResetPaths(false) // configurable; reset prefs with paths - {} - ~MyApp(void) - { - delete mpAssetManager; - delete mHelpController; - } - - virtual bool OnInit(void); - virtual int OnExit(void); - - wxHtmlHelpController* GetHelpController(void) const { - return mHelpController; - } - - Preferences* GetPrefs(void) { return &mPrefs; } - - /* return a pointer to the main window */ - wxWindow* GetMainFrame(void) { return mpMainFrame; } - - /* get a pointer to our Asset Manager */ - android::AssetManager* GetAssetManager(void) { return mpAssetManager; } - - /* change the asset dir; requires re-creating Asset Manager */ - void ChangeAssetDirectory(const wxString& dir); - - const wxString& GetConfigFileName(void) const { return mConfigFile; } - - wxString GetSimAssetPath() { return mSimAssetPath; } - wxString GetAndroidRoot() { return mAndroidRoot; } - wxString GetRuntimeExe() { return mRuntimeExe; } - bool GetDebuggerOption() { return mDebuggerOption; } - wxString GetDebuggerScript() { return mDebuggerScript; } - wxString GetAutoRunApp() { return mAutoRunApp; } - - void Vibrate(int vibrateOn) { ((MainFrame*)mpMainFrame)->Vibrate(vibrateOn); } - -private: - void SetDefaults(); - bool ParseArgs(int argc, char** argv); - void AbsifyPath(wxString& dir); - bool ProcessConfigFile(void); - static void FindExe(const wxString& exeName, const wxString paths[], - const wxString& defaultPath, wxString* pOut); - - wxHtmlHelpController* mHelpController; - - wxWindow* mpMainFrame; - - android::AssetManager* mpAssetManager; - - wxString mAndroidRoot; - wxString mSimAssetPath; - wxString mRuntimeExe; - - /* command-line options */ - wxString mConfigFile; - bool mResetPaths; - bool mDebuggerOption; - wxString mDebuggerScript; - wxString mAutoRunApp; - - Preferences mPrefs; -}; - -#endif // _SIM_APPMAIN_H diff --git a/simulator/app/PhoneButton.cpp b/simulator/app/PhoneButton.cpp deleted file mode 100644 index eca7ddcb1..000000000 --- a/simulator/app/PhoneButton.cpp +++ /dev/null @@ -1,180 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Simulated device data. -// - -// For compilers that support precompilation, include "wx/wx.h". -#include "wx/wxprec.h" - -// Otherwise, include all standard headers -#ifndef WX_PRECOMP -# include "wx/wx.h" -#endif -#include "wx/image.h" // needed for Windows build - -#include "LinuxKeys.h" -#include "PhoneButton.h" - -using namespace android; - - -/* - * Create a PhoneButton without a backing image. - */ -bool PhoneButton::Create(const char* label) -{ - assert(!mHasImage); // quick check for re-use - - mKeyCode = LookupKeyCode(label); - if (mKeyCode == kKeyCodeUnknown) { - fprintf(stderr, "WARNING: key code '%s' not recognized\n", label); - // keep going - } - - return true; -} - -/* - * Create a PhoneButton with an associated image. Don't load the image yet. - */ -bool PhoneButton::Create(const char* label, const char* imageFileName, - int x, int y) -{ - if (!Create(label)) - return false; - - if (mSelectedImage.Create(imageFileName, x, y)) - mHasImage = true; - else - fprintf(stderr, "Warning: image create (%s, %d, %d) failed\n", - imageFileName, x, y); - - return true; -} - -/* - * Load the image, if any. - */ -bool PhoneButton::LoadResources(void) -{ - if (!mHasImage) - return true; // no image associated with this button - - bool result = mSelectedImage.LoadResources(); - if (result) - CreateHighlightedBitmap(); - return result; -} - -/* - * Unload the image if we loaded one. - */ -bool PhoneButton::UnloadResources(void) -{ - if (!mHasImage) - return true; - - return mSelectedImage.UnloadResources(); -} - -/* use an inline instead of macro so we don't evaluate args multiple times */ -static inline int MinVal(int a, int b) { return (a < b ? a : b); } - -/* - * Create the "highlighted" bitmap from the "selected" image. - */ -void PhoneButton::CreateHighlightedBitmap(void) -{ - wxBitmap* src = mSelectedImage.GetBitmap(); - assert(src != NULL); - wxImage tmpImage = src->ConvertToImage(); - - unsigned char* pRGB = tmpImage.GetData(); // top-left RGBRGB... - int x, y; - - /* - * Modify the color used for the "highlight" image. - */ - for (y = tmpImage.GetHeight()-1; y >= 0; --y) { - for (x = tmpImage.GetWidth()-1; x >= 0; --x) { - *(pRGB) = MinVal(*(pRGB) + *(pRGB) / 8, 255); - *(pRGB+1) = MinVal(*(pRGB+1) + *(pRGB+1) / 8, 255); - *(pRGB+2) = *(pRGB+2) * 5 / 8; - - pRGB += 3; - } - } - - mHighlightedBitmap = wxBitmap(tmpImage); -} - -/* - * Check to see if the button "collides" with the specified point. - * - * This is currently a simple rectangle check, but could be modified - * to take image transparency into account. - */ -bool PhoneButton::CheckCollision(int x, int y) const -{ - if (!mHasImage) - return false; - - return (x >= mSelectedImage.GetX() && - x < mSelectedImage.GetX() + mSelectedImage.GetWidth() && - y >= mSelectedImage.GetY() && - y < mSelectedImage.GetY() + mSelectedImage.GetHeight()); -} - -/* - * Look up a key code based on a string. - * - * Returns kKeyCodeUnknown if the label doesn't match anything. - */ -KeyCode PhoneButton::LookupKeyCode(const char* label) const -{ - static const struct { - const char* label; - int keyCode; - } codeList[] = { - { "soft-left", KEY_MENU }, - { "soft-right", KEY_KBDILLUMUP }, - { "home", KEY_HOME }, - { "back", KEY_BACK }, - { "call", KEY_F3 }, - { "phone-dial", KEY_F3 }, - { "end-call", KEY_F4 }, - { "phone-hangup", KEY_F4 }, - { "0", KEY_0 }, - { "1", KEY_1 }, - { "2", KEY_2 }, - { "3", KEY_3 }, - { "4", KEY_4 }, - { "5", KEY_5 }, - { "6", KEY_6 }, - { "7", KEY_7 }, - { "8", KEY_8 }, - { "9", KEY_9 }, - { "star", KEY_SWITCHVIDEOMODE }, - { "pound", KEY_KBDILLUMTOGGLE }, - { "dpad-up", KEY_UP }, - { "dpad-down", KEY_DOWN }, - { "dpad-left", KEY_LEFT }, - { "dpad-right", KEY_RIGHT }, - { "dpad-center", KEY_REPLY }, - { "volume-up", KEY_VOLUMEUP }, - { "volume-down", KEY_VOLUMEDOWN }, - { "power", KEY_POWER }, - { "camera", KEY_CAMERA }, - //{ "clear", kKeyCodeClear }, - }; - const int numCodes = sizeof(codeList) / sizeof(codeList[0]); - - for (int i = 0; i < numCodes; i++) { - if (strcmp(label, codeList[i].label) == 0) - return (KeyCode) codeList[i].keyCode; - } - - return kKeyCodeUnknown; -}; - diff --git a/simulator/app/PhoneButton.h b/simulator/app/PhoneButton.h deleted file mode 100644 index 4bbaf5666..000000000 --- a/simulator/app/PhoneButton.h +++ /dev/null @@ -1,80 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Phone button image holder. -// -#ifndef _SIM_PHONE_BUTTON_H -#define _SIM_PHONE_BUTTON_H - -#include "LoadableImage.h" -#include <ui/KeycodeLabels.h> - -/* - * One button on a phone. Position, size, and a highlight graphic. The - * coordinates are relative to the device graphic. - * - * We now have a "highlighted" graphic for mouse-overs and a "selected" - * graphic for button presses. We assume they have the same dimensions. - * We currently assume that either both or neither exist, because we - * generate one from the other. - */ -class PhoneButton { -public: - PhoneButton(void) - : mHasImage(false), mKeyCode(kKeyCodeUnknown) - {} - virtual ~PhoneButton(void) {} - PhoneButton(const PhoneButton& src) - : mHasImage(false), mKeyCode(kKeyCodeUnknown) - { - CopyMembers(src); - } - PhoneButton& operator=(const PhoneButton& src) { - if (this != &src) { - // Unload any resources in case we're using operator= to - // assign to an existing object. - mSelectedImage.UnloadResources(); - // Copy fields. - CopyMembers(src); - } - return *this; - } - void CopyMembers(const PhoneButton& src) { - mSelectedImage = src.mSelectedImage; - mHighlightedBitmap = src.mHighlightedBitmap; - mHasImage = src.mHasImage; - mKeyCode = src.mKeyCode; - } - - /* finish construction of PhoneButton, with or without an image */ - bool Create(const char* label); - bool Create(const char* label, const char* imageFileName, int x, int y); - - int GetX(void) const { return mSelectedImage.GetX(); } - int GetY(void) const { return mSelectedImage.GetY(); } - int GetWidth(void) const { return mSelectedImage.GetWidth(); } - int GetHeight(void) const { return mSelectedImage.GetHeight(); } - wxBitmap* GetHighlightedBitmap(void) { return &mHighlightedBitmap; } - wxBitmap* GetSelectedBitmap(void) const { - return mSelectedImage.GetBitmap(); - } - - bool CheckCollision(int x, int y) const; - KeyCode GetKeyCode(void) const { return mKeyCode; } - - // load or unload the image bitmap, if any - bool LoadResources(void); - bool UnloadResources(void); - -private: - void CreateHighlightedBitmap(void); - KeyCode LookupKeyCode(const char* label) const; - - LoadableImage mSelectedImage; - wxBitmap mHighlightedBitmap; - bool mHasImage; // both exist or neither exist - - KeyCode mKeyCode; -}; - -#endif // _SIM_PHONE_BUTTON_H diff --git a/simulator/app/PhoneCollection.cpp b/simulator/app/PhoneCollection.cpp deleted file mode 100644 index 5cddfa8b3..000000000 --- a/simulator/app/PhoneCollection.cpp +++ /dev/null @@ -1,174 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Our collection of devices. -// - -// For compilers that support precompilation, include "wx/wx.h". -#include "wx/wxprec.h" - -// Otherwise, include all standard headers -#ifndef WX_PRECOMP -# include "wx/wx.h" -#endif -//#include "wx/image.h" // needed for Windows build - - -#include "PhoneCollection.h" -#include "PhoneData.h" -#include "MyApp.h" - -#include <utils.h> - -#include <stdlib.h> -#include <unistd.h> -#include <stdio.h> -#include <string.h> -#include <sys/types.h> -#include <dirent.h> -#include <assert.h> - -using namespace android; - -/*static*/ PhoneCollection* PhoneCollection::mpInstance = NULL; - -/*static*/ const char* PhoneCollection::kLayoutFile = "layout.xml"; - - -/* - * (Re-)scan the specified directory for phones. We register a hit if we can - * see a file called "<directory>/layout.xml". - */ -void PhoneCollection::ScanForPhones(const char* directory) -{ - /* - * Scan through the directory and find everything that looks like it - * might hold phone data. - */ - StringArray strArr; - -#ifdef BEFORE_ASSET - DIR* dirp; - struct dirent* entp; - - dirp = opendir(directory); - if (dirp == NULL) { - char buf[512]; - fprintf(stderr, "ERROR: unable to scan directory '%s' for phone data\n", - directory); - fprintf(stderr, "Current dir is %s\n", getcwd(buf, sizeof(buf))); - return; - } - - while (1) { - wxString dirName; - wxString fileName; - - entp = readdir(dirp); - if (entp == NULL) - break; // done with scan - dirName = directory; - dirName += '/'; - dirName += entp->d_name; - fileName = dirName; - fileName += '/'; - fileName += kLayoutFile; - - if (access(fileName, R_OK) == 0) { - strArr.push_back(dirName); - //printf("--- examining '%s'\n", (const char*) fileName); - } - } - closedir(dirp); -#else - android::AssetManager* pAssetMgr = ((MyApp*)wxTheApp)->GetAssetManager(); - android::AssetDir* pDir; - int i, count; - - pDir = pAssetMgr->openDir(""); - assert(pDir != NULL); - count = pDir->getFileCount(); - - for (i = 0; i < count; i++) { - android::String8 layoutPath; - - if (pDir->getFileType(i) != kFileTypeDirectory) - continue; - - layoutPath = pDir->getFileName(i); - layoutPath.appendPath(kLayoutFile); - - if (pAssetMgr->getFileType(layoutPath.string()) == kFileTypeRegular) { - strArr.push_back(pDir->getFileName(i).string()); - printf("--- examining '%s'\n", layoutPath.string()); - } - } - - delete pDir; -#endif - - if (strArr.size() == 0) { - fprintf(stderr, "ERROR: no phone data found in '%s'\n", directory); - return; - } - - /* - * Found some candidates. If they parse successfully, add them to - * our list. - * - * We sort them first, because it's nice when everybody's user - * interface looks the same. Note we're sorting the directory name, - * so it's possible to define a sort order in the filesystem that - * doesn't require messing up the phone's title string. - */ - mPhoneList.clear(); - strArr.sort(StringArray::cmpAscendingAlpha); - - for (int i = 0; i < strArr.size(); i++) { - PhoneData tmpPhone; - - if (!tmpPhone.Create(strArr.getEntry(i))) { - fprintf(stderr, "Sim: Abandoning phone '%s'\n", strArr.getEntry(i)); - //strArr.erase(i); - //i--; - } else { - if (GetPhoneData(tmpPhone.GetName()) != NULL) { - fprintf(stderr, "Sim: ERROR: duplicate name '%s' in '%s'\n", - tmpPhone.GetName(), strArr.getEntry(i)); - } else { - mPhoneList.push_back(tmpPhone); - } - } - } -} - - -/* - * Return the Nth member of the phone data array. (Replace w/Vector.) - */ -PhoneData* PhoneCollection::GetPhoneData(int idx) -{ - typedef List<PhoneData>::iterator Iter; - - for (Iter ii = mPhoneList.begin(); ii != mPhoneList.end(); ++ii) { - if (idx == 0) - return &(*ii); - --idx; - } - return NULL; -} - -/* - * Return the entry whose phone data name matches "name". - */ -PhoneData* PhoneCollection::GetPhoneData(const char* name) -{ - typedef List<PhoneData>::iterator Iter; - - for (Iter ii = mPhoneList.begin(); ii != mPhoneList.end(); ++ii) { - if (strcasecmp((*ii).GetName(), name) == 0) - return &(*ii); - } - return NULL; -} - diff --git a/simulator/app/PhoneCollection.h b/simulator/app/PhoneCollection.h deleted file mode 100644 index d16c4a03f..000000000 --- a/simulator/app/PhoneCollection.h +++ /dev/null @@ -1,52 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Our collection of devices. -// -#ifndef _SIM_PHONE_COLLECTION_H -#define _SIM_PHONE_COLLECTION_H - -#include <stdlib.h> -#include "PhoneData.h" - -/* - * Only one instance of this class exists. It contains a list of all - * known devices, and methods for scanning for devices. - */ -class PhoneCollection { -public: - /* get the global instance */ - static PhoneCollection* GetInstance(void) { - if (mpInstance == NULL) - mpInstance = new PhoneCollection; - return mpInstance; - } - /* destroy the global instance when shutting down */ - static void DestroyInstance(void) { - delete mpInstance; - mpInstance = NULL; - } - - /* scan for phones in subdirectories of "directory" */ - void ScanForPhones(const char* directory); - - /* get phone data */ - int GetPhoneCount(void) const { return mPhoneList.size(); } // slow - PhoneData* GetPhoneData(int idx); - PhoneData* GetPhoneData(const char* name); - - /* layout.xml filename -- a string constant used in various places */ - static const char* kLayoutFile; - -private: - PhoneCollection(void) {} - ~PhoneCollection(void) {} - - /* the phone data; make this a Vector someday */ - android::List<PhoneData> mPhoneList; - - /* storage for global instance pointer */ - static PhoneCollection* mpInstance; -}; - -#endif // _SIM_PHONE_COLLECTION_H diff --git a/simulator/app/PhoneData.cpp b/simulator/app/PhoneData.cpp deleted file mode 100644 index 48614fd7a..000000000 --- a/simulator/app/PhoneData.cpp +++ /dev/null @@ -1,868 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Simulated device data. -// - -// For compilers that support precompilation, include "wx/wx.h". -#include "wx/wxprec.h" - -// Otherwise, include all standard headers -#ifndef WX_PRECOMP -# include "wx/wx.h" -#endif -#include "wx/image.h" // needed for Windows build - - -#include "PhoneData.h" -#include "PhoneButton.h" -#include "PhoneCollection.h" -#include "MyApp.h" - -#include <utils.h> -#include <utils/AssetManager.h> -#include <utils/String8.h> - -#include "tinyxml.h" - -#include <stdlib.h> -#include <unistd.h> -#include <stdio.h> -#include <string.h> -#include <assert.h> - -using namespace android; - -/* image relative path hack */ -static const char* kRelPathMagic = "::/"; - - -/* - * =========================================================================== - * PhoneKeyboard - * =========================================================================== - */ - -/* - * Load a <keyboard> chunk. - */ -bool PhoneKeyboard::ProcessAndValidate(TiXmlNode* pNode) -{ - //TiXmlNode* pChild; - TiXmlElement* pElem; - int qwerty = 0; - - assert(pNode->Type() == TiXmlNode::ELEMENT); - - pElem = pNode->ToElement(); - pElem->Attribute("qwerty", &qwerty); - const char *kmap = pElem->Attribute("keycharmap"); - - if (qwerty == 1) { - printf("############## PhoneKeyboard::ProcessAndValidate: qwerty = true!\n"); - mQwerty = true; - } - - if (kmap != NULL) { - printf("############## PhoneKeyboard::ProcessAndValidate: keycharmap = %s\n", kmap); - mKeyMap = strdup(kmap); - } - - return true; -} - - -/* - * =========================================================================== - * PhoneDisplay - * =========================================================================== - */ - -/* - * Load a <display> chunk. - */ -bool PhoneDisplay::ProcessAndValidate(TiXmlNode* pNode) -{ - //TiXmlNode* pChild; - TiXmlElement* pElem; - const char* name; - const char* format; - - assert(pNode->Type() == TiXmlNode::ELEMENT); - - /* - * Process attributes. Right now they're all mandatory, but some of - * them could be defaulted (e.g. "rotate"). - * - * [We should do some range-checking here.] - */ - pElem = pNode->ToElement(); - name = pElem->Attribute("name"); - if (name == NULL) - goto missing; - if (pElem->Attribute("width", &mWidth) == NULL) - goto missing; - if (pElem->Attribute("height", &mHeight) == NULL) - goto missing; - if (pElem->Attribute("refresh", &mRefresh) == NULL) - goto missing; - format = pElem->Attribute("format"); - if (format == NULL) - goto missing; - - delete[] mName; - mName = strdupNew(name); - - if (strcasecmp(format, "rgb565") == 0) { - mFormat = android::PIXEL_FORMAT_RGB_565; - } else { - fprintf(stderr, "SimCFG: unexpected value for display format\n"); - return false; - } - - return true; - -missing: - fprintf(stderr, - "SimCFG: <display> requires name/width/height/format/refresh\n"); - return false; -} - - -/* - * Returns "true" if the two displays are compatible, "false" if not. - * - * Compatibility means they have the same resolution, format, refresh - * rate, and so on. Anything transmitted to the runtime as part of the - * initial configuration setup should be tested. - */ -/*static*/ bool PhoneDisplay::IsCompatible(PhoneDisplay* pDisplay1, - PhoneDisplay* pDisplay2) -{ - return (pDisplay1->mWidth == pDisplay2->mWidth && - pDisplay1->mHeight == pDisplay2->mHeight && - pDisplay1->mFormat == pDisplay2->mFormat && - pDisplay1->mRefresh == pDisplay2->mRefresh); -} - - -/* - * =========================================================================== - * PhoneView - * =========================================================================== - */ - -/* - * Load a <view> chunk. - */ -bool PhoneView::ProcessAndValidate(TiXmlNode* pNode, const char* directory) -{ - TiXmlNode* pChild; - TiXmlElement* pElem; - int rotate; - const char* displayName; - - assert(pNode->Type() == TiXmlNode::ELEMENT); - - /* - * Process attributes. Right now they're all mandatory, but some of - * them could be defaulted (e.g. "rotate"). - * - * [We should do some range-checking here.] - */ - pElem = pNode->ToElement(); - displayName = pElem->Attribute("display"); - if (displayName == NULL) - goto missing; - if (pElem->Attribute("x", &mXOffset) == NULL) - goto missing; - if (pElem->Attribute("y", &mYOffset) == NULL) - goto missing; - if (pElem->Attribute("rotate", &rotate) == NULL) - goto missing; - - switch (rotate) { - case 0: mRotation = kRot0; break; - case 90: mRotation = kRot90; break; - case 180: mRotation = kRot180; break; - case 270: mRotation = kRot270; break; - default: - fprintf(stderr, "SimCFG: unexpected value for rotation\n"); - mRotation = kRotUnknown; - return false; - } - - delete[] mDisplayName; - mDisplayName = android::strdupNew(displayName); - - /* - * Process elements. - */ - for (pChild = pNode->FirstChild(); pChild != NULL; - pChild = pChild->NextSibling()) - { - if (pChild->Type() == TiXmlNode::COMMENT) - continue; - - if (pChild->Type() == TiXmlNode::ELEMENT) { - if (strcasecmp(pChild->Value(), "image") == 0) { - if (!ProcessImage(pChild, directory)) - return false; - } else if (strcasecmp(pChild->Value(), "button") == 0) { - if (!ProcessButton(pChild, directory)) - return false; - } else { - fprintf(stderr, - "SimCFG: Warning: unexpected elements in <display>\n"); - } - } else { - fprintf(stderr, "SimCFG: Warning: unexpected stuff in <display>\n"); - } - } - - return true; - -missing: - fprintf(stderr, - "SimCFG: <view> requires display/x/y/rotate\n"); - return false; -} - -/* - * Handle <image src="zzz" x="123" y="123"/>. - */ -bool PhoneView::ProcessImage(TiXmlNode* pNode, const char* directory) -{ - TiXmlNode* pChild; - TiXmlElement* pElem; - int x, y; - const char* src; - LoadableImage tmpLimg; - android::String8 fileName; - - pChild = pNode->FirstChild(); - if (pChild != NULL) { - fprintf(stderr, "SimCFG: <image> is funky\n"); - return false; - } - - /* - * All attributes are mandatory. - */ - pElem = pNode->ToElement(); - src = pElem->Attribute("src"); - if (src == NULL) - goto missing; - if (pElem->Attribute("x", &x) == NULL) - goto missing; - if (pElem->Attribute("y", &y) == NULL) - goto missing; - - if (strncmp(src, kRelPathMagic, strlen(kRelPathMagic)) == 0) { - fileName = src + strlen(kRelPathMagic); - } else { - fileName = directory; - fileName += "/"; - fileName += src; - } - - tmpLimg.Create(fileName, x, y); - mImageList.push_back(tmpLimg); - - return true; - -missing: - fprintf(stderr, "SimCFG: <image> requires src/x/y\n"); - return false; -} - -/* - * Handle <button keyCode="zzz" src="zzz" x="123" y="123"/> and - * <button keyCode="zzz"/>. - */ -bool PhoneView::ProcessButton(TiXmlNode* pNode, const char* directory) -{ - TiXmlNode* pChild; - TiXmlElement* pElem; - int x, y; - const char* keyCode; - const char* src; - PhoneButton tmpButton; - android::String8 fileName; - - pChild = pNode->FirstChild(); - if (pChild != NULL) { - fprintf(stderr, "SimCFG: button is funky\n"); - return false; - } - - /* - * Only keyCode is mandatory. If they specify "src", then "x" and "y" - * are also required. - */ - pElem = pNode->ToElement(); - keyCode = pElem->Attribute("keyCode"); - if (keyCode == NULL) - goto missing; - - src = pElem->Attribute("src"); - if (src != NULL) { - if (pElem->Attribute("x", &x) == NULL) - goto missing; - if (pElem->Attribute("y", &y) == NULL) - goto missing; - } - - if (src == NULL) - tmpButton.Create(keyCode); - else { - if (strncmp(src, kRelPathMagic, strlen(kRelPathMagic)) == 0) { - fileName = src + strlen(kRelPathMagic); - } else { - fileName = directory; - fileName += "/"; - fileName += src; - } - tmpButton.Create(keyCode, fileName, x, y); - } - - mButtonList.push_back(tmpButton); - - return true; - -missing: - fprintf(stderr, "SimCFG: <button> requires keycode and may have src/x/y\n"); - return false; -} - - -/* - * Load all resources associated with the display. - */ -bool PhoneView::LoadResources(void) -{ - typedef List<LoadableImage>::iterator LIter; - typedef List<PhoneButton>::iterator BIter; - - for (LIter ii = mImageList.begin(); ii != mImageList.end(); ++ii) - (*ii).LoadResources(); - for (BIter ii = mButtonList.begin(); ii != mButtonList.end(); ++ii) - (*ii).LoadResources(); - return true; -} - -/* - * Unload all resources associated with the display. - */ -bool PhoneView::UnloadResources(void) -{ - typedef List<LoadableImage>::iterator LIter; - typedef List<PhoneButton>::iterator BIter; - - for (LIter ii = mImageList.begin(); ii != mImageList.end(); ++ii) - (*ii).UnloadResources(); - for (BIter ii = mButtonList.begin(); ii != mButtonList.end(); ++ii) - (*ii).UnloadResources(); - return true; -} - - -/* - * Get the #of images. - */ -int PhoneView::GetBkgImageCount(void) const -{ - return mImageList.size(); -} - -/* - * Return the Nth entry. - */ -const LoadableImage* PhoneView::GetBkgImage(int idx) const -{ - typedef List<LoadableImage>::const_iterator Iter; - - for (Iter ii = mImageList.begin(); ii != mImageList.end(); ++ii) { - if (!idx) - return &(*ii); - --idx; - } - - return NULL; -} - - -/* - * Find the first button that covers the specified coordinates. - * - * The coordinates must be relative to the upper left corner of the - * phone image. - */ -PhoneButton* PhoneView::FindButtonHit(int x, int y) -{ - typedef List<PhoneButton>::iterator Iter; - - for (Iter ii = mButtonList.begin(); ii != mButtonList.end(); ++ii) { - if ((*ii).CheckCollision(x, y)) - return &(*ii); - } - - return NULL; -} - -/* - * Find the first button with a matching key code. - */ -PhoneButton* PhoneView::FindButtonByKey(KeyCode keyCode) -{ - typedef List<PhoneButton>::iterator Iter; - - for (Iter ii = mButtonList.begin(); ii != mButtonList.end(); ++ii) { - if ((*ii).GetKeyCode() == keyCode) - return &(*ii); - } - - return NULL; -} - - -/* - * =========================================================================== - * PhoneMode - * =========================================================================== - */ - -/* - * Process a <mode name="zzz"> chunk. - */ -bool PhoneMode::ProcessAndValidate(TiXmlNode* pNode, const char* directory) -{ - TiXmlNode* pChild; - const char* name; - - assert(pNode->Type() == TiXmlNode::ELEMENT); - - name = pNode->ToElement()->Attribute("name"); - if (name == NULL) { - fprintf(stderr, "SimCFG: <mode> requires name attrib\n"); - return false; - } - SetName(name); - - for (pChild = pNode->FirstChild(); pChild != NULL; - pChild = pChild->NextSibling()) - { - if (pChild->Type() == TiXmlNode::COMMENT) - continue; - - if (pChild->Type() == TiXmlNode::ELEMENT && - strcasecmp(pChild->Value(), "view") == 0) - { - PhoneView tmpDisplay; - bool result; - - result = tmpDisplay.ProcessAndValidate(pChild, directory); - if (!result) - return false; - - mViewList.push_back(tmpDisplay); - } else { - fprintf(stderr, "SimCFG: Warning: unexpected stuff in <mode>\n"); - } - } - - if (mViewList.size() == 0) { - fprintf(stderr, "SimCFG: no <view> entries found\n"); - return false; - } - - return true; -} - - -/* - * Load all resources associated with the phone. - */ -bool PhoneMode::LoadResources(void) -{ - typedef List<PhoneView>::iterator Iter; - - for (Iter ii = mViewList.begin(); ii != mViewList.end(); ++ii) - (*ii).LoadResources(); - return true; -} - -/* - * Unload all resources associated with the phone. - */ -bool PhoneMode::UnloadResources(void) -{ - typedef List<PhoneView>::iterator Iter; - - for (Iter ii = mViewList.begin(); ii != mViewList.end(); ++ii) - (*ii).UnloadResources(); - return true; -} - - -/* - * Return the Nth entry. [make this a Vector?] - */ -PhoneView* PhoneMode::GetPhoneView(int viewNum) -{ - typedef List<PhoneView>::iterator Iter; - - for (Iter ii = mViewList.begin(); ii != mViewList.end(); ++ii) { - if (viewNum == 0) - return &(*ii); - --viewNum; - } - return NULL; -} - - -/* - * =========================================================================== - * PhoneData - * =========================================================================== - */ - - -/* - * Look for a "layout.xml" in the specified directory. If found, parse - * the contents out. - * - * Returns "true" on success, "false" on failure. - */ -bool PhoneData::Create(const char* directory) -{ - android::String8 fileName; - - SetDirectory(directory); - - fileName = directory; - fileName += "/"; - fileName += PhoneCollection::kLayoutFile; - -#ifdef BEFORE_ASSET - TiXmlDocument doc(fileName); - if (!doc.LoadFile()) -#else - android::AssetManager* pAssetMgr = ((MyApp*)wxTheApp)->GetAssetManager(); - TiXmlDocument doc; - android::Asset* pAsset; - bool result; - - pAsset = pAssetMgr->open(fileName, Asset::ACCESS_STREAMING); - if (pAsset == NULL) { - fprintf(stderr, "Unable to open asset '%s'\n", (const char*) fileName); - return false; - } else { - //printf("--- opened asset '%s'\n", - // (const char*) pAsset->getAssetSource()); - } - - /* TinyXml insists that the buffer be NULL-terminated... ugh */ - char* buf = new char[pAsset->getLength() +1]; - pAsset->read(buf, pAsset->getLength()); - buf[pAsset->getLength()] = '\0'; - - delete pAsset; - result = doc.Parse(buf); - delete[] buf; - - if (!result) -#endif - { - fprintf(stderr, "SimCFG: ERROR: failed parsing '%s'\n", - (const char*) fileName); - if (doc.ErrorRow() != 0) - fprintf(stderr, " XML: %s (row=%d col=%d)\n", - doc.ErrorDesc(), doc.ErrorRow(), doc.ErrorCol()); - else - fprintf(stderr, " XML: %s\n", doc.ErrorDesc()); - return false; - } - - if (!ProcessAndValidate(&doc)) { - fprintf(stderr, "SimCFG: ERROR: failed analyzing '%s'\n", - (const char*) fileName); - return false; - } - - printf("SimCFG: loaded data from '%s'\n", (const char*) fileName); - - return true; -} - -/* - * TinyXml has loaded and parsed the XML document for us. We need to - * run through the DOM tree, pull out the interesting bits, and make - * sure the stuff we need is present. - * - * Returns "true" on success, "false" on failure. - */ -bool PhoneData::ProcessAndValidate(TiXmlDocument* pDoc) -{ - bool deviceFound = false; - TiXmlNode* pChild; - - assert(pDoc->Type() == TiXmlNode::DOCUMENT); - - for (pChild = pDoc->FirstChild(); pChild != NULL; - pChild = pChild->NextSibling()) - { - /* - * Find the <device> entry. There should be exactly one. - */ - if (pChild->Type() == TiXmlNode::ELEMENT) { - if (strcasecmp(pChild->Value(), "device") != 0) { - fprintf(stderr, - "SimCFG: Warning: unexpected element '%s' at top level\n", - pChild->Value()); - continue; - } - if (deviceFound) { - fprintf(stderr, "SimCFG: one <device> per customer\n"); - return false; - } - - bool result = ProcessDevice(pChild); - if (!result) - return false; - deviceFound = true; - } - } - - if (!deviceFound) { - fprintf(stderr, "SimCFG: no <device> section found\n"); - return false; - } - - return true; -} - -/* - * Process a <device name="zzz"> chunk. - */ -bool PhoneData::ProcessDevice(TiXmlNode* pNode) -{ - TiXmlNode* pChild; - const char* name; - - assert(pNode->Type() == TiXmlNode::ELEMENT); - - name = pNode->ToElement()->Attribute("name"); - if (name == NULL) { - fprintf(stderr, "SimCFG: <device> requires name attrib\n"); - return false; - } - SetName(name); - - /* - * Walk through the children and find interesting stuff. - * - * Might be more correct to process all <display> entries and - * then process all <view> entries, since <view> has "pointers" - * to <display>. We're deferring the lookup until later, though, - * so for now it doesn't really matter. - */ - for (pChild = pNode->FirstChild(); pChild != NULL; - pChild = pChild->NextSibling()) - { - bool result; - - if (pChild->Type() == TiXmlNode::COMMENT) - continue; - - if (pChild->Type() == TiXmlNode::ELEMENT && - strcasecmp(pChild->Value(), "title") == 0) - { - result = ProcessTitle(pChild); - if (!result) - return false; - } else if (pChild->Type() == TiXmlNode::ELEMENT && - strcasecmp(pChild->Value(), "display") == 0) - { - PhoneDisplay tmpDisplay; - - result = tmpDisplay.ProcessAndValidate(pChild); - if (!result) - return false; - - mDisplayList.push_back(tmpDisplay); - } else if (pChild->Type() == TiXmlNode::ELEMENT && - strcasecmp(pChild->Value(), "keyboard") == 0) - { - PhoneKeyboard tmpKeyboard; - result = tmpKeyboard.ProcessAndValidate(pChild); - if (!result) - return false; - - mKeyboardList.push_back(tmpKeyboard); - } else if (pChild->Type() == TiXmlNode::ELEMENT && - strcasecmp(pChild->Value(), "mode") == 0) - { - PhoneMode tmpMode; - - result = tmpMode.ProcessAndValidate(pChild, mDirectory); - if (!result) - return false; - - mModeList.push_back(tmpMode); - } else { - fprintf(stderr, "SimCFG: Warning: unexpected stuff in <device>\n"); - } - } - - if (mDisplayList.size() == 0) { - fprintf(stderr, "SimCFG: no <display> entries found\n"); - return false; - } - if (mModeList.size() == 0) { - fprintf(stderr, "SimCFG: no <mode> entries found\n"); - return false; - } - - return true; -} - -/* - * Handle <title>. - */ -bool PhoneData::ProcessTitle(TiXmlNode* pNode) -{ - TiXmlNode* pChild; - - pChild = pNode->FirstChild(); - if (pChild->Type() != TiXmlNode::TEXT) { - fprintf(stderr, "SimCFG: title is funky\n"); - return false; - } - - SetTitle(pChild->Value()); - return true; -} - - -/* - * Load all resources associated with the phone. - */ -bool PhoneData::LoadResources(void) -{ - typedef List<PhoneMode>::iterator Iter; - - for (Iter ii = mModeList.begin(); ii != mModeList.end(); ++ii) - (*ii).LoadResources(); - return true; -} - -/* - * Unload all resources associated with the phone. - */ -bool PhoneData::UnloadResources(void) -{ - typedef List<PhoneMode>::iterator Iter; - - for (Iter ii = mModeList.begin(); ii != mModeList.end(); ++ii) - (*ii).UnloadResources(); - return true; -} - - -/* - * Return the PhoneMode entry with the matching name. - * - * Returns NULL if no match was found. - */ -PhoneMode* PhoneData::GetPhoneMode(const char* modeName) -{ - typedef List<PhoneMode>::iterator Iter; - - for (Iter ii = mModeList.begin(); ii != mModeList.end(); ++ii) { - if (strcmp((*ii).GetName(), modeName) == 0) - return &(*ii); - } - return NULL; -} - -/* - * Return the Nth phone mode entry. - */ -PhoneMode* PhoneData::GetPhoneMode(int idx) -{ - typedef List<PhoneMode>::iterator Iter; - - for (Iter ii = mModeList.begin(); ii != mModeList.end(); ++ii) { - if (!idx) - return &(*ii); - --idx; - } - return NULL; -} - - -/* - * Return the PhoneDisplay entry with the matching name. - * - * Returns NULL if no match was found. - */ -PhoneDisplay* PhoneData::GetPhoneDisplay(const char* dispName) -{ - typedef List<PhoneDisplay>::iterator Iter; - - for (Iter ii = mDisplayList.begin(); ii != mDisplayList.end(); ++ii) { - if (strcmp((*ii).GetName(), dispName) == 0) - return &(*ii); - } - return NULL; -} - -/* - * Return the Nth phone mode entry. - */ -PhoneDisplay* PhoneData::GetPhoneDisplay(int idx) -{ - typedef List<PhoneDisplay>::iterator Iter; - - for (Iter ii = mDisplayList.begin(); ii != mDisplayList.end(); ++ii) { - if (!idx) - return &(*ii); - --idx; - } - return NULL; -} - -/* - * Find the PhoneDisplay entry with the matching name, and return its index. - * - * Returns -1 if the entry wasn't found. - */ -int PhoneData::GetPhoneDisplayIndex(const char* dispName) -{ - typedef List<PhoneDisplay>::iterator Iter; - int idx = 0; - - for (Iter ii = mDisplayList.begin(); ii != mDisplayList.end(); ++ii) { - if (strcmp((*ii).GetName(), dispName) == 0) - return idx; - idx++; - } - return -1; -} - - -/* - * Return the Nth phone keyboard entry. - */ -PhoneKeyboard* PhoneData::GetPhoneKeyboard(int idx) -{ - typedef List<PhoneKeyboard>::iterator Iter; - - for (Iter ii = mKeyboardList.begin(); ii != mKeyboardList.end(); ++ii) { - if (!idx) - return &(*ii); - --idx; - } - return NULL; -} diff --git a/simulator/app/PhoneData.h b/simulator/app/PhoneData.h deleted file mode 100644 index c7f473274..000000000 --- a/simulator/app/PhoneData.h +++ /dev/null @@ -1,365 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Simulated device definition. -// -// The "root" of the data structures here is PhoneCollection, which may -// discard the entire set if the user asks to re-scan the phone definitions. -// These structures should be considered read-only. -// -// PhoneCollection (single global instance) -// -->PhoneData -// -->PhoneDisplay -// -->PhoneMode -// -->PhoneView -// -#ifndef _SIM_PHONE_DATA_H -#define _SIM_PHONE_DATA_H - -#include <stdio.h> -#include "tinyxml.h" - -#include "PhoneButton.h" -#include "LoadableImage.h" -#include <ui/PixelFormat.h> -#include <utils.h> - - -/* - * This represents the keyboard type of the simulated device - */ -class PhoneKeyboard { -public: - PhoneKeyboard(void) - : mQwerty(false), mKeyMap(NULL) - {} - ~PhoneKeyboard(void) { - free((void*)mKeyMap); - } - - PhoneKeyboard(const PhoneKeyboard& src) - : mQwerty(false), mKeyMap(NULL) - { - CopyMembers(src); - } - PhoneKeyboard& operator=(const PhoneKeyboard& src) { - if (this != &src) // self-assignment - CopyMembers(src); - return *this; - } - void CopyMembers(const PhoneKeyboard& src) { - mQwerty = src.mQwerty; - mKeyMap = src.mKeyMap ? strdup(src.mKeyMap) : NULL; - } - - bool ProcessAndValidate(TiXmlNode* pNode); - - bool getQwerty() { return mQwerty; } - - const char *getKeyMap() { return mKeyMap; } -private: - bool mQwerty; - const char * mKeyMap; -}; - -/* - * This represents a single display device, usually an LCD screen. - * It also includes an optional surrounding graphic, usually a picture of - * the device itself. - */ -class PhoneDisplay { -public: - PhoneDisplay(void) - : mName(NULL) - {} - ~PhoneDisplay(void) { - delete[] mName; - } - - PhoneDisplay(const PhoneDisplay& src) - : mName(NULL) - { - CopyMembers(src); - } - PhoneDisplay& operator=(const PhoneDisplay& src) { - if (this != &src) // self-assignment - CopyMembers(src); - return *this; - } - void CopyMembers(const PhoneDisplay& src) { - // Can't memcpy and member-copy the container classes, because the - // containers have already been constructed, and for operator= they - // might even have stuff in them. - delete[] mName; - mName = android::strdupNew(src.mName); - mWidth = src.mWidth; - mHeight = src.mHeight; - mFormat = src.mFormat; - mRefresh = src.mRefresh; - } - - bool ProcessAndValidate(TiXmlNode* pNode); - - const char* GetName(void) const { return mName; } - 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; } - - static bool IsCompatible(PhoneDisplay* pDisplay1, PhoneDisplay* pDisplay2); - -private: - char* mName; - - // display dimensions, in pixels - int mWidth; - int mHeight; - - // frame buffer format - android::PixelFormat mFormat; - - // display refresh rate, in fps - int mRefresh; -}; - -/* - * This is a "view" of a device, which includes the display, a background - * image, and perhaps some clickable keys for input. - * - * Because the key graphics are associated with a particular display, we - * hold a list of keys here. (It also allows the possibility of handling - * a situation where the same key shows up in multiple background images, - * e.g. a flip phone with a "volume" key on the side. If we include the - * key in both places, we can highlight it on both displays.) - */ -class PhoneView { -public: - PhoneView(void) - : mDisplayName(NULL) - {} - ~PhoneView(void) { - delete[] mDisplayName; - } - - PhoneView(const PhoneView& src) { - CopyMembers(src); - } - PhoneView& operator=(const PhoneView& src) { - if (this != &src) // self-assignment - CopyMembers(src); - return *this; - } - void CopyMembers(const PhoneView& src) { - // Can't memcpy and member-copy the container classes, because the - // containers have already been constructed, and for operator= they - // might even have stuff in them. - mImageList = src.mImageList; - mButtonList = src.mButtonList; - mDisplayName = android::strdupNew(src.mDisplayName); - mXOffset = src.mXOffset; - mYOffset = src.mYOffset; - mRotation = src.mRotation; - } - - // load or unload resources, e.g. wxBitmaps from image files - bool LoadResources(void); - bool UnloadResources(void); - - // simple accessors - int GetXOffset(void) const { return mXOffset; } - int GetYOffset(void) const { return mYOffset; } - const char* GetDisplayName(void) const { return mDisplayName; } - - // image list access - int GetBkgImageCount(void) const; - const LoadableImage* GetBkgImage(int idx) const; - - // find the first button that covers the specified coords - PhoneButton* FindButtonHit(int x, int y); - - // find the first button with a matching key code - PhoneButton* FindButtonByKey(KeyCode keyCode); - - bool ProcessAndValidate(TiXmlNode* pNode, const char* directory); - bool ProcessImage(TiXmlNode* pNode, const char* directory); - bool ProcessButton(TiXmlNode* pNode, const char* directory); - -private: - // background images for the phone picture that surrounds the display - android::List<LoadableImage> mImageList; - - // list of accessible buttons, some of which have highlight graphics - android::List<PhoneButton> mButtonList; - - char* mDisplayName; - - // these determine where in the image the display output goes - int mXOffset; - int mYOffset; - - // clockwise rotation of the output; sim must rotate in opposite direction - typedef enum Rotation { - kRotUnknown = 0, - kRot0, - kRot90, - kRot180, - kRot270, - } Rotation; - Rotation mRotation; -}; - -/* - * One mode of a phone. Simple devices only have one mode. Flip phones - * have two (opened and closed). Other devices might have more. The - * mode is communicated to the runtime because it may need to process - * input events differently. - */ -class PhoneMode { -public: - PhoneMode(void) - : mName(NULL) - {} - ~PhoneMode(void) { - delete[] mName; - } - - PhoneMode(const PhoneMode& src) - : mName(NULL) - { - CopyMembers(src); - } - PhoneMode& operator=(const PhoneMode& src) { - if (this != &src) // self-assignment - CopyMembers(src); - return *this; - } - void CopyMembers(const PhoneMode& src) { - delete[] mName; - mName = android::strdupNew(src.mName); - mViewList = src.mViewList; - } - - - // load or unload resources for this object and all members of mViewList - bool LoadResources(void); - bool UnloadResources(void); - - // get the #of views - int GetNumViews(void) const { return mViewList.size(); } - // get the Nth display - PhoneView* GetPhoneView(int viewNum); - - const char* GetName(void) const { return mName; } - void SetName(const char* name) { - delete[] mName; - mName = android::strdupNew(name); - } - - // load the <mode> section from the config file - bool ProcessAndValidate(TiXmlNode* pNode, const char* directory); - -private: - char* mName; - - android::List<PhoneView> mViewList; -}; - -/* - * This holds the data for one device. - * - * Each device may have multiple "modes", e.g. a flip-phone that can be - * open or shut. Each mode has different configurations for the visible - * displays and active keys. - */ -class PhoneData { -public: - PhoneData(void) : - mName(NULL), mTitle(NULL), mDirectory(NULL) - {} - virtual ~PhoneData(void) { - delete[] mName; - delete[] mTitle; - delete[] mDirectory; - } - - PhoneData(const PhoneData& src) - : mName(NULL), mTitle(NULL), mDirectory(NULL) - { - CopyMembers(src); - } - PhoneData& operator=(const PhoneData& src) { - if (this != &src) // self-assignment - CopyMembers(src); - return *this; - } - void CopyMembers(const PhoneData& src) { - delete[] mName; - delete[] mTitle; - delete[] mDirectory; - mName = android::strdupNew(src.mName); - mTitle = android::strdupNew(src.mTitle); - mDirectory = android::strdupNew(src.mDirectory); - mModeList = src.mModeList; - mDisplayList = src.mDisplayList; - mKeyboardList = src.mKeyboardList; - } - - // initialize the object with the phone data in the specified dir - bool Create(const char* directory); - - // load or unload resources, e.g. wxBitmaps from image files - bool LoadResources(void); - bool UnloadResources(void); - - // simple accessors - const char* GetName(void) const { return mName; } - void SetName(const char* name) { - delete[] mName; - mName = android::strdupNew(name); - } - const char* GetTitle(void) const { return mTitle; } - void SetTitle(const char* title) { - delete[] mTitle; - mTitle = android::strdupNew(title); - } - const char* GetDirectory(void) const { return mDirectory; } - void SetDirectory(const char* dir) { - delete[] mDirectory; - mDirectory = android::strdupNew(dir); - } - - - // get number of modes - int GetNumModes(void) const { return mModeList.size(); } - // get the specified mode object - PhoneMode* GetPhoneMode(int idx); - PhoneMode* GetPhoneMode(const char* modeName); - - // get number of displays - int GetNumDisplays(void) const { return mDisplayList.size(); } - // get the specified display object - PhoneDisplay* GetPhoneDisplay(int idx); - PhoneDisplay* GetPhoneDisplay(const char* displayName); - // get the index of the matching display - int GetPhoneDisplayIndex(const char* displayName); - - // get number of keyboards - int GetNumKeyboards(void) const { return mKeyboardList.size(); } - // get the specified display object - PhoneKeyboard* GetPhoneKeyboard(int idx); - -private: - bool ProcessAndValidate(TiXmlDocument* pDoc); - bool ProcessDevice(TiXmlNode* pNode); - bool ProcessTitle(TiXmlNode* pNode); - - char* mName; - char* mTitle; - char* mDirectory; - - android::List<PhoneMode> mModeList; - android::List<PhoneDisplay> mDisplayList; - android::List<PhoneKeyboard> mKeyboardList; -}; - -#endif // _SIM_PHONE_DATA_H diff --git a/simulator/app/PhoneWindow.cpp b/simulator/app/PhoneWindow.cpp deleted file mode 100644 index 60a98090c..000000000 --- a/simulator/app/PhoneWindow.cpp +++ /dev/null @@ -1,1051 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Displays the phone image and handles user input. -// - -// For compilers that support precompilation, include "wx/wx.h". -#include "wx/wxprec.h" - -// Otherwise, include all standard headers -#ifndef WX_PRECOMP -# include "wx/wx.h" -#endif -#include "wx/image.h" // needed for Windows build -#include "wx/dcbuffer.h" - -#include "LinuxKeys.h" -#include "PhoneWindow.h" -#include "DeviceWindow.h" -#include "PhoneData.h" -#include "PhoneCollection.h" -#include "MainFrame.h" -#include "MyApp.h" - -using namespace android; - -BEGIN_EVENT_TABLE(PhoneWindow, wxWindow) // NOT wxDialog - EVT_ACTIVATE(PhoneWindow::OnActivate) - //EVT_ACTIVATE_APP(PhoneWindow::OnActivate) - EVT_CLOSE(PhoneWindow::OnClose) - EVT_MOVE(PhoneWindow::OnMove) - EVT_ERASE_BACKGROUND(PhoneWindow::OnErase) - EVT_PAINT(PhoneWindow::OnPaint) - - EVT_KEY_DOWN(PhoneWindow::OnKeyDown) - EVT_KEY_UP(PhoneWindow::OnKeyUp) - EVT_LEFT_DOWN(PhoneWindow::OnMouseLeftDown) - EVT_LEFT_DCLICK(PhoneWindow::OnMouseLeftDown) - EVT_LEFT_UP(PhoneWindow::OnMouseLeftUp) - EVT_RIGHT_DOWN(PhoneWindow::OnMouseRightDown) - EVT_RIGHT_DCLICK(PhoneWindow::OnMouseRightDown) - EVT_RIGHT_UP(PhoneWindow::OnMouseRightUp) - EVT_MOTION(PhoneWindow::OnMouseMotion) - EVT_LEAVE_WINDOW(PhoneWindow::OnMouseLeaveWindow) - EVT_TIMER(kVibrateTimerId, PhoneWindow::OnTimer) -END_EVENT_TABLE() - - -/* - * Create a new PhoneWindow. This should be a child of the main frame. - */ -PhoneWindow::PhoneWindow(wxWindow* parent, const wxPoint& posn) - : wxDialog(parent, wxID_ANY, wxT("Device"), posn, wxDefaultSize, - wxDEFAULT_DIALOG_STYLE), - mpMOHViewIndex(-1), - mpMOHButton(NULL), - mMouseKeySent(kKeyCodeUnknown), - mpViewInfo(NULL), - mNumViewInfo(0), - mpDeviceWindow(NULL), - mNumDeviceWindows(0), - mPhoneModel(-1), - mCurrentMode(wxT("(unknown)")), - mPlacementChecked(false), - mpParent((MainFrame*)parent), - mTimer(this, kVibrateTimerId), - mTrackingTouch(false) -{ - SetBackgroundColour(*wxLIGHT_GREY); - SetBackgroundStyle(wxBG_STYLE_CUSTOM); - - //SetCursor(wxCursor(wxCURSOR_HAND)); // a bit distracting (pg.276) -} - -/* - * Destroy everything we own. - * - * This might be called well after we've been closed and another - * PhoneWindow has been created, because wxWidgets likes to defer things. - */ -PhoneWindow::~PhoneWindow(void) -{ - //printf("--- ~PhoneWindow %p\n", this); - delete[] mpViewInfo; - if (mpDeviceWindow != NULL) { - for (int i = 0; i < mNumDeviceWindows; i++) { - /* make sure they don't try to use our member */ - mpDeviceWindow[i]->DeviceManagerClosing(); - /* make sure the child window gets destroyed -- not necessary? */ - mpDeviceWindow[i]->Destroy(); - } - - /* delete our array of pointers */ - delete[] mpDeviceWindow; - } -} - -/* - * Check for an updated runtime when window becomes active - */ -void PhoneWindow::OnActivate(wxActivateEvent& event) -{ - /* - * DO NOT do this. Under Windows, it causes the parent window to get - * an activate event, which causes our parent to get the focus. With - * this bit of code active it is impossible for the phone window to - * receive user input. - */ - //GetParent()->AddPendingEvent(event); - - // If we are being deactivated, go ahead and send key up events so that the - // runtime doesn't think we are holding down the key. Issue #685750 - if (!event.GetActive()) { - ListIter iter; - for (iter = mPressedKeys.begin(); iter != mPressedKeys.end(); ) { - KeyCode keyCode = (*iter).GetKeyCode(); - GetDeviceManager()->SendKeyEvent(keyCode, false); - iter = mPressedKeys.erase(iter); - } - } -} - -/* - * Close the phone window. - */ -void PhoneWindow::OnClose(wxCloseEvent& event) -{ - //printf("--- PhoneWindow::OnClose %p\n", this); -#if 0 - if (mDeviceManager.IsRunning() && !mDeviceManager.IsKillable()) { - printf("Sim: refusing to close window on external runtime\n"); - event.Veto(); - return; - } -#endif - - wxRect rect = GetRect(); - printf("Sim: Closing phone window (posn=(%d,%d))\n", rect.x, rect.y); - - /* notify others */ - mpParent->PhoneWindowClosing(rect.x, rect.y); - mDeviceManager.WindowsClosing(); - - /* end it all */ - Destroy(); -} - -/* - * Prep the PhoneWindow to display a specific phone model. Pass in the - * model index. - * - * This gets called whenever the display changes. This could be a new - * device with identical characteristics, or a different mode for the same - * device. - * - * The window can be re-used so long as the display characteristics are - * the same. If the display characteristics are different, we have to - * restart the device. - */ -bool PhoneWindow::Setup(int phoneIdx) -{ - wxString fileName; - PhoneCollection* pCollection = PhoneCollection::GetInstance(); - - if (phoneIdx < 0 || phoneIdx >= pCollection->GetPhoneCount()) { - fprintf(stderr, "Bogus phone index %d\n", phoneIdx); - return false; - } - - /* - * Clear these out so that failure here is noticeable to caller. We - * regenerate the ViewInfo array every time, because the set of Views - * is different for every Mode. - */ - delete[] mpViewInfo; - mpViewInfo = NULL; - mNumViewInfo = -1; - - PhoneData* pPhoneData; - PhoneMode* pPhoneMode; - PhoneView* pPhoneView; - - pPhoneData = pCollection->GetPhoneData(phoneIdx); - - pPhoneMode = pPhoneData->GetPhoneMode(GetCurrentMode().ToAscii()); - if (pPhoneMode == NULL) { - fprintf(stderr, "current mode (%s) not known\n", - (const char*) GetCurrentMode().ToAscii()); - return false; - } - - int numViews = pPhoneMode->GetNumViews(); - if (numViews == 0) { - fprintf(stderr, "Phone %d mode %s has no views\n", - phoneIdx, pPhoneMode->GetName()); - return false; - } - - const int kBorder = 2; - int i; - int maxHeight = 0; - int fullWidth = kBorder; - ViewInfo* pViewInfo; - - pViewInfo = new ViewInfo[numViews]; - - /* figure out individual and overall dimensions */ - for (i = 0; i < numViews; i++) { - pPhoneView = pPhoneMode->GetPhoneView(i); - if (pPhoneView == NULL) { - fprintf(stderr, "view %d not found\n", i); - return false; - } - - if (!GetDimensions(pPhoneData, pPhoneView, &pViewInfo[i])) - return false; - - if (maxHeight < pViewInfo[i].GetHeight()) - maxHeight = pViewInfo[i].GetHeight(); - fullWidth += pViewInfo[i].GetWidth() + kBorder; - } - - /* create the device windows if we don't already have them */ - if (mpDeviceWindow == NULL) { - mNumDeviceWindows = pPhoneData->GetNumDisplays(); - mpDeviceWindow = new DeviceWindow*[mNumDeviceWindows]; - if (mpDeviceWindow == NULL) - return false; - - for (i = 0; i < mNumDeviceWindows; i++) { - mpDeviceWindow[i] = new DeviceWindow(this, &mDeviceManager); - } - } else { - assert(pPhoneData->GetNumDisplays() == mNumDeviceWindows); - } - - /* - * Position device windows within their views, taking into account - * border areas. - */ - int shift = kBorder; - for (i = 0; i < numViews; i++) { - int displayIdx; - PhoneDisplay* pPhoneDisplay; - - displayIdx = pViewInfo[i].GetDisplayIndex(); - pPhoneDisplay = pPhoneData->GetPhoneDisplay(displayIdx); - //printf("View %d: display %d\n", i, displayIdx); - - pViewInfo[i].SetX(shift); - pViewInfo[i].SetY(kBorder); - - mpDeviceWindow[displayIdx]->SetSize( - pViewInfo[i].GetX() + pViewInfo[i].GetDisplayX(), - pViewInfo[i].GetY() + pViewInfo[i].GetDisplayY(), - pPhoneDisplay->GetWidth(), pPhoneDisplay->GetHeight()); - - // incr by width of view - shift += pViewInfo[i].GetWidth() + kBorder; - } - - /* configure the device manager if it's not already running */ - if (!mDeviceManager.IsInitialized()) { - mDeviceManager.Init(pPhoneData->GetNumDisplays(), mpParent); - - for (i = 0; i < pPhoneData->GetNumDisplays(); i++) { - PhoneDisplay* pPhoneDisplay; - bool res; - - pPhoneDisplay = pPhoneData->GetPhoneDisplay(i); - - res = mDeviceManager.SetDisplayConfig(i, mpDeviceWindow[i], - pPhoneDisplay->GetWidth(), pPhoneDisplay->GetHeight(), - pPhoneDisplay->GetFormat(), pPhoneDisplay->GetRefresh()); - if (!res) { - fprintf(stderr, "Sim: ERROR: could not configure device mgr\n"); - return false; - } - } - const char *kmap = pPhoneData->GetPhoneKeyboard(0)->getKeyMap(); - mDeviceManager.SetKeyboardConfig(kmap); - } else { - assert(pPhoneData->GetNumDisplays() == mDeviceManager.GetNumDisplays()); - } - - /* - * Success. Finish up. - */ - mPhoneModel = phoneIdx; - mpViewInfo = pViewInfo; - mNumViewInfo = numViews; - - /* set up our window */ - SetClientSize(fullWidth, maxHeight + kBorder * 2); - SetBackgroundColour(*wxLIGHT_GREY); - //SetBackgroundColour(*wxBLUE); - SetTitle(wxString::FromAscii(pPhoneData->GetTitle())); - - SetFocus(); // set keyboard input focus - - return true; -} - -/* - * The device table has been reloaded. We need to throw out any pointers - * we had into it and possibly reload some stuff. - */ -void PhoneWindow::DevicesRescanned(void) -{ - mpMOHButton = NULL; - mpMOHViewIndex = -1; - - /* - * Re-evaluate phone definition. There is an implicit assumption - * that the re-scanned version is compatible with the previous - * version (i.e. it still exists and has the same screen size). - * - * We're also currently assuming that no phone definitions have been - * added or removed, which is bad -- we should get the new index for - * for phone by searching for it by name. - * - * TODO: don't make these assumptions. - */ - Setup(mPhoneModel); -} - -/* - * Check the initial placement of the window. We get one of these messages - * when the window is first placed, and every time it's moved thereafter. - * - * Right now we're just trying to make sure wxWidgets doesn't shove it off - * the top of the screen under Linux. Might want to change this to - * remember the previous placement and put the window back. - */ -void PhoneWindow::OnMove(wxMoveEvent& event) -{ - if (mPlacementChecked) - return; - - wxPoint point; - point = event.GetPosition(); - if (point.y < 0) { - printf("Sim: window is at (%d,%d), adjusting\n", point.x, point.y); - point.y = 0; - Move(point); - } - - mPlacementChecked = true; -} - -/* - * Figure out the dimensions required to contain the specified view. - * - * This is usually the size of the background image, but if we can't - * load it or it's too small just create a trivial window. - */ -bool PhoneWindow::GetDimensions(PhoneData* pPhoneData, PhoneView* pPhoneView, - ViewInfo* pInfo) -{ - PhoneDisplay* pPhoneDisplay; - int xoff=0, yoff=0, width, height; - int displayIdx; - - displayIdx = pPhoneData->GetPhoneDisplayIndex(pPhoneView->GetDisplayName()); - if (displayIdx < 0) - return false; - - pPhoneDisplay = pPhoneData->GetPhoneDisplay(displayIdx); - if (pPhoneDisplay == NULL) { - fprintf(stderr, "display '%s' not found in device '%s'\n", - pPhoneView->GetDisplayName(), pPhoneData->GetName()); - return false; - } - - // load images for this phone - (void) pPhoneView->LoadResources(); - - width = height = 0; - - // by convention, the background bitmap is the first image in the list - if (pPhoneView->GetBkgImageCount() > 0) { - wxBitmap* pBitmap = pPhoneView->GetBkgImage(0)->GetBitmap(); - if (pBitmap != NULL) { - // size window to match bitmap - xoff = pPhoneView->GetXOffset(); - yoff = pPhoneView->GetYOffset(); - width = pBitmap->GetWidth(); - height = pBitmap->GetHeight(); - } - } - - // no bitmap, or bitmap is smaller than display - if (width < pPhoneDisplay->GetWidth() || - height < pPhoneDisplay->GetHeight()) - { - // create window to just hold display - xoff = yoff = 0; - width = pPhoneDisplay->GetWidth(); - height = pPhoneDisplay->GetHeight(); - } - if (width <= 0 || height <= 0) { - fprintf(stderr, "ERROR: couldn't determine display size\n"); - return false; - } - - pInfo->SetX(0); - pInfo->SetY(0); // another function determines these - pInfo->SetDisplayX(xoff); - pInfo->SetDisplayY(yoff); - pInfo->SetWidth(width); - pInfo->SetHeight(height); - pInfo->SetDisplayIndex(displayIdx); - - //printf("xoff=%d yoff=%d width=%d height=%d index=%d\n", - // pInfo->GetDisplayX(), pInfo->GetDisplayY(), - // pInfo->GetWidth(), pInfo->GetHeight(), pInfo->GetDisplayIndex()); - - return true; -} - -/* - * Return PhoneData pointer for the current phone model. - */ -PhoneData* PhoneWindow::GetPhoneData(void) const -{ - PhoneCollection* pCollection = PhoneCollection::GetInstance(); - return pCollection->GetPhoneData(mPhoneModel); -} - -/* - * Convert a wxWidgets key code into a device key code. - * - * Someday we may want to make this configurable. - * - * NOTE: we need to create a mapping between simulator key and desired - * function. The "return" key should always mean "select", whether - * it's a "select" button or pressing in on the d-pad. Ditto for - * the arrow keys, whether we have a joystick, d-pad, or four buttons. - * Each key here should have a set of things that it could possibly be, - * and we match it up with the set of buttons actually defined for the - * phone. [for convenience, need to ensure that buttons need not have - * an associated image] - */ -int PhoneWindow::ConvertKeyCode(int wxKeyCode) const -{ - switch (wxKeyCode) { - case WXK_NUMPAD_INSERT: - case WXK_NUMPAD0: - case '0': return KEY_0; - case WXK_NUMPAD_HOME: - case WXK_NUMPAD1: - case '1': return KEY_1; - case WXK_NUMPAD_UP: - case WXK_NUMPAD2: - case '2': return KEY_2; - case WXK_NUMPAD_PRIOR: - case WXK_NUMPAD3: - case '3': return KEY_3; - case WXK_NUMPAD_LEFT: - case WXK_NUMPAD4: - case '4': return KEY_4; - case WXK_NUMPAD_BEGIN: - case WXK_NUMPAD5: - case '5': return KEY_5; - case WXK_NUMPAD_RIGHT: - case WXK_NUMPAD6: - case '6': return KEY_6; - case WXK_NUMPAD_END: - case WXK_NUMPAD7: - case '7': return KEY_7; - case WXK_NUMPAD_DOWN: - case WXK_NUMPAD8: - case '8': return KEY_8; - case WXK_NUMPAD_NEXT: - case WXK_NUMPAD9: - case '9': return KEY_9; - case WXK_NUMPAD_MULTIPLY: return KEY_SWITCHVIDEOMODE; //kKeyCodeStar; - case WXK_LEFT: return KEY_LEFT; - case WXK_RIGHT: return KEY_RIGHT; - case WXK_UP: return KEY_UP; - case WXK_DOWN: return KEY_DOWN; - case WXK_NUMPAD_ENTER: return KEY_REPLY; //kKeyCodeDpadCenter; - case WXK_HOME: return KEY_HOME; - case WXK_PRIOR: - case WXK_PAGEUP: return KEY_MENU; //kKeyCodeSoftLeft; - case WXK_NEXT: - case WXK_PAGEDOWN: return KEY_KBDILLUMUP; //kKeyCodeSoftRight; - case WXK_DELETE: - case WXK_BACK: return KEY_BACKSPACE; //kKeyCodeDel; - case WXK_ESCAPE: - case WXK_END: return KEY_BACK; //kKeyCodeBack; - case WXK_NUMPAD_DELETE: - case WXK_NUMPAD_DECIMAL: return KEY_KBDILLUMTOGGLE; //kKeyCodePound; - case WXK_SPACE: return KEY_SPACE; //kKeyCodeSpace; - case WXK_RETURN: return KEY_ENTER; //kKeyCodeNewline; - case WXK_F3: return KEY_F3; //kKeyCodeCall; - case WXK_F4: return KEY_F4; //kKeyCodeEndCall; - case WXK_NUMPAD_ADD: - case WXK_F5: return KEY_VOLUMEUP; - case WXK_NUMPAD_SUBTRACT: - case WXK_F6: return KEY_VOLUMEDOWN; - case WXK_F7: return KEY_POWER; - case WXK_F8: return KEY_CAMERA; - case 'A': return KEY_A; - case 'B': return KEY_B; - case 'C': return KEY_C; - case 'D': return KEY_D; - case 'E': return KEY_E; - case 'F': return KEY_F; - case 'G': return KEY_G; - case 'H': return KEY_H; - case 'I': return KEY_I; - case 'J': return KEY_J; - case 'K': return KEY_K; - case 'L': return KEY_L; - case 'M': return KEY_M; - case 'N': return KEY_N; - case 'O': return KEY_O; - case 'P': return KEY_P; - case 'Q': return KEY_Q; - case 'R': return KEY_R; - case 'S': return KEY_S; - case 'T': return KEY_T; - case 'U': return KEY_U; - case 'V': return KEY_V; - case 'W': return KEY_W; - case 'X': return KEY_X; - case 'Y': return KEY_Y; - case 'Z': return KEY_Z; - case ',': return KEY_COMMA; - case '.': return KEY_DOT; - case '<': return KEY_COMMA; - case '>': return KEY_DOT; - case '`': return KEY_GREEN; /*KEY_GRAVE;*/ - case '-': return KEY_MINUS; - case '=': return KEY_EQUAL; - case '[': return KEY_LEFTBRACE; - case ']': return KEY_RIGHTBRACE; - case '\\': return KEY_BACKSLASH; - case ';': return KEY_SEMICOLON; - case '\'': return KEY_APOSTROPHE; - case '/': return KEY_SLASH; - case WXK_SHIFT: return KEY_LEFTSHIFT; - case WXK_CONTROL: - case WXK_ALT: return KEY_LEFTALT; - case WXK_TAB: return KEY_TAB; - // don't show "ignoring key" message for these - case WXK_MENU: - break; - default: - printf("(ignoring key %d)\n", wxKeyCode); - break; - } - - return kKeyCodeUnknown; -} - - -/* - * Keyboard handling. These get converted into Android-defined key - * constants here. - * - * NOTE: would be nice to handle menu keyboard accelerators here. - * Simply stuffing the key events into MainFrame with AddPendingEvent - * didn't seem to do the trick. - */ -void PhoneWindow::OnKeyDown(wxKeyEvent& event) -{ - KeyCode keyCode; - - keyCode = (KeyCode) ConvertKeyCode(event.GetKeyCode()); - if (keyCode != kKeyCodeUnknown) { - if (!IsKeyPressed(keyCode)) { - //printf("PW: down: key %d\n", keyCode); - GetDeviceManager()->SendKeyEvent(keyCode, true); - AddPressedKey(keyCode); - } - } else { - //printf("PW: down: %d\n", event.GetKeyCode()); - event.Skip(); // not handled by us - } -} - -/* - * Pass key-up events to runtime. - */ -void PhoneWindow::OnKeyUp(wxKeyEvent& event) -{ - KeyCode keyCode; - - keyCode = (KeyCode) ConvertKeyCode(event.GetKeyCode()); - if (keyCode != kKeyCodeUnknown) { - // Send the key event if we already have this key pressed. - if (IsKeyPressed(keyCode)) { - //printf("PW: up: key %d\n", keyCode); - GetDeviceManager()->SendKeyEvent(keyCode, false); - RemovePressedKey(keyCode); - } - } else { - //printf("PW: up: %d\n", event.GetKeyCode()); - event.Skip(); // not handled by us - } -} - -/* - * Mouse handling. - * - * Unlike more conventional button tracking, we highlight on mouse-over - * and send the key on mouse-down. This behavior may be confusing for - * people expecting standard behavior, but it allows us to simulate the - * effect of holding a key down. - * - * We want to catch both "down" and "double click" events; otherwise - * fast clicking results in a lot of discarded events. - */ -void PhoneWindow::OnMouseLeftDown(wxMouseEvent& event) -{ - if (mpMOHButton != NULL) { - //printf("PW: left down\n"); - KeyCode keyCode = mpMOHButton->GetKeyCode(); - GetDeviceManager()->SendKeyEvent(keyCode, true); - mMouseKeySent = keyCode; - AddPressedKey(keyCode); - } else { - int screenX, screenY; - - if (GetTouchPosition(event, &screenX, &screenY)) { - //printf("TOUCH at %d,%d\n", screenX, screenY); - mTrackingTouch = true; - mTouchX = screenX; - mTouchY = screenY; - GetDeviceManager()->SendTouchEvent(Simulator::kTouchDown, - mTouchX, mTouchY); - } else { - //printf("(ignoring left click)\n"); - } - } -} - -/* - * Left button has been released. Do something clever. - * - * On some platforms we will lose this if the mouse leaves the window. - */ -void PhoneWindow::OnMouseLeftUp(wxMouseEvent& WXUNUSED(event)) -{ - if (mMouseKeySent != kKeyCodeUnknown) { - //printf("PW: left up\n"); - GetDeviceManager()->SendKeyEvent(mMouseKeySent, false); - RemovePressedKey(mMouseKeySent); - } else { - if (mTrackingTouch) { - //printf("TOUCH release (last was %d,%d)\n", mTouchX, mTouchY); - mTrackingTouch = false; - GetDeviceManager()->SendTouchEvent(Simulator::kTouchUp, - mTouchX, mTouchY); - } else { - //printf("(ignoring left-up)\n"); - } - } - mMouseKeySent = kKeyCodeUnknown; -} - -void PhoneWindow::OnMouseRightDown(wxMouseEvent& event) -{ - //printf("(ignoring right-down)\n"); -} -void PhoneWindow::OnMouseRightUp(wxMouseEvent& event) -{ - //printf("(ignoring right-up)\n"); -} - -/* - * Track mouse motion so we can do mouse-over button highlighting. - */ -void PhoneWindow::OnMouseMotion(wxMouseEvent& event) -{ - /* - * If the mouse motion event occurred inside the device window, - * we treat it differently than mouse movement over the picture of - * the device. - */ - if (event.GetEventObject() == mpDeviceWindow[0]) { - if (mpMOHViewIndex >= 0) { - /* can happen if the mouse moves fast enough */ - //printf("Mouse now in dev window, clearing button highlight\n"); - mpMOHViewIndex = -1; - mpMOHButton = NULL; - Refresh(); - } - - if (!event.LeftIsDown() && event.RightIsDown()) { - /* right-button movement */ - //printf("(ignoring right-drag)\n"); - return; - } - - //printf("moveto: %d,%d\n", event.m_x, event.m_y); - - int screenX, screenY; - if (mTrackingTouch) { - if (GetTouchPosition(event, &screenX, &screenY)) { - //printf("TOUCH moved to %d,%d\n", screenX, screenY); - mTouchX = screenX; - mTouchY = screenY; - GetDeviceManager()->SendTouchEvent(Simulator::kTouchDrag, - mTouchX, mTouchY); - } else { - //printf("TOUCH moved off screen\n"); - } - } - - return; - } - - PhoneData* pPhoneData = GetPhoneData(); - if (pPhoneData == NULL) - return; - - /* - * Check to see if we're on top of a button. If our "on top of - * something" state has changed, force a redraw. - * - * We have to run through the list of Views and check all of the - * buttons in each. - */ - PhoneMode* pMode = pPhoneData->GetPhoneMode(GetCurrentMode().ToAscii()); - if (pMode == NULL) - return; - - int viewIndex = -1; - PhoneButton* pHighlight = NULL; - int i; - - for (i = pMode->GetNumViews()-1; i >= 0; i--) { - PhoneView* pView = pMode->GetPhoneView(i); - assert(pView != NULL); - - /* convert from window-relative to view-relative */ - pHighlight = pView->FindButtonHit(event.m_x - mpViewInfo[i].GetX(), - event.m_y - mpViewInfo[i].GetY()); - if (pHighlight != NULL) { - viewIndex = i; - break; - } - } - - if (viewIndex == mpMOHViewIndex && pHighlight == mpMOHButton) { - /* still hovering over same button */ - } else { - /* mouse has moved, possibly to a new button */ - - mpMOHViewIndex = viewIndex; - mpMOHButton = pHighlight; - - /* force refresh */ - Refresh(); - } -} - -/* - * Mouse has left the building. All keys and mouse buttons up. - * - * We get one of these if the mouse moves over a child window, such as - * our DeviceWindow, so it is not the case that we no longer receive - * key input after getting this event. - */ -void PhoneWindow::OnMouseLeaveWindow(wxMouseEvent& WXUNUSED(event)) -{ - //printf("--- mouse is GONE\n"); - ClearPressedKeys(); -} - -/* - * Determine device touch screen (x,y) based on window position. - * - * Returns "true" if the click corresponds to a location on the display. - * - * TODO: should return display index as well -- currently this only - * supports touch on the main display. - */ -bool PhoneWindow::GetTouchPosition(const wxMouseEvent& event, int* pScreenX, - int* pScreenY) -{ - /* - * If the click came from our device window, treat it as a touch. - */ - if (event.GetEventObject() != mpDeviceWindow[0]) - return false; - - *pScreenX = event.m_x; - *pScreenY = event.m_y; - return true; -} - -/* - * We don't want to erase the background now, because it causes flicker - * under Windows. - */ -void PhoneWindow::OnErase(wxEraseEvent& WXUNUSED(event)) -{ - //printf("erase\n"); -} - -/* - * Paint the phone and any highlighted buttons. - * - * The device output is drawn by DeviceWindow. - */ -void PhoneWindow::OnPaint(wxPaintEvent& WXUNUSED(event)) -{ - int view; - - /* - * Under Mac OS X, the parent window is redrawn every time the child - * window is redrawn. This causes poor performance in the simulator. - * If we're being asked to update a region that corresponds exactly - * to one of the device output windows, skip the redraw. - */ - assert(mpViewInfo != NULL); - for (view = 0; view < mNumViewInfo; view++) { - int displayIndex; - - displayIndex = mpViewInfo[view].GetDisplayIndex(); - assert(displayIndex >= 0); - DeviceWindow* pDeviceWindow = mpDeviceWindow[displayIndex]; - assert(pDeviceWindow != NULL); - - wxRect displayRect = pDeviceWindow->GetRect(); - wxRect updateRect = GetUpdateClientRect(); - - if (displayRect == updateRect) { - //printf("(skipping redraw)\n"); - return; - } - } - - wxBufferedPaintDC dc(this); - - /* - * Erase the background to the currently-specified background color. - */ - wxColour backColor = GetBackgroundColour(); - dc.SetBrush(wxBrush(backColor)); - dc.SetPen(wxPen(backColor, 1)); - wxRect windowRect(wxPoint(0, 0), GetClientSize()); - dc.DrawRectangle(windowRect); - - PhoneData* pPhoneData = GetPhoneData(); - if (pPhoneData == NULL) { - fprintf(stderr, "OnPaint: no phone data\n"); - return; - } - - PhoneMode* pPhoneMode; - PhoneView* pPhoneView; - int numImages; - - pPhoneMode = pPhoneData->GetPhoneMode(GetCurrentMode().ToAscii()); - if (pPhoneMode == NULL) { - fprintf(stderr, "current mode (%s) not known\n", - (const char*) GetCurrentMode().ToAscii()); - return; - } - - for (view = 0; view < pPhoneMode->GetNumViews(); view++) { - pPhoneView = pPhoneMode->GetPhoneView(view); - if (pPhoneView == NULL) { - fprintf(stderr, "view %d not found\n", view); - return; - } - - /* draw background image and "button patches" */ - numImages = pPhoneView->GetBkgImageCount(); - for (int i = 0; i < numImages; i++) { - const LoadableImage* pLimg = pPhoneView->GetBkgImage(i); - wxBitmap* pBitmap = pLimg->GetBitmap(); - if (pBitmap != NULL) - dc.DrawBitmap(*pBitmap, - mpViewInfo[view].GetX() + pLimg->GetX(), - mpViewInfo[view].GetY() + pLimg->GetY(), - TRUE); - } - } - - - /* - * Draw button mouse-over highlight. - * - * Currently we don't do anything different when the button is held down. - */ - if (mpMOHViewIndex >= 0 && mpMOHButton != NULL) { - // button must have graphic, or hit-testing wouldn't have worked - assert(mpMOHButton->GetHighlightedBitmap() != NULL); - dc.DrawBitmap(*mpMOHButton->GetHighlightedBitmap(), - mpViewInfo[mpMOHViewIndex].GetX() + mpMOHButton->GetX(), - mpViewInfo[mpMOHViewIndex].GetY() + mpMOHButton->GetY(), - TRUE); - } - - /* - * Highlight pressed keys. We want to do this in all views, because - * some buttons on the side of the phone might be visible in more - * than one view. - */ - for (view = 0; view < pPhoneMode->GetNumViews(); view++) { - pPhoneView = pPhoneMode->GetPhoneView(view); - assert(pPhoneView != NULL); - - ListIter iter; - for (iter = mPressedKeys.begin(); iter != mPressedKeys.end(); ++iter) { - KeyCode keyCode; - PhoneButton* pButton; - - keyCode = (*iter).GetKeyCode(); - pButton = pPhoneView->FindButtonByKey(keyCode); - if (pButton != NULL) { - wxBitmap* pBitmap = pButton->GetSelectedBitmap(); - if (pBitmap != NULL) { - dc.DrawBitmap(*pBitmap, - mpViewInfo[view].GetX() + pButton->GetX(), - mpViewInfo[view].GetY() + pButton->GetY(), - TRUE); - } - } - } - } -} - - -/* - * Press a key on the device. - * - * Schedules a screen refresh if the set of held-down keys changes. - */ -void PhoneWindow::AddPressedKey(KeyCode keyCode) -{ - /* - * See if the key is already down. This usually means that the key - * repeat has kicked into gear. It could also mean that we - * missed the key-up event, or the user has hit the same device - * key with both mouse and keyboard. Either way, we don't add it - * a second time. This way, if we did lose a key-up somehow, they - * can "clear" the stuck key by hitting it again. - */ - if (keyCode == kKeyCodeUnknown) { - //printf("--- not adding kKeyCodeUnknown!\n"); - return; - } - - ListIter iter; - for (iter = mPressedKeys.begin(); iter != mPressedKeys.end(); ++iter) { - if ((*iter).GetKeyCode() == keyCode) - break; - } - if (iter == mPressedKeys.end()) { - KeyInfo newInfo; - newInfo.SetKeyCode(keyCode); - mPressedKeys.push_back(newInfo); - //printf("--- added down=%d\n", keyCode); - Refresh(); // redraw w/ highlight - } else { - //printf("--- already have down=%d\n", keyCode); - } -} - -/* - * Release a key on the device. - * - * Schedules a screen refresh if the set of held-down keys changes. - */ -void PhoneWindow::RemovePressedKey(KeyCode keyCode) -{ - /* - * Release the key. If it's not in the list, we either missed a - * key-down event, or the user used both mouse and keyboard and we - * removed the key when the first device went up. - */ - ListIter iter; - for (iter = mPressedKeys.begin(); iter != mPressedKeys.end(); ++iter) { - if ((*iter).GetKeyCode() == keyCode) { - mPressedKeys.erase(iter); - //printf("--- removing down=%d\n", keyCode); - Refresh(); // redraw w/o highlight - break; - } - } - if (iter == mPressedKeys.end()) { - //printf("--- didn't find down=%d\n", keyCode); - } -} - -/* - * Clear the set of keys that we think are being held down. - */ -void PhoneWindow::ClearPressedKeys(void) -{ - //printf("--- All keys up (count=%d)\n", mPressedKeys.size()); - - if (!mPressedKeys.empty()) { - ListIter iter = mPressedKeys.begin(); - while (iter != mPressedKeys.end()) { - KeyCode keyCode = (*iter).GetKeyCode(); - GetDeviceManager()->SendKeyEvent(keyCode, false); - iter = mPressedKeys.erase(iter); - } - Refresh(); - } -} - -/* - * Returns "true" if the specified key is currently pressed. - */ -bool PhoneWindow::IsKeyPressed(KeyCode keyCode) -{ - ListIter iter; - for (iter = mPressedKeys.begin(); iter != mPressedKeys.end(); ++iter) { - if ((*iter).GetKeyCode() == keyCode) - return true; - } - return false; -} - -void PhoneWindow::Vibrate(int vibrateOn) -{ - wxRect rect = GetRect(); - if(vibrateOn) - { - mVibrateX = 0; - mTimer.Start(25); // arg is delay in ms - Move(rect.x-2,rect.y); - } - else if(mTimer.IsRunning()) - { - mTimer.Stop(); - if(mVibrateX&1) - Move(rect.x-2,rect.y); - else - Move(rect.x+2,rect.y); - } -} - -void PhoneWindow::OnTimer(wxTimerEvent& event) -{ - wxRect rect = GetRect(); - mVibrateX++; - if(mVibrateX&1) - Move(rect.x+4,rect.y); - else - Move(rect.x-4,rect.y); -} diff --git a/simulator/app/PhoneWindow.h b/simulator/app/PhoneWindow.h deleted file mode 100644 index 5eb18000d..000000000 --- a/simulator/app/PhoneWindow.h +++ /dev/null @@ -1,186 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Window with simulated phone. -// -#ifndef _SIM_PHONE_WINDOW_H -#define _SIM_PHONE_WINDOW_H - -#include "PhoneData.h" -#include "DeviceManager.h" -#include "DeviceWindow.h" -#include <ui/KeycodeLabels.h> - -class MainFrame; - -/* - * This window displays the simulated phone views, and handles keyboard and - * mouse input. - * - * If we switch to a different "mode", we may display different "views", - * but the set of "displays" remains the same. (Got that?) - * - * We can't just do these things in the main frame because we can't easily - * grab the keyboard input. - */ -class PhoneWindow : public wxDialog { -public: - PhoneWindow(wxWindow* parent, const wxPoint& posn); - virtual ~PhoneWindow(void); - - /* call this initially, and after a mode change */ - bool Setup(int phoneIdx); - - bool IsReady(void) const { - return (mNumViewInfo > 0 && mpViewInfo != NULL); - } - - PhoneData* GetPhoneData(void) const; - - const wxString& GetCurrentMode(void) const { return mCurrentMode; } - void SetCurrentMode(const wxString& mode) { mCurrentMode = mode; } - void SetCurrentMode(const char* mode) { mCurrentMode = wxString::FromAscii(mode); } - - DeviceManager* GetDeviceManager(void) { return &mDeviceManager; } - - /* this is called when the phone data is reloaded */ - void DevicesRescanned(void); - - void Vibrate(int vibrateOn); - -private: - /* - * Hold some information about the "views" being shown in our window. - */ - class ViewInfo { - public: - ViewInfo(void) - : mX(-1), mY(-1), mDisplayX(-1), mDisplayY(-1), - mWidth(-1), mHeight(-1), mDisplayIndex(-1) - {} - ~ViewInfo(void) {} - - int GetX(void) const { return mX; } - int GetY(void) const { return mY; } - int GetDisplayX(void) const { return mDisplayX; } - int GetDisplayY(void) const { return mDisplayY; } - int GetWidth(void) const { return mWidth; } - int GetHeight(void) const { return mHeight; } - int GetDisplayIndex(void) const { return mDisplayIndex; } - - void SetX(int val) { mX = val; } - void SetY(int val) { mY = val; } - void SetDisplayX(int val) { mDisplayX = val; } - void SetDisplayY(int val) { mDisplayY = val; } - void SetWidth(int val) { mWidth = val; } - void SetHeight(int val) { mHeight = val; } - void SetDisplayIndex(int val) { mDisplayIndex = val; } - - private: - int mX, mY; // view offset within PhoneWindow - int mDisplayX, mDisplayY; // display offset within view - int mWidth, mHeight; // view dimensions - - int mDisplayIndex; // index into mpDeviceWindow - }; - - /* - * Hold information about currently pressed keys. - */ - class KeyInfo { - public: - KeyInfo(void) : mKeyCode(kKeyCodeUnknown) {} - KeyInfo(const KeyInfo& src) { - mKeyCode = src.mKeyCode; - } - ~KeyInfo(void) {} - - KeyInfo& operator=(const KeyInfo& src) { - if (this != &src) { - mKeyCode = src.mKeyCode; - } - return *this; - } - - KeyCode GetKeyCode(void) const { return mKeyCode; } - void SetKeyCode(KeyCode keyCode) { mKeyCode = keyCode; } - - //PhoneButton* GetPhoneButton(void) const { return mpButton; } - //void SetPhoneButton(PhoneButton* pButton) { mpButton = pButton; } - - private: - KeyCode mKeyCode; - //PhoneButton* mpButton; - }; - - void OnActivate(wxActivateEvent& event); - void OnMove(wxMoveEvent& event); - void OnClose(wxCloseEvent& event); - void OnTimer(wxTimerEvent& event); - void OnKeyDown(wxKeyEvent& event); - void OnKeyUp(wxKeyEvent& event); - void OnErase(wxEraseEvent& event); - void OnPaint(wxPaintEvent& WXUNUSED(event)); - void OnMouseLeftDown(wxMouseEvent& event); - void OnMouseLeftUp(wxMouseEvent& event); - void OnMouseRightDown(wxMouseEvent& event); - void OnMouseRightUp(wxMouseEvent& event); - void OnMouseMotion(wxMouseEvent& event); - void OnMouseLeaveWindow(wxMouseEvent& WXUNUSED(event)); - bool GetTouchPosition(const wxMouseEvent& event, int* pScreenX, - int* pScreenY); - - bool GetDimensions(PhoneData* pPhoneData, PhoneView* pPhoneView, - ViewInfo* pDim); - int ConvertKeyCode(int wxKeyCode) const; - - /* press a key on the device */ - void AddPressedKey(KeyCode keyCode); - /* release a key on the device */ - void RemovePressedKey(KeyCode keyCode); - /* "raise" all keys */ - void ClearPressedKeys(void); - /* determine whether a key is down */ - bool IsKeyPressed(KeyCode keyCode); - - /* manage the device runtime */ - DeviceManager mDeviceManager; - - /* button mouse-over highlight handling */ - int mpMOHViewIndex; // mouse is in this view - PhoneButton* mpMOHButton; // over this button - KeyCode mMouseKeySent; // to handle "key up" for mouse button - - /* handle multiple simultaneous key presses */ - android::List<KeyInfo> mPressedKeys; - typedef android::List<KeyInfo>::iterator ListIter; - - /* ViewInfos, 1:1 with PhoneView entries for the current mode */ - ViewInfo* mpViewInfo; // array of view data - int mNumViewInfo; // #of elements in mpViewInfo - - /* DeviceWindows, 1:1 with PhoneDisplay entries for this device */ - DeviceWindow** mpDeviceWindow; // array of pointers to device windows - int mNumDeviceWindows; // #of device windows - - /* state */ - int mPhoneModel; // index into model list - wxString mCurrentMode; - - bool mPlacementChecked; // leave it offscreen if they want - - MainFrame* mpParent; // retain pointer to parent window - - enum { kVibrateTimerId = 1010 }; - wxTimer mTimer; - int mVibrateX; - - /* touchscreen simulation */ - bool mTrackingTouch; - int mTouchX; - int mTouchY; - - DECLARE_EVENT_TABLE() -}; - -#endif // _SIM_PHONE_WINDOW_H diff --git a/simulator/app/Preferences.cpp b/simulator/app/Preferences.cpp deleted file mode 100644 index 039f1ffe5..000000000 --- a/simulator/app/Preferences.cpp +++ /dev/null @@ -1,475 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Preferences file access. -// - -// For compilers that support precompilation, include "wx/wx.h". -#include "wx/wxprec.h" -// Otherwise, include all standard headers -#ifndef WX_PRECOMP -//# include "wx/wx.h" -# include "wx/string.h" -#endif - -#include "Preferences.h" - -#include "utils.h" -#include "tinyxml.h" - -static const char* kName = "name"; -static const char* kValue = "value"; - - -/* - * Load from a file. - */ -bool Preferences::Load(const char* fileName) -{ - assert(fileName != NULL); - printf("SimPref: reading preferences file '%s'\n", fileName); - - // throw out any existing stuff - delete mpDoc; - - mpDoc = new TiXmlDocument; - if (mpDoc == NULL) - return false; - - if (!mpDoc->LoadFile(fileName)) { - fprintf(stderr, "SimPref: ERROR: failed loading '%s'\n", fileName); - if (mpDoc->ErrorRow() != 0) - fprintf(stderr, " XML: %s (row=%d col=%d)\n", - mpDoc->ErrorDesc(), mpDoc->ErrorRow(), mpDoc->ErrorCol()); - else - fprintf(stderr, " XML: %s\n", mpDoc->ErrorDesc()); - goto fail; - } - - TiXmlNode* pPrefs; - pPrefs = mpDoc->FirstChild("prefs"); - if (pPrefs == NULL) { - fprintf(stderr, "SimPref: ERROR: could not find <prefs> in '%s'\n", - fileName); - goto fail; - } - - // set defaults for anything we haven't set explicitly - SetDefaults(); - - return true; - -fail: - delete mpDoc; - mpDoc = NULL; - return false; -} - -/* - * Save to a file. - */ -bool Preferences::Save(const char* fileName) -{ - assert(fileName != NULL); - - if (mpDoc == NULL) - return false; - - if (!mpDoc->SaveFile(fileName)) { - fprintf(stderr, "SimPref: ERROR: failed saving '%s': %s\n", - fileName, mpDoc->ErrorDesc()); - return false; - } - - mDirty = false; - - return true; -} - -/* - * Create an empty collection of preferences. - */ -bool Preferences::Create(void) -{ - static const char* docBase = - "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" - "<!-- Android device simulator preferences -->\n" - "<!-- This file is updated by the simulator -->\n" - "<prefs>\n" - "</prefs>\n"; - - // throw out any existing stuff - delete mpDoc; - - // alloc and initialize - mpDoc = new TiXmlDocument; - if (mpDoc == NULL) - return false; - - if (!mpDoc->Parse(docBase)) { - fprintf(stderr, "SimPref: bad docBase: %s\n", mpDoc->ErrorDesc()); - return false; - } - - SetDefaults(); - mDirty = true; // should already be, mbut make sure - return true; -} - -/* - * Add default values to XML doc. - * - * This isn't strictly necessary, because the functions that are interested - * in the preferences can set appropriate defaults themselves when the - * "get" function returns "false". However, in some cases a preference - * can be interesting to more than one function, and you either have to - * cut & paste the default value or write a "get default for xxx" function. - * - * We want this to work even if they already have an older config file, so - * this only sets values that don't already exist. - */ -void Preferences::SetDefaults(void) -{ - /* table of default values */ - static const struct { - const char* type; - const char* name; - const char* value; - } kDefault[] = { - { "pref", "auto-power-on", "true" }, - { "pref", "debug", "false" }, - { "pref", "valgrind", "false" }, - { "pref", "check-jni", "true" }, - { "pref", "enable-sound", "true" }, - { "pref", "enable-fake-camera", "true" }, - { "pref", "java-vm", "Dalvik" }, - /* goobuntu dapper needed LD_ASSUME_KERNEL or gdb choked badly */ - { "pref", "ld-assume-kernel", "" /*2.4.19*/ }, - { "pref", "launch-command", - "xterm -geom 80x60+10+10 -sb -title Simulator -e" }, - { "pref", "launch-wrapper-args", "-wait" }, - }; - TiXmlNode* pPrefs; - - assert(mpDoc != NULL); - - pPrefs = mpDoc->FirstChild("prefs"); - - /* - * Look up the name. If it doesn't exist, add it. - */ - for (int i = 0; i < NELEM(kDefault); i++) { - TiXmlNode* pNode = _FindNode(kDefault[i].type, kDefault[i].name); - - if (pNode == NULL) { - TiXmlElement elem(kDefault[i].type); - elem.SetAttribute(kName, kDefault[i].name); - elem.SetAttribute(kValue, kDefault[i].value); - pPrefs->InsertEndChild(elem); - - printf("SimPref: added default <%s> '%s'='%s'\n", - kDefault[i].type, kDefault[i].name, kDefault[i].value); - } else { - printf("SimPref: found existing <%s> '%s'\n", - kDefault[i].type, kDefault[i].name); - } - } -} - -static TiXmlNode* get_next_node(TiXmlNode* pNode) -{ - if (!pNode->NoChildren()) - { - pNode = pNode->FirstChild(); - } - else if (pNode->NoChildren() && - (pNode->NextSibling() == NULL)) - { - pNode = pNode->Parent()->NextSibling(); - } - else - { - pNode = pNode->NextSibling(); - } - return pNode; -} - -/* - * Returns the node with element type and name specified - * - * WARNING: this searches through the tree and returns the first matching - * node. - */ -TiXmlNode* Preferences::_FindNode(const char* type, const char* str) const -{ - assert((type != NULL) && (str != NULL)); - TiXmlNode* pRoot; - TiXmlNode* pNode; - - pRoot = mpDoc->FirstChild("prefs"); - assert(pRoot != NULL); - - for (pNode = pRoot->FirstChild(); pNode != NULL;) - { - if (pNode->Type() != TiXmlNode::ELEMENT || - strcasecmp(pNode->Value(), type) != 0) - { - pNode = get_next_node(pNode); - continue; - } - - TiXmlElement* pElem = pNode->ToElement(); - assert(pElem != NULL); - - const char* name = pElem->Attribute(kName); - - /* 1. If the name is blank, something is wrong with the config file - * 2. If the name matches the passed in string, we found the node - * 3. If the node has children, descend another level - * 4. If there are no children and no siblings of the node, go up a level - * 5. Otherwise, grab the next sibling - */ - if (name == NULL) - { - fprintf(stderr, "WARNING: found <%s> without name\n", type); - continue; - } - else if (strcasecmp(name, str) == 0) - { - return pNode; - } - else - { - pNode = get_next_node(pNode); - } - } - - return NULL; -} - -/* - * Locate the specified preference. - */ -TiXmlNode* Preferences::FindPref(const char* str) const -{ - TiXmlNode* pNode = _FindNode("pref", str); - return pNode; -} - -/* - * Like FindPref(), but returns a TiXmlElement. - */ -TiXmlElement* Preferences::FindPrefElement(const char* str) const -{ - TiXmlNode* pNode; - - pNode = FindPref(str); - if (pNode != NULL) - return pNode->ToElement(); - return NULL; -} - -/* - * Add a new preference entry with a blank entry for value. Returns a - * pointer to the new element. - */ -TiXmlElement* Preferences::AddPref(const char* str) -{ - assert(FindPref(str) == NULL); - - TiXmlNode* pPrefs; - - pPrefs = mpDoc->FirstChild("prefs"); - assert(pPrefs != NULL); - - TiXmlElement elem("pref"); - elem.SetAttribute(kName, str); - elem.SetAttribute(kValue, ""); - pPrefs->InsertEndChild(elem); - - TiXmlNode* pNewPref = FindPref(str); - return pNewPref->ToElement(); -} - -/* - * Remove a node from the tree - */ -bool Preferences::_RemoveNode(TiXmlNode* pNode) -{ - if (pNode == NULL) - return false; - - TiXmlNode* pParent = pNode->Parent(); - if (pParent == NULL) - return false; - - pParent->RemoveChild(pNode); - mDirty = true; - return true; -} - -/* - * Remove a preference entry. - */ -bool Preferences::RemovePref(const char* delName) -{ - return _RemoveNode(FindPref(delName)); -} - -/* - * Test for existence. - */ -bool Preferences::Exists(const char* name) const -{ - TiXmlElement* pElem = FindPrefElement(name); - return (pElem != NULL); -} - -/* - * Internal implemenations for getting values - */ -bool Preferences::_GetBool(TiXmlElement* pElem, bool* pVal) const -{ - if (pElem != NULL) - { - const char* str = pElem->Attribute(kValue); - if (str != NULL) - { - if (strcasecmp(str, "true") == 0) - *pVal = true; - else if (strcasecmp(str, "false") == 0) - *pVal = false; - else - { - printf("SimPref: evaluating as bool name='%s' val='%s'\n", - pElem->Attribute(kName), str); - return false; - } - return true; - } - } - return false; -} - -bool Preferences::_GetInt(TiXmlElement* pElem, int* pInt) const -{ - int val; - if (pElem != NULL && pElem->Attribute(kValue, &val) != NULL) { - *pInt = val; - return true; - } - return false; -} - -bool Preferences::_GetDouble(TiXmlElement* pElem, double* pDouble) const -{ - double val; - if (pElem != NULL && pElem->Attribute(kValue, &val) != NULL) { - *pDouble = val; - return true; - } - return false; -} - -bool Preferences::_GetString(TiXmlElement* pElem, wxString& str) const -{ - const char* val; - if (pElem != NULL) { - val = pElem->Attribute(kValue); - if (val != NULL) { - str = wxString::FromAscii(val); - return true; - } - } - return false; -} - -/* - * Get a value. Do not disturb "*pVal" unless we have something to return. - */ -bool Preferences::GetBool(const char* name, bool* pVal) const -{ - return _GetBool(FindPrefElement(name), pVal); -} - -bool Preferences::GetInt(const char* name, int* pInt) const -{ - return _GetInt(FindPrefElement(name), pInt); -} - -bool Preferences::GetDouble(const char* name, double* pDouble) const -{ - return _GetDouble(FindPrefElement(name), pDouble); -} - -bool Preferences::GetString(const char* name, char** pVal) const -{ - wxString str = wxString::FromAscii(*pVal); - if (_GetString(FindPrefElement(name), str)) - { - *pVal = android::strdupNew(str.ToAscii()); - return true; - } - return false; -} - -bool Preferences::GetString(const char* name, wxString& str) const -{ - return _GetString(FindPrefElement(name), str); -} - -/* - * Set a value. If the preference already exists, and the value hasn't - * changed, don't do anything. This avoids setting the "dirty" flag - * unnecessarily. - */ -void Preferences::SetBool(const char* name, bool val) -{ - bool oldVal; - if (GetBool(name, &oldVal) && val == oldVal) - return; - - SetString(name, val ? "true" : "false"); - mDirty = true; -} - -void Preferences::SetInt(const char* name, int val) -{ - int oldVal; - if (GetInt(name, &oldVal) && val == oldVal) - return; - - TiXmlElement* pElem = FindPrefElement(name); - if (pElem == NULL) - pElem = AddPref(name); - pElem->SetAttribute(kValue, val); - mDirty = true; -} - -void Preferences::SetDouble(const char* name, double val) -{ - double oldVal; - if (GetDouble(name, &oldVal) && val == oldVal) - return; - - TiXmlElement* pElem = FindPrefElement(name); - if (pElem == NULL) - pElem = AddPref(name); - pElem->SetDoubleAttribute(kValue, val); - mDirty = true; -} - -void Preferences::SetString(const char* name, const char* val) -{ - wxString oldVal; - if (GetString(name, /*ref*/oldVal) && strcmp(oldVal.ToAscii(), val) == 0) - return; - - TiXmlElement* pElem = FindPrefElement(name); - if (pElem == NULL) - pElem = AddPref(name); - pElem->SetAttribute(kValue, val); - mDirty = true; -} - - diff --git a/simulator/app/Preferences.h b/simulator/app/Preferences.h deleted file mode 100644 index 91c35dec9..000000000 --- a/simulator/app/Preferences.h +++ /dev/null @@ -1,104 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Preferences file access. -// -#ifndef _SIM_PREFERENCES_H -#define _SIM_PREFERENCES_H - -#include "tinyxml.h" - -/* - * This class provides access to a preferences file. It's possible to - * have more than one instance, though it's probably unwise to have multiple - * objects for the same file on disk. - * - * All value are stored as strings. The class doesn't really try to - * enforce type safety, but it will complain if you try to do something - * nonsensical (like convert "foo" to an integer). - */ -class Preferences { -public: - Preferences(void) : - mpDoc(NULL), mDirty(false) - {} - ~Preferences(void) { - delete mpDoc; - } - - /* load all preferences from a file */ - bool Load(const char* fileName); - - /* save all preferences to a file */ - bool Save(const char* fileName); - - /* create new preferences set (use when file does not exist) */ - bool Create(void); - - /* - * Retrieve a value from the preferences database. - * - * These return "false" if the value was not found or could not be - * converted to the expected type. The value pointed to be the second - * arg is guaranteed to be left undisturbed in this case. - * - * The value set by GetString(const char*, char**) will be set to - * newly-allocated storage that must be freed with "delete[]". This - * is done instead of returning a const char* because it's unclear - * what guarantees TinyXml makes wrt string lifetime (especially in - * a multithreaded environment). - */ - bool GetBool(const char* name, bool* pVal) const; - bool GetInt(const char* name, int* pInt) const; - bool GetDouble(const char* name, double* pDouble) const; - bool GetString(const char* name, char** pVal) const; - bool GetString(const char* name, wxString& str) const; - - /* - * Set a value in the database. - */ - void SetBool(const char* name, bool val); - void SetInt(const char* name, int val); - void SetDouble(const char* name, double val); - void SetString(const char* name, const char* val); - - /* - * Just test for existence. - */ - bool Exists(const char* name) const; - - /* - * Remove a <pref> from the config file. - */ - bool RemovePref(const char* name); - - /* - * Get the value of the "dirty" flag. - */ - bool GetDirty(void) const { return mDirty; } - -private: - /* Implementation of getters */ - bool _GetBool(TiXmlElement* pElem, bool* pVal) const; - bool _GetInt(TiXmlElement* pElem, int* pInt) const; - bool _GetDouble(TiXmlElement* pElem, double* pDouble) const; - bool _GetString(TiXmlElement* pElem, wxString& str) const; - - /* this can be used to generate some defaults */ - void SetDefaults(void); - - /* locate the named preference */ - TiXmlNode* _FindNode(const char* type, const char* name) const; - TiXmlNode* FindPref(const char* str) const; - /* like FindPref, but returns a TiXmlElement */ - TiXmlElement* FindPrefElement(const char* str) const; - /* add a new preference entry */ - TiXmlElement* AddPref(const char* str); - /* removes a node */ - bool _RemoveNode(TiXmlNode* pNode); - - TiXmlDocument* mpDoc; - bool mDirty; -}; - -#endif // _SIM_PREFERENCES_H diff --git a/simulator/app/PrefsDialog.cpp b/simulator/app/PrefsDialog.cpp deleted file mode 100644 index e146a56b9..000000000 --- a/simulator/app/PrefsDialog.cpp +++ /dev/null @@ -1,292 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Preferences modal dialog. -// - -// For compilers that support precompilation, include "wx/wx.h". -#include "wx/wxprec.h" -// Otherwise, include all standard headers -#ifndef WX_PRECOMP -# include "wx/wx.h" -#endif - -#include "PrefsDialog.h" -#include "Preferences.h" -#include "MyApp.h" -#include "Resource.h" - -BEGIN_EVENT_TABLE(PrefsDialog, wxDialog) -END_EVENT_TABLE() - -/* - * Constructor. - */ -PrefsDialog::PrefsDialog(wxWindow* parent) - : wxDialog(parent, IDD_PREFS, wxT("Preferences"), wxDefaultPosition, - wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ), - mAutoPowerOn(false), - mGammaCorrection(1.0), - mEnableSound(true), - mEnableFakeCamera(true), - mLogLevel(0) -{ - LoadPreferences(); - CreateControls(); -} - -/* - * Destructor. Not much to do. - */ -PrefsDialog::~PrefsDialog() -{ -} - -/* - * Create all of the pages and add them to the notebook. - */ -void PrefsDialog::CreateControls(void) -{ - wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL); - wxBoxSizer* okCancelSizer = new wxBoxSizer(wxHORIZONTAL); - mNotebook.Create(this, wxID_ANY); - wxPanel* page; - - /* pages added to notebook are owned by notebook */ - page = CreateSimulatorPage(&mNotebook); - mNotebook.AddPage(page, wxT("Simulator"), true); // selected page - page = CreateRuntimePage(&mNotebook); - mNotebook.AddPage(page, wxT("Runtime"), false); - - wxButton* cancel = new wxButton(this, wxID_CANCEL, wxT("&Cancel"), - wxDefaultPosition, wxDefaultSize, 0); - okCancelSizer->Add(cancel, 0, wxALL | wxALIGN_RIGHT, kInterSpacing); - - wxButton* ok = new wxButton(this, wxID_OK, wxT("&OK"), - wxDefaultPosition, wxDefaultSize, 0); - okCancelSizer->Add(ok, 0, wxALL | wxALIGN_RIGHT, kInterSpacing); - - mainSizer->Add(&mNotebook, 1, wxEXPAND); - mainSizer->Add(okCancelSizer, 0, wxALIGN_RIGHT); - - SetSizer(mainSizer); - - mainSizer->Fit(this); // shrink-to-fit - mainSizer->SetSizeHints(this); // define minimum size -} - -/* - * Load preferences from config file - */ -void PrefsDialog::LoadPreferences(void) -{ - Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - assert(pPrefs != NULL); - - /* - * Load preferences. - */ - mConfigFile = ((MyApp*)wxTheApp)->GetConfigFileName(); - - pPrefs->GetDouble("gamma", &mGammaCorrection); - pPrefs->GetString("debugger", /*ref*/ mDebugger); - pPrefs->GetString("valgrinder", /*ref*/ mValgrinder); - pPrefs->GetBool("auto-power-on", &mAutoPowerOn); - pPrefs->GetBool("enable-sound", &mEnableSound); - pPrefs->GetBool("enable-fake-camera", &mEnableFakeCamera); -} - -/* - * Transfer data from our members to the window controls. - * - * First we have to pull the data out of the preferences database. - * Anything that hasn't already been added with a default value will - * be given a default here, which may or may not match the default - * behavior elsewhere. The best solution to this is to define the - * default when the preferences file is created or read, so that we're - * never left guessing here. - */ -bool PrefsDialog::TransferDataToWindow(void) -{ - /* - * Do standard dialog setup. - */ - wxTextCtrl* configFileName = (wxTextCtrl*) FindWindow(IDC_SPREFS_CONFIG_NAME); - wxTextCtrl* debugger = (wxTextCtrl*) FindWindow(IDC_SPREFS_DEBUGGER); - wxTextCtrl* valgrinder = (wxTextCtrl*) FindWindow(IDC_SPREFS_VALGRINDER); - wxCheckBox* autoPowerOn = (wxCheckBox*) FindWindow(IDC_SPREFS_AUTO_POWER_ON); - wxCheckBox* enableSound = (wxCheckBox*) FindWindow(IDC_RPREFS_ENABLE_SOUND); - wxCheckBox* enableFakeCamera = (wxCheckBox*) FindWindow(IDC_RPREFS_ENABLE_FAKE_CAMERA); - - wxTextCtrl* gamma = (wxTextCtrl*) FindWindow(IDC_RPREFS_GAMMA); - - configFileName->SetValue(mConfigFile); - debugger->SetValue(mDebugger); - valgrinder->SetValue(mValgrinder); - autoPowerOn->SetValue(mAutoPowerOn); - enableSound->SetValue(mEnableSound); - enableFakeCamera->SetValue(mEnableFakeCamera); - - wxString tmpStr; - tmpStr.Printf(wxT("%.3f"), mGammaCorrection); - gamma->SetValue(tmpStr); - - return true; -} - -/* - * Transfer and validate data from the window controls. - * - * This doesn't get called if the user cancels out of the dialog. - */ -bool PrefsDialog::TransferDataFromControls(void) -{ - /* - * Do standard dialog export. - * - * We should error-check all of these. - */ - // configName is read-only, don't need it here - wxTextCtrl* debugger = (wxTextCtrl*) FindWindow(IDC_SPREFS_DEBUGGER); - wxTextCtrl* valgrinder = (wxTextCtrl*) FindWindow(IDC_SPREFS_VALGRINDER); - wxCheckBox* autoPowerOn = (wxCheckBox*) FindWindow(IDC_SPREFS_AUTO_POWER_ON); - wxCheckBox* enableSound = (wxCheckBox*) FindWindow(IDC_RPREFS_ENABLE_SOUND); - wxCheckBox* enableFakeCamera = (wxCheckBox*) FindWindow(IDC_RPREFS_ENABLE_FAKE_CAMERA); - - wxTextCtrl* gamma = (wxTextCtrl*) FindWindow(IDC_RPREFS_GAMMA); - - mDebugger = debugger->GetValue(); - mValgrinder = valgrinder->GetValue(); - mAutoPowerOn = autoPowerOn->GetValue(); - mEnableSound = enableSound->GetValue(); - mEnableFakeCamera = enableFakeCamera->GetValue(); - - wxString tmpStr; - tmpStr = gamma->GetValue(); - bool toDouble = tmpStr.ToDouble(&mGammaCorrection); // returns 0.0 on err; use strtof()? - - if (!toDouble || mGammaCorrection <= 0.0 || mGammaCorrection > 2.0) { - wxMessageBox(wxT("Bad value for gamma -- must be > 0.0 and <= 2.0"), - wxT("Hoser"), wxOK, this); - return false; - } - - return true; -} - -/* - * Transfer preferences to config file - */ -bool PrefsDialog::TransferDataFromWindow(void) -{ - Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - assert(pPrefs != NULL); - - /* - * Grab the information from the controls and save in member field - */ - - if (!TransferDataFromControls()) - return false; - - pPrefs->SetString("debugger", mDebugger.ToAscii()); - pPrefs->SetString("valgrinder", mValgrinder.ToAscii()); - pPrefs->SetBool("auto-power-on", mAutoPowerOn); - pPrefs->SetBool("enable-sound", mEnableSound); - pPrefs->SetBool("enable-fake-camera", mEnableFakeCamera); - - pPrefs->SetDouble("gamma", mGammaCorrection); - - return true; -} - - -/* - * Create the Simulator Preferences page. - */ -wxPanel* PrefsDialog::CreateSimulatorPage(wxBookCtrlBase* parent) -{ - wxPanel* panel = new wxPanel(parent); - - wxStaticText* configNameDescr = new wxStaticText(panel, wxID_STATIC, - wxT("Config file:")); - wxTextCtrl* configName = new wxTextCtrl(panel, IDC_SPREFS_CONFIG_NAME, - wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_READONLY); - // make it visibly different; unfortunately this kills scroll, copy&paste - configName->Enable(false); - - wxStaticText* debuggerDescr = new wxStaticText(panel, wxID_STATIC, - wxT("Debugger:")); - wxTextCtrl* debugger = new wxTextCtrl(panel, IDC_SPREFS_DEBUGGER); - - wxStaticText* valgrinderDescr = new wxStaticText(panel, wxID_STATIC, - wxT("Valgrind:")); - wxTextCtrl* valgrinder = new wxTextCtrl(panel, IDC_SPREFS_VALGRINDER); - - wxCheckBox* autoPowerOn = new wxCheckBox(panel, IDC_SPREFS_AUTO_POWER_ON, - wxT("Boot runtime when simulator starts")); - - wxBoxSizer* sizerPanel = new wxBoxSizer(wxVERTICAL); - sizerPanel->Add(kMinWidth, kEdgeSpacing); // forces minimum width - sizerPanel->Add(configNameDescr); - sizerPanel->Add(configName, 0, wxEXPAND); - sizerPanel->AddSpacer(kInterSpacing); - sizerPanel->AddSpacer(kInterSpacing); - sizerPanel->Add(debuggerDescr); - sizerPanel->Add(debugger, 0, wxEXPAND); - sizerPanel->AddSpacer(kInterSpacing); - sizerPanel->Add(valgrinderDescr); - sizerPanel->Add(valgrinder, 0, wxEXPAND); - sizerPanel->AddSpacer(kInterSpacing); - sizerPanel->Add(autoPowerOn); - sizerPanel->AddSpacer(kInterSpacing); - - wxBoxSizer* horizIndent = new wxBoxSizer(wxHORIZONTAL); - horizIndent->AddSpacer(kEdgeSpacing); - horizIndent->Add(sizerPanel, wxSHAPED); - horizIndent->AddSpacer(kEdgeSpacing); - panel->SetSizer(horizIndent); - - return panel; -} - -/* - * Create the Runtime Preferences page. - */ -wxPanel* PrefsDialog::CreateRuntimePage(wxBookCtrlBase* parent) -{ - wxPanel* panel = new wxPanel(parent); - - wxStaticText* gammaStrDescr = new wxStaticText(panel, wxID_STATIC, - wxT("Gamma correction:")); - wxTextCtrl* gammaStr = new wxTextCtrl(panel, IDC_RPREFS_GAMMA); - - wxBoxSizer* gammaSizer = new wxBoxSizer(wxHORIZONTAL); - gammaSizer->Add(gammaStrDescr, 0, wxALIGN_CENTER_VERTICAL); - gammaSizer->AddSpacer(kInterSpacing); - gammaSizer->Add(gammaStr); - - wxBoxSizer* sizerPanel = new wxBoxSizer(wxVERTICAL); - sizerPanel->Add(kMinWidth, kEdgeSpacing); // forces minimum width - sizerPanel->Add(gammaSizer); - sizerPanel->AddSpacer(kInterSpacing); - - wxCheckBox* enableSound = new wxCheckBox(panel, IDC_RPREFS_ENABLE_SOUND, - wxT("Enable Sound")); - sizerPanel->AddSpacer(kInterSpacing); - sizerPanel->Add(enableSound); - - wxCheckBox* enableFakeCamera = new wxCheckBox(panel, IDC_RPREFS_ENABLE_FAKE_CAMERA, - wxT("Enable Fake Camera")); - sizerPanel->AddSpacer(kInterSpacing); - sizerPanel->Add(enableFakeCamera); - - wxBoxSizer* horizIndent = new wxBoxSizer(wxHORIZONTAL); - horizIndent->AddSpacer(kEdgeSpacing); - horizIndent->Add(sizerPanel, wxEXPAND); - horizIndent->AddSpacer(kEdgeSpacing); - panel->SetSizer(horizIndent); - - return panel; -} - diff --git a/simulator/app/PrefsDialog.h b/simulator/app/PrefsDialog.h deleted file mode 100644 index 250f79e15..000000000 --- a/simulator/app/PrefsDialog.h +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Prefs modal dialog. -// -#ifndef _SIM_PREFS_DIALOG_H -#define _SIM_PREFS_DIALOG_H - -/* - * Declaration of preferences dialog. This class defines the outer - * wrapper as well as all of the pages. - */ -class PrefsDialog : public wxDialog { - //DECLARE_CLASS(PrefsDialog) // shown in book, but causes link problems - DECLARE_EVENT_TABLE() - -public: - PrefsDialog(wxWindow* parent); - virtual ~PrefsDialog(); - - void CreateControls(void); - - wxString mConfigFile; - -private: - bool TransferDataToWindow(void); - bool TransferDataFromWindow(void); - bool TransferDataFromControls(void); - void LoadPreferences(void); - - wxPanel* CreateSimulatorPage(wxBookCtrlBase* parent); - wxPanel* CreateRuntimePage(wxBookCtrlBase* parent); - - /* main notebook; for aesthetic reasons we may want a Choicebook */ - wxNotebook mNotebook; - - /* Global simulator options */ - wxString mDebugger; - wxString mValgrinder; - bool mAutoPowerOn; - // log window size? - - /* Global runtime options */ - double mGammaCorrection; - bool mEnableSound; - bool mEnableFakeCamera; - int mLogLevel; - - enum { - kMinWidth = 300, // minimum prefs dialog width, in pixels - }; -}; - -#endif // _SIM_PREFS_DIALOG_H diff --git a/simulator/app/PropertyServer.cpp b/simulator/app/PropertyServer.cpp deleted file mode 100644 index 0d6054fdd..000000000 --- a/simulator/app/PropertyServer.cpp +++ /dev/null @@ -1,467 +0,0 @@ -// -// Copyright 2007 The Android Open Source Project -// -// Property sever. Mimics behavior provided on the device by init(8) and -// some code built into libc. -// - -// For compilers that support precompilation, include "wx/wx.h". -#include "wx/wxprec.h" - -// Otherwise, include all standard headers -#ifndef WX_PRECOMP -# include "wx/wx.h" -#endif -#include "wx/image.h" - -#include "PropertyServer.h" -#include "MyApp.h" -#include "Preferences.h" -#include "MainFrame.h" -#include "utils.h" - -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/un.h> - - -using namespace android; - -const char* PropertyServer::kPropCheckJni = "ro.kernel.android.checkjni"; - -/* - * Destructor. - */ -PropertyServer::~PropertyServer(void) -{ - if (IsRunning()) { - // TODO: cause thread to stop, then Wait for it - } - printf("Sim: in ~PropertyServer()\n"); -} - -/* - * Create and run the thread. - */ -bool PropertyServer::StartThread(void) -{ - if (Create() != wxTHREAD_NO_ERROR) { - fprintf(stderr, "Sim: ERROR: can't create PropertyServer thread\n"); - return false; - } - - Run(); - return true; -} - - -/* - * Clear out the list. - */ -void PropertyServer::ClearProperties(void) -{ - typedef List<Property>::iterator PropIter; - - for (PropIter pi = mPropList.begin(); pi != mPropList.end(); ++pi) { - pi = mPropList.erase(pi); - } -} - -/* - * Set default values for several properties. - */ -void PropertyServer::SetDefaultProperties(void) -{ - static const struct { - const char* key; - const char* value; - } propList[] = { - { "net.bt.name", "Android" }, - { "ro.kernel.mem", "60M" }, - { "ro.kernel.board_sardine.version", "4" }, - { "ro.kernel.console", "null" }, - { "ro.build.id", "engineering" }, - { "ro.build.date", "Wed Nov 28 07:44:14 PST 2007" }, - { "ro.build.date.utc", "1196264654" }, - { "ro.build.type", "eng" }, - { "ro.product.device", "simulator" /*"sooner"*/ }, - { "ro.product.brand", "generic" }, - { "ro.build.user", "fadden" }, - { "ro.build.host", "marathon" }, - { "ro.config.nocheckin", "yes" }, - { "ro.product.manufacturer", "" }, - { "ro.radio.use-ppp", "no" }, - { "ro.FOREGROUND_APP_ADJ", "0" }, - { "ro.VISIBLE_APP_ADJ", "1" }, - { "ro.SECONDARY_SERVER_ADJ", "2" }, - { "ro.HIDDEN_APP_MIN_ADJ", "7" }, - { "ro.CONTENT_PROVIDER_ADJ", "14" }, - { "ro.EMPTY_APP_ADJ", "15" }, - { "ro.FOREGROUND_APP_MEM", "1536" }, - { "ro.VISIBLE_APP_MEM", "2048" }, - { "ro.SECONDARY_SERVER_MEM", "4096" }, - { "ro.HIDDEN_APP_MEM", "8192" }, - { "ro.EMPTY_APP_MEM", "16384" }, - //{ "init.svc.adbd", "running" }, // causes ADB-JDWP - { "init.svc.usbd", "running" }, - { "init.svc.debuggerd", "running" }, - { "init.svc.ril-daemon", "running" }, - { "init.svc.zygote", "running" }, - { "init.svc.runtime", "running" }, - { "init.svc.dbus", "running" }, - { "init.svc.pppd_gprs", "running" }, - { "adb.connected", "0" }, - //{ "use-adb-networking", "1" }, - /* - { "status.battery.state", "Slow" }, - { "status.battery.level", "5" }, - { "status.battery.level_raw", "50" }, - { "status.battery.level_scale", "9" }, - */ - - /* disable the annoying setup wizard */ - { "app.setupwizard.disable", "1" }, - - /* Dalvik options, set by AndroidRuntime */ - { "dalvik.vm.stack-trace-file", "/data/anr/traces.txt" }, - //{ "dalvik.vm.execution-mode", "int:portable" }, - { "dalvik.vm.enableassertions", "all" }, // -ea - { "dalvik.vm.dexopt-flags", "" }, // e.g. "v=a,o=v,m=n" - { "dalvik.vm.deadlock-predict", "off" }, // -Xdeadlockpredict - //{ "dalvik.vm.jniopts", "forcecopy" }, // -Xjniopts - { "log.redirect-stdio", "false" }, // -Xlog-stdio - - /* SurfaceFlinger options */ - { "debug.sf.nobootanimation", "1" }, - { "debug.sf.showupdates", "0" }, - { "debug.sf.showcpu", "0" }, - { "debug.sf.showbackground", "0" }, - { "debug.sf.showfps", "0" }, - }; - - for (int i = 0; i < NELEM(propList); i++) - SetProperty(propList[i].key, propList[i].value); - - Preferences* pPrefs = ((MyApp*)wxTheApp)->GetPrefs(); - bool doCheckJni = false; - - pPrefs->GetBool("check-jni", &doCheckJni); - if (doCheckJni) - SetProperty(kPropCheckJni, "1"); - else - SetProperty(kPropCheckJni, "0"); -} - -/* - * Get the value of a property. - * - * "valueBuf" must hold at least PROPERTY_VALUE_MAX bytes. - * - * Returns "true" if the property was found. - */ -bool PropertyServer::GetProperty(const char* key, char* valueBuf) -{ - typedef List<Property>::iterator PropIter; - - assert(key != NULL); - assert(valueBuf != NULL); - - for (PropIter pi = mPropList.begin(); pi != mPropList.end(); ++pi) { - Property& prop = *pi; - if (strcmp(prop.key, key) == 0) { - if (strlen(prop.value) >= PROPERTY_VALUE_MAX) { - fprintf(stderr, - "GLITCH: properties table holds '%s' '%s' (len=%d)\n", - prop.key, prop.value, strlen(prop.value)); - abort(); - } - assert(strlen(prop.value) < PROPERTY_VALUE_MAX); - strcpy(valueBuf, prop.value); - return true; - } - } - - //printf("Prop: get [%s] not found\n", key); - return false; -} - -/* - * Set the value of a property, replacing it if it already exists. - * - * If "value" is NULL, the property is removed. - * - * If the property is immutable, this returns "false" without doing - * anything. (Not implemented.) - */ -bool PropertyServer::SetProperty(const char* key, const char* value) -{ - typedef List<Property>::iterator PropIter; - - assert(key != NULL); - assert(value != NULL); - - for (PropIter pi = mPropList.begin(); pi != mPropList.end(); ++pi) { - Property& prop = *pi; - if (strcmp(prop.key, key) == 0) { - if (value != NULL) { - //printf("Prop: replacing [%s]: [%s] with [%s]\n", - // prop.key, prop.value, value); - strcpy(prop.value, value); - } else { - //printf("Prop: removing [%s]\n", prop.key); - mPropList.erase(pi); - } - return true; - } - } - - //printf("Prop: adding [%s]: [%s]\n", key, value); - Property tmp; - strcpy(tmp.key, key); - strcpy(tmp.value, value); - mPropList.push_back(tmp); - return true; -} - -/* - * Create a UNIX domain socket, carefully removing it if it already - * exists. - */ -bool PropertyServer::CreateSocket(const char* fileName) -{ - struct stat sb; - bool result = false; - int sock = -1; - int cc; - - cc = stat(fileName, &sb); - if (cc < 0) { - if (errno != ENOENT) { - LOG(LOG_ERROR, "sim-prop", - "Unable to stat '%s' (errno=%d)\n", fileName, errno); - goto bail; - } - } else { - /* don't touch it if it's not a socket */ - if (!(S_ISSOCK(sb.st_mode))) { - LOG(LOG_ERROR, "sim-prop", - "File '%s' exists and is not a socket\n", fileName); - goto bail; - } - - /* remove the cruft */ - if (unlink(fileName) < 0) { - LOG(LOG_ERROR, "sim-prop", - "Unable to remove '%s' (errno=%d)\n", fileName, errno); - goto bail; - } - } - - struct sockaddr_un addr; - - sock = ::socket(AF_UNIX, SOCK_STREAM, 0); - if (sock < 0) { - LOG(LOG_ERROR, "sim-prop", - "UNIX domain socket create failed (errno=%d)\n", errno); - goto bail; - } - - /* bind the socket; this creates the file on disk */ - strcpy(addr.sun_path, fileName); // max 108 bytes - addr.sun_family = AF_UNIX; - cc = ::bind(sock, (struct sockaddr*) &addr, SUN_LEN(&addr)); - if (cc < 0) { - LOG(LOG_ERROR, "sim", - "AF_UNIX bind failed for '%s' (errno=%d)\n", fileName, errno); - goto bail; - } - - cc = ::listen(sock, 5); - if (cc < 0) { - LOG(LOG_ERROR, "sim", "AF_UNIX listen failed (errno=%d)\n", errno); - goto bail; - } - - mListenSock = sock; - sock = -1; - result = true; - -bail: - if (sock >= 0) - close(sock); - return result; -} - -/* - * Handle a client request. - * - * Returns true on success, false if the fd should be closed. - */ -bool PropertyServer::HandleRequest(int fd) -{ - char reqBuf[PROPERTY_KEY_MAX + PROPERTY_VALUE_MAX]; - char valueBuf[1 + PROPERTY_VALUE_MAX]; - ssize_t actual; - - memset(valueBuf, 'x', sizeof(valueBuf)); // placate valgrind - - /* read the command byte; this determines the message length */ - actual = read(fd, reqBuf, 1); - if (actual <= 0) - return false; - - if (reqBuf[0] == kSystemPropertyGet) { - actual = read(fd, reqBuf, PROPERTY_KEY_MAX); - - if (actual != PROPERTY_KEY_MAX) { - fprintf(stderr, "Bad read on get: %d of %d\n", - actual, PROPERTY_KEY_MAX); - return false; - } - if (GetProperty(reqBuf, valueBuf+1)) - valueBuf[0] = 1; - else - valueBuf[0] = 0; - //printf("GET property [%s]: (found=%d) [%s]\n", - // reqBuf, valueBuf[0], valueBuf+1); - if (write(fd, valueBuf, sizeof(valueBuf)) != sizeof(valueBuf)) { - fprintf(stderr, "Bad write on get\n"); - return false; - } - } else if (reqBuf[0] == kSystemPropertySet) { - actual = read(fd, reqBuf, PROPERTY_KEY_MAX + PROPERTY_VALUE_MAX); - if (actual != PROPERTY_KEY_MAX + PROPERTY_VALUE_MAX) { - fprintf(stderr, "Bad read on set: %d of %d\n", - actual, PROPERTY_KEY_MAX + PROPERTY_VALUE_MAX); - return false; - } - //printf("SET property '%s'\n", reqBuf); - if (SetProperty(reqBuf, reqBuf + PROPERTY_KEY_MAX)) - valueBuf[0] = 1; - else - valueBuf[0] = 0; - if (write(fd, valueBuf, 1) != 1) { - fprintf(stderr, "Bad write on set\n"); - return false; - } - } else if (reqBuf[0] == kSystemPropertyList) { - /* TODO */ - assert(false); - } else { - fprintf(stderr, "Unexpected request %d from prop client\n", reqBuf[0]); - return false; - } - - return true; -} - -/* - * Serve up properties. - */ -void PropertyServer::ServeProperties(void) -{ - typedef List<int>::iterator IntIter; - fd_set readfds; - int maxfd; - - while (true) { - int cc; - - FD_ZERO(&readfds); - FD_SET(mListenSock, &readfds); - maxfd = mListenSock; - - for (IntIter ii = mClientList.begin(); ii != mClientList.end(); ++ii) { - int fd = (*ii); - - FD_SET(fd, &readfds); - if (maxfd < fd) - maxfd = fd; - } - - cc = select(maxfd+1, &readfds, NULL, NULL, NULL); - if (cc < 0) { - if (errno == EINTR) { - printf("hiccup!\n"); - continue; - } - return; - } - if (FD_ISSET(mListenSock, &readfds)) { - struct sockaddr_un from; - socklen_t fromlen; - int newSock; - - fromlen = sizeof(from); - newSock = ::accept(mListenSock, (struct sockaddr*) &from, &fromlen); - if (newSock < 0) { - LOG(LOG_WARN, "sim", - "AF_UNIX accept failed (errno=%d)\n", errno); - } else { - //printf("new props connection on %d --> %d\n", - // mListenSock, newSock); - - mClientList.push_back(newSock); - } - } - - for (IntIter ii = mClientList.begin(); ii != mClientList.end(); ) { - int fd = (*ii); - bool ok = true; - - if (FD_ISSET(fd, &readfds)) { - //printf("--- activity on %d\n", fd); - - ok = HandleRequest(fd); - } - - if (ok) { - ++ii; - } else { - //printf("--- closing %d\n", fd); - close(fd); - ii = mClientList.erase(ii); - } - } - } -} - -/* - * Thread entry point. - * - * This just sits and waits for a new connection. It hands it off to the - * main thread and then goes back to waiting. - * - * There is currently no "polite" way to shut this down. - */ -void* PropertyServer::Entry(void) -{ - if (CreateSocket(SYSTEM_PROPERTY_PIPE_NAME)) { - assert(mListenSock >= 0); - SetDefaultProperties(); - - /* loop until it's time to exit or we fail */ - ServeProperties(); - - ClearProperties(); - - /* - * Close listen socket and all clients. - */ - LOG(LOG_INFO, "sim", "Cleaning up socket list\n"); - typedef List<int>::iterator IntIter; - for (IntIter ii = mClientList.begin(); ii != mClientList.end(); ++ii) - close((*ii)); - close(mListenSock); - } - - LOG(LOG_INFO, "sim", "PropertyServer thread exiting\n"); - return NULL; -} - diff --git a/simulator/app/PropertyServer.h b/simulator/app/PropertyServer.h deleted file mode 100644 index 193dd7047..000000000 --- a/simulator/app/PropertyServer.h +++ /dev/null @@ -1,68 +0,0 @@ -// -// Copyright 2007 The Android Open Source Project -// -// Serve properties to the simulated runtime. -// -#ifndef _SIM_PROPERTY_SERVER_H -#define _SIM_PROPERTY_SERVER_H - -#include "cutils/properties.h" -#include "utils/List.h" - -/* - * Define a thread that responds to requests from clients to get/set/list - * system properties. - */ -class PropertyServer : public wxThread { -public: - PropertyServer(void) : mListenSock(-1) {} - virtual ~PropertyServer(void); - - /* start the thread running */ - bool StartThread(void); - - /* thread entry point */ - virtual void* Entry(void); - - /* clear out all properties */ - void ClearProperties(void); - - /* add some default values */ - void SetDefaultProperties(void); - - /* copy a property into valueBuf; returns false if property not found */ - bool GetProperty(const char* key, char* valueBuf); - - /* set the property, replacing it if it already exists */ - bool SetProperty(const char* key, const char* value); - - /* property name constants */ - static const char* kPropCheckJni; - -private: - /* one property entry */ - typedef struct Property { - char key[PROPERTY_KEY_MAX]; - char value[PROPERTY_VALUE_MAX]; - } Property; - - /* create the UNIX-domain socket we listen on */ - bool CreateSocket(const char* fileName); - - /* serve up properties */ - void ServeProperties(void); - - /* handle a client request */ - bool HandleRequest(int fd); - - /* listen here for new connections */ - int mListenSock; - - /* list of connected fds to scan */ - android::List<int> mClientList; - - /* set of known properties */ - android::List<Property> mPropList; -}; - -#endif // PROPERTY_SERVER_H diff --git a/simulator/app/README b/simulator/app/README deleted file mode 100644 index 5a51f6322..000000000 --- a/simulator/app/README +++ /dev/null @@ -1,74 +0,0 @@ -Android Simulator README -Last updated: 14-Nov-2007 - -See "docs/sim-layout-xml.txt" for a description of the layout.xml files -in the device directories. - -The coding conventions here are generally aligned with wxWidgets' style, -which is similar to standard Windows style. The only significant shift -from Android style is that function names are capitalized. Note the -simulator code is not part of the "android" namespace. - - -===== Arguments ===== - -The config file for the simulator, ".android.cf", can live in your -$HOME directory or in $cwd. The copy in $cwd takes priority. If a -config file does not exist, one will be created in your home directory. -(Note that the current directory is set by "runsim.sh", so if you launch -the simulator from the script it will look for the config file in your -"install" directory.) - -The simulator takes the following optional arguments: - - -f <file> : specify the configuration file to use. - - -p <platform> : specify platform information. This is usually - something like "Linux-release" or "CYGWIN_NT-5.1-debug". - - -r : reset paths. This causes the simulator to regenerate the paths - based on defaults. This is useful when copying your .android.cf from - a different system, because it updates all the local paths without - disturbing the other options. - - -===== Preferences Quick Reference ===== - -Path preferences. These are reset by the "-r" flag: - -"debugger" (str) Path to the debugger (usually /usr/bin/gdb). -"valgrinder" (str) Path to valgrind (usually /usr/bin/valgrind). - -Common prefs: - -"auto-power-on" (bool) Automatically start runtime on simulator start. -"debug" (bool) Launch the runtime inside <debugger>. -"valgrind" (bool) Launch the runtime inside <valgrinder>. -"log-*" (various) Preferences for the log window. -"window-*" (int) Positions and sizes of windows. -"default-device" (str) Name of the device that opens initially. -"ld-assume-kernel" (str) Hack to make goobuntu GDB work; use "" to disable. - -Less-common prefs: - -"gamma" (float) Gamma correction factor (default 1.0). -"window-device-x" (int) Position of device window. -"window-device-y" (int) Position of device window. -"trap-sigint" (bool) Catch Ctrl-C. Kill the runtime when we do. -"refocus-on-restart" (bool) When runtime rstarts, give focus to phone window. -"launch-command" (str) Command to run, e.g. "xterm -e" (cmd is appended). -"launch-wrapper-args" (str) Args to launch wrapper, e.g. "-wait -output foo". - - -(If you prefer gnome-terminal to xterm, you can use something like -"gnome-terminal --disable-factory -x". The "disable-factory" arg is -needed to ensure that it inherits the environment variables.) - - -***** NOTE ***** - -If you're using a non-goobuntu system, make sure "ld-assume-kernel" is "" -in your .android.cf. gdb works correctly on Ubuntu 7.04 (fiesty) and 7.10 -(gutsy), and the goobuntu workaround will cause shared library version -failures on startup. - diff --git a/simulator/app/Resource.h b/simulator/app/Resource.h deleted file mode 100644 index 160242820..000000000 --- a/simulator/app/Resource.h +++ /dev/null @@ -1,98 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Resource enumeration. -// -#ifndef _SIM_RESOURCE_H -#define _SIM_RESOURCE_H - -/* - * IDs for dialogs, controls, menu items, and whatever else comes along. - * - * Some standard defs are in "wx/defs.h". They run from 5000 to 6000. - */ -enum { - // common stuff - //ID_ANONYMOUS = -1, // use wxID_ANY(-1) or wxID_STATIC(5105) - - - // Menu item IDs - IDM_FILE_PREFERENCES = 100, - IDM_FILE_EXIT, - - IDM_RUNTIME_START, - IDM_RUNTIME_STOP, - IDM_RUNTIME_RESTART, - IDM_RUNTIME_KILL, - - IDM_DEVICE, - IDM_DEVICE_SEL0, - // leave space; each phone model gets a menu item ID - IDM_DEVICE_SELN = IDM_DEVICE_SEL0 + 32, - IDM_DEVICE_RESCAN, - - IDM_DEBUG_SHOW_LOG, - - IDM_HELP_CONTENTS, - IDM_HELP_ABOUT, - - - // Dialog IDs - IDD_PREFS, - IDD_LOG_PREFS, - - // Control IDs - IDC_MODE_SELECT, // main - combobox - IDC_USE_GDB, // main - checkbox - IDC_USE_VALGRIND, // main - checkbox - IDC_CHECK_JNI, // main - checkbox - IDC_JAVA_APP_NAME, // main - combobox - IDC_JAVA_VM, // main - combobox - IDC_OVERLAY_ONION_SKIN, // main - combobox - IDC_ONION_SKIN_FILE_NAME, // main - textctrl - IDC_ONION_SKIN_BUTTON, // main - button - IDC_ONION_SKIN_ALPHA_VAL, // main - slider - - IDC_SPREFS_CONFIG_NAME, // sim prefs page - textctrl - IDC_SPREFS_DEBUGGER, // sim prefs page - textctrl - IDC_SPREFS_VALGRINDER, // sim prefs page - textctrl - IDC_SPREFS_AUTO_POWER_ON, // sim prefs page - checkbox - - IDC_RPREFS_GAMMA, // runtime prefs page - textctrl - IDC_RPREFS_ENABLE_SOUND, // runtime prefs page - checkbox - IDC_RPREFS_ENABLE_FAKE_CAMERA,// runtime prefs page - checkbox - - IDC_LOG_TEXT, // log window - textctrl - IDC_LOG_LEVEL, // log window - combobox - IDC_LOG_CLEAR, // log window - button - IDC_LOG_PAUSE, // log window - button - IDC_LOG_PREFS, // log window - button - - IDC_LOG_PREFS_FMT_FULL, // log prefs - radio button - IDC_LOG_PREFS_FMT_BRIEF, // log prefs - radio button - IDC_LOG_PREFS_FMT_MINIMAL, // log prefs - radio button - IDC_LOG_PREFS_SINGLE_LINE, // log prefs - checkbox - IDC_LOG_PREFS_EXTRA_SPACING, // log prefs - combobox - IDC_LOG_PREFS_POINT_SIZE, // log prefs - textctrl - IDC_LOG_PREFS_USE_COLOR, // log prefs - checkbox - IDC_LOG_PREFS_FONT_MONO, // log prefs - checkbox - - IDC_LOG_PREFS_DISPLAY_MAX, // log prefs - textctrl - IDC_LOG_PREFS_POOL_SIZE, // log prefs - textctrl - - IDC_LOG_PREFS_WRITE_FILE, // log prefs - checkbox - IDC_LOG_PREFS_FILENAME, // log prefs - textctrl - IDC_LOG_PREFS_TRUNCATE_OLD, // log prefs - textctrl -}; - -/* - * Common definitions for control spacing. - * - * Doesn't really belong here, but it'll do. - */ -enum { - kEdgeSpacing = 4, // padding at edge of prefs pages, in pixels - kInterSpacing = 5, // padding between controls, in pixels -}; - -#endif // _SIM_RESOURCE_H diff --git a/simulator/app/Semaphore.cpp b/simulator/app/Semaphore.cpp deleted file mode 100644 index 3b6ee7b1d..000000000 --- a/simulator/app/Semaphore.cpp +++ /dev/null @@ -1,516 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Inter-process semaphores. -// -#include "Semaphore.h" - -#if defined(HAVE_MACOSX_IPC) -# include <semaphore.h> -#elif defined(HAVE_SYSV_IPC) -# include <sys/types.h> -# include <sys/ipc.h> -# include <sys/sem.h> -#elif defined(HAVE_WIN32_IPC) -# include <windows.h> -#elif defined(HAVE_ANDROID_IPC) -// not yet -#else -# error "unknown sem config" -#endif - -#include <utils/Log.h> - -#include <errno.h> -#include <assert.h> - -using namespace android; - - -#if defined(HAVE_ANDROID_IPC) // ---------------------------------------------- - -Semaphore::Semaphore(void) - : mHandle(0), mCreator(false), mKey(-1) -{} - -Semaphore::~Semaphore(void) -{} - -bool Semaphore::create(int key, int initialValue, bool deleteExisting) -{ - return false; -} - -bool Semaphore::attach(int key) -{ - return false; -} - -void Semaphore::acquire(void) -{} - -void Semaphore::release(void) -{} - -bool Semaphore::tryAcquire(void) -{ - return false; -} - -#elif defined(HAVE_MACOSX_IPC) // --------------------------------------------- - -/* - * The SysV semaphores don't work on all of our machines. The POSIX - * named semaphores seem to work better. - */ - -#define kInvalidHandle SEM_FAILED - -static const char* kSemStr = "/tmp/android-sem-"; - -/* - * Constructor. Just init fields. - */ -Semaphore::Semaphore(void) - : mHandle((unsigned long) kInvalidHandle), mCreator(false), mKey(-1) -{ -} - -/* - * Destructor. If we created the semaphore, destroy it. - */ -Semaphore::~Semaphore(void) -{ - LOG(LOG_VERBOSE, "sem", "~Semaphore(handle=%ld creator=%d)\n", - mHandle, mCreator); - - if (mHandle != (unsigned long) kInvalidHandle) { - sem_close((sem_t*) mHandle); - - if (mCreator) { - char nameBuf[64]; - int cc; - - snprintf(nameBuf, sizeof(nameBuf), "%s%d", kSemStr, mKey); - - cc = sem_unlink(nameBuf); - if (cc != 0) { - LOG(LOG_ERROR, "sem", - "Failed to remove sem '%s' (errno=%d)\n", nameBuf, errno); - } - } - } -} - -/* - * Create the semaphore. - */ -bool Semaphore::create(int key, int initialValue, bool deleteExisting) -{ - int cc; - char nameBuf[64]; - - snprintf(nameBuf, sizeof(nameBuf), "%s%d", kSemStr, key); - - if (deleteExisting) { - cc = sem_unlink(nameBuf); - if (cc != 0 && errno != ENOENT) { - LOG(LOG_WARN, "sem", "Warning: failed to remove sem '%s'\n", - nameBuf); - /* keep going? */ - } - } - - /* create and set initial value */ - sem_t* semPtr; - semPtr = sem_open(nameBuf, O_CREAT | O_EXCL, 0666, 1); - if (semPtr == (sem_t*)SEM_FAILED) { - LOG(LOG_ERROR, "sem", - "ERROR: sem_open failed to create '%s' (errno=%d)\n", - nameBuf, errno); - return false; - } - - mHandle = (unsigned long) semPtr; - mCreator = true; - mKey = key; - - return true; -} - -/* - * Attach to an existing semaphore. - */ -bool Semaphore::attach(int key) -{ - char nameBuf[64]; - - snprintf(nameBuf, sizeof(nameBuf), "%s%d", kSemStr, key); - - sem_t* semPtr; - semPtr = sem_open(nameBuf, 0, 0666, 0); - if (semPtr == (sem_t*) SEM_FAILED) { - LOG(LOG_ERROR, "sem", - "ERROR: sem_open failed to attach to '%s' (errno=%d)\n", - nameBuf, errno); - return false; - } - - mHandle = (unsigned long) semPtr; - assert(mCreator == false); - mKey = key; - - return true; -} - -/* - * Acquire or release the semaphore. - */ -void Semaphore::acquire(void) -{ - int cc = sem_wait((sem_t*) mHandle); - if (cc != 0) - LOG(LOG_WARN, "sem", "acquire failed (errno=%d)\n", errno); -} -void Semaphore::release(void) -{ - int cc = sem_post((sem_t*) mHandle); - if (cc != 0) - LOG(LOG_WARN, "sem", "release failed (errno=%d)\n", errno); -} -bool Semaphore::tryAcquire(void) -{ - int cc = sem_trywait((sem_t*) mHandle); - if (cc != 0) { - if (errno != EAGAIN) - LOG(LOG_WARN, "sem", "tryAcquire failed (errno=%d)\n", errno); - return false; - } - return true; -} - - -#elif defined(HAVE_SYSV_IPC) // ----------------------------------------------- - -/* - * Basic SysV semaphore stuff. - */ - -#define kInvalidHandle ((unsigned long)-1) - -#if defined(_SEM_SEMUN_UNDEFINED) -/* according to X/OPEN we have to define it ourselves */ -union semun { - int val; /* value for SETVAL */ - struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ - unsigned short *array; /* array for GETALL, SETALL */ - /* Linux specific part: */ - struct seminfo *__buf; /* buffer for IPC_INFO */ -}; -#endif - -/* - * Constructor. Just init fields. - */ -Semaphore::Semaphore(void) - : mHandle(kInvalidHandle), mCreator(false) -{ -} - -/* - * Destructor. If we created the semaphore, destroy it. - */ -Semaphore::~Semaphore(void) -{ - LOG(LOG_VERBOSE, "sem", "~Semaphore(handle=%ld creator=%d)\n", - mHandle, mCreator); - - if (mCreator && mHandle != kInvalidHandle) { - int cc; - - cc = semctl((int) mHandle, 0, IPC_RMID); - if (cc != 0) { - LOG(LOG_WARN, "sem", - "Destructor failed to destroy key=%ld\n", mHandle); - } - } -} - -/* - * Create the semaphore. - */ -bool Semaphore::create(int key, int initialValue, bool deleteExisting) -{ - int semid, cc; - - if (deleteExisting) { - semid = semget(key, 1, 0); - if (semid != -1) { - LOG(LOG_DEBUG, "sem", "Key %d exists (semid=%d), removing\n", - key, semid); - cc = semctl(semid, 0, IPC_RMID); - if (cc != 0) { - LOG(LOG_ERROR, "sem", "Failed to remove key=%d semid=%d\n", - key, semid); - return false; - } else { - LOG(LOG_DEBUG, "sem", - "Removed previous semaphore with key=%d\n", key); - } - } - } - - semid = semget(key, 1, 0600 | IPC_CREAT | IPC_EXCL); - if (semid == -1) { - LOG(LOG_ERROR, "sem", "Failed to create key=%d (errno=%d)\n", - key, errno); - return false; - } - - mHandle = semid; - mCreator = true; - mKey = key; - - /* - * Set initial value. - */ - union semun init; - init.val = initialValue; - cc = semctl(semid, 0, SETVAL, init); - if (cc == -1) { - LOG(LOG_ERROR, "sem", - "Unable to initialize semaphore, key=%d iv=%d (errno=%d)\n", - key, initialValue, errno); - return false; - } - - return true; -} - -/* - * Attach to an existing semaphore. - */ -bool Semaphore::attach(int key) -{ - int semid; - - semid = semget(key, 0, 0); - if (semid == -1) { - LOG(LOG_ERROR, "sem", "Failed to find key=%d\n", key); - return false; - } - - mHandle = semid; - assert(mCreator == false); - mKey = key; - - return true; -} - -/* - * Acquire or release the semaphore. - */ -void Semaphore::acquire(void) -{ - assert(mHandle != kInvalidHandle); - adjust(-1, true); -} -void Semaphore::release(void) -{ - assert(mHandle != kInvalidHandle); - adjust(1, true); -} -bool Semaphore::tryAcquire(void) -{ - assert(mHandle != kInvalidHandle); - return adjust(-1, false); -} - -/* - * Do the actual semaphore manipulation. - * - * The semaphore's value indicates the number of free resources. Pass - * in a negative value for "adj" to acquire resources, or a positive - * value to free resources. - * - * Returns true on success, false on failure. - */ -bool Semaphore::adjust(int adj, bool wait) -{ - struct sembuf op; - int cc; - - op.sem_num = 0; - op.sem_op = adj; - op.sem_flg = SEM_UNDO; - if (!wait) - op.sem_flg |= IPC_NOWAIT; - - cc = semop((int) mHandle, &op, 1); - if (cc != 0) { - if (wait || errno != EAGAIN) { - LOG(LOG_WARN, "sem", - "semaphore adjust by %d failed for semid=%ld (errno=%d)\n", - adj, mHandle, errno); - } - return false; - } - - //LOG(LOG_VERBOSE, "sem", - // "adjusted semaphore by %d (semid=%ld)\n", adj, mHandle); - - return true; -} - - -#elif defined(HAVE_WIN32_IPC) // ---------------------------------------------- - -/* - * Win32 semaphore implementation. - * - * Pretty straightforward. - */ - -static const char* kSemStr = "android-sem-"; - -/* - * Constructor. Just init fields. - */ -Semaphore::Semaphore(void) - : mHandle((unsigned long) INVALID_HANDLE_VALUE), mCreator(false) -{ -} - -/* - * Destructor. Just close the semaphore handle. - */ -Semaphore::~Semaphore(void) -{ - LOG(LOG_DEBUG, "sem", "~Semaphore(handle=%ld creator=%d)\n", - mHandle, mCreator); - - if (mHandle != (unsigned long) INVALID_HANDLE_VALUE) - CloseHandle((HANDLE) mHandle); -} - -/* - * Create the semaphore. - */ -bool Semaphore::create(int key, int initialValue, bool deleteExisting) -{ - char keyBuf[64]; - HANDLE hSem; - long max; - - snprintf(keyBuf, sizeof(keyBuf), "%s%d", kSemStr, key); - - if (initialValue == 0) - max = 1; - else - max = initialValue; - - hSem = CreateSemaphore( - NULL, // security attributes - initialValue, // initial count - max, // max count, must be >= initial - keyBuf); // object name - if (hSem == NULL) { - DWORD err = GetLastError(); - if (err == ERROR_ALREADY_EXISTS) { - LOG(LOG_ERROR, "sem", "Semaphore '%s' already exists\n", keyBuf); - } else { - LOG(LOG_ERROR, "sem", "CreateSemaphore(%s) failed (err=%ld)\n", - keyBuf, err); - } - return false; - } - - mHandle = (unsigned long) hSem; - mCreator = true; - mKey = key; - - //LOG(LOG_DEBUG, "sem", "Semaphore '%s' created (handle=0x%08lx)\n", - // keyBuf, mHandle); - - return true; -} - -/* - * Attach to an existing semaphore. - */ -bool Semaphore::attach(int key) -{ - char keyBuf[64]; - HANDLE hSem; - - snprintf(keyBuf, sizeof(keyBuf), "%s%d", kSemStr, key); - - hSem = OpenSemaphore( - //SEMAPHORE_MODIFY_STATE, // mostly-full access - SEMAPHORE_ALL_ACCESS, // full access - FALSE, // don't let kids inherit handle - keyBuf); // object name - if (hSem == NULL) { - LOG(LOG_ERROR, "sem", "OpenSemaphore(%s) failed (err=%ld)\n", - keyBuf, GetLastError()); - return false; - } - - mHandle = (unsigned long) hSem; - assert(mCreator == false); - mKey = key; - - return true; -} - -/* - * Acquire or release the semaphore. - */ -void Semaphore::acquire(void) -{ - DWORD result; - - assert(mHandle != (unsigned long) INVALID_HANDLE_VALUE); - - result = WaitForSingleObject((HANDLE) mHandle, INFINITE); - if (result != WAIT_OBJECT_0) { - LOG(LOG_WARN, "sem", - "WaitForSingleObject(INF) on semaphore returned %ld (err=%ld)\n", - result, GetLastError()); - } -} -void Semaphore::release(void) -{ - DWORD result; - - assert(mHandle != (unsigned long) INVALID_HANDLE_VALUE); - - result = ReleaseSemaphore((HANDLE) mHandle, 1, NULL); // incr by 1 - if (result == 0) { - LOG(LOG_WARN, "sem", "ReleaseSemaphore failed (err=%ld)\n", - GetLastError()); - } -} -bool Semaphore::tryAcquire(void) -{ - DWORD result; - - assert(mHandle != (unsigned long) INVALID_HANDLE_VALUE); - result = WaitForSingleObject((HANDLE) mHandle, 0); - if (result == WAIT_OBJECT_0) - return true; // grabbed it - else if (result == WAIT_TIMEOUT) - return false; // not available - else if (result == WAIT_FAILED) { - LOG(LOG_WARN, "sem", "WaitForSingleObject(0) on sem failed (err=%ld)\n", - GetLastError()); - return false; - } else { - LOG(LOG_WARN, "sem", - "WaitForSingleObject(0) on sem returned %ld (err=%ld)\n", - result, GetLastError()); - return false; - } -} - -#endif // --------------------------------------------------------------------- diff --git a/simulator/app/Semaphore.h b/simulator/app/Semaphore.h deleted file mode 100644 index 3b834f3d0..000000000 --- a/simulator/app/Semaphore.h +++ /dev/null @@ -1,59 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Inter-process semaphore. -// -// These are meant for IPC, not thread management. The Mutex and Condition -// classes are much lighter weight. -// -#ifndef __LIBS_SEMAPHORE_H -#define __LIBS_SEMAPHORE_H - -#ifdef HAVE_ANDROID_OS -#error DO NOT USE THIS FILE IN THE DEVICE BUILD -#endif - -namespace android { - -/* - * Platform-independent semaphore class. - * - * Each object holds a single semaphore. - * - * The "key" is usually the process ID of the process that created the - * semaphore (following POSIX semantics). See the comments in shmem.h. - */ -class Semaphore { -public: - Semaphore(void); - virtual ~Semaphore(void); - - /* - * Create a new semaphore, with the specified initial value. The - * value indicates the number of resources available. - */ - bool create(int key, int initialValue, bool deleteExisting); - - /* - * Attach to an existing semaphore. - */ - bool attach(int key); - - /* - * Acquire or release the semaphore. - */ - void acquire(void); - void release(void); - bool tryAcquire(void); // take a timeout? - -private: - bool adjust(int adj, bool wait); - - unsigned long mHandle; // semid(int) or HANDLE - bool mCreator; - int mKey; -}; - -}; // namespace android - -#endif // __LIBS_SEMAPHORE_H diff --git a/simulator/app/Shmem.cpp b/simulator/app/Shmem.cpp deleted file mode 100644 index 4c619c240..000000000 --- a/simulator/app/Shmem.cpp +++ /dev/null @@ -1,558 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Shared memory interface. -// -#include "Shmem.h" -#include "utils/Log.h" - -#if defined(HAVE_MACOSX_IPC) || defined(HAVE_ANDROID_IPC) -# include <sys/mman.h> -# include <fcntl.h> -# include <unistd.h> -#elif defined(HAVE_SYSV_IPC) -# include <sys/types.h> -# include <sys/ipc.h> -# include <sys/shm.h> -#elif defined(HAVE_WIN32_IPC) -# include <windows.h> -#else -# error "unknown shm config" -#endif - -#include <errno.h> -#include <assert.h> - -using namespace android; - - -#if defined(HAVE_MACOSX_IPC) || defined(HAVE_ANDROID_IPC) - -/* - * SysV IPC under Mac OS X seems to have problems. It works fine on - * some machines but totally fails on others. We're working around it - * here by using mmap(). - */ - -#define kInvalidHandle ((unsigned long)-1) - -static const char* kShmemFile = "/tmp/android-"; - -/* - * Constructor. Just set up the fields. - */ -Shmem::Shmem(void) - : mHandle(kInvalidHandle), mAddr(MAP_FAILED), mLength(-1), mCreator(false), - mKey(-1) -{ -} - -/* - * Destructor. Detach and, if we created it, mark the segment for - * destruction. - */ -Shmem::~Shmem(void) -{ - if (mAddr != MAP_FAILED) - munmap(mAddr, mLength); - if ((long)mHandle >= 0) { - close(mHandle); - - if (mCreator) { - char nameBuf[64]; - int cc; - - snprintf(nameBuf, sizeof(nameBuf), "%s%d", kShmemFile, mKey); - cc = unlink(nameBuf); - if (cc != 0) { - LOG(LOG_WARN, "shmem", "Couldn't clean up '%s'\n", nameBuf); - /* oh well */ - } - } - } -} - -/* - * Create the segment and attach ourselves to it. - */ -bool Shmem::create(int key, long size, bool deleteExisting) -{ - char nameBuf[64]; - int fd, cc; - - snprintf(nameBuf, sizeof(nameBuf), "%s%d", kShmemFile, key); - - if (deleteExisting) { - cc = unlink(nameBuf); - if (cc != 0 && errno != ENOENT) { - LOG(LOG_ERROR, "shmem", "Failed to remove old map file '%s'\n", - nameBuf); - return false; - } - } - - fd = open(nameBuf, O_CREAT|O_EXCL|O_RDWR, 0600); - if (fd < 0) { - LOG(LOG_ERROR, "shmem", "Unable to create map file '%s' (errno=%d)\n", - nameBuf, errno); - return false; - } - - /* - * Set the file size by seeking and writing. - */ - if (ftruncate(fd, size) == -1) { - LOG(LOG_ERROR, "shmem", "Unable to set file size in '%s' (errno=%d)\n", - nameBuf, errno); - close(fd); - return false; - } - - mAddr = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); - if (mAddr == MAP_FAILED) { - LOG(LOG_ERROR, "shmem", "mmap failed (errno=%d)\n", errno); - close(fd); - return false; - } - - mHandle = fd; - mLength = size; - mCreator = true; - mKey = key; - - /* done with shmem, create the associated semaphore */ - if (!mSem.create(key, 1, true)) { - LOG(LOG_ERROR, "shmem", - "Failed creating semaphore for Shmem (key=%d)\n", key); - return false; - } - - return true; -} - -/* - * Attach ourselves to an existing segment. - */ -bool Shmem::attach(int key) -{ - char nameBuf[64]; - int fd; - - snprintf(nameBuf, sizeof(nameBuf), "%s%d", kShmemFile, key); - fd = open(nameBuf, O_RDWR, 0600); - if (fd < 0) { - LOG(LOG_ERROR, "shmem", "Unable to open map file '%s' (errno=%d)\n", - nameBuf, errno); - return false; - } - - off_t len; - len = lseek(fd, 0, SEEK_END); - if (len == (off_t) -1) { - LOG(LOG_ERROR, "shmem", - "Could not determine file size of '%s' (errno=%d)\n", - nameBuf, errno); - close(fd); - return false; - } - - mAddr = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); - if (mAddr == MAP_FAILED) { - LOG(LOG_ERROR, "shmem", "mmap failed (errno=%d)\n", errno); - close(fd); - return false; - } - - mHandle = fd; - mLength = len; - assert(mCreator == false); - mKey = key; - - /* done with shmem, attach to associated semaphore */ - if (!mSem.attach(key)) { - LOG(LOG_ERROR, "shmem", - "Failed to attach to semaphore for Shmem (key=%d)\n", key); - return false; - } - - return true; -} - -/* - * Get address. - */ -void* Shmem::getAddr(void) -{ - assert(mAddr != MAP_FAILED); - return mAddr; -} - -/* - * Return the length of the segment. - * - * Returns -1 on failure. - */ -long Shmem::getLength(void) -{ - if (mLength >= 0) - return mLength; - - // we should always have it by now - assert(false); - return -1; -} - - -#elif defined(HAVE_SYSV_IPC) // ---------------------------------------------- - -/* - * SysV-style IPC. The SysV shared memory API is fairly annoying to - * deal with, but it's present on many UNIX-like systems. - */ - -#define kInvalidHandle ((unsigned long)-1) - -/* - * Constructor. Just set up the fields. - */ -Shmem::Shmem(void) - : mHandle(kInvalidHandle), mAddr(NULL), mLength(-1), mCreator(false), - mKey(-1) -{ -} - -/* - * Destructor. Detach and, if we created it, mark the segment for - * destruction. - */ -Shmem::~Shmem(void) -{ - int cc; - - //LOG(LOG_DEBUG, "shmem", "~Shmem(handle=%ld creator=%d)", - // mHandle, mCreator); - - if (mAddr != NULL) - cc = shmdt(mAddr); - - if (mCreator && mHandle != kInvalidHandle) { - cc = shmctl((int) mHandle, IPC_RMID, NULL); - if (cc != 0) { - LOG(LOG_WARN, "shmem", - "Destructor failed to remove shmid=%ld (errno=%d)\n", - mHandle, errno); - } - } -} - -/* - * Create the segment and attach ourselves to it. - */ -bool Shmem::create(int key, long size, bool deleteExisting) -{ - int shmid, cc; - - if (deleteExisting) { - shmid = shmget(key, size, 0); - if (shmid != -1) { - LOG(LOG_DEBUG, "shmem", - "Key %d exists (shmid=%d), marking for destroy", key, shmid); - cc = shmctl(shmid, IPC_RMID, NULL); - if (cc != 0) { - LOG(LOG_ERROR, "shmem", - "Failed to remove key=%d shmid=%d (errno=%d)\n", - key, shmid, errno); - return false; // IPC_CREAT | IPC_EXCL will fail, so bail now - } else { - LOG(LOG_DEBUG, "shmem", - "Removed previous segment with key=%d\n", key); - } - } - } - - shmid = shmget(key, size, 0600 | IPC_CREAT | IPC_EXCL); - if (shmid == -1) { - LOG(LOG_ERROR, "shmem", "Failed to create key=%d (errno=%d)\n", - key, errno); - return false; - } - - mHandle = shmid; - mCreator = true; - mKey = key; - - void* addr = shmat(shmid, NULL, 0); - if (addr == (void*) -1) { - LOG(LOG_ERROR, "shmem", - "Could not attach to key=%d shmid=%d (errno=%d)\n", - key, shmid, errno); - return false; - } - - mAddr = addr; - mLength = size; - - /* done with shmem, create the associated semaphore */ - if (!mSem.create(key, 1, true)) { - LOG(LOG_ERROR, "shmem", - "Failed creating semaphore for Shmem (key=%d)\n", key); - return false; - } - - return true; -} - -/* - * Attach ourselves to an existing segment. - */ -bool Shmem::attach(int key) -{ - int shmid; - - shmid = shmget(key, 0, 0); - if (shmid == -1) { - LOG(LOG_ERROR, "shmem", "Failed to find key=%d\n", key); - return false; - } - - mHandle = shmid; - assert(mCreator == false); - mKey = key; - - void* addr = shmat(shmid, NULL, 0); - if (addr == (void*) -1) { - LOG(LOG_ERROR, "shmem", "Could not attach to key=%d shmid=%d\n", - key, shmid); - return false; - } - - mAddr = addr; - - /* done with shmem, attach to associated semaphore */ - if (!mSem.attach(key)) { - LOG(LOG_ERROR, "shmem", - "Failed to attach to semaphore for Shmem (key=%d)\n", key); - return false; - } - - return true; -} - -/* - * Get address. - */ -void* Shmem::getAddr(void) -{ - assert(mAddr != NULL); - return mAddr; -} - -/* - * Return the length of the segment. - * - * Returns -1 on failure. - */ -long Shmem::getLength(void) -{ - if (mLength >= 0) - return mLength; - - assert(mHandle != kInvalidHandle); - - struct shmid_ds shmids; - int cc; - - cc = shmctl((int) mHandle, IPC_STAT, &shmids); - if (cc != 0) { - LOG(LOG_ERROR, "shmem", "Could not IPC_STAT shmid=%ld\n", mHandle); - return -1; - } - mLength = shmids.shm_segsz; // save a copy to avoid future lookups - - return mLength; -} - - -#elif defined(HAVE_WIN32_IPC) // --------------------------------------------- - -/* - * Win32 shared memory implementation. - * - * Shared memory is implemented as an "anonymous" file mapping, using the - * memory-mapped I/O interfaces. - */ - -static const char* kShmemStr = "android-shmem-"; - -/* - * Constructor. Just set up the fields. - */ -Shmem::Shmem(void) - : mHandle((unsigned long) INVALID_HANDLE_VALUE), - mAddr(NULL), mLength(-1), mCreator(false), mKey(-1) -{ -} - -/* - * Destructor. The Win32 API doesn't require a distinction between - * the "creator" and other mappers. - */ -Shmem::~Shmem(void) -{ - LOG(LOG_DEBUG, "shmem", "~Shmem(handle=%ld creator=%d)", - mHandle, mCreator); - - if (mAddr != NULL) - UnmapViewOfFile(mAddr); - if (mHandle != (unsigned long) INVALID_HANDLE_VALUE) - CloseHandle((HANDLE) mHandle); -} - -/* - * Create the segment and map it. - */ -bool Shmem::create(int key, long size, bool deleteExisting) -{ - char keyBuf[64]; - HANDLE hMapFile; - - snprintf(keyBuf, sizeof(keyBuf), "%s%d", kShmemStr, key); - - hMapFile = CreateFileMapping( - INVALID_HANDLE_VALUE, // use paging file, not actual file - NULL, // default security - PAGE_READWRITE, // read/write access - 0, // max size; no need to cap - size, // min size - keyBuf); // mapping name - if (hMapFile == NULL || hMapFile == INVALID_HANDLE_VALUE) { - LOG(LOG_ERROR, "shmem", - "Could not create mapping object '%s' (err=%ld)\n", - keyBuf, GetLastError()); - return false; - } - - mHandle = (unsigned long) hMapFile; - mCreator = true; - mKey = key; - - mAddr = MapViewOfFile( - hMapFile, // handle to map object - FILE_MAP_ALL_ACCESS, // read/write - 0, // offset (hi) - 0, // offset (lo) - size); // #of bytes to map - if (mAddr == NULL) { - LOG(LOG_ERROR, "shmem", "Could not map shared area (err=%ld)\n", - GetLastError()); - return false; - } - mLength = size; - - /* done with shmem, create the associated semaphore */ - if (!mSem.create(key, 1, true)) { - LOG(LOG_ERROR, "shmem", - "Failed creating semaphore for Shmem (key=%d)\n", key); - return false; - } - - return true; -} - -/* - * Attach ourselves to an existing segment. - */ -bool Shmem::attach(int key) -{ - char keyBuf[64]; - HANDLE hMapFile; - - snprintf(keyBuf, sizeof(keyBuf), "%s%d", kShmemStr, key); - - hMapFile = OpenFileMapping( - FILE_MAP_ALL_ACCESS, // read/write - FALSE, // don't let kids inherit handle - keyBuf); // mapping name - if (hMapFile == NULL) { - LOG(LOG_ERROR, "shmem", - "Could not open mapping object '%s' (err=%ld)\n", - keyBuf, GetLastError()); - return false; - } - - mHandle = (unsigned long) hMapFile; - assert(mCreator == false); - mKey = key; - - mAddr = MapViewOfFile( - hMapFile, // handle to map object - FILE_MAP_ALL_ACCESS, // read/write - 0, // offset (hi) - 0, // offset (lo) - 0); // #of bytes to map - if (mAddr == NULL) { - LOG(LOG_ERROR, "shmem", "Could not map shared area (err=%ld)\n", - GetLastError()); - return false; - } - - /* done with shmem, attach to associated semaphore */ - if (!mSem.attach(key)) { - LOG(LOG_ERROR, "shmem", - "Failed to attach to semaphore for Shmem (key=%d)\n", key); - return false; - } - - return true; -} - -/* - * Get address. - */ -void* Shmem::getAddr(void) -{ - assert(mAddr != NULL); - return mAddr; -} - -/* - * Get the length of the segment. - */ -long Shmem::getLength(void) -{ - SIZE_T size; - MEMORY_BASIC_INFORMATION mbInfo; - - if (mLength >= 0) - return mLength; - - assert(mAddr != NULL); - - size = VirtualQuery(mAddr, &mbInfo, sizeof(mbInfo)); - if (size == 0) { - LOG(LOG_WARN, "shmem", "VirtualQuery returned no data\n"); - return -1; - } - - mLength = mbInfo.RegionSize; - return mLength; -} - -#endif // -------------------------------------------------------------------- - -/* - * Semaphore operations. - */ -void Shmem::lock(void) -{ - mSem.acquire(); -} -void Shmem::unlock(void) -{ - mSem.release(); -} -bool Shmem::tryLock(void) -{ - return mSem.tryAcquire(); -} - diff --git a/simulator/app/Shmem.h b/simulator/app/Shmem.h deleted file mode 100644 index 3d53b58b6..000000000 --- a/simulator/app/Shmem.h +++ /dev/null @@ -1,95 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Inter-process shared memory. -// -#ifndef __LIBS_SHMEM_H -#define __LIBS_SHMEM_H - -#ifdef HAVE_ANDROID_OS -#error DO NOT USE THIS FILE IN THE DEVICE BUILD -#endif - -#include "Semaphore.h" - -namespace android { - -/* - * Platform-independent shared memory. Each object can be used to - * create a chunk of memory that is shared between processes. - * - * For convenience, a semaphore is associated with each segment. - * (Whether this should have been done in a subclass is debatable.) - * - * The "key" is usually the process ID of the process that created the - * segment. The goal is to avoid clashing with other processes that are - * trying to do the same thing. It's a little awkward to use when you - * want to have multiple shared segments created in one process. In - * SysV you can work around this by using a "private" key and sharing - * the shmid with your friends, in Win32 you can use a string, but we're - * in lowest-common-denominator mode here. Assuming we have 16-bit PIDs, - * the upper 16 bits can be used to serialize keys. - * - * When the object goes out of scope, the shared memory segment is - * detached from the process. If the object was responsible for creating - * the segment, it is also marked for destruction on SysV systems. This - * will make it impossible for others to attach to. - * - * On some systems, the length returned by getLength() may be different - * for parent and child due to page size rounding. - */ -class Shmem { -public: - Shmem(void); - virtual ~Shmem(void); - - /* - * Create a new shared memory segment, with the specified size. If - * "deleteExisting" is set, any existing segment will be deleted first - * (useful for SysV IPC). - * - * Returns "true" on success, "false" on failure. - */ - bool create(int key, long size, bool deleteExisting); - - /* - * Attach to a shared memory segment. Use this from the process that - * didn't create the segment. - * - * Returns "true" on success, "false" on failure. - */ - bool attach(int key); - - /* - * Get the memory segment address and length. These will not change - * for the lifetime of the object, so it's okay to cache the results. - * - * On failure, getAddr() returns NULL and getLength() returns -1. - */ - void* getAddr(void); - long getLength(void); - - /* - * Lock or unlock the shared memory segment. This is useful if you - * are updating pieces of shared data. The segment is initially - * "unlocked". - * - * This does *not* lock down the segment in the virtual paging system. - * It's just a mutex. - */ - void lock(void); - void unlock(void); - bool tryLock(void); - -private: - Semaphore mSem; // uses the same value for "key" - unsigned long mHandle; // shmid(int) or HANDLE - void* mAddr; // address - long mLength; // length of segment (cached) - bool mCreator; // true if we created the segment - int mKey; // key passed in as arg -}; - -}; // namespace android - -#endif // __LIBS_SHMEM_H diff --git a/simulator/app/SimRuntime.h b/simulator/app/SimRuntime.h deleted file mode 100644 index 6dadfb25d..000000000 --- a/simulator/app/SimRuntime.h +++ /dev/null @@ -1,124 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Miscellaneous definitions and declarations used for interaction -// between the device and the simulator. -// -// This header is included on both sides, so try not to include -// any other headers from here. -// -#ifndef _RUNTIME_SIMULATOR_H -#define _RUNTIME_SIMULATOR_H - -#include "MessageStream.h" -#include "Shmem.h" -//#include "utils/RefBase.h" -#include "utils/Log.h" - -namespace android { - -#define ANDROID_PIPE_NAME "runtime" - -/* - * Hold simulator state. - */ -class Simulator { -public: - Simulator(void); - ~Simulator(void); - - /* - * Commands exchanged between simulator and runtime. - */ - typedef enum Command { - kCommandUnknown = 0, - - /* sent from sim to runtime */ - kCommandGoAway, // sim says: go away, I'm busy - kCommandConfigDone, // sim says: done sending config - kCommandQuit, // quit nicely - kCommandNewPGroup, // process group management - kCommandKeyDown, // key has been pressed - kCommandKeyUp, // key has been released - kCommandTouch, // finger touched/lifted/dragged - - /* sent from runtime to sim */ - kCommandNewPGroupCreated, // send process group as argument - kCommandRuntimeReady, // we're initialized and about to start - kCommandUpdateDisplay, // display has been updated - kCommandVibrate, // vibrate on or off - } Command; - - typedef enum TouchMode { - kTouchDown = 0, - kTouchUp = 1, - kTouchDrag = 2 - } TouchMode; - - /* - * Some parameters for config exchange. - */ - enum { - kDisplayConfigMagic = 0x44495350, - kValuesPerDisplay = 5, - }; - - /* - * Set up communication with parent process. - */ - //bool create(ParentProcess* pParent); - - /* - * Set up communication with detached simulator. - */ - bool create(Pipe* reader, Pipe* writer); - - /* - * Tell simulator that we're ready to go. - */ - void sendRuntimeReady(void); - - /* - * Tell the simulator that a display has been refreshed. - */ - void sendDisplayUpdate(int displayIndex); - - /* - * Tell the simulator to turn the vibrator on or off - */ - void sendVibrate(int vibrateOn); - - /* - * Get a pointer to the shared memory for the Nth display. - */ - Shmem* getGraphicsBuffer(int displayIndex); - - /* - * Return a copy of our input pipe so the event system can monitor - * it for pending activity. - */ - Pipe* getReadPipe(void) { return mStream.getReadPipe(); } - - /* - * Retrieve the next command from the parent. Returns NO_ERROR - * if all is okay, WOULD_BLOCK if blocking is false and there - * are no pending commands, or INVALID_OPERATION if the simulator - * has disappeared. - */ - int getNextKey(int32_t* outKey, bool* outDown); - - /* - * Log system callback function. - */ - static void writeLogMsg(const android_LogBundle* pBundle); - -private: - bool finishCreate(void); - bool handleDisplayConfig(const long* pData, int length); - - MessageStream mStream; -}; - -}; // namespace android - -#endif // _RUNTIME_SIMULATOR_H diff --git a/simulator/app/UserEvent.cpp b/simulator/app/UserEvent.cpp deleted file mode 100644 index 01d33377a..000000000 --- a/simulator/app/UserEvent.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Some additional glue for "user event" type. -// - -// For compilers that support precompilation, include "wx/wx.h". -#include "wx/wxprec.h" - -// Otherwise, include all standard headers -#ifndef WX_PRECOMP -# include "wx/wx.h" -#endif - -#include "UserEvent.h" - -DEFINE_EVENT_TYPE(wxEVT_USER_EVENT) - -IMPLEMENT_DYNAMIC_CLASS(UserEvent, wxEvent) - diff --git a/simulator/app/UserEvent.h b/simulator/app/UserEvent.h deleted file mode 100644 index 76664e19f..000000000 --- a/simulator/app/UserEvent.h +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// A "user event" for wxWidgets. -// -#ifndef _SIM_USER_EVENT_H -#define _SIM_USER_EVENT_H - -/* - * Event declaration. The book says to use DECLARE_EVENT_TYPE, but that - * causes a compiler warning and a link failure with gcc under MinGW. - * - * It looks like the "magic number", in this case 12345, is just picked - * by hand. There may be a better mechanism in this version of - * wxWidgets, but the documentation and sample code doesn't reflect it. - */ -BEGIN_DECLARE_EVENT_TYPES() - DECLARE_LOCAL_EVENT_TYPE(wxEVT_USER_EVENT, 12345) -END_DECLARE_EVENT_TYPES() - -/* - * A "user event" class. This can be used like any other wxWidgets - * event, but we get to stuff anything we want to in it. - */ -class UserEvent : public wxEvent { -public: - UserEvent(int id = 0, void* data = (void*) 0) - : wxEvent(id, wxEVT_USER_EVENT), mData(data) - {} - UserEvent(const UserEvent& event) - : wxEvent(event), mData(event.mData) - {} - - virtual wxEvent* Clone() const { - return new UserEvent(*this); - } - - void* GetData(void) const { return mData; } - - DECLARE_DYNAMIC_CLASS(UserEvent); - -private: - UserEvent& operator=(const UserEvent&); // not implemented - void* mData; -}; - -typedef void (wxEvtHandler::*UserEventFunction)(UserEvent&); - -#define EVT_USER_EVENT(fn) \ - DECLARE_EVENT_TABLE_ENTRY(wxEVT_USER_EVENT, wxID_ANY, wxID_ANY, \ - (wxObjectEventFunction)(wxEventFunction)(UserEventFunction)&fn, \ - (wxObject*) NULL ), - -#endif // _SIM_USER_EVENT_H diff --git a/simulator/app/UserEventMessage.h b/simulator/app/UserEventMessage.h deleted file mode 100644 index 4a66cc2cb..000000000 --- a/simulator/app/UserEventMessage.h +++ /dev/null @@ -1,84 +0,0 @@ -// -// Copyright 2005 The Android Open Source Project -// -// Contents of the "user event" sent from the device thread. -// -#ifndef _SIM_USER_EVENT_MESSAGE_H -#define _SIM_USER_EVENT_MESSAGE_H - -#include <utils.h> -#include "LogMessage.h" - -/* - * This gets stuffed into a UserEvent, which is posted to the main thread - * from a worker thread. - * - * The object does NOT own anything you stuff into it. It's just a vehicle - * for carting data from one thread to another in a wxWidgets-safe manner, - * usually as pointers to data that can be shared between threads. - */ -class UserEventMessage { -public: - /* - * What type of message is this? - */ - typedef enum UEMType { - kUnknown = 0, - - kRuntimeStarted, - kRuntimeStopped, - kErrorMessage, // message in mString - kLogMessage, // ptr to heap-allocated LogMessage - kExternalRuntime, // external runtime wants to party - } UEMType; - - UserEventMessage(void) - : mType(kUnknown), mpLogMessage(NULL) - {} - ~UserEventMessage(void) { - } - - /* - * Create one of our various messages. - */ - void CreateRuntimeStarted(void) { - mType = kRuntimeStarted; - } - void CreateRuntimeStopped(void) { - mType = kRuntimeStopped; - } - void CreateErrorMessage(wxString& str) { - mType = kErrorMessage; - mString = str; - } - void CreateLogMessage(LogMessage* pLogMessage) { - mType = kLogMessage; - mpLogMessage = pLogMessage; - } - void CreateExternalRuntime(android::Pipe* reader, android::Pipe* writer) { - mType = kExternalRuntime; - mReader = reader; - mWriter = writer; - } - - /* - * Accessors. - */ - UEMType GetType(void) const { return mType; } - const wxString& GetString(void) const { return mString; } - LogMessage* GetLogMessage(void) const { return mpLogMessage; } - android::Pipe* GetReader(void) const { return mReader; } - android::Pipe* GetWriter(void) const { return mWriter; } - -private: - UserEventMessage& operator=(const UserEventMessage&); // not implemented - UserEventMessage(const UserEventMessage&); // not implemented - - UEMType mType; - wxString mString; // for kErrorMessage - LogMessage* mpLogMessage; // for kLogMessage - android::Pipe* mReader; // for kExternalRuntime - android::Pipe* mWriter; // for kExternalRuntime -}; - -#endif // _SIM_USER_EVENT_MESSAGE_H diff --git a/simulator/app/assets/android-dream/arrow_down.png b/simulator/app/assets/android-dream/arrow_down.png Binary files differdeleted file mode 100644 index 19b3764e8..000000000 --- a/simulator/app/assets/android-dream/arrow_down.png +++ /dev/null diff --git a/simulator/app/assets/android-dream/arrow_left.png b/simulator/app/assets/android-dream/arrow_left.png Binary files differdeleted file mode 100644 index 113e58427..000000000 --- a/simulator/app/assets/android-dream/arrow_left.png +++ /dev/null diff --git a/simulator/app/assets/android-dream/arrow_right.png b/simulator/app/assets/android-dream/arrow_right.png Binary files differdeleted file mode 100644 index ffe3356c0..000000000 --- a/simulator/app/assets/android-dream/arrow_right.png +++ /dev/null diff --git a/simulator/app/assets/android-dream/arrow_up.png b/simulator/app/assets/android-dream/arrow_up.png Binary files differdeleted file mode 100644 index 81c54df51..000000000 --- a/simulator/app/assets/android-dream/arrow_up.png +++ /dev/null diff --git a/simulator/app/assets/android-dream/back.png b/simulator/app/assets/android-dream/back.png Binary files differdeleted file mode 100644 index 41034d910..000000000 --- a/simulator/app/assets/android-dream/back.png +++ /dev/null diff --git a/simulator/app/assets/android-dream/background.png b/simulator/app/assets/android-dream/background.png Binary files differdeleted file mode 100644 index bab8c6d1c..000000000 --- a/simulator/app/assets/android-dream/background.png +++ /dev/null diff --git a/simulator/app/assets/android-dream/end.png b/simulator/app/assets/android-dream/end.png Binary files differdeleted file mode 100644 index 6830a603b..000000000 --- a/simulator/app/assets/android-dream/end.png +++ /dev/null diff --git a/simulator/app/assets/android-dream/home.png b/simulator/app/assets/android-dream/home.png Binary files differdeleted file mode 100644 index 7d021369b..000000000 --- a/simulator/app/assets/android-dream/home.png +++ /dev/null diff --git a/simulator/app/assets/android-dream/key.png b/simulator/app/assets/android-dream/key.png Binary files differdeleted file mode 100644 index 7a3f563bd..000000000 --- a/simulator/app/assets/android-dream/key.png +++ /dev/null diff --git a/simulator/app/assets/android-dream/layout.xml b/simulator/app/assets/android-dream/layout.xml deleted file mode 100644 index 8a7c5f862..000000000 --- a/simulator/app/assets/android-dream/layout.xml +++ /dev/null @@ -1,356 +0,0 @@ -<?xml version="1.0" ?> -<!-- Copyright 2006 The Android Open Source Project --> - -<device name="Dream"> - <!-- title for menus --> - <title>Android Dream</title> - - <display name="main" width="320" height="480" format="rgb565" refresh="30"/> - - <keyboard qwerty="1" keycharmap="qwerty2" /> - - <mode name="closed"> - <view display="main" x="75" y="84" rotate="0"> - - <!-- surrounding device image and "patches", drawn in order --> - <image src="background.png" x="0" y="0"/> - - <!-- buttons for which we have highlight images --> - <button keyCode="1" src="key.png" x="468" y="276"/> - <button keyCode="q" src="key.png" x="468" y="312"/> - <button keyCode="power" src="power.png" x="7" y="66"/> - <button keyCode="volume-up" src="volume_up.png" x="407" y="274"/> - <button keyCode="volume-down" src="volume_down.png" x="407" y="324"/> - - <button keyCode="home" src="home.png" x="93" y="602"/> - <button keyCode="back" src="back.png" x="331" y="602"/> - <button keyCode="dpad-up" src="arrow_up.png" x="185" y="608"/> - <button keyCode="dpad-down" src="arrow_down.png" x="185" y="669"/> - <button keyCode="dpad-left" src="arrow_left.png" x="155" y="610"/> - <button keyCode="dpad-right" src="arrow_right.png" x="266" y="610"/> - <button keyCode="dpad-center" src="select.png" x="186" y="637"/> - <button keyCode="phone-dial" src="send.png" x="93" y="658"/> - <button keyCode="phone-hangup" src="end.png" x="331" y="658"/> - <button keyCode="soft-left" src="menu.png" x="192" y="569"/> - -<!-- - 1 { - image key.png - x 468 - y 302 - } - 2 { - image key.png - x 505 - y 302 - } - 3 { - image key.png - x 543 - y 302 - } - 4 { - image key.png - x 579 - y 302 - } - 5 { - image key.png - x 616 - y 302 - } - 6 { - image key.png - x 653 - y 302 - } - 7 { - image key.png - x 690 - y 302 - } - 8 { - image key.png - x 727 - y 302 - } - 9 { - image key.png - x 763 - y 302 - } - 0 { - image key.png - x 801 - y 302 - } - - q { - image key.png - x 468 - y 338 - } - w { - image key.png - x 505 - y 338 - } - e { - image key.png - x 543 - y 338 - } - r { - image key.png - x 579 - y 338 - } - t { - image key.png - x 616 - y 338 - } - y { - image key.png - x 653 - y 338 - } - u { - image key.png - x 690 - y 338 - } - i { - image key.png - x 727 - y 338 - } - o { - image key.png - x 763 - y 338 - } - p { - image key.png - x 801 - y 338 - } - - a { - image key.png - x 468 - y 374 - } - s { - image key.png - x 505 - y 374 - } - d { - image key.png - x 543 - y 374 - } - f { - image key.png - x 579 - y 374 - } - g { - image key.png - x 616 - y 374 - } - h { - image key.png - x 653 - y 374 - } - j { - image key.png - x 690 - y 374 - } - k { - image key.png - x 727 - y 374 - } - l { - image key.png - x 763 - y 374 - } - DEL { - image key.png - x 801 - y 374 - } - - CAP { - image key.png - x 468 - y 410 - } - z { - image key.png - x 505 - y 410 - } - x { - image key.png - x 543 - y 410 - } - c { - image key.png - x 579 - y 410 - } - v { - image key.png - x 616 - y 410 - } - b { - image key.png - x 653 - y 410 - } - n { - image key.png - x 690 - y 410 - } - m { - image key.png - x 727 - y 410 - } - PERIOD { - image key.png - x 763 - y 410 - } - ENTER { - image key.png - x 801 - y 410 - } - - ALT { - image key.png - x 468 - y 446 - } - SYM { - image key.png - x 505 - y 446 - } - AT { - image key.png - x 543 - y 446 - } - SPACE { - image spacebar.png - x 579 - y 446 - } - SLASH { - image key.png - x 727 - y 446 - } - COMMA { - image key.png - x 763 - y 446 - } - ALT2 { - image key.png - x 801 - y 446 - } - - soft-left { - image menu.png - x 192 - y 623 - } - home { - image home.png - x 93 - y 656 - } - back { - image back.png - x 331 - y 656 - } - dpad-up { - image arrow_up.png - x 185 - y 662 - } - dpad-down { - image arrow_down.png - x 185 - y 723 - } - dpad-left { - image arrow_left.png - x 155 - y 664 - } - dpad-right { - image arrow_right.png - x 266 - y 664 - } - dpad-center { - image select.png - x 186 - y 691 - } - phone-dial { - image send.png - x 93 - y 712 - } - phone-hangup { - image end.png - x 331 - y 712 - } - - power { - image power.png - x 7 - y 120 - } - - volume-up { - image volume_up.png - x 407 - y 328 - } - - volume-down { - image volume_down.png - x 407 - y 378 - } ---> - </view> - </mode> - -<!-- - <mode name="open"> - <view display="main" x="0" y="0" rotate="90"> - </view> - </mode> ---> - -</device> diff --git a/simulator/app/assets/android-dream/menu.png b/simulator/app/assets/android-dream/menu.png Binary files differdeleted file mode 100644 index e81d8abcf..000000000 --- a/simulator/app/assets/android-dream/menu.png +++ /dev/null diff --git a/simulator/app/assets/android-dream/power.png b/simulator/app/assets/android-dream/power.png Binary files differdeleted file mode 100644 index 5894288f0..000000000 --- a/simulator/app/assets/android-dream/power.png +++ /dev/null diff --git a/simulator/app/assets/android-dream/select.png b/simulator/app/assets/android-dream/select.png Binary files differdeleted file mode 100644 index 803d49315..000000000 --- a/simulator/app/assets/android-dream/select.png +++ /dev/null diff --git a/simulator/app/assets/android-dream/send.png b/simulator/app/assets/android-dream/send.png Binary files differdeleted file mode 100644 index f547c8817..000000000 --- a/simulator/app/assets/android-dream/send.png +++ /dev/null diff --git a/simulator/app/assets/android-dream/spacebar.png b/simulator/app/assets/android-dream/spacebar.png Binary files differdeleted file mode 100644 index 19fe60476..000000000 --- a/simulator/app/assets/android-dream/spacebar.png +++ /dev/null diff --git a/simulator/app/assets/android-dream/volume_down.png b/simulator/app/assets/android-dream/volume_down.png Binary files differdeleted file mode 100644 index f8a88dec8..000000000 --- a/simulator/app/assets/android-dream/volume_down.png +++ /dev/null diff --git a/simulator/app/assets/android-dream/volume_up.png b/simulator/app/assets/android-dream/volume_up.png Binary files differdeleted file mode 100644 index 940457f70..000000000 --- a/simulator/app/assets/android-dream/volume_up.png +++ /dev/null diff --git a/simulator/app/assets/android-sooner/back.png b/simulator/app/assets/android-sooner/back.png Binary files differdeleted file mode 100644 index 5190939c7..000000000 --- a/simulator/app/assets/android-sooner/back.png +++ /dev/null diff --git a/simulator/app/assets/android-sooner/background.png b/simulator/app/assets/android-sooner/background.png Binary files differdeleted file mode 100644 index 32534b905..000000000 --- a/simulator/app/assets/android-sooner/background.png +++ /dev/null diff --git a/simulator/app/assets/android-sooner/down.png b/simulator/app/assets/android-sooner/down.png Binary files differdeleted file mode 100644 index 1d602b01c..000000000 --- a/simulator/app/assets/android-sooner/down.png +++ /dev/null diff --git a/simulator/app/assets/android-sooner/end.png b/simulator/app/assets/android-sooner/end.png Binary files differdeleted file mode 100644 index 17d8cc7f0..000000000 --- a/simulator/app/assets/android-sooner/end.png +++ /dev/null diff --git a/simulator/app/assets/android-sooner/favorites.png b/simulator/app/assets/android-sooner/favorites.png Binary files differdeleted file mode 100644 index ad85c5c89..000000000 --- a/simulator/app/assets/android-sooner/favorites.png +++ /dev/null diff --git a/simulator/app/assets/android-sooner/home.png b/simulator/app/assets/android-sooner/home.png Binary files differdeleted file mode 100644 index 04f9a2173..000000000 --- a/simulator/app/assets/android-sooner/home.png +++ /dev/null diff --git a/simulator/app/assets/android-sooner/imap b/simulator/app/assets/android-sooner/imap deleted file mode 100644 index 64c9aff3d..000000000 --- a/simulator/app/assets/android-sooner/imap +++ /dev/null @@ -1,15 +0,0 @@ -# awk '{print $1, $4-$2 "x" $5-$3 "+" $2 "+" $3}' - -BACKGROUND=background-alpha.png - -convert $BACKGROUND -crop 43x47+55+410 send.png -convert $BACKGROUND -crop 43x47+338+411 end.png -convert $BACKGROUND -crop 43x40+98+393 menu.png -convert $BACKGROUND -crop 43x40+98+433 back.png -convert $BACKGROUND -crop 47x40+291+393 favorites.png -convert $BACKGROUND -crop 47x40+291+433 home.png -convert $BACKGROUND -crop 81x24+177+422 select.png -convert $BACKGROUND -crop 81x30+177+392 up.png -convert $BACKGROUND -crop 81x30+177+446 down.png -convert $BACKGROUND -crop 31x84+146+392 left.png -convert $BACKGROUND -crop 31x84+258+392 right.png diff --git a/simulator/app/assets/android-sooner/layout.xml b/simulator/app/assets/android-sooner/layout.xml deleted file mode 100644 index d17b9d8e3..000000000 --- a/simulator/app/assets/android-sooner/layout.xml +++ /dev/null @@ -1,34 +0,0 @@ -<?xml version="1.0" ?> -<!-- Copyright 2006 The Android Open Source Project --> - -<device name="Sooner"> - <!-- title for menus --> - <title>Android Sooner</title> - - <display name="main" width="320" height="240" format="rgb565" refresh="30"/> - - <keyboard qwerty="1" keycharmap="qwerty" /> - - <mode name="default"> - <view display="main" x="53" y="95" rotate="0"> - - <!-- surrounding device image and "patches", drawn in order --> - <image src="background.png" x="0" y="0"/> - - <!-- buttons for which we have highlight images --> - <button keyCode="soft-left" src="menu.png" x="93" y="367"/> - <button keyCode="soft-right" src="favorites.png" x="286" y="367"/> - <button keyCode="home" src="home.png" x="286" y="407"/> - <button keyCode="back" src="back.png" x="93" y="407"/> - <button keyCode="dpad-up" src="up.png" x="172" y="366"/> - <button keyCode="dpad-down" src="down.png" x="172" y="420"/> - <button keyCode="dpad-left" src="left.png" x="141" y="366"/> - <button keyCode="dpad-right" src="right.png" x="253" y="366"/> - <button keyCode="dpad-center" src="select.png" x="172" y="396"/> - - <button keyCode="phone-dial" src="send.png" x="50" y="384"/> - <button keyCode="phone-hangup" src="end.png" x="333" y="385"/> - </view> - </mode> - -</device> diff --git a/simulator/app/assets/android-sooner/left.png b/simulator/app/assets/android-sooner/left.png Binary files differdeleted file mode 100644 index f712f5c10..000000000 --- a/simulator/app/assets/android-sooner/left.png +++ /dev/null diff --git a/simulator/app/assets/android-sooner/menu.png b/simulator/app/assets/android-sooner/menu.png Binary files differdeleted file mode 100644 index 4c7f15ac1..000000000 --- a/simulator/app/assets/android-sooner/menu.png +++ /dev/null diff --git a/simulator/app/assets/android-sooner/right.png b/simulator/app/assets/android-sooner/right.png Binary files differdeleted file mode 100644 index b1aa1f95f..000000000 --- a/simulator/app/assets/android-sooner/right.png +++ /dev/null diff --git a/simulator/app/assets/android-sooner/select.png b/simulator/app/assets/android-sooner/select.png Binary files differdeleted file mode 100644 index 79606d185..000000000 --- a/simulator/app/assets/android-sooner/select.png +++ /dev/null diff --git a/simulator/app/assets/android-sooner/send.png b/simulator/app/assets/android-sooner/send.png Binary files differdeleted file mode 100644 index 9bf103dcb..000000000 --- a/simulator/app/assets/android-sooner/send.png +++ /dev/null diff --git a/simulator/app/assets/android-sooner/up.png b/simulator/app/assets/android-sooner/up.png Binary files differdeleted file mode 100644 index 324d67efd..000000000 --- a/simulator/app/assets/android-sooner/up.png +++ /dev/null diff --git a/simulator/app/assets/chimera-2000/layout.xml b/simulator/app/assets/chimera-2000/layout.xml deleted file mode 100644 index d80828146..000000000 --- a/simulator/app/assets/chimera-2000/layout.xml +++ /dev/null @@ -1,194 +0,0 @@ -<?xml version="1.0" ?> -<!-- Copyright 2005 The Android Open Source Project --> - -<!-- -This is a silly, contrived example of a dual-screen display device. -The "front" and "back" are shown side-by-side. I used the phone graphics -from two phones, which are presented as if they were glued back-to-back. - -This also illustrates front and back views, which for our purposes just -determines which phone is on the left. - -This used to use relative paths (../whatever) to get at the phone content, -but relative paths aren't supported in the "AssetManager" world. We now -use "::/whatever", which is interpreted by the simulator. (The change from -'.' to ':' was done to make it obvious that we weren't using UNIX paths.) ---> - - -<device name="Chimera2000"> - <!-- title for menus --> - <title>Chimera WeirdPhone 2000</title> - - <!-- primary display characteristics --> - <display name="top" width="176" height="220" format="rgb565" refresh="30"/> - <display name="bottom" width="176" height="220" format="rgb565" refresh="30"/> - - <mode name="front"> - <!-- the "top" device looks like a Samsung phone --> - <view display="top" x="49" y="73" rotate="0"> - - <!-- surrounding device image and "patches", drawn in order --> - <!-- (phone image is optional) --> - <image src="::/samsung-flip-2005/background-176x220.png" x="0" y="0"/> - <image src="::/samsung-flip-2005/home-background.png" x="22" y="426"/> - <image src="::/samsung-flip-2005/back-background.png" x="179" y="426"/> - - <!-- buttons for which we have highlight images --> - <button keyCode="soft-left" src="::/samsung-flip-2005/soft-left.png" x="24" y="388"/> - <button keyCode="soft-right" src="::/samsung-flip-2005/soft-right.png" x="182" y="388"/> - <button keyCode="home" src="::/samsung-flip-2005/home.png" x="22" y="426"/> - <button keyCode="back" src="::/samsung-flip-2005/back.png" x="179" y="426"/> - <button keyCode="dpad-up" src="::/samsung-flip-2005/arrow-up.png" x="99" y="399"/> - <button keyCode="dpad-down" src="::/samsung-flip-2005/arrow-down.png" x="99" y="461"/> - <button keyCode="dpad-left" src="::/samsung-flip-2005/arrow-left.png" x="82" y="411"/> - <button keyCode="dpad-right" src="::/samsung-flip-2005/arrow-right.png" x="147" y="411"/> - <button keyCode="dpad-center" src="::/samsung-flip-2005/select.png" x="115" y="431"/> - - <button keyCode="1" src="::/samsung-flip-2005/1.png" x="24" y="533"/> - <button keyCode="2" src="::/samsung-flip-2005/2.png" x="94" y="544"/> - <button keyCode="3" src="::/samsung-flip-2005/3.png" x="173" y="534"/> - <button keyCode="4" src="::/samsung-flip-2005/4.png" x="25" y="576"/> - <button keyCode="5" src="::/samsung-flip-2005/5.png" x="94" y="581"/> - <button keyCode="6" src="::/samsung-flip-2005/6.png" x="172" y="576"/> - <button keyCode="7" src="::/samsung-flip-2005/7.png" x="27" y="619"/> - <button keyCode="8" src="::/samsung-flip-2005/8.png" x="95" y="621"/> - <button keyCode="9" src="::/samsung-flip-2005/9.png" x="168" y="620"/> - <button keyCode="0" src="::/samsung-flip-2005/0.png" x="96" y="658"/> - <button keyCode="star" src="::/samsung-flip-2005/star.png" x="31" y="659"/> - <button keyCode="pound" src="::/samsung-flip-2005/pound.png" x="169" y="659"/> - - <!-- buttons we haven't bothered to create highlight images for, - or that aren't visible on-screen --> - <button keyCode="volume-up"/> - <button keyCode="volume-down"/> - <button keyCode="power"/> - <button keyCode="clear"/> - </view> - - <!-- the "bottom" device looks like an HTC phone --> - <view display="bottom" x="36" y="73" rotate="0"> - - <!-- surrounding device image and "patches", drawn in order --> - <!-- (phone image is optional) --> - <image src="::/htc-audiovox-5600/background.png" x="0" y="0"/> - - <!-- buttons for which we have highlight images --> - <button keyCode="soft-left" src="::/htc-audiovox-5600/soft-left.png" x="40" y="312"/> - <button keyCode="soft-right" src="::/htc-audiovox-5600/soft-right.png" x="145" y="312"/> - <button keyCode="home" src="::/htc-audiovox-5600/home.png" x="57" y="331"/> - <button keyCode="back" src="::/htc-audiovox-5600/back.png" x="123" y="333"/> - <button keyCode="dpad-up" src="::/htc-audiovox-5600/arrow-up.png" x="59" y="364"/> - <button keyCode="dpad-down" src="::/htc-audiovox-5600/arrow-down.png" x="60" y="393"/> - <button keyCode="dpad-left"/> - <button keyCode="dpad-right"/> - <button keyCode="dpad-center" src="::/htc-audiovox-5600/select.png" x="103" y="381"/> - - <button keyCode="1" src="::/htc-audiovox-5600/1.png" x="30" y="411"/> - <button keyCode="2" src="::/htc-audiovox-5600/2.png" x="90" y="409"/> - <button keyCode="3" src="::/htc-audiovox-5600/3.png" x="159" y="413"/> - <button keyCode="4" src="::/htc-audiovox-5600/4.png" x="32" y="445"/> - <button keyCode="5" src="::/htc-audiovox-5600/5.png" x="92" y="445"/> - <button keyCode="6" src="::/htc-audiovox-5600/6.png" x="157" y="444"/> - <button keyCode="7" src="::/htc-audiovox-5600/7.png" x="28" y="476"/> - <button keyCode="8" src="::/htc-audiovox-5600/8.png" x="94" y="480"/> - <button keyCode="9" src="::/htc-audiovox-5600/9.png" x="156" y="477"/> - <button keyCode="0" src="::/htc-audiovox-5600/0.png" x="97" y="513"/> - <button keyCode="star" src="::/htc-audiovox-5600/star.png" x="45" y="509"/> - <button keyCode="pound" src="::/htc-audiovox-5600/pound.png" x="155" y="511"/> - - <!-- buttons we haven't bothered to create highlight images for, - or that aren't visible on-screen --> - <button keyCode="volume-up"/> - <button keyCode="volume-down"/> - <button keyCode="power"/> - <button keyCode="clear"/> - - </view> - </mode> - - <mode name="back"> - <!-- show the back view first, then the front view --> - <view display="bottom" x="36" y="73" rotate="0"> - - <!-- surrounding device image and "patches", drawn in order --> - <!-- (phone image is optional) --> - <image src="::/htc-audiovox-5600/background.png" x="0" y="0"/> - - <!-- buttons for which we have highlight images --> - <button keyCode="soft-left" src="::/htc-audiovox-5600/soft-left.png" x="40" y="312"/> - <button keyCode="soft-right" src="::/htc-audiovox-5600/soft-right.png" x="145" y="312"/> - <button keyCode="home" src="::/htc-audiovox-5600/home.png" x="57" y="331"/> - <button keyCode="back" src="::/htc-audiovox-5600/back.png" x="123" y="333"/> - <button keyCode="dpad-up" src="::/htc-audiovox-5600/arrow-up.png" x="59" y="364"/> - <button keyCode="dpad-down" src="::/htc-audiovox-5600/arrow-down.png" x="60" y="393"/> - <button keyCode="dpad-left"/> - <button keyCode="dpad-right"/> - <button keyCode="dpad-center" src="::/htc-audiovox-5600/select.png" x="103" y="381"/> - - <button keyCode="1" src="::/htc-audiovox-5600/1.png" x="30" y="411"/> - <button keyCode="2" src="::/htc-audiovox-5600/2.png" x="90" y="409"/> - <button keyCode="3" src="::/htc-audiovox-5600/3.png" x="159" y="413"/> - <button keyCode="4" src="::/htc-audiovox-5600/4.png" x="32" y="445"/> - <button keyCode="5" src="::/htc-audiovox-5600/5.png" x="92" y="445"/> - <button keyCode="6" src="::/htc-audiovox-5600/6.png" x="157" y="444"/> - <button keyCode="7" src="::/htc-audiovox-5600/7.png" x="28" y="476"/> - <button keyCode="8" src="::/htc-audiovox-5600/8.png" x="94" y="480"/> - <button keyCode="9" src="::/htc-audiovox-5600/9.png" x="156" y="477"/> - <button keyCode="0" src="::/htc-audiovox-5600/0.png" x="97" y="513"/> - <button keyCode="star" src="::/htc-audiovox-5600/star.png" x="45" y="509"/> - <button keyCode="pound" src="::/htc-audiovox-5600/pound.png" x="155" y="511"/> - - <!-- buttons we haven't bothered to create highlight images for, - or that aren't visible on-screen --> - <button keyCode="volume-up"/> - <button keyCode="volume-down"/> - <button keyCode="power"/> - <button keyCode="clear"/> - - </view> - - <!-- our view of the device that shows the main display --> - <view display="top" x="49" y="73" rotate="0"> - - <!-- surrounding device image and "patches", drawn in order --> - <!-- (phone image is optional) --> - <image src="::/samsung-flip-2005/background-176x220.png" x="0" y="0"/> - <image src="::/samsung-flip-2005/home-background.png" x="22" y="426"/> - <image src="::/samsung-flip-2005/back-background.png" x="179" y="426"/> - - <!-- buttons for which we have highlight images --> - <button keyCode="soft-left" src="::/samsung-flip-2005/soft-left.png" x="24" y="388"/> - <button keyCode="soft-right" src="::/samsung-flip-2005/soft-right.png" x="182" y="388"/> - <button keyCode="home" src="::/samsung-flip-2005/home.png" x="22" y="426"/> - <button keyCode="back" src="::/samsung-flip-2005/back.png" x="179" y="426"/> - <button keyCode="dpad-up" src="::/samsung-flip-2005/arrow-up.png" x="99" y="399"/> - <button keyCode="dpad-down" src="::/samsung-flip-2005/arrow-down.png" x="99" y="461"/> - <button keyCode="dpad-left" src="::/samsung-flip-2005/arrow-left.png" x="82" y="411"/> - <button keyCode="dpad-right" src="::/samsung-flip-2005/arrow-right.png" x="147" y="411"/> - <button keyCode="dpad-center" src="::/samsung-flip-2005/select.png" x="115" y="431"/> - - <button keyCode="1" src="::/samsung-flip-2005/1.png" x="24" y="533"/> - <button keyCode="2" src="::/samsung-flip-2005/2.png" x="94" y="544"/> - <button keyCode="3" src="::/samsung-flip-2005/3.png" x="173" y="534"/> - <button keyCode="4" src="::/samsung-flip-2005/4.png" x="25" y="576"/> - <button keyCode="5" src="::/samsung-flip-2005/5.png" x="94" y="581"/> - <button keyCode="6" src="::/samsung-flip-2005/6.png" x="172" y="576"/> - <button keyCode="7" src="::/samsung-flip-2005/7.png" x="27" y="619"/> - <button keyCode="8" src="::/samsung-flip-2005/8.png" x="95" y="621"/> - <button keyCode="9" src="::/samsung-flip-2005/9.png" x="168" y="620"/> - <button keyCode="0" src="::/samsung-flip-2005/0.png" x="96" y="658"/> - <button keyCode="star" src="::/samsung-flip-2005/star.png" x="31" y="659"/> - <button keyCode="pound" src="::/samsung-flip-2005/pound.png" x="169" y="659"/> - - <!-- buttons we haven't bothered to create highlight images for, - or that aren't visible on-screen --> - <button keyCode="volume-up"/> - <button keyCode="volume-down"/> - <button keyCode="power"/> - <button keyCode="clear"/> - </view> - - </mode> -</device> - diff --git a/simulator/app/assets/danger-hiptop-m1/background-open.png b/simulator/app/assets/danger-hiptop-m1/background-open.png Binary files differdeleted file mode 100644 index 62d2c298f..000000000 --- a/simulator/app/assets/danger-hiptop-m1/background-open.png +++ /dev/null diff --git a/simulator/app/assets/danger-hiptop-m1/background.png b/simulator/app/assets/danger-hiptop-m1/background.png Binary files differdeleted file mode 100644 index f8c58c724..000000000 --- a/simulator/app/assets/danger-hiptop-m1/background.png +++ /dev/null diff --git a/simulator/app/assets/danger-hiptop-m1/layout.xml b/simulator/app/assets/danger-hiptop-m1/layout.xml deleted file mode 100644 index f8d7cba06..000000000 --- a/simulator/app/assets/danger-hiptop-m1/layout.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" ?> -<!-- Copyright 2005 The Android Open Source Project --> - -<device name="DangerM1"> - <!-- title for menus --> - <title>Danger hiptop M1</title> - - <display name="main" width="240" height="160" format="rgb565" refresh="30"/> - - <keyboard qwerty="1" /> - - <mode name="closed"> - <!-- hiptop when closed --> - <view display="main" x="160" y="69" rotate="0"> - - <!-- surrounding device image and "patches", drawn in order --> - <image src="background.png" x="0" y="0"/> - - </view> - </mode> - - <mode name="open"> - <!-- hiptop when flipped open --> - <view display="main" x="172" y="60" rotate="180"> - - <image src="background-open.png" x="0" y="0"/> - </view> - </mode> - -</device> - diff --git a/simulator/app/assets/htc-audiovox-5600/0.png b/simulator/app/assets/htc-audiovox-5600/0.png Binary files differdeleted file mode 100644 index 1fa4b7249..000000000 --- a/simulator/app/assets/htc-audiovox-5600/0.png +++ /dev/null diff --git a/simulator/app/assets/htc-audiovox-5600/1.png b/simulator/app/assets/htc-audiovox-5600/1.png Binary files differdeleted file mode 100644 index f9393342b..000000000 --- a/simulator/app/assets/htc-audiovox-5600/1.png +++ /dev/null diff --git a/simulator/app/assets/htc-audiovox-5600/2.png b/simulator/app/assets/htc-audiovox-5600/2.png Binary files differdeleted file mode 100644 index 09be58b53..000000000 --- a/simulator/app/assets/htc-audiovox-5600/2.png +++ /dev/null diff --git a/simulator/app/assets/htc-audiovox-5600/3.png b/simulator/app/assets/htc-audiovox-5600/3.png Binary files differdeleted file mode 100644 index 91c70c115..000000000 --- a/simulator/app/assets/htc-audiovox-5600/3.png +++ /dev/null diff --git a/simulator/app/assets/htc-audiovox-5600/4.png b/simulator/app/assets/htc-audiovox-5600/4.png Binary files differdeleted file mode 100644 index da930ff12..000000000 --- a/simulator/app/assets/htc-audiovox-5600/4.png +++ /dev/null diff --git a/simulator/app/assets/htc-audiovox-5600/5.png b/simulator/app/assets/htc-audiovox-5600/5.png Binary files differdeleted file mode 100644 index 5c4625a19..000000000 --- a/simulator/app/assets/htc-audiovox-5600/5.png +++ /dev/null diff --git a/simulator/app/assets/htc-audiovox-5600/6.png b/simulator/app/assets/htc-audiovox-5600/6.png Binary files differdeleted file mode 100644 index f30996070..000000000 --- a/simulator/app/assets/htc-audiovox-5600/6.png +++ /dev/null diff --git a/simulator/app/assets/htc-audiovox-5600/7.png b/simulator/app/assets/htc-audiovox-5600/7.png Binary files differdeleted file mode 100644 index e09b08cff..000000000 --- a/simulator/app/assets/htc-audiovox-5600/7.png +++ /dev/null diff --git a/simulator/app/assets/htc-audiovox-5600/8.png b/simulator/app/assets/htc-audiovox-5600/8.png Binary files differdeleted file mode 100644 index c8b3dcc22..000000000 --- a/simulator/app/assets/htc-audiovox-5600/8.png +++ /dev/null diff --git a/simulator/app/assets/htc-audiovox-5600/9.png b/simulator/app/assets/htc-audiovox-5600/9.png Binary files differdeleted file mode 100644 index f28421206..000000000 --- a/simulator/app/assets/htc-audiovox-5600/9.png +++ /dev/null diff --git a/simulator/app/assets/htc-audiovox-5600/arrow-down.png b/simulator/app/assets/htc-audiovox-5600/arrow-down.png Binary files differdeleted file mode 100644 index 08a17ead6..000000000 --- a/simulator/app/assets/htc-audiovox-5600/arrow-down.png +++ /dev/null diff --git a/simulator/app/assets/htc-audiovox-5600/arrow-up.png b/simulator/app/assets/htc-audiovox-5600/arrow-up.png Binary files differdeleted file mode 100644 index f2998b9a7..000000000 --- a/simulator/app/assets/htc-audiovox-5600/arrow-up.png +++ /dev/null diff --git a/simulator/app/assets/htc-audiovox-5600/back.png b/simulator/app/assets/htc-audiovox-5600/back.png Binary files differdeleted file mode 100644 index 4110ec7c5..000000000 --- a/simulator/app/assets/htc-audiovox-5600/back.png +++ /dev/null diff --git a/simulator/app/assets/htc-audiovox-5600/background-orange.png b/simulator/app/assets/htc-audiovox-5600/background-orange.png Binary files differdeleted file mode 100644 index b147546a1..000000000 --- a/simulator/app/assets/htc-audiovox-5600/background-orange.png +++ /dev/null diff --git a/simulator/app/assets/htc-audiovox-5600/background.png b/simulator/app/assets/htc-audiovox-5600/background.png Binary files differdeleted file mode 100644 index 9ffd7f3e0..000000000 --- a/simulator/app/assets/htc-audiovox-5600/background.png +++ /dev/null diff --git a/simulator/app/assets/htc-audiovox-5600/home.png b/simulator/app/assets/htc-audiovox-5600/home.png Binary files differdeleted file mode 100644 index a10d29344..000000000 --- a/simulator/app/assets/htc-audiovox-5600/home.png +++ /dev/null diff --git a/simulator/app/assets/htc-audiovox-5600/layout.xml b/simulator/app/assets/htc-audiovox-5600/layout.xml deleted file mode 100644 index 9e68c0f18..000000000 --- a/simulator/app/assets/htc-audiovox-5600/layout.xml +++ /dev/null @@ -1,53 +0,0 @@ -<?xml version="1.0" ?> -<!-- Copyright 2005 The Android Open Source Project --> - -<device name="HTC5600"> - <!-- title for menus --> - <title>HTC AudioVox 5600</title> - - <!-- primary display characteristics --> - <display name="main" width="176" height="220" format="rgb565" refresh="30"/> - - <mode name="default"> - <view display="main" x="36" y="73" rotate="0"> - - <!-- surrounding device image and "patches", drawn in order --> - <!-- (phone image is optional) --> - <image src="background.png" x="0" y="0"/> - - <!-- buttons for which we have highlight images --> - <button keyCode="soft-left" src="soft-left.png" x="40" y="312"/> - <button keyCode="soft-right" src="soft-right.png" x="145" y="312"/> - <button keyCode="home" src="home.png" x="57" y="331"/> - <button keyCode="back" src="back.png" x="123" y="333"/> - <button keyCode="dpad-up" src="arrow-up.png" x="59" y="364"/> - <button keyCode="dpad-down" src="arrow-down.png" x="60" y="393"/> - <button keyCode="dpad-left"/> - <button keyCode="dpad-right"/> - <button keyCode="dpad-center" src="select.png" x="103" y="381"/> - - <button keyCode="1" src="1.png" x="30" y="411"/> - <button keyCode="2" src="2.png" x="90" y="409"/> - <button keyCode="3" src="3.png" x="159" y="413"/> - <button keyCode="4" src="4.png" x="32" y="445"/> - <button keyCode="5" src="5.png" x="92" y="445"/> - <button keyCode="6" src="6.png" x="157" y="444"/> - <button keyCode="7" src="7.png" x="28" y="476"/> - <button keyCode="8" src="8.png" x="94" y="480"/> - <button keyCode="9" src="9.png" x="156" y="477"/> - <button keyCode="0" src="0.png" x="97" y="513"/> - <button keyCode="star" src="star.png" x="45" y="509"/> - <button keyCode="pound" src="pound.png" x="155" y="511"/> - - <!-- buttons we haven't bothered to create highlight images for, - or that aren't visible on-screen --> - <button keyCode="volume-up"/> - <button keyCode="volume-down"/> - <button keyCode="power"/> - <button keyCode="clear"/> - - </view> - </mode> - -</device> - diff --git a/simulator/app/assets/htc-audiovox-5600/pound.png b/simulator/app/assets/htc-audiovox-5600/pound.png Binary files differdeleted file mode 100644 index 90df1fa48..000000000 --- a/simulator/app/assets/htc-audiovox-5600/pound.png +++ /dev/null diff --git a/simulator/app/assets/htc-audiovox-5600/select.png b/simulator/app/assets/htc-audiovox-5600/select.png Binary files differdeleted file mode 100644 index 509082c64..000000000 --- a/simulator/app/assets/htc-audiovox-5600/select.png +++ /dev/null diff --git a/simulator/app/assets/htc-audiovox-5600/soft-left.png b/simulator/app/assets/htc-audiovox-5600/soft-left.png Binary files differdeleted file mode 100644 index ce8cc5c6e..000000000 --- a/simulator/app/assets/htc-audiovox-5600/soft-left.png +++ /dev/null diff --git a/simulator/app/assets/htc-audiovox-5600/soft-right.png b/simulator/app/assets/htc-audiovox-5600/soft-right.png Binary files differdeleted file mode 100644 index f3c76c7b8..000000000 --- a/simulator/app/assets/htc-audiovox-5600/soft-right.png +++ /dev/null diff --git a/simulator/app/assets/htc-audiovox-5600/star.png b/simulator/app/assets/htc-audiovox-5600/star.png Binary files differdeleted file mode 100644 index 19aa0575b..000000000 --- a/simulator/app/assets/htc-audiovox-5600/star.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/0.png b/simulator/app/assets/htc-tornado/0.png Binary files differdeleted file mode 100644 index a40e89859..000000000 --- a/simulator/app/assets/htc-tornado/0.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/1.png b/simulator/app/assets/htc-tornado/1.png Binary files differdeleted file mode 100644 index 92c678223..000000000 --- a/simulator/app/assets/htc-tornado/1.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/2.png b/simulator/app/assets/htc-tornado/2.png Binary files differdeleted file mode 100644 index 42a79ecd5..000000000 --- a/simulator/app/assets/htc-tornado/2.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/3.png b/simulator/app/assets/htc-tornado/3.png Binary files differdeleted file mode 100644 index 7e685a803..000000000 --- a/simulator/app/assets/htc-tornado/3.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/4.png b/simulator/app/assets/htc-tornado/4.png Binary files differdeleted file mode 100644 index c1b8060d3..000000000 --- a/simulator/app/assets/htc-tornado/4.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/5.png b/simulator/app/assets/htc-tornado/5.png Binary files differdeleted file mode 100644 index 29d2607e7..000000000 --- a/simulator/app/assets/htc-tornado/5.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/6.png b/simulator/app/assets/htc-tornado/6.png Binary files differdeleted file mode 100644 index 509aae541..000000000 --- a/simulator/app/assets/htc-tornado/6.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/7.png b/simulator/app/assets/htc-tornado/7.png Binary files differdeleted file mode 100644 index 16087778b..000000000 --- a/simulator/app/assets/htc-tornado/7.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/8.png b/simulator/app/assets/htc-tornado/8.png Binary files differdeleted file mode 100644 index 9fac3e6ad..000000000 --- a/simulator/app/assets/htc-tornado/8.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/9.png b/simulator/app/assets/htc-tornado/9.png Binary files differdeleted file mode 100644 index 6a357cb03..000000000 --- a/simulator/app/assets/htc-tornado/9.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/arrow-down.png b/simulator/app/assets/htc-tornado/arrow-down.png Binary files differdeleted file mode 100644 index c00787f30..000000000 --- a/simulator/app/assets/htc-tornado/arrow-down.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/arrow-left.png b/simulator/app/assets/htc-tornado/arrow-left.png Binary files differdeleted file mode 100644 index 1180a94aa..000000000 --- a/simulator/app/assets/htc-tornado/arrow-left.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/arrow-right.png b/simulator/app/assets/htc-tornado/arrow-right.png Binary files differdeleted file mode 100644 index 6a511d225..000000000 --- a/simulator/app/assets/htc-tornado/arrow-right.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/arrow-up.png b/simulator/app/assets/htc-tornado/arrow-up.png Binary files differdeleted file mode 100644 index da508713d..000000000 --- a/simulator/app/assets/htc-tornado/arrow-up.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/back.png b/simulator/app/assets/htc-tornado/back.png Binary files differdeleted file mode 100644 index d12273d67..000000000 --- a/simulator/app/assets/htc-tornado/back.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/background.png b/simulator/app/assets/htc-tornado/background.png Binary files differdeleted file mode 100644 index 09169b85c..000000000 --- a/simulator/app/assets/htc-tornado/background.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/home.png b/simulator/app/assets/htc-tornado/home.png Binary files differdeleted file mode 100644 index 90775a8c6..000000000 --- a/simulator/app/assets/htc-tornado/home.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/internet.png b/simulator/app/assets/htc-tornado/internet.png Binary files differdeleted file mode 100644 index 47f1bb48f..000000000 --- a/simulator/app/assets/htc-tornado/internet.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/layout.xml b/simulator/app/assets/htc-tornado/layout.xml deleted file mode 100644 index 55c1d6546..000000000 --- a/simulator/app/assets/htc-tornado/layout.xml +++ /dev/null @@ -1,64 +0,0 @@ -<?xml version="1.0" ?> -<!-- Copyright 2005 The Android Open Source Project --> - -<device name="HTC_Tornado"> - <!-- title for menus --> - <title>HTC Tornado</title> - - <!-- primary display characteristics --> - <display name="main" width="240" height="320" format="rgb565" refresh="30"/> - - <!-- display is 33.84mm x 45.12mm --> - - <mode name="default"> - <view display="main" x="58" y="117" rotate="0"> - - <!-- surrounding device image and "patches", drawn in order --> - <!-- (phone image is optional) --> - <image src="background.png" x="0" y="0"/> - - <!-- buttons for which we have highlight images --> - <button keyCode="soft-left" src="soft-left.png" x="49" y="450"/> - <button keyCode="soft-right" src="soft-right.png" x="249" y="450"/> - <button keyCode="home" src="home.png" x="115" y="450"/> - <button keyCode="back" src="back.png" x="182" y="450"/> - <button keyCode="dpad-up" src="arrow-up.png" x="159" y="542"/> - <button keyCode="dpad-down" src="arrow-down.png" x="160" y="573"/> - <button keyCode="dpad-left" src="arrow-left.png" x="152" y="549"/> - <button keyCode="dpad-right" src="arrow-right.png" x="183" y="549"/> - <button keyCode="dpad-center" src="select.png" x="167" y="556"/> - - <button keyCode="1" src="1.png" x="51" y="595"/> - <button keyCode="2" src="2.png" x="133" y="595"/> - <button keyCode="3" src="3.png" x="221" y="595"/> - <button keyCode="4" src="4.png" x="51" y="633"/> - <button keyCode="5" src="5.png" x="133" y="633"/> - <button keyCode="6" src="6.png" x="221" y="633"/> - <button keyCode="7" src="7.png" x="51" y="666"/> - <button keyCode="8" src="8.png" x="133" y="666"/> - <button keyCode="9" src="9.png" x="221" y="666"/> - <button keyCode="0" src="0.png" x="133" y="699"/> - <button keyCode="star" src="star.png" x="51" y="699"/> - <button keyCode="pound" src="pound.png" x="221" y="699"/> - - <button keyCode="phone-dial" src="phone-dial.png" x="51" y="547"/> - <button keyCode="phone-hangup" src="phone-hangup.png" x="221" y="547"/> - - <button keyCode="internet" src="internet.png" x="52" y="490"/> - <button keyCode="skip-backward" src="skip-backward.png" x="121" y="490"/> - <button keyCode="pause-play" src="pause-play.png" x="191" y="490"/> - <button keyCode="skip-forward" src="skip-forward.png" x="260" y="490"/> - - - <!-- buttons we haven't bothered to create highlight images for, - or that aren't visible on-screen --> - <button keyCode="volume-up"/> - <button keyCode="volume-down"/> - <button keyCode="power"/> - <button keyCode="clear"/> - - </view> - </mode> - -</device> - diff --git a/simulator/app/assets/htc-tornado/pause-play.png b/simulator/app/assets/htc-tornado/pause-play.png Binary files differdeleted file mode 100644 index ae74d9fd7..000000000 --- a/simulator/app/assets/htc-tornado/pause-play.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/phone-dial.png b/simulator/app/assets/htc-tornado/phone-dial.png Binary files differdeleted file mode 100644 index 30bdf9e0f..000000000 --- a/simulator/app/assets/htc-tornado/phone-dial.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/phone-hangup.png b/simulator/app/assets/htc-tornado/phone-hangup.png Binary files differdeleted file mode 100644 index 68fe47b17..000000000 --- a/simulator/app/assets/htc-tornado/phone-hangup.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/pound.png b/simulator/app/assets/htc-tornado/pound.png Binary files differdeleted file mode 100644 index 92e49cb6b..000000000 --- a/simulator/app/assets/htc-tornado/pound.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/select.png b/simulator/app/assets/htc-tornado/select.png Binary files differdeleted file mode 100644 index a89db9a72..000000000 --- a/simulator/app/assets/htc-tornado/select.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/skip-backward.png b/simulator/app/assets/htc-tornado/skip-backward.png Binary files differdeleted file mode 100644 index 263b3d6cf..000000000 --- a/simulator/app/assets/htc-tornado/skip-backward.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/skip-forward.png b/simulator/app/assets/htc-tornado/skip-forward.png Binary files differdeleted file mode 100644 index e069db144..000000000 --- a/simulator/app/assets/htc-tornado/skip-forward.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/soft-left.png b/simulator/app/assets/htc-tornado/soft-left.png Binary files differdeleted file mode 100644 index ab6dff19a..000000000 --- a/simulator/app/assets/htc-tornado/soft-left.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/soft-right.png b/simulator/app/assets/htc-tornado/soft-right.png Binary files differdeleted file mode 100644 index 590982e29..000000000 --- a/simulator/app/assets/htc-tornado/soft-right.png +++ /dev/null diff --git a/simulator/app/assets/htc-tornado/star.png b/simulator/app/assets/htc-tornado/star.png Binary files differdeleted file mode 100644 index 9b7d79a2e..000000000 --- a/simulator/app/assets/htc-tornado/star.png +++ /dev/null diff --git a/simulator/app/assets/motorola-q/back.png b/simulator/app/assets/motorola-q/back.png Binary files differdeleted file mode 100644 index 6be251282..000000000 --- a/simulator/app/assets/motorola-q/back.png +++ /dev/null diff --git a/simulator/app/assets/motorola-q/background.png b/simulator/app/assets/motorola-q/background.png Binary files differdeleted file mode 100644 index d9b30adf7..000000000 --- a/simulator/app/assets/motorola-q/background.png +++ /dev/null diff --git a/simulator/app/assets/motorola-q/down.png b/simulator/app/assets/motorola-q/down.png Binary files differdeleted file mode 100644 index bbe3a188d..000000000 --- a/simulator/app/assets/motorola-q/down.png +++ /dev/null diff --git a/simulator/app/assets/motorola-q/end.png b/simulator/app/assets/motorola-q/end.png Binary files differdeleted file mode 100644 index daff1630e..000000000 --- a/simulator/app/assets/motorola-q/end.png +++ /dev/null diff --git a/simulator/app/assets/motorola-q/home.png b/simulator/app/assets/motorola-q/home.png Binary files differdeleted file mode 100644 index 4f65f9123..000000000 --- a/simulator/app/assets/motorola-q/home.png +++ /dev/null diff --git a/simulator/app/assets/motorola-q/layout.xml b/simulator/app/assets/motorola-q/layout.xml deleted file mode 100644 index c48bce651..000000000 --- a/simulator/app/assets/motorola-q/layout.xml +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0" ?> -<!-- Copyright 2006 The Android Open Source Project --> - -<device name="MotorolaQ"> - <!-- title for menus --> - <title>Motorola Q</title> - - <display name="main" width="320" height="240" format="rgb565" refresh="30"/> - - <keyboard qwerty="1" /> - - <mode name="default"> - <!-- hiptop when closed --> - <view display="main" x="58" y="121" rotate="0"> - - <!-- surrounding device image and "patches", drawn in order --> - <image src="background.png" x="0" y="0"/> - - <!-- buttons for which we have highlight images --> - <button keyCode="soft-left" src="menu-left.png" x="35" y="385"/> - <button keyCode="soft-right" src="menu-right.png" x="270" y="385"/> - <button keyCode="home" src="home.png" x="92" y="425"/> - <button keyCode="back" src="back.png" x="264" y="425"/> - <button keyCode="dpad-up" src="up.png" x="166" y="400"/> - <button keyCode="dpad-down" src="down.png" x="166" y="444"/> - <button keyCode="dpad-left" src="left.png" x="158" y="406"/> - <button keyCode="dpad-right" src="right.png" x="224" y="406"/> - <button keyCode="dpad-center" src="select.png" x="194" y="419"/> - - <button keyCode="phone-dial" src="send.png" x="35" y="421"/> - <button keyCode="phone-hangup" src="end.png" x="333" y="422"/> - </view> - </mode> - -</device> - diff --git a/simulator/app/assets/motorola-q/left.png b/simulator/app/assets/motorola-q/left.png Binary files differdeleted file mode 100644 index 3204f9b4f..000000000 --- a/simulator/app/assets/motorola-q/left.png +++ /dev/null diff --git a/simulator/app/assets/motorola-q/menu-left.png b/simulator/app/assets/motorola-q/menu-left.png Binary files differdeleted file mode 100644 index 4d1bc11c2..000000000 --- a/simulator/app/assets/motorola-q/menu-left.png +++ /dev/null diff --git a/simulator/app/assets/motorola-q/menu-right.png b/simulator/app/assets/motorola-q/menu-right.png Binary files differdeleted file mode 100644 index 58f31c6df..000000000 --- a/simulator/app/assets/motorola-q/menu-right.png +++ /dev/null diff --git a/simulator/app/assets/motorola-q/right.png b/simulator/app/assets/motorola-q/right.png Binary files differdeleted file mode 100644 index b6190c9a0..000000000 --- a/simulator/app/assets/motorola-q/right.png +++ /dev/null diff --git a/simulator/app/assets/motorola-q/select.png b/simulator/app/assets/motorola-q/select.png Binary files differdeleted file mode 100644 index 343fb45a1..000000000 --- a/simulator/app/assets/motorola-q/select.png +++ /dev/null diff --git a/simulator/app/assets/motorola-q/send.png b/simulator/app/assets/motorola-q/send.png Binary files differdeleted file mode 100644 index b3ebcd50d..000000000 --- a/simulator/app/assets/motorola-q/send.png +++ /dev/null diff --git a/simulator/app/assets/motorola-q/up.png b/simulator/app/assets/motorola-q/up.png Binary files differdeleted file mode 100644 index 7df6736f5..000000000 --- a/simulator/app/assets/motorola-q/up.png +++ /dev/null diff --git a/simulator/app/assets/panasonic-x70/arrow-down.png b/simulator/app/assets/panasonic-x70/arrow-down.png Binary files differdeleted file mode 100644 index 7ab16b4a4..000000000 --- a/simulator/app/assets/panasonic-x70/arrow-down.png +++ /dev/null diff --git a/simulator/app/assets/panasonic-x70/arrow-up.png b/simulator/app/assets/panasonic-x70/arrow-up.png Binary files differdeleted file mode 100644 index 6fb2454bb..000000000 --- a/simulator/app/assets/panasonic-x70/arrow-up.png +++ /dev/null diff --git a/simulator/app/assets/panasonic-x70/back.png b/simulator/app/assets/panasonic-x70/back.png Binary files differdeleted file mode 100644 index 04b91ef01..000000000 --- a/simulator/app/assets/panasonic-x70/back.png +++ /dev/null diff --git a/simulator/app/assets/panasonic-x70/background.png b/simulator/app/assets/panasonic-x70/background.png Binary files differdeleted file mode 100644 index 25bc3ebea..000000000 --- a/simulator/app/assets/panasonic-x70/background.png +++ /dev/null diff --git a/simulator/app/assets/panasonic-x70/home.png b/simulator/app/assets/panasonic-x70/home.png Binary files differdeleted file mode 100644 index 12ac7bb99..000000000 --- a/simulator/app/assets/panasonic-x70/home.png +++ /dev/null diff --git a/simulator/app/assets/panasonic-x70/layout.xml b/simulator/app/assets/panasonic-x70/layout.xml deleted file mode 100644 index 0cb8bbdb4..000000000 --- a/simulator/app/assets/panasonic-x70/layout.xml +++ /dev/null @@ -1,50 +0,0 @@ -<?xml version="1.0" ?> -<!-- Copyright 2005 The Android Open Source Project --> - -<device name="PanasonicX70"> - <!-- title for menus --> - <title>Panasonic X70</title> - - <display name="main" width="176" height="220" format="rgb565" refresh="30"/> - - <mode name="default"> - <!-- primary display characteristics --> - <view display="main" x="39" y="43" rotate="0"> - - <!-- surrounding device image and "patches", drawn in order --> - <!-- (phone image is optional) --> - <image src="background.png" x="0" y="0"/> - - <button keyCode="soft-left" src="soft-left.png" x="45" y="324"/> - <button keyCode="soft-right" src="soft-right.png" x="146" y="324"/> - <button keyCode="home" src="home.png" x="21" y="345"/> - <button keyCode="back" src="back.png" x="180" y="347"/> - <button keyCode="dpad-up" src="arrow-up.png" x="88" y="348"/> - <button keyCode="dpad-down" src="arrow-down.png" x="95" y="414"/> - <button keyCode="dpad-left"/> - <button keyCode="dpad-right"/> - <button keyCode="dpad-center" src="select.png" x="101" y="377"/> - - <button keyCode="1"/> - <button keyCode="2"/> - <button keyCode="3"/> - <button keyCode="4"/> - <button keyCode="5"/> - <button keyCode="6"/> - <button keyCode="7"/> - <button keyCode="8"/> - <button keyCode="9"/> - <button keyCode="0"/> - <button keyCode="star"/> - <button keyCode="pound"/> - - <button keyCode="volume-up"/> - <button keyCode="volume-down"/> - <button keyCode="power"/> - <button keyCode="clear"/> - - </view> - </mode> - -</device> - diff --git a/simulator/app/assets/panasonic-x70/select.png b/simulator/app/assets/panasonic-x70/select.png Binary files differdeleted file mode 100644 index 993ecad72..000000000 --- a/simulator/app/assets/panasonic-x70/select.png +++ /dev/null diff --git a/simulator/app/assets/panasonic-x70/soft-left.png b/simulator/app/assets/panasonic-x70/soft-left.png Binary files differdeleted file mode 100644 index c384bb7e5..000000000 --- a/simulator/app/assets/panasonic-x70/soft-left.png +++ /dev/null diff --git a/simulator/app/assets/panasonic-x70/soft-right.png b/simulator/app/assets/panasonic-x70/soft-right.png Binary files differdeleted file mode 100644 index 948e40f6f..000000000 --- a/simulator/app/assets/panasonic-x70/soft-right.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/0.png b/simulator/app/assets/samsung-flip-2005/0.png Binary files differdeleted file mode 100644 index 839e6d1ad..000000000 --- a/simulator/app/assets/samsung-flip-2005/0.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/1.png b/simulator/app/assets/samsung-flip-2005/1.png Binary files differdeleted file mode 100644 index 499cf6c8b..000000000 --- a/simulator/app/assets/samsung-flip-2005/1.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/2.png b/simulator/app/assets/samsung-flip-2005/2.png Binary files differdeleted file mode 100644 index 93207cc26..000000000 --- a/simulator/app/assets/samsung-flip-2005/2.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/3.png b/simulator/app/assets/samsung-flip-2005/3.png Binary files differdeleted file mode 100644 index 499efdb2e..000000000 --- a/simulator/app/assets/samsung-flip-2005/3.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/4.png b/simulator/app/assets/samsung-flip-2005/4.png Binary files differdeleted file mode 100644 index 775b15ddb..000000000 --- a/simulator/app/assets/samsung-flip-2005/4.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/5.png b/simulator/app/assets/samsung-flip-2005/5.png Binary files differdeleted file mode 100644 index b8a57236a..000000000 --- a/simulator/app/assets/samsung-flip-2005/5.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/6.png b/simulator/app/assets/samsung-flip-2005/6.png Binary files differdeleted file mode 100644 index b6e0de968..000000000 --- a/simulator/app/assets/samsung-flip-2005/6.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/7.png b/simulator/app/assets/samsung-flip-2005/7.png Binary files differdeleted file mode 100644 index 541618626..000000000 --- a/simulator/app/assets/samsung-flip-2005/7.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/8.png b/simulator/app/assets/samsung-flip-2005/8.png Binary files differdeleted file mode 100644 index 2dfcae34e..000000000 --- a/simulator/app/assets/samsung-flip-2005/8.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/9.png b/simulator/app/assets/samsung-flip-2005/9.png Binary files differdeleted file mode 100644 index 6c11eed87..000000000 --- a/simulator/app/assets/samsung-flip-2005/9.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/abc.png b/simulator/app/assets/samsung-flip-2005/abc.png Binary files differdeleted file mode 100644 index 9f43afec7..000000000 --- a/simulator/app/assets/samsung-flip-2005/abc.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/arrow-down.png b/simulator/app/assets/samsung-flip-2005/arrow-down.png Binary files differdeleted file mode 100644 index 0f7ea7b38..000000000 --- a/simulator/app/assets/samsung-flip-2005/arrow-down.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/arrow-left.png b/simulator/app/assets/samsung-flip-2005/arrow-left.png Binary files differdeleted file mode 100644 index ad1982f60..000000000 --- a/simulator/app/assets/samsung-flip-2005/arrow-left.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/arrow-right.png b/simulator/app/assets/samsung-flip-2005/arrow-right.png Binary files differdeleted file mode 100644 index bf9cf48ba..000000000 --- a/simulator/app/assets/samsung-flip-2005/arrow-right.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/arrow-up.png b/simulator/app/assets/samsung-flip-2005/arrow-up.png Binary files differdeleted file mode 100644 index ab62e33a3..000000000 --- a/simulator/app/assets/samsung-flip-2005/arrow-up.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/back-background.png b/simulator/app/assets/samsung-flip-2005/back-background.png Binary files differdeleted file mode 100644 index 741db99ea..000000000 --- a/simulator/app/assets/samsung-flip-2005/back-background.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/back.png b/simulator/app/assets/samsung-flip-2005/back.png Binary files differdeleted file mode 100644 index 9eb9a176b..000000000 --- a/simulator/app/assets/samsung-flip-2005/back.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/background-176_208.png b/simulator/app/assets/samsung-flip-2005/background-176_208.png Binary files differdeleted file mode 100644 index 1ed124830..000000000 --- a/simulator/app/assets/samsung-flip-2005/background-176_208.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/background-176x220.png b/simulator/app/assets/samsung-flip-2005/background-176x220.png Binary files differdeleted file mode 100644 index 361304e9e..000000000 --- a/simulator/app/assets/samsung-flip-2005/background-176x220.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/clear.png b/simulator/app/assets/samsung-flip-2005/clear.png Binary files differdeleted file mode 100644 index f9c421c8f..000000000 --- a/simulator/app/assets/samsung-flip-2005/clear.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/end.png b/simulator/app/assets/samsung-flip-2005/end.png Binary files differdeleted file mode 100644 index 5d0056cb6..000000000 --- a/simulator/app/assets/samsung-flip-2005/end.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/home-background.png b/simulator/app/assets/samsung-flip-2005/home-background.png Binary files differdeleted file mode 100644 index 3ceee9c22..000000000 --- a/simulator/app/assets/samsung-flip-2005/home-background.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/home.png b/simulator/app/assets/samsung-flip-2005/home.png Binary files differdeleted file mode 100644 index 8510b7eb2..000000000 --- a/simulator/app/assets/samsung-flip-2005/home.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/layout.xml b/simulator/app/assets/samsung-flip-2005/layout.xml deleted file mode 100644 index 3bc2dddc3..000000000 --- a/simulator/app/assets/samsung-flip-2005/layout.xml +++ /dev/null @@ -1,56 +0,0 @@ -<?xml version="1.0" ?> -<!-- Copyright 2005 The Android Open Source Project --> - -<device name="Samsung1234"> - <!-- title for menus --> - <title>Samsung Flip Phone</title> - - <!-- primary display characteristics --> - <display name="main" width="176" height="220" format="rgb565" refresh="30"/> - - <mode name="default"> - <!-- our view of the device that shows the main display --> - <view display="main" x="49" y="73" rotate="0"> - - <!-- surrounding device image and "patches", drawn in order --> - <!-- (phone image is optional) --> - <image src="background-176x220.png" x="0" y="0"/> - <image src="home-background.png" x="22" y="426"/> - <image src="back-background.png" x="179" y="426"/> - - <!-- buttons for which we have highlight images --> - <button keyCode="soft-left" src="soft-left.png" x="24" y="388"/> - <button keyCode="soft-right" src="soft-right.png" x="182" y="388"/> - <button keyCode="home" src="home.png" x="22" y="426"/> - <button keyCode="back" src="back.png" x="179" y="426"/> - <button keyCode="dpad-up" src="arrow-up.png" x="99" y="399"/> - <button keyCode="dpad-down" src="arrow-down.png" x="99" y="461"/> - <button keyCode="dpad-left" src="arrow-left.png" x="82" y="411"/> - <button keyCode="dpad-right" src="arrow-right.png" x="147" y="411"/> - <button keyCode="dpad-center" src="select.png" x="115" y="431"/> - - <button keyCode="1" src="1.png" x="24" y="533"/> - <button keyCode="2" src="2.png" x="94" y="544"/> - <button keyCode="3" src="3.png" x="173" y="534"/> - <button keyCode="4" src="4.png" x="25" y="576"/> - <button keyCode="5" src="5.png" x="94" y="581"/> - <button keyCode="6" src="6.png" x="172" y="576"/> - <button keyCode="7" src="7.png" x="27" y="619"/> - <button keyCode="8" src="8.png" x="95" y="621"/> - <button keyCode="9" src="9.png" x="168" y="620"/> - <button keyCode="0" src="0.png" x="96" y="658"/> - <button keyCode="star" src="star.png" x="31" y="659"/> - <button keyCode="pound" src="pound.png" x="169" y="659"/> - - <!-- buttons we haven't bothered to create highlight images for, - or that aren't visible on-screen --> - <button keyCode="volume-up"/> - <button keyCode="volume-down"/> - <button keyCode="power"/> - <button keyCode="clear"/> - - </view> - </mode> - -</device> - diff --git a/simulator/app/assets/samsung-flip-2005/menu.png b/simulator/app/assets/samsung-flip-2005/menu.png Binary files differdeleted file mode 100644 index 7ac077c3a..000000000 --- a/simulator/app/assets/samsung-flip-2005/menu.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/pound.png b/simulator/app/assets/samsung-flip-2005/pound.png Binary files differdeleted file mode 100644 index 22440bc7a..000000000 --- a/simulator/app/assets/samsung-flip-2005/pound.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/select.png b/simulator/app/assets/samsung-flip-2005/select.png Binary files differdeleted file mode 100644 index 1c735f85d..000000000 --- a/simulator/app/assets/samsung-flip-2005/select.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/send.png b/simulator/app/assets/samsung-flip-2005/send.png Binary files differdeleted file mode 100644 index 23cea52e5..000000000 --- a/simulator/app/assets/samsung-flip-2005/send.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/soft-left.png b/simulator/app/assets/samsung-flip-2005/soft-left.png Binary files differdeleted file mode 100644 index 224d28145..000000000 --- a/simulator/app/assets/samsung-flip-2005/soft-left.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/soft-right.png b/simulator/app/assets/samsung-flip-2005/soft-right.png Binary files differdeleted file mode 100644 index a8eec973a..000000000 --- a/simulator/app/assets/samsung-flip-2005/soft-right.png +++ /dev/null diff --git a/simulator/app/assets/samsung-flip-2005/star.png b/simulator/app/assets/samsung-flip-2005/star.png Binary files differdeleted file mode 100644 index 457348dbc..000000000 --- a/simulator/app/assets/samsung-flip-2005/star.png +++ /dev/null diff --git a/simulator/app/help/unnamed.htb b/simulator/app/help/unnamed.htb Binary files differdeleted file mode 100644 index 3933e6955..000000000 --- a/simulator/app/help/unnamed.htb +++ /dev/null diff --git a/simulator/wrapsim/Android.mk b/simulator/wrapsim/Android.mk deleted file mode 100644 index ca9a5928c..000000000 --- a/simulator/wrapsim/Android.mk +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright 2007 The Android Open Source Project - -# -# Build instructions for simulator LD_PRELOAD wrapper. -# -ifneq ($(TARGET_ARCH),arm) -ifeq ($(TARGET_SIMULATOR),true) - -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - BitVector.c \ - DevAudio.c \ - DevConsoleTty.c \ - DevEvent.c \ - DevFb.c \ - DevLog.c \ - DevPower.c \ - DevVibrator.c \ - FakeDev.c \ - Init.c \ - Intercept.c \ - Log.c \ - SimMgr.c - -LOCAL_C_INCLUDES += prebuilt/common/esd - -LOCAL_MODULE := libwrapsim - -# Relying on other Android libraries is probably a bad idea, since any -# library or system calls they make could lead to recursive behavior. -LOCAL_LDLIBS += -lpthread -ldl - -ifeq ($(BUILD_SIM_WITHOUT_AUDIO),true) -LOCAL_CFLAGS += -DBUILD_SIM_WITHOUT_AUDIO=1 -else -LOCAL_LDLIBS += -lesd -endif - -include $(BUILD_SHARED_LIBRARY) - - - -# -# Build instructions for simulator runtime launch wrapper. -# -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - LaunchWrapper.c - -LOCAL_MODULE := launch-wrapper -include $(BUILD_EXECUTABLE) - -endif # ifeq ($(TARGET_SIMULATOR),true) -endif -# ifneq ($(TARGET_ARCH),arm) diff --git a/simulator/wrapsim/BitVector.c b/simulator/wrapsim/BitVector.c deleted file mode 100644 index aaa14085e..000000000 --- a/simulator/wrapsim/BitVector.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2007 The Android Open Source Project - * - * Simple bit vector. - */ -#include "Common.h" - -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <assert.h> - -#define kBitVectorGrowth 4 /* increase by 4 uint32_t when limit hit */ - - -/* - * Allocate a bit vector with enough space to hold at least the specified - * number of bits. - */ -BitVector* wsAllocBitVector(int startBits, int isExpandable) -{ - BitVector* bv; - int count; - - assert(sizeof(bv->storage[0]) == 4); /* assuming 32-bit units */ - assert(startBits > 0); - - bv = (BitVector*) malloc(sizeof(BitVector)); - - count = (startBits + 31) >> 5; - - bv->storageSize = count; - bv->isExpandable = isExpandable; - bv->storage = (uint32_t*) malloc(count * sizeof(uint32_t)); - memset(bv->storage, 0xff, count * sizeof(uint32_t)); - return bv; -} - -/* - * Free a BitVector. - */ -void wsFreeBitVector(BitVector* pBits) -{ - if (pBits == NULL) - return; - - free(pBits->storage); - free(pBits); -} - -/* - * "Allocate" the first-available bit in the bitmap. - * - * This is not synchronized. The caller is expected to hold some sort of - * lock that prevents multiple threads from executing simultaneously in - * dvmAllocBit/dvmFreeBit. - * - * The bitmap indicates which resources are free, so we use '1' to indicate - * available and '0' to indicate allocated. - */ -int wsAllocBit(BitVector* pBits) -{ - int word, bit; - -retry: - for (word = 0; word < pBits->storageSize; word++) { - if (pBits->storage[word] != 0) { - /* - * There are unallocated bits in this word. Return the first. - */ - bit = ffs(pBits->storage[word]) -1; - assert(bit >= 0 && bit < 32); - pBits->storage[word] &= ~(1 << bit); - return (word << 5) | bit; - } - } - - /* - * Ran out of space, allocate more if we're allowed to. - */ - if (!pBits->isExpandable) - return -1; - - pBits->storage = realloc(pBits->storage, - (pBits->storageSize + kBitVectorGrowth) * sizeof(uint32_t)); - memset(&pBits->storage[pBits->storageSize], 0xff, - kBitVectorGrowth * sizeof(uint32_t)); - pBits->storageSize += kBitVectorGrowth; - goto retry; -} - -/* - * Mark the specified bit as "free". - */ -void wsFreeBit(BitVector* pBits, int num) -{ - assert(num >= 0 && - num < (int) pBits->storageSize * (int)sizeof(uint32_t) * 8); - - pBits->storage[num >> 5] |= 1 << (num & 0x1f); -} - diff --git a/simulator/wrapsim/BitVector.h b/simulator/wrapsim/BitVector.h deleted file mode 100644 index 048cf9123..000000000 --- a/simulator/wrapsim/BitVector.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2007 The Android Open Source Project - * - * Simple bit vector. - */ -#ifndef _WRAPSIM_BITVECTOR_H -#define _WRAPSIM_BITVECTOR_H - -#include <stdint.h> - -/* - * Expanding bitmap, used for tracking resources. Bits are numbered starting - * from zero. - */ -typedef struct BitVector { - int isExpandable; /* expand bitmap if we run out? */ - int storageSize; /* current size, in 32-bit words */ - uint32_t* storage; -} BitVector; - -/* allocate a bit vector with enough space to hold "startBits" bits */ -BitVector* wsAllocBitVector(int startBits, int isExpandable); -void wsFreeBitVector(BitVector* pBits); - -/* - * Set/clear a single bit; assumes external synchronization. - * - * We always allocate the first possible bit. If we run out of space in - * the bitmap, and it's not marked expandable, dvmAllocBit returns -1. - */ -int wsAllocBit(BitVector* pBits); -void wsFreeBit(BitVector* pBits, int num); - -#endif /*_WRAPSIM_BITVECTOR_H*/ diff --git a/simulator/wrapsim/Common.h b/simulator/wrapsim/Common.h deleted file mode 100644 index a9c3bb847..000000000 --- a/simulator/wrapsim/Common.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2007 The Android Open Source Project - * - * Common defines and includes. - */ -#ifndef _WRAPSIM_COMMON_H -#define _WRAPSIM_COMMON_H - -#include <unistd.h> -#include <sys/types.h> - -#include "BitVector.h" -#include "FakeDev.h" -#include "Log.h" -#include "SimMgr.h" -#include "Globals.h" - -#endif /*_WRAPSIM_COMMON_H*/ diff --git a/simulator/wrapsim/DevAudio.c b/simulator/wrapsim/DevAudio.c deleted file mode 100644 index 752ee6534..000000000 --- a/simulator/wrapsim/DevAudio.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2007 The Android Open Source Project - * - * Audio output device. - */ -#include "Common.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <esd.h> - -#include <fcntl.h> -#include <sys/ioctl.h> -#include <linux/input.h> - - -/* - * Input event device state. - */ -typedef struct AudioState { - int fd; - int sourceId; - int esdVol; - int streamType; -} AudioState; - -/* - * Set some stuff up. - */ -static int configureInitialState(const char* pathName, AudioState* audioState) -{ -#if BUILD_SIM_WITHOUT_AUDIO - return 0; -#else - esd_player_info_t *pi; - audioState->fd = -1; - audioState->sourceId = -1; - audioState->esdVol = -1; - audioState->streamType = 0; - - int format = ESD_BITS16 | ESD_STEREO | ESD_STREAM | ESD_PLAY; - char namestring[] = "Android Audio XXXXXXXX"; - sprintf(namestring,"Android Audio %08x", (unsigned int)audioState); - int esd_fd = esd_play_stream_fallback(format, 44100, NULL, namestring); - if (esd_fd > 0) { - // find the source_id for this stream - int mix = esd_open_sound(NULL); - if (mix > 0) { - esd_info_t *info = esd_get_all_info(mix); - - if (info) { - for(pi = info->player_list; pi; pi = pi->next) { - if(strcmp(pi->name, namestring) == 0) { - audioState->sourceId = pi->source_id; - break; - } - } - esd_free_all_info(info); - } - esd_close(mix); - } - audioState->fd = esd_fd; - return 0; - } - printf("Couldn't open audio device. Faking it.\n"); - return 0; -#endif -} - -/* - * Return the next available input event. - * - * We just pass this through to the real "write", since "fd" is real. - */ -static ssize_t writeAudio(FakeDev* dev, int fd, const void* buf, size_t count) -{ -#if BUILD_SIM_WITHOUT_AUDIO - return 0; -#else - AudioState *state = (AudioState*)dev->state; - if (state->fd >= 0) - return _ws_write(state->fd, buf, count); - - // fake timing - usleep(count * 10000 / 441 * 4); - return count; -#endif -} - -/* - * Handle event ioctls. - */ -static int ioctlAudio(FakeDev* dev, int fd, int request, void* argp) -{ - return -1; -} - -/* - * Free up our state before closing down the fake descriptor. - */ -static int closeAudio(FakeDev* dev, int fd) -{ -#if BUILD_SIM_WITHOUT_AUDIO - return 0; -#else - AudioState *state = (AudioState*)dev->state; - close(state->fd); - free(state); - dev->state = NULL; - return 0; -#endif -} - -/* - * Open an audio output device. - */ -FakeDev* wsOpenDevAudio(const char* pathName, int flags) -{ - FakeDev* newDev = wsCreateFakeDev(pathName); - if (newDev != NULL) { - newDev->write = writeAudio; - newDev->ioctl = ioctlAudio; - newDev->close = closeAudio; - - AudioState* eventState = calloc(1, sizeof(AudioState)); - - if (configureInitialState(pathName, eventState) != 0) { - free(eventState); - return NULL; - } - newDev->state = eventState; - } - - return newDev; -} diff --git a/simulator/wrapsim/DevConsoleTty.c b/simulator/wrapsim/DevConsoleTty.c deleted file mode 100644 index 166d6489e..000000000 --- a/simulator/wrapsim/DevConsoleTty.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2007 The Android Open Source Project - * - * Console tty device. - */ -#include "Common.h" - -#include <string.h> - -#include <sys/ioctl.h> -#include <linux/vt.h> - - -/* - * Handle the various console ioctls, most of which we can just ignore. - */ -static int ioctlConsoleTty(FakeDev* dev, int fd, int request, void* argp) -{ - wsLog("%s: ioctl(0x%x, %p)\n", dev->debugName, request, argp); - switch (request) { - case VT_GETSTATE: // struct vt_stat* - /* - * Looks like they want vs.v_active. This just gets fed back into - * another console ioctl, so we don't really need to do anything. - * We zero out the struct so the data will at least appear to be - * initialized. - */ - memset(argp, 0, sizeof(struct vt_stat)); - break; - case VT_OPENQRY: // int* - /* they want the console number */ - *(int*)argp = 123; - break; - default: - /* ignore anything we don't understand */ - break; - } - - return 0; -} - -/* - * Open the console TTY device, which responds to a collection of ioctl()s. - */ -FakeDev* wsOpenDevConsoleTty(const char* pathName, int flags) -{ - FakeDev* newDev = wsCreateFakeDev(pathName); - if (newDev != NULL) { - newDev->ioctl = ioctlConsoleTty; - } - return newDev; -} - diff --git a/simulator/wrapsim/DevEvent.c b/simulator/wrapsim/DevEvent.c deleted file mode 100644 index 692856ecd..000000000 --- a/simulator/wrapsim/DevEvent.c +++ /dev/null @@ -1,414 +0,0 @@ -/* - * Copyright 2007 The Android Open Source Project - * - * Input event device. - */ -#include "Common.h" - -#include <stdlib.h> -#include <string.h> - -#include <fcntl.h> -#include <sys/ioctl.h> -#include <linux/input.h> - - -/* - * Input event device state. - */ -typedef struct EventState { - struct input_id ident; - - char* name; - char* location; - char* idstr; - int protoVersion; -} EventState; - -/* - * Key bit mask, for EVIOCGBIT(EV_KEY). - * - * (For now, just pretend to be a "goldfish" like the emulator.) - */ -static const unsigned char gKeyBitMask[64] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -}; - -/* - * Set some stuff up. - */ -static void configureInitialState(const char* pathName, EventState* eventState) -{ - /* - * Swim like a goldfish. - */ - eventState->ident.bustype = 0; - eventState->ident.vendor = 0; - eventState->ident.product = 0; - eventState->ident.version = 0; - - eventState->name = strdup(gWrapSim.keyMap); - eventState->location = strdup(""); - eventState->idstr = strdup(""); - eventState->protoVersion = 0x010000; -} - -/* - * Free up the state structure. - */ -static void freeState(EventState* eventState) -{ - if (eventState != NULL) { - free(eventState->name); - free(eventState->location); - free(eventState->idstr); - free(eventState); - } -} - -/* - * Handle one of the EVIOCGABS requests. - * - * Currently not doing much here. - */ -static void handleAbsGet(int reqIdx, void* argp) -{ - struct input_absinfo info; - - switch (reqIdx) { - case ABS_X: - wsLog(" req for abs X\n"); - break; - case ABS_Y: - wsLog(" req for abs Y\n"); - break; - case ABS_PRESSURE: - wsLog(" req for abs PRESSURE\n"); - break; - case ABS_TOOL_WIDTH: - wsLog(" req for abs TOOL_WIDTH\n"); - break; - default: - wsLog(" req for unexpected event abs 0x%02x\n", reqIdx); - break; - } - - memset(&info, 0, sizeof(info)); - memcpy(argp, &info, sizeof(struct input_absinfo)); -} - -/* - * Return the next available input event. - * - * We just pass this through to the real "read", since "fd" is real. - */ -static ssize_t readEvent(FakeDev* dev, int fd, void* buf, size_t count) -{ - return _ws_read(fd, buf, count); -} - -/* - * Somebody is trying to write to the event pipe. This can be used to set - * the state of LED. - */ -static ssize_t writeEvent(FakeDev* dev, int fd, const void* buf, size_t count) -{ - const struct input_event* piev; - - if (count == sizeof(*piev)) { - piev = (const struct input_event*) buf; - - if (piev->type == EV_LED) { - wsLog("%s: set LED code=%d value=%d\n", - dev->debugName, piev->code, piev->value); - } else { - wsLog("%s: writeEvent got %d bytes, type=%d\n", - dev->debugName, count, piev->type); - } - } else { - wsLog("%s: warning: writeEvent got %d bytes, not sure why\n", - dev->debugName, count); - } - - return count; -} - -/* - * Handle event ioctls. - */ -static int ioctlEvent(FakeDev* dev, int fd, int request, void* argp) -{ - EventState* state = (EventState*) dev->state; - unsigned int urequest = (unsigned int) request; - - wsLog("%s: ioctl(0x%x, %p)\n", dev->debugName, urequest, argp); - - if (_IOC_TYPE(urequest) != _IOC_TYPE(EVIOCGVERSION)) { - wsLog("%s: inappropriate ioctl 0x%08x\n", dev->debugName, urequest); - return -1; - } - - if (urequest == EVIOCGVERSION) { - *(int*)argp = state->protoVersion; - } else if (urequest == EVIOCGID) { - memcpy(argp, &state->ident, sizeof(struct input_id)); - } else if (_IOC_NR(urequest) == _IOC_NR(EVIOCGNAME(0))) { - int maxLen = _IOC_SIZE(urequest); - int strLen = (int) strlen(state->name); - if (strLen >= maxLen) { - errno = EINVAL; - return -1; - } - memcpy(argp, state->name, strLen+1); - return strLen; - } else if (_IOC_NR(urequest) == _IOC_NR(EVIOCGPHYS(0))) { - int maxLen = _IOC_SIZE(urequest); - int strLen = (int) strlen(state->location); - if (strLen >= maxLen) { - errno = EINVAL; - return -1; - } - memcpy(argp, state->location, strLen+1); - return strLen; - } else if (_IOC_NR(urequest) == _IOC_NR(EVIOCGUNIQ(0))) { - /* device doesn't seem to support this, neither will we */ - return -1; - } else if (_IOC_NR(urequest) == _IOC_NR(EVIOCGBIT(EV_KEY,0))) { - /* keys */ - int maxLen = _IOC_SIZE(urequest); - if (maxLen > (int) sizeof(gKeyBitMask)) - maxLen = sizeof(gKeyBitMask); - memcpy(argp, gKeyBitMask, maxLen); - } else if (_IOC_NR(urequest) == _IOC_NR(EVIOCGBIT(EV_REL,0))) { - /* relative controllers (trackball) */ - int maxLen = _IOC_SIZE(urequest); - memset(argp, 0xff, maxLen); - } else if (!getenv("NOTOUCH") && _IOC_NR(urequest) == _IOC_NR(EVIOCGBIT(EV_ABS,0))) { - // absolute controllers (touch screen) - int maxLen = _IOC_SIZE(urequest); - memset(argp, 0xff, maxLen); - - } else if (_IOC_NR(urequest) >= _IOC_NR(EVIOCGABS(ABS_X)) && - _IOC_NR(urequest) <= _IOC_NR(EVIOCGABS(ABS_MAX))) - { - /* get abs value / limits */ - int reqIdx = _IOC_NR(urequest) - _IOC_NR(EVIOCGABS(ABS_X)); - handleAbsGet(reqIdx, argp); - } else { - wsLog("GLITCH: UNKNOWN ioctl request 0x%x on %s\n", - urequest, dev->debugName); - return -1; - } - - return 0; -} - -/* - * Free up our state before closing down the fake descriptor. - */ -static int closeEvent(FakeDev* dev, int fd) -{ - freeState((EventState*)dev->state); - dev->state = NULL; - if (gWrapSim.keyInputDevice == dev) { - gWrapSim.keyInputDevice = NULL; - wsLog("Sim input device closed\n"); - } - return 0; -} - -/* - * Open an input event device. - */ -FakeDev* wsOpenDevEvent(const char* pathName, int flags) -{ - FakeDev* newDev = wsCreateRealFakeDev(pathName); - if (newDev != NULL) { - newDev->read = readEvent; - newDev->write = writeEvent; - newDev->ioctl = ioctlEvent; - newDev->close = closeEvent; - - EventState* eventState = calloc(1, sizeof(EventState)); - - configureInitialState(pathName, eventState); - newDev->state = eventState; - - /* - * First one opened becomes the place where we queue up input - * events from the simulator. This approach will fail if the - * app opens the device, then opens it a second time for input, - * then closes the first. The app doesn't currently do this (though - * it does do quick opens to fiddle with LEDs). - */ - if (gWrapSim.keyInputDevice == NULL) { - gWrapSim.keyInputDevice = newDev; - wsLog("Device %p / %d will receive sim input events\n", - newDev, newDev->fd); - } - } - - return newDev; -} - -/* - * Write a key event. - */ -static int sendKeyEvent(FakeDev* dev, int code, int isDown) -{ - struct input_event iev; - ssize_t actual; - - gettimeofday(&iev.time, NULL); - iev.type = EV_KEY; - iev.code = code; - iev.value = (isDown != 0) ? 1 : 0; - - actual = _ws_write(dev->otherFd, &iev, sizeof(iev)); - if (actual != (ssize_t) sizeof(iev)) { - wsLog("WARNING: send key event partial write (%d of %d)\n", - actual, sizeof(iev)); - return -1; - } - - return 0; -} - -/* - * Write an absolute (touch screen) event. - */ -static int sendAbsButton(FakeDev* dev, int x, int y, int isDown) -{ - struct input_event iev; - ssize_t actual; - - wsLog("absButton x=%d y=%d down=%d\n", x, y, isDown); - - gettimeofday(&iev.time, NULL); - iev.type = EV_KEY; - iev.code = BTN_TOUCH; - iev.value = (isDown != 0) ? 1 : 0; - - actual = _ws_write(dev->otherFd, &iev, sizeof(iev)); - if (actual != (ssize_t) sizeof(iev)) { - wsLog("WARNING: send touch event partial write (%d of %d)\n", - actual, sizeof(iev)); - return -1; - } - - return 0; -} - -/* - * Write an absolute (touch screen) event. - */ -static int sendAbsMovement(FakeDev* dev, int x, int y) -{ - struct input_event iev; - ssize_t actual; - - wsLog("absMove x=%d y=%d\n", x, y); - - gettimeofday(&iev.time, NULL); - iev.type = EV_ABS; - iev.code = ABS_X; - iev.value = x; - - actual = _ws_write(dev->otherFd, &iev, sizeof(iev)); - if (actual != (ssize_t) sizeof(iev)) { - wsLog("WARNING: send abs movement event partial X write (%d of %d)\n", - actual, sizeof(iev)); - return -1; - } - - iev.code = ABS_Y; - iev.value = y; - - actual = _ws_write(dev->otherFd, &iev, sizeof(iev)); - if (actual != (ssize_t) sizeof(iev)) { - wsLog("WARNING: send abs movement event partial Y write (%d of %d)\n", - actual, sizeof(iev)); - return -1; - } - - return 0; -} - -/* - * Not quite sure what this is for, but the emulator does it. - */ -static int sendAbsSyn(FakeDev* dev) -{ - struct input_event iev; - ssize_t actual; - - gettimeofday(&iev.time, NULL); - iev.type = EV_SYN; - iev.code = 0; - iev.value = 0; - - actual = _ws_write(dev->otherFd, &iev, sizeof(iev)); - if (actual != (ssize_t) sizeof(iev)) { - wsLog("WARNING: send abs movement syn (%d of %d)\n", - actual, sizeof(iev)); - return -1; - } - - return 0; -} - -/* - * Send a key event to the fake key event device. - * - * We have to translate the simulator key event into one or more device - * key events. - */ -void wsSendSimKeyEvent(int key, int isDown) -{ - FakeDev* dev; - EventState* state; - - dev = gWrapSim.keyInputDevice; - if (dev == NULL) - return; - - sendKeyEvent(dev, key, isDown); -} - -/* - * Send a touch-screen event to the fake key event device. - * - * We have to translate the simulator key event into one or more device - * key events. - */ -void wsSendSimTouchEvent(int action, int x, int y) -{ - FakeDev* dev; - EventState* state; - - dev = gWrapSim.keyInputDevice; - if (dev == NULL) - return; - - if (action == kTouchDown) { - sendAbsMovement(dev, x, y); - sendAbsButton(dev, x, y, 1); - sendAbsSyn(dev); - } else if (action == kTouchUp) { - sendAbsButton(dev, x, y, 0); - sendAbsSyn(dev); - } else if (action == kTouchDrag) { - sendAbsMovement(dev, x, y); - sendAbsSyn(dev); - } else { - wsLog("WARNING: unexpected sim touch action %d\n", action); - } -} - diff --git a/simulator/wrapsim/DevFb.c b/simulator/wrapsim/DevFb.c deleted file mode 100644 index c54403ec9..000000000 --- a/simulator/wrapsim/DevFb.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright 2007 The Android Open Source Project - * - * Fake device support. - */ -#include "Common.h" - -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include <sys/mman.h> -#include <sys/ioctl.h> -#include <linux/fb.h> - -typedef struct FbState { - /* index into gWrapSim.display[] */ - int displayIdx; - - /* VRAM address, set by mmap() call */ - void* vramAddr; - - /* kernel data structures */ - struct fb_var_screeninfo vinfo; - struct fb_fix_screeninfo finfo; -} FbState; - - -/* - * Set up the initial values of the structs. - * - * The FbState struct is zeroed out initially, so we only need to set the - * fields that don't default to zero. - */ -static void configureInitialState(int displayIdx, FbState* fbState) -{ - int width, height; - - assert(displayIdx >= 0 && displayIdx < gWrapSim.numDisplays); - - width = gWrapSim.display[displayIdx].width; - height = gWrapSim.display[displayIdx].height; - wsLog("Configuring FbState for display %d (%dx%x key=0x%08x)\n", - displayIdx, width, height, gWrapSim.display[displayIdx].shmemKey); - - /* fb_fix_screeninfo */ - strcpy(fbState->finfo.id, "omapfb"); - fbState->finfo.smem_len = (width * 2) * height * 2; - fbState->finfo.line_length = width * 2; - - /* fb_var_screeninfo */ - fbState->vinfo.xres = width; - fbState->vinfo.yres = height; - fbState->vinfo.xres_virtual = width; - fbState->vinfo.yres_virtual = height * 2; - fbState->vinfo.bits_per_pixel = 16; - - fbState->vinfo.red.offset = 11; - fbState->vinfo.red.length = 5; - fbState->vinfo.green.offset = 5; - fbState->vinfo.green.length = 6; - fbState->vinfo.blue.offset = 0; - fbState->vinfo.blue.length = 5; - - fbState->vinfo.width = 51; // physical dimension, used for dpi - fbState->vinfo.height = 76; - - fbState->vinfo.pixclock = 103092; - fbState->vinfo.upper_margin = 3; - fbState->vinfo.lower_margin = 227; - fbState->vinfo.left_margin = 12; - fbState->vinfo.right_margin = 8; -} - -/* - * Free allocated state. - */ -static void freeState(FbState* fbState) -{ - free(fbState); -} - -/* - * Wait for our synthetic vsync to happen. - */ -static void waitForVsync(FbState* state) -{ - /* TODO: simulate a real interval */ - usleep(1000000/60); -} - -/* - * Forward pixels to the simulator. - */ -static void sendPixelsToSim(FbState* state) -{ - if (state->vramAddr == 0) { - wsLog("## not sending pixels (no addr yet)\n"); - return; - } - - //wsLog("+++ sending pixels to sim (disp=%d yoff=%d)\n", - // state->displayIdx, state->vinfo.yoffset); - - wsLockDisplay(state->displayIdx); - - uint8_t* dst = gWrapSim.display[state->displayIdx].addr; - - int l,t,r,b,w,h; - w = gWrapSim.display[state->displayIdx].width; - h = gWrapSim.display[state->displayIdx].height; - -#if 0 - /* - * TODO: surfaceflinger encodes the dirty region in vinfo.reserved[]. We - * can use that to perform a partial update. - */ - const Rect dirty(dirtyReg.bounds()); - l = dirty.left >=0 ? dirty.left : 0; - t = dirty.top >=0 ? dirty.top : 0; - r = dirty.right <=w ? dirty.right : w; - b = dirty.bottom<=h ? dirty.bottom : h; -#else - l = t = 0; - r = w; - b = h; -#endif - - /* find the right page */ - int ypage = state->vinfo.yoffset; - - int x, y; - for (y = t ; y < b ; y++) { - // no "stride" issues with this display - uint8_t* outPtr = dst + (y*w+l)*3; - const uint16_t* ptr16 = (uint16_t*)state->vramAddr + ((y+ypage)*w+l); - for (x = l; x < r; x++) { - uint16_t in = *ptr16++; - uint32_t R,G,B; - R = ((in>>8)&0xF8) | (in>>(8+5)); - G = (in & 0x7E0)>>3; - G |= G>>6; - B = (in & 0x1F)<<3; - B |= B>>5; - *outPtr++ = R; - *outPtr++ = G; - *outPtr++ = B; - } - } - - wsUnlockDisplay(state->displayIdx); - - /* notify the simulator */ - wsPostDisplayUpdate(state->displayIdx); -} - -/* - * Provide a memory-mapped region for framebuffer data. We want to use a - * real mmap() call, not fake it with a malloc, so that related calls - * (munmap, madvise) will just work. - */ -static void* mmapFb(FakeDev* dev, void* start, size_t length, int prot, - int flags, int fd, __off_t offset) -{ - FbState* state = (FbState*) dev->state; - void* map; - - /* be reasonable */ - if (length > (640*480*2)*4) { - errno = EINVAL; - return MAP_FAILED; - } - - /* this is supposed to be VRAM, so just map a chunk */ - map = mmap(start, length, prot, MAP_PRIVATE | MAP_ANON, -1, 0); - - /* update our "VRAM address"; this feels a bit fragile */ - if (state->vramAddr != NULL) { - wsLog("%s: NOTE: changing vram address from %p\n", - dev->debugName, state->vramAddr); - } - state->vramAddr = map; - - wsLog("%s: mmap %u bytes --> %p\n", dev->debugName, length, map); - return map; -} - -/* - * Handle framebuffer ioctls. - */ -static int ioctlFb(FakeDev* dev, int fd, int request, void* argp) -{ - FbState* state = (FbState*) dev->state; - - wsLog("%s: ioctl(0x%x, %p)\n", dev->debugName, request, argp); - - switch (request) { - case FBIOGET_FSCREENINFO: // struct fb_fix_screeninfo* - memcpy(argp, &state->finfo, sizeof(struct fb_fix_screeninfo)); - break; - case FBIOGET_VSCREENINFO: // struct fb_var_screeninfo* - memcpy(argp, &state->vinfo, sizeof(struct fb_var_screeninfo)); - break; - case FBIOPUT_VSCREENINFO: // struct fb_var_screeninfo* - memcpy(&state->vinfo, argp, sizeof(struct fb_var_screeninfo)); - if (state->vinfo.activate == FB_ACTIVATE_NOW) { - //wsLog("%s: activate now\n", dev->debugName); - sendPixelsToSim(state); - } else if (state->vinfo.activate == FB_ACTIVATE_VBL) { - //wsLog("%s: activate on VBL\n", dev->debugName); - sendPixelsToSim(state); - /* we wait *after* so other process gets scheduled to draw */ - waitForVsync(state); - } else { - wsLog("%s: activate value is %d\n", - dev->debugName, state->vinfo.activate); - } - break; - case FBIOGET_VBLANK: // struct fb_vblank* - /* the device doesn't actually implement this */ - //memset(argp, 0, sizeof(struct fb_vblank)); - errno = EINVAL; - return -1; - default: - /*case FBIO_WAITFORVSYNC:*/ - wsLog("GLITCH: UNKNOWN ioctl request 0x%x on %s\n", - request, dev->debugName); - return -1; - } - - return 0; -} - -/* - * Free up our state before closing down the fake descriptor. - */ -static int closeFb(FakeDev* dev, int fd) -{ - freeState((FbState*)dev->state); - dev->state = NULL; - return 0; -} - -/* - * Open the console TTY device, which responds to a collection of ioctl()s. - */ -FakeDev* wsOpenDevFb(const char* pathName, int flags) -{ - FakeDev* newDev = wsCreateFakeDev(pathName); - if (newDev != NULL) { - newDev->mmap = mmapFb; - newDev->ioctl = ioctlFb; - newDev->close = closeFb; - - FbState* fbState = calloc(1, sizeof(FbState)); - - /* establish a connection to the front-end if necessary */ - /* (also gets display configuration) */ - wsSimConnect(); - - configureInitialState(0, fbState); // always use display 0 for now - newDev->state = fbState; - } - - return newDev; -} - diff --git a/simulator/wrapsim/DevLog.c b/simulator/wrapsim/DevLog.c deleted file mode 100644 index fe1144d4d..000000000 --- a/simulator/wrapsim/DevLog.c +++ /dev/null @@ -1,485 +0,0 @@ -/* - * Copyright 2007 The Android Open Source Project - * - * Log devices. We want to filter and display messages, with separate - * treatment for "debug" and "event" logs. - * - * All messages are just dumped to stderr. - */ -#include "Common.h" - -#include "cutils/logd.h" - -#include <stdlib.h> -#include <string.h> -#include <ctype.h> - -#include <fcntl.h> - -#define kMaxTagLen 16 /* from utils/Log.cpp */ - -#define kTagSetSize 16 /* arbitrary */ - -/* from utils/Log.cpp */ -typedef enum { - FORMAT_OFF = 0, - FORMAT_BRIEF, - FORMAT_PROCESS, - FORMAT_TAG, - FORMAT_THREAD, - FORMAT_RAW, - FORMAT_TIME, - FORMAT_LONG -} LogFormat; - - -/* - * Log driver state. - */ -typedef struct LogState { - /* nonzero if this is a binary log */ - int isBinary; - - /* global minimum priority */ - int globalMinPriority; - - /* output format */ - LogFormat outputFormat; - - /* tags and priorities */ - struct { - char tag[kMaxTagLen]; - int minPriority; - } tagSet[kTagSetSize]; -} LogState; - - -/* - * Configure logging based on ANDROID_LOG_TAGS environment variable. We - * need to parse a string that looks like - * - * '*:v jdwp:d dalvikvm:d dalvikvm-gc:i dalvikvmi:i - * - * The tag (or '*' for the global level) comes first, followed by a colon - * and a letter indicating the minimum priority level we're expected to log. - * This can be used to reveal or conceal logs with specific tags. - * - * We also want to check ANDROID_PRINTF_LOG to determine how the output - * will look. - */ -static void configureInitialState(const char* pathName, LogState* logState) -{ - static const int kDevLogLen = 9; /* strlen("/dev/log/") */ - - /* identify binary logs */ - if (strcmp(pathName + kDevLogLen, "events") == 0) { - logState->isBinary = 1; - } - - /* global min priority defaults to "info" level */ - logState->globalMinPriority = ANDROID_LOG_INFO; - - /* - * This is based on the utils/Log.cpp code. - */ - const char* tags = getenv("ANDROID_LOG_TAGS"); - wsLog("Found ANDROID_LOG_TAGS='%s'\n", tags); - if (tags != NULL) { - int entry = 0; - - while (*tags != '\0') { - char tagName[kMaxTagLen]; - int i, minPrio; - - while (isspace(*tags)) - tags++; - - i = 0; - while (*tags != '\0' && !isspace(*tags) && *tags != ':' && - i < kMaxTagLen) - { - tagName[i++] = *tags++; - } - if (i == kMaxTagLen) { - wsLog("ERROR: env tag too long (%d chars max)\n", kMaxTagLen-1); - return; - } - tagName[i] = '\0'; - - /* default priority, if there's no ":" part; also zero out '*' */ - minPrio = ANDROID_LOG_VERBOSE; - if (tagName[0] == '*' && tagName[1] == '\0') { - minPrio = ANDROID_LOG_DEBUG; - tagName[0] = '\0'; - } - - if (*tags == ':') { - tags++; - if (*tags >= '0' && *tags <= '9') { - if (*tags >= ('0' + ANDROID_LOG_SILENT)) - minPrio = ANDROID_LOG_VERBOSE; - else - minPrio = *tags - '\0'; - } else { - switch (*tags) { - case 'v': minPrio = ANDROID_LOG_VERBOSE; break; - case 'd': minPrio = ANDROID_LOG_DEBUG; break; - case 'i': minPrio = ANDROID_LOG_INFO; break; - case 'w': minPrio = ANDROID_LOG_WARN; break; - case 'e': minPrio = ANDROID_LOG_ERROR; break; - case 'f': minPrio = ANDROID_LOG_FATAL; break; - case 's': minPrio = ANDROID_LOG_SILENT; break; - default: minPrio = ANDROID_LOG_DEFAULT; break; - } - } - - tags++; - if (*tags != '\0' && !isspace(*tags)) { - wsLog("ERROR: garbage in tag env; expected whitespace\n"); - wsLog(" env='%s'\n", tags); - return; - } - } - - if (tagName[0] == 0) { - logState->globalMinPriority = minPrio; - wsLog("+++ global min prio %d\n", logState->globalMinPriority); - } else { - logState->tagSet[entry].minPriority = minPrio; - strcpy(logState->tagSet[entry].tag, tagName); - wsLog("+++ entry %d: %s:%d\n", - entry, - logState->tagSet[entry].tag, - logState->tagSet[entry].minPriority); - entry++; - } - } - } - - - /* - * Taken from utils/Log.cpp - */ - const char* fstr = getenv("ANDROID_PRINTF_LOG"); - LogFormat format; - if (fstr == NULL) { - format = FORMAT_BRIEF; - } else { - if (strcmp(fstr, "brief") == 0) - format = FORMAT_BRIEF; - else if (strcmp(fstr, "process") == 0) - format = FORMAT_PROCESS; - else if (strcmp(fstr, "tag") == 0) - format = FORMAT_PROCESS; - else if (strcmp(fstr, "thread") == 0) - format = FORMAT_PROCESS; - else if (strcmp(fstr, "raw") == 0) - format = FORMAT_PROCESS; - else if (strcmp(fstr, "time") == 0) - format = FORMAT_PROCESS; - else if (strcmp(fstr, "long") == 0) - format = FORMAT_PROCESS; - else - format = (LogFormat) atoi(fstr); // really?! - } - - logState->outputFormat = format; -} - -/* - * Free up the state structure. - */ -static void freeState(LogState* logState) -{ - free(logState); -} - -/* - * Return a human-readable string for the priority level. Always returns - * a valid string. - */ -static const char* getPriorityString(int priority) -{ - /* the first character of each string should be unique */ - static const char* priorityStrings[] = { - "Verbose", "Debug", "Info", "Warn", "Error", "Assert" - }; - int idx; - - idx = (int) priority - (int) ANDROID_LOG_VERBOSE; - if (idx < 0 || - idx >= (int) (sizeof(priorityStrings) / sizeof(priorityStrings[0]))) - return "?unknown?"; - return priorityStrings[idx]; -} - -/* - * Show a log message. We write it to stderr and send a copy to the - * simulator front-end for the log window. - * - * Taken from utils/Log.cpp. - */ -static void showLog(FakeDev* dev, int logPrio, const char* tag, const char* msg) -{ - LogState* state = (LogState*) dev->state; - -#if defined(HAVE_LOCALTIME_R) - struct tm tmBuf; -#endif - struct tm* ptm; - char timeBuf[32]; - char prefixBuf[128], suffixBuf[128]; - char priChar; - time_t when; - pid_t pid, tid; - - //wsLog("LOG %d: %s %s", logPrio, tag, msg); - wsPostLogMessage(logPrio, tag, msg); - - priChar = getPriorityString(logPrio)[0]; - when = time(NULL); - pid = tid = getpid(); // find gettid()? - - /* - * Get the current date/time in pretty form - * - * It's often useful when examining a log with "less" to jump to - * a specific point in the file by searching for the date/time stamp. - * For this reason it's very annoying to have regexp meta characters - * in the time stamp. Don't use forward slashes, parenthesis, - * brackets, asterisks, or other special chars here. - */ -#if defined(HAVE_LOCALTIME_R) - ptm = localtime_r(&when, &tmBuf); -#else - ptm = localtime(&when); -#endif - //strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", ptm); - strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm); - - /* - * Construct a buffer containing the log header and log message. - */ - size_t prefixLen, suffixLen; - - switch (state->outputFormat) { - case FORMAT_TAG: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "%c/%-8s: ", priChar, tag); - strcpy(suffixBuf, "\n"); suffixLen = 1; - break; - case FORMAT_PROCESS: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "%c(%5d) ", priChar, pid); - suffixLen = snprintf(suffixBuf, sizeof(suffixBuf), - " (%s)\n", tag); - break; - case FORMAT_THREAD: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "%c(%5d:%p) ", priChar, pid, (void*)tid); - strcpy(suffixBuf, "\n"); suffixLen = 1; - break; - case FORMAT_RAW: - prefixBuf[0] = 0; prefixLen = 0; - strcpy(suffixBuf, "\n"); suffixLen = 1; - break; - case FORMAT_TIME: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "%s %-8s\n\t", timeBuf, tag); - strcpy(suffixBuf, "\n"); suffixLen = 1; - break; - case FORMAT_LONG: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "[ %s %5d:%p %c/%-8s ]\n", - timeBuf, pid, (void*)tid, priChar, tag); - strcpy(suffixBuf, "\n\n"); suffixLen = 2; - break; - default: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "%c/%-8s(%5d): ", priChar, tag, pid); - strcpy(suffixBuf, "\n"); suffixLen = 1; - break; - } - - /* - * Figure out how many lines there will be. - */ - const char* end = msg + strlen(msg); - size_t numLines = 0; - const char* p = msg; - while (p < end) { - if (*p++ == '\n') numLines++; - } - if (p > msg && *(p-1) != '\n') numLines++; - - /* - * Create an array of iovecs large enough to write all of - * the lines with a prefix and a suffix. - */ - const size_t INLINE_VECS = 6; - struct iovec stackVec[INLINE_VECS]; - struct iovec* vec = stackVec; - - numLines *= 3; // 3 iovecs per line. - if (numLines > INLINE_VECS) { - vec = (struct iovec*)malloc(sizeof(struct iovec)*numLines); - if (vec == NULL) { - msg = "LOG: write failed, no memory"; - numLines = 3; - } - } - - /* - * Fill in the iovec pointers. - */ - p = msg; - struct iovec* v = vec; - int totalLen = 0; - while (p < end) { - if (prefixLen > 0) { - v->iov_base = prefixBuf; - v->iov_len = prefixLen; - totalLen += prefixLen; - v++; - } - const char* start = p; - while (p < end && *p != '\n') p++; - if ((p-start) > 0) { - v->iov_base = (void*)start; - v->iov_len = p-start; - totalLen += p-start; - v++; - } - if (*p == '\n') p++; - if (suffixLen > 0) { - v->iov_base = suffixBuf; - v->iov_len = suffixLen; - totalLen += suffixLen; - v++; - } - } - - /* - * Write the entire message to the log file with a single writev() call. - * We need to use this rather than a collection of printf()s on a FILE* - * because of multi-threading and multi-process issues. - * - * If the file was not opened with O_APPEND, this will produce interleaved - * output when called on the same file from multiple processes. - * - * If the file descriptor is actually a network socket, the writev() - * call may return with a partial write. Putting the writev() call in - * a loop can result in interleaved data. This can be alleviated - * somewhat by wrapping the writev call in the Mutex. - */ - - for(;;) { - int cc; - - cc = writev(fileno(stderr), vec, v-vec); - if (cc == totalLen) break; - - if (cc < 0) { - if(errno == EINTR) continue; - - /* can't really log the failure; for now, throw out a stderr */ - fprintf(stderr, "+++ LOG: write failed (errno=%d)\n", errno); - break; - } else { - /* shouldn't happen when writing to file or tty */ - fprintf(stderr, "+++ LOG: write partial (%d of %d)\n", cc, totalLen); - break; - } - } - - /* if we allocated storage for the iovecs, free it */ - if (vec != stackVec) - free(vec); -} - - -/* - * Receive a log message. We happen to know that "vector" has three parts: - * - * priority (1 byte) - * tag (N bytes -- null-terminated ASCII string) - * message (N bytes -- null-terminated ASCII string) - */ -static ssize_t writevLog(FakeDev* dev, int fd, const struct iovec* vector, - int count) -{ - LogState* state = (LogState*) dev->state; - int ret = 0; - - if (state->isBinary) { - wsLog("%s: ignoring binary log\n", dev->debugName); - goto bail; - } - - if (count != 3) { - wsLog("%s: writevLog with count=%d not expected\n", - dev->debugName, count); - errno = EINVAL; - return -1; - } - - /* pull out the three fields */ - int logPrio = *(const char*)vector[0].iov_base; - const char* tag = (const char*) vector[1].iov_base; - const char* msg = (const char*) vector[2].iov_base; - - /* see if this log tag is configured */ - int i; - int minPrio = state->globalMinPriority; - for (i = 0; i < kTagSetSize; i++) { - if (state->tagSet[i].minPriority == ANDROID_LOG_UNKNOWN) - break; /* reached end of configured values */ - - if (strcmp(state->tagSet[i].tag, tag) == 0) { - //wsLog("MATCH tag '%s'\n", tag); - minPrio = state->tagSet[i].minPriority; - break; - } - } - - if (logPrio >= minPrio) { - showLog(dev, logPrio, tag, msg); - } else { - //wsLog("+++ NOLOG(%d): %s %s", logPrio, tag, msg); - } - -bail: - for (i = 0; i < count; i++) - ret += vector[i].iov_len; - return ret; -} - -/* - * Free up our state before closing down the fake descriptor. - */ -static int closeLog(FakeDev* dev, int fd) -{ - freeState((LogState*)dev->state); - dev->state = NULL; - return 0; -} - -/* - * Open a log output device. - */ -FakeDev* wsOpenDevLog(const char* pathName, int flags) -{ - FakeDev* newDev = wsCreateFakeDev(pathName); - if (newDev != NULL) { - newDev->writev = writevLog; - newDev->close = closeLog; - - LogState* logState = calloc(1, sizeof(LogState)); - - configureInitialState(pathName, logState); - newDev->state = logState; - } - - return newDev; -} - diff --git a/simulator/wrapsim/DevPower.c b/simulator/wrapsim/DevPower.c deleted file mode 100644 index b44231bd3..000000000 --- a/simulator/wrapsim/DevPower.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright 2007 The Android Open Source Project - * - * Magic entries in /sys/class/power_supply/. - */ -#include "Common.h" - -#include <stdlib.h> -#include <string.h> -#include <ctype.h> - -#include <fcntl.h> -#include <sys/ioctl.h> - -/* - * Map filename to device index. - * - * [ not using DeviceIndex -- would be useful if we need to return something - * other than a static string ] - */ -static const struct { - const char* name; - //DeviceIndex idx; - const char* data; -} gDeviceMap[] = { - { "ac/online", - "0\n" }, - - { "battery/batt_temp", - "281\n", }, - { "battery/batt_vol", - "4170\n" }, - { "battery/capacity", - "100\n" }, - { "battery/health", - "Good\n" }, - { "battery/present", - "0\n" }, - { "battery/status", - "Full" }, - { "battery/technology", - "Li-ion\n" }, - - { "usb/online", - "1\n" }, -}; - -/* - * Power driver state. - * - * Right now we just ignore everything written. - */ -typedef struct PowerState { - int which; -} PowerState; - - -/* - * Figure out who we are, based on "pathName". - */ -static void configureInitialState(const char* pathName, PowerState* powerState) -{ - const char* cp = pathName + strlen("/sys/class/power_supply/"); - int i; - - powerState->which = -1; - for (i = 0; i < (int) (sizeof(gDeviceMap) / sizeof(gDeviceMap[0])); i++) { - if (strcmp(cp, gDeviceMap[i].name) == 0) { - powerState->which = i; - break; - } - } - - if (powerState->which == -1) { - wsLog("Warning: access to unknown power device '%s'\n", pathName); - return; - } -} - -/* - * Free up the state structure. - */ -static void freeState(PowerState* powerState) -{ - free(powerState); -} - -/* - * Read data from the device. - * - * We don't try to keep track of how much was read -- existing clients just - * try to read into a large buffer. - */ -static ssize_t readPower(FakeDev* dev, int fd, void* buf, size_t count) -{ - PowerState* state = (PowerState*) dev->state; - int dataLen; - - wsLog("%s: read %d\n", dev->debugName, count); - - if (state->which < 0 || - state->which >= (int) (sizeof(gDeviceMap)/sizeof(gDeviceMap[0]))) - { - return 0; - } - - const char* data = gDeviceMap[state->which].data; - size_t strLen = strlen(data); - - while(strLen == 0) - sleep(10); // block forever - - ssize_t copyCount = (strLen < count) ? strLen : count; - memcpy(buf, data, copyCount); - return copyCount; -} - -/* - * Ignore the request. - */ -static ssize_t writePower(FakeDev* dev, int fd, const void* buf, size_t count) -{ - wsLog("%s: write %d bytes\n", dev->debugName, count); - return count; -} - -/* - * Our Java classes want to be able to do ioctl(FIONREAD) on files. The - * battery power manager is blowing up if we get an error other than - * ENOTTY (meaning a device that doesn't understand buffering). - */ -static int ioctlPower(FakeDev* dev, int fd, int request, void* argp) -{ - if (request == FIONREAD) { - wsLog("%s: ioctl(FIONREAD, %p)\n", dev->debugName, argp); - errno = ENOTTY; - return -1; - } else { - wsLog("%s: ioctl(0x%08x, %p) ??\n", dev->debugName, request, argp); - errno = EINVAL; - return -1; - } -} - -/* - * Free up our state before closing down the fake descriptor. - */ -static int closePower(FakeDev* dev, int fd) -{ - freeState((PowerState*)dev->state); - dev->state = NULL; - return 0; -} - -/* - * Open a power device. - */ -FakeDev* wsOpenDevPower(const char* pathName, int flags) -{ - FakeDev* newDev = wsCreateFakeDev(pathName); - if (newDev != NULL) { - newDev->read = readPower; - newDev->write = writePower; - newDev->ioctl = ioctlPower; - newDev->close = closePower; - - PowerState* powerState = calloc(1, sizeof(PowerState)); - - configureInitialState(pathName, powerState); - newDev->state = powerState; - } - - return newDev; -} - diff --git a/simulator/wrapsim/DevVibrator.c b/simulator/wrapsim/DevVibrator.c deleted file mode 100644 index b736f7519..000000000 --- a/simulator/wrapsim/DevVibrator.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2007 The Android Open Source Project - * - * Vibrating notification device. - */ -#include "Common.h" - -#include <stdlib.h> -#include <string.h> -#include <ctype.h> - -#include <unistd.h> - - -/* - * The user will write a decimal integer indicating the time, in milliseconds, - * that the device should vibrate. In current usage, this is either -1 - * (meaning vibrate forever) or 0 (don't vibrate). - */ -static ssize_t writeVibrator(FakeDev* dev, int fd, const void* buf, - size_t count) -{ - if (count == 2 && memcmp(buf, "0\n", 2) == 0) { - wsEnableVibration(0); - } else if (count == 3 && memcmp(buf, "-1\n", 3) == 0) { - wsEnableVibration(1); - } else { - wsLog("%s: got %d bytes: '%*s'\n", - dev->debugName, count, count, (const char*) buf); - } - - return count; -} - -/* - * Open the vibration control device. - */ -FakeDev* wsOpenDevVibrator(const char* pathName, int flags) -{ - FakeDev* newDev = wsCreateFakeDev(pathName); - if (newDev != NULL) { - newDev->write = writeVibrator; - } - - return newDev; -} - diff --git a/simulator/wrapsim/FakeDev.c b/simulator/wrapsim/FakeDev.c deleted file mode 100644 index 3e223d363..000000000 --- a/simulator/wrapsim/FakeDev.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright 2007 The Android Open Source Project - * - * Fake device support. - */ -/* -Implementation notes: - -There are a couple of basic scenarios, exemplified by the "fb" and -"events" devices. The framebuffer driver is pretty simple, handling a -few ioctl()s and managing a stretch of memory. We can just intercept a -few calls. The input event driver can be used in a select() or poll() -call with other file descriptors, which either requires us to do some -fancy tricks with select() and poll(), or requires that we return a real -file descriptor (perhaps based on a socketpair). - -We have three basic approaches to dealing with "fake" file descriptors: - -(1) Always use real fds. We can dup() an open /dev/null to get a number - for the cases where we don't need a socketpair. -(2) Always use fake fds with absurdly high numeric values. Testing to see - if the fd is one we handle is trivial (range check). This doesn't - work for select(), which uses fd bitmaps accessed through macros. -(3) Use a mix of real and fake fds, in a high range (512-1023). Because - it's in the "real" range, we can pass real fds around for things that - are handed to poll() and select(), but because of the high numeric - value we *should* be able to get away with a trivial range check. - -Approach (1) is the most portable and least likely to break, but the -efficiencies gained in approach (2) make it more desirable. There is -a small risk of application fds wandering into our range, but we can -minimize that by asserting on a "guard zone" and/or obstructing dup2(). -(We can also dup2(/dev/null) to "reserve" our fds, but that wastes -resources.) -*/ - -#include "Common.h" - -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <assert.h> -#include <fnmatch.h> - -/* - * Devices we intercept. - * - * Needed: - * /dev/alarm - * radio - */ -typedef FakeDev* (*wsFileHook)(const char *path, int flags); - -typedef struct FakedPath { - const char *pathexpr; - wsFileHook hook; -} FakedPath; - -FakedPath fakedpaths[] = -{ - { "/dev/graphics/fb0", wsOpenDevFb }, - { "/dev/hw3d", NULL }, - { "/dev/eac", wsOpenDevAudio }, - { "/dev/tty0", wsOpenDevConsoleTty }, - { "/dev/input/event0", wsOpenDevEvent }, - { "/dev/input/*", NULL }, - { "/dev/log/*", wsOpenDevLog }, - { "/sys/class/power_supply/*", wsOpenDevPower }, - { "/sys/devices/platform/android-vibrator/enable", wsOpenDevVibrator }, - { "/sys/qemu_trace/*", NULL }, - { NULL, NULL } -}; - - -/* - * Generic drop-in for an unimplemented call. - * - * Returns -1, which conveniently is the same as MAP_FAILED for mmap. - */ -static int notImplemented(FakeDev* dev, const char* callName) -{ - wsLog("WARNING: unimplemented %s() on '%s' %p\n", - callName, dev->debugName, dev->state); - errno = kNoHandlerError; - return -1; -} - -/* - * Default implementations. We want to log as much information as we can - * so that we can fill in the missing implementation. - * - * TODO: for some or all of these we will want to display the full arg list. - */ -static int noClose(FakeDev* dev, ...) -{ - return 0; -} -static int noRead(FakeDev* dev, ...) -{ - return notImplemented(dev, "read"); -} -static int noReadv(FakeDev* dev, ...) -{ - return notImplemented(dev, "readv"); -} -static int noWrite(FakeDev* dev, ...) -{ - return notImplemented(dev, "write"); -} -static int noWritev(FakeDev* dev, ...) -{ - return notImplemented(dev, "writev"); -} -static int noMmap(FakeDev* dev, ...) -{ - return notImplemented(dev, "mmap"); -} -static int noIoctl(FakeDev* dev, ...) -{ - return notImplemented(dev, "ioctl"); -} - - -/* - * Create a new FakeDev entry. - * - * We mark the fd slot as "used" in the bitmap, but don't add it to the - * table yet since the entry is not fully prepared. - */ -FakeDev* wsCreateFakeDev(const char* debugName) -{ - FakeDev* newDev; - int cc; - - assert(debugName != NULL); - - newDev = (FakeDev*) calloc(1, sizeof(FakeDev)); - if (newDev == NULL) - return NULL; - - newDev->debugName = strdup(debugName); - newDev->state = NULL; - - newDev->close = (Fake_close) noClose; - newDev->read = (Fake_read) noRead; - newDev->readv = (Fake_readv) noReadv; - newDev->write = (Fake_write) noWrite; - newDev->writev = (Fake_writev) noWritev; - newDev->mmap = (Fake_mmap) noMmap; - newDev->ioctl = (Fake_ioctl) noIoctl; - - /* - * Allocate a new entry. The bit vector map is really only used as a - * performance boost in the current implementation. - */ - cc = pthread_mutex_lock(&gWrapSim.fakeFdLock); assert(cc == 0); - int newfd = wsAllocBit(gWrapSim.fakeFdMap); - cc = pthread_mutex_unlock(&gWrapSim.fakeFdLock); assert(cc == 0); - - if (newfd < 0) { - wsLog("WARNING: ran out of 'fake' file descriptors\n"); - free(newDev); - return NULL; - } - newDev->fd = newfd + kFakeFdBase; - newDev->otherFd = -1; - assert(gWrapSim.fakeFdList[newDev->fd - kFakeFdBase] == NULL); - - return newDev; -} - -/* - * Create a new FakeDev entry, and open a file descriptor that actually - * works. - */ -FakeDev* wsCreateRealFakeDev(const char* debugName) -{ - FakeDev* newDev = wsCreateFakeDev(debugName); - if (newDev == NULL) - return newDev; - - int fds[2]; - - if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) { - wsLog("socketpair() failed: %s\n", strerror(errno)); - wsFreeFakeDev(newDev); - return NULL; - } - - if (dup2(fds[0], newDev->fd) < 0) { - wsLog("dup2(%d,%d) failed: %s\n", - fds[0], newDev->fd, strerror(errno)); - wsFreeFakeDev(newDev); - return NULL; - } - close(fds[0]); - - /* okay to leave this one in the "normal" range; not visible to app */ - newDev->otherFd = fds[1]; - - return newDev; -} - -/* - * Free fake device entry. - */ -void wsFreeFakeDev(FakeDev* dev) -{ - if (dev == NULL) - return; - - wsLog("## closing/freeing '%s' (%d/%d)\n", - dev->debugName, dev->fd, dev->otherFd); - - /* - * If we assigned a file descriptor slot, free it up. - */ - if (dev->fd >= 0) { - int cc; - - gWrapSim.fakeFdList[dev->fd - kFakeFdBase] = NULL; - - cc = pthread_mutex_lock(&gWrapSim.fakeFdLock); assert(cc == 0); - wsFreeBit(gWrapSim.fakeFdMap, dev->fd - kFakeFdBase); - cc = pthread_mutex_unlock(&gWrapSim.fakeFdLock); assert(cc == 0); - } - if (dev->otherFd >= 0) - close(dev->otherFd); - - if (dev->debugName) free(dev->debugName); - free(dev); -} - -/* - * Map a file descriptor to a fake device. - * - * Returns NULL if there's no corresponding entry. - */ -FakeDev* wsFakeDevFromFd(int fd) -{ - /* quick range test */ - if (fd < kFakeFdBase || fd >= kFakeFdBase + kMaxFakeFdCount) - return NULL; - - return gWrapSim.fakeFdList[fd - kFakeFdBase]; -} - - -/* - * Check to see if we're opening a device that we want to fake out. - * - * We return a file descriptor >= 0 on success, -1 if we're not interested, - * or -2 if we explicitly want to pretend that the device doesn't exist. - */ -int wsInterceptDeviceOpen(const char* pathName, int flags) -{ - FakedPath* p = fakedpaths; - - while (p->pathexpr) { - if (fnmatch(p->pathexpr, pathName, 0) == 0) { - if (p->hook != NULL) { - FakeDev* dev = p->hook(pathName, flags); - if (dev != NULL) { - /* - * Now that the device entry is ready, add it to the list. - */ - wsLog("## created fake dev %d: '%s' %p\n", - dev->fd, dev->debugName, dev->state); - gWrapSim.fakeFdList[dev->fd - kFakeFdBase] = dev; - return dev->fd; - } - } else { - wsLog("## rejecting attempt to open %s\n", pathName); - errno = ENOENT; - return -2; - } - break; - } - p++; - } - return -1; -} - -/* - * Check to see if we're accessing a device that we want to fake out. - * Returns 0 if the device can be (fake) opened with the given mode, - * -1 if it can't, -2 if it can't and we don't want to allow fallback - * to the host-device either. - * TODO: actually check the mode. - */ -int wsInterceptDeviceAccess(const char *pathName, int mode) -{ - FakedPath *p = fakedpaths; - - while (p->pathexpr) { - if (fnmatch(p->pathexpr, pathName, 0) == 0) { - if (p->hook) { - return 0; - } else { - wsLog("## rejecting attempt to open %s\n", pathName); - errno = ENOENT; - return -2; - } - break; - } - p++; - } - errno = ENOENT; - return -1; -} diff --git a/simulator/wrapsim/FakeDev.h b/simulator/wrapsim/FakeDev.h deleted file mode 100644 index eacbbf55d..000000000 --- a/simulator/wrapsim/FakeDev.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2007 The Android Open Source Project - * - * Fake device support. - */ -#ifndef _WRAPSIM_FAKEDEV_H -#define _WRAPSIM_FAKEDEV_H - -#include <sys/types.h> -#include <sys/uio.h> -#include <errno.h> - -typedef struct FakeDev FakeDev; - -typedef int (*Fake_close)(FakeDev* dev, int); -typedef ssize_t (*Fake_read)(FakeDev* dev, int, void*, size_t); -typedef ssize_t (*Fake_readv)(FakeDev* dev, int, const struct iovec*, int); -typedef ssize_t (*Fake_write)(FakeDev* dev, int, const void*, size_t); -typedef ssize_t (*Fake_writev)(FakeDev* dev, int, const struct iovec*, int); -typedef void* (*Fake_mmap)(FakeDev* dev, void*, size_t, int, int, int, __off_t); -typedef int (*Fake_ioctl)(FakeDev* dev, int, int, void*); - -/* - * An open fake device entry. - */ -struct FakeDev { - /* string, for debugging; usually orig. device name */ - char* debugName; - - /* state bucket */ - void* state; - - /* the file descriptor we're associated with */ - int fd; - - /* in some cases we use a pair; this is the other one */ - int otherFd; - - /* - * Device functions we provide. - * - * All other file descriptor operations should fail, usually with EBADF. - */ - Fake_close close; - Fake_read read; - Fake_readv readv; - Fake_write write; - Fake_writev writev; - Fake_mmap mmap; // handles both mmap() and mmap64() - Fake_ioctl ioctl; -}; - -/* - * If a handler isn't defined for a syscall, we return EMLINK so that it's - * obvious when the error is generated by us. - */ -#define kNoHandlerError EMLINK - -/* - * Fake file descriptors begin here. This should be chosen such that no - * real descriptor is ever at or above this value. - */ -#define kFakeFdBase 512 -#define kMaxFakeFdCount 256 - -/* - * Create a new, completely fake device entry. - */ -FakeDev* wsCreateFakeDev(const char* debugName); - -/* - * Create a new, mostly fake device entry. - */ -FakeDev* wsCreateRealFakeDev(const char* debugName); - -/* - * Free a fake device entry. - */ -void wsFreeFakeDev(FakeDev* dev); - -/* - * Given a file descriptor, find the corresponding fake device. Returns - * NULL if the fd doesn't correspond to one of our entries. - */ -FakeDev* wsFakeDevFromFd(int fd); - -/* - * Check to see if this open() call is on a device we want to spoof. - * - * Returns a "fake" file descriptor on success, <0 on error. - */ -int wsInterceptDeviceOpen(const char* pathName, int flags); - -/* - * Check to see if this access() call is on a device we want to spoof. - * - * Returns 0 if the device can be fake-accessed, -1 if it can't, -2 - * if it can't and we don't want to allow fallback to the host-device. - */ -int wsInterceptDeviceAccess(const char* pathName, int flags); - -/* - * Devices. - */ -FakeDev* wsOpenDevAudio(const char* pathName, int flags); -FakeDev* wsOpenDevConsoleTty(const char* pathName, int flags); -FakeDev* wsOpenDevEvent(const char* pathName, int flags); -FakeDev* wsOpenDevFb(const char* pathName, int flags); -FakeDev* wsOpenDevLog(const char* pathName, int flags); -FakeDev* wsOpenDevPower(const char* pathName, int flags); -FakeDev* wsOpenDevVibrator(const char* pathName, int flags); - -/* - * Performs key remapping and sends the event to the global input event device. - */ -void wsSendSimKeyEvent(int key, int isDown); - -/* - * Send a touch event to the global input event device. - */ -void wsSendSimTouchEvent(int action, int x, int y); - -#endif /*_WRAPSIM_FAKEDEV_H*/ diff --git a/simulator/wrapsim/Globals.h b/simulator/wrapsim/Globals.h deleted file mode 100644 index 75c98d8fa..000000000 --- a/simulator/wrapsim/Globals.h +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright 2007 The Android Open Source Project - * - * Sim wrapper global state. - */ -#ifndef _WRAPSIM_GLOBALS_H -#define _WRAPSIM_GLOBALS_H - -#include <stdio.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/uio.h> -#include <sys/time.h> -#include <sys/vfs.h> -#include <utime.h> -#include <fcntl.h> -#include <dirent.h> -#include <pthread.h> - -/* - * Type declarations for the functions we're replacing. - * - * For syscalls this matches the syscall definition, not the libc definition, - * e.g. no varargs for open() or ioctl(). - */ -typedef int (*Func_access)(const char*, int); -typedef int (*Func_open)(const char*, int, mode_t); -typedef int (*Func_open64)(const char*, int, mode_t); - -typedef int (*Func_close)(int); -typedef ssize_t (*Func_read)(int, void*, size_t); -typedef ssize_t (*Func_readv)(int, const struct iovec*, int); -typedef ssize_t (*Func_write)(int, const void*, size_t); -typedef ssize_t (*Func_writev)(int, const struct iovec*, int); -typedef void* (*Func_mmap)(void*, size_t, int, int, int, __off_t); -typedef void* (*Func_mmap64)(void*, size_t, int, int, int, __off64_t); -typedef int (*Func_ioctl)(int, int, void*); - -typedef int (*Func_chdir)(const char*); -typedef int (*Func_chmod)(const char*, mode_t); -typedef int (*Func_chown)(const char*, uid_t, uid_t); -typedef int (*Func_creat)(const char*, mode_t); -typedef int (*Func_execve)(const char*, char* const[], char* const[]); -typedef char* (*Func_getcwd)(char* buf, size_t size); -typedef int (*Func_lchown)(const char*, uid_t, uid_t); -typedef int (*Func_link)(const char*, const char*); -typedef int (*Func_lstat)(const char*, struct stat*); -typedef int (*Func_lstat64)(const char*, struct stat*); -typedef int (*Func___lxstat)(int version, const char*, struct stat*); -typedef int (*Func___lxstat64)(int version, const char*, struct stat*); -typedef int (*Func_mkdir)(const char*, mode_t mode); -typedef ssize_t (*Func_readlink)(const char*, char*, size_t); -typedef int (*Func_rename)(const char*, const char*); -typedef int (*Func_rmdir)(const char*); -typedef int (*Func_stat)(const char*, struct stat*); -typedef int (*Func_stat64)(const char*, struct stat*); -typedef int (*Func___xstat)(int version, const char*, struct stat*); -typedef int (*Func___xstat64)(int version, const char*, struct stat*); -typedef int (*Func_statfs)(const char*, struct statfs*); -typedef int (*Func_statfs64)(const char*, struct statfs*); -typedef int (*Func_symlink)(const char*, const char*); -typedef int (*Func_unlink)(const char*); -typedef int (*Func_utime)(const char*, const struct utimbuf*); -typedef int (*Func_utimes)(const char*, const struct timeval []); - -typedef int (*Func_execl)(const char*, const char*, ...); -typedef int (*Func_execle)(const char*, const char*, ...); -typedef int (*Func_execlp)(const char*, const char*, ...); -typedef int (*Func_execv)(const char*, char* const []); -typedef int (*Func_execvp)(const char*, char* const []); -typedef FILE* (*Func_fopen)(const char*, const char*); -typedef FILE* (*Func_fopen64)(const char*, const char*); -typedef FILE* (*Func_freopen)(const char*, const char*, FILE*); -typedef int (*Func_ftw)(const char*, - int (*fn) (const char*, const struct stat*, int), - int); -typedef DIR* (*Func_opendir)(const char* path); -typedef void* (*Func_dlopen)(const char*, int); - -typedef int (*Func_setpriority)(int, int, int); -//typedef int (*Func_pipe)(int [2]); - - -/* - * Pointers to the actual implementations. - */ -#ifndef CREATE_FUNC_STORAGE -# define EXTERN_FUNC extern -#else -# define EXTERN_FUNC -#endif -EXTERN_FUNC Func_access _ws_access; -EXTERN_FUNC Func_open _ws_open; -EXTERN_FUNC Func_open64 _ws_open64; - -EXTERN_FUNC Func_close _ws_close; -EXTERN_FUNC Func_read _ws_read; -EXTERN_FUNC Func_readv _ws_readv; -EXTERN_FUNC Func_write _ws_write; -EXTERN_FUNC Func_writev _ws_writev; -EXTERN_FUNC Func_mmap _ws_mmap; -EXTERN_FUNC Func_mmap64 _ws_mmap64; -EXTERN_FUNC Func_ioctl _ws_ioctl; - -EXTERN_FUNC Func_chdir _ws_chdir; -EXTERN_FUNC Func_chmod _ws_chmod; -EXTERN_FUNC Func_chown _ws_chown; -EXTERN_FUNC Func_creat _ws_creat; -EXTERN_FUNC Func_execve _ws_execve; -EXTERN_FUNC Func_getcwd _ws_getcwd; -EXTERN_FUNC Func_lchown _ws_lchown; -EXTERN_FUNC Func_link _ws_link; -EXTERN_FUNC Func_lstat _ws_lstat; -EXTERN_FUNC Func_lstat64 _ws_lstat64; -EXTERN_FUNC Func___lxstat _ws___lxstat; -EXTERN_FUNC Func___lxstat64 _ws___lxstat64; -EXTERN_FUNC Func_mkdir _ws_mkdir; -EXTERN_FUNC Func_readlink _ws_readlink; -EXTERN_FUNC Func_rename _ws_rename; -EXTERN_FUNC Func_rmdir _ws_rmdir; -EXTERN_FUNC Func_stat _ws_stat; -EXTERN_FUNC Func_stat64 _ws_stat64; -EXTERN_FUNC Func___xstat _ws___xstat; -EXTERN_FUNC Func___xstat64 _ws___xstat64; -EXTERN_FUNC Func_statfs _ws_statfs; -EXTERN_FUNC Func_statfs64 _ws_statfs64; -EXTERN_FUNC Func_symlink _ws_symlink; -EXTERN_FUNC Func_unlink _ws_unlink; -EXTERN_FUNC Func_utime _ws_utime; -EXTERN_FUNC Func_utimes _ws_utimes; - -EXTERN_FUNC Func_execl _ws_execl; -EXTERN_FUNC Func_execle _ws_execle; -EXTERN_FUNC Func_execlp _ws_execlp; -EXTERN_FUNC Func_execv _ws_execv; -EXTERN_FUNC Func_execvp _ws_execvp; -EXTERN_FUNC Func_fopen _ws_fopen; -EXTERN_FUNC Func_fopen64 _ws_fopen64; -EXTERN_FUNC Func_freopen _ws_freopen; -EXTERN_FUNC Func_ftw _ws_ftw; -EXTERN_FUNC Func_opendir _ws_opendir; -EXTERN_FUNC Func_dlopen _ws_dlopen; - -EXTERN_FUNC Func_setpriority _ws_setpriority; -//EXTERN_FUNC Func_pipe _ws_pipe; - -#define kMaxDisplays 4 - -/* - * Global values. Must be initialized in initGlobals(), which is executed - * the first time somebody calls dlopen on the wrapper lib. - */ -struct WrapSimGlobals { - volatile int initialized; - - /* descriptor where we write log messages */ - int logFd; - - /* socket for communicating with simulator front-end */ - int simulatorFd; - - /* coordinate thread startup */ - pthread_mutex_t startLock; - pthread_cond_t startCond; - int startReady; - int simulatorInitFailed; - - /* base directory for filename remapping */ - char* remapBaseDir; - int remapBaseDirLen; - - /* - * Display characteristics. - * - * TODO: this is retrieved from the simulator during initial config. - * It needs to be visible to whatever process holds the surfaceflinger, - * which may or may not be the initial process in multi-process mode. - * We probably want to get the display config via a query, performed at - * intercepted-ioctl time, rather than a push from the sim at startup. - */ - struct { - int width; - int height; - - int shmemKey; - int shmid; - void* addr; - long length; - int semid; - } display[kMaxDisplays]; - int numDisplays; - - /* - * Input device. - */ - FakeDev* keyInputDevice; - const char *keyMap; - - /* fake file descriptor allocation map */ - pthread_mutex_t fakeFdLock; - BitVector* fakeFdMap; - FakeDev* fakeFdList[kMaxFakeFdCount]; -}; - -extern struct WrapSimGlobals gWrapSim; - -#endif /*_WRAPSIM_GLOBALS_H*/ diff --git a/simulator/wrapsim/Init.c b/simulator/wrapsim/Init.c deleted file mode 100644 index eed650bfe..000000000 --- a/simulator/wrapsim/Init.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2007 The Android Open Source Project - * - * Initialize the intercepts. - */ -#include "Common.h" - -#define __USE_GNU /* need RTLD_NEXT */ -#include <dlfcn.h> - -#include <stdlib.h> -#include <pthread.h> -#include <string.h> -#include <errno.h> -#include <assert.h> -#include <sys/stat.h> -#include <sys/types.h> - - -/* - * Global state. - */ -struct WrapSimGlobals gWrapSim; -pthread_once_t gWrapSimInitialized = PTHREAD_ONCE_INIT; - -/* - * Initialize our global state. - */ -static void initGlobals(void) -{ - memset(&gWrapSim, 0xdd, sizeof(gWrapSim)); - gWrapSim.logFd = -1; - gWrapSim.keyMap = NULL; - - /* - * Find the original version of functions we override. - */ - _ws_access = dlsym(RTLD_NEXT, "access"); - _ws_open = dlsym(RTLD_NEXT, "open"); - _ws_open64 = dlsym(RTLD_NEXT, "open64"); - - _ws_close = dlsym(RTLD_NEXT, "close"); - _ws_read = dlsym(RTLD_NEXT, "read"); - _ws_readv = dlsym(RTLD_NEXT, "readv"); - _ws_write = dlsym(RTLD_NEXT, "write"); - _ws_writev = dlsym(RTLD_NEXT, "writev"); - _ws_mmap = dlsym(RTLD_NEXT, "mmap"); - _ws_mmap64 = dlsym(RTLD_NEXT, "mmap64"); - _ws_ioctl = dlsym(RTLD_NEXT, "ioctl"); - - _ws_chdir = dlsym(RTLD_NEXT, "chdir"); - _ws_chmod = dlsym(RTLD_NEXT, "chmod"); - _ws_chown = dlsym(RTLD_NEXT, "chown"); - _ws_creat = dlsym(RTLD_NEXT, "creat"); - _ws_execve = dlsym(RTLD_NEXT, "execve"); - _ws_getcwd = dlsym(RTLD_NEXT, "getcwd"); - _ws_lchown = dlsym(RTLD_NEXT, "lchown"); - _ws_link = dlsym(RTLD_NEXT, "link"); - _ws_lstat = dlsym(RTLD_NEXT, "lstat"); - _ws_lstat64 = dlsym(RTLD_NEXT, "lstat64"); - _ws___lxstat = dlsym(RTLD_NEXT, "__lxstat"); - _ws___lxstat64 = dlsym(RTLD_NEXT, "__lxstat64"); - _ws_mkdir = dlsym(RTLD_NEXT, "mkdir"); - _ws_readlink = dlsym(RTLD_NEXT, "readlink"); - _ws_rename = dlsym(RTLD_NEXT, "rename"); - _ws_rmdir = dlsym(RTLD_NEXT, "rmdir"); - _ws_stat = dlsym(RTLD_NEXT, "stat"); - _ws_stat64 = dlsym(RTLD_NEXT, "stat64"); - _ws___xstat = dlsym(RTLD_NEXT, "__xstat"); - _ws___xstat64 = dlsym(RTLD_NEXT, "__xstat64"); - _ws_statfs = dlsym(RTLD_NEXT, "statfs"); - _ws_statfs64 = dlsym(RTLD_NEXT, "statfs64"); - _ws_symlink = dlsym(RTLD_NEXT, "symlink"); - _ws_unlink = dlsym(RTLD_NEXT, "unlink"); - _ws_utime = dlsym(RTLD_NEXT, "utime"); - _ws_utimes = dlsym(RTLD_NEXT, "utimes"); - - _ws_execl = dlsym(RTLD_NEXT, "execl"); - _ws_execle = dlsym(RTLD_NEXT, "execle"); - _ws_execlp = dlsym(RTLD_NEXT, "execlp"); - _ws_execv = dlsym(RTLD_NEXT, "execv"); - _ws_execvp = dlsym(RTLD_NEXT, "execvp"); - _ws_fopen = dlsym(RTLD_NEXT, "fopen"); - _ws_fopen64 = dlsym(RTLD_NEXT, "fopen64"); - _ws_freopen = dlsym(RTLD_NEXT, "freopen"); - _ws_ftw = dlsym(RTLD_NEXT, "ftw"); - _ws_opendir = dlsym(RTLD_NEXT, "opendir"); - _ws_dlopen = dlsym(RTLD_NEXT, "dlopen"); - - _ws_setpriority = dlsym(RTLD_NEXT, "setpriority"); - //_ws_pipe = dlsym(RTLD_NEXT, "pipe"); - - const char* logFileName = getenv("WRAPSIM_LOG"); - if (logFileName != NULL ){ - gWrapSim.logFd = _ws_open(logFileName, O_WRONLY|O_APPEND|O_CREAT, 0664); - } - - /* log messages now work; say hello */ - wsLog("--- initializing sim wrapper ---\n"); - - gWrapSim.simulatorFd = -1; - - pthread_mutex_init(&gWrapSim.startLock, NULL); - pthread_cond_init(&gWrapSim.startCond, NULL); - gWrapSim.startReady = 0; - - pthread_mutex_init(&gWrapSim.fakeFdLock, NULL); - gWrapSim.fakeFdMap = wsAllocBitVector(kMaxFakeFdCount, 0); - memset(gWrapSim.fakeFdList, 0, sizeof(gWrapSim.fakeFdList)); - - gWrapSim.numDisplays = 0; - - gWrapSim.keyInputDevice = NULL; - - /* - * Get target for remapped "/system" and "/data". - * - * The ANDROID_PRODUCT_OUT env var *must* be set for rewriting to work. - */ - const char* outEnv = getenv("ANDROID_PRODUCT_OUT"); - if (outEnv == NULL) { - gWrapSim.remapBaseDir = NULL; - wsLog("--- $ANDROID_PRODUCT_OUT not set, " - "filename remapping disabled\n"); - } else { - /* grab string and append '/' -- note this never gets freed */ - gWrapSim.remapBaseDirLen = strlen(outEnv); - gWrapSim.remapBaseDir = strdup(outEnv); - wsLog("--- name remap to %s\n", gWrapSim.remapBaseDir); - } - - gWrapSim.initialized = 1; -} - -/* - * Creates a directory, or prints a log message if it fails. - */ -static int createTargetDirectory(const char *path, mode_t mode) -{ - int ret; - - ret = mkdir(path, mode); - if (ret == 0 || errno == EEXIST) { - return 0; - } - wsLog("--- could not create target directory %s: %s\n", - path, strerror(errno)); - return ret; -} - -/* - * Any setup that would normally be done by init(8). - * Note that since the syscall redirects have been installed - * at this point, we are effectively operating within the - * simulation context. - */ -static void initGeneral(void) -{ - wsLog("--- preparing system\n"); - - /* Try to make sure that certain directories exist. - * If we fail to create them, the errors will show up in the log, - * but we keep going. - */ - createTargetDirectory("/data", 0777); - createTargetDirectory("/data/dalvik-cache", 0777); -} - -/* - * Initialize all necessary state, and indicate that we're ready to go. - */ -static void initOnce(void) -{ - initGlobals(); - initGeneral(); -} - -/* - * Shared object initializer. glibc guarantees that this function is - * called before dlopen() returns. It may be called multiple times. - */ -__attribute__((constructor)) -static void initialize(void) -{ - pthread_once(&gWrapSimInitialized, initOnce); -} - - diff --git a/simulator/wrapsim/Intercept.c b/simulator/wrapsim/Intercept.c deleted file mode 100644 index 29b0e0074..000000000 --- a/simulator/wrapsim/Intercept.c +++ /dev/null @@ -1,816 +0,0 @@ -/* - * Copyright 2007 The Android Open Source Project - * - * Syscall and library intercepts. - */ - -/* don't remap open() to open64() */ -#undef _FILE_OFFSET_BITS - -#define CREATE_FUNC_STORAGE -#include "Common.h" - -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/uio.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/resource.h> -#include <utime.h> -#include <limits.h> -#include <ftw.h> -#include <assert.h> - - -#if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS == 64 -#warning "big" -#endif - -//#define CALLTRACE(format, ...) wsLog(format, ##__VA_ARGS__) -#define CALLTRACE(format, ...) ((void)0) - -//#define CALLTRACEV(format, ...) wsLog(format, ##__VA_ARGS__) -#define CALLTRACEV(format, ...) ((void)0) - -/* -When opening certain files, we need to simulate the contents. For example, -we can pretend to open the frame buffer, and respond to ioctl()s by -returning fake data or telling the front-end to render new data. - -We want to intercept specific files in /dev. In some cases we want to -intercept and reject, e.g. to indicate that a standard Linux device does -not exist. - -Some things we're not going to intercept: - /etc/... (e.g. /etc/timezone) -- std. Linux version should be okay - /proc/... (e.g. /proc/stat) -- we're showing real pid, so real proc will work - -For the device drivers we need to intercept: - - close(), ioctl(), mmap(), open()/open64(), read(), readv(), write(), - writev() - -May also need stat(). We don't need all fd calls, e.g. fchdir() is -not likely to succeed on a device driver. The expected uses of mmap() -shouldn't require intercepting related calls like madvise() -- we will -provide an actual mapping of the requested size. In some cases we will -want to return a "real" fd so the app can poll() or select() on it. - - -We also need to consider: - getuid/setuid + variations -- fake out multi-user-id stuff - - -We also want to translate filenames, effectively performing a "chroot" -without all the baggage that comes with it. The mapping looks like: - - /system/... --> $ANDROID_PRODUCT_OUT/system/... - /data/... --> $ANDROID_PRODUCT_OUT/data/... - -Translating pathnames requires interception of additional system calls, -substituting a new path. Calls include: - - access(), chdir(), chmod(), chown(), creat(), execve(), getcwd(), - lchown(), link(), lstat()/lstat64(), mkdir(), open()/open64(), - readlink(), rename(), rmdir(), stat()/stat64(), statfs/statfs64(), - symlink(), unlink(), utimes(), - -Possibly also mknod(), mount(), umount(). - -The "at" family, notably openat(), should just work since the root comes -from an open directory fd. - -We also need these libc calls, because LD_LIBRARY_PATH substitutes at -the libc link level, not the syscall layer: - - execl(), execlp(), execle(), execv(), execvp(), fopen(), ftw(), getwd(), - opendir(), dlopen() - -It is possible for the cwd to leak out. Some possible leaks: - - /proc/[self]/exe - - /proc/[self]/cwd - - LD_LIBRARY_PATH (which may be awkward to work around) - - -To provide a replacement for the dirent functions -- only required if we -want to show "fake" directory contents -- we would need: - - closedir(), dirfd() readdir(), rewinddir(), scandir(), seekdir(), - telldir() - - -*/ - - -/* - * =========================================================================== - * Filename remapping - * =========================================================================== - */ - -/* - * If appropriate, rewrite the path to point to a different location. - * - * Returns either "pathBuf" or "origPath" depending on whether or not we - * chose to rewrite the path. "origPath" must be a buffer capable of - * holding an extended pathname; for best results use PATH_MAX. - */ -static const char* rewritePath(const char* func, char* pathBuf, - const char* origPath) -{ - /* - * Rewrite paths that start with "/system/" or "/data/" - */ - if (origPath[0] != '/') - goto skip_rewrite; - if (memcmp(origPath+1, "system", 6) == 0 && - (origPath[7] == '/' || origPath[7] == '\0')) - goto do_rewrite; - if (memcmp(origPath+1, "data", 4) == 0 && - (origPath[5] == '/' || origPath[5] == '\0')) - goto do_rewrite; - -skip_rewrite: - /* check to see if something is side-stepping the rewrite */ - if (memcmp(origPath, gWrapSim.remapBaseDir, gWrapSim.remapBaseDirLen) == 0) - { - wsLog("NOTE: full path used: %s(%s)\n", func, origPath); - } - - CALLTRACE("rewrite %s('%s') --> (not rewritten)\n", func, origPath); - return origPath; - -do_rewrite: - memcpy(pathBuf, gWrapSim.remapBaseDir, gWrapSim.remapBaseDirLen); - strcpy(pathBuf + gWrapSim.remapBaseDirLen, origPath); - CALLTRACE("rewrite %s('%s') --> '%s'\n", func, origPath, pathBuf); - return pathBuf; -} - -/* - * This works if the pathname is the first argument to the function, and - * the function returns "int". - */ -#define PASS_THROUGH_DECL(_fname, _rtype, ...) \ - _rtype _fname( __VA_ARGS__ ) -#define PASS_THROUGH_BODY(_fname, _patharg, ...) \ - { \ - CALLTRACEV("%s\n", __FUNCTION__); \ - char pathBuf[PATH_MAX]; \ - return _ws_##_fname(rewritePath(#_fname, pathBuf, _patharg), \ - ##__VA_ARGS__); \ - } - - -PASS_THROUGH_DECL(chdir, int, const char* path) -PASS_THROUGH_BODY(chdir, path) - -PASS_THROUGH_DECL(chmod, int, const char* path, mode_t mode) -PASS_THROUGH_BODY(chmod, path, mode) - -PASS_THROUGH_DECL(chown, int, const char* path, uid_t owner, gid_t group) -PASS_THROUGH_BODY(chown, path, owner, group) - -PASS_THROUGH_DECL(creat, int, const char* path, mode_t mode) -PASS_THROUGH_BODY(creat, path, mode) - -PASS_THROUGH_DECL(execve, int, const char* path, char* const argv[], - char* const envp[]) -PASS_THROUGH_BODY(execve, path, argv, envp) - -PASS_THROUGH_DECL(lchown, int, const char* path, uid_t owner, gid_t group) -PASS_THROUGH_BODY(lchown, path, owner, group) - -PASS_THROUGH_DECL(lstat, int, const char* path, struct stat* buf) -PASS_THROUGH_BODY(lstat, path, buf) - -PASS_THROUGH_DECL(lstat64, int, const char* path, struct stat* buf) -PASS_THROUGH_BODY(lstat64, path, buf) - -PASS_THROUGH_DECL(mkdir, int, const char* path, mode_t mode) -PASS_THROUGH_BODY(mkdir, path, mode) - -PASS_THROUGH_DECL(readlink, ssize_t, const char* path, char* buf, size_t bufsiz) -PASS_THROUGH_BODY(readlink, path, buf, bufsiz) - -PASS_THROUGH_DECL(rmdir, int, const char* path) -PASS_THROUGH_BODY(rmdir, path) - -PASS_THROUGH_DECL(stat, int, const char* path, struct stat* buf) -PASS_THROUGH_BODY(stat, path, buf) - -PASS_THROUGH_DECL(stat64, int, const char* path, struct stat* buf) -PASS_THROUGH_BODY(stat64, path, buf) - -PASS_THROUGH_DECL(statfs, int, const char* path, struct statfs* buf) -PASS_THROUGH_BODY(statfs, path, buf) - -PASS_THROUGH_DECL(statfs64, int, const char* path, struct statfs* buf) -PASS_THROUGH_BODY(statfs64, path, buf) - -PASS_THROUGH_DECL(unlink, int, const char* path) -PASS_THROUGH_BODY(unlink, path) - -PASS_THROUGH_DECL(utime, int, const char* path, const struct utimbuf* buf) -PASS_THROUGH_BODY(utime, path, buf) - -PASS_THROUGH_DECL(utimes, int, const char* path, const struct timeval times[2]) -PASS_THROUGH_BODY(utimes, path, times) - - -PASS_THROUGH_DECL(fopen, FILE*, const char* path, const char* mode) -PASS_THROUGH_BODY(fopen, path, mode) - -PASS_THROUGH_DECL(fopen64, FILE*, const char* path, const char* mode) -PASS_THROUGH_BODY(fopen64, path, mode) - -PASS_THROUGH_DECL(freopen, FILE*, const char* path, const char* mode, - FILE* stream) -PASS_THROUGH_BODY(freopen, path, mode, stream) - -PASS_THROUGH_DECL(ftw, int, const char* dirpath, - int (*fn) (const char* fpath, const struct stat* sb, int typeflag), - int nopenfd) -PASS_THROUGH_BODY(ftw, dirpath, fn, nopenfd) - -PASS_THROUGH_DECL(opendir, DIR*, const char* path) -PASS_THROUGH_BODY(opendir, path) - -PASS_THROUGH_DECL(dlopen, void*, const char* path, int flag) -PASS_THROUGH_BODY(dlopen, path, flag) - -/* - * Opposite of path translation -- remove prefix. - * - * It looks like BSD allows you to pass a NULL value for "buf" to inspire - * getcwd to allocate storage with malloc() (as an extension to the POSIX - * definition, which doesn't specify this). getcwd() is a system call - * under Linux, so this doesn't work, but that doesn't stop gdb from - * trying to use it anyway. - */ -char* getcwd(char* buf, size_t size) -{ - CALLTRACEV("%s %p %d\n", __FUNCTION__, buf, size); - - char* result = _ws_getcwd(buf, size); - if (buf != NULL && result != NULL) { - if (memcmp(buf, gWrapSim.remapBaseDir, - gWrapSim.remapBaseDirLen) == 0) - { - memmove(buf, buf + gWrapSim.remapBaseDirLen, - strlen(buf + gWrapSim.remapBaseDirLen)+1); - CALLTRACE("rewrite getcwd() -> %s\n", result); - } else { - CALLTRACE("not rewriting getcwd(%s)\n", result); - } - } - return result; -} - -/* - * Need to tweak both pathnames. - */ -int link(const char* oldPath, const char* newPath) -{ - CALLTRACEV("%s\n", __FUNCTION__); - - char pathBuf1[PATH_MAX]; - char pathBuf2[PATH_MAX]; - return _ws_link(rewritePath("link-1", pathBuf1, oldPath), - rewritePath("link-2", pathBuf2, newPath)); -} - -/* - * Need to tweak both pathnames. - */ -int rename(const char* oldPath, const char* newPath) -{ - CALLTRACEV("%s\n", __FUNCTION__); - - char pathBuf1[PATH_MAX]; - char pathBuf2[PATH_MAX]; - return _ws_rename(rewritePath("rename-1", pathBuf1, oldPath), - rewritePath("rename-2", pathBuf2, newPath)); -} - -/* - * Need to tweak both pathnames. - */ -int symlink(const char* oldPath, const char* newPath) -{ - CALLTRACEV("%s\n", __FUNCTION__); - - char pathBuf1[PATH_MAX]; - char pathBuf2[PATH_MAX]; - return _ws_symlink(rewritePath("symlink-1", pathBuf1, oldPath), - rewritePath("symlink-2", pathBuf2, newPath)); -} - -/* - * glibc stat turns into this (32-bit). - */ -int __xstat(int version, const char* path, struct stat* sbuf) -{ - CALLTRACEV("%s\n", __FUNCTION__); - char pathBuf[PATH_MAX]; - return _ws___xstat(version, rewritePath("__xstat", pathBuf, path), - sbuf); -} - -/* - * glibc stat turns into this (64-bit). - */ -int __xstat64(int version, const char* path, struct stat* sbuf) -{ - CALLTRACEV("%s\n", __FUNCTION__); - char pathBuf[PATH_MAX]; - return _ws___xstat64(version, rewritePath("__xstat64", pathBuf, path), - sbuf); -} - -/* - * glibc lstat turns into this (32-bit). - */ -int __lxstat(int version, const char* path, struct stat* sbuf) -{ - CALLTRACEV("%s\n", __FUNCTION__); - char pathBuf[PATH_MAX]; - return _ws___lxstat(version, rewritePath("__lxstat", pathBuf, path), - sbuf); -} - -/* - * glibc lstat turns into this (64-bit). - */ -int __lxstat64(int version, const char* path, struct stat* sbuf) -{ - CALLTRACEV("%s\n", __FUNCTION__); - char pathBuf[PATH_MAX]; - return _ws___lxstat64(version, rewritePath("__lxstat64", pathBuf, path), - sbuf); -} - -/* - * Copy the argument list out of varargs for execl/execlp/execle. This - * leaves the argc value in _argc, and a NULL-terminated array of character - * pointers in _argv. We stop at the first NULL argument, so we shouldn't - * end up copying "envp" out. - * - * We could use gcc __builtin_apply_args to just pass stuff through, - * but that may not get along with the path rewriting. It's unclear - * whether we want to rewrite the first argument (i.e. the string that - * becomes argv[0]); it only makes sense if the exec'ed program is also - * getting remapped. - */ -#define COPY_EXEC_ARGLIST(_first, _argc, _argv) \ - int _argc = 0; \ - { \ - va_list vargs; \ - va_start(vargs, _first); \ - while (1) { \ - _argc++; \ - const char* val = va_arg(vargs, const char*); \ - if (val == NULL) \ - break; \ - } \ - va_end(vargs); \ - } \ - const char* _argv[_argc+1]; \ - _argv[0] = _first; \ - { \ - va_list vargs; \ - int i; \ - va_start(vargs, _first); \ - for (i = 1; i < _argc; i++) { \ - _argv[i] = va_arg(vargs, const char*); \ - } \ - va_end(vargs); \ - } \ - _argv[_argc] = NULL; - -/* - * Debug dump. - */ -static void dumpExecArgs(const char* callName, const char* path, - int argc, const char* argv[], char* const envp[]) -{ - int i; - - CALLTRACE("Calling %s '%s' (envp=%p)\n", callName, path, envp); - for (i = 0; i <= argc; i++) - CALLTRACE(" %d: %s\n", i, argv[i]); -} - -/* - * Extract varargs, convert paths, hand off to execv. - */ -int execl(const char* path, const char* arg, ...) -{ - CALLTRACEV("%s\n", __FUNCTION__); - - char pathBuf[PATH_MAX]; - - COPY_EXEC_ARGLIST(arg, argc, argv); - dumpExecArgs("execl", path, argc, argv, NULL); - path = rewritePath("execl", pathBuf, path); - return _ws_execv(path, (char* const*) argv); -} - -/* - * Extract varargs, convert paths, hand off to execve. - * - * The execle prototype in the man page isn't valid C -- it shows the - * "envp" argument after the "...". We have to pull it out with the rest - * of the varargs. - */ -int execle(const char* path, const char* arg, ...) -{ - CALLTRACEV("%s\n", __FUNCTION__); - - char pathBuf[PATH_MAX]; - - COPY_EXEC_ARGLIST(arg, argc, argv); - - /* run through again and find envp */ - char* const* envp; - - va_list vargs; - va_start(vargs, arg); - while (1) { - const char* val = va_arg(vargs, const char*); - if (val == NULL) { - envp = va_arg(vargs, char* const*); - break; - } - } - va_end(vargs); - - dumpExecArgs("execle", path, argc, argv, envp); - path = rewritePath("execl", pathBuf, path); - - return _ws_execve(path, (char* const*) argv, envp); -} - -/* - * Extract varargs, convert paths, hand off to execvp. - */ -int execlp(const char* file, const char* arg, ...) -{ - CALLTRACEV("%s\n", __FUNCTION__); - - char pathBuf[PATH_MAX]; - - COPY_EXEC_ARGLIST(arg, argc, argv); - dumpExecArgs("execlp", file, argc, argv, NULL); - file = rewritePath("execlp", pathBuf, file); - return _ws_execvp(file, (char* const*) argv); -} - -/* - * Update path, forward to execv. - */ -int execv(const char* path, char* const argv[]) -{ - CALLTRACEV("%s\n", __FUNCTION__); - - char pathBuf[PATH_MAX]; - - path = rewritePath("execv", pathBuf, path); - return _ws_execv(path, argv); -} - -/* - * Shouldn't need to do anything unless they specified a full path to execvp. - */ -int execvp(const char* file, char* const argv[]) -{ - CALLTRACEV("%s\n", __FUNCTION__); - - char pathBuf[PATH_MAX]; - - file = rewritePath("execvp", pathBuf, file); - return _ws_execvp(file, argv); -} - - -/* - * =========================================================================== - * Device fakery - * =========================================================================== - */ - -/* - * Need to do filesystem translation and show fake devices. - */ -int access(const char* pathName, int mode) -{ - CALLTRACEV("%s\n", __FUNCTION__); - - int status = wsInterceptDeviceAccess(pathName, mode); - if (status == 0) - return 0; - else if (status == -2) - return -1; // errno already set - else { - char pathBuf[PATH_MAX]; - return _ws_access(rewritePath("access", pathBuf, pathName), mode); - } -} - -/* - * Common handler for open(). - */ -int openCommon(const char* pathName, int flags, mode_t mode) -{ - char pathBuf[PATH_MAX]; - int fd; - - assert(gWrapSim.initialized); - - fd = wsInterceptDeviceOpen(pathName, flags); - if (fd >= 0) { - return fd; - } else if (fd == -2) { - /* errno should be set */ - return -1; - } - - if ((flags & O_CREAT) != 0) { - fd = _ws_open(rewritePath("open", pathBuf, pathName), flags, mode); - CALLTRACE("open(%s, 0x%x, 0%o) = %d\n", pathName, flags, mode, fd); - } else { - fd = _ws_open(rewritePath("open", pathBuf, pathName), flags, 0); - CALLTRACE("open(%s, 0x%x) = %d\n", pathName, flags, fd); - } - return fd; -} - -/* - * Replacement open() and variants. - * - * We have to use the vararg decl for the standard call so it matches - * the definition in fcntl.h. - */ -int open(const char* pathName, int flags, ...) -{ - CALLTRACEV("%s\n", __FUNCTION__); - - mode_t mode = 0; - if ((flags & O_CREAT) != 0) { - va_list args; - - va_start(args, flags); - mode = va_arg(args, mode_t); - va_end(args); - } - - return openCommon(pathName, flags, mode); -} -int __open(const char* pathName, int flags, mode_t mode) -{ - CALLTRACEV("%s\n", __FUNCTION__); - - return openCommon(pathName, flags, mode); -} - -/* - * Common handler for open64(). - */ -int open64Common(const char* pathName, int flags, mode_t mode) -{ - char pathBuf[PATH_MAX]; - int fd; - - assert(gWrapSim.initialized); - - fd = wsInterceptDeviceOpen(pathName, flags); - if (fd >= 0) { - return fd; - } - - if ((flags & O_CREAT) != 0) { - fd = _ws_open64(rewritePath("open64", pathBuf, pathName), flags, mode); - CALLTRACE("open64(%s, 0x%x, 0%o) = %d\n", pathName, flags, mode, fd); - } else { - fd = _ws_open64(rewritePath("open64", pathBuf, pathName), flags, 0); - CALLTRACE("open64(%s, 0x%x) = %d\n", pathName, flags, fd); - } - return fd; -} - -/* - * Replacement open64() and variants. - * - * We have to use the vararg decl for the standard call so it matches - * the definition in fcntl.h. - */ -int open64(const char* pathName, int flags, ...) -{ - CALLTRACEV("%s\n", __FUNCTION__); - - mode_t mode = 0; - if ((flags & O_CREAT) != 0) { - va_list args; - - va_start(args, flags); - mode = va_arg(args, mode_t); - va_end(args); - } - return open64Common(pathName, flags, mode); -} -int __open64(const char* pathName, int flags, mode_t mode) -{ - CALLTRACEV("%s\n", __FUNCTION__); - - return open64Common(pathName, flags, mode); -} - - -/* - * Close a file descriptor. - */ -int close(int fd) -{ - CALLTRACEV("%s(%d)\n", __FUNCTION__, fd); - - FakeDev* dev = wsFakeDevFromFd(fd); - if (dev != NULL) { - int result = dev->close(dev, fd); - wsFreeFakeDev(dev); - return result; - } else { - CALLTRACE("close(%d)\n", fd); - return _ws_close(fd); - } -} - -/* - * Map a region. - */ -void* mmap(void* start, size_t length, int prot, int flags, int fd, - __off_t offset) -{ - CALLTRACEV("%s\n", __FUNCTION__); - - FakeDev* dev = wsFakeDevFromFd(fd); - if (dev != NULL) { - return dev->mmap(dev, start, length, prot, flags, fd, offset); - } else { - CALLTRACE("mmap(%p, %d, %d, %d, %d, %d)\n", - start, (int) length, prot, flags, fd, (int) offset); - return _ws_mmap(start, length, prot, flags, fd, offset); - } -} - -/* - * Map a region. - */ -void* mmap64(void* start, size_t length, int prot, int flags, int fd, - __off64_t offset) -{ - CALLTRACEV("%s\n", __FUNCTION__); - - FakeDev* dev = wsFakeDevFromFd(fd); - if (dev != NULL) { - return dev->mmap(dev, start, length, prot, flags, fd, (__off_t) offset); - } else { - CALLTRACE("mmap64(%p, %d, %d, %d, %d, %d)\n", - start, (int) length, prot, flags, fd, (int) offset); - return _ws_mmap(start, length, prot, flags, fd, offset); - } -} - -/* - * The Linux headers show this with a vararg header, but as far as I can - * tell the kernel always expects 3 args. - */ -int ioctl(int fd, int request, ...) -{ - CALLTRACEV("%s(%d, %d, ...)\n", __FUNCTION__, fd, request); - - FakeDev* dev = wsFakeDevFromFd(fd); - va_list args; - void* argp; - - /* extract argp from varargs */ - va_start(args, request); - argp = va_arg(args, void*); - va_end(args); - - if (dev != NULL) { - return dev->ioctl(dev, fd, request, argp); - } else { - CALLTRACE("ioctl(%d, 0x%x, %p)\n", fd, request, argp); - return _ws_ioctl(fd, request, argp); - } -} - -/* - * Read data. - */ -ssize_t read(int fd, void* buf, size_t count) -{ - CALLTRACEV("%s\n", __FUNCTION__); - - FakeDev* dev = wsFakeDevFromFd(fd); - if (dev != NULL) { - return dev->read(dev, fd, buf, count); - } else { - CALLTRACE("read(%d, %p, %u)\n", fd, buf, count); - return _ws_read(fd, buf, count); - } -} - -/* - * Write data. - */ -ssize_t write(int fd, const void* buf, size_t count) -{ - CALLTRACEV("%s\n", __FUNCTION__); - - FakeDev* dev = wsFakeDevFromFd(fd); - if (dev != NULL) { - return dev->write(dev, fd, buf, count); - } else { - CALLTRACE("write(%d, %p, %u)\n", fd, buf, count); - return _ws_write(fd, buf, count); - } -} - -/* - * Read a data vector. - */ -ssize_t readv(int fd, const struct iovec* vector, int count) -{ - CALLTRACEV("%s\n", __FUNCTION__); - - FakeDev* dev = wsFakeDevFromFd(fd); - if (dev != NULL) { - return dev->readv(dev, fd, vector, count); - } else { - CALLTRACE("readv(%d, %p, %u)\n", fd, vector, count); - return _ws_readv(fd, vector, count); - } -} - -/* - * Write a data vector. - */ -ssize_t writev(int fd, const struct iovec* vector, int count) -{ - CALLTRACEV("%s\n", __FUNCTION__); - - FakeDev* dev = wsFakeDevFromFd(fd); - if (dev != NULL) { - return dev->writev(dev, fd, vector, count); - } else { - CALLTRACE("writev(%d, %p, %u)\n", fd, vector, count); - return _ws_writev(fd, vector, count); - } -} - -/* - * Set the scheduling priority. The sim doesn't run as root, so we have - * to fake this out. - * - * For now, do some basic verification of the which and who parameters, - * but otherwise return success. In the future we may want to track - * these so getpriority works. - */ -int setpriority(__priority_which_t which, id_t who, int what) -{ - CALLTRACEV("%s\n", __FUNCTION__); - - if (which != PRIO_PROCESS && - which != PRIO_PGRP && - which != PRIO_USER) { - return EINVAL; - } - - if ((int)who < 0) { - return ESRCH; - } - - return 0; -} - -#if 0 -/* - * Create a pipe. (Only needed for debugging an fd leak.) - */ -int pipe(int filedes[2]) -{ - CALLTRACEV("%s\n", __FUNCTION__); - - int result = _ws_pipe(filedes); - if (result == 0) - CALLTRACE("pipe(%p) -> %d,%d\n", filedes, filedes[0], filedes[1]); - if (filedes[0] == 83) - abort(); - return result; -} -#endif diff --git a/simulator/wrapsim/LaunchWrapper.c b/simulator/wrapsim/LaunchWrapper.c deleted file mode 100644 index c4f0efbb5..000000000 --- a/simulator/wrapsim/LaunchWrapper.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright 2007 The Android Open Source Project - * - * Launch the specified program and, if "-wait" was specified, wait for it - * to exit. - * - * When in "wait mode", print a message indicating the exit status, then - * wait for Ctrl-C before we exit. This is useful if we were launched - * with "xterm -e", because it lets us see the output before the xterm bails. - * - * We want to ignore signals while waiting, so Ctrl-C kills the child rather - * than us, but we need to configure the signals *after* the fork() so we - * don't block them for the child too. - */ -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <limits.h> -#include <fcntl.h> -#include <errno.h> -#include <assert.h> - -/* - * This is appended to $ANDROID_PRODUCT_OUT, - * e.g. "/work/device/out/debug/host/linux-x8x/product/sim". - */ -static const char* kWrapLib = "/system/lib/libwrapsim.so"; - - -/* - * Configure LD_PRELOAD if possible. - * - * Returns newly-allocated storage with the preload path. - */ -static char* configurePreload(void) -{ - const char* outEnv = getenv("ANDROID_PRODUCT_OUT"); - const char* preloadEnv = getenv("LD_PRELOAD"); - char* preload = NULL; - - if (preloadEnv != NULL) { - /* TODO: append our stuff to existing LD_PRELOAD string */ - fprintf(stderr, - "LW WARNING: LD_PRELOAD already set, not adding libwrapsim\n"); - } else if (outEnv == NULL || *outEnv == '\0') { - fprintf(stderr, "LW WARNING: " - "$ANDROID_PRODUCT_OUT not in env, not setting LD_PRELOAD\n"); - } else { - preload = (char*) malloc(strlen(outEnv) + strlen(kWrapLib) +1); - sprintf(preload, "%s%s", outEnv, kWrapLib); - setenv("LD_PRELOAD", preload, 1); - printf("LW: launching with LD_PRELOAD=%s\n", preload); - } - - /* Let the process know that it's executing inside this LD_PRELOAD - * wrapper. - */ - setenv("ANDROID_WRAPSIM", "1", 1); - - return preload; -} - -/* - * Configure some environment variables that the runtime wants. - * - * Returns 0 if all goes well. - */ -static int configureEnvironment() -{ - const char* outEnv = getenv("ANDROID_PRODUCT_OUT"); - char pathBuf[PATH_MAX]; - int outLen; - - if (outEnv == NULL || *outEnv == '\0') { - fprintf(stderr, "LW WARNING: " - "$ANDROID_PRODUCT_OUT not in env, not configuring environment\n"); - return 1; - } - outLen = strlen(outEnv); - assert(outLen + 64 < PATH_MAX); - memcpy(pathBuf, outEnv, outLen); - strcpy(pathBuf + outLen, "/system/lib"); - - /* - * Linux wants LD_LIBRARY_PATH - * Mac OS X wants DYLD_LIBRARY_PATH - * gdb under Mac OS X tramples on both of the above, so we added - * ANDROID_LIBRARY_PATH as a workaround. - * - * We're only supporting Linux now, so just set LD_LIBRARY_PATH. Note - * this stomps the existing value, if any. - * - * If we only needed this for System.loadLibrary() we could do it later, - * but we need it to get the runtime started. - */ - printf("LW: setting LD_LIBRARY_PATH=%s\n", pathBuf); - setenv("LD_LIBRARY_PATH", pathBuf, 1); - - /* - * Trusted certificates are found, for some bizarre reason, through - * the JAVA_HOME environment variable. We don't need to set this - * here, but it's convenient to do so. - */ - strcpy(pathBuf /*+ outLen*/, "/system"); - printf("LW: setting JAVA_HOME=%s\n", pathBuf); - setenv("JAVA_HOME", pathBuf, 1); - - return 0; -} - -/* - * Redirect stdout/stderr to the specified file. If "fileName" is NULL, - * this returns successfully without doing anything. - * - * Returns 0 on success. - */ -static int redirectStdio(const char* fileName) -{ - int fd; - - if (fileName == NULL) - return 0; - - printf("Redirecting stdio to append to '%s'\n", fileName); - fflush(stdout); - fflush(stderr); - - fd = open(fileName, O_WRONLY | O_APPEND | O_CREAT, 0666); - if (fd < 0) { - fprintf(stderr, "ERROR: unable to open '%s' for writing\n", - fileName); - return 1; - } - dup2(fd, 1); - dup2(fd, 2); - close(fd); - - return 0; -} - -/* - * Launch the requested process directly. - * - * On success this does not return (ever). - */ -static int launch(char* argv[], const char* outputFile) -{ - (void) configurePreload(); - (void) redirectStdio(outputFile); - execvp(argv[0], argv); - fprintf(stderr, "execvp %s failed: %s\n", argv[0], strerror(errno)); - return 1; -} - -/* - * Launch in a sub-process and wait for it to finish. - */ -static int launchWithWait(char* argv[], const char* outputFile) -{ - pid_t child; - - child = fork(); - if (child < 0) { - fprintf(stderr, "fork() failed: %s\n", strerror(errno)); - return 1; - } else if (child == 0) { - /* - * This is the child, set up LD_PRELOAD if possible and launch. - */ - (void) configurePreload(); - (void) redirectStdio(outputFile); - execvp(argv[0], argv); - fprintf(stderr, "execvp %s failed: %s\n", argv[0], strerror(errno)); - return 1; - } else { - pid_t result; - int status; - - signal(SIGINT, SIG_IGN); - signal(SIGQUIT, SIG_IGN); - - while (1) { - printf("LW: in pid %d (grp=%d), waiting on pid %d\n", - (int) getpid(), (int) getpgrp(), (int) child); - result = waitpid(child, &status, 0); - if (result < 0) { - if (errno == EINTR) { - printf("Hiccup!\n"); - continue; - } else { - fprintf(stderr, "waitpid failed: %s\n", strerror(errno)); - return 1; - } - } else if (result != child) { - fprintf(stderr, "bizarre: waitpid returned %d (wanted %d)\n", - result, child); - return 1; - } else { - break; - } - } - - printf("\n"); - if (WIFEXITED(status)) { - printf("LW: process exited (status=%d)", WEXITSTATUS(status)); - } else if (WIFSIGNALED(status)) { - printf("LW: process killed by signal %d", WTERMSIG(status)); - } else { - printf("LW: process freaked out, status=0x%x\n", status); - } - if (WCOREDUMP(status)) { - printf(" (core dumped)"); - } - printf("\n"); - - signal(SIGINT, SIG_DFL); - signal(SIGQUIT, SIG_DFL); - - /* - * The underlying process may have changed process groups and pulled - * itself into the foreground. Now that it's gone, pull ourselves - * back into the foreground. - */ - signal(SIGTTOU, SIG_IGN); - if (tcsetpgrp(fileno(stdin), getpgrp()) != 0) - fprintf(stderr, "WARNING: tcsetpgrp failed\n"); - - printf("\nHit Ctrl-C or close window.\n"); - - while (1) { - sleep(10); - } - - /* not reached */ - return 0; - } -} - - -/* - * All args are passed through. - */ -int main(int argc, char** argv) -{ - int waitForChild = 0; - const char* outputFile = NULL; - int result; - - /* - * Skip past the reference to ourselves, and check for args. - */ - argv++; - argc--; - while (argc > 0) { - if (strcmp(argv[0], "-wait") == 0) { - waitForChild = 1; - } else if (strcmp(argv[0], "-output") == 0 && argc > 1) { - argv++; - argc--; - outputFile = argv[0]; - } else { - /* no more args for us */ - break; - } - - argv++; - argc--; - } - - if (argc == 0) { - fprintf(stderr, - "Usage: launch-wrapper [-wait] [-output filename] <cmd> [args...]\n"); - result = 2; - goto bail; - } - - /* - * Configure some environment variables. - */ - if (configureEnvironment() != 0) { - result = 1; - goto bail; - } - - /* - * Launch. - */ - if (waitForChild) - result = launchWithWait(argv, outputFile); - else - result = launch(argv, outputFile); - -bail: - if (result != 0) - sleep(2); - return result; -} - diff --git a/simulator/wrapsim/Log.c b/simulator/wrapsim/Log.c deleted file mode 100644 index 7edb6771a..000000000 --- a/simulator/wrapsim/Log.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2007 The Android Open Source Project - * - * Debug-logging code. - */ -#include "Common.h" - -#include <stdio.h> -#include <stdarg.h> -#include <time.h> - -/* - * Write a message to our private log file. This is a little awkward since - * some or all of the system calls we want to use are being intercepted. - */ -void wsLog(const char* format, ...) -{ -#if defined(HAVE_LOCALTIME_R) - struct tm tmBuf; -#endif - struct tm* ptm; - time_t now; - char timeBuf[32]; - char prefixBuf[64]; - int prefixLen; - char msgBuf[256]; - int msgLen; - - if (gWrapSim.logFd < 0) - return; - - /* - * Create a prefix with a timestamp. - */ - now = time(NULL); -#if defined(HAVE_LOCALTIME_R) - ptm = localtime_r(&now, &tmBuf); -#else - ptm = localtime(&now); -#endif - //strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm); - strftime(timeBuf, sizeof(timeBuf), "%H:%M:%S", ptm); - - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), "%s %5d ", - timeBuf, (int) getpid()); - - /* - * Format the message into a buffer. - */ - va_list args; - - va_start(args, format); - msgLen = vsnprintf(msgBuf, sizeof(msgBuf), format, args); - va_end(args); - - /* if we overflowed, trim and annotate */ - if (msgLen >= (int) sizeof(msgBuf)) { - msgBuf[sizeof(msgBuf)-2] = '!'; - msgBuf[sizeof(msgBuf)-1] = '\n'; - msgLen = sizeof(msgBuf); - } - - /* - * Write the whole thing in one shot. The log file was opened with - * O_APPEND so we don't have to worry about clashes. - */ - struct iovec logVec[2]; - logVec[0].iov_base = prefixBuf; - logVec[0].iov_len = prefixLen; - logVec[1].iov_base = msgBuf; - logVec[1].iov_len = msgLen; - (void) _ws_writev(gWrapSim.logFd, logVec, 2); -} - diff --git a/simulator/wrapsim/Log.h b/simulator/wrapsim/Log.h deleted file mode 100644 index 024ba4459..000000000 --- a/simulator/wrapsim/Log.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2007 The Android Open Source Project - * - * Logging. - */ -#ifndef _WRAPSIM_LOG_H -#define _WRAPSIM_LOG_H - - -/* - * Log debug info. - */ -void wsLog(const char* format, ...) - #if defined(__GNUC__) - __attribute__ ((format(printf, 1, 2))) - #endif - ; - -#endif /*_WRAPSIM_LOG_H*/ diff --git a/simulator/wrapsim/README.txt b/simulator/wrapsim/README.txt deleted file mode 100644 index 358c06c4a..000000000 --- a/simulator/wrapsim/README.txt +++ /dev/null @@ -1,21 +0,0 @@ -This shared library is used with LD_PRELOAD to wrap the Android runtime -when used with the desktop simulator. - -Because LD_PRELOAD is part of the environment when gdb and valgrind are -invoked, the wrapper can "see" activity from both of these (more so gdb -than valgrind). For this reason it needs to be very careful about which -"open" calls are intercepted. - -It's also important that none of the intercepted system or library calls -are invoked directly, or infinite recursion could result. - -Avoid creating dependencies on other libraries. - - -To debug wrapsim, set WRAPSIM_LOG to a log file before launching, e.g. - -% WRAPSIM_LOG=/tmp/wraplog.txt simulator - -For more verbose logging, you can enable the verbose forms of CALLTRACE -and CALLTRACEV in Intercept.c. - diff --git a/simulator/wrapsim/SimMgr.c b/simulator/wrapsim/SimMgr.c deleted file mode 100644 index a35c7c6ad..000000000 --- a/simulator/wrapsim/SimMgr.c +++ /dev/null @@ -1,988 +0,0 @@ -/* - * Copyright 2007 The Android Open Source Project - * - * Simulator interactions. - * - * TODO: for multi-process we probably need to switch to a new process - * group if we are the first process (could be runtime, could be gdb), - * rather than wait for the simulator to tell us to switch. - */ -#include "Common.h" - -#include <stdlib.h> -#include <stdio.h> -#include <stdint.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/ipc.h> -#include <sys/shm.h> -#include <sys/sem.h> -#include <sys/un.h> -#include <signal.h> -#include <assert.h> - -// fwd -static int connectToSim(void); -static void listenToSim(void); - -/* - * Env var to restrict who tries to talk to the front end. - */ -#define kWrapSimConnectedEnv "WRAP_SIM_CONNECTED" - - -/* - * Signal the main thread that we're ready to continue. - */ -static void signalMainThread(void) -{ - int cc; - - cc = pthread_mutex_lock(&gWrapSim.startLock); - assert(cc == 0); - - gWrapSim.startReady = 1; - - cc = pthread_cond_signal(&gWrapSim.startCond); - assert(cc == 0); - - cc = pthread_mutex_unlock(&gWrapSim.startLock); - assert(cc == 0); -} - - -/* - * Entry point for the sim management thread. - * - * Once we have established a connection to the simulator and are ready - * for other threads to send messages, we signal the main thread. - */ -static void* simThreadEntry(void* arg) -{ - wsLog("--- sim manager thread started\n"); - - /* - * Establish a connection to the simulator front-end. If we can't do - * that, we have no access to input or output devices, and we might - * as well give up. - */ - if (connectToSim() != 0) { - signalMainThread(); - return NULL; - } - - /* success! */ - wsLog("--- sim manager thread ready\n"); - gWrapSim.simulatorInitFailed = 0; - signalMainThread(); - - listenToSim(); - - wsLog("--- sim manager thread exiting\n"); - - return NULL; -} - -/* - * If we think we're not yet connected to the sim, do so now. We only - * want to do this once per process *group*, so we control access with - * an environment variable. - */ -int wsSimConnect(void) -{ - /* - * If the environment variable hasn't been set, assume we're the first - * to get here, and should attach to the simulator. We set the env - * var here whether or not we succeed in connecting to the sim. - * - * (For correctness we should wrap the getenv/setenv in a semaphore.) - */ - if (getenv(kWrapSimConnectedEnv) == NULL) { - pthread_attr_t threadAttr; - pthread_t threadHandle; - int cc; - - gWrapSim.simulatorInitFailed = 1; - setenv(kWrapSimConnectedEnv, "1", 1); - - cc = pthread_mutex_lock(&gWrapSim.startLock); - assert(cc == 0); - - pthread_attr_init(&threadAttr); - pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED); - cc = pthread_create(&threadHandle, &threadAttr, simThreadEntry, NULL); - if (cc != 0) { - wsLog("Unable to create new thread: %s\n", strerror(errno)); - abort(); - } - - while (!gWrapSim.startReady) { - cc = pthread_cond_wait(&gWrapSim.startCond, &gWrapSim.startLock); - assert(cc == 0); - } - - cc = pthread_mutex_unlock(&gWrapSim.startLock); - assert(cc == 0); - - if (gWrapSim.simulatorInitFailed) { - wsLog("Simulator initialization failed, bailing\n"); - - /* this *should* be okay to do */ - fprintf(stderr, "Fatal error:" - " unable to connect to sim front-end (not running?)\n"); - abort(); - } - } - - wsLog("+++ continuing\n"); - return 0; -} - - -/* - * =========================================================================== - * Message / MessageStream - * =========================================================================== - */ - -/* - * This is a quick & dirty rewrite of the C++ Message and MessageStream - * classes, ported to C, reduced in generality, with syscalls stubbed - * where necessary. I didn't fix the API to make it more sensible in C - * (which lacks destructors), so some of this is a little fragile or - * awkward. - */ - -/* values for message type byte; must match android::Message constants */ -typedef enum MessageType { - kTypeUnknown = 0, - kTypeRaw, // chunk of raw data - kTypeConfig, // send a name=value pair to peer - kTypeCommand, // simple command w/arg - kTypeCommandExt, // slightly more complicated command - kTypeLogBundle, // multi-part log message -} MessageType; - -/* - * Reusable message object. - */ -typedef struct Message { - MessageType mType; - unsigned char* mData; - int mLength; -} Message; - -/* magic init messages; must match android::MessageStream constants */ -enum { - kHelloMsg = 0x4e303047, // 'N00G' - kHelloAckMsg = 0x31455221, // '1ER!' -}; - - -/* - * Clear out a Message. - */ -static void Message_clear(Message* msg) -{ - memset(msg, 0, sizeof(Message)); -} - -/* - * Keep reading until we get all bytes or hit EOF/error. "fd" is expected - * to be in blocking mode. - * - * Returns 0 on success. - */ -static int readAll(int fd, void* buf, size_t count) -{ - ssize_t actual; - ssize_t have; - - have = 0; - while (have != (ssize_t) count) { - actual = _ws_read(fd, ((char*) buf) + have, count - have); - if (actual < 0) { - if (errno == EINTR) - continue; - wsLog("read %d failed: %s\n", fd, strerror(errno)); - } else if (actual == 0) { - wsLog("early EOF on %d\n", fd); - return -1; - } else { - have += actual; - } - - assert(have <= (ssize_t)count); - } - - return 0; -} - -#if 0 -/* - * Keep writing until we put all bytes or hit an error. "fd" is expected - * to be in blocking mode. - * - * Returns 0 on success. - */ -static int writeAll(int fd, const void* buf, size_t count) -{ - ssize_t actual; - ssize_t have; - - have = 0; - while (have != count) { - actual = _ws_write(fd, ((const char*) buf) + have, count - have); - if (actual < 0) { - if (errno == EINTR) - continue; - wsLog("write %d failed: %s\n", fd, strerror(errno)); - } else if (actual == 0) { - wsLog("wrote zero on %d\n", fd); - return -1; - } else { - have += actual; - } - - assert(have <= count); - } - - return 0; -} -#endif - -/* - * Read a message from the specified file descriptor. - * - * The caller must Message_release(&msg). - * - * We guarantee 32-bit alignment for msg->mData. - */ -static int Message_read(Message* msg, int fd) -{ - unsigned char header[4]; - - readAll(fd, header, 4); - - msg->mType = (MessageType) header[2]; - msg->mLength = header[0] | header[1] << 8; - msg->mLength -= 2; // we already read two of them in the header - - if (msg->mLength > 0) { - int actual; - - /* Linux malloc guarantees at least 32-bit alignment */ - msg->mData = (unsigned char*) malloc(msg->mLength); - if (msg->mData == NULL) { - wsLog("alloc %d failed\n", msg->mLength); - return -1; - } - - if (readAll(fd, msg->mData, msg->mLength) != 0) { - wsLog("failed reading message body (wanted %d)\n", msg->mLength); - return -1; - } - } else { - msg->mData = NULL; - } - - return 0; -} - -/* - * Write a message to the specified file descriptor. - * - * The caller must Message_release(&msg). - */ -static int Message_write(Message* msg, int fd) -{ - struct iovec writeVec[2]; - unsigned char header[4]; - int len, numVecs; - ssize_t actual; - - len = msg->mLength + 2; - header[0] = len & 0xff; - header[1] = (len >> 8) & 0xff; - header[2] = msg->mType; - header[3] = 0; - writeVec[0].iov_base = header; - writeVec[0].iov_len = 4; - numVecs = 1; - - if (msg->mLength > 0) { - assert(msg->mData != NULL); - writeVec[1].iov_base = msg->mData; - writeVec[1].iov_len = msg->mLength; - numVecs++; - } - - /* write it all in one shot; not worrying about partial writes for now */ - actual = _ws_writev(fd, writeVec, numVecs); - if (actual != len+2) { - wsLog("failed writing message to fd %d: %d of %d %s\n", - fd, actual, len+2, strerror(errno)); - return -1; - } - - return 0; -} - -/* - * Release storage associated with a Message. - */ -static void Message_release(Message* msg) -{ - free(msg->mData); - msg->mData = NULL; -} - -/* - * Extract a name/value pair from a message. - */ -static int getConfig(const Message* msg, const char** name, const char** val) -{ - if (msg->mLength < 2) { - wsLog("message len (%d) is too short\n", msg->mLength); - return -1; - } - const char* ptr = (const char*) msg->mData; - - *name = (const char*) ptr; - *val = (const char*) (ptr + strlen((char*)ptr) +1); - return 0; -} - -/* - * Extract a command from a message. - */ -static int getCommand(const Message* msg, int* pCmd, int* pArg) -{ - if (msg->mLength != sizeof(int) * 2) { - wsLog("message len (%d) is wrong for cmd (%d)\n", - msg->mLength, sizeof(int) * 2); - return -1; - } - - /* this assumes 32-bit alignment on mData */ - const int* ptr = (const int*) msg->mData; - - *pCmd = ptr[0]; - *pArg = ptr[1]; - - return 0; -} - -/* - * Extract an extended command from a message. - */ -static int getCommandExt(const Message* msg, int* pCmd, int* pArg0, - int* pArg1, int* pArg2) -{ - if (msg->mLength != sizeof(int) * 4) { - wsLog("message len (%d) is wrong for cmd (%d)\n", - msg->mLength, sizeof(int) * 4); - return -1; - } - - /* this assumes 32-bit alignment on mData */ - const int* ptr = (const int*) msg->mData; - - *pCmd = ptr[0]; - *pArg0 = ptr[1]; - *pArg1 = ptr[2]; - *pArg2 = ptr[3]; - - return 0; -} - -/* - * Attach 8 bytes of data with "cmd" and "arg" to "msg". - * - * "msg->mData" will need to be freed by the caller. (This approach made - * more sense when C++ destructors were available, but it's just not worth - * reworking it.) - */ -static int setCommand(Message* msg, int cmd, int arg) -{ - Message_clear(msg); - - msg->mLength = 8; - msg->mData = malloc(msg->mLength); - msg->mType = kTypeCommand; - - /* assumes 32-bit alignment on malloc blocks */ - int* pInt = (int*) msg->mData; - pInt[0] = cmd; - pInt[1] = arg; - - return 0; -} - -/* - * Construct the full path. The caller must free() the return value. - */ -static char* makeFilename(const char* name) -{ - static const char* kBasePath = "/tmp/android-"; - char* fileName; - - assert(name != NULL && name[0] != '\0'); - - fileName = (char*) malloc(strlen(kBasePath) + strlen(name) + 1); - strcpy(fileName, kBasePath); - strcat(fileName, name); - - return fileName; -} - -/* - * Attach to a SysV shared memory segment. - */ -static int attachToShmem(int key, int* pShmid, void** pAddr, long* pLength) -{ - int shmid; - - shmid = shmget(key, 0, 0); - if (shmid == -1) { - wsLog("ERROR: failed to find shmem key=%d\n", key); - return -1; - } - - void* addr = shmat(shmid, NULL, 0); - if (addr == (void*) -1) { - wsLog("ERROR: could not attach to key=%d shmid=%d\n", key, shmid); - return -1; - } - - struct shmid_ds shmids; - int cc; - - cc = shmctl(shmid, IPC_STAT, &shmids); - if (cc != 0) { - wsLog("ERROR: could not IPC_STAT shmid=%d\n", shmid); - return -1; - } - *pLength = shmids.shm_segsz; - - *pAddr = addr; - *pShmid = shmid; - return 0; -} - -/* - * Attach to a SysV semaphore. - */ -static int attachToSem(int key, int* pSemid) -{ - int semid; - - semid = semget(key, 0, 0); - if (semid == -1) { - wsLog("ERROR: failed to attach to semaphore key=%d\n", key); - return -1; - } - - *pSemid = semid; - return 0; -} - -/* - * "Adjust" a semaphore. - */ -static int adjustSem(int semid, int adj) -{ - const int wait = 1; - struct sembuf op; - int cc; - - op.sem_num = 0; - op.sem_op = adj; - op.sem_flg = SEM_UNDO; - if (!wait) - op.sem_flg |= IPC_NOWAIT; - - cc = semop(semid, &op, 1); - if (cc != 0) { - if (wait || errno != EAGAIN) { - wsLog("Warning:" - " semaphore adjust by %d failed for semid=%d (errno=%d)\n", - adj, semid, errno); - } - return -1; - } - - return 0; -} - -/* - * Acquire the semaphore associated with a display. - */ -void wsLockDisplay(int displayIdx) -{ - assert(displayIdx >= 0 && displayIdx < gWrapSim.numDisplays); - int semid = gWrapSim.display[displayIdx].semid; - - (void) adjustSem(semid, -1); -} - -/* - * Acquire the semaphore associated with a display. - */ -void wsUnlockDisplay(int displayIdx) -{ - assert(displayIdx >= 0 && displayIdx < gWrapSim.numDisplays); - int semid = gWrapSim.display[displayIdx].semid; - - (void) adjustSem(semid, 1); -} - -/* - * Process the display config from the simulator - * - * Right now this is a blob of raw data that looks like this: - * +00 magic number - * +04 #of displays - * +08 display 0: - * +00 width - * +04 height - * +08 format - * +0c refresh rate - * +10 shmem key - * +1c display 1... - */ -static int handleDisplayConfig(const int* pData, int length) -{ - int numDisplays; - - if (length < 8) { - wsLog("Bad display config: length is %d\n", length); - return -1; - } - assert(*pData == kDisplayConfigMagic); - - /* - * Pull out the #of displays. If it looks valid, configure the runtime. - */ - pData++; // skip over magic - numDisplays = *pData++; - - if (numDisplays <= 0 || numDisplays > kMaxDisplays) { - wsLog("Bizarre display count %d\n", numDisplays); - return -1; - } - if (length != 8 + numDisplays * kValuesPerDisplay * (int)sizeof(int)) { - wsLog("Bad display config: length is %d (expected %d)\n", - length, 8 + numDisplays * kValuesPerDisplay * (int)sizeof(int)); - return -1; - } - - /* - * Extract the config values. - * - * The runtime doesn't support multiple devices, so we don't either. - */ - int i; - for (i = 0; i < numDisplays; i++) { - gWrapSim.display[i].width = pData[0]; - gWrapSim.display[i].height = pData[1]; - gWrapSim.display[i].shmemKey = pData[4]; - /* format/refresh no longer needed */ - - void* addr; - int shmid, semid; - long length; - if (attachToShmem(gWrapSim.display[i].shmemKey, &shmid, &addr, - &length) != 0) - { - wsLog("Unable to connect to shared memory\n"); - return -1; - } - - if (attachToSem(gWrapSim.display[i].shmemKey, &semid) != 0) { - wsLog("Unable to attach to sempahore\n"); - return -1; - } - - gWrapSim.display[i].shmid = shmid; - gWrapSim.display[i].addr = addr; - gWrapSim.display[i].length = length; - gWrapSim.display[i].semid = semid; - - wsLog("Display %d: width=%d height=%d\n", - i, - gWrapSim.display[i].width, - gWrapSim.display[i].height); - wsLog(" shmem=0x%08x addr=%p len=%ld semid=%d\n", - gWrapSim.display[i].shmemKey, - gWrapSim.display[i].addr, - gWrapSim.display[i].length, - gWrapSim.display[i].semid); - - pData += kValuesPerDisplay; - } - gWrapSim.numDisplays = numDisplays; - - return 0; -} - - -/* - * Initialize our connection to the simulator, which will be listening on - * a UNIX domain socket. - * - * On success, this configures gWrapSim.simulatorFd and returns 0. - */ -static int openSimConnection(const char* name) -{ - int result = -1; - char* fileName = NULL; - int sock = -1; - int cc; - - assert(gWrapSim.simulatorFd == -1); - - fileName = makeFilename(name); - - struct sockaddr_un addr; - - sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock < 0) { - wsLog("UNIX domain socket create failed (errno=%d)\n", errno); - goto bail; - } - - /* connect to socket; fails if file doesn't exist */ - strcpy(addr.sun_path, fileName); // max 108 bytes - addr.sun_family = AF_UNIX; - cc = connect(sock, (struct sockaddr*) &addr, SUN_LEN(&addr)); - if (cc < 0) { - // ENOENT means socket file doesn't exist - // ECONNREFUSED means socket exists but nobody is listening - wsLog("AF_UNIX connect failed for '%s': %s\n", - fileName, strerror(errno)); - goto bail; - } - - gWrapSim.simulatorFd = sock; - sock = -1; - - result = 0; - wsLog("+++ connected to '%s'\n", fileName); - -bail: - if (sock >= 0) - _ws_close(sock); - free(fileName); - return result; -} - -/* - * Prepare communication with the front end. We wait for a "hello" from - * the other side, and respond in kind. - */ -static int prepSimConnection(void) -{ - /* NOTE: this is endian-specific; we're x86 Linux only, so no problem */ - static const unsigned int hello = kHelloMsg; - static const unsigned int helloAck = kHelloAckMsg; - Message msg; - - if (Message_read(&msg, gWrapSim.simulatorFd) != 0) { - wsLog("hello read failed\n"); - return -1; - } - - if (memcmp(msg.mData, &hello, 4) != 0) { - wsLog("Got bad hello from peer\n"); - return -1; - } - - Message_release(&msg); - - msg.mType = kTypeRaw; - msg.mData = (unsigned char*) &helloAck; - msg.mLength = 4; - - if (Message_write(&msg, gWrapSim.simulatorFd) != 0) { - wsLog("hello ack write failed\n"); - return -1; - } - - return 0; -} - -/* - * Get the sim front-end configuration. We loop here until the sim claims - * to be done with us. - */ -static int getSimConfig(void) -{ - Message msg; - int joinNewGroup, grabTerminal, done; - int result = -1; - - joinNewGroup = grabTerminal = done = 0; - Message_clear(&msg); // clear out msg->mData - - wsLog("+++ awaiting hardware configuration\n"); - while (!done) { - if (Message_read(&msg, gWrapSim.simulatorFd) != 0) { - wsLog("failed receiving config from parent\n"); - goto bail; - } - - if (msg.mType == kTypeCommand) { - int cmd, arg; - - if (getCommand(&msg, &cmd, &arg) != 0) - goto bail; - - switch (cmd) { - case kCommandGoAway: - wsLog("Simulator front-end is busy\n"); - goto bail; - case kCommandNewPGroup: - joinNewGroup = 1; - grabTerminal = (arg != 0); - wsLog("Simulator wants us to be in a new pgrp (term=%d)\n", - grabTerminal); - break; - case kCommandConfigDone: - done = 1; - break; - default: - wsLog("Got unexpected command %d/%d\n", cmd, arg); - break; - } - } else if (msg.mType == kTypeRaw) { - /* assumes 32-bit alignment and identical byte ordering */ - int* pData = (int*) msg.mData; - if (msg.mLength >= 4 && *pData == kDisplayConfigMagic) { - if (handleDisplayConfig(pData, msg.mLength) != 0) - goto bail; - } - } else if (msg.mType == kTypeConfig) { - const char *name; - const char *val; - getConfig(&msg, &name, &val); - if(strcmp(name, "keycharmap") == 0) { - free((void*)gWrapSim.keyMap); - gWrapSim.keyMap = strdup(val); - } - } else { - wsLog("Unexpected msg type %d during startup\n", msg.mType); - goto bail; - } - - /* clear out the data field if necessary */ - Message_release(&msg); - } - - wsLog("Configuration received from simulator\n"); - - if (joinNewGroup) { - /* set pgid to pid */ - pid_t pgid = getpid(); - setpgid(0, pgid); - - /* - * Put our pgrp in the foreground. - * tcsetpgrp() from background process causes us to get a SIGTTOU, - * which is mostly harmless but makes tcsetpgrp() fail with EINTR. - */ - signal(SIGTTOU, SIG_IGN); - if (grabTerminal) { - if (tcsetpgrp(fileno(stdin), getpgrp()) != 0) { - wsLog("tcsetpgrp(%d, %d) failed (errno=%d)\n", - fileno(stdin), getpgrp(), errno); - } - wsLog("Set pgrp %d as foreground\n", (int) getpgrp()); - } - - /* tell the sim where we're at */ - Message msg; - setCommand(&msg, kCommandNewPGroupCreated, pgid); - Message_write(&msg, gWrapSim.simulatorFd); - Message_release(&msg); - } - - result = 0; - -bail: - /* make sure the data was freed */ - Message_release(&msg); - //wsLog("bailing, result=%d\n", result); - return result; -} - -/* - * Connect to the simulator and exchange pleasantries. - * - * Returns 0 on success. - */ -static int connectToSim(void) -{ - if (openSimConnection(kAndroidPipeName) != 0) - return -1; - - if (prepSimConnection() != 0) - return -1; - - if (getSimConfig() != 0) - return -1; - - wsLog("+++ sim is ready to go\n"); - - return 0; -} - -/* - * Listen to the sim forever or until the front end shuts down, whichever - * comes first. - * - * All we're really getting here are key events. - */ -static void listenToSim(void) -{ - wsLog("--- listening for input events from front end\n"); - - while (1) { - Message msg; - - Message_clear(&msg); - if (Message_read(&msg, gWrapSim.simulatorFd) != 0) { - wsLog("--- sim message read failed\n"); - return; - } - - if (msg.mType == kTypeCommand) { - int cmd, arg; - - if (getCommand(&msg, &cmd, &arg) != 0) { - wsLog("bad command from sim?\n"); - continue; - } - - switch (cmd) { - case kCommandQuit: - wsLog("--- sim sent us a QUIT message\n"); - return; - case kCommandKeyDown: - wsLog("KEY DOWN: %d\n", arg); - wsSendSimKeyEvent(arg, 1); - break; - case kCommandKeyUp: - wsLog("KEY UP: %d\n", arg); - wsSendSimKeyEvent(arg, 0); - break; - default: - wsLog("--- sim sent unrecognized command %d\n", cmd); - break; - } - - Message_release(&msg); - } else if (msg.mType == kTypeCommandExt) { - int cmd, arg0, arg1, arg2; - - if (getCommandExt(&msg, &cmd, &arg0, &arg1, &arg2) != 0) { - wsLog("bad ext-command from sim?\n"); - continue; - } - - switch (cmd) { - case kCommandTouch: - wsSendSimTouchEvent(arg0, arg1, arg2); - break; - } - - Message_release(&msg); - } else { - wsLog("--- sim sent non-command message, type=%d\n", msg.mType); - } - } - - assert(0); // not reached -} - - -/* - * Tell the simulator front-end that the display has been updated. - */ -void wsPostDisplayUpdate(int displayIdx) -{ - if (gWrapSim.simulatorFd < 0) { - wsLog("Not posting display update -- sim not ready\n"); - return; - } - - Message msg; - - setCommand(&msg, kCommandUpdateDisplay, displayIdx); - Message_write(&msg, gWrapSim.simulatorFd); - Message_release(&msg); -} - -/* - * Send a log message to the front-end. - */ -void wsPostLogMessage(int logPrio, const char* tag, const char* message) -{ - if (gWrapSim.simulatorFd < 0) { - wsLog("Not posting log message -- sim not ready\n"); - return; - } - - time_t when = time(NULL); - int pid = (int) getpid(); - int tagLen, messageLen, totalLen; - - tagLen = strlen(tag) +1; - messageLen = strlen(message) +1; - totalLen = sizeof(int) * 3 + tagLen + messageLen; - unsigned char outBuf[totalLen]; - unsigned char* cp = outBuf; - - /* See Message::set/getLogBundle() in simulator/MessageStream.cpp. */ - memcpy(cp, &when, sizeof(int)); - cp += sizeof(int); - memcpy(cp, &logPrio, sizeof(int)); - cp += sizeof(int); - memcpy(cp, &pid, sizeof(int)); - cp += sizeof(int); - memcpy(cp, tag, tagLen); - cp += tagLen; - memcpy(cp, message, messageLen); - cp += messageLen; - - assert(cp - outBuf == totalLen); - - Message msg; - msg.mType = kTypeLogBundle; - msg.mData = outBuf; - msg.mLength = totalLen; - Message_write(&msg, gWrapSim.simulatorFd); - - msg.mData = NULL; // don't free - Message_release(&msg); -} - -/* - * Turn the vibrating notification device on or off. - */ -void wsEnableVibration(int vibrateOn) -{ - if (gWrapSim.simulatorFd < 0) { - wsLog("Not posting vibrator update -- sim not ready\n"); - return; - } - - Message msg; - - //wsLog("+++ sending vibrate:%d\n", vibrateOn); - - setCommand(&msg, kCommandVibrate, vibrateOn); - Message_write(&msg, gWrapSim.simulatorFd); - Message_release(&msg); -} - diff --git a/simulator/wrapsim/SimMgr.h b/simulator/wrapsim/SimMgr.h deleted file mode 100644 index 378dfbc47..000000000 --- a/simulator/wrapsim/SimMgr.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2007 The Android Open Source Project - * - * Simulator interactions. - */ -#ifndef _WRAPSIM_SIMULATOR_H -#define _WRAPSIM_SIMULATOR_H - -/* - * Commands exchanged between simulator and runtime. - * - * NOTE: this is cloned from SimRuntime.h -- fix this. - */ -typedef enum SimCommand { - kCommandUnknown = 0, - - /* sent from sim to runtime */ - kCommandGoAway, // sim says: go away, I'm busy - kCommandConfigDone, // sim says: done sending config - kCommandQuit, // quit nicely - kCommandNewPGroup, // process group management - kCommandKeyDown, // key has been pressed - kCommandKeyUp, // key has been released - kCommandTouch, // finger touched/lifted/dragged - - /* sent from runtime to sim */ - kCommandNewPGroupCreated, // send process group as argument - kCommandRuntimeReady, // we're initialized and about to start - kCommandUpdateDisplay, // display has been updated - kCommandVibrate, // vibrate on or off -} SimCommand; - -/* - * Touch screen action; also clined from SimRuntime.h. - */ -typedef enum TouchMode { - kTouchDown = 0, - kTouchUp = 1, - kTouchDrag = 2 -} TouchMode; - - -/* - * Some parameters for config exchange. - */ -enum { - kDisplayConfigMagic = 0x44495350, - kValuesPerDisplay = 5, -}; - -/* - * UNIX domain socket name. - */ -#define kAndroidPipeName "runtime" - -int wsSimConnect(void); - -/* - * Display management. - */ -void wsLockDisplay(int displayIdx); -void wsUnlockDisplay(int displayIdx); -void wsPostDisplayUpdate(int displayIdx); - -/* - * Send a log message. - */ -void wsPostLogMessage(int logPrio, const char* tag, const char* msg); - -/* - * Change the state of the vibration device. - */ -void wsEnableVibration(int vibrateOn); - -#endif /*_WRAPSIM_SIMULATOR_H*/ |
