19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Copyright 2005 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Main entry point for runtime.
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "ServiceManager.h"
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SignalHandler.h"
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
103b4062eeb01be33951ba214e027da523cf09f8b1Mathias Agopian#include <utils/threads.h>
113b4062eeb01be33951ba214e027da523cf09f8b1Mathias Agopian#include <utils/Errors.h>
123b4062eeb01be33951ba214e027da523cf09f8b1Mathias Agopian
130795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/IPCThreadState.h>
140795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/ProcessState.h>
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h>
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <cutils/zygote.h>
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <cutils/properties.h>
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <private/utils/Static.h>
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
226b03844b48c13c52d4c7ec4754d53501814098d8Marco Nelissen#include <surfaceflinger/ISurfaceComposer.h>
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <android_runtime/AndroidRuntime.h>
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h>
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h>
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <fcntl.h>
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h>
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h>
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <getopt.h>
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <signal.h>
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <errno.h>
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/stat.h>
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <linux/capability.h>
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <linux/ioctl.h>
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_ANDROID_OS
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project# include <linux/android_alarm.h>
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#undef LOG_TAG
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "runtime"
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char* ZYGOTE_ARGV[] = {
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "--setuid=1000",
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "--setgid=1000",
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,3001,3002,3003",
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* CAP_SYS_TTY_CONFIG & CAP_SYS_RESOURCE & CAP_NET_BROADCAST &
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * CAP_NET_ADMIN & CAP_NET_RAW & CAP_NET_BIND_SERVICE  & CAP_KILL &
50ca63bb72ef82d392c759a2bd507b7410ea82eacfSan Mehat     * CAP_SYS_BOOT CAP_SYS_NICE
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
52ca63bb72ef82d392c759a2bd507b7410ea82eacfSan Mehat    "--capabilities=96549920,96549920",
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "--runtime-init",
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "--nice-name=system_server",
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "com.android.server.SystemServer"
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectusing namespace android;
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectextern "C" status_t system_init();
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectenum {
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SYSTEM_PROCESS_TAG = DEFAULT_PROCESS_TAG+1
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectextern Mutex gEventQMutex;
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectextern Condition gEventQCondition;
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android {
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectextern status_t app_init(const char* className);
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectextern void set_finish_init_func(void (*func)());
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This class is used to kill this process (runtime) when the system_server dies.
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass GrimReaper : public IBinder::DeathRecipient {
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic:
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    GrimReaper() { }
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    virtual void binderDied(const wp<IBinder>& who)
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGI("Grim Reaper killing runtime...");
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        kill(getpid(), SIGKILL);
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectextern void QuickTests();
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Print usage info.
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void usage(const char* argv0)
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fprintf(stderr,
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        "Usage: runtime [-g gamma] [-l logfile] [-n] [-s]\n"
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        "               [-j app-component] [-v app-verb] [-d app-data]\n"
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        "\n"
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        "-l: File to send log messages to\n"
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        "-n: Don't print to stdout/stderr\n"
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        "-s: Force single-process mode\n"
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        "-j: Custom home app component name\n"
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        "-v: Custom home app intent verb\n"
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        "-d: Custom home app intent data\n"
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    );
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    exit(1);
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Selected application to run.
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char* gInitialApplication = NULL;
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char* gInitialVerb = NULL;
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char* gInitialData = NULL;
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void writeStringToParcel(Parcel& parcel, const char* str)
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (str) {
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        parcel.writeString16(String16(str));
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        parcel.writeString16(NULL, 0);
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Starting point for program logic.
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns with an exit status code (0 on success, nonzero on error).
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int run(sp<ProcessState>& proc)
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Temporary hack to call startRunning() on the activity manager.
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<IServiceManager> sm = defaultServiceManager();
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<IBinder> am;
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while ((am = sm->getService(String16("activity"))) == NULL) {
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGI("Waiting for activity manager...");
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Parcel data, reply;
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // XXX Need to also supply a package name for this to work again.
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // IActivityManager::getInterfaceDescriptor() is the token for invoking on this interface;
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // hardcoding it here avoids having to link with the full Activity Manager library
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    data.writeInterfaceToken(String16("android.app.IActivityManager"));
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    writeStringToParcel(data, NULL);
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    writeStringToParcel(data, gInitialApplication);
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    writeStringToParcel(data, gInitialVerb);
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    writeStringToParcel(data, gInitialData);
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectLOGI("run() sending FIRST_CALL_TRANSACTION to activity manager");
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    am->transact(IBinder::FIRST_CALL_TRANSACTION, data, &reply);
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (proc->supportsProcesses()) {
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Now we link to the Activity Manager waiting for it to die. If it does kill ourself.
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // initd will restart this process and bring the system back up.
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sp<GrimReaper> grim = new GrimReaper();
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        am->linkToDeath(grim, grim.get(), 0);
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Now join the thread pool. Note this is needed so that the message enqueued in the driver
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // for the linkToDeath gets processed.
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IPCThreadState::self()->joinThreadPool();
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Keep this thread running forever...
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (1) {
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            usleep(100000);
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 1;
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};  // namespace android
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Post-system-process initialization.
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This function continues initialization after the system process
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * has been initialized.  It needs to be separate because the system
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * initialization needs to care of starting the Android runtime if it is not
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * running in its own process, which doesn't return until the runtime is
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * being shut down.  So it will call back to here from inside of Dalvik,
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to allow us to continue booting up.
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void finish_system_init(sp<ProcessState>& proc)
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // If we are running multiprocess, we now need to have the
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // thread pool started here.  We don't do this in boot_init()
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // because when running single process we need to start the
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // thread pool after the Android runtime has been started (so
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // the pool uses Dalvik threads).
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (proc->supportsProcesses()) {
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        proc->startThreadPool();
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// This function can be used to enforce security to different
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// root contexts.  For now, we just give every access.
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic bool contextChecker(
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const String16& name, const sp<IBinder>& caller, void* userData)
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return true;
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Initialization of boot services.
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is where we perform initialization of all of our low-level
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * boot services.  Most importantly, here we become the context
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * manager and use that to publish the service manager that will provide
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * access to all other services.
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void boot_init()
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGI("Entered boot_init()!\n");
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<ProcessState> proc(ProcessState::self());
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGD("ProcessState: %p\n", proc.get());
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    proc->becomeContextManager(contextChecker, NULL);
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (proc->supportsProcesses()) {
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGI("Binder driver opened.  Multiprocess enabled.\n");
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGI("Binder driver not found.  Processes not supported.\n");
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<BServiceManager> sm = new BServiceManager;
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    proc->setContextObject(sm);
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Redirect stdin/stdout/stderr to /dev/null.
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void redirectStdFds(void)
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int fd = open("/dev/null", O_RDWR, 0);
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (fd < 0) {
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGW("Unable to open /dev/null: %s\n", strerror(errno));
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dup2(fd, 0);
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dup2(fd, 1);
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        dup2(fd, 2);
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        close(fd);
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int hasDir(const char* dir)
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    struct stat s;
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int res = stat(dir, &s);
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (res == 0) {
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return S_ISDIR(s.st_mode);
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 0;
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void validateTime()
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if HAVE_ANDROID_OS
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int fd;
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int res;
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    time_t min_time = 1167652800; // jan 1 2007, type 'date -ud "1/1 12:00" +%s' to get value for current year
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    struct timespec ts;
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fd = open("/dev/alarm", O_RDWR);
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if(fd < 0) {
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGW("Unable to open alarm driver: %s\n", strerror(errno));
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    res = ioctl(fd, ANDROID_ALARM_GET_TIME(ANDROID_ALARM_RTC_WAKEUP), &ts);
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if(res < 0) {
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGW("Unable to read rtc, %s\n", strerror(errno));
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    else if(ts.tv_sec >= min_time) {
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        goto done;
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGW("Invalid time detected, %ld set to %ld\n", ts.tv_sec, min_time);
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ts.tv_sec = min_time;
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ts.tv_nsec = 0;
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    res = ioctl(fd, ANDROID_ALARM_SET_RTC, &ts);
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if(res < 0) {
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGW("Unable to set rtc to %ld: %s\n", ts.tv_sec, strerror(errno));
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectdone:
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    close(fd);
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifndef HAVE_ANDROID_OS
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass QuickRuntime : public AndroidRuntime
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic:
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    QuickRuntime() {}
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    virtual void onStarted()
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        printf("QuickRuntime: onStarted\n");
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic status_t start_process(const char* name);
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void restart_me(pid_t child, void* userData)
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    start_process((const char*)userData);
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic status_t start_process(const char* name)
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String8 path(name);
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Vector<const char*> args;
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String8 leaf(path.getPathLeaf());
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String8 parentDir(path.getPathDir());
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    args.insertAt(leaf.string(), 0);
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    args.add(parentDir.string());
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    args.add(NULL);
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pid_t child = fork();
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (child < 0) {
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        status_t err = errno;
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("*** fork of child %s failed: %s", leaf.string(), strerror(err));
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -errno;
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (child == 0) {
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGI("Executing: %s", path.string());
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        execv(path.string(), const_cast<char**>(args.array()));
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int err = errno;
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("Exec failed: %s\n", strerror(err));
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        _exit(err);
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SignalHandler::setChildHandler(child, DEFAULT_PROCESS_TAG,
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                restart_me, (void*)name);
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return -errno;
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Application entry point.
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Parse arguments, set some values, and pass control off to Run().
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is redefined to "SDL_main" on SDL simulator builds, and
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * "runtime_main" on wxWidgets builds.
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectextern "C"
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint main(int argc, char* const argv[])
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool singleProcess = false;
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* logFile = NULL;
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int ic;
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int result = 1;
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pid_t systemPid;
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<ProcessState> proc;
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifndef HAVE_ANDROID_OS
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* Set stdout/stderr to unbuffered for MinGW/MSYS. */
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //setvbuf(stdout, NULL, _IONBF, 0);
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //setvbuf(stderr, NULL, _IONBF, 0);
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGI("commandline args:\n");
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (int i = 0; i < argc; i++)
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGI("  %2d: '%s'\n", i, argv[i]);
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (1) {
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ic = getopt(argc, argv, "g:j:v:d:l:ns");
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ic < 0)
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (ic) {
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 'g':
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 'j':
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            gInitialApplication = optarg;
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 'v':
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            gInitialVerb = optarg;
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 'd':
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            gInitialData = optarg;
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 'l':
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            logFile = optarg;
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 'n':
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            redirectStdFds();
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 's':
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            singleProcess = true;
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case '?':
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        default:
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            LOGE("runtime: unrecognized flag -%c\n", ic);
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            usage(argv[0]);
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (optind < argc) {
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("runtime: extra stuff: %s\n", argv[optind]);
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        usage(argv[0]);
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (singleProcess) {
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ProcessState::setSingleProcess(true);
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (logFile != NULL) {
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        android_logToFile(NULL, logFile);
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set up ANDROID_* environment variables.
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * TODO: the use of $ANDROID_PRODUCT_OUT will go away soon.
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static const char* kSystemDir = "/system";
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static const char* kDataDir = "/data";
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static const char* kAppSubdir = "/app";
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const char* out = NULL;
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifndef HAVE_ANDROID_OS
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //out = getenv("ANDROID_PRODUCT_OUT");
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (out == NULL)
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        out = "";
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char* systemDir = (char*) malloc(strlen(out) + strlen(kSystemDir) +1);
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char* dataDir = (char*) malloc(strlen(out) + strlen(kDataDir) +1);
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sprintf(systemDir, "%s%s", out, kSystemDir);
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sprintf(dataDir, "%s%s", out, kDataDir);
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    setenv("ANDROID_ROOT", systemDir, 1);
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    setenv("ANDROID_DATA", dataDir, 1);
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char* assetDir = (char*) malloc(strlen(systemDir) + strlen(kAppSubdir) +1);
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sprintf(assetDir, "%s%s", systemDir, kAppSubdir);
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOGI("Startup: sys='%s' asset='%s' data='%s'\n",
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        systemDir, assetDir, dataDir);
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    free(systemDir);
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    free(dataDir);
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_ANDROID_OS
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* set up a process group for easier killing on the device */
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    setpgid(0, getpid());
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Change to asset dir.  This is only necessary if we've changed to
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // a different directory, but there's little harm in doing it regardless.
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Expecting assets to live in the current dir is not a great idea,
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // because some of our code or one of our libraries could change the
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // directory out from under us.  Preserve the behavior for now.
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (chdir(assetDir) != 0) {
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGW("WARNING: could not change dir to '%s': %s\n",
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             assetDir, strerror(errno));
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    free(assetDir);
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Hack to keep libc from beating the filesystem to death.  It's
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // hitting /etc/localtime frequently,
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // This statement locks us into Pacific time.  We could do better,
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // but there's not much point until we're sure that the library
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // can't be changed to do more along the lines of what we want.
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifndef XP_WIN
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    setenv("TZ", "PST+8PDT,M4.1.0/2,M10.5.0/2", true);
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* track our progress through the boot sequence */
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const int LOG_BOOT_PROGRESS_START = 3000;
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    validateTime();
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    proc = ProcessState::self();
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boot_init();
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* If we are in multiprocess mode, have zygote spawn the system
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * server process and call system_init(). If we are running in
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * single process mode just call system_init() directly.
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (proc->supportsProcesses()) {
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // If stdio logging is on, system_server should not inherit our stdio
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // The dalvikvm instance will copy stdio to the log on its own
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char propBuf[PROPERTY_VALUE_MAX];
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bool logStdio = false;
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        property_get("log.redirect-stdio", propBuf, "");
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        logStdio = (strcmp(propBuf, "true") == 0);
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        zygote_run_oneshot((int)(!logStdio),
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sizeof(ZYGOTE_ARGV) / sizeof(ZYGOTE_ARGV[0]),
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ZYGOTE_ARGV);
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //start_process("/system/bin/mediaserver");
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifndef HAVE_ANDROID_OS
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        QuickRuntime* runt = new QuickRuntime();
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        runt->start("com/android/server/SystemServer",
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    false /* spontaneously fork system server from zygote */);
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //printf("+++ post-zygote\n");
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    finish_system_init(proc);
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    run(proc);
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbail:
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (proc != NULL) {
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        proc->setContextObject(NULL);
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return 0;
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
517