auto import from //depot/cupcake/@135843
diff --git a/cmds/runtime/Android.mk b/cmds/runtime/Android.mk
new file mode 100644
index 0000000..521eb2b
--- /dev/null
+++ b/cmds/runtime/Android.mk
@@ -0,0 +1,29 @@
+ifeq ($(TARGET_SIMULATOR),true)
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	ServiceManager.cpp \
+	SignalHandler.cpp \
+	main_runtime.cpp 
+
+LOCAL_SHARED_LIBRARIES := \
+	libutils \
+	libandroid_runtime \
+	libcutils \
+	libui \
+	libsystem_server \
+	libhardware_legacy
+
+LOCAL_C_INCLUDES := \
+	$(JNI_H_INCLUDE)
+
+ifeq ($(TARGET_OS),linux)
+	LOCAL_CFLAGS += -DXP_UNIX
+endif
+
+LOCAL_MODULE:= runtime
+
+include $(BUILD_EXECUTABLE)
+endif
diff --git a/cmds/runtime/MODULE_LICENSE_APACHE2 b/cmds/runtime/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmds/runtime/MODULE_LICENSE_APACHE2
diff --git a/cmds/runtime/NOTICE b/cmds/runtime/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/cmds/runtime/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-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.
+
+   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.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/cmds/runtime/ServiceManager.cpp b/cmds/runtime/ServiceManager.cpp
new file mode 100644
index 0000000..758a95c
--- /dev/null
+++ b/cmds/runtime/ServiceManager.cpp
@@ -0,0 +1,74 @@
+//
+// Copyright 2005 The Android Open Source Project
+//
+
+#define LOG_TAG "ServiceManager"
+
+#include "ServiceManager.h"
+#include "SignalHandler.h"
+
+#include <utils/Debug.h>
+#include <utils/Log.h>
+#include <utils/Parcel.h>
+#include <utils/String8.h>
+#include <utils/ProcessState.h>
+
+#include <private/utils/Static.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+namespace android {
+
+BServiceManager::BServiceManager()
+{
+}
+
+sp<IBinder> BServiceManager::getService(const String16& name) const
+{
+    AutoMutex _l(mLock);
+    ssize_t i = mServices.indexOfKey(name);
+    LOGV("ServiceManager: getService(%s) -> %d\n", String8(name).string(), i);
+    if (i >= 0) return mServices.valueAt(i);
+    return NULL;
+}
+
+sp<IBinder> BServiceManager::checkService(const String16& name) const
+{
+    AutoMutex _l(mLock);
+    ssize_t i = mServices.indexOfKey(name);
+    LOGV("ServiceManager: getService(%s) -> %d\n", String8(name).string(), i);
+    if (i >= 0) return mServices.valueAt(i);
+    return NULL;
+}
+
+status_t BServiceManager::addService(const String16& name, const sp<IBinder>& service)
+{
+    AutoMutex _l(mLock);
+    LOGI("ServiceManager: addService(%s, %p)\n", String8(name).string(), service.get());
+    const ssize_t res = mServices.add(name, service);
+    if (res >= NO_ERROR) {
+        mChanged.broadcast();
+        return NO_ERROR;
+    }
+    return res;
+}
+
+Vector<String16> BServiceManager::listServices()
+{
+    Vector<String16> res;
+
+    AutoMutex _l(mLock);
+    const size_t N = mServices.size();
+    for (size_t i=0; i<N; i++) {
+        res.add(mServices.keyAt(i));
+    }
+
+    return res;
+}
+
+}; // namespace android
diff --git a/cmds/runtime/ServiceManager.h b/cmds/runtime/ServiceManager.h
new file mode 100644
index 0000000..d09cec8
--- /dev/null
+++ b/cmds/runtime/ServiceManager.h
@@ -0,0 +1,38 @@
+//
+// Copyright 2005 The Android Open Source Project
+//
+#ifndef ANDROID_SERVICE_MANAGER_H
+#define ANDROID_SERVICE_MANAGER_H
+
+#include <utils/IServiceManager.h>
+#include <utils/KeyedVector.h>
+#include <utils/threads.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+class BServiceManager : public BnServiceManager
+{
+public:
+                                BServiceManager();
+    
+    virtual sp<IBinder>         getService( const String16& name) const;
+    virtual sp<IBinder>         checkService( const String16& name) const;
+    virtual status_t            addService( const String16& name,
+                                            const sp<IBinder>& service);
+    virtual Vector<String16>    listServices();
+
+    
+private:
+    mutable Mutex               mLock;
+    mutable Condition           mChanged;
+    sp<IPermissionController>   mPermissionController;
+    KeyedVector<String16, sp<IBinder> > mServices;
+};
+
+// ----------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_SERVICE_MANAGER_H
diff --git a/cmds/runtime/SignalHandler.cpp b/cmds/runtime/SignalHandler.cpp
new file mode 100644
index 0000000..cccaabf
--- /dev/null
+++ b/cmds/runtime/SignalHandler.cpp
@@ -0,0 +1,249 @@
+//
+// Copyright 2005 The Android Open Source Project
+//
+
+#define LOG_TAG "SignalHandler"
+
+#include "SignalHandler.h"
+
+#include <utils/Atomic.h>
+#include <utils/Debug.h>
+#include <utils/Log.h>
+
+#include <errno.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+namespace android {
+
+class SignalHandler::ProcessThread : public Thread
+{
+public:
+    ProcessThread(SignalHandler& sh)
+        : Thread(false)
+        , mOwner(sh)
+    {
+    }
+
+    virtual bool threadLoop()
+    {
+        char buffer[32];
+        read(mOwner.mAvailMsg[0], buffer, sizeof(buffer));
+
+        LOGV("Signal command processing thread woke up!");
+
+        if (mOwner.mLostCommands) {
+            LOGE("Lost %d signals!", mOwner.mLostCommands);
+            mOwner.mLostCommands = 0;
+        }
+
+        int cur;
+        while ((cur=mOwner.mCommandBottom) != mOwner.mCommandTop) {
+            if (mOwner.mCommands[cur].filled == 0) {
+                LOGV("Command at %d is not yet filled", cur);
+                break;
+            }
+
+            LOGV("Processing command at %d, top is %d",
+                 cur, mOwner.mCommandTop);
+            processCommand(mOwner.mCommands[cur]);
+            mOwner.mCommands[cur].filled = 0;
+
+            int next = mOwner.mCommandBottom+1;
+            if (next >= COMMAND_QUEUE_SIZE) {
+                next = 0;
+            }
+
+            mOwner.mCommandBottom = next;
+        }
+
+        return true;
+    }
+
+    void processCommand(const CommandEntry& entry)
+    {
+        switch (entry.signum) {
+        case SIGCHLD: {
+            mOwner.mLock.lock();
+            ssize_t i = mOwner.mChildHandlers.indexOfKey(entry.info.si_pid);
+            ChildHandler ch;
+            if (i >= 0) {
+                ch = mOwner.mChildHandlers.valueAt(i);
+                mOwner.mChildHandlers.removeItemsAt(i);
+            }
+            mOwner.mLock.unlock();
+
+            LOGD("SIGCHLD: pid=%d, handle index=%d", entry.info.si_pid, i);
+
+            if (i >= 0) {
+                int res = waitpid(entry.info.si_pid, NULL, WNOHANG);
+                LOGW_IF(res == 0,
+                        "Received SIGCHLD, but pid %d is not yet stopped",
+                        entry.info.si_pid);
+                if (ch.handler) {
+                    ch.handler(entry.info.si_pid, ch.userData);
+                }
+            } else {
+                LOGW("Unhandled SIGCHLD for pid %d", entry.info.si_pid);
+            }
+        } break;
+        }
+    }
+
+    SignalHandler& mOwner;
+};
+
+
+Mutex SignalHandler::mInstanceLock;
+SignalHandler* SignalHandler::mInstance = NULL;
+
+status_t SignalHandler::setChildHandler(pid_t childPid,
+                                        int tag,
+                                        child_callback_t handler,
+                                        void* userData)
+{
+    SignalHandler* const self = getInstance();
+
+    self->mLock.lock();
+
+    // First make sure this child hasn't already exited.
+    pid_t res = waitpid(childPid, NULL, WNOHANG);
+    if (res != 0) {
+        if (res < 0) {
+            LOGW("setChildHandler waitpid of %d failed: %d (%s)",
+                 childPid, res, strerror(errno));
+        } else {
+            LOGW("setChildHandler waitpid of %d said %d already dead",
+                 childPid, res);
+        }
+
+        // Some kind of error...  just handle the exit now.
+        self->mLock.unlock();
+
+        if (handler) {
+            handler(childPid, userData);
+        }
+
+        // Return an error code -- 0 means it already exited.
+        return (status_t)res;
+    }
+
+    ChildHandler entry;
+    entry.childPid = childPid;
+    entry.tag = tag;
+    entry.handler = handler;
+    entry.userData = userData;
+
+    // Note: this replaces an existing entry for this pid, if there already
+    // is one.  This is the required behavior.
+    LOGD("setChildHandler adding pid %d, tag %d, handler %p, data %p",
+         childPid, tag, handler, userData);
+    self->mChildHandlers.add(childPid, entry);
+
+    self->mLock.unlock();
+
+    return NO_ERROR;
+}
+
+void SignalHandler::killAllChildren(int tag)
+{
+    SignalHandler* const self = getInstance();
+
+    AutoMutex _l (self->mLock);
+    const size_t N = self->mChildHandlers.size();
+    for (size_t i=0; i<N; i++) {
+        const ChildHandler& ch(self->mChildHandlers.valueAt(i));
+        if (tag == 0 || ch.tag == tag) {
+            const pid_t pid = ch.childPid;
+            LOGI("Killing child %d (tag %d)\n", pid, ch.tag);
+            kill(pid, SIGKILL);
+        }
+    }
+}
+
+SignalHandler::SignalHandler()
+    : mCommandTop(0)
+    , mCommandBottom(0)
+    , mLostCommands(0)
+{
+    memset(mCommands, 0, sizeof(mCommands));
+
+    int res = pipe(mAvailMsg);
+    LOGE_IF(res != 0, "Unable to create signal handler pipe: %s", strerror(errno));
+
+    mProcessThread = new ProcessThread(*this);
+    mProcessThread->run("SignalHandler", PRIORITY_HIGHEST);
+
+    struct sigaction sa;
+    memset(&sa, 0, sizeof(sa));
+    sa.sa_sigaction = sigAction;
+    sa.sa_flags = SA_NOCLDSTOP|SA_SIGINFO;
+    sigaction(SIGCHLD, &sa, NULL);
+}
+
+SignalHandler::~SignalHandler()
+{
+}
+
+SignalHandler* SignalHandler::getInstance()
+{
+    AutoMutex _l(mInstanceLock);
+    if (mInstance == NULL) {
+        mInstance = new SignalHandler();
+    }
+    return mInstance;
+}
+
+void SignalHandler::sigAction(int signum, siginfo_t* info, void*)
+{
+    static const char wakeupMsg[1] = { 0xff };
+
+    // If our signal handler is being called, then we know we have
+    // already initialized the SignalHandler class and thus mInstance
+    // is valid.
+    SignalHandler* const self = mInstance;
+
+    // XXX This is not safe!
+    #if 0
+    LOGV("Signal %d: signo=%d, errno=%d, code=%d, pid=%d\n",
+           signum,
+           info->si_signo, info->si_errno, info->si_code,
+           info->si_pid);
+    #endif
+
+    int32_t oldTop, newTop;
+
+    // Find the next command slot...
+    do {
+        oldTop = self->mCommandTop;
+
+        newTop = oldTop + 1;
+        if (newTop >= COMMAND_QUEUE_SIZE) {
+            newTop = 0;
+        }
+
+        if (newTop == self->mCommandBottom) {
+            // The buffer is filled up!  Ouch!
+            // XXX This is not safe!
+            #if 0
+            LOGE("Command buffer overflow!  newTop=%d\n", newTop);
+            #endif
+            android_atomic_add(1, &self->mLostCommands);
+            write(self->mAvailMsg[1], wakeupMsg, sizeof(wakeupMsg));
+            return;
+        }
+    } while(android_atomic_cmpxchg(oldTop, newTop, &(self->mCommandTop)));
+
+    // Fill in the command data...
+    self->mCommands[oldTop].signum = signum;
+    self->mCommands[oldTop].info = *info;
+
+    // And now make this command available.
+    self->mCommands[oldTop].filled = 1;
+
+    // Wake up the processing thread.
+    write(self->mAvailMsg[1], wakeupMsg, sizeof(wakeupMsg));
+}
+
+}; // namespace android
+
diff --git a/cmds/runtime/SignalHandler.h b/cmds/runtime/SignalHandler.h
new file mode 100644
index 0000000..7f4ef8e
--- /dev/null
+++ b/cmds/runtime/SignalHandler.h
@@ -0,0 +1,137 @@
+//
+// Copyright 2005 The Android Open Source Project
+//
+#ifndef ANDROID_SIGNAL_HANDLER_H
+#define ANDROID_SIGNAL_HANDLER_H
+
+#include <utils/KeyedVector.h>
+#include <utils/threads.h>
+
+#include <signal.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+enum {
+    DEFAULT_PROCESS_TAG = 1
+};
+
+class SignalHandler
+{
+public:
+    typedef void (*child_callback_t)(pid_t child, void* userData);
+
+    /**
+     * Set a handler for when a child process exits.  By calling
+     * this, a waitpid() will be done when the child exits to remove
+     * it from the zombie state.  You can also optionally specify a
+     * handler to be called when the child exits.
+     * 
+     * If there is already a handler for this child process, it is
+     * replaced by this new handler.  In this case the old handler's
+     * function is not called.
+     * 
+     * @param childPid Process ID of child to watch.
+     * @param childTag User-defined tag for this child.  Must be
+     *                 greater than zero.
+     * @param handler If non-NULL, this will be called when the
+     *                child exits.  It may be called in either a
+     *                separate signal handling thread, or
+     *                immediately if the child has already exited.
+     * @param userData Propageted as-is to handler.
+     * 
+     * @return status_t NO_ERROR if all is well.
+     */
+    static status_t             setChildHandler(pid_t childPid,
+                                                int childTag = DEFAULT_PROCESS_TAG,
+                                                child_callback_t handler = NULL,
+                                                void* userData = NULL);
+
+    /**
+     * Kill all of the child processes for which we have a waiting
+     * handler, whose tag is the given value.  If tag is 0, all
+     * children are killed.
+     * 
+     * @param tag
+     */
+    static void                 killAllChildren(int tag = 0);
+
+private:
+                                SignalHandler();
+                                ~SignalHandler();
+
+    static SignalHandler*       getInstance();
+
+    static void                 sigAction(int, siginfo_t*, void*);
+
+    // --------------------------------------------------
+    // Shared state...  all of this is protected by mLock.
+    // --------------------------------------------------
+
+    mutable Mutex                       mLock;
+
+    struct ChildHandler
+    {
+        pid_t childPid;
+        int tag;
+        child_callback_t handler;
+        void* userData;
+    };
+    KeyedVector<pid_t, ChildHandler>    mChildHandlers;
+
+    // --------------------------------------------------
+    // Commmand queue...  data is inserted by the signal
+    // handler using atomic ops, and retrieved by the
+    // signal processing thread.  Because these are touched
+    // by the signal handler, no lock is used.
+    // --------------------------------------------------
+
+    enum {
+        COMMAND_QUEUE_SIZE = 64
+    };
+    struct CommandEntry
+    {
+        int filled;
+        int signum;
+        siginfo_t info;
+    };
+
+    // The top of the queue.  This is incremented atomically by the
+    // signal handler before placing a command in the queue.
+    volatile int32_t                    mCommandTop;
+
+    // The bottom of the queue.  Only modified by the processing
+    // thread; the signal handler reads it only to determine if the
+    // queue is full.
+    int32_t                             mCommandBottom;
+
+    // Incremented each time we receive a signal and don't have room
+    // for it on the command queue.
+    volatile int32_t                    mLostCommands;
+
+    // The command processing thread.
+    class ProcessThread;
+    sp<Thread>                          mProcessThread;
+
+    // Pipe used to tell command processing thread when new commands.
+    // are available.  The thread blocks on the read end, the signal
+    // handler writes when it enqueues new commands.
+    int                                 mAvailMsg[2];
+
+    // The commands.
+    CommandEntry                        mCommands[COMMAND_QUEUE_SIZE];
+
+    // --------------------------------------------------
+    // Singleton.
+    // --------------------------------------------------
+
+    static Mutex                        mInstanceLock;
+    static SignalHandler*               mInstance;
+};
+
+// ----------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_SIGNAL_HANDLER_H
diff --git a/cmds/runtime/main_runtime.cpp b/cmds/runtime/main_runtime.cpp
new file mode 100644
index 0000000..1531a9e
--- /dev/null
+++ b/cmds/runtime/main_runtime.cpp
@@ -0,0 +1,514 @@
+//
+// Copyright 2005 The Android Open Source Project
+//
+// Main entry point for runtime.
+//
+
+#include "ServiceManager.h"
+#include "SignalHandler.h"
+
+#include <utils.h>
+#include <utils/IPCThreadState.h>
+#include <utils/ProcessState.h>
+#include <utils/Log.h>  
+#include <cutils/zygote.h>
+
+#include <cutils/properties.h>
+
+#include <private/utils/Static.h>
+
+#include <ui/ISurfaceComposer.h>
+
+#include <android_runtime/AndroidRuntime.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <getopt.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <linux/capability.h>
+#include <linux/ioctl.h>
+#ifdef HAVE_ANDROID_OS
+# include <linux/android_alarm.h>
+#endif
+
+#undef LOG_TAG
+#define LOG_TAG "runtime"
+
+static const char* ZYGOTE_ARGV[] = { 
+    "--setuid=1000",
+    "--setgid=1000",
+    "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,3001,3002,3003",
+    /* CAP_SYS_TTY_CONFIG & CAP_SYS_RESOURCE & CAP_NET_BROADCAST &
+     * CAP_NET_ADMIN & CAP_NET_RAW & CAP_NET_BIND_SERVICE  & CAP_KILL &
+     * CAP_SYS_BOOT
+     */
+    "--capabilities=88161312,88161312",
+    "--runtime-init",
+    "--nice-name=system_server",
+    "com.android.server.SystemServer"
+};
+
+using namespace android;
+
+extern "C" status_t system_init();
+
+enum {
+    SYSTEM_PROCESS_TAG = DEFAULT_PROCESS_TAG+1
+};
+
+extern Mutex gEventQMutex;
+extern Condition gEventQCondition;
+
+namespace android {
+
+extern status_t app_init(const char* className);
+extern void set_finish_init_func(void (*func)());
+
+
+/**
+ * This class is used to kill this process (runtime) when the system_server dies.
+ */
+class GrimReaper : public IBinder::DeathRecipient {
+public: 
+    GrimReaper() { }
+
+    virtual void binderDied(const wp<IBinder>& who)
+    {
+        LOGI("Grim Reaper killing runtime...");
+        kill(getpid(), SIGKILL);
+    }
+};
+
+extern void QuickTests();
+
+/*
+ * Print usage info.
+ */
+static void usage(const char* argv0)
+{
+    fprintf(stderr,
+        "Usage: runtime [-g gamma] [-l logfile] [-n] [-s]\n"
+        "               [-j app-component] [-v app-verb] [-d app-data]\n"
+        "\n"
+        "-l: File to send log messages to\n"
+        "-n: Don't print to stdout/stderr\n"
+        "-s: Force single-process mode\n"
+        "-j: Custom home app component name\n"
+        "-v: Custom home app intent verb\n"
+        "-d: Custom home app intent data\n"
+    );
+    exit(1);
+}
+
+// Selected application to run.
+static const char* gInitialApplication = NULL;
+static const char* gInitialVerb = NULL;
+static const char* gInitialData = NULL;
+
+static void writeStringToParcel(Parcel& parcel, const char* str)
+{
+    if (str) {
+        parcel.writeString16(String16(str));
+    } else {
+        parcel.writeString16(NULL, 0);
+    }
+}
+
+/*
+ * Starting point for program logic.
+ *
+ * Returns with an exit status code (0 on success, nonzero on error).
+ */
+static int run(sp<ProcessState>& proc)
+{
+    // Temporary hack to call startRunning() on the activity manager.
+    sp<IServiceManager> sm = defaultServiceManager();
+    sp<IBinder> am;
+    while ((am = sm->getService(String16("activity"))) == NULL) {
+        LOGI("Waiting for activity manager...");
+    }
+    Parcel data, reply;
+    // XXX Need to also supply a package name for this to work again.
+    // IActivityManager::getInterfaceDescriptor() is the token for invoking on this interface;
+    // hardcoding it here avoids having to link with the full Activity Manager library
+    data.writeInterfaceToken(String16("android.app.IActivityManager"));
+    writeStringToParcel(data, NULL);
+    writeStringToParcel(data, gInitialApplication);
+    writeStringToParcel(data, gInitialVerb);
+    writeStringToParcel(data, gInitialData);
+LOGI("run() sending FIRST_CALL_TRANSACTION to activity manager");
+    am->transact(IBinder::FIRST_CALL_TRANSACTION, data, &reply);
+
+    if (proc->supportsProcesses()) {
+        // Now we link to the Activity Manager waiting for it to die. If it does kill ourself.
+        // initd will restart this process and bring the system back up.
+        sp<GrimReaper> grim = new GrimReaper();
+        am->linkToDeath(grim, grim.get(), 0);
+
+        // Now join the thread pool. Note this is needed so that the message enqueued in the driver
+        // for the linkToDeath gets processed.
+        IPCThreadState::self()->joinThreadPool();
+    } else {
+        // Keep this thread running forever...
+        while (1) {
+            usleep(100000);
+        }
+    }
+    return 1;
+}
+
+
+};  // namespace android
+
+
+/*
+ * Post-system-process initialization.
+ * 
+ * This function continues initialization after the system process
+ * has been initialized.  It needs to be separate because the system
+ * initialization needs to care of starting the Android runtime if it is not
+ * running in its own process, which doesn't return until the runtime is
+ * being shut down.  So it will call back to here from inside of Dalvik,
+ * to allow us to continue booting up.
+ */
+static void finish_system_init(sp<ProcessState>& proc)
+{
+    // If we are running multiprocess, we now need to have the
+    // thread pool started here.  We don't do this in boot_init()
+    // because when running single process we need to start the
+    // thread pool after the Android runtime has been started (so
+    // the pool uses Dalvik threads).
+    if (proc->supportsProcesses()) {
+        proc->startThreadPool();
+    }
+}
+
+
+// This function can be used to enforce security to different
+// root contexts.  For now, we just give every access.
+static bool contextChecker(
+    const String16& name, const sp<IBinder>& caller, void* userData)
+{
+    return true;
+}
+
+/*
+ * Initialization of boot services.
+ *
+ * This is where we perform initialization of all of our low-level
+ * boot services.  Most importantly, here we become the context
+ * manager and use that to publish the service manager that will provide
+ * access to all other services.
+ */
+static void boot_init()
+{
+    LOGI("Entered boot_init()!\n");
+    
+    sp<ProcessState> proc(ProcessState::self());
+    LOGD("ProcessState: %p\n", proc.get());
+    proc->becomeContextManager(contextChecker, NULL);
+    
+    if (proc->supportsProcesses()) {
+        LOGI("Binder driver opened.  Multiprocess enabled.\n");
+    } else {
+        LOGI("Binder driver not found.  Processes not supported.\n");
+    }
+    
+    sp<BServiceManager> sm = new BServiceManager;
+    proc->setContextObject(sm);
+}
+
+/*
+ * Redirect stdin/stdout/stderr to /dev/null.
+ */
+static void redirectStdFds(void)
+{
+    int fd = open("/dev/null", O_RDWR, 0);
+    if (fd < 0) {
+        LOGW("Unable to open /dev/null: %s\n", strerror(errno));
+    } else {
+        dup2(fd, 0);
+        dup2(fd, 1);
+        dup2(fd, 2);
+        close(fd);
+    }
+}
+
+static int hasDir(const char* dir)
+{
+    struct stat s;
+    int res = stat(dir, &s);
+    if (res == 0) {
+        return S_ISDIR(s.st_mode);
+    }
+    return 0;
+}
+
+static void validateTime()
+{
+#if HAVE_ANDROID_OS
+    int fd;
+    int res;
+    time_t min_time = 1167652800; // jan 1 2007, type 'date -ud "1/1 12:00" +%s' to get value for current year
+    struct timespec ts;
+    
+    fd = open("/dev/alarm", O_RDWR);
+    if(fd < 0) {
+        LOGW("Unable to open alarm driver: %s\n", strerror(errno));
+        return;
+    }
+    res = ioctl(fd, ANDROID_ALARM_GET_TIME(ANDROID_ALARM_RTC_WAKEUP), &ts);
+    if(res < 0) {
+        LOGW("Unable to read rtc, %s\n", strerror(errno));
+    }
+    else if(ts.tv_sec >= min_time) {
+        goto done;
+    }
+    LOGW("Invalid time detected, %ld set to %ld\n", ts.tv_sec, min_time);
+    ts.tv_sec = min_time;
+    ts.tv_nsec = 0;
+    res = ioctl(fd, ANDROID_ALARM_SET_RTC, &ts);
+    if(res < 0) {
+        LOGW("Unable to set rtc to %ld: %s\n", ts.tv_sec, strerror(errno));
+    }
+done:
+    close(fd);
+#endif
+}
+
+#ifndef HAVE_ANDROID_OS
+class QuickRuntime : public AndroidRuntime
+{
+public:
+    QuickRuntime() {}
+
+    virtual void onStarted()
+    {
+        printf("QuickRuntime: onStarted\n");
+    }
+};
+#endif
+
+static status_t start_process(const char* name);
+
+static void restart_me(pid_t child, void* userData)
+{
+    start_process((const char*)userData);
+}
+
+static status_t start_process(const char* name)
+{
+    String8 path(name);
+    Vector<const char*> args;
+    String8 leaf(path.getPathLeaf());
+    String8 parentDir(path.getPathDir());
+    args.insertAt(leaf.string(), 0);
+    args.add(parentDir.string());
+    args.add(NULL);
+    pid_t child = fork();
+    if (child < 0) {
+        status_t err = errno;
+        LOGE("*** fork of child %s failed: %s", leaf.string(), strerror(err));
+        return -errno;
+    } else if (child == 0) {
+        LOGI("Executing: %s", path.string());
+        execv(path.string(), const_cast<char**>(args.array()));
+        int err = errno;
+        LOGE("Exec failed: %s\n", strerror(err));
+        _exit(err);
+    } else {
+        SignalHandler::setChildHandler(child, DEFAULT_PROCESS_TAG,
+                restart_me, (void*)name);
+    }
+    return -errno;
+}
+
+/*
+ * Application entry point.
+ *
+ * Parse arguments, set some values, and pass control off to Run().
+ *
+ * This is redefined to "SDL_main" on SDL simulator builds, and
+ * "runtime_main" on wxWidgets builds.
+ */
+extern "C"
+int main(int argc, char* const argv[])
+{
+    bool singleProcess = false;
+    const char* logFile = NULL;
+    int ic;
+    int result = 1;
+    pid_t systemPid;
+    
+    sp<ProcessState> proc;
+
+#ifndef HAVE_ANDROID_OS
+    /* Set stdout/stderr to unbuffered for MinGW/MSYS. */
+    //setvbuf(stdout, NULL, _IONBF, 0);
+    //setvbuf(stderr, NULL, _IONBF, 0);
+    
+    LOGI("commandline args:\n");
+    for (int i = 0; i < argc; i++)
+        LOGI("  %2d: '%s'\n", i, argv[i]);
+#endif
+
+    while (1) {
+        ic = getopt(argc, argv, "g:j:v:d:l:ns");
+        if (ic < 0)
+            break;
+
+        switch (ic) {
+        case 'g':
+            break;
+        case 'j':
+            gInitialApplication = optarg;
+            break;
+        case 'v':
+            gInitialVerb = optarg;
+            break;
+        case 'd':
+            gInitialData = optarg;
+            break;
+        case 'l':
+            logFile = optarg;
+            break;
+        case 'n':
+            redirectStdFds();
+            break;
+        case 's':
+            singleProcess = true;
+            break;
+        case '?':
+        default:
+            LOGE("runtime: unrecognized flag -%c\n", ic);
+            usage(argv[0]);
+            break;
+        }
+    }
+    if (optind < argc) {
+        LOGE("runtime: extra stuff: %s\n", argv[optind]);
+        usage(argv[0]);
+    }
+
+    if (singleProcess) {
+        ProcessState::setSingleProcess(true);
+    }
+
+    if (logFile != NULL) {
+        android_logToFile(NULL, logFile);
+    }
+
+    /*
+     * Set up ANDROID_* environment variables.
+     *
+     * TODO: the use of $ANDROID_PRODUCT_OUT will go away soon.
+     */
+    static const char* kSystemDir = "/system";
+    static const char* kDataDir = "/data";
+    static const char* kAppSubdir = "/app";
+    const char* out = NULL;
+#ifndef HAVE_ANDROID_OS
+    //out = getenv("ANDROID_PRODUCT_OUT");
+#endif
+    if (out == NULL)
+        out = "";
+
+    char* systemDir = (char*) malloc(strlen(out) + strlen(kSystemDir) +1);
+    char* dataDir = (char*) malloc(strlen(out) + strlen(kDataDir) +1);
+
+    sprintf(systemDir, "%s%s", out, kSystemDir);
+    sprintf(dataDir, "%s%s", out, kDataDir);
+    setenv("ANDROID_ROOT", systemDir, 1);
+    setenv("ANDROID_DATA", dataDir, 1);
+
+    char* assetDir = (char*) malloc(strlen(systemDir) + strlen(kAppSubdir) +1);
+    sprintf(assetDir, "%s%s", systemDir, kAppSubdir);
+
+    LOGI("Startup: sys='%s' asset='%s' data='%s'\n",
+        systemDir, assetDir, dataDir);
+    free(systemDir);
+    free(dataDir);
+
+#ifdef HAVE_ANDROID_OS
+    /* set up a process group for easier killing on the device */
+    setpgid(0, getpid());
+#endif
+
+    // Change to asset dir.  This is only necessary if we've changed to
+    // a different directory, but there's little harm in doing it regardless.
+    //
+    // Expecting assets to live in the current dir is not a great idea,
+    // because some of our code or one of our libraries could change the
+    // directory out from under us.  Preserve the behavior for now.
+    if (chdir(assetDir) != 0) {
+        LOGW("WARNING: could not change dir to '%s': %s\n",
+             assetDir, strerror(errno));
+    }
+    free(assetDir);
+
+#if 0
+    // Hack to keep libc from beating the filesystem to death.  It's
+    // hitting /etc/localtime frequently, 
+    //
+    // This statement locks us into Pacific time.  We could do better,
+    // but there's not much point until we're sure that the library
+    // can't be changed to do more along the lines of what we want.
+#ifndef XP_WIN
+    setenv("TZ", "PST+8PDT,M4.1.0/2,M10.5.0/2", true);
+#endif
+#endif
+
+    /* track our progress through the boot sequence */
+    const int LOG_BOOT_PROGRESS_START = 3000;
+    LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, 
+        ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
+
+    validateTime();
+
+    proc = ProcessState::self();
+    
+    boot_init();
+    
+    /* If we are in multiprocess mode, have zygote spawn the system
+     * server process and call system_init(). If we are running in
+     * single process mode just call system_init() directly.
+     */
+    if (proc->supportsProcesses()) {
+        // If stdio logging is on, system_server should not inherit our stdio
+        // The dalvikvm instance will copy stdio to the log on its own
+        char propBuf[PROPERTY_VALUE_MAX];
+        bool logStdio = false;
+        property_get("log.redirect-stdio", propBuf, "");
+        logStdio = (strcmp(propBuf, "true") == 0);
+
+        zygote_run_oneshot((int)(!logStdio), 
+                sizeof(ZYGOTE_ARGV) / sizeof(ZYGOTE_ARGV[0]), 
+                ZYGOTE_ARGV);
+
+        //start_process("/system/bin/mediaserver");
+
+    } else {
+#ifndef HAVE_ANDROID_OS
+        QuickRuntime* runt = new QuickRuntime();
+        runt->start("com/android/server/SystemServer", 
+                    false /* spontaneously fork system server from zygote */);
+#endif
+    }
+
+    //printf("+++ post-zygote\n");
+
+    finish_system_init(proc);
+    run(proc);
+    
+bail:
+    if (proc != NULL) {
+        proc->setContextObject(NULL);
+    }
+    
+    return 0;
+}