/* * Main entry of app process. * * Starts the interpreted runtime, then starts up the application. * */ #define LOG_TAG "appproc" #include #include #include #include #include #include #include #include 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 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 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(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