参考:
https://segmentfault.com/a/1190000020526400 《Java 世界的盘古和女娲 —— Zygote》
https://zhuanlan.zhihu.com/p/494650195 《基于Android12 分析系统启动过程》
https://www.csdn.net/tags/MtzaggzsMzU4NTctYmxvZwO0O0OO0O0O.html 《Android Launcher启动过程》
https://juejin.cn/post/6873066972616065038 《浅谈 Zygote 和 SystemServer 》
https://article.itxueyuan.com/wZRbv 《Android 8.1 源码_启动篇(二) -- 深入研究 zygote 》
https://www.jianshu.com/p/c1632e673e30 《zygote》
https://blog.csdn.net/zhaojigao/article/details/85614257 《Android 8.1 zygote创建新应用进程》
上文:
http://www.gaohaiyan.com/4073.html
上文梳理,frameworks/base/core/jni/AndroidRuntime.cpp中,
startVm、startReg构建了虚拟机JNIEnv* env;,
又用反射构将接收的参数className“com.android.internal.os.ZygoteInit”构造出一个java类startClass“com/android/internal/os/ZygoteInit”,
最终通过env->CallStaticVoidMethod(startClass, startMeth, strArray);启动这个java类。
然后,就到了本文。
1. ZygoteInit
在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java约832行,是main函数。根据参数预加载资源文件;启动SystemServer,或者启动Zygote中的socket。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
public static void main(String argv[]) { Log.e("aosp-acer", "Zygote入口main的参数:" + Arrays.toString(argv) + ",位置:" + JarUtil.getFilePath(new File("."))); ZygoteServer zygoteServer = null; // 同路径ZygoteServer.java。ZygoteServer作用是用来创建 Socket ,用来接受 创建(fork)子进程的命令 // 为了确保zygote启动,当有子线程创建时将引发错误。 // libcore/dalvik/src/main/java/dalvik/system/ZygoteHooks.java,约45行。public static native void startZygoteNoThreadCreation(); ZygoteHooks.startZygoteNoThreadCreation(); // 禁止多线程 // Zygote goes into its own process group. try { Os.setpgid(0, 0); // 指定当前进程的id(第一个参数是 目标进程id,第二个参数是 进程组id,把第二个参数设置成第一个的值) } catch (ErrnoException ex) { throw new RuntimeException("Failed to setpgid(0,0)", ex); } Runnable caller; // 声明一个线程 try { // Store now for StatsLogging later. final long startTime = SystemClock.elapsedRealtime(); // Zygote进程启动的时间 final boolean isRuntimeRestarted = "1".equals(SystemProperties.get("sys.boot_completed"));// 如果sys.boot_completed值是1表示重启来的 String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing"; TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag, Trace.TRACE_TAG_DALVIK); bootTimingsTraceLog.traceBegin("ZygoteInit"); RuntimeInit.preForkInit(); boolean startSystemServer = false; // 是否 启动SystemServer String zygoteSocketName = "zygote"; // socket名称 String abiList = null; // so库的类型 boolean enableLazyPreload = false; // 32位cpu时传入的参数里有这个,是否 开启懒加载资源 for (int i = 1; i < argv.length; i++) { // 解析参数 if ("start-system-server".equals(argv[i])) { startSystemServer = true; } else if ("--enable-lazy-preload".equals(argv[i])) { enableLazyPreload = true; } else if (argv[i].startsWith(ABI_LIST_ARG)) { abiList = argv[i].substring(ABI_LIST_ARG.length()); } else if (argv[i].startsWith(SOCKET_NAME_ARG)) { zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length()); } else { throw new RuntimeException("Unknown command line argument: " + argv[i]); } } // 同目录Zygote.java。约271行 public static final String PRIMARY_SOCKET_NAME = "zygote"; final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME); if (!isRuntimeRestarted) { // 本次系统启动不是重启 if (isPrimaryZygote) { // Zygote名称是‘zygote’ FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED, BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__ZYGOTE_INIT_START, startTime); } else if (zygoteSocketName.equals(Zygote.SECONDARY_SOCKET_NAME)) { FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED, BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__SECONDARY_ZYGOTE_INIT_START, startTime); } } Log.e("aosp-acer", "Zygote入口main的参数:" + JarUtil.getProgramPath(FrameworkStatsLog.class)); if (abiList == null) { throw new RuntimeException("No ABI list supplied."); } // In some configurations, we avoid preloading resources and classes eagerly. // In such cases, we will preload things prior to our first fork. if (!enableLazyPreload) { // 如果没有开启懒加载 bootTimingsTraceLog.traceBegin("ZygotePreload"); EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock.uptimeMillis()); preload(bootTimingsTraceLog); // 约128行。预加载资源 [---- 1.1 ----] EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis()); bootTimingsTraceLog.traceEnd(); // ZygotePreload } // Do an initial gc to clean up after startup bootTimingsTraceLog.traceBegin("PostZygoteInitGC"); gcAndFinalize(); // 启动后进行初始的GC清理 System.gc(); 因为上面可能预加载了 bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC bootTimingsTraceLog.traceEnd(); // ZygoteInit Zygote.initNativeState(isPrimaryZygote); // 调用Native初始化状态。Zygote.java约512行 ZygoteHooks.stopZygoteNoThreadCreation(); // ZygoteServer.java,约172行。ZygoteServer(boolean isPrimaryZygote) zygoteServer = new ZygoteServer(isPrimaryZygote); // 创建Socket服务端LocalServerSocket。 [---- 2 ----] if (startSystemServer) { // 启动SystemServer进程 Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer); // 约717行 [---- 1.2 ----] // {@code r == null} in the parent (zygote) process, and {@code r != null} in the child (system_server) process. // r为null表示在zygote进程执行,r不为null表示在system_server进程执行 if (r != null) { r.run(); // 启动SystemServer [---- 重点,下一篇,进入frameworks/base/services/java/com/android/server/SystemServer.java ----] return; } } Log.i(TAG, "Accepting command socket connections"); // The select loop returns early in the child process after a fork and loops forever in the zygote. // 没意外的话,Zygote进程进入永久循环,等待处理客户端请求。sokcet服务端等待AMS请求(AMS会通过socket请求Zygote来创建应用程序进程) caller = zygoteServer.runSelectLoop(abiList); // [---- 2.1 ----] } catch (Throwable ex) { Log.e(TAG, "System zygote died with exception", ex); throw ex; } finally { if (zygoteServer != null) { zygoteServer.closeServerSocket(); // 关闭zygote自己创建的用来接收ActivityManager的链接请求的socket } } // We're in the child process and have exited the select loop. Proceed to execute the command. if (caller != null) { caller.run(); // 启动Zygote进程进入永久循环,等待处理客户端请求 } } // end main |
1.1. preload
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
static void preload(TimingsTraceLog bootTimingsTraceLog) { Log.d(TAG, "begin preload"); bootTimingsTraceLog.traceBegin("BeginPreload"); beginPreload(); // 调用ZygoteHooks初始化ICU缓存,反射JaCoCo中的class bootTimingsTraceLog.traceEnd(); // BeginPreload bootTimingsTraceLog.traceBegin("PreloadClasses"); preloadClasses(); // 加载和初始化常用的类 bootTimingsTraceLog.traceEnd(); // PreloadClasses bootTimingsTraceLog.traceBegin("CacheNonBootClasspathClassLoaders"); cacheNonBootClasspathClassLoaders(); // 缓存hidi相关的ClassLoader bootTimingsTraceLog.traceEnd(); // CacheNonBootClasspathClassLoaders bootTimingsTraceLog.traceBegin("PreloadResources"); preloadResources(); // 加载常用资源,使它们可以跨进程共享 bootTimingsTraceLog.traceEnd(); // PreloadResources Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs"); nativePreloadAppProcessHALs(); // 调用native函数来初始化的HAL层逻辑 Trace.traceEnd(Trace.TRACE_TAG_DALVIK); Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadGraphicsDriver"); maybePreloadGraphicsDriver(); // 调用native函数来初始化图形驱动程序 Trace.traceEnd(Trace.TRACE_TAG_DALVIK); preloadSharedLibraries(); // 加载共享库(android,compiler_rt,jnigraphics) preloadTextResources(); // 初始化文本字体资源 // Ask the WebViewFactory to do any initialization that must run in the zygote process, // for memory sharing purposes. WebViewFactory.prepareWebViewInZygote(); // 初始化WebView需要进程内存共享的空间(64位:1GB,32位:130MB) endPreload(); // 预加载结束,同时会调用ZygoteHooks进程克隆标准文件描述符(in,out,err) warmUpJcaProviders(); // 注册AndroidKeyStoreProvider,并且通知Security的providers Log.d(TAG, "end preload"); sPreloadComplete = true; } |
1.2. forkSystemServer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
private static Runnable forkSystemServer(String abiList, String socketName, ZygoteServer zygoteServer) { // 约808行 private static long posixCapabilitiesAsBits(int... capabilities) long capabilities = posixCapabilitiesAsBits( // 获取所提供的POSIX功能列表的位数组表示形式 OsConstants.CAP_IPC_LOCK, OsConstants.CAP_KILL, OsConstants.CAP_NET_ADMIN, OsConstants.CAP_NET_BIND_SERVICE, OsConstants.CAP_NET_BROADCAST, OsConstants.CAP_NET_RAW, OsConstants.CAP_SYS_MODULE, OsConstants.CAP_SYS_NICE, OsConstants.CAP_SYS_PTRACE, OsConstants.CAP_SYS_TIME, OsConstants.CAP_SYS_TTY_CONFIG, OsConstants.CAP_WAKE_ALARM, OsConstants.CAP_BLOCK_SUSPEND ); /* Containers run without some capabilities, so drop any caps that are not available. 容器运行时没有某些功能,因此请删除任何不可用的CAP。*/ // libcore/luni/src/main/java/android/system/StructCapUserHeader.java 。保存version和pid StructCapUserHeader header = new StructCapUserHeader( OsConstants._LINUX_CAPABILITY_VERSION_3, 0); StructCapUserData[] data; // libcore/luni/src/main/java/android/system/StructCapUserData.java。保存一堆api版本 try { data = Os.capget(header); } catch (ErrnoException ex) { throw new RuntimeException("Failed to capget()", ex); } capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32); /* Hardcoded command line to start the system server。用于启动系统服务的硬编码命令行 */ String args[] = { "--setuid=1000", "--setgid=1000", "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023," + "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010,3011", "--capabilities=" + capabilities + "," + capabilities, "--nice-name=system_server", "--runtime-args", "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT, "com.android.server.SystemServer", // system_server启动的类名 }; ZygoteArguments parsedArgs = null; // 参数解析器。ZygoteArguments.java,约250行。ZygoteArguments(String[] args) int pid; try { parsedArgs = new ZygoteArguments(args); Zygote.applyDebuggerSystemProperty(parsedArgs); // 提取‘--runtime-flags’ Zygote.applyInvokeWithSystemProperty(parsedArgs); // 提取‘--invoke-with’ if (Zygote.nativeSupportsTaggedPointers()) { // native是否支持tagged指针 /* Enable pointer tagging in the system server. Hardware support for this is present in all ARMv8 CPUs. */ parsedArgs.mRuntimeFlags |= Zygote.MEMORY_TAG_LEVEL_TBI; } /* Enable gwp-asan on the system server with a small probability. * This is the same policy as applied to native processes and system apps. */ parsedArgs.mRuntimeFlags |= Zygote.GWP_ASAN_LEVEL_LOTTERY; if (shouldProfileSystemServer()) { parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER; } /* Request to fork the system server process */ // 创建SystemServer进程,具体实现在native层 pid = Zygote.forkSystemServer( parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids, parsedArgs.mRuntimeFlags, null, parsedArgs.mPermittedCapabilities, parsedArgs.mEffectiveCapabilities); } catch (IllegalArgumentException ex) { throw new RuntimeException(ex); } /* For child process */ if (pid == 0) { // pid为0代表在新创建的system_server进程中 if (hasSecondZygote(abiList)) { // 约957行。是否存在第2个zygote进程 waitForSecondaryZygote(socketName); // 尝试连接 } zygoteServer.closeServerSocket();// 关闭并释放从 Zygote copy 过来的 socket return handleSystemServerProcess(parsedArgs); // [---- 1.3 ----]约501行。完成 新创建1个的system_server进程 的剩余工作,拿到启动器 } return null; } // end forkSystemServer |
1.3. handleSystemServerProcess
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) { // set umask to 0077 so new files and directories will default to owner-only permissions. Os.umask(S_IRWXG | S_IRWXO); // umask一般是用在你初始创建一个目录或者文件的时候赋予他们的权限 if (parsedArgs.mNiceName != null) { // 设置当前进程名为 "system_server" Process.setArgV0(parsedArgs.mNiceName); } final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH"); if (systemServerClasspath != null) { performSystemServerDexOpt(systemServerClasspath); // dex 优化操作 // Capturing profiles is only supported for debug or eng builds since selinux normally // prevents it. if (shouldProfileSystemServer() && (Build.IS_USERDEBUG || Build.IS_ENG)) { try { Log.d(TAG, "Preparing system server profile"); prepareSystemServerProfile(systemServerClasspath); } catch (Exception e) { Log.wtf(TAG, "Failed to set up system server profile", e); } } } if (parsedArgs.mInvokeWith != null) { String[] args = parsedArgs.mRemainingArgs; // If we have a non-null system server class path, we'll have to duplicate the // existing arguments and append the classpath to it. ART will handle the classpath // correctly when we exec a new process. if (systemServerClasspath != null) { String[] amendedArgs = new String[args.length + 2]; amendedArgs[0] = "-cp"; amendedArgs[1] = systemServerClasspath; System.arraycopy(args, 0, amendedArgs, 2, args.length); args = amendedArgs; } WrapperInit.execApplication(parsedArgs.mInvokeWith, parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion, VMRuntime.getCurrentInstructionSet(), null, args); throw new IllegalStateException("Unexpected return from WrapperInit.execApplication"); } else { ClassLoader cl = null; if (systemServerClasspath != null) { // 创建类加载器,并赋给当前线程 cl = createPathClassLoader(systemServerClasspath, parsedArgs.mTargetSdkVersion); Thread.currentThread().setContextClassLoader(cl); } /* Pass the remaining arguments to SystemServer. * 调用 ZygoteInit.zygoteInit() 继续处理剩余参数 */ // [---- 1.4 ----] 约991行。得到 ”com.android.server.SystemServer“的启动器 return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion, parsedArgs.mDisabledCompatChanges, parsedArgs.mRemainingArgs, cl); } /* should never reach here */ } // end handleSystemServerProcess |
1.4. zygoteInit
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public static final Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges, String[] argv, ClassLoader classLoader) { if (RuntimeInit.DEBUG) { Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote"); } Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit"); RuntimeInit.redirectLogStreams(); // 重定向 System.out 和 System.err 到 Android log RuntimeInit.commonInit(); // 一些初始化工作。通过setDefaultUncaughtExceptionHandler设置默认的异常处理机制 ZygoteInit.nativeZygoteInit(); // native 层初始化。触发启动进程的Binder线程池 // [---- 3 ----] frameworks/base/core/java/com/android/internal/os/RuntimeInit.java,约404行 // 调用入口函数。内部经过层层调用,最终创建一个 通过反射得到"com.android.server.SystemServer"类并执行其main函数 的Runnable对象 return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv, classLoader); } |
2. ZygoteServer
在frameworks/base/core/java/com/android/internal/os/ZygoteServer.java,约172行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
ZygoteServer(boolean isPrimaryZygote) { mUsapPoolEventFD = Zygote.getUsapPoolEventFD(); // Usap文件描述符 if (isPrimaryZygote) { // mZygoteSocket、mUsapPoolSocket都为frameworks/base/core/java/android/net/LocalServerSocket.java // 创建zygote和usap_pool_primary的Socket连接 mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME); // [---- 4 ----] "zygote" mUsapPoolSocket = Zygote.createManagedSocketFromInitSocket(Zygote.USAP_POOL_PRIMARY_SOCKET_NAME); // [---- 4 ----] "usap_pool_primary" } else { // 创建zygote_secondary和usap_pool_secondary的Socket连接 mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.SECONDARY_SOCKET_NAME); // [---- 4 ----] "zygote_secondary" mUsapPoolSocket = Zygote.createManagedSocketFromInitSocket(Zygote.USAP_POOL_SECONDARY_SOCKET_NAME); // [---- 4 ----] "usap_pool_secondary" } mUsapPoolSupported = true; // 最终建立的Socket的名字会被加上 ANDROID_SOCKET_ 前缀 fetchUsapPoolPolicyProps(); // 约268行。获取Usap相关配置。USAP(Unspecialized App Process) } |
2.1. runSelectLoop
创建一个进程,用于循环等待处理客户端发来的 socket 请求。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 |
Runnable runSelectLoop(String abiList) { ArrayList<FileDescriptor> socketFDs = new ArrayList<>(); ArrayList<ZygoteConnection> peers = new ArrayList<>(); socketFDs.add(mZygoteSocket.getFileDescriptor()); peers.add(null); mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP; while (true) { fetchUsapPoolPolicyPropsWithMinInterval(); // 约315行。获取UsapPool相关配置 mUsapPoolRefillAction = UsapPoolRefillAction.NONE; int[] usapPipeFDs = null; StructPollfd[] pollFDs; // Allocate enough space for the poll structs, taking into account // the state of the USAP pool for this Zygote (could be a // regular Zygote, a WebView Zygote, or an AppZygote). if (mUsapPoolEnabled) { usapPipeFDs = Zygote.getUsapPipeFDs(); pollFDs = new StructPollfd[socketFDs.size() + 1 + usapPipeFDs.length]; } else { pollFDs = new StructPollfd[socketFDs.size()]; } /* For reasons of correctness the USAP pool pipe and event FDs must be processed before the session and server sockets. * This is to ensure that the USAP pool accounting information is * accurate when handling other requests like API blacklist exemptions. */ int pollIndex = 0; for (FileDescriptor socketFD : socketFDs) { pollFDs[pollIndex] = new StructPollfd(); pollFDs[pollIndex].fd = socketFD; pollFDs[pollIndex].events = (short) POLLIN; ++pollIndex; } final int usapPoolEventFDIndex = pollIndex; // SocketFD个数 if (mUsapPoolEnabled) { pollFDs[pollIndex] = new StructPollfd(); pollFDs[pollIndex].fd = mUsapPoolEventFD; pollFDs[pollIndex].events = (short) POLLIN; ++pollIndex; // The usapPipeFDs array will always be filled in if the USAP Pool is enabled. assert usapPipeFDs != null; for (int usapPipeFD : usapPipeFDs) { FileDescriptor managedFd = new FileDescriptor(); managedFd.setInt$(usapPipeFD); pollFDs[pollIndex] = new StructPollfd(); pollFDs[pollIndex].fd = managedFd; pollFDs[pollIndex].events = (short) POLLIN; ++pollIndex; } } int pollTimeoutMs; if (mUsapPoolRefillTriggerTimestamp == INVALID_TIMESTAMP) { pollTimeoutMs = -1; } else { long elapsedTimeMs = System.currentTimeMillis() - mUsapPoolRefillTriggerTimestamp; if (elapsedTimeMs >= mUsapPoolRefillDelayMs) { // The refill delay has elapsed during the period between poll invocations. // We will now check for any currently ready file descriptors before refilling the USAP pool. pollTimeoutMs = 0; mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP; mUsapPoolRefillAction = UsapPoolRefillAction.DELAYED; } else if (elapsedTimeMs <= 0) { // This can occur if the clock used by currentTimeMillis is reset, // which is possible because it is not guaranteed to be monotonic. // Because we can't tell how far back the clock was set the best way to recover is to simply re-start the respawn delay countdown. pollTimeoutMs = mUsapPoolRefillDelayMs; } else { pollTimeoutMs = (int) (mUsapPoolRefillDelayMs - elapsedTimeMs); } } int pollReturnValue; try { pollReturnValue = Os.poll(pollFDs, pollTimeoutMs); } catch (ErrnoException ex) { throw new RuntimeException("poll failed", ex); } if (pollReturnValue == 0) { // The poll returned zero results either when the timeout value has been exceeded // or when a non-blocking poll is issued and no FDs are ready. In either case it is time to refill the pool. // This will result in a duplicate assignment when the non-blocking poll returns zero results, // but it avoids an additional conditional in the else branch. mUsapPoolRefillTriggerTimestamp = INVALID_TIMESTAMP; mUsapPoolRefillAction = UsapPoolRefillAction.DELAYED; } else { boolean usapPoolFDRead = false; while (--pollIndex >= 0) { // 读取的状态不是客户端连接或者数据请求时,进入下一次循环 if ((pollFDs[pollIndex].revents & POLLIN) == 0) { continue; } if (pollIndex == 0) { // 跟客户端Socket 连接上了 // Zygote server socket // frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java ZygoteConnection newPeer = acceptCommandPeer(abiList); // 约219行。产生一个ZygoteConnection连接 [---- 2.2 ----] peers.add(newPeer);// 保存到集合中 socketFDs.add(newPeer.getFileDescriptor()); // FD也保存到集中中 } else if (pollIndex < usapPoolEventFDIndex) { // // Session socket accepted from the Zygote server socket 从ZygoteServer接收到客户端请求 try { ZygoteConnection connection = peers.get(pollIndex); final Runnable command = connection.processOneCommand(this); // 获取处理请求的脚本执行器 [---- 5.1 ----] // TODO (chriswailes): Is this extra check necessary? if (mIsForkChild) { // We're in the child. We should always have a command to run at this stage if processOneCommand hasn't called "exec". // 在子进程中,如果没有命令来执行,抛出异常 if (command == null) { throw new IllegalStateException("command == null"); } return command; } else { // We're in the server - we should never have any commands to run. // 在Server进程中,我们不应该有命令需要执行 if (command != null) { throw new IllegalStateException("command != null"); } // We don't know whether the remote side of the socket was closed or not until we attempt to read from it from processOneCommand. // This shows up as a regular POLLIN event in our regular processing loop. // 关闭Socket if (connection.isClosedByPeer()) { connection.closeSocket(); peers.remove(pollIndex); socketFDs.remove(pollIndex); } } } catch (Exception e) { if (!mIsForkChild) { // We're in the server so any exception here is one that has taken // place pre-fork while processing commands or reading / writing from the control socket. // Make a loud noise about any such exceptions so that we know exactly what failed and why. Slog.e(TAG, "Exception executing zygote command: ", e); // Make sure the socket is closed so that the other end knows immediately that something has gone wrong // and doesn't time out waiting for a response. ZygoteConnection conn = peers.remove(pollIndex); conn.closeSocket(); // 关闭连接 socketFDs.remove(pollIndex); } else { // We're in the child so any exception caught here has happened post fork and // before we execute ActivityThread.main (or any other main() method). // Log the details of the exception and bring down the process. Log.e(TAG, "Caught post-fork exception in child process.", e); throw e; } } finally { // Reset the child flag, in the event that the child process is a child-zygote. // The flag will not be consulted this loop pass after the Runnable is returned. mIsForkChild = false; // 恢复默认值 } } else { // Either the USAP pool event FD or a USAP reporting pipe. // If this is the event FD the payload will be the number of USAPs removed. // If this is a reporting pipe FD the payload will be the PID of the USAP that was just specialized. // The `continue` statements below ensure that the messagePayload will always be valid // if we complete the try block without an exception. long messagePayload; try { byte[] buffer = new byte[Zygote.USAP_MANAGEMENT_MESSAGE_BYTES]; int readBytes = Os.read(pollFDs[pollIndex].fd, buffer, 0, buffer.length); if (readBytes == Zygote.USAP_MANAGEMENT_MESSAGE_BYTES) { DataInputStream inputStream = new DataInputStream(new ByteArrayInputStream(buffer)); messagePayload = inputStream.readLong(); } else { Log.e(TAG, "Incomplete read from USAP management FD of size " + readBytes); continue; } } catch (Exception ex) { if (pollIndex == usapPoolEventFDIndex) { Log.e(TAG, "Failed to read from USAP pool event FD: " + ex.getMessage()); } else { Log.e(TAG, "Failed to read from USAP reporting pipe: " + ex.getMessage()); } continue; } if (pollIndex > usapPoolEventFDIndex) { Zygote.removeUsapTableEntry((int) messagePayload); // Zygote.java,约852行 } usapPoolFDRead = true; } } if (usapPoolFDRead) { int usapPoolCount = Zygote.getUsapPoolCount(); // Zygote.java,约568行 if (usapPoolCount < mUsapPoolSizeMin) { // Immediate refill mUsapPoolRefillAction = UsapPoolRefillAction.IMMEDIATE; } else if (mUsapPoolSizeMax - usapPoolCount >= mUsapPoolRefillThreshold) { // Delayed refill mUsapPoolRefillTriggerTimestamp = System.currentTimeMillis(); } } } if (mUsapPoolRefillAction != UsapPoolRefillAction.NONE) { int[] sessionSocketRawFDs = socketFDs.subList(1, socketFDs.size()) .stream() .mapToInt(FileDescriptor::getInt$) .toArray(); final boolean isPriorityRefill = mUsapPoolRefillAction == UsapPoolRefillAction.IMMEDIATE; final Runnable command = fillUsapPool(sessionSocketRawFDs, isPriorityRefill); // 约343行。产生usap进程 [---- 2.3 ----] if (command != null) { return command; } else if (isPriorityRefill) { // Schedule a delayed refill to finish refilling the pool. mUsapPoolRefillTriggerTimestamp = System.currentTimeMillis(); } } } // end while(true) } |
2.2. acceptCommandPeer
等待一个独立连接。
1 2 3 4 5 6 7 8 9 10 11 12 |
private ZygoteConnection acceptCommandPeer(String abiList) { try { return createNewConnection(mZygoteSocket.accept(), abiList); // 约228行 } catch (IOException ex) { throw new RuntimeException("IOException during accept()", ex); } } protected ZygoteConnection createNewConnection(LocalSocket socket, String abiList) throws IOException { // frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java,约83行。 return new ZygoteConnection(socket, abiList); // 创建1个连接。 [---- 5 ----] } |
2.3. fillUsapPool
等待一个独立连接。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
Runnable fillUsapPool(int[] sessionSocketRawFDs, boolean isPriorityRefill) { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Zygote:FillUsapPool"); // Ensure that the pool properties have been fetched. 确保已提取池属性。 fetchUsapPoolPolicyPropsIfUnfetched(); // 约326行。 int usapPoolCount = Zygote.getUsapPoolCount(); // Zygote.java约567行。当前未专门化的应用程序进程数 int numUsapsToSpawn; if (isPriorityRefill) { // Refill to min 。mUsapPoolSizeMin:运行时可调整的最小USAP池大小。 numUsapsToSpawn = mUsapPoolSizeMin - usapPoolCount; Log.i("zygote", "Priority USAP Pool refill. New USAPs: " + numUsapsToSpawn); } else { // Refill up to max。mUsapPoolSizeMax:运行时可调整的最大USAP池大小。 numUsapsToSpawn = mUsapPoolSizeMax - usapPoolCount; Log.i("zygote", "Delayed USAP Pool refill. New USAPs: " + numUsapsToSpawn); } // Disable some VM functionality and reset some system values before forking. // 创建前,禁用一些VM功能并重置一些系统值。 ZygoteHooks.preFork(); // Zygote.java,约116行。 while (--numUsapsToSpawn >= 0) { Runnable caller = Zygote.forkUsap(mUsapPoolSocket, sessionSocketRawFDs, isPriorityRefill); // Zygote.java,约596行。 if (caller != null) { return caller; } } // Re-enable runtime services for the Zygote. 重启zygote的运行时服务。 // Services for unspecialized app process are re-enabled in specializeAppProcess. 在specializeAppProcess中重新启用非专业化应用程序进程的服务。 ZygoteHooks.postForkCommon(); // ZygoteHooks.java,约150行。 resetUsapRefillState(); // 约414行。重置。 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); return null; } |
3. RuntimeInit
在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java,约404行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges, String[] argv, ClassLoader classLoader) { Log.e("aosp-acer", "反射创建Systemserver的参数:" + Arrays.toString(argv)); // If the application calls System.exit(), terminate the process immediately without running any shutdown hooks. // It is not possible to shutdown an Android application gracefully. // Among other things, the Android runtime shutdown hooks close the Binder driver, // which can cause leftover running threads to crash before the process actually exits. nativeSetExitWithoutCleanup(true); VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion); VMRuntime.getRuntime().setDisabledCompatChanges(disabledCompatChanges); final Arguments args = new Arguments(argv); // The end of of the RuntimeInit event (see #zygoteInit). Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); // Remaining arguments are passed to the start class's static main return findStaticMain(args.startClass, args.startArgs, classLoader); // 约345行 [---- 3.1 ----] } |
3.1. findStaticMain
等待一个独立连接。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
protected static Runnable findStaticMain(String className, String[] argv, ClassLoader classLoader) { Class<?> cl; try { cl = Class.forName(className, true, classLoader); // 通过反射加载构建"com.android.server.SystemServer"类对象 } catch (ClassNotFoundException ex) { throw new RuntimeException("Missing class when invoking static main " + className, ex); } Method m; try { m = cl.getMethod("main", new Class[] { String[].class }); // 获取"com.android.server.SystemServer"的main方法 } catch (NoSuchMethodException ex) { throw new RuntimeException("Missing static main on " + className, ex); } catch (SecurityException ex) { throw new RuntimeException("Problem getting static main on " + className, ex); } int modifiers = m.getModifiers(); if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) { throw new RuntimeException("Main method is not public and static on " + className); } /* This throw gets caught in ZygoteInit.main(), which responds by invoking the exception's run() method. * This arrangement clears up all the stack frames that were required in setting up the process. */ return new MethodAndArgsCaller(m, argv); // [---- 3.2 ----]约578行。实现Runnable的内部类。反射执行main函数 } |
3.2. MethodAndArgsCaller
等待一个独立连接。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
static class MethodAndArgsCaller implements Runnable { private final Method mMethod; /** method to call */ private final String[] mArgs; /** argument array */ public MethodAndArgsCaller(Method method, String[] args) { mMethod = method; mArgs = args; } public void run() { try { mMethod.invoke(null, new Object[] { mArgs }); } catch (IllegalAccessException ex) { throw new RuntimeException(ex); } catch (InvocationTargetException ex) { Throwable cause = ex.getCause(); if (cause instanceof RuntimeException) { throw (RuntimeException) cause; } else if (cause instanceof Error) { throw (Error) cause; } throw new RuntimeException(ex); } } } |
4. Zygote.createManagedSocketFromInitSocket
在frameworks/base/core/java/com/android/internal/os/Zygote.java,约1013行。创建一个LocalServerSocket。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
static LocalServerSocket createManagedSocketFromInitSocket(String socketName) { int fileDesc; final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName; try { String env = System.getenv(fullSocketName); fileDesc = Integer.parseInt(env); } catch (RuntimeException ex) { throw new RuntimeException("Socket unset or invalid: " + fullSocketName, ex); } try { FileDescriptor fd = new FileDescriptor(); fd.setInt$(fileDesc); // frameworks/base/core/java/android/net/LocalServerSocket.java,约63行。public LocalServerSocket(FileDescriptor fd) return new LocalServerSocket(fd); // 创建socket。[---- 6 ----] } catch (IOException ex) { throw new RuntimeException("Error building socket from file descriptor: " + fileDesc, ex); } } |
4.1. readArgumentList
读取socket的输入端/客户端的数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
static String[] readArgumentList(BufferedReader socketReader) throws IOException { int argc; try { String argc_string = socketReader.readLine(); if (argc_string == null) { // EOF reached. return null; } argc = Integer.parseInt(argc_string); } catch (NumberFormatException ex) { Log.e("Zygote", "Invalid Zygote wire format: non-int at argc"); throw new IOException("Invalid wire format"); } // See bug 1092107: large argc can be used for a DOS attack if (argc > MAX_ZYGOTE_ARGC) { throw new IOException("Max arg count exceeded"); } String[] args = new String[argc]; for (int arg_index = 0; arg_index < argc; arg_index++) { args[arg_index] = socketReader.readLine(); if (args[arg_index] == null) { // We got an unexpected EOF. throw new IOException("Truncated request"); } } return args; } |
5. ZygoteConnection
在frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java,约83行。创建连接对象,内部初始化输入输出接口。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
ZygoteConnection(LocalSocket socket, String abiList) throws IOException { mSocket = socket; this.abiList = abiList; mSocketOutStream = new DataOutputStream(socket.getOutputStream()); mSocketReader = new BufferedReader(new InputStreamReader(socket.getInputStream()), Zygote.SOCKET_BUFFER_SIZE); mSocket.setSoTimeout(CONNECTION_TIMEOUT_MILLIS); try { peer = mSocket.getPeerCredentials(); } catch (IOException ex) { Log.e(TAG, "Cannot read peer credentials", ex); throw ex; } isEof = false; } |
5.1. processOneCommand
获取脚本执行器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
Runnable processOneCommand(ZygoteServer zygoteServer) { String[] args; try { args = Zygote.readArgumentList(mSocketReader); // 读取客户端数据。上面的[---- 4.1 ----] Zygote.java,约971行 } catch (IOException ex) { throw new IllegalStateException("IOException on command socket", ex); } // readArgumentList returns null only when it has reached EOF with no available data to read. // This will only happen when the remote socket has disconnected. if (args == null) { isEof = true; return null; } int pid; FileDescriptor childPipeFd = null; FileDescriptor serverPipeFd = null; ZygoteArguments parsedArgs = new ZygoteArguments(args); if (parsedArgs.mBootCompleted) { handleBootCompleted(); // 约309行。 return null; } if (parsedArgs.mAbiListQuery) { handleAbiListQuery(); // 约228行 return null; } if (parsedArgs.mPidQuery) { handlePidQuery(); // 约298行 return null; } if (parsedArgs.mUsapPoolStatusSpecified) { return handleUsapPoolStatusChange(zygoteServer, parsedArgs.mUsapPoolEnabled); // 约388行 } if (parsedArgs.mPreloadDefault) { handlePreload(); // 约325行 return null; } if (parsedArgs.mPreloadPackage != null) { handlePreloadPackage(parsedArgs.mPreloadPackage, parsedArgs.mPreloadPackageLibs, parsedArgs.mPreloadPackageLibFileName, parsedArgs.mPreloadPackageCacheKey); return null; } if (canPreloadApp() && parsedArgs.mPreloadApp != null) { byte[] rawParcelData = Base64.getDecoder().decode(parsedArgs.mPreloadApp); Parcel appInfoParcel = Parcel.obtain(); appInfoParcel.unmarshall(rawParcelData, 0, rawParcelData.length); appInfoParcel.setDataPosition(0); ApplicationInfo appInfo = ApplicationInfo.CREATOR.createFromParcel(appInfoParcel); appInfoParcel.recycle(); if (appInfo != null) { handlePreloadApp(appInfo); } else { throw new IllegalArgumentException("Failed to deserialize --preload-app"); } return null; } if (parsedArgs.mApiBlacklistExemptions != null) { return handleApiBlacklistExemptions(zygoteServer, parsedArgs.mApiBlacklistExemptions); } if (parsedArgs.mHiddenApiAccessLogSampleRate != -1 || parsedArgs.mHiddenApiAccessStatslogSampleRate != -1) { return handleHiddenApiAccessLogSampleRate(zygoteServer, parsedArgs.mHiddenApiAccessLogSampleRate, parsedArgs.mHiddenApiAccessStatslogSampleRate); } if (parsedArgs.mPermittedCapabilities != 0 || parsedArgs.mEffectiveCapabilities != 0) { throw new ZygoteSecurityException("Client may not specify capabilities: " + "permitted=0x" + Long.toHexString(parsedArgs.mPermittedCapabilities) + ", effective=0x" + Long.toHexString(parsedArgs.mEffectiveCapabilities)); } Zygote.applyUidSecurityPolicy(parsedArgs, peer); Zygote.applyInvokeWithSecurityPolicy(parsedArgs, peer); Zygote.applyDebuggerSystemProperty(parsedArgs); Zygote.applyInvokeWithSystemProperty(parsedArgs); int[][] rlimits = null; if (parsedArgs.mRLimits != null) { rlimits = parsedArgs.mRLimits.toArray(Zygote.INT_ARRAY_2D); } int[] fdsToIgnore = null; if (parsedArgs.mInvokeWith != null) { try { FileDescriptor[] pipeFds = Os.pipe2(O_CLOEXEC); childPipeFd = pipeFds[1]; serverPipeFd = pipeFds[0]; Os.fcntlInt(childPipeFd, F_SETFD, 0); fdsToIgnore = new int[]{childPipeFd.getInt$(), serverPipeFd.getInt$()}; } catch (ErrnoException errnoEx) { throw new IllegalStateException("Unable to set up pipe for invoke-with", errnoEx); } } /* * In order to avoid leaking descriptors to the Zygote child, * the native code must close the two Zygote socket descriptors * in the child process before it switches from Zygote-root to * the UID and privileges of the application being launched. * * In order to avoid "bad file descriptor" errors when the two LocalSocket objects are closed, * the Posix file descriptors are released via a dup2() call * which closes the socket and substitutes an open descriptor to /dev/null. */ int [] fdsToClose = { -1, -1 }; FileDescriptor fd = mSocket.getFileDescriptor(); if (fd != null) { fdsToClose[0] = fd.getInt$(); } fd = zygoteServer.getZygoteSocketFileDescriptor(); if (fd != null) { fdsToClose[1] = fd.getInt$(); } pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids, parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo, parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote, parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mIsTopApp, parsedArgs.mPkgDataInfoList, parsedArgs.mWhitelistedDataInfoList, parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs); try { if (pid == 0) { // in child zygoteServer.setForkChild(); zygoteServer.closeServerSocket(); IoUtils.closeQuietly(serverPipeFd); serverPipeFd = null; return handleChildProc(parsedArgs, childPipeFd, parsedArgs.mStartChildZygote); } else { // In the parent. A pid < 0 indicates a failure and will be handled in // handleParentProc. IoUtils.closeQuietly(childPipeFd); childPipeFd = null; handleParentProc(pid, serverPipeFd); return null; } } finally { IoUtils.closeQuietly(childPipeFd); IoUtils.closeQuietly(serverPipeFd); } } |
6. LocalServerSocket
在frameworks/base/core/java/android/net/LocalServerSocket.java,约63行。创建一个LocalServerSocket对象。
1 2 3 4 5 6 |
public LocalServerSocket(FileDescriptor fd) throws IOException { // frameworks/base/core/java/android/net/LocalSocketImpl.java impl = new LocalSocketImpl(fd); // 实际的输入输出器。[---- 7 ----] impl.listen(LISTEN_BACKLOG); localAddress = impl.getSockAddress(); } |
7. LocalSocketImpl
在frameworks/base/core/java/android/net/LocalSocketImpl.java,约191行。创建一个LocalSocketImpl对象。监听地址、接收、发送消息。
1 2 3 |
LocalSocketImpl(FileDescriptor fd) { this.fd = fd; } |
- end
本文由崔维友 威格灵 cuiweiyou vigiles cuiweiyou 原创,转载请注明出处:http://www.gaohaiyan.com/4093.html
承接App定制、企业web站点、办公系统软件 设计开发,外包项目,毕设