Loading cmds/app_process/app_main.cpp +41 −20 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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(); Loading @@ -68,7 +87,8 @@ public: proc->startThreadPool(); } app_init(mClassName, mArgC, mArgV); AndroidRuntime* ar = AndroidRuntime::getRuntime(); ar->callMain(mClassName, mClass, mArgC, mArgV); if (ProcessState::self()->supportsProcesses()) { IPCThreadState::self()->stopProcess(); Loading Loading @@ -99,6 +119,7 @@ public: const char* mParentDir; const char* mClassName; jclass mClass; int mArgC; const char* const* mArgV; }; Loading cmds/runtime/main_runtime.cpp +19 −20 Original line number Diff line number Diff line Loading @@ -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)()); Loading cmds/system_server/library/system_init.cpp +19 −9 Original line number Diff line number Diff line Loading @@ -97,11 +97,22 @@ 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 Loading @@ -114,4 +125,3 @@ extern "C" status_t system_init() } return NO_ERROR; } core/jni/AndroidRuntime.cpp +54 −148 Original line number Diff line number Diff line /* //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" Loading Loading @@ -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; } Loading Loading @@ -351,70 +315,6 @@ status_t AndroidRuntime::callMain( return NO_ERROR; } /* * 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. */ Loading Loading @@ -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 Loading @@ -900,10 +811,6 @@ 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(); /* Loading @@ -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); } Loading @@ -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; } /* Loading Loading @@ -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); Loading @@ -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() Loading @@ -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. * Loading core/jni/android_util_Process.cpp +0 −11 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading
cmds/app_process/app_main.cpp +41 −20 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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(); Loading @@ -68,7 +87,8 @@ public: proc->startThreadPool(); } app_init(mClassName, mArgC, mArgV); AndroidRuntime* ar = AndroidRuntime::getRuntime(); ar->callMain(mClassName, mClass, mArgC, mArgV); if (ProcessState::self()->supportsProcesses()) { IPCThreadState::self()->stopProcess(); Loading Loading @@ -99,6 +119,7 @@ public: const char* mParentDir; const char* mClassName; jclass mClass; int mArgC; const char* const* mArgV; }; Loading
cmds/runtime/main_runtime.cpp +19 −20 Original line number Diff line number Diff line Loading @@ -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)()); Loading
cmds/system_server/library/system_init.cpp +19 −9 Original line number Diff line number Diff line Loading @@ -97,11 +97,22 @@ 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 Loading @@ -114,4 +125,3 @@ extern "C" status_t system_init() } return NO_ERROR; }
core/jni/AndroidRuntime.cpp +54 −148 Original line number Diff line number Diff line /* //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" Loading Loading @@ -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; } Loading Loading @@ -351,70 +315,6 @@ status_t AndroidRuntime::callMain( return NO_ERROR; } /* * 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. */ Loading Loading @@ -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 Loading @@ -900,10 +811,6 @@ 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(); /* Loading @@ -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); } Loading @@ -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; } /* Loading Loading @@ -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); Loading @@ -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() Loading @@ -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. * Loading
core/jni/android_util_Process.cpp +0 −11 Original line number Diff line number Diff line Loading @@ -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(); Loading