diff options
Diffstat (limited to 'cmds/app_process/app_main.cpp')
-rw-r--r-- | cmds/app_process/app_main.cpp | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/cmds/app_process/app_main.cpp b/cmds/app_process/app_main.cpp new file mode 100644 index 0000000..d825d5a --- /dev/null +++ b/cmds/app_process/app_main.cpp @@ -0,0 +1,180 @@ +/* + * Main entry of app process. + * + * Starts the interpreted runtime, then starts up the application. + * + */ + +#define LOG_TAG "appproc" + +#include <utils/IPCThreadState.h> +#include <utils/ProcessState.h> +#include <utils/Log.h> +#include <cutils/process_name.h> +#include <cutils/memory.h> +#include <android_runtime/AndroidRuntime.h> + +#include <stdio.h> +#include <unistd.h> + +namespace android { + +void app_usage() +{ + fprintf(stderr, + "Usage: app_process [java-options] cmd-dir start-class-name [options]\n"); +} + +status_t app_init(const char* className, int argc, const char* const argv[]) +{ + LOGV("Entered app_init()!\n"); + + AndroidRuntime* jr = AndroidRuntime::getRuntime(); + jr->callMain(className, argc, argv); + + LOGV("Exiting app_init()!\n"); + return NO_ERROR; +} + +class AppRuntime : public AndroidRuntime +{ +public: + AppRuntime() + : mParentDir(NULL) + , mClassName(NULL) + , mArgC(0) + , mArgV(NULL) + { + } + +#if 0 + // this appears to be unused + const char* getParentDir() const + { + return mParentDir; + } +#endif + + const char* getClassName() const + { + return mClassName; + } + + virtual void onStarted() + { + sp<ProcessState> proc = ProcessState::self(); + if (proc->supportsProcesses()) { + LOGV("App process: starting thread pool.\n"); + proc->startThreadPool(); + } + + app_init(mClassName, mArgC, mArgV); + + if (ProcessState::self()->supportsProcesses()) { + IPCThreadState::self()->stopProcess(); + } + } + + virtual void onZygoteInit() + { + sp<ProcessState> proc = ProcessState::self(); + if (proc->supportsProcesses()) { + LOGV("App process: starting thread pool.\n"); + proc->startThreadPool(); + } + } + + virtual void onExit(int code) + { + if (mClassName == NULL) { + // if zygote + if (ProcessState::self()->supportsProcesses()) { + IPCThreadState::self()->stopProcess(); + } + } + + AndroidRuntime::onExit(code); + } + + + const char* mParentDir; + const char* mClassName; + int mArgC; + const char* const* mArgV; +}; + +} + +using namespace android; + +/* + * sets argv0 to as much of newArgv0 as will fit + */ +static void setArgv0(const char *argv0, const char *newArgv0) +{ + strlcpy(const_cast<char *>(argv0), newArgv0, strlen(argv0)); +} + +int main(int argc, const char* const argv[]) +{ + // These are global variables in ProcessState.cpp + mArgC = argc; + mArgV = argv; + + mArgLen = 0; + for (int i=0; i<argc; i++) { + mArgLen += strlen(argv[i]) + 1; + } + mArgLen--; + + AppRuntime runtime; + const char *arg; + const char *argv0; + + argv0 = argv[0]; + + // Process command line arguments + // ignore argv[0] + argc--; + argv++; + + // Everything up to '--' or first non '-' arg goes to the vm + + int i = runtime.addVmArguments(argc, argv); + + // Next arg is parent directory + if (i < argc) { + runtime.mParentDir = argv[i++]; + } + + // Next arg is startup classname or "--zygote" + if (i < argc) { + arg = argv[i++]; + if (0 == strcmp("--zygote", arg)) { + bool startSystemServer = (i < argc) ? + strcmp(argv[i], "--start-system-server") == 0 : false; + setArgv0(argv0, "zygote"); + set_process_name("zygote"); + runtime.start("com.android.internal.os.ZygoteInit", + startSystemServer); + } else { + set_process_name(argv0); + + runtime.mClassName = arg; + + // Remainder of args get passed to startup class main() + runtime.mArgC = argc-i; + runtime.mArgV = argv+i; + + LOGV("App process is starting with pid=%d, class=%s.\n", + getpid(), runtime.getClassName()); + runtime.start(); + } + } else { + LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied."); + fprintf(stderr, "Error: no class name or --zygote supplied.\n"); + app_usage(); + return 10; + } + +} |