OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / frameworks / base / cmds / runtime / main_runtime.cpp
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
44 static 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
58 using namespace android;
59
60 extern "C" status_t system_init();
61
62 enum {
63     SYSTEM_PROCESS_TAG = DEFAULT_PROCESS_TAG+1
64 };
65
66 extern Mutex gEventQMutex;
67 extern Condition gEventQCondition;
68
69 namespace android {
70
71 extern status_t app_init(const char* className);
72 extern 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  */
78 class GrimReaper : public IBinder::DeathRecipient {
79 public: 
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
89 extern void QuickTests();
90
91 /*
92  * Print usage info.
93  */
94 static 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.
111 static const char* gInitialApplication = NULL;
112 static const char* gInitialVerb = NULL;
113 static const char* gInitialData = NULL;
114
115 static 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  */
129 static 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);
146 LOGI("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  */
181 static 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.
196 static 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  */
210 static 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  */
231 static 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
244 static 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
254 static 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     }
281 done:
282     close(fd);
283 #endif
284 }
285
286 #ifndef HAVE_ANDROID_OS
287 class QuickRuntime : public AndroidRuntime
288 {
289 public:
290     QuickRuntime() {}
291
292     virtual void onStarted()
293     {
294         printf("QuickRuntime: onStarted\n");
295     }
296 };
297 #endif
298
299 static status_t start_process(const char* name);
300
301 static void restart_me(pid_t child, void* userData)
302 {
303     start_process((const char*)userData);
304 }
305
306 static 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  */
341 extern "C"
342 int 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     
510 bail:
511     if (proc != NULL) {
512         proc->setContextObject(NULL);
513     }
514     
515     return 0;
516 }