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 } 517