//
// Copyright 2005 The Android Open Source Project
//
// Main entry point for runtime.
//

#include "ServiceManager.h"
#include "SignalHandler.h"

#include <utils/threads.h>
#include <utils/Errors.h>

#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <utils/Log.h>
#include <cutils/zygote.h>

#include <cutils/properties.h>

#include <private/utils/Static.h>

#include <surfaceflinger/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 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;
}
