181 lines
4.1 KiB
C++
181 lines
4.1 KiB
C++
|
/*
|
||
|
* Main entry of app process.
|
||
|
*
|
||
|
* Starts the interpreted runtime, then starts up the application.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#define LOG_TAG "appproc"
|
||
|
|
||
|
#include <binder/IPCThreadState.h>
|
||
|
#include <binder/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;
|
||
|
}
|
||
|
|
||
|
}
|