//
// 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;
}
