Zygote的启动流程
Init进程启动后,会加载并执行init.rc文件。该.rc文件中,就包含启动Zygote进程的Action。详见“RC文件剖析”章节。
根据Zygote对应的RC文件,可知Zygote进程是由/system/bin/app_process程序来创建的。
app_process大抵处理流程如下,详见“app_process剖析”章节。
- 创建AppRuntime
- 整理传参,并将相应参数传给Runtime或Zygote进程。
- 利用Runtime调用start方法,传入“com.android.internal.os.ZygoteInit”类和zygote传参,启动zygote。
class AppRuntime 继承自 public AndroidRuntime。调用start方法后,将执行以下步调。详见"AndroidRuntime剖析"章节。
- 搜集JVM参数,启动VM
- 注册JNI方法。
- 利用java的反射,调用com.android.internal.os.ZygoteInit类中的main方法,创建zygote进程。
Zygote代码分析
RC文件剖析
Init.rc中的Zygote内容
init.rc中涉及Zygote的部分有五处。从代码中可以看出,在初始化晚期阶段late-init,会触发Zygote-start行为,而该行为会创建zygote,以及zygote_secondary两个进程。
- import /system/etc/init/hw/init.${ro.zygote}.rc
- import /system/etc/init/hw/init.boringssl.${ro.zygote}.rc
- ...
- on late-init
- trigger zygote-start
- ...
- on zygote-start
- wait_for_prop odsign.verification.done 1
- # A/B update verifier that marks a successful boot.
- exec_start update_verifier
- start statsd
- start netd
- start zygote
- start zygote_secondary
- ...
- on userspace-reboot-resume
- trigger userspace-reboot-fs-remount
- trigger post-fs-data
- trigger zygote-start
- trigger early-boot
- trigger boot
复制代码 关于怎样启动这两个进程,可以参照init.${ro.zygote}.rc。${ro.zygote}的值,可以通过shell指令“getprop ro.zygote”获取。以下图为例,zygote64_32代表64模式为主,32位模式为辅。
init.zygote64_32.rc
引用了init.zygote64.rc
声明了一个名字为“zygote_secondary”的service。该service将有/system/bin/app_process进程来启动。其中以“-”开头的是JVM参数,-Xzygote /system/bin。以“--”开头的是进程参数,--zygote --socket-name=zygote_secondary --enable-lazy-preload。
创建了两个socket,名字为zygote_secondary和usap_pool_secondary。
- import /system/etc/init/hw/init.zygote64.rc
- service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary --enable-lazy-preload
- class main
- priority -20
- user root
- group root readproc reserved_disk
- socket zygote_secondary stream 660 root system
- socket usap_pool_secondary stream 660 root system
- onrestart restart zygote
- task_profiles ProcessCapacityHigh MaxPerformance
复制代码 init.zygote64.rc
声明了一个名字为“zygote”的service。该service将有/system/bin/app_process进程来启动。其中以“-”开头的是JVM参数,-Xzygote /system/bin。以“--”开头的是进程参数,--zygote --start-system-server --socket-name=zygote。
创建了两个socket,名字为zygote和usap_pool_primary。
- service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
- class main
- priority -20
- user root
- group root readproc reserved_disk
- socket zygote stream 660 root system
- socket usap_pool_primary stream 660 root system
- onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
- onrestart write /sys/power/state on
- # NOTE: If the wakelock name here is changed, then also
- # update it in SystemSuspend.cpp
- onrestart write /sys/power/wake_lock zygote_kwl
- onrestart restart audioserver
- onrestart restart cameraserver
- onrestart restart media
- onrestart restart --only-if-running media.tuner
- onrestart restart netd
- onrestart restart wificond
- task_profiles ProcessCapacityHigh MaxPerformance
- critical window=${zygote.critical_window.minute:-off} target=zygote-fatal
复制代码 init.boringssl.zygote64_32.rc
包含的都是在某些条件下触发的自测进程。相识即可。
- on init && property:ro.product.cpu.abilist32=*
- exec_start boringssl_self_test32
- on init && property:ro.product.cpu.abilist64=*
- exec_start boringssl_self_test64
- on property:apexd.status=ready && property:ro.product.cpu.abilist32=*
- exec_start boringssl_self_test_apex32
- on property:apexd.status=ready && property:ro.product.cpu.abilist64=*
- exec_start boringssl_self_test_apex64
复制代码 app_process剖析
frameworks/base/cmds/app_process/app_main.cpp
- int main(int argc, char* const argv[])
- {
- if (!LOG_NDEBUG) {
- String8 argv_String;
- for (int i = 0; i < argc; ++i) {
- argv_String.append(""");
- argv_String.append(argv[i]);
- argv_String.append("" ");
- }
- ALOGV("app_process main with argv: %s", argv_String.c_str());
- }
- //步骤1:创建Runtime.--------------------------------------------
- AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
- // Process command line arguments
- // ignore argv[0]
- argc--;
- argv++;
- // 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.
- //
- // Note that we must copy argument string values since we will rewrite the
- // entire argument block when we apply the nice name to argv0.
- //
- // As an exception to the above rule, anything in "spaced commands"
- // goes to the vm even though it has a space in it.
- const char* spaced_commands[] = { "-cp", "-classpath" };
- // Allow "spaced commands" to be succeeded by exactly 1 argument (regardless of -s).
- bool known_command = false;
- //步骤2:解析传参,将'-'开头的参数传给Runtime.--------------------------------------------
- int i;
- for (i = 0; i < argc; i++) {
- if (known_command == true) {
- runtime.addOption(strdup(argv[i]));
- // The static analyzer gets upset that we don't ever free the above
- // string. Since the allocation is from main, leaking it doesn't seem
- // problematic. NOLINTNEXTLINE
- ALOGV("app_process main add known option '%s'", argv[i]);
- known_command = false;
- continue;
- }
- for (int j = 0;
- j < static_cast<int>(sizeof(spaced_commands) / sizeof(spaced_commands[0]));
- ++j) {
- if (strcmp(argv[i], spaced_commands[j]) == 0) {
- known_command = true;
- ALOGV("app_process main found known command '%s'", argv[i]);
- }
- }
- if (argv[i][0] != '-') {
- break;
- }
- if (argv[i][1] == '-' && argv[i][2] == 0) {
- ++i; // Skip --.
- break;
- }
- runtime.addOption(strdup(argv[i]));
- // The static analyzer gets upset that we don't ever free the above
- // string. Since the allocation is from main, leaking it doesn't seem
- // problematic. NOLINTNEXTLINE
- ALOGV("app_process main add option '%s'", argv[i]);
- }
- // Parse runtime arguments. Stop at first unrecognized option.
- bool zygote = false;
- bool startSystemServer = false;
- bool application = false;
- String8 niceName;
- String8 className;
- //步骤3:整理zygote进程的传参.--------------------------------------------
- ++i; // Skip unused "parent dir" argument.
- while (i < argc) {
- const char* arg = argv[i++];
- if (strcmp(arg, "--zygote") == 0) {
- zygote = true;
- niceName = ZYGOTE_NICE_NAME;
- } else if (strcmp(arg, "--start-system-server") == 0) {
- startSystemServer = true;
- } else if (strcmp(arg, "--application") == 0) {
- application = true;
- } else if (strncmp(arg, "--nice-name=", 12) == 0) {
- niceName = (arg + 12);
- } else if (strncmp(arg, "--", 2) != 0) {
- className = arg;
- break;
- } else {
- --i;
- break;
- }
- }
- //步骤4:根据整理的zygote传参,判断是否是zygote进程,并根据判断结果,补充“--abi-list”和“start-system-server”传参.--------------------------------------------
- Vector<String8> args;
- if (!className.empty()) {
- // 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);
- if (!LOG_NDEBUG) {
- String8 restOfArgs;
- char* const* argv_new = argv + i;
- int argc_new = argc - i;
- for (int k = 0; k < argc_new; ++k) {
- restOfArgs.append(""");
- restOfArgs.append(argv_new[k]);
- restOfArgs.append("" ");
- }
- ALOGV("Class name = %s, args = %s", className.c_str(), restOfArgs.c_str());
- }
- } else {
- // We're in zygote mode.
- maybeCreateDalvikCache();
- if (startSystemServer) {
- args.add(String8("start-system-server"));
- }
- char prop[PROP_VALUE_MAX];
- if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {
- LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",
- ABI_LIST_PROPERTY);
- return 11;
- }
- String8 abiFlag("--abi-list=");
- abiFlag.append(prop);
- args.add(abiFlag);
- // In zygote mode, pass all remaining arguments to the zygote
- // main() method.
- for (; i < argc; ++i) {
- args.add(String8(argv[i]));
- }
- }
- if (!niceName.empty()) {
- runtime.setArgv0(niceName.c_str(), true /* setProcName */);
- }
- //步骤5:使用runtime,调用“com.android.internal.os.ZygoteInit”类,并传入传参,启动zygote.--------------------------------------------
- if (zygote) {
- runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
- } else if (!className.empty()) {
- runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
- } else {
- fprintf(stderr, "Error: no class name or --zygote supplied.\n");
- app_usage();
- LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
- }
- }
复制代码 AndroidRuntime剖析
frameworks/base/core/jni/AndroidRuntime.cpp
Runtime的start方法
- void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
- {
- ALOGD(">>>>>> START %s uid %d <<<<<<\n",
- className != NULL ? className : "(unknown)", getuid());
- static const String8 startSystemServer("start-system-server");
- // Whether this is the primary zygote, meaning the zygote which will fork system server.
- bool primary_zygote = false;
- //步骤1:必要的参数及环境变量检查。-----------------------------------
- /*
- * 'startSystemServer == true' means runtime is obsolete and not run from
- * init.rc anymore, so we print out the boot start event here.
- */
- for (size_t i = 0; i < options.size(); ++i) {
- if (options[i] == startSystemServer) {
- primary_zygote = true;
- /* track our progress through the boot sequence */
- const int LOG_BOOT_PROGRESS_START = 3000;
- LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
- }
- }
- const char* rootDir = getenv("ANDROID_ROOT");
- if (rootDir == NULL) {
- rootDir = "/system";
- if (!hasDir("/system")) {
- LOG_FATAL("No root directory specified, and /system does not exist.");
- return;
- }
- setenv("ANDROID_ROOT", rootDir, 1);
- }
- const char* artRootDir = getenv("ANDROID_ART_ROOT");
- if (artRootDir == NULL) {
- LOG_FATAL("No ART directory specified with ANDROID_ART_ROOT environment variable.");
- return;
- }
- const char* i18nRootDir = getenv("ANDROID_I18N_ROOT");
- if (i18nRootDir == NULL) {
- LOG_FATAL("No runtime directory specified with ANDROID_I18N_ROOT environment variable.");
- return;
- }
- const char* tzdataRootDir = getenv("ANDROID_TZDATA_ROOT");
- if (tzdataRootDir == NULL) {
- LOG_FATAL("No tz data directory specified with ANDROID_TZDATA_ROOT environment variable.");
- return;
- }
- //const char* kernelHack = getenv("LD_ASSUME_KERNEL");
- //ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);
- //步骤2:启动VM。-----------------------------------
- /* start the virtual machine */
- JniInvocation jni_invocation;
- jni_invocation.Init(NULL);
- JNIEnv* env;
- if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
- return;
- }
- onVmCreated(env);
- /*
- * Register android functions.
- */
- //步骤3:注册JNI方法。-----------------------------------
- if (startReg(env) < 0) {
- ALOGE("Unable to register all android natives\n");
- return;
- }
- /*
- * We want to call main() with a String array with arguments in it.
- * At present we have two arguments, the class name and an option string.
- * Create an array to hold them.
- */
- jclass stringClass;
- jobjectArray strArray;
- jstring classNameStr;
- stringClass = env->FindClass("java/lang/String");
- assert(stringClass != NULL);
- strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
- assert(strArray != NULL);
- classNameStr = env->NewStringUTF(className);
- assert(classNameStr != NULL);
- env->SetObjectArrayElement(strArray, 0, classNameStr);
- for (size_t i = 0; i < options.size(); ++i) {
- jstring optionsStr = env->NewStringUTF(options.itemAt(i).c_str());
- assert(optionsStr != NULL);
- env->SetObjectArrayElement(strArray, i + 1, optionsStr);
- }
- //步骤4:利用java的反射,调用com.android.internal.os.ZygoteInit类中的main方法,创建zygote进程。-----------------------------------
- /*
- * Start VM. This thread becomes the main thread of the VM, and will
- * not return until the VM exits.
- */
- char* slashClassName = toSlashClassName(className != NULL ? className : "");
- jclass startClass = env->FindClass(slashClassName);
- if (startClass == NULL) {
- ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
- /* keep going */
- } else {
- jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
- "([Ljava/lang/String;)V");
- if (startMeth == NULL) {
- ALOGE("JavaVM unable to find main() in '%s'\n", className);
- /* keep going */
- } else {
- env->CallStaticVoidMethod(startClass, startMeth, strArray);
- #if 0
- if (env->ExceptionCheck())
- threadExitUncaughtException(env);
- #endif
- }
- }
- free(slashClassName);
- ALOGD("Shutting down VM\n");
- if (mJavaVM->DetachCurrentThread() != JNI_OK)
- ALOGW("Warning: unable to detach main thread\n");
- if (mJavaVM->DestroyJavaVM() != 0)
- ALOGW("Warning: VM did not shut down cleanly\n");
- }
复制代码 启动VM
该方法有600+行,都是网络VM参数,并调用JNI_CreateJavaVM启动VM。参数是一个可以做性能优化的点。相识即可。
- int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool primary_zygote)
- {
- JavaVMInitArgs initArgs;
- char propBuf[PROPERTY_VALUE_MAX];
- char jniOptsBuf[sizeof("-Xjniopts:")-1 + PROPERTY_VALUE_MAX];
- char heapstartsizeOptsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX];
- char heapsizeOptsBuf[sizeof("-Xmx")-1 + PROPERTY_VALUE_MAX];
- char heapgrowthlimitOptsBuf[sizeof("-XX:HeapGrowthLimit=")-1 + PROPERTY_VALUE_MAX];
- char heapminfreeOptsBuf[sizeof("-XX:HeapMinFree=")-1 + PROPERTY_VALUE_MAX];
- char heapmaxfreeOptsBuf[sizeof("-XX:HeapMaxFree=")-1 + PROPERTY_VALUE_MAX];
- char usejitOptsBuf[sizeof("-Xusejit:")-1 + PROPERTY_VALUE_MAX];
- char jitpthreadpriorityOptsBuf[sizeof("-Xjitpthreadpriority:")-1 + PROPERTY_VALUE_MAX];
- char jitmaxsizeOptsBuf[sizeof("-Xjitmaxsize:")-1 + PROPERTY_VALUE_MAX];
- char jitinitialsizeOptsBuf[sizeof("-Xjitinitialsize:")-1 + PROPERTY_VALUE_MAX];
- char jitthresholdOptsBuf[sizeof("-Xjitthreshold:")-1 + PROPERTY_VALUE_MAX];
- char jitprithreadweightOptBuf[sizeof("-Xjitprithreadweight:")-1 + PROPERTY_VALUE_MAX];
- char jittransitionweightOptBuf[sizeof("-Xjittransitionweight:")-1 + PROPERTY_VALUE_MAX];
- char hotstartupsamplesOptsBuf[sizeof("-Xps-hot-startup-method-samples:")-1 + PROPERTY_VALUE_MAX];
- char saveResolvedClassesDelayMsOptsBuf[
- sizeof("-Xps-save-resolved-classes-delay-ms:")-1 + PROPERTY_VALUE_MAX];
- char profileMinSavePeriodOptsBuf[sizeof("-Xps-min-save-period-ms:")-1 + PROPERTY_VALUE_MAX];
- char profileMinFirstSaveOptsBuf[sizeof("-Xps-min-first-save-ms:") - 1 + PROPERTY_VALUE_MAX];
- char profileInlineCacheThresholdOptsBuf[
- sizeof("-Xps-inline-cache-threshold:") - 1 + PROPERTY_VALUE_MAX];
- char madviseWillNeedFileSizeVdex[
- sizeof("-XMadviseWillNeedVdexFileSize:")-1 + PROPERTY_VALUE_MAX];
- char madviseWillNeedFileSizeOdex[
- sizeof("-XMadviseWillNeedOdexFileSize:")-1 + PROPERTY_VALUE_MAX];
- char madviseWillNeedFileSizeArt[
- sizeof("-XMadviseWillNeedArtFileSize:")-1 + PROPERTY_VALUE_MAX];
- char gctypeOptsBuf[sizeof("-Xgc:")-1 + PROPERTY_VALUE_MAX];
- char backgroundgcOptsBuf[sizeof("-XX:BackgroundGC=")-1 + PROPERTY_VALUE_MAX];
- char heaptargetutilizationOptsBuf[sizeof("-XX:HeapTargetUtilization=")-1 + PROPERTY_VALUE_MAX];
- char foregroundHeapGrowthMultiplierOptsBuf[
- sizeof("-XX:ForegroundHeapGrowthMultiplier=")-1 + PROPERTY_VALUE_MAX];
- char finalizerTimeoutMsOptsBuf[sizeof("-XX:FinalizerTimeoutMs=")-1 + PROPERTY_VALUE_MAX];
- char threadSuspendTimeoutOptsBuf[sizeof("-XX:ThreadSuspendTimeout=")-1 + PROPERTY_VALUE_MAX];
- char cachePruneBuf[sizeof("-Xzygote-max-boot-retry=")-1 + PROPERTY_VALUE_MAX];
- char dex2oatXmsImageFlagsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX];
- char dex2oatXmxImageFlagsBuf[sizeof("-Xmx")-1 + PROPERTY_VALUE_MAX];
- char dex2oatCompilerFilterBuf[sizeof("--compiler-filter=")-1 + PROPERTY_VALUE_MAX];
- char dex2oatImageCompilerFilterBuf[sizeof("--compiler-filter=")-1 + PROPERTY_VALUE_MAX];
- char dex2oatThreadsBuf[sizeof("-j")-1 + PROPERTY_VALUE_MAX];
- char dex2oatThreadsImageBuf[sizeof("-j")-1 + PROPERTY_VALUE_MAX];
- char dex2oatCpuSetBuf[sizeof("--cpu-set=")-1 + PROPERTY_VALUE_MAX];
- char dex2oatCpuSetImageBuf[sizeof("--cpu-set=")-1 + PROPERTY_VALUE_MAX];
- char dex2oat_isa_variant_key[PROPERTY_KEY_MAX];
- char dex2oat_isa_variant[sizeof("--instruction-set-variant=") -1 + PROPERTY_VALUE_MAX];
- char dex2oat_isa_features_key[PROPERTY_KEY_MAX];
- char dex2oat_isa_features[sizeof("--instruction-set-features=") -1 + PROPERTY_VALUE_MAX];
- char dex2oatFlagsBuf[PROPERTY_VALUE_MAX];
- char dex2oatImageFlagsBuf[PROPERTY_VALUE_MAX];
- char extraOptsBuf[PROPERTY_VALUE_MAX];
- char perfettoHprofOptBuf[sizeof("-XX:PerfettoHprof=") + PROPERTY_VALUE_MAX];
- char perfettoJavaHeapStackOptBuf[
- sizeof("-XX:PerfettoJavaHeapStackProf=") + PROPERTY_VALUE_MAX];
- enum {
- kEMDefault,
- kEMIntPortable,
- kEMIntFast,
- kEMJitCompiler,
- } executionMode = kEMDefault;
- char localeOption[sizeof("-Duser.locale=") + PROPERTY_VALUE_MAX];
- char lockProfThresholdBuf[sizeof("-Xlockprofthreshold:")-1 + PROPERTY_VALUE_MAX];
- char nativeBridgeLibrary[sizeof("-XX:NativeBridge=") + PROPERTY_VALUE_MAX];
- char cpuAbiListBuf[sizeof("--cpu-abilist=") + PROPERTY_VALUE_MAX];
- char corePlatformApiPolicyBuf[sizeof("-Xcore-platform-api-policy:") + PROPERTY_VALUE_MAX];
- char methodTraceFileBuf[sizeof("-Xmethod-trace-file:") + PROPERTY_VALUE_MAX];
- char methodTraceFileSizeBuf[sizeof("-Xmethod-trace-file-size:") + PROPERTY_VALUE_MAX];
- std::string fingerprintBuf;
- char javaZygoteForkLoopBuf[sizeof("-XX:ForceJavaZygoteForkLoop=") + PROPERTY_VALUE_MAX];
- char jdwpProviderBuf[sizeof("-XjdwpProvider:") - 1 + PROPERTY_VALUE_MAX];
- char opaqueJniIds[sizeof("-Xopaque-jni-ids:") - 1 + PROPERTY_VALUE_MAX];
- char bootImageBuf[sizeof("-Ximage:") - 1 + PROPERTY_VALUE_MAX];
- // Read if we are using the profile configuration, do this at the start since the last ART args
- // take precedence.
- std::string profile_boot_class_path_flag =
- server_configurable_flags::GetServerConfigurableFlag(RUNTIME_NATIVE_BOOT_NAMESPACE,
- PROFILE_BOOT_CLASS_PATH,
- /*default_value=*/"");
- bool profile_boot_class_path;
- switch (ParseBool(profile_boot_class_path_flag)) {
- case ParseBoolResult::kError:
- // Default to the system property.
- profile_boot_class_path =
- GetBoolProperty("dalvik.vm.profilebootclasspath", /*default_value=*/false);
- break;
- case ParseBoolResult::kTrue:
- profile_boot_class_path = true;
- break;
- case ParseBoolResult::kFalse:
- profile_boot_class_path = false;
- break;
- }
- if (profile_boot_class_path) {
- addOption("-Xcompiler-option");
- addOption("--count-hotness-in-compiled-code");
- addOption("-Xps-profile-boot-class-path");
- addOption("-Xps-profile-aot-code");
- addOption("-Xjitsaveprofilinginfo");
- }
- std::string use_jitzygote_image_flag =
- server_configurable_flags::GetServerConfigurableFlag(RUNTIME_NATIVE_BOOT_NAMESPACE,
- ENABLE_JITZYGOTE_IMAGE,
- /*default_value=*/"");
- // Use the APEX boot image for boot class path profiling to get JIT samples on BCP methods.
- // Also use the APEX boot image if it's explicitly enabled via configuration flag.
- const bool use_apex_image = profile_boot_class_path || (use_jitzygote_image_flag == "true");
- if (use_apex_image) {
- ALOGI("Using JIT Zygote image: '%s'\n", kJitZygoteImageOption);
- addOption(kJitZygoteImageOption);
- } else if (parseRuntimeOption("dalvik.vm.boot-image", bootImageBuf, "-Ximage:")) {
- ALOGI("Using dalvik.vm.boot-image: '%s'\n", bootImageBuf);
- } else {
- ALOGI("Using default boot image");
- }
- std::string disable_lock_profiling =
- server_configurable_flags::GetServerConfigurableFlag(RUNTIME_NATIVE_BOOT_NAMESPACE,
- DISABLE_LOCK_PROFILING,
- /*default_value=*/ "");
- if (disable_lock_profiling == "true") {
- addOption(kLockProfThresholdRuntimeOption);
- ALOGI("Disabling lock profiling: '%s'\n", kLockProfThresholdRuntimeOption);
- } else {
- ALOGI("Leaving lock profiling enabled");
- }
- const bool checkJni = GetBoolProperty("dalvik.vm.checkjni", false);
- if (checkJni) {
- ALOGD("CheckJNI is ON");
- /* extended JNI checking */
- addOption("-Xcheck:jni");
- /* with -Xcheck:jni, this provides a JNI function call trace */
- //addOption("-verbose:jni");
- }
- const bool odsignVerificationSuccess = GetBoolProperty("odsign.verification.success", false);
- if (!odsignVerificationSuccess) {
- addOption("-Xdeny-art-apex-data-files");
- }
- property_get("dalvik.vm.execution-mode", propBuf, "");
- if (strcmp(propBuf, "int:portable") == 0) {
- executionMode = kEMIntPortable;
- } else if (strcmp(propBuf, "int:fast") == 0) {
- executionMode = kEMIntFast;
- } else if (strcmp(propBuf, "int:jit") == 0) {
- executionMode = kEMJitCompiler;
- }
- strcpy(jniOptsBuf, "-Xjniopts:");
- if (parseRuntimeOption("dalvik.vm.jniopts", jniOptsBuf, "-Xjniopts:")) {
- ALOGI("JNI options: '%s'\n", jniOptsBuf);
- }
- /* route exit() to our handler */
- addOption("exit", (void*) runtime_exit);
- /* route fprintf() to our handler */
- addOption("vfprintf", (void*) runtime_vfprintf);
- /* register the framework-specific "is sensitive thread" hook */
- addOption("sensitiveThread", (void*) runtime_isSensitiveThread);
- /* enable verbose; standard options are { jni, gc, class } */
- //addOption("-verbose:jni");
- addOption("-verbose:gc");
- //addOption("-verbose:class");
- // On Android, we always want to allow loading the PerfettoHprof plugin.
- // Even with this option set, we will still only actually load the plugin
- // if we are on a userdebug build or the app is debuggable or profileable.
- // This is enforced in art/runtime/runtime.cc.
- //
- // We want to be able to disable this, because this does not work on host,
- // and we do not want to enable it in tests.
- parseRuntimeOption("dalvik.vm.perfetto_hprof", perfettoHprofOptBuf, "-XX:PerfettoHprof=",
- "true");
- // Enable PerfettoJavaHeapStackProf in the zygote
- parseRuntimeOption("dalvik.vm.perfetto_javaheap", perfettoJavaHeapStackOptBuf,
- "-XX:PerfettoJavaHeapStackProf=", "true");
- if (primary_zygote) {
- addOption("-Xprimaryzygote");
- }
- /*
- * The default starting and maximum size of the heap. Larger
- * values should be specified in a product property override.
- */
- parseRuntimeOption("dalvik.vm.heapstartsize", heapstartsizeOptsBuf, "-Xms", "4m");
- parseRuntimeOption("dalvik.vm.heapsize", heapsizeOptsBuf, "-Xmx", "16m");
- parseRuntimeOption("dalvik.vm.heapgrowthlimit", heapgrowthlimitOptsBuf, "-XX:HeapGrowthLimit=");
- parseRuntimeOption("dalvik.vm.heapminfree", heapminfreeOptsBuf, "-XX:HeapMinFree=");
- parseRuntimeOption("dalvik.vm.heapmaxfree", heapmaxfreeOptsBuf, "-XX:HeapMaxFree=");
- parseRuntimeOption("dalvik.vm.heaptargetutilization",
- heaptargetutilizationOptsBuf,
- "-XX:HeapTargetUtilization=");
- /* Foreground heap growth multiplier option */
- parseRuntimeOption("dalvik.vm.foreground-heap-growth-multiplier",
- foregroundHeapGrowthMultiplierOptsBuf,
- "-XX:ForegroundHeapGrowthMultiplier=");
- /*
- * Finalizer and thread suspend timeouts.
- */
- parseRuntimeOption("dalvik.vm.finalizer-timeout-ms",
- finalizerTimeoutMsOptsBuf,
- "-XX:FinalizerTimeoutMs=");
- parseRuntimeOption("dalvik.vm.thread-suspend-timeout-ms",
- threadSuspendTimeoutOptsBuf,
- "-XX:ThreadSuspendTimeout=");
- /*
- * JIT related options.
- */
- parseRuntimeOption("dalvik.vm.usejit", usejitOptsBuf, "-Xusejit:");
- parseRuntimeOption("dalvik.vm.jitmaxsize", jitmaxsizeOptsBuf, "-Xjitmaxsize:");
- parseRuntimeOption("dalvik.vm.jitinitialsize", jitinitialsizeOptsBuf, "-Xjitinitialsize:");
- parseRuntimeOption("dalvik.vm.jitthreshold", jitthresholdOptsBuf, "-Xjitthreshold:");
- parseRuntimeOption("dalvik.vm.jitpthreadpriority",
- jitpthreadpriorityOptsBuf,
- "-Xjitpthreadpriority:");
- addOption("-Xjitsaveprofilinginfo");
- parseRuntimeOption("dalvik.vm.jitprithreadweight",
- jitprithreadweightOptBuf,
- "-Xjitprithreadweight:");
- parseRuntimeOption("dalvik.vm.jittransitionweight", jittransitionweightOptBuf,
- "-Xjittransitionweight:");
- /*
- * Use default platform configuration as limits for madvising,
- * when no properties are specified.
- */
- parseRuntimeOption("dalvik.vm.madvise.vdexfile.size",
- madviseWillNeedFileSizeVdex,
- "-XMadviseWillNeedVdexFileSize:");
- parseRuntimeOption("dalvik.vm.madvise.odexfile.size",
- madviseWillNeedFileSizeOdex,
- "-XMadviseWillNeedOdexFileSize:");
- parseRuntimeOption("dalvik.vm.madvise.artfile.size",
- madviseWillNeedFileSizeArt,
- "-XMadviseWillNeedArtFileSize:");
- /*
- * Profile related options.
- */
- parseRuntimeOption("dalvik.vm.hot-startup-method-samples", hotstartupsamplesOptsBuf,
- "-Xps-hot-startup-method-samples:");
- parseRuntimeOption("dalvik.vm.ps-resolved-classes-delay-ms", saveResolvedClassesDelayMsOptsBuf,
- "-Xps-save-resolved-classes-delay-ms:");
- parseRuntimeOption("dalvik.vm.ps-min-save-period-ms", profileMinSavePeriodOptsBuf,
- "-Xps-min-save-period-ms:");
- parseRuntimeOption("dalvik.vm.ps-min-first-save-ms", profileMinFirstSaveOptsBuf,
- "-Xps-min-first-save-ms:");
- parseRuntimeOption("dalvik.vm.ps-inline-cache-threshold", profileInlineCacheThresholdOptsBuf,
- "-Xps-inline-cache-threshold:");
- property_get("ro.config.low_ram", propBuf, "");
- if (strcmp(propBuf, "true") == 0) {
- addOption("-XX:LowMemoryMode");
- }
- /*
- * Garbage-collection related options.
- */
- parseRuntimeOption("dalvik.vm.gctype", gctypeOptsBuf, "-Xgc:");
- // If it set, honor the "enable_generational_cc" device configuration;
- // otherwise, let the runtime use its default behavior.
- std::string enable_generational_cc =
- server_configurable_flags::GetServerConfigurableFlag(RUNTIME_NATIVE_BOOT_NAMESPACE,
- ENABLE_GENERATIONAL_CC,
- /*default_value=*/ "");
- if (enable_generational_cc == "true") {
- addOption(kGenerationalCCRuntimeOption);
- } else if (enable_generational_cc == "false") {
- addOption(kNoGenerationalCCRuntimeOption);
- }
- parseRuntimeOption("dalvik.vm.backgroundgctype", backgroundgcOptsBuf, "-XX:BackgroundGC=");
- /*
- * Enable/disable zygote native fork loop.
- */
- parseRuntimeOption("dalvik.vm.force-java-zygote-fork-loop",
- javaZygoteForkLoopBuf,
- "-XX:ForceJavaZygoteForkLoop=");
- /*
- * Enable debugging only for apps forked from zygote.
- */
- if (zygote) {
- // Set the JDWP provider and required arguments. By default let the runtime choose how JDWP is
- // implemented. When this is not set the runtime defaults to not allowing JDWP.
- addOption("-XjdwpOptions:suspend=n,server=y");
- parseRuntimeOption("dalvik.vm.jdwp-provider",
- jdwpProviderBuf,
- "-XjdwpProvider:",
- "default");
- }
- // Only pass an explicit opaque-jni-ids to apps forked from zygote
- if (zygote) {
- parseRuntimeOption("dalvik.vm.opaque-jni-ids",
- opaqueJniIds,
- "-Xopaque-jni-ids:",
- "swapable");
- }
- parseRuntimeOption("dalvik.vm.lockprof.threshold",
- lockProfThresholdBuf,
- "-Xlockprofthreshold:");
- if (executionMode == kEMIntPortable) {
- addOption("-Xint:portable");
- } else if (executionMode == kEMIntFast) {
- addOption("-Xint:fast");
- } else if (executionMode == kEMJitCompiler) {
- addOption("-Xint:jit");
- }
- // Extra options for JIT.
- parseCompilerOption("dalvik.vm.dex2oat-filter", dex2oatCompilerFilterBuf,
- "--compiler-filter=", "-Xcompiler-option");
- parseCompilerOption("dalvik.vm.dex2oat-threads", dex2oatThreadsBuf, "-j", "-Xcompiler-option");
- parseCompilerOption("dalvik.vm.dex2oat-cpu-set", dex2oatCpuSetBuf, "--cpu-set=",
- "-Xcompiler-option");
- // Copy the variant.
- sprintf(dex2oat_isa_variant_key, "dalvik.vm.isa.%s.variant", ABI_STRING);
- parseCompilerOption(dex2oat_isa_variant_key, dex2oat_isa_variant,
- "--instruction-set-variant=", "-Xcompiler-option");
- // Copy the features.
- sprintf(dex2oat_isa_features_key, "dalvik.vm.isa.%s.features", ABI_STRING);
- parseCompilerOption(dex2oat_isa_features_key, dex2oat_isa_features,
- "--instruction-set-features=", "-Xcompiler-option");
- /*
- * When running with debug.generate-debug-info, add --generate-debug-info to the compiler
- * options so that both JITted code and the boot image, if it is compiled on device, will
- * include native debugging information.
- */
- property_get("debug.generate-debug-info", propBuf, "");
- bool generate_debug_info = (strcmp(propBuf, "true") == 0);
- if (generate_debug_info) {
- addOption("-Xcompiler-option");
- addOption("--generate-debug-info");
- }
- // The mini-debug-info makes it possible to backtrace through compiled code.
- bool generate_mini_debug_info = property_get_bool("dalvik.vm.minidebuginfo", 0);
- if (generate_mini_debug_info) {
- addOption("-Xcompiler-option");
- addOption("--generate-mini-debug-info");
- }
- property_get("dalvik.vm.dex2oat-flags", dex2oatFlagsBuf, "");
- parseExtraOpts(dex2oatFlagsBuf, "-Xcompiler-option");
- /* extra options; parse this late so it overrides others */
- property_get("dalvik.vm.extra-opts", extraOptsBuf, "");
- parseExtraOpts(extraOptsBuf, NULL);
- // Extra options for boot image generation.
- parseCompilerRuntimeOption("dalvik.vm.image-dex2oat-Xms", dex2oatXmsImageFlagsBuf,
- "-Xms", "-Ximage-compiler-option");
- parseCompilerRuntimeOption("dalvik.vm.image-dex2oat-Xmx", dex2oatXmxImageFlagsBuf,
- "-Xmx", "-Ximage-compiler-option");
- parseCompilerOption("dalvik.vm.image-dex2oat-filter", dex2oatImageCompilerFilterBuf,
- "--compiler-filter=", "-Ximage-compiler-option");
- // If there is a dirty-image-objects file, push it.
- if (hasFile("/system/etc/dirty-image-objects")) {
- addOption("-Ximage-compiler-option");
- addOption("--dirty-image-objects=/system/etc/dirty-image-objects");
- }
- parseCompilerOption("dalvik.vm.image-dex2oat-threads", dex2oatThreadsImageBuf, "-j",
- "-Ximage-compiler-option");
- parseCompilerOption("dalvik.vm.image-dex2oat-cpu-set", dex2oatCpuSetImageBuf, "--cpu-set=",
- "-Ximage-compiler-option");
- // The runtime may compile a boot image, when necessary, not using installd. Thus, we need
- // to pass the instruction-set-features/variant as an image-compiler-option.
- // Note: it is OK to reuse the buffer, as the values are exactly the same between
- // * compiler-option, used for runtime compilation (DexClassLoader)
- // * image-compiler-option, used for boot-image compilation on device
- parseCompilerOption(dex2oat_isa_variant_key, dex2oat_isa_variant,
- "--instruction-set-variant=", "-Ximage-compiler-option");
- parseCompilerOption(dex2oat_isa_features_key, dex2oat_isa_features,
- "--instruction-set-features=", "-Ximage-compiler-option");
- if (generate_debug_info) {
- addOption("-Ximage-compiler-option");
- addOption("--generate-debug-info");
- }
- if (generate_mini_debug_info) {
- addOption("-Ximage-compiler-option");
- addOption("--generate-mini-debug-info");
- }
- property_get("dalvik.vm.image-dex2oat-flags", dex2oatImageFlagsBuf, "");
- parseExtraOpts(dex2oatImageFlagsBuf, "-Ximage-compiler-option");
- /* Set the properties for locale */
- {
- strcpy(localeOption, "-Duser.locale=");
- const std::string locale = readLocale();
- strncat(localeOption, locale.c_str(), PROPERTY_VALUE_MAX);
- addOption(localeOption);
- }
- // Trace files are stored in /data/misc/trace which is writable only in debug mode.
- property_get("ro.debuggable", propBuf, "0");
- if (strcmp(propBuf, "1") == 0) {
- property_get("dalvik.vm.method-trace", propBuf, "false");
- if (strcmp(propBuf, "true") == 0) {
- addOption("-Xmethod-trace");
- parseRuntimeOption("dalvik.vm.method-trace-file",
- methodTraceFileBuf,
- "-Xmethod-trace-file:");
- parseRuntimeOption("dalvik.vm.method-trace-file-siz",
- methodTraceFileSizeBuf,
- "-Xmethod-trace-file-size:");
- property_get("dalvik.vm.method-trace-stream", propBuf, "false");
- if (strcmp(propBuf, "true") == 0) {
- addOption("-Xmethod-trace-stream");
- }
- }
- }
- // Native bridge library. "0" means that native bridge is disabled.
- //
- // Note: bridging is only enabled for the zygote. Other runs of
- // app_process may not have the permissions to mount etc.
- property_get("ro.dalvik.vm.native.bridge", propBuf, "");
- if (propBuf[0] == '\0') {
- ALOGW("ro.dalvik.vm.native.bridge is not expected to be empty");
- } else if (zygote && strcmp(propBuf, "0") != 0) {
- snprintf(nativeBridgeLibrary, sizeof("-XX:NativeBridge=") + PROPERTY_VALUE_MAX,
- "-XX:NativeBridge=%s", propBuf);
- addOption(nativeBridgeLibrary);
- }
- #if defined(__LP64__)
- const char* cpu_abilist_property_name = "ro.product.cpu.abilist64";
- #else
- const char* cpu_abilist_property_name = "ro.product.cpu.abilist32";
- #endif // defined(__LP64__)
- property_get(cpu_abilist_property_name, propBuf, "");
- if (propBuf[0] == '\0') {
- ALOGE("%s is not expected to be empty", cpu_abilist_property_name);
- return -1;
- }
- snprintf(cpuAbiListBuf, sizeof(cpuAbiListBuf), "--cpu-abilist=%s", propBuf);
- addOption(cpuAbiListBuf);
- // Dalvik-cache pruning counter.
- parseRuntimeOption("dalvik.vm.zygote.max-boot-retry", cachePruneBuf,
- "-Xzygote-max-boot-retry=");
- // If set, the property below can be used to enable core platform API violation reporting.
- property_get("persist.debug.dalvik.vm.core_platform_api_policy", propBuf, "");
- if (propBuf[0] != '\0') {
- snprintf(corePlatformApiPolicyBuf,
- sizeof(corePlatformApiPolicyBuf),
- "-Xcore-platform-api-policy:%s",
- propBuf);
- addOption(corePlatformApiPolicyBuf);
- }
- /*
- * Retrieve the build fingerprint and provide it to the runtime. That way, ANR dumps will
- * contain the fingerprint and can be parsed.
- * Fingerprints are potentially longer than PROPERTY_VALUE_MAX, so parseRuntimeOption() cannot
- * be used here.
- * Do not ever re-assign fingerprintBuf as its c_str() value is stored in mOptions.
- */
- std::string fingerprint = GetProperty("ro.build.fingerprint", "");
- if (!fingerprint.empty()) {
- fingerprintBuf = "-Xfingerprint:" + fingerprint;
- addOption(fingerprintBuf.c_str());
- }
- initArgs.version = JNI_VERSION_1_4;
- initArgs.options = mOptions.editArray();
- initArgs.nOptions = mOptions.size();
- initArgs.ignoreUnrecognized = JNI_FALSE;
- /*
- * Initialize the VM.
- *
- * The JavaVM* is essentially per-process, and the JNIEnv* is per-thread.
- * If this call succeeds, the VM is ready, and we can start issuing
- * JNI calls.
- */
- if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
- ALOGE("JNI_CreateJavaVM failed\n");
- return -1;
- }
- return 0;
- }
复制代码 注册JNI
将gRegJNI数组里的JNI方法进行注册。RegJNIRec 包含100+个JNI方法。
- /*static*/ int AndroidRuntime::startReg(JNIEnv* env)
- {
- ATRACE_NAME("RegisterAndroidNatives");
- /*
- * This hook causes all future threads created in this process to be
- * attached to the JavaVM. (This needs to go away in favor of JNI
- * Attach calls.)
- */
- androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
- ALOGV("--- registering native functions ---\n");
- /*
- * Every "register" function calls one or more things that return
- * a local reference (e.g. FindClass). Because we haven't really
- * started the VM yet, they're all getting stored in the base frame
- * and never released. Use Push/Pop to manage the storage.
- */
- env->PushLocalFrame(200);
- //核心步骤:将gRegJNI数组里的JNI方法进行注册。
- if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
- env->PopLocalFrame(NULL);
- return -1;
- }
- env->PopLocalFrame(NULL);
- //createJavaThread("fubar", quickTest, (void*) "hello");
- return 0;
- }
复制代码- static const RegJNIRec gRegJNI[] = {
- REG_JNI(register_com_android_internal_os_RuntimeInit),
- REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit),
- REG_JNI(register_android_os_SystemClock),
- REG_JNI(register_android_util_CharsetUtils),
- REG_JNI(register_android_util_EventLog),
- REG_JNI(register_android_util_Log),
- REG_JNI(register_android_util_MemoryIntArray),
- REG_JNI(register_android_app_admin_SecurityLog),
- REG_JNI(register_android_content_AssetManager),
- REG_JNI(register_android_content_StringBlock),
- REG_JNI(register_android_content_XmlBlock),
- REG_JNI(register_android_content_res_ApkAssets),
- REG_JNI(register_android_content_res_ResourceTimer),
- REG_JNI(register_android_text_AndroidCharacter),
- REG_JNI(register_android_text_Hyphenator),
- REG_JNI(register_android_view_InputDevice),
- REG_JNI(register_android_view_KeyCharacterMap),
- REG_JNI(register_android_os_Process),
- REG_JNI(register_android_os_SystemProperties),
- REG_JNI(register_android_os_Binder),
- REG_JNI(register_android_os_Parcel),
- REG_JNI(register_android_os_PerformanceHintManager),
- REG_JNI(register_android_os_HidlMemory),
- REG_JNI(register_android_os_HidlSupport),
- REG_JNI(register_android_os_HwBinder),
- REG_JNI(register_android_os_HwBlob),
- REG_JNI(register_android_os_HwParcel),
- REG_JNI(register_android_os_HwRemoteBinder),
- REG_JNI(register_android_os_NativeHandle),
- REG_JNI(register_android_os_ServiceManager),
- REG_JNI(register_android_os_ServiceManagerNative),
- REG_JNI(register_android_os_storage_StorageManager),
- REG_JNI(register_android_service_DataLoaderService),
- REG_JNI(register_android_view_DisplayEventReceiver),
- REG_JNI(register_android_view_Surface),
- REG_JNI(register_android_view_SurfaceControl),
- REG_JNI(register_android_view_SurfaceControlHdrLayerInfoListener),
- REG_JNI(register_android_view_SurfaceSession),
- REG_JNI(register_android_view_InputApplicationHandle),
- // This must be called after register_android_view_SurfaceControl since it has a dependency
- // on the Java SurfaceControl object that references a native resource via static request.
- REG_JNI(register_android_view_InputWindowHandle),
- REG_JNI(register_android_view_CompositionSamplingListener),
- REG_JNI(register_android_view_TextureView),
- REG_JNI(register_android_view_TunnelModeEnabledListener),
- REG_JNI(register_com_google_android_gles_jni_EGLImpl),
- REG_JNI(register_com_google_android_gles_jni_GLImpl),
- REG_JNI(register_android_opengl_jni_EGL14),
- REG_JNI(register_android_opengl_jni_EGL15),
- REG_JNI(register_android_opengl_jni_EGLExt),
- REG_JNI(register_android_opengl_jni_GLES10),
- REG_JNI(register_android_opengl_jni_GLES10Ext),
- REG_JNI(register_android_opengl_jni_GLES11),
- REG_JNI(register_android_opengl_jni_GLES11Ext),
- REG_JNI(register_android_opengl_jni_GLES20),
- REG_JNI(register_android_opengl_jni_GLES30),
- REG_JNI(register_android_opengl_jni_GLES31),
- REG_JNI(register_android_opengl_jni_GLES31Ext),
- REG_JNI(register_android_opengl_jni_GLES32),
- REG_JNI(register_android_graphics_classes),
- REG_JNI(register_android_graphics_BLASTBufferQueue),
- REG_JNI(register_android_graphics_GraphicBuffer),
- REG_JNI(register_android_graphics_GraphicsStatsService),
- REG_JNI(register_android_graphics_SurfaceTexture),
- REG_JNI(register_android_database_CursorWindow),
- REG_JNI(register_android_database_SQLiteConnection),
- REG_JNI(register_android_database_SQLiteGlobal),
- REG_JNI(register_android_database_SQLiteDebug),
- REG_JNI(register_android_database_SQLiteRawStatement),
- REG_JNI(register_android_os_Debug),
- REG_JNI(register_android_os_FileObserver),
- REG_JNI(register_android_os_GraphicsEnvironment),
- REG_JNI(register_android_os_MessageQueue),
- REG_JNI(register_android_os_SELinux),
- REG_JNI(register_android_os_Trace),
- REG_JNI(register_android_os_UEventObserver),
- REG_JNI(register_android_net_LocalSocketImpl),
- REG_JNI(register_android_os_MemoryFile),
- REG_JNI(register_android_os_SharedMemory),
- REG_JNI(register_android_os_incremental_IncrementalManager),
- REG_JNI(register_com_android_internal_content_om_OverlayConfig),
- REG_JNI(register_com_android_internal_content_om_OverlayManagerImpl),
- REG_JNI(register_com_android_internal_net_NetworkUtilsInternal),
- REG_JNI(register_com_android_internal_os_ClassLoaderFactory),
- REG_JNI(register_com_android_internal_os_LongArrayMultiStateCounter),
- REG_JNI(register_com_android_internal_os_LongMultiStateCounter),
- REG_JNI(register_com_android_internal_os_Zygote),
- REG_JNI(register_com_android_internal_os_ZygoteCommandBuffer),
- REG_JNI(register_com_android_internal_os_ZygoteInit),
- REG_JNI(register_com_android_internal_security_VerityUtils),
- REG_JNI(register_com_android_internal_util_VirtualRefBasePtr),
- REG_JNI(register_android_hardware_Camera),
- REG_JNI(register_android_hardware_camera2_CameraMetadata),
- REG_JNI(register_android_hardware_camera2_DngCreator),
- REG_JNI(register_android_hardware_camera2_impl_CameraExtensionJpegProcessor),
- REG_JNI(register_android_hardware_camera2_utils_SurfaceUtils),
- REG_JNI(register_android_hardware_display_DisplayManagerGlobal),
- REG_JNI(register_android_hardware_HardwareBuffer),
- REG_JNI(register_android_hardware_OverlayProperties),
- REG_JNI(register_android_hardware_SensorManager),
- REG_JNI(register_android_hardware_SerialPort),
- REG_JNI(register_android_hardware_SyncFence),
- REG_JNI(register_android_hardware_UsbDevice),
- REG_JNI(register_android_hardware_UsbDeviceConnection),
- REG_JNI(register_android_hardware_UsbRequest),
- REG_JNI(register_android_hardware_location_ActivityRecognitionHardware),
- REG_JNI(register_android_media_AudioDeviceAttributes),
- REG_JNI(register_android_media_AudioEffectDescriptor),
- REG_JNI(register_android_media_AudioSystem),
- REG_JNI(register_android_media_AudioRecord),
- REG_JNI(register_android_media_AudioTrack),
- REG_JNI(register_android_media_AudioAttributes),
- REG_JNI(register_android_media_AudioProductStrategies),
- REG_JNI(register_android_media_AudioVolumeGroups),
- REG_JNI(register_android_media_AudioVolumeGroupChangeHandler),
- REG_JNI(register_android_media_MediaMetrics),
- REG_JNI(register_android_media_MicrophoneInfo),
- REG_JNI(register_android_media_RemoteDisplay),
- REG_JNI(register_android_media_ToneGenerator),
- REG_JNI(register_android_media_audio_common_AidlConversion),
- REG_JNI(register_android_media_midi),
- REG_JNI(register_android_opengl_classes),
- REG_JNI(register_android_ddm_DdmHandleNativeHeap),
- REG_JNI(register_android_backup_BackupDataInput),
- REG_JNI(register_android_backup_BackupDataOutput),
- REG_JNI(register_android_backup_FileBackupHelperBase),
- REG_JNI(register_android_backup_BackupHelperDispatcher),
- REG_JNI(register_android_app_backup_FullBackup),
- REG_JNI(register_android_app_Activity),
- REG_JNI(register_android_app_ActivityThread),
- REG_JNI(register_android_app_NativeActivity),
- REG_JNI(register_android_util_jar_StrictJarFile),
- REG_JNI(register_android_view_InputChannel),
- REG_JNI(register_android_view_InputEventReceiver),
- REG_JNI(register_android_view_InputEventSender),
- REG_JNI(register_android_view_InputQueue),
- REG_JNI(register_android_view_KeyEvent),
- REG_JNI(register_android_view_MotionEvent),
- REG_JNI(register_android_view_MotionPredictor),
- REG_JNI(register_android_view_PointerIcon),
- REG_JNI(register_android_view_VelocityTracker),
- REG_JNI(register_android_view_VerifiedKeyEvent),
- REG_JNI(register_android_view_VerifiedMotionEvent),
- REG_JNI(register_android_content_res_ObbScanner),
- REG_JNI(register_android_content_res_Configuration),
- REG_JNI(register_android_animation_PropertyValuesHolder),
- REG_JNI(register_android_security_Scrypt),
- REG_JNI(register_com_android_internal_content_F2fsUtils),
- REG_JNI(register_com_android_internal_content_NativeLibraryHelper),
- REG_JNI(register_com_android_internal_os_FuseAppLoop),
- REG_JNI(register_com_android_internal_os_KernelAllocationStats),
- REG_JNI(register_com_android_internal_os_KernelCpuBpfTracking),
- REG_JNI(register_com_android_internal_os_KernelCpuTotalBpfMapReader),
- REG_JNI(register_com_android_internal_os_KernelCpuUidBpfMapReader),
- REG_JNI(register_com_android_internal_os_KernelSingleProcessCpuThreadReader),
- REG_JNI(register_com_android_internal_os_KernelSingleUidTimeReader),
- REG_JNI(register_android_window_WindowInfosListener),
- REG_JNI(register_android_window_ScreenCapture),
- REG_JNI(register_jni_common),
- REG_JNI(register_android_tracing_PerfettoDataSource),
- REG_JNI(register_android_tracing_PerfettoDataSourceInstance),
- REG_JNI(register_android_tracing_PerfettoProducer),
- };
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |