blob: e3b72c264c75e7805268eb2b1ea703d028cdf186 [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,
Jeff Brown10e89712011-07-08 18:52:57 -070096 "Usage: runtime [-g gamma] [-l logfile] [-n]\n"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097 " [-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"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101 "-j: Custom home app component name\n"
102 "-v: Custom home app intent verb\n"
103 "-d: Custom home app intent data\n"
104 );
105 exit(1);
106}
107
108// Selected application to run.
109static const char* gInitialApplication = NULL;
110static const char* gInitialVerb = NULL;
111static const char* gInitialData = NULL;
112
113static void writeStringToParcel(Parcel& parcel, const char* str)
114{
115 if (str) {
116 parcel.writeString16(String16(str));
117 } else {
118 parcel.writeString16(NULL, 0);
119 }
120}
121
122/*
123 * Starting point for program logic.
124 *
125 * Returns with an exit status code (0 on success, nonzero on error).
126 */
127static int run(sp<ProcessState>& proc)
128{
129 // Temporary hack to call startRunning() on the activity manager.
130 sp<IServiceManager> sm = defaultServiceManager();
131 sp<IBinder> am;
132 while ((am = sm->getService(String16("activity"))) == NULL) {
133 LOGI("Waiting for activity manager...");
134 }
135 Parcel data, reply;
136 // XXX Need to also supply a package name for this to work again.
137 // IActivityManager::getInterfaceDescriptor() is the token for invoking on this interface;
138 // hardcoding it here avoids having to link with the full Activity Manager library
139 data.writeInterfaceToken(String16("android.app.IActivityManager"));
140 writeStringToParcel(data, NULL);
141 writeStringToParcel(data, gInitialApplication);
142 writeStringToParcel(data, gInitialVerb);
143 writeStringToParcel(data, gInitialData);
144LOGI("run() sending FIRST_CALL_TRANSACTION to activity manager");
145 am->transact(IBinder::FIRST_CALL_TRANSACTION, data, &reply);
146
Jeff Brown10e89712011-07-08 18:52:57 -0700147 // Now we link to the Activity Manager waiting for it to die. If it does kill ourself.
148 // initd will restart this process and bring the system back up.
149 sp<GrimReaper> grim = new GrimReaper();
150 am->linkToDeath(grim, grim.get(), 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151
Jeff Brown10e89712011-07-08 18:52:57 -0700152 // Now join the thread pool. Note this is needed so that the message enqueued in the driver
153 // for the linkToDeath gets processed.
154 IPCThreadState::self()->joinThreadPool();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155 return 1;
156}
157
158
159}; // namespace android
160
161
162/*
163 * Post-system-process initialization.
Elliott Hughesd195e5a2011-04-13 15:39:37 -0700164 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165 * This function continues initialization after the system process
166 * has been initialized. It needs to be separate because the system
167 * initialization needs to care of starting the Android runtime if it is not
168 * running in its own process, which doesn't return until the runtime is
169 * being shut down. So it will call back to here from inside of Dalvik,
170 * to allow us to continue booting up.
171 */
172static void finish_system_init(sp<ProcessState>& proc)
173{
Jeff Brown10e89712011-07-08 18:52:57 -0700174 proc->startThreadPool();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800175}
176
177
178// This function can be used to enforce security to different
179// root contexts. For now, we just give every access.
180static bool contextChecker(
181 const String16& name, const sp<IBinder>& caller, void* userData)
182{
183 return true;
184}
185
186/*
187 * Initialization of boot services.
188 *
189 * This is where we perform initialization of all of our low-level
190 * boot services. Most importantly, here we become the context
191 * manager and use that to publish the service manager that will provide
192 * access to all other services.
193 */
194static void boot_init()
195{
196 LOGI("Entered boot_init()!\n");
Elliott Hughesd195e5a2011-04-13 15:39:37 -0700197
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800198 sp<ProcessState> proc(ProcessState::self());
199 LOGD("ProcessState: %p\n", proc.get());
200 proc->becomeContextManager(contextChecker, NULL);
Elliott Hughesd195e5a2011-04-13 15:39:37 -0700201
Jeff Brown10e89712011-07-08 18:52:57 -0700202 LOGI("Binder driver opened.\n");
Elliott Hughesd195e5a2011-04-13 15:39:37 -0700203
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204 sp<BServiceManager> sm = new BServiceManager;
205 proc->setContextObject(sm);
206}
207
208/*
209 * Redirect stdin/stdout/stderr to /dev/null.
210 */
211static void redirectStdFds(void)
212{
213 int fd = open("/dev/null", O_RDWR, 0);
214 if (fd < 0) {
215 LOGW("Unable to open /dev/null: %s\n", strerror(errno));
216 } else {
217 dup2(fd, 0);
218 dup2(fd, 1);
219 dup2(fd, 2);
220 close(fd);
221 }
222}
223
224static int hasDir(const char* dir)
225{
226 struct stat s;
227 int res = stat(dir, &s);
228 if (res == 0) {
229 return S_ISDIR(s.st_mode);
230 }
231 return 0;
232}
233
234static void validateTime()
235{
236#if HAVE_ANDROID_OS
237 int fd;
238 int res;
239 time_t min_time = 1167652800; // jan 1 2007, type 'date -ud "1/1 12:00" +%s' to get value for current year
240 struct timespec ts;
Elliott Hughesd195e5a2011-04-13 15:39:37 -0700241
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242 fd = open("/dev/alarm", O_RDWR);
243 if(fd < 0) {
244 LOGW("Unable to open alarm driver: %s\n", strerror(errno));
245 return;
246 }
247 res = ioctl(fd, ANDROID_ALARM_GET_TIME(ANDROID_ALARM_RTC_WAKEUP), &ts);
248 if(res < 0) {
249 LOGW("Unable to read rtc, %s\n", strerror(errno));
250 }
251 else if(ts.tv_sec >= min_time) {
252 goto done;
253 }
254 LOGW("Invalid time detected, %ld set to %ld\n", ts.tv_sec, min_time);
255 ts.tv_sec = min_time;
256 ts.tv_nsec = 0;
257 res = ioctl(fd, ANDROID_ALARM_SET_RTC, &ts);
258 if(res < 0) {
259 LOGW("Unable to set rtc to %ld: %s\n", ts.tv_sec, strerror(errno));
260 }
261done:
262 close(fd);
263#endif
264}
265
266#ifndef HAVE_ANDROID_OS
267class QuickRuntime : public AndroidRuntime
268{
269public:
270 QuickRuntime() {}
271
272 virtual void onStarted()
273 {
274 printf("QuickRuntime: onStarted\n");
275 }
276};
277#endif
278
279static status_t start_process(const char* name);
280
281static void restart_me(pid_t child, void* userData)
282{
283 start_process((const char*)userData);
284}
285
286static status_t start_process(const char* name)
287{
288 String8 path(name);
289 Vector<const char*> args;
290 String8 leaf(path.getPathLeaf());
291 String8 parentDir(path.getPathDir());
292 args.insertAt(leaf.string(), 0);
293 args.add(parentDir.string());
294 args.add(NULL);
295 pid_t child = fork();
296 if (child < 0) {
297 status_t err = errno;
298 LOGE("*** fork of child %s failed: %s", leaf.string(), strerror(err));
299 return -errno;
300 } else if (child == 0) {
301 LOGI("Executing: %s", path.string());
302 execv(path.string(), const_cast<char**>(args.array()));
303 int err = errno;
304 LOGE("Exec failed: %s\n", strerror(err));
305 _exit(err);
306 } else {
307 SignalHandler::setChildHandler(child, DEFAULT_PROCESS_TAG,
308 restart_me, (void*)name);
309 }
310 return -errno;
311}
312
313/*
314 * Application entry point.
315 *
316 * Parse arguments, set some values, and pass control off to Run().
317 *
318 * This is redefined to "SDL_main" on SDL simulator builds, and
319 * "runtime_main" on wxWidgets builds.
320 */
321extern "C"
322int main(int argc, char* const argv[])
323{
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800324 const char* logFile = NULL;
325 int ic;
326 int result = 1;
327 pid_t systemPid;
Elliott Hughesd195e5a2011-04-13 15:39:37 -0700328
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329 sp<ProcessState> proc;
330
331#ifndef HAVE_ANDROID_OS
332 /* Set stdout/stderr to unbuffered for MinGW/MSYS. */
333 //setvbuf(stdout, NULL, _IONBF, 0);
334 //setvbuf(stderr, NULL, _IONBF, 0);
Elliott Hughesd195e5a2011-04-13 15:39:37 -0700335
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336 LOGI("commandline args:\n");
337 for (int i = 0; i < argc; i++)
338 LOGI(" %2d: '%s'\n", i, argv[i]);
339#endif
340
341 while (1) {
Jeff Brown10e89712011-07-08 18:52:57 -0700342 ic = getopt(argc, argv, "g:j:v:d:l:n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343 if (ic < 0)
344 break;
345
346 switch (ic) {
347 case 'g':
348 break;
349 case 'j':
350 gInitialApplication = optarg;
351 break;
352 case 'v':
353 gInitialVerb = optarg;
354 break;
355 case 'd':
356 gInitialData = optarg;
357 break;
358 case 'l':
359 logFile = optarg;
360 break;
361 case 'n':
362 redirectStdFds();
363 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800364 case '?':
365 default:
366 LOGE("runtime: unrecognized flag -%c\n", ic);
367 usage(argv[0]);
368 break;
369 }
370 }
371 if (optind < argc) {
372 LOGE("runtime: extra stuff: %s\n", argv[optind]);
373 usage(argv[0]);
374 }
375
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376 if (logFile != NULL) {
377 android_logToFile(NULL, logFile);
378 }
379
380 /*
381 * Set up ANDROID_* environment variables.
382 *
383 * TODO: the use of $ANDROID_PRODUCT_OUT will go away soon.
384 */
385 static const char* kSystemDir = "/system";
386 static const char* kDataDir = "/data";
387 static const char* kAppSubdir = "/app";
388 const char* out = NULL;
389#ifndef HAVE_ANDROID_OS
390 //out = getenv("ANDROID_PRODUCT_OUT");
391#endif
392 if (out == NULL)
393 out = "";
394
395 char* systemDir = (char*) malloc(strlen(out) + strlen(kSystemDir) +1);
396 char* dataDir = (char*) malloc(strlen(out) + strlen(kDataDir) +1);
397
398 sprintf(systemDir, "%s%s", out, kSystemDir);
399 sprintf(dataDir, "%s%s", out, kDataDir);
400 setenv("ANDROID_ROOT", systemDir, 1);
401 setenv("ANDROID_DATA", dataDir, 1);
402
403 char* assetDir = (char*) malloc(strlen(systemDir) + strlen(kAppSubdir) +1);
404 sprintf(assetDir, "%s%s", systemDir, kAppSubdir);
405
406 LOGI("Startup: sys='%s' asset='%s' data='%s'\n",
407 systemDir, assetDir, dataDir);
408 free(systemDir);
409 free(dataDir);
410
411#ifdef HAVE_ANDROID_OS
412 /* set up a process group for easier killing on the device */
413 setpgid(0, getpid());
414#endif
415
416 // Change to asset dir. This is only necessary if we've changed to
417 // a different directory, but there's little harm in doing it regardless.
418 //
419 // Expecting assets to live in the current dir is not a great idea,
420 // because some of our code or one of our libraries could change the
421 // directory out from under us. Preserve the behavior for now.
422 if (chdir(assetDir) != 0) {
423 LOGW("WARNING: could not change dir to '%s': %s\n",
424 assetDir, strerror(errno));
425 }
426 free(assetDir);
427
428#if 0
429 // Hack to keep libc from beating the filesystem to death. It's
Elliott Hughesd195e5a2011-04-13 15:39:37 -0700430 // hitting /etc/localtime frequently,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800431 //
432 // This statement locks us into Pacific time. We could do better,
433 // but there's not much point until we're sure that the library
434 // can't be changed to do more along the lines of what we want.
435#ifndef XP_WIN
436 setenv("TZ", "PST+8PDT,M4.1.0/2,M10.5.0/2", true);
437#endif
438#endif
439
440 /* track our progress through the boot sequence */
441 const int LOG_BOOT_PROGRESS_START = 3000;
Elliott Hughesd195e5a2011-04-13 15:39:37 -0700442 LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800443 ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
444
445 validateTime();
446
447 proc = ProcessState::self();
Elliott Hughesd195e5a2011-04-13 15:39:37 -0700448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449 boot_init();
Elliott Hughesd195e5a2011-04-13 15:39:37 -0700450
Jeff Brown10e89712011-07-08 18:52:57 -0700451 // Have zygote spawn the system server process and call system_init().
452 // If stdio logging is on, system_server should not inherit our stdio
453 // The dalvikvm instance will copy stdio to the log on its own
454 char propBuf[PROPERTY_VALUE_MAX];
455 bool logStdio = false;
456 property_get("log.redirect-stdio", propBuf, "");
457 logStdio = (strcmp(propBuf, "true") == 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800458
Jeff Brown10e89712011-07-08 18:52:57 -0700459 zygote_run_oneshot((int)(!logStdio),
460 sizeof(ZYGOTE_ARGV) / sizeof(ZYGOTE_ARGV[0]),
461 ZYGOTE_ARGV);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800462
463 finish_system_init(proc);
464 run(proc);
Elliott Hughesd195e5a2011-04-13 15:39:37 -0700465
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800466bail:
467 if (proc != NULL) {
468 proc->setContextObject(NULL);
469 }
Elliott Hughesd195e5a2011-04-13 15:39:37 -0700470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800471 return 0;
472}