1//
2// Copyright 2005 The Android Open Source Project
3//
4// Main entry point for runtime.
5//
6
7#include "ServiceManager.h"
8#include "SignalHandler.h"
9
10#include <utils/threads.h>
11#include <utils/Errors.h>
12
13#include <binder/IPCThreadState.h>
14#include <binder/ProcessState.h>
15#include <utils/Log.h>
16#include <cutils/zygote.h>
17
18#include <cutils/properties.h>
19
20#include <private/utils/Static.h>
21
22#include <surfaceflinger/ISurfaceComposer.h>
23
24#include <android_runtime/AndroidRuntime.h>
25
26#include <stdlib.h>
27#include <unistd.h>
28#include <fcntl.h>
29#include <stdio.h>
30#include <string.h>
31#include <getopt.h>
32#include <signal.h>
33#include <errno.h>
34#include <sys/stat.h>
35#include <linux/capability.h>
36#include <linux/ioctl.h>
37#ifdef HAVE_ANDROID_OS
38# include <linux/android_alarm.h>
39#endif
40
41#undef LOG_TAG
42#define LOG_TAG "runtime"
43
44static const char* ZYGOTE_ARGV[] = {
45    "--setuid=1000",
46    "--setgid=1000",
47    "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,3001,3002,3003",
48    /* CAP_SYS_TTY_CONFIG & CAP_SYS_RESOURCE & CAP_NET_BROADCAST &
49     * CAP_NET_ADMIN & CAP_NET_RAW & CAP_NET_BIND_SERVICE  & CAP_KILL &
50     * CAP_SYS_BOOT CAP_SYS_NICE
51     */
52    "--capabilities=96549920,96549920",
53    "--runtime-init",
54    "--nice-name=system_server",
55    "com.android.server.SystemServer"
56};
57
58using namespace android;
59
60extern "C" status_t system_init();
61
62enum {
63    SYSTEM_PROCESS_TAG = DEFAULT_PROCESS_TAG+1
64};
65
66extern Mutex gEventQMutex;
67extern Condition gEventQCondition;
68
69namespace android {
70
71extern status_t app_init(const char* className);
72extern void set_finish_init_func(void (*func)());
73
74
75/**
76 * This class is used to kill this process (runtime) when the system_server dies.
77 */
78class GrimReaper : public IBinder::DeathRecipient {
79public:
80    GrimReaper() { }
81
82    virtual void binderDied(const wp<IBinder>& who)
83    {
84        LOGI("Grim Reaper killing runtime...");
85        kill(getpid(), SIGKILL);
86    }
87};
88
89extern void QuickTests();
90
91/*
92 * Print usage info.
93 */
94static void usage(const char* argv0)
95{
96    fprintf(stderr,
97        "Usage: runtime [-g gamma] [-l logfile] [-n] [-s]\n"
98        "               [-j app-component] [-v app-verb] [-d app-data]\n"
99        "\n"
100        "-l: File to send log messages to\n"
101        "-n: Don't print to stdout/stderr\n"
102        "-s: Force single-process mode\n"
103        "-j: Custom home app component name\n"
104        "-v: Custom home app intent verb\n"
105        "-d: Custom home app intent data\n"
106    );
107    exit(1);
108}
109
110// Selected application to run.
111static const char* gInitialApplication = NULL;
112static const char* gInitialVerb = NULL;
113static const char* gInitialData = NULL;
114
115static void writeStringToParcel(Parcel& parcel, const char* str)
116{
117    if (str) {
118        parcel.writeString16(String16(str));
119    } else {
120        parcel.writeString16(NULL, 0);
121    }
122}
123
124/*
125 * Starting point for program logic.
126 *
127 * Returns with an exit status code (0 on success, nonzero on error).
128 */
129static int run(sp<ProcessState>& proc)
130{
131    // Temporary hack to call startRunning() on the activity manager.
132    sp<IServiceManager> sm = defaultServiceManager();
133    sp<IBinder> am;
134    while ((am = sm->getService(String16("activity"))) == NULL) {
135        LOGI("Waiting for activity manager...");
136    }
137    Parcel data, reply;
138    // XXX Need to also supply a package name for this to work again.
139    // IActivityManager::getInterfaceDescriptor() is the token for invoking on this interface;
140    // hardcoding it here avoids having to link with the full Activity Manager library
141    data.writeInterfaceToken(String16("android.app.IActivityManager"));
142    writeStringToParcel(data, NULL);
143    writeStringToParcel(data, gInitialApplication);
144    writeStringToParcel(data, gInitialVerb);
145    writeStringToParcel(data, gInitialData);
146LOGI("run() sending FIRST_CALL_TRANSACTION to activity manager");
147    am->transact(IBinder::FIRST_CALL_TRANSACTION, data, &reply);
148
149    if (proc->supportsProcesses()) {
150        // Now we link to the Activity Manager waiting for it to die. If it does kill ourself.
151        // initd will restart this process and bring the system back up.
152        sp<GrimReaper> grim = new GrimReaper();
153        am->linkToDeath(grim, grim.get(), 0);
154
155        // Now join the thread pool. Note this is needed so that the message enqueued in the driver
156        // for the linkToDeath gets processed.
157        IPCThreadState::self()->joinThreadPool();
158    } else {
159        // Keep this thread running forever...
160        while (1) {
161            usleep(100000);
162        }
163    }
164    return 1;
165}
166
167
168};  // namespace android
169
170
171/*
172 * Post-system-process initialization.
173 *
174 * This function continues initialization after the system process
175 * has been initialized.  It needs to be separate because the system
176 * initialization needs to care of starting the Android runtime if it is not
177 * running in its own process, which doesn't return until the runtime is
178 * being shut down.  So it will call back to here from inside of Dalvik,
179 * to allow us to continue booting up.
180 */
181static void finish_system_init(sp<ProcessState>& proc)
182{
183    // If we are running multiprocess, we now need to have the
184    // thread pool started here.  We don't do this in boot_init()
185    // because when running single process we need to start the
186    // thread pool after the Android runtime has been started (so
187    // the pool uses Dalvik threads).
188    if (proc->supportsProcesses()) {
189        proc->startThreadPool();
190    }
191}
192
193
194// This function can be used to enforce security to different
195// root contexts.  For now, we just give every access.
196static bool contextChecker(
197    const String16& name, const sp<IBinder>& caller, void* userData)
198{
199    return true;
200}
201
202/*
203 * Initialization of boot services.
204 *
205 * This is where we perform initialization of all of our low-level
206 * boot services.  Most importantly, here we become the context
207 * manager and use that to publish the service manager that will provide
208 * access to all other services.
209 */
210static void boot_init()
211{
212    LOGI("Entered boot_init()!\n");
213
214    sp<ProcessState> proc(ProcessState::self());
215    LOGD("ProcessState: %p\n", proc.get());
216    proc->becomeContextManager(contextChecker, NULL);
217
218    if (proc->supportsProcesses()) {
219        LOGI("Binder driver opened.  Multiprocess enabled.\n");
220    } else {
221        LOGI("Binder driver not found.  Processes not supported.\n");
222    }
223
224    sp<BServiceManager> sm = new BServiceManager;
225    proc->setContextObject(sm);
226}
227
228/*
229 * Redirect stdin/stdout/stderr to /dev/null.
230 */
231static void redirectStdFds(void)
232{
233    int fd = open("/dev/null", O_RDWR, 0);
234    if (fd < 0) {
235        LOGW("Unable to open /dev/null: %s\n", strerror(errno));
236    } else {
237        dup2(fd, 0);
238        dup2(fd, 1);
239        dup2(fd, 2);
240        close(fd);
241    }
242}
243
244static int hasDir(const char* dir)
245{
246    struct stat s;
247    int res = stat(dir, &s);
248    if (res == 0) {
249        return S_ISDIR(s.st_mode);
250    }
251    return 0;
252}
253
254static void validateTime()
255{
256#if HAVE_ANDROID_OS
257    int fd;
258    int res;
259    time_t min_time = 1167652800; // jan 1 2007, type 'date -ud "1/1 12:00" +%s' to get value for current year
260    struct timespec ts;
261
262    fd = open("/dev/alarm", O_RDWR);
263    if(fd < 0) {
264        LOGW("Unable to open alarm driver: %s\n", strerror(errno));
265        return;
266    }
267    res = ioctl(fd, ANDROID_ALARM_GET_TIME(ANDROID_ALARM_RTC_WAKEUP), &ts);
268    if(res < 0) {
269        LOGW("Unable to read rtc, %s\n", strerror(errno));
270    }
271    else if(ts.tv_sec >= min_time) {
272        goto done;
273    }
274    LOGW("Invalid time detected, %ld set to %ld\n", ts.tv_sec, min_time);
275    ts.tv_sec = min_time;
276    ts.tv_nsec = 0;
277    res = ioctl(fd, ANDROID_ALARM_SET_RTC, &ts);
278    if(res < 0) {
279        LOGW("Unable to set rtc to %ld: %s\n", ts.tv_sec, strerror(errno));
280    }
281done:
282    close(fd);
283#endif
284}
285
286#ifndef HAVE_ANDROID_OS
287class QuickRuntime : public AndroidRuntime
288{
289public:
290    QuickRuntime() {}
291
292    virtual void onStarted()
293    {
294        printf("QuickRuntime: onStarted\n");
295    }
296};
297#endif
298
299static status_t start_process(const char* name);
300
301static void restart_me(pid_t child, void* userData)
302{
303    start_process((const char*)userData);
304}
305
306static status_t start_process(const char* name)
307{
308    String8 path(name);
309    Vector<const char*> args;
310    String8 leaf(path.getPathLeaf());
311    String8 parentDir(path.getPathDir());
312    args.insertAt(leaf.string(), 0);
313    args.add(parentDir.string());
314    args.add(NULL);
315    pid_t child = fork();
316    if (child < 0) {
317        status_t err = errno;
318        LOGE("*** fork of child %s failed: %s", leaf.string(), strerror(err));
319        return -errno;
320    } else if (child == 0) {
321        LOGI("Executing: %s", path.string());
322        execv(path.string(), const_cast<char**>(args.array()));
323        int err = errno;
324        LOGE("Exec failed: %s\n", strerror(err));
325        _exit(err);
326    } else {
327        SignalHandler::setChildHandler(child, DEFAULT_PROCESS_TAG,
328                restart_me, (void*)name);
329    }
330    return -errno;
331}
332
333/*
334 * Application entry point.
335 *
336 * Parse arguments, set some values, and pass control off to Run().
337 *
338 * This is redefined to "SDL_main" on SDL simulator builds, and
339 * "runtime_main" on wxWidgets builds.
340 */
341extern "C"
342int main(int argc, char* const argv[])
343{
344    bool singleProcess = false;
345    const char* logFile = NULL;
346    int ic;
347    int result = 1;
348    pid_t systemPid;
349
350    sp<ProcessState> proc;
351
352#ifndef HAVE_ANDROID_OS
353    /* Set stdout/stderr to unbuffered for MinGW/MSYS. */
354    //setvbuf(stdout, NULL, _IONBF, 0);
355    //setvbuf(stderr, NULL, _IONBF, 0);
356
357    LOGI("commandline args:\n");
358    for (int i = 0; i < argc; i++)
359        LOGI("  %2d: '%s'\n", i, argv[i]);
360#endif
361
362    while (1) {
363        ic = getopt(argc, argv, "g:j:v:d:l:ns");
364        if (ic < 0)
365            break;
366
367        switch (ic) {
368        case 'g':
369            break;
370        case 'j':
371            gInitialApplication = optarg;
372            break;
373        case 'v':
374            gInitialVerb = optarg;
375            break;
376        case 'd':
377            gInitialData = optarg;
378            break;
379        case 'l':
380            logFile = optarg;
381            break;
382        case 'n':
383            redirectStdFds();
384            break;
385        case 's':
386            singleProcess = true;
387            break;
388        case '?':
389        default:
390            LOGE("runtime: unrecognized flag -%c\n", ic);
391            usage(argv[0]);
392            break;
393        }
394    }
395    if (optind < argc) {
396        LOGE("runtime: extra stuff: %s\n", argv[optind]);
397        usage(argv[0]);
398    }
399
400    if (singleProcess) {
401        ProcessState::setSingleProcess(true);
402    }
403
404    if (logFile != NULL) {
405        android_logToFile(NULL, logFile);
406    }
407
408    /*
409     * Set up ANDROID_* environment variables.
410     *
411     * TODO: the use of $ANDROID_PRODUCT_OUT will go away soon.
412     */
413    static const char* kSystemDir = "/system";
414    static const char* kDataDir = "/data";
415    static const char* kAppSubdir = "/app";
416    const char* out = NULL;
417#ifndef HAVE_ANDROID_OS
418    //out = getenv("ANDROID_PRODUCT_OUT");
419#endif
420    if (out == NULL)
421        out = "";
422
423    char* systemDir = (char*) malloc(strlen(out) + strlen(kSystemDir) +1);
424    char* dataDir = (char*) malloc(strlen(out) + strlen(kDataDir) +1);
425
426    sprintf(systemDir, "%s%s", out, kSystemDir);
427    sprintf(dataDir, "%s%s", out, kDataDir);
428    setenv("ANDROID_ROOT", systemDir, 1);
429    setenv("ANDROID_DATA", dataDir, 1);
430
431    char* assetDir = (char*) malloc(strlen(systemDir) + strlen(kAppSubdir) +1);
432    sprintf(assetDir, "%s%s", systemDir, kAppSubdir);
433
434    LOGI("Startup: sys='%s' asset='%s' data='%s'\n",
435        systemDir, assetDir, dataDir);
436    free(systemDir);
437    free(dataDir);
438
439#ifdef HAVE_ANDROID_OS
440    /* set up a process group for easier killing on the device */
441    setpgid(0, getpid());
442#endif
443
444    // Change to asset dir.  This is only necessary if we've changed to
445    // a different directory, but there's little harm in doing it regardless.
446    //
447    // Expecting assets to live in the current dir is not a great idea,
448    // because some of our code or one of our libraries could change the
449    // directory out from under us.  Preserve the behavior for now.
450    if (chdir(assetDir) != 0) {
451        LOGW("WARNING: could not change dir to '%s': %s\n",
452             assetDir, strerror(errno));
453    }
454    free(assetDir);
455
456#if 0
457    // Hack to keep libc from beating the filesystem to death.  It's
458    // hitting /etc/localtime frequently,
459    //
460    // This statement locks us into Pacific time.  We could do better,
461    // but there's not much point until we're sure that the library
462    // can't be changed to do more along the lines of what we want.
463#ifndef XP_WIN
464    setenv("TZ", "PST+8PDT,M4.1.0/2,M10.5.0/2", true);
465#endif
466#endif
467
468    /* track our progress through the boot sequence */
469    const int LOG_BOOT_PROGRESS_START = 3000;
470    LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,
471        ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
472
473    validateTime();
474
475    proc = ProcessState::self();
476
477    boot_init();
478
479    /* If we are in multiprocess mode, have zygote spawn the system
480     * server process and call system_init(). If we are running in
481     * single process mode just call system_init() directly.
482     */
483    if (proc->supportsProcesses()) {
484        // If stdio logging is on, system_server should not inherit our stdio
485        // The dalvikvm instance will copy stdio to the log on its own
486        char propBuf[PROPERTY_VALUE_MAX];
487        bool logStdio = false;
488        property_get("log.redirect-stdio", propBuf, "");
489        logStdio = (strcmp(propBuf, "true") == 0);
490
491        zygote_run_oneshot((int)(!logStdio),
492                sizeof(ZYGOTE_ARGV) / sizeof(ZYGOTE_ARGV[0]),
493                ZYGOTE_ARGV);
494
495        //start_process("/system/bin/mediaserver");
496
497    } else {
498#ifndef HAVE_ANDROID_OS
499        QuickRuntime* runt = new QuickRuntime();
500        runt->start("com/android/server/SystemServer",
501                    false /* spontaneously fork system server from zygote */);
502#endif
503    }
504
505    //printf("+++ post-zygote\n");
506
507    finish_system_init(proc);
508    run(proc);
509
510bail:
511    if (proc != NULL) {
512        proc->setContextObject(NULL);
513    }
514
515    return 0;
516}
517