* commit '3856a219fa414ee53c5ef3a0c35dae35e2ca80b1': Clean up argc / argv processing for runtime args.
This commit is contained in:
@ -32,30 +32,20 @@ class AppRuntime : public AndroidRuntime
|
|||||||
public:
|
public:
|
||||||
AppRuntime(char* argBlockStart, const size_t argBlockLength)
|
AppRuntime(char* argBlockStart, const size_t argBlockLength)
|
||||||
: AndroidRuntime(argBlockStart, argBlockLength)
|
: AndroidRuntime(argBlockStart, argBlockLength)
|
||||||
, mParentDir(NULL)
|
|
||||||
, mClassName(NULL)
|
|
||||||
, mClass(NULL)
|
, mClass(NULL)
|
||||||
, mArgC(0)
|
|
||||||
, mArgV(NULL)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
void setClassNameAndArgs(const String8& className, int argc, char * const *argv) {
|
||||||
// this appears to be unused
|
mClassName = className;
|
||||||
const char* getParentDir() const
|
for (int i = 0; i < argc; ++i) {
|
||||||
{
|
mArgs.add(String8(argv[i]));
|
||||||
return mParentDir;
|
}
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const char* getClassName() const
|
|
||||||
{
|
|
||||||
return mClassName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void onVmCreated(JNIEnv* env)
|
virtual void onVmCreated(JNIEnv* env)
|
||||||
{
|
{
|
||||||
if (mClassName == NULL) {
|
if (mClassName.isEmpty()) {
|
||||||
return; // Zygote. Nothing to do here.
|
return; // Zygote. Nothing to do here.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,10 +62,10 @@ public:
|
|||||||
* executing boot class Java code and thereby deny ourselves access to
|
* executing boot class Java code and thereby deny ourselves access to
|
||||||
* non-boot classes.
|
* non-boot classes.
|
||||||
*/
|
*/
|
||||||
char* slashClassName = toSlashClassName(mClassName);
|
char* slashClassName = toSlashClassName(mClassName.string());
|
||||||
mClass = env->FindClass(slashClassName);
|
mClass = env->FindClass(slashClassName);
|
||||||
if (mClass == NULL) {
|
if (mClass == NULL) {
|
||||||
ALOGE("ERROR: could not find class '%s'\n", mClassName);
|
ALOGE("ERROR: could not find class '%s'\n", mClassName.string());
|
||||||
}
|
}
|
||||||
free(slashClassName);
|
free(slashClassName);
|
||||||
|
|
||||||
@ -89,7 +79,7 @@ public:
|
|||||||
proc->startThreadPool();
|
proc->startThreadPool();
|
||||||
|
|
||||||
AndroidRuntime* ar = AndroidRuntime::getRuntime();
|
AndroidRuntime* ar = AndroidRuntime::getRuntime();
|
||||||
ar->callMain(mClassName, mClass, mArgC, mArgV);
|
ar->callMain(mClassName, mClass, mArgs);
|
||||||
|
|
||||||
IPCThreadState::self()->stopProcess();
|
IPCThreadState::self()->stopProcess();
|
||||||
}
|
}
|
||||||
@ -115,11 +105,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char* mParentDir;
|
String8 mClassName;
|
||||||
const char* mClassName;
|
Vector<String8> mArgs;
|
||||||
jclass mClass;
|
jclass mClass;
|
||||||
int mArgC;
|
|
||||||
const char* const* mArgV;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -155,7 +143,26 @@ int main(int argc, char* const argv[])
|
|||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
|
|
||||||
// Everything up to '--' or first non '-' arg goes to the vm
|
// Everything up to '--' or first non '-' arg goes to the vm.
|
||||||
|
//
|
||||||
|
// The first argument after the VM args is the "parent dir", which
|
||||||
|
// is currently unused.
|
||||||
|
//
|
||||||
|
// After the parent dir, we expect one or more the following internal
|
||||||
|
// arguments :
|
||||||
|
//
|
||||||
|
// --zygote : Start in zygote mode
|
||||||
|
// --start-system-server : Start the system server.
|
||||||
|
// --application : Start in application (stand alone, non zygote) mode.
|
||||||
|
// --nice-name : The nice name for this process.
|
||||||
|
//
|
||||||
|
// For non zygote starts, these arguments will be followed by
|
||||||
|
// the main class name. All remaining arguments are passed to
|
||||||
|
// the main method of this class.
|
||||||
|
//
|
||||||
|
// For zygote starts, all remaining arguments are passed to the zygote.
|
||||||
|
// main function.
|
||||||
|
|
||||||
|
|
||||||
int i = runtime.addVmArguments(argc, argv);
|
int i = runtime.addVmArguments(argc, argv);
|
||||||
|
|
||||||
@ -163,14 +170,13 @@ int main(int argc, char* const argv[])
|
|||||||
bool zygote = false;
|
bool zygote = false;
|
||||||
bool startSystemServer = false;
|
bool startSystemServer = false;
|
||||||
bool application = false;
|
bool application = false;
|
||||||
const char* parentDir = NULL;
|
|
||||||
const char* niceName = NULL;
|
const char* niceName = NULL;
|
||||||
const char* className = NULL;
|
String8 className;
|
||||||
|
|
||||||
|
++i; // Skip unused "parent dir" argument.
|
||||||
while (i < argc) {
|
while (i < argc) {
|
||||||
const char* arg = argv[i++];
|
const char* arg = argv[i++];
|
||||||
if (!parentDir) {
|
if (strcmp(arg, "--zygote") == 0) {
|
||||||
parentDir = arg;
|
|
||||||
} else if (strcmp(arg, "--zygote") == 0) {
|
|
||||||
zygote = true;
|
zygote = true;
|
||||||
niceName = "zygote";
|
niceName = "zygote";
|
||||||
} else if (strcmp(arg, "--start-system-server") == 0) {
|
} else if (strcmp(arg, "--start-system-server") == 0) {
|
||||||
@ -180,28 +186,41 @@ int main(int argc, char* const argv[])
|
|||||||
} else if (strncmp(arg, "--nice-name=", 12) == 0) {
|
} else if (strncmp(arg, "--nice-name=", 12) == 0) {
|
||||||
niceName = arg + 12;
|
niceName = arg + 12;
|
||||||
} else {
|
} else {
|
||||||
className = arg;
|
className.setTo(arg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector<String8> args;
|
||||||
|
if (!className.isEmpty()) {
|
||||||
|
// We're not in zygote mode, the only argument we need to pass
|
||||||
|
// to RuntimeInit is the application argument.
|
||||||
|
//
|
||||||
|
// The Remainder of args get passed to startup class main(). Make
|
||||||
|
// copies of them before we overwrite them with the process name.
|
||||||
|
args.add(application ? String8("application") : String8("tool"));
|
||||||
|
runtime.setClassNameAndArgs(className, argc - i, argv + i);
|
||||||
|
} else {
|
||||||
|
if (startSystemServer) {
|
||||||
|
args.add(String8("start-system-server"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// In zygote mode, pass all remaining arguments to the zygote
|
||||||
|
// main() method.
|
||||||
|
for (; i < argc; ++i) {
|
||||||
|
args.add(String8(argv[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (niceName && *niceName) {
|
if (niceName && *niceName) {
|
||||||
runtime.setArgv0(niceName);
|
runtime.setArgv0(niceName);
|
||||||
set_process_name(niceName);
|
set_process_name(niceName);
|
||||||
}
|
}
|
||||||
|
|
||||||
runtime.mParentDir = parentDir;
|
|
||||||
|
|
||||||
if (zygote) {
|
if (zygote) {
|
||||||
runtime.start("com.android.internal.os.ZygoteInit",
|
runtime.start("com.android.internal.os.ZygoteInit", args);
|
||||||
startSystemServer ? "start-system-server" : "");
|
|
||||||
} else if (className) {
|
} else if (className) {
|
||||||
// Remainder of args get passed to startup class main()
|
runtime.start("com.android.internal.os.RuntimeInit", args);
|
||||||
runtime.mClassName = className;
|
|
||||||
runtime.mArgC = argc - i;
|
|
||||||
runtime.mArgV = argv + i;
|
|
||||||
runtime.start("com.android.internal.os.RuntimeInit",
|
|
||||||
application ? "application" : "tool");
|
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
|
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
|
||||||
app_usage();
|
app_usage();
|
||||||
|
@ -270,13 +270,13 @@ void AndroidRuntime::setArgv0(const char* argv0) {
|
|||||||
strlcpy(mArgBlockStart, argv0, mArgBlockLength);
|
strlcpy(mArgBlockStart, argv0, mArgBlockLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t AndroidRuntime::callMain(const char* className,
|
status_t AndroidRuntime::callMain(const String8& className, jclass clazz,
|
||||||
jclass clazz, int argc, const char* const argv[])
|
const Vector<String8>& args)
|
||||||
{
|
{
|
||||||
JNIEnv* env;
|
JNIEnv* env;
|
||||||
jmethodID methodId;
|
jmethodID methodId;
|
||||||
|
|
||||||
ALOGD("Calling main entry %s", className);
|
ALOGD("Calling main entry %s", className.string());
|
||||||
|
|
||||||
env = getJNIEnv();
|
env = getJNIEnv();
|
||||||
if (clazz == NULL || env == NULL) {
|
if (clazz == NULL || env == NULL) {
|
||||||
@ -285,7 +285,7 @@ status_t AndroidRuntime::callMain(const char* className,
|
|||||||
|
|
||||||
methodId = env->GetStaticMethodID(clazz, "main", "([Ljava/lang/String;)V");
|
methodId = env->GetStaticMethodID(clazz, "main", "([Ljava/lang/String;)V");
|
||||||
if (methodId == NULL) {
|
if (methodId == NULL) {
|
||||||
ALOGE("ERROR: could not find method %s.main(String[])\n", className);
|
ALOGE("ERROR: could not find method %s.main(String[])\n", className.string());
|
||||||
return UNKNOWN_ERROR;
|
return UNKNOWN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,11 +296,12 @@ status_t AndroidRuntime::callMain(const char* className,
|
|||||||
jclass stringClass;
|
jclass stringClass;
|
||||||
jobjectArray strArray;
|
jobjectArray strArray;
|
||||||
|
|
||||||
|
const size_t numArgs = args.size();
|
||||||
stringClass = env->FindClass("java/lang/String");
|
stringClass = env->FindClass("java/lang/String");
|
||||||
strArray = env->NewObjectArray(argc, stringClass, NULL);
|
strArray = env->NewObjectArray(numArgs, stringClass, NULL);
|
||||||
|
|
||||||
for (int i = 0; i < argc; i++) {
|
for (size_t i = 0; i < numArgs; i++) {
|
||||||
jstring argStr = env->NewStringUTF(argv[i]);
|
jstring argStr = env->NewStringUTF(args[i].string());
|
||||||
env->SetObjectArrayElement(strArray, i, argStr);
|
env->SetObjectArrayElement(strArray, i, argStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -872,20 +873,23 @@ char* AndroidRuntime::toSlashClassName(const char* className)
|
|||||||
* Passes the main function two arguments, the class name and the specified
|
* Passes the main function two arguments, the class name and the specified
|
||||||
* options string.
|
* options string.
|
||||||
*/
|
*/
|
||||||
void AndroidRuntime::start(const char* className, const char* options)
|
void AndroidRuntime::start(const char* className, const Vector<String8>& options)
|
||||||
{
|
{
|
||||||
ALOGD("\n>>>>>> AndroidRuntime START %s <<<<<<\n",
|
ALOGD("\n>>>>>> AndroidRuntime START %s <<<<<<\n",
|
||||||
className != NULL ? className : "(unknown)");
|
className != NULL ? className : "(unknown)");
|
||||||
|
|
||||||
|
static const String8 startSystemServer("start-system-server");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 'startSystemServer == true' means runtime is obsolete and not run from
|
* 'startSystemServer == true' means runtime is obsolete and not run from
|
||||||
* init.rc anymore, so we print out the boot start event here.
|
* init.rc anymore, so we print out the boot start event here.
|
||||||
*/
|
*/
|
||||||
if (strcmp(options, "start-system-server") == 0) {
|
for (size_t i = 0; i < options.size(); ++i) {
|
||||||
/* track our progress through the boot sequence */
|
if (options[i] == startSystemServer) {
|
||||||
const int LOG_BOOT_PROGRESS_START = 3000;
|
/* track our progress through the boot sequence */
|
||||||
LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,
|
const int LOG_BOOT_PROGRESS_START = 3000;
|
||||||
ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
|
LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* rootDir = getenv("ANDROID_ROOT");
|
const char* rootDir = getenv("ANDROID_ROOT");
|
||||||
@ -926,17 +930,20 @@ void AndroidRuntime::start(const char* className, const char* options)
|
|||||||
jclass stringClass;
|
jclass stringClass;
|
||||||
jobjectArray strArray;
|
jobjectArray strArray;
|
||||||
jstring classNameStr;
|
jstring classNameStr;
|
||||||
jstring optionsStr;
|
|
||||||
|
|
||||||
stringClass = env->FindClass("java/lang/String");
|
stringClass = env->FindClass("java/lang/String");
|
||||||
assert(stringClass != NULL);
|
assert(stringClass != NULL);
|
||||||
strArray = env->NewObjectArray(2, stringClass, NULL);
|
strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
|
||||||
assert(strArray != NULL);
|
assert(strArray != NULL);
|
||||||
classNameStr = env->NewStringUTF(className);
|
classNameStr = env->NewStringUTF(className);
|
||||||
assert(classNameStr != NULL);
|
assert(classNameStr != NULL);
|
||||||
env->SetObjectArrayElement(strArray, 0, classNameStr);
|
env->SetObjectArrayElement(strArray, 0, classNameStr);
|
||||||
optionsStr = env->NewStringUTF(options);
|
|
||||||
env->SetObjectArrayElement(strArray, 1, optionsStr);
|
for (size_t i = 0; i < options.size(); ++i) {
|
||||||
|
jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
|
||||||
|
assert(optionsStr != NULL);
|
||||||
|
env->SetObjectArrayElement(strArray, i + 1, optionsStr);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start VM. This thread becomes the main thread of the VM, and will
|
* Start VM. This thread becomes the main thread of the VM, and will
|
||||||
|
@ -55,8 +55,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Call a class's static main method with the given arguments,
|
* Call a class's static main method with the given arguments,
|
||||||
*/
|
*/
|
||||||
status_t callMain(const char* className, jclass clazz, int argc,
|
status_t callMain(const String8& className, jclass clazz, const Vector<String8>& args);
|
||||||
const char* const argv[]);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a class, with the input either of the form
|
* Find a class, with the input either of the form
|
||||||
@ -66,7 +65,7 @@ public:
|
|||||||
|
|
||||||
int addVmArguments(int argc, const char* const argv[]);
|
int addVmArguments(int argc, const char* const argv[]);
|
||||||
|
|
||||||
void start(const char *classname, const char* options);
|
void start(const char *classname, const Vector<String8>& options);
|
||||||
|
|
||||||
void exit(int code);
|
void exit(int code);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user