summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2011-04-13 15:39:37 -0700
committerElliott Hughes <enh@google.com>2011-04-13 16:43:15 -0700
commitd195e5ab401432ddac659791640a2927fc668699 (patch)
tree61169b923b4d530a097ac8ff9e3029dfe468b7cd
parent966f9e558d714d9d41189e989b21e6d5fec35047 (diff)
downloadframeworks_base-d195e5ab401432ddac659791640a2927fc668699.zip
frameworks_base-d195e5ab401432ddac659791640a2927fc668699.tar.gz
frameworks_base-d195e5ab401432ddac659791640a2927fc668699.tar.bz2
Replace a custom AndroidRuntime::findClass with a more targeted fix.
This seems simpler and more contained, and I think the comment explaining why hoop-jumping is necessary is a bit clearer now. Change-Id: Ief4afd7cbb42188ed835fce23e497520bdb753a8
-rw-r--r--cmds/app_process/app_main.cpp61
-rw-r--r--cmds/runtime/main_runtime.cpp39
-rw-r--r--cmds/system_server/library/system_init.cpp28
-rw-r--r--core/jni/AndroidRuntime.cpp202
-rw-r--r--core/jni/android_util_Process.cpp11
-rw-r--r--include/android_runtime/AndroidRuntime.h18
6 files changed, 145 insertions, 214 deletions
diff --git a/cmds/app_process/app_main.cpp b/cmds/app_process/app_main.cpp
index 0159edd..371268f 100644
--- a/cmds/app_process/app_main.cpp
+++ b/cmds/app_process/app_main.cpp
@@ -1,8 +1,8 @@
/*
* Main entry of app process.
- *
+ *
* Starts the interpreted runtime, then starts up the application.
- *
+ *
*/
#define LOG_TAG "appproc"
@@ -25,23 +25,13 @@ void app_usage()
"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)
+ , mClass(NULL)
, mArgC(0)
, mArgV(NULL)
{
@@ -60,6 +50,35 @@ public:
return mClassName;
}
+ virtual void onVmCreated(JNIEnv* env)
+ {
+ if (mClassName == NULL) {
+ return; // Zygote. Nothing to do here.
+ }
+
+ /*
+ * This is a little awkward because the JNI FindClass call uses the
+ * class loader associated with the native method we're executing in.
+ * If called in onStarted (from RuntimeInit.finishInit because we're
+ * launching "am", for example), FindClass would see that we're calling
+ * from a boot class' native method, and so wouldn't look for the class
+ * we're trying to look up in CLASSPATH. Unfortunately it needs to,
+ * because the "am" classes are not boot classes.
+ *
+ * The easiest fix is to call FindClass here, early on before we start
+ * executing boot class Java code and thereby deny ourselves access to
+ * non-boot classes.
+ */
+ char* slashClassName = toSlashClassName(mClassName);
+ mClass = env->FindClass(slashClassName);
+ if (mClass == NULL) {
+ LOGE("ERROR: could not find class '%s'\n", mClassName);
+ }
+ free(slashClassName);
+
+ mClass = reinterpret_cast<jclass>(env->NewGlobalRef(mClass));
+ }
+
virtual void onStarted()
{
sp<ProcessState> proc = ProcessState::self();
@@ -67,8 +86,9 @@ public:
LOGV("App process: starting thread pool.\n");
proc->startThreadPool();
}
-
- app_init(mClassName, mArgC, mArgV);
+
+ AndroidRuntime* ar = AndroidRuntime::getRuntime();
+ ar->callMain(mClassName, mClass, mArgC, mArgV);
if (ProcessState::self()->supportsProcesses()) {
IPCThreadState::self()->stopProcess();
@@ -81,7 +101,7 @@ public:
if (proc->supportsProcesses()) {
LOGV("App process: starting thread pool.\n");
proc->startThreadPool();
- }
+ }
}
virtual void onExit(int code)
@@ -96,9 +116,10 @@ public:
AndroidRuntime::onExit(code);
}
-
+
const char* mParentDir;
const char* mClassName;
+ jclass mClass;
int mArgC;
const char* const* mArgV;
};
@@ -120,7 +141,7 @@ 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;
@@ -139,7 +160,7 @@ int main(int argc, const char* const argv[])
argv++;
// Everything up to '--' or first non '-' arg goes to the vm
-
+
int i = runtime.addVmArguments(argc, argv);
// Next arg is parent directory
@@ -151,7 +172,7 @@ int main(int argc, const char* const argv[])
if (i < argc) {
arg = argv[i++];
if (0 == strcmp("--zygote", arg)) {
- bool startSystemServer = (i < argc) ?
+ bool startSystemServer = (i < argc) ?
strcmp(argv[i], "--start-system-server") == 0 : false;
setArgv0(argv0, "zygote");
set_process_name("zygote");
diff --git a/cmds/runtime/main_runtime.cpp b/cmds/runtime/main_runtime.cpp
index 83cb533..785e4cc 100644
--- a/cmds/runtime/main_runtime.cpp
+++ b/cmds/runtime/main_runtime.cpp
@@ -12,7 +12,7 @@
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
-#include <utils/Log.h>
+#include <utils/Log.h>
#include <cutils/zygote.h>
#include <cutils/properties.h>
@@ -41,7 +41,7 @@
#undef LOG_TAG
#define LOG_TAG "runtime"
-static const char* ZYGOTE_ARGV[] = {
+static const char* ZYGOTE_ARGV[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,3001,3002,3003",
@@ -68,7 +68,6 @@ extern Condition gEventQCondition;
namespace android {
-extern status_t app_init(const char* className);
extern void set_finish_init_func(void (*func)());
@@ -76,7 +75,7 @@ extern void set_finish_init_func(void (*func)());
* This class is used to kill this process (runtime) when the system_server dies.
*/
class GrimReaper : public IBinder::DeathRecipient {
-public:
+public:
GrimReaper() { }
virtual void binderDied(const wp<IBinder>& who)
@@ -170,7 +169,7 @@ LOGI("run() sending FIRST_CALL_TRANSACTION to activity manager");
/*
* Post-system-process initialization.
- *
+ *
* This function continues initialization after the system process
* has been initialized. It needs to be separate because the system
* initialization needs to care of starting the Android runtime if it is not
@@ -210,17 +209,17 @@ static bool contextChecker(
static void boot_init()
{
LOGI("Entered boot_init()!\n");
-
+
sp<ProcessState> proc(ProcessState::self());
LOGD("ProcessState: %p\n", proc.get());
proc->becomeContextManager(contextChecker, NULL);
-
+
if (proc->supportsProcesses()) {
LOGI("Binder driver opened. Multiprocess enabled.\n");
} else {
LOGI("Binder driver not found. Processes not supported.\n");
}
-
+
sp<BServiceManager> sm = new BServiceManager;
proc->setContextObject(sm);
}
@@ -258,7 +257,7 @@ static void validateTime()
int res;
time_t min_time = 1167652800; // jan 1 2007, type 'date -ud "1/1 12:00" +%s' to get value for current year
struct timespec ts;
-
+
fd = open("/dev/alarm", O_RDWR);
if(fd < 0) {
LOGW("Unable to open alarm driver: %s\n", strerror(errno));
@@ -346,14 +345,14 @@ int main(int argc, char* const argv[])
int ic;
int result = 1;
pid_t systemPid;
-
+
sp<ProcessState> proc;
#ifndef HAVE_ANDROID_OS
/* Set stdout/stderr to unbuffered for MinGW/MSYS. */
//setvbuf(stdout, NULL, _IONBF, 0);
//setvbuf(stderr, NULL, _IONBF, 0);
-
+
LOGI("commandline args:\n");
for (int i = 0; i < argc; i++)
LOGI(" %2d: '%s'\n", i, argv[i]);
@@ -455,7 +454,7 @@ int main(int argc, char* const argv[])
#if 0
// Hack to keep libc from beating the filesystem to death. It's
- // hitting /etc/localtime frequently,
+ // hitting /etc/localtime frequently,
//
// This statement locks us into Pacific time. We could do better,
// but there's not much point until we're sure that the library
@@ -467,15 +466,15 @@ int main(int argc, char* const argv[])
/* track our progress through the boot sequence */
const int LOG_BOOT_PROGRESS_START = 3000;
- LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,
+ LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,
ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
validateTime();
proc = ProcessState::self();
-
+
boot_init();
-
+
/* If we are in multiprocess mode, have zygote spawn the system
* server process and call system_init(). If we are running in
* single process mode just call system_init() directly.
@@ -488,8 +487,8 @@ int main(int argc, char* const argv[])
property_get("log.redirect-stdio", propBuf, "");
logStdio = (strcmp(propBuf, "true") == 0);
- zygote_run_oneshot((int)(!logStdio),
- sizeof(ZYGOTE_ARGV) / sizeof(ZYGOTE_ARGV[0]),
+ zygote_run_oneshot((int)(!logStdio),
+ sizeof(ZYGOTE_ARGV) / sizeof(ZYGOTE_ARGV[0]),
ZYGOTE_ARGV);
//start_process("/system/bin/mediaserver");
@@ -497,7 +496,7 @@ int main(int argc, char* const argv[])
} else {
#ifndef HAVE_ANDROID_OS
QuickRuntime* runt = new QuickRuntime();
- runt->start("com/android/server/SystemServer",
+ runt->start("com/android/server/SystemServer",
false /* spontaneously fork system server from zygote */);
#endif
}
@@ -506,11 +505,11 @@ int main(int argc, char* const argv[])
finish_system_init(proc);
run(proc);
-
+
bail:
if (proc != NULL) {
proc->setContextObject(NULL);
}
-
+
return 0;
}
diff --git a/cmds/system_server/library/system_init.cpp b/cmds/system_server/library/system_init.cpp
index a29ba73..b615764 100644
--- a/cmds/system_server/library/system_init.cpp
+++ b/cmds/system_server/library/system_init.cpp
@@ -37,7 +37,7 @@ namespace android {
* This class is used to kill this process when the runtime dies.
*/
class GrimReaper : public IBinder::DeathRecipient {
-public:
+public:
GrimReaper() { }
virtual void binderDied(const wp<IBinder>& who)
@@ -54,15 +54,15 @@ public:
extern "C" status_t system_init()
{
LOGI("Entered system_init()");
-
+
sp<ProcessState> proc(ProcessState::self());
-
+
sp<IServiceManager> sm = defaultServiceManager();
LOGI("ServiceManager: %p\n", sm.get());
-
+
sp<GrimReaper> grim = new GrimReaper();
sm->asBinder()->linkToDeath(grim, grim.get(), 0);
-
+
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsurfaceflinger", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
@@ -97,12 +97,23 @@ extern "C" status_t system_init()
// the beginning of their processes's main(), before calling
// the init function.
LOGI("System server: starting Android runtime.\n");
-
AndroidRuntime* runtime = AndroidRuntime::getRuntime();
LOGI("System server: starting Android services.\n");
- runtime->callStatic("com/android/server/SystemServer", "init2");
-
+ JNIEnv* env = runtime->getJNIEnv();
+ if (env == NULL) {
+ return UNKNOWN_ERROR;
+ }
+ jclass clazz = env->FindClass("com/android/server/SystemServer");
+ if (clazz == NULL) {
+ return UNKNOWN_ERROR;
+ }
+ jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");
+ if (methodId == NULL) {
+ return UNKNOWN_ERROR;
+ }
+ env->CallStaticVoidMethod(clazz, methodId);
+
// If running in our own process, just go into the thread
// pool. Otherwise, call the initialization finished
// func to let this process continue its initilization.
@@ -114,4 +125,3 @@ extern "C" status_t system_init()
}
return NO_ERROR;
}
-
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index f29d83e..b628b9d 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -1,19 +1,18 @@
-/* //device/libs/android_runtime/AndroidRuntime.cpp
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
#define LOG_TAG "AndroidRuntime"
//#define LOG_NDEBUG 0
@@ -212,7 +211,7 @@ static jint com_android_internal_os_RuntimeInit_getQwertyKeyboard(JNIEnv* env, j
if (value != NULL && strcmp(value, "true") == 0) {
return 1;
}
-
+
return 0;
}
@@ -227,7 +226,7 @@ static JNINativeMethod gMethods[] = {
{ "isComputerOn", "()I",
(void*) com_android_internal_os_RuntimeInit_isComputerOn },
{ "turnComputerOn", "()V",
- (void*) com_android_internal_os_RuntimeInit_turnComputerOn },
+ (void*) com_android_internal_os_RuntimeInit_turnComputerOn },
{ "getQwertyKeyboard", "()I",
(void*) com_android_internal_os_RuntimeInit_getQwertyKeyboard },
};
@@ -278,51 +277,16 @@ AndroidRuntime::~AndroidRuntime()
return jniRegisterNativeMethods(env, className, gMethods, numMethods);
}
-/*
- * Call a static Java Programming Language function that takes no arguments and returns void.
- */
-status_t AndroidRuntime::callStatic(const char* className, const char* methodName)
+status_t AndroidRuntime::callMain(const char* className,
+ jclass clazz, int argc, const char* const argv[])
{
JNIEnv* env;
- jclass clazz;
- jmethodID methodId;
-
- env = getJNIEnv();
- if (env == NULL)
- return UNKNOWN_ERROR;
-
- clazz = findClass(env, className);
- if (clazz == NULL) {
- LOGE("ERROR: could not find class '%s'\n", className);
- return UNKNOWN_ERROR;
- }
- methodId = env->GetStaticMethodID(clazz, methodName, "()V");
- if (methodId == NULL) {
- LOGE("ERROR: could not find method %s.%s\n", className, methodName);
- return UNKNOWN_ERROR;
- }
-
- env->CallStaticVoidMethod(clazz, methodId);
-
- return NO_ERROR;
-}
-
-status_t AndroidRuntime::callMain(
- const char* className, int argc, const char* const argv[])
-{
- JNIEnv* env;
- jclass clazz;
jmethodID methodId;
LOGD("Calling main entry %s", className);
env = getJNIEnv();
- if (env == NULL)
- return UNKNOWN_ERROR;
-
- clazz = findClass(env, className);
- if (clazz == NULL) {
- LOGE("ERROR: could not find class '%s'\n", className);
+ if (clazz == NULL || env == NULL) {
return UNKNOWN_ERROR;
}
@@ -352,70 +316,6 @@ status_t AndroidRuntime::callMain(
}
/*
- * Find the named class.
- */
-jclass AndroidRuntime::findClass(JNIEnv* env, const char* className)
-{
- if (env->ExceptionCheck()) {
- LOGE("ERROR: exception pending on entry to findClass()");
- return NULL;
- }
-
- /*
- * This is a little awkward because the JNI FindClass call uses the
- * class loader associated with the native method we're executing in.
- * Because this native method is part of a "boot" class, JNI doesn't
- * look for the class in CLASSPATH, which unfortunately is a likely
- * location for it. (Had we issued the FindClass call before calling
- * into the VM -- at which point there isn't a native method frame on
- * the stack -- the VM would have checked CLASSPATH. We have to do
- * this because we call into Java Programming Language code and
- * bounce back out.)
- *
- * JNI lacks a "find class in a specific class loader" operation, so we
- * have to do things the hard way.
- */
- jclass cls = NULL;
-
- jclass javaLangClassLoader;
- jmethodID getSystemClassLoader, loadClass;
- jobject systemClassLoader;
- jstring strClassName;
-
- /* find the "system" class loader; none of this is expected to fail */
- javaLangClassLoader = env->FindClass("java/lang/ClassLoader");
- assert(javaLangClassLoader != NULL);
- getSystemClassLoader = env->GetStaticMethodID(javaLangClassLoader,
- "getSystemClassLoader", "()Ljava/lang/ClassLoader;");
- loadClass = env->GetMethodID(javaLangClassLoader,
- "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
- assert(getSystemClassLoader != NULL && loadClass != NULL);
- systemClassLoader = env->CallStaticObjectMethod(javaLangClassLoader,
- getSystemClassLoader);
- assert(systemClassLoader != NULL);
-
- /* create an object for the class name string; alloc could fail */
- strClassName = env->NewStringUTF(className);
- if (env->ExceptionCheck()) {
- LOGE("ERROR: unable to convert '%s' to string", className);
- return NULL;
- }
- LOGV("system class loader is %p, loading %p (%s)",
- systemClassLoader, strClassName, className);
-
- /* try to find the named class */
- cls = (jclass) env->CallObjectMethod(systemClassLoader, loadClass,
- strClassName);
- if (env->ExceptionCheck()) {
- LOGE("ERROR: unable to load class '%s' from %p",
- className, systemClassLoader);
- return NULL;
- }
-
- return cls;
-}
-
-/*
* The VM calls this through the "exit" hook.
*/
static void runtime_exit(int code)
@@ -457,7 +357,7 @@ static bool runtime_isSensitiveThread() {
int AndroidRuntime::addVmArguments(int argc, const char* const argv[])
{
int i;
-
+
for (i = 0; i<argc; i++) {
if (argv[i][0] != '-') {
return i;
@@ -890,6 +790,17 @@ bail:
return result;
}
+char* AndroidRuntime::toSlashClassName(const char* className)
+{
+ char* result = strdup(className);
+ for (char* cp = result; *cp != '\0'; cp++) {
+ if (*cp == '.') {
+ *cp = '/';
+ }
+ }
+ return result;
+}
+
/*
* Start the Android runtime. This involves starting the virtual machine
* and calling the "static void main(String[] args)" method in the class
@@ -900,20 +811,16 @@ void AndroidRuntime::start(const char* className, const bool startSystemServer)
LOGD("\n>>>>>> AndroidRuntime START %s <<<<<<\n",
className != NULL ? className : "(unknown)");
- char* slashClassName = NULL;
- char* cp;
- JNIEnv* env;
-
blockSigpipe();
- /*
- * '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.
*/
if (startSystemServer) {
/* track our progress through the boot sequence */
const int LOG_BOOT_PROGRESS_START = 3000;
- LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,
+ LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,
ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
}
@@ -922,7 +829,7 @@ void AndroidRuntime::start(const char* className, const bool startSystemServer)
rootDir = "/system";
if (!hasDir("/system")) {
LOG_FATAL("No root directory specified, and /android does not exist.");
- goto bail;
+ return;
}
setenv("ANDROID_ROOT", rootDir, 1);
}
@@ -931,15 +838,18 @@ void AndroidRuntime::start(const char* className, const bool startSystemServer)
//LOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);
/* start the virtual machine */
- if (startVm(&mJavaVM, &env) != 0)
- goto bail;
+ JNIEnv* env;
+ if (startVm(&mJavaVM, &env) != 0) {
+ return;
+ }
+ onVmCreated(env);
/*
* Register android functions.
*/
if (startReg(env) < 0) {
LOGE("Unable to register all android natives\n");
- goto bail;
+ return;
}
/*
@@ -959,7 +869,7 @@ void AndroidRuntime::start(const char* className, const bool startSystemServer)
classNameStr = env->NewStringUTF(className);
assert(classNameStr != NULL);
env->SetObjectArrayElement(strArray, 0, classNameStr);
- startSystemServerStr = env->NewStringUTF(startSystemServer ?
+ startSystemServerStr = env->NewStringUTF(startSystemServer ?
"true" : "false");
env->SetObjectArrayElement(strArray, 1, startSystemServerStr);
@@ -967,20 +877,13 @@ void AndroidRuntime::start(const char* className, const bool startSystemServer)
* Start VM. This thread becomes the main thread of the VM, and will
* not return until the VM exits.
*/
- jclass startClass;
- jmethodID startMeth;
-
- slashClassName = strdup(className);
- for (cp = slashClassName; *cp != '\0'; cp++)
- if (*cp == '.')
- *cp = '/';
-
- startClass = env->FindClass(slashClassName);
+ char* slashClassName = toSlashClassName(className);
+ jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
LOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
- startMeth = env->GetStaticMethodID(startClass, "main",
+ jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
LOGE("JavaVM unable to find main() in '%s'\n", className);
@@ -994,15 +897,13 @@ void AndroidRuntime::start(const char* className, const bool startSystemServer)
#endif
}
}
+ free(slashClassName);
LOGD("Shutting down VM\n");
if (mJavaVM->DetachCurrentThread() != JNI_OK)
LOGW("Warning: unable to detach main thread\n");
if (mJavaVM->DestroyJavaVM() != 0)
LOGW("Warning: VM did not shut down cleanly\n");
-
-bail:
- free(slashClassName);
}
void AndroidRuntime::start()
@@ -1017,6 +918,11 @@ void AndroidRuntime::onExit(int code)
exit(code);
}
+void AndroidRuntime::onVmCreated(JNIEnv* env)
+{
+ // If AndroidRuntime had anything to do here, we'd have done it in 'start'.
+}
+
/*
* Get the JNIEnv pointer for this thread.
*
@@ -1111,7 +1017,7 @@ static int javaDetachThread(void)
* into the VM before it really starts executing.
*/
/*static*/ int AndroidRuntime::javaCreateThreadEtc(
- android_thread_func_t entryFunction,
+ android_thread_func_t entryFunction,
void* userData,
const char* threadName,
int32_t threadPriority,
@@ -1299,7 +1205,7 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_backup_BackupDataOutput),
REG_JNI(register_android_backup_FileBackupHelperBase),
REG_JNI(register_android_backup_BackupHelperDispatcher),
-
+
REG_JNI(register_android_app_ActivityThread),
REG_JNI(register_android_app_NativeActivity),
REG_JNI(register_android_view_InputChannel),
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 34f0fdc..e5c2848 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -103,17 +103,6 @@ static void signalExceptionForGroupError(JNIEnv* env, jobject obj, int err)
}
}
-
-static void fakeProcessEntry(void* arg)
-{
- String8* cls = (String8*)arg;
-
- AndroidRuntime* jr = AndroidRuntime::getRuntime();
- jr->callMain(cls->string(), 0, NULL);
-
- delete cls;
-}
-
jint android_os_Process_myPid(JNIEnv* env, jobject clazz)
{
return getpid();
diff --git a/include/android_runtime/AndroidRuntime.h b/include/android_runtime/AndroidRuntime.h
index de2d50b..b02a057 100644
--- a/include/android_runtime/AndroidRuntime.h
+++ b/include/android_runtime/AndroidRuntime.h
@@ -46,14 +46,10 @@ public:
const char* className, const JNINativeMethod* gMethods, int numMethods);
/**
- * Call a static Java function that takes no arguments and returns void.
- */
- status_t callStatic(const char* className, const char* methodName);
-
- /**
* Call a class's static main method with the given arguments,
*/
- status_t callMain(const char* className, int argc, const char* const argv[]);
+ status_t callMain(const char* className, jclass clazz, int argc,
+ const char* const argv[]);
/**
* Find a class, with the input either of the form
@@ -69,6 +65,13 @@ public:
static AndroidRuntime* getRuntime();
/**
+ * This gets called after the VM has been created, but before we
+ * run any code. Override it to make any FindClass calls that need
+ * to use CLASSPATH.
+ */
+ virtual void onVmCreated(JNIEnv* env);
+
+ /**
* This gets called after the JavaVM has initialized. Override it
* with the system's native entry point.
*/
@@ -98,6 +101,9 @@ public:
/** return a pointer to the JNIEnv pointer for this thread */
static JNIEnv* getJNIEnv();
+ /** return a new string corresponding to 'className' with all '.'s replaced by '/'s. */
+ static char* toSlashClassName(const char* className);
+
private:
static int startReg(JNIEnv* env);
void parseExtraOpts(char* extraOptsBuf);