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