//
// 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 CAP_SYS_NICE
     */
    "--capabilities=96549920,96549920",
    "--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;
}
