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