app_main.cpp revision 8a0a929422682ba3eb6a205dc6c0638e68b909de
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Main entry of app process. 3d195e5ab401432ddac659791640a2927fc668699Elliott Hughes * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Starts the interpreted runtime, then starts up the application. 5d195e5ab401432ddac659791640a2927fc668699Elliott Hughes * 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "appproc" 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 100795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/IPCThreadState.h> 110795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/ProcessState.h> 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h> 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <cutils/process_name.h> 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <cutils/memory.h> 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <android_runtime/AndroidRuntime.h> 168a0a929422682ba3eb6a205dc6c0638e68b909deNick Kralevich#include <sys/personality.h> 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h> 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h> 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid app_usage() 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Usage: app_process [java-options] cmd-dir start-class-name [options]\n"); 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass AppRuntime : public AndroidRuntime 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic: 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AppRuntime() 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mParentDir(NULL) 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mClassName(NULL) 35d195e5ab401432ddac659791640a2927fc668699Elliott Hughes , mClass(NULL) 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mArgC(0) 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mArgV(NULL) 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this appears to be unused 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* getParentDir() const 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mParentDir; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* getClassName() const 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mClassName; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 54d195e5ab401432ddac659791640a2927fc668699Elliott Hughes virtual void onVmCreated(JNIEnv* env) 55d195e5ab401432ddac659791640a2927fc668699Elliott Hughes { 56d195e5ab401432ddac659791640a2927fc668699Elliott Hughes if (mClassName == NULL) { 57d195e5ab401432ddac659791640a2927fc668699Elliott Hughes return; // Zygote. Nothing to do here. 58d195e5ab401432ddac659791640a2927fc668699Elliott Hughes } 59d195e5ab401432ddac659791640a2927fc668699Elliott Hughes 60d195e5ab401432ddac659791640a2927fc668699Elliott Hughes /* 61d195e5ab401432ddac659791640a2927fc668699Elliott Hughes * This is a little awkward because the JNI FindClass call uses the 62d195e5ab401432ddac659791640a2927fc668699Elliott Hughes * class loader associated with the native method we're executing in. 63d195e5ab401432ddac659791640a2927fc668699Elliott Hughes * If called in onStarted (from RuntimeInit.finishInit because we're 64d195e5ab401432ddac659791640a2927fc668699Elliott Hughes * launching "am", for example), FindClass would see that we're calling 65d195e5ab401432ddac659791640a2927fc668699Elliott Hughes * from a boot class' native method, and so wouldn't look for the class 66d195e5ab401432ddac659791640a2927fc668699Elliott Hughes * we're trying to look up in CLASSPATH. Unfortunately it needs to, 67d195e5ab401432ddac659791640a2927fc668699Elliott Hughes * because the "am" classes are not boot classes. 68d195e5ab401432ddac659791640a2927fc668699Elliott Hughes * 69d195e5ab401432ddac659791640a2927fc668699Elliott Hughes * The easiest fix is to call FindClass here, early on before we start 70d195e5ab401432ddac659791640a2927fc668699Elliott Hughes * executing boot class Java code and thereby deny ourselves access to 71d195e5ab401432ddac659791640a2927fc668699Elliott Hughes * non-boot classes. 72d195e5ab401432ddac659791640a2927fc668699Elliott Hughes */ 73d195e5ab401432ddac659791640a2927fc668699Elliott Hughes char* slashClassName = toSlashClassName(mClassName); 74d195e5ab401432ddac659791640a2927fc668699Elliott Hughes mClass = env->FindClass(slashClassName); 75d195e5ab401432ddac659791640a2927fc668699Elliott Hughes if (mClass == NULL) { 763762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("ERROR: could not find class '%s'\n", mClassName); 77d195e5ab401432ddac659791640a2927fc668699Elliott Hughes } 78d195e5ab401432ddac659791640a2927fc668699Elliott Hughes free(slashClassName); 79d195e5ab401432ddac659791640a2927fc668699Elliott Hughes 80d195e5ab401432ddac659791640a2927fc668699Elliott Hughes mClass = reinterpret_cast<jclass>(env->NewGlobalRef(mClass)); 81d195e5ab401432ddac659791640a2927fc668699Elliott Hughes } 82d195e5ab401432ddac659791640a2927fc668699Elliott Hughes 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project virtual void onStarted() 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<ProcessState> proc = ProcessState::self(); 8671f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("App process: starting thread pool.\n"); 8710e89712863f5b91a2982dc1783fbdfe39c1485dJeff Brown proc->startThreadPool(); 88d195e5ab401432ddac659791640a2927fc668699Elliott Hughes 89d195e5ab401432ddac659791640a2927fc668699Elliott Hughes AndroidRuntime* ar = AndroidRuntime::getRuntime(); 90d195e5ab401432ddac659791640a2927fc668699Elliott Hughes ar->callMain(mClassName, mClass, mArgC, mArgV); 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9210e89712863f5b91a2982dc1783fbdfe39c1485dJeff Brown IPCThreadState::self()->stopProcess(); 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project virtual void onZygoteInit() 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<ProcessState> proc = ProcessState::self(); 9871f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("App process: starting thread pool.\n"); 9910e89712863f5b91a2982dc1783fbdfe39c1485dJeff Brown proc->startThreadPool(); 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project virtual void onExit(int code) 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mClassName == NULL) { 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if zygote 10610e89712863f5b91a2982dc1783fbdfe39c1485dJeff Brown IPCThreadState::self()->stopProcess(); 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AndroidRuntime::onExit(code); 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 112d195e5ab401432ddac659791640a2927fc668699Elliott Hughes 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* mParentDir; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* mClassName; 115d195e5ab401432ddac659791640a2927fc668699Elliott Hughes jclass mClass; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mArgC; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* const* mArgV; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectusing namespace android; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * sets argv0 to as much of newArgv0 as will fit 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void setArgv0(const char *argv0, const char *newArgv0) 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strlcpy(const_cast<char *>(argv0), newArgv0, strlen(argv0)); 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1328a0a929422682ba3eb6a205dc6c0638e68b909deNick Kralevichint main(int argc, char* const argv[]) 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1348a0a929422682ba3eb6a205dc6c0638e68b909deNick Kralevich#ifdef __arm__ 1358a0a929422682ba3eb6a205dc6c0638e68b909deNick Kralevich /* 1368a0a929422682ba3eb6a205dc6c0638e68b909deNick Kralevich * b/7188322 - Temporarily revert to the compat memory layout 1378a0a929422682ba3eb6a205dc6c0638e68b909deNick Kralevich * to avoid breaking third party apps. 1388a0a929422682ba3eb6a205dc6c0638e68b909deNick Kralevich * 1398a0a929422682ba3eb6a205dc6c0638e68b909deNick Kralevich * THIS WILL GO AWAY IN A FUTURE ANDROID RELEASE. 1408a0a929422682ba3eb6a205dc6c0638e68b909deNick Kralevich * 1418a0a929422682ba3eb6a205dc6c0638e68b909deNick Kralevich * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=7dbaa466 1428a0a929422682ba3eb6a205dc6c0638e68b909deNick Kralevich * changes the kernel mapping from bottom up to top-down. 1438a0a929422682ba3eb6a205dc6c0638e68b909deNick Kralevich * This breaks some programs which improperly embed 1448a0a929422682ba3eb6a205dc6c0638e68b909deNick Kralevich * an out of date copy of Android's linker. 1458a0a929422682ba3eb6a205dc6c0638e68b909deNick Kralevich */ 1468a0a929422682ba3eb6a205dc6c0638e68b909deNick Kralevich int current = personality(0xFFFFFFFF); 1478a0a929422682ba3eb6a205dc6c0638e68b909deNick Kralevich if ((current & ADDR_COMPAT_LAYOUT) == 0) { 1488a0a929422682ba3eb6a205dc6c0638e68b909deNick Kralevich personality(current | ADDR_COMPAT_LAYOUT); 1498a0a929422682ba3eb6a205dc6c0638e68b909deNick Kralevich execv("/system/bin/app_process", argv); 1508a0a929422682ba3eb6a205dc6c0638e68b909deNick Kralevich return -1; 1518a0a929422682ba3eb6a205dc6c0638e68b909deNick Kralevich } 1528a0a929422682ba3eb6a205dc6c0638e68b909deNick Kralevich#endif 1538a0a929422682ba3eb6a205dc6c0638e68b909deNick Kralevich 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // These are global variables in ProcessState.cpp 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mArgC = argc; 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mArgV = argv; 157d195e5ab401432ddac659791640a2927fc668699Elliott Hughes 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mArgLen = 0; 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<argc; i++) { 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mArgLen += strlen(argv[i]) + 1; 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mArgLen--; 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AppRuntime runtime; 165ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown const char* argv0 = argv[0]; 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Process command line arguments 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ignore argv[0] 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project argc--; 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project argv++; 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Everything up to '--' or first non '-' arg goes to the vm 173d195e5ab401432ddac659791640a2927fc668699Elliott Hughes 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i = runtime.addVmArguments(argc, argv); 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 176ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown // Parse runtime arguments. Stop at first unrecognized option. 177ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown bool zygote = false; 178ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown bool startSystemServer = false; 179ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown bool application = false; 180ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown const char* parentDir = NULL; 181ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown const char* niceName = NULL; 182ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown const char* className = NULL; 183ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown while (i < argc) { 184ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown const char* arg = argv[i++]; 185ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown if (!parentDir) { 186ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown parentDir = arg; 187ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown } else if (strcmp(arg, "--zygote") == 0) { 188ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown zygote = true; 189ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown niceName = "zygote"; 190ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown } else if (strcmp(arg, "--start-system-server") == 0) { 191ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown startSystemServer = true; 192ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown } else if (strcmp(arg, "--application") == 0) { 193ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown application = true; 194ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown } else if (strncmp(arg, "--nice-name=", 12) == 0) { 195ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown niceName = arg + 12; 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 197ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown className = arg; 198ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown break; 199ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown } 200ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown } 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 202ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown if (niceName && *niceName) { 203ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown setArgv0(argv0, niceName); 204ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown set_process_name(niceName); 205ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown } 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 207ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown runtime.mParentDir = parentDir; 208ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown 209ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown if (zygote) { 210ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown runtime.start("com.android.internal.os.ZygoteInit", 211ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown startSystemServer ? "start-system-server" : ""); 212ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown } else if (className) { 213ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown // Remainder of args get passed to startup class main() 214ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown runtime.mClassName = className; 215ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown runtime.mArgC = argc - i; 216ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown runtime.mArgV = argv + i; 217ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown runtime.start("com.android.internal.os.RuntimeInit", 218ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown application ? "application" : "tool"); 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fprintf(stderr, "Error: no class name or --zygote supplied.\n"); 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project app_usage(); 222de6d1d889ebf15250c04a8ffc204b91af1e447e3Brian Carlstrom LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied."); 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 10; 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 226