源码: system/core/rootdir/
system/core/init/
init.cpp
init_parser.cpp
signal_handler.cpp
frameworks/base/cmds/app_process/
frameworks/base/core/jni/
frameworks/base/core/java/com/android/internal/os/
ZygoteInit.java
Zygote.java
ZygoteConnection.java
frameworks/base/core/java/com/android/internal/os/
ZygoteInit.java
RuntimeInit.java
Zygote.java
frameworks/base/core/services/java/com/android/server/
frameworks/base/core/jni/
com_android_internal_os_Zygote.cpp
AndroidRuntime.cpp
frameworks/base/services/java/com/android/server/
frameworks/base/services/core/java/com/android/server/
SystemServiceManager.java
ServiceThread.java
am/ActivityManagerService.java
frameworks/base/core/java/android/app/
ActivityThread.java
LoadedApk.java
ContextImpl.java
frameworks/base/core/java/android/app/
ActivityThread.java
LoadedApk.java
ContextImpl.java
frameworks/base/services/java/com/android/server/
frameworks/base/services/core/java/com/android/server/
SystemServiceManager.java
ServiceThread.java
pm/Installer.java
am/ActivityManagerService.java
一、Android概述 Android系统非常庞大,底层是采用Linux作为基底,上层采用带有虚拟机的Java层,通过通过JNI技术,将上下打通,融为一体。下图是Google提供的一张经典的4层架构图,从下往上,依次分为Linux内核,系统库和Android Runtime,应用框架层,应用程序层这4层架构,每一层都包含大量的子模块或子系统。
二、系统启动 Google提供的4层架构图,是非常经典,但只是如垒砖般的方式,简单地分层,而不足表达Android整个系统的启动过程,环环相扣的连接关系,本文更多的是以进程的视角,以分层的架构来诠释Android系统的全貌。 系统启动架构图
三、设备启动过程 3.1、Bootloader引导 Boot ROM: 当手机处于关机状态时,长按Power键开机,引导芯片开始从固化在ROM里的预设出代码开始执行,然后加载引导程序到RAM;
Boot Loader:这是启动Android系统之前的引导程序,主要是检查RAM,初始化硬件设备(如CPU、内存、Flash等)并且通过建立内存空间映射,为装载Linux内核准备合适的环境。一旦Linux内核装载完毕,Bootloader将会从内存中清除掉。 如果用户在Bootloader运行期间,按下预定义的组合健,可以进入系统的更新模块。Android的下载更新可以选择进入Fastboot模式或者Recovery模式。
Fastboot是Android设计的一套通过USB来更新手机分区映像的协议,方便开发人员能快速更新指定的手机分区。但是一般的零售机上往往去掉了Fastboot,Google销售的开发机则带有Fastboot模块。 Recovery模式是Android特有的升级系统。利用Recovery模式,手机可以进行恢复出厂设置或进行OTA、补丁和固件升级。进入Recovery模式实际上是启动了一个文本模式的Linux。
3.2、装载和启动Linux内核 到这里才刚刚开始进入Android系统.
启动Kernel的0号进程:初始化进程管理、内存管理,加载Display,Camera Driver,Binder Driver等相关工作; 启动kthreadd进程(pid=2):是Linux系统的内核进程,会创建内核工作线程kworkder,软中断线程ksoftirqd,thermal等内核守护进程。kthreadd进程是所有内核进程的鼻祖。
Android的boot.img存放的就是Linux内核和一个根文件系统。Bootloader会把boot.img映像装载进内存。然后Linux内核会执行整个系统的初始化,完成后装载根文件系统,最后启动Init进程。
3.3、启动Init进程 Linux内核加载完毕后,会首先启动Init进程,Init进程是系统的第一个进程。在Init进程的启动过程中,会解析Linux的配置脚本init.rc文件,根据init.rc文件的内容,Init进程会装载Android的文件系统、创建系统目录。初始 化属性系统、启动Android系统重要的守护进程,这些进程包括USB守护进程、adb守护进程、vold守护进程、rild守护进程。
启动init进程(pid=1),是Linux系统的用户进程,init进程是所有用户进程的鼻祖。
init进程启动Media Server(多媒体服务)、servicemanager(binder服务管家)、bootanim(开机动画)等重要服务 init进程还会孵化出installd、ueventd、adbd、等用户守护进程; init进程孵化出Zygote进程,Zygote进程是Android系统的首个Java进程,Zygote是所有Java进程的父进程,Zygote进程本身是由init进程孵化而来的。 Android 7.0 init.rc的一点改变 - 哈哈的个人专栏 - CSDN博客
1 2 3 4 5 6 7 8 9 10 11 12 13 /system/core/rootdir/init.rc ..... service ueventd /sbin/ueventd class core critical seclabel u:r:ueventd:s0 service healthd /sbin/healthd class core critical seclabel u:r:healthd:s0 group root system wakelock ......
3.4、启动Zygote进程 init进程初始化结束时,会启动Zygote进程。Zygote进程负责fork出应用进程,是所有应用进程的父进程。Zygote进程初始化时会创建Dalivik虚拟机、预装系统的资源文件和Java类。所有从Zygote进程fork出的用户进程将继承和共享这些预加载的资源,不用浪费时间重新加载,加快了应用程序的启动过程。启动结束后,Zygote进程也将变成守护进程,负责响应和启动APK应用程序的请求:
1 2 3 4 5 6 7 8 9 10 11 /system/core/rootdir/init.zygote64.rc service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server class main socket zygote stream 660 root system onrestart write /sys /android_power /request_state wake onrestart write /sys /power /state on onrestart restart audioserver onrestart restart cameraserver onrestart restart media onrestart restart netd writepid /dev /cpuset /foreground /tasks
3.5、启动SystemServer SystemServer是Zygote进程fork出的第一个进程,也是整个Android系统的核心进程。在SystemServer中运行着系统大部分的Binder服务,SystemServer首先启动本地服务SensorService;接着启动ActivityManagerService、WindowManagerService、PackageManagerService在内的所有Java服务。
Zygote进程fork出System Server进程,System Server是Zygote孵化的第一个进程,地位非常重要; System Server进程:负责启动和管理整个Java framework,包含ActivityManager,PowerManager等服务。 Media Server进程:负责启动和管理整个C++ framework,包含AudioFlinger,Camera Service等服务。
1 2 /frameworks/base/services/java/com/android/server/SystemServer.java SystemServer().run()
3.6、启动ActivityManagerService 3.7、启动Launcher(Activity) SystemServer加载完所有的Java服务后,最后会调用ActivityManagerService的SystemReady()方法,在这个方法的执行中,会发出Intent”android.intent.category.HOME”。凡是响应这个Intent的APK都会运行起来,Launcher应用就是Android系统默认的桌面应用,一般只有它会响应这个Intent,因此,系统开机后,第一个运行的应用就是Launcher。 Zygote进程孵化出的第一个App进程是Launcher;
1 2 /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java startHomeActivityLocked(mCurrentUserId, "systemReady" );
四、设备启动过程详细分析 (1)、启动Init进程 概述: init是Linux系统中用户空间的第一个进程,进程号为1。Kernel启动后,在用户空间,启动init进程,并调用init中的main()方法执行init进程的职责。对于init进程的功能分为4部分:
分析和运行所有的init.rc文件; 生成设备驱动节点; (通过rc文件创建) 处理子进程的终止(signal方式); 提供属性服务。 接下来从main()方法说起。
4.1.1、main() [-> init.cpp]
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 int main (int argc, char ** argv) {if (!strcmp (basename(argv[0 ]), "ueventd" )) { return ueventd_main(argc, argv); } if (!strcmp (basename(argv[0 ]), "watchdogd" )) { return watchdogd_main(argc, argv); } umask(0 ); add_environment("PATH" , _PATH_DEFPATH); bool is_first_stage = (argc == 1 ) || (strcmp (argv[1 ], "--second-stage" ) != 0 );if (is_first_stage) { mount("tmpfs" , "/dev" , "tmpfs" , MS_NOSUID, "mode=0755" ); mkdir("/dev/pts" , 0755 ); mkdir("/dev/socket" , 0755 ); mount("devpts" , "/dev/pts" , "devpts" , 0 , NULL ); #define MAKE_STR(x) __STRING(x) mount("proc" , "/proc" , "proc" , 0 , "hidepid=2,gid=" MAKE_STR(AID_READPROC)); mount("sysfs" , "/sys" , "sysfs" , 0 , NULL ); } open_devnull_stdio(); klog_init(); klog_set_level(KLOG_NOTICE_LEVEL); NOTICE("init %s started!\n" , is_first_stage ? "first stage" : "second stage" ); if (!is_first_stage) { close(open("/dev/.booting" , O_WRONLY | O_CREAT | O_CLOEXEC, 0000 )); property_init(); process_kernel_dt(); process_kernel_cmdline(); export_kernel_boot_props(); } selinux_initialize(is_first_stage); if (is_first_stage) { if (restorecon("/init" ) == -1 ) { ERROR("restorecon failed: %s\n" , strerror(errno)); security_failure(); } char * path = argv[0 ]; char * args[] = { path, const_cast <char *>("--second-stage" ), nullptr }; if (execv(path, args) == -1 ) { ERROR("execv(\"%s\") failed: %s\n" , path, strerror(errno)); security_failure(); } } NOTICE("Running restorecon...\n" ); restorecon("/dev" ); restorecon("/dev/socket" ); restorecon("/dev/__properties__" ); restorecon("/property_contexts" ); restorecon_recursive("/sys" ); epoll_fd = epoll_create1(EPOLL_CLOEXEC); if (epoll_fd == -1 ) { ERROR("epoll_create1 failed: %s\n" , strerror(errno)); exit (1 ); } signal_handler_init(); property_load_boot_defaults(); export_oem_lock_status(); start_property_service(); const BuiltinFunctionMap function_map;Action::set_function_map(&function_map); Parser& parser = Parser::GetInstance(); parser.AddSectionParser("service" ,std ::make_unique<ServiceParser>()); parser.AddSectionParser("on" , std ::make_unique<ActionParser>()); parser.AddSectionParser("import" , std ::make_unique<ImportParser>()); parser.ParseConfig("/init.rc" ); ActionManager& am = ActionManager::GetInstance(); am.QueueEventTrigger("early-init" ); am.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done" ); am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng" ); am.QueueBuiltinAction(set_mmap_rnd_bits_action, "set_mmap_rnd_bits" ); am.QueueBuiltinAction(keychord_init_action, "keychord_init" ); am.QueueBuiltinAction(console_init_action, "console_init" ); am.QueueEventTrigger("init" ); am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng" ); std ::string bootmode = property_get("ro.bootmode" );if (bootmode == "charger" ) { am.QueueEventTrigger("charger" ); } else { am.QueueEventTrigger("late-init" ); } am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers" ); while (true ) { if (!waiting_for_exec) { am.ExecuteOneCommand(); restart_processes(); } int timeout = -1 ; if (process_needs_restart) { timeout = (process_needs_restart - gettime()) * 1000 ; if (timeout < 0 ) timeout = 0 ; } if (am.HasMoreCommands()) { timeout = 0 ; } bootchart_sample(&timeout); epoll_event ev; int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1 , timeout)); if (nr == -1 ) { ERROR("epoll_wait failed: %s\n" , strerror(errno)); } else if (nr == 1 ) { ((void (*)()) ev.data.ptr)(); } } return 0 ;}
4.1.2、创建文件系统目录并挂载相关的文件系统 此时android的log系统还没有启动,采用kernel的log系统,打开的设备节点/dev/kmsg, 那么可通过cat /dev/kmsg来获取内核log。
接下来,设置log的输出级别为KLOG_NOTICE_LEVEL(5),当log级别小于5时则会输出到kernel log, 默认值为3.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 add_environment("PATH" , _PATH_DEFPATH); bool is_first_stage = (argc == 1 ) || (strcmp (argv[1 ], "--second-stage" ) != 0 );if (is_first_stage) { mount("tmpfs" , "/dev" , "tmpfs" , MS_NOSUID, "mode=0755" ); mkdir("/dev/pts" , 0755 ); mkdir("/dev/socket" , 0755 ); mount("devpts" , "/dev/pts" , "devpts" , 0 , NULL ); #define MAKE_STR(x) __STRING(x) mount("proc" , "/proc" , "proc" , 0 , "hidepid=2,gid=" MAKE_STR(AID_READPROC)); mount("sysfs" , "/sys" , "sysfs" , 0 , NULL ); }
该部分主要用于创建和挂载启动所需的文件目录。 需要注意的是,在编译Android系统源码时,在生成的根文件系统中,并不存在这些目录,它们是系统运行时的目录,即当系统终止时,就会消失。
在init初始化过程中,Android分别挂载了tmpfs,devpts,proc,sysfs这4类文件系统。
tmpfs是一种虚拟内存文件系统,它会将所有的文件存储在虚拟内存中,如果你将tmpfs文件系统卸载后,那么其下的所有的内容将不复存在。 tmpfs既可以使用RAM,也可以使用交换分区,会根据你的实际需要而改变大小。tmpfs的速度非常惊人,毕竟它是驻留在RAM中的,即使用了交换分区,性能仍然非常卓越。 由于tmpfs是驻留在RAM的,因此它的内容是不持久的。断电后,tmpfs的内容就消失了,这也是被称作tmpfs的根本原因。
devpts文件系统为伪终端提供了一个标准接口,它的标准挂接点是/dev/ pts。只要pty的主复合设备/dev/ptmx被打开,就会在/dev/pts下动态的创建一个新的pty设备文件。
proc文件系统是一个非常重要的虚拟文件系统,它可以看作是内核内部数据结构的接口,通过它我们可以获得系统的信息,同时也能够在运行时修改特定的内核参数。
与proc文件系统类似,sysfs文件系统也是一个不占有任何磁盘空间的虚拟文件系统。它通常被挂接在/sys目录下。sysfs文件系统是Linux2.6内核引入的,它把连接在系统上的设备和总线组织成为一个分级的文件,使得它们可以在用户空间存取。
4.1.3、屏蔽标准的输入输出 [-> init.cpp]
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 void open_devnull_stdio (void ) {int fd = open("/sys/fs/selinux/null" , O_RDWR);if (fd == -1 ) { static const char *name = "/dev/__null__" ; if (mknod(name, S_IFCHR | 0600 , (1 << 8 ) | 3 ) == 0 ) { fd = open(name, O_RDWR); unlink(name); } if (fd == -1 ) { exit (1 ); } } dup2(fd, 0 ); dup2(fd, 1 ); dup2(fd, 2 ); if (fd > 2 ) { close(fd); } }
前文生成/dev目录后,init进程将调用open_devnull_stdio函数,屏蔽标准的输入输出。 open_devnull_stdio函数会在/dev目录下生成__null__设备节点文件,并将标准输入、标准输出、标准错误输出全部重定向到__null__设备中。 open_devnull_stdio函数定义于system/core/init/util.cpp中。
这里需要说明的是,dup2函数的作用是用来复制一个文件的描述符,通常用来重定向进程的stdin、stdout和stderr。它的函数原形是:
int dup2(int oldfd, int targetfd)
该函数执行后,targetfd将变成oldfd的复制品。
因此上述过程其实就是:创建出null 设备后,将0、1、2绑定到null 设备上。因此init进程调用open_devnull_stdio函数后,通过标准的输入输出无法输出信息。
4.1.4、初始化内核log系统 我们继续回到init进程的main函数,init进程通过klog_init函数,提供输出log信息的设备。 [-> init.cpp]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 klog_init(); klog_set_level(KLOG_NOTICE_LEVEL); void klog_init (void ) {if (klog_fd >= 0 ) return ; klog_fd = open("/dev/kmsg" , O_WRONLY | O_CLOEXEC); if (klog_fd >= 0 ) { return ; } static const char * name = "/dev/__kmsg__" ;if (mknod(name, S_IFCHR | 0600 , (1 << 8 ) | 11 ) == 0 ) { klog_fd = open(name, O_WRONLY | O_CLOEXEC); unlink(name); } }
klog_init函数定义于system/core/libcutils/klog.c中。通过klog_init函数,init进程生成kmsg设备节点文件。该设备可以调用内核信息输出函数printk,以输出log信息。
4.1.5、初始化属性域 1 2 3 4 5 if (!is_first_stage) {....... property_init(); ....... }
调用property_init初始化属性域。在Android平台中,为了让运行中的所有进程共享系统运行时所需要的各种设置值,系统开辟了属性存储区域,并提供了访问该区域的API。
这里存在一个问题是,在init进程中有部分代码块以is_first_stage标志进行区分,决定是否需要进行初始化。 is_first_stage的值,由init进程main函数的入口参数决定,之前不太明白具体的含义。 后来写博客后,有朋友留言,在引入selinux机制后,有些操作必须要在内核态才能完成; 但init进程作为android的第一个进程,又是运行在用户态的。 于是,最终设计为用is_first_stage进行区分init进程的运行状态。init进程在运行的过程中,会完成从内核态到用户态的切换。
1 2 3 4 5 6 void property_init () {if (__system_property_area_init()) { ERROR("Failed to initialize property area\n" ); exit (1 ); } }
property_init函数定义于system/core/init/property_service.cpp中,如上面代码所示,最终调用_system_property_area_init函数初始化属性域。
4.1.6、完成SELinux相关工作 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 selinux_initialize(is_first_stage); static void selinux_initialize (bool in_kernel_domain) {Timer t; selinux_callback cb; cb.func_log = selinux_klog_callback; selinux_set_callback(SELINUX_CB_LOG, cb); cb.func_audit = audit_callback; selinux_set_callback(SELINUX_CB_AUDIT, cb); if (in_kernel_domain) { INFO("Loading SELinux policy...\n" ); if (selinux_android_load_policy() < 0 ) { ERROR("failed to load policy: %s\n" , strerror(errno)); security_failure(); } bool kernel_enforcing = (security_getenforce() == 1 ); bool is_enforcing = selinux_is_enforcing(); if (kernel_enforcing != is_enforcing) { if (security_setenforce(is_enforcing)) { ERROR("security_setenforce(%s) failed: %s\n" , is_enforcing ? "true" : "false" , strerror(errno)); security_failure(); } } if (write_file("/sys/fs/selinux/checkreqprot" , "0" ) == -1 ) { security_failure(); } NOTICE("(Initializing SELinux %s took %.2fs.)\n" , is_enforcing ? "enforcing" : "non-enforcing" , t.duration()); } else { selinux_init_all_handles(); } }
init进程进程调用selinux_initialize启动SELinux。从注释来看,init进程的运行确实是区分用户态和内核态的。
4.1.7、重新设置属性 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 if (is_first_stage) { if (restorecon("/init" ) == -1 ) { ERROR("restorecon failed: %s\n" , strerror(errno)); security_failure(); } char * path = argv[0 ]; char * args[] = { path, const_cast <char *>("--second-stage" ), nullptr }; if (execv(path, args) == -1 ) { ERROR("execv(\"%s\") failed: %s\n" , path, strerror(errno)); security_failure(); } } NOTICE("Running restorecon...\n" ); restorecon("/dev" ); restorecon("/dev/socket" ); restorecon("/dev/__properties__" ); restorecon("/property_contexts" ); restorecon_recursive("/sys" );
上述文件节点在加载Sepolicy之前已经被创建了,因此在加载完Sepolicy后,需要重新设置相关的属性。
4.1.8、创建epoll句柄 如下面代码所示,init进程调用epoll_create1创建epoll句柄。
1 2 3 4 5 epoll_fd = epoll_create1(EPOLL_CLOEXEC); if (epoll_fd == -1 ) { ERROR("epoll_create1 failed: %s\n" , strerror(errno)); exit (1 ); }
在linux的网络编程中,很长的时间都在使用select来做事件触发。在linux新的内核中,有了一种替换它的机制,就是epoll。相比于select,epoll最大的好处在于它不会随着监听fd数目的增长而降低效率。因为在内核中的select实现中,它是采用轮询来处理的,轮询的fd数目越多,自然耗时越多。
epoll机制一般使用epoll_create(int size)函数创建epoll句柄,size用来告诉内核这个句柄可监听的fd的数目。注意这个参数不同于select()中的第一个参数,在select中需给出最大监听数加1的值。 此外,当创建好epoll句柄后,它就会占用一个fd值,在linux下如果查看/proc/进程id/fd/,能够看到创建出的fd,因此在使用完epoll后,必须调用close()关闭,否则可能导致fd被耗尽。 上述代码使用的epoll_create1(EPOLLCLOEXEC)来创建epoll句柄,该标志位表示生成的epoll fd具有”执行后关闭”特性。
4.1.9、装载子进程信号处理器 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 void signal_handler_init () {int s[2 ];if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0 , s) == -1 ) { ERROR("socketpair failed: %s\n" , strerror(errno)); exit (1 ); } signal_write_fd = s[0 ]; signal_read_fd = s[1 ]; struct sigaction act ;memset (&act, 0 , sizeof (act));act.sa_handler = SIGCHLD_handler; act.sa_flags = SA_NOCLDSTOP; sigaction(SIGCHLD, &act, 0 ); ServiceManager::GetInstance().ReapAnyOutstandingChildren(); register_epoll_handler(signal_read_fd, handle_signal); }
Linux进程通过互相发送接收消息来实现进程间的通信,这些消息被称为”信号”。每个进程在处理其它进程发送的信号时都要注册处理者,处理者被称为信号处理器。
注意到sigaction结构体的sa_flags为SA_NOCLDSTOP。由于系统默认在子进程暂停时也会发送信号SIGCHLD,init需要忽略子进程在暂停时发出的SIGCHLD信号,因此将act.sa_flags 置为SA_NOCLDSTOP,该标志位表示仅当进程终止时才接受SIGCHLD信号。
我们来看看SIGCHLD_handler的具体工作。
1 2 3 4 5 static void SIGCHLD_handler (int ) {if (TEMP_FAILURE_RETRY(write(signal_write_fd, "1" , 1 )) == -1 ) { ERROR("write(signal_write_fd) failed: %s\n" , strerror(errno)); } }
从上面代码我们知道,init进程是所有进程的父进程,当其子进程终止产生SIGCHLD信号时,SIGCHLD_handler对signal_write_fd执行写操作。由于socketpair的绑定关系,这将触发信号对应的signal_read_fd收到数据。
在装载信号监听器的最后,signal_handler_init调用register_epoll_handler,其代码如下所示,传入参数分别为signal_read_fd和handle_signal。
1 2 3 4 5 6 7 8 9 void register_epoll_handler (int fd, void (*fn)()) {epoll_event ev; ev.events = EPOLLIN; ev.data.ptr = reinterpret_cast <void *>(fn); if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev) == -1 ) { ERROR("epoll_ctl failed: %s\n" , strerror(errno)); } }
根据代码,我们知道:当epoll句柄监听到signal_read_fd中有数据可读时,将调用handle_signal进行处理。
至此,结合上文我们知道:当init进程调用signal_handler_init后,一旦收到子进程终止带来的SIGCHLD消息后,将利用信号处理者SIGCHLD_handler向signal_write_fd写入信息; epoll句柄监听到signal_read_fd收消息后,将调用handle_signal进行处理。整个过程如下图所示。
1 2 3 4 5 6 7 static void handle_signal () {char buf[32 ];read(signal_read_fd, buf, sizeof (buf)); ServiceManager::GetInstance().ReapAnyOutstandingChildren(); }
从代码中可以看出,handle_signal只是清空signal_read_fd中的数据,然后调用ServiceManager::GetInstance().ReapAnyOutstandingChildren()。
ServiceManager定义于system/core/init/service.cpp中,是一个单例对象:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 ............ ServiceManager::ServiceManager() { } ServiceManager& ServiceManager::GetInstance () {static ServiceManager instance;return instance;} void ServiceManager::ReapAnyOutstandingChildren () {while (ReapOneProcess()) {} } ............
ReapAnyOutstandingChildren函数实际上调用了ReapOneProcess。 我们结合代码,看看ReapOneProcess的具体工作。
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 bool ServiceManager::ReapOneProcess () {int status;pid_t pid = TEMP_FAILURE_RETRY(waitpid(-1 , &status, WNOHANG));if (pid == 0 ) { return false ; } else if (pid == -1 ) { ERROR("waitpid failed: %s\n" , strerror(errno)); return false ; } Service* svc = FindServiceByPid(pid); ......... if (!svc) { return true ; } if (svc->Reap()) { waiting_for_exec = false ; RemoveService(*svc); } return true ;} bool Service::Reap () {if (!(flags_ & SVC_ONESHOT) || (flags_ & SVC_RESTART)) { NOTICE("Service '%s' (pid %d) killing any children in process group\n" , name_.c_str(), pid_); kill(-pid_, SIGKILL); } for (const auto & si : sockets_) { std ::string tmp = StringPrintf(ANDROID_SOCKET_DIR "/%s" , si.name.c_str()); unlink(tmp.c_str()); } if (flags_ & SVC_EXEC) { INFO("SVC_EXEC pid %d finished...\n" , pid_); return true ; } pid_ = 0 ; flags_ &= (~SVC_RUNNING); if ((flags_ & SVC_ONESHOT) && !(flags_ & SVC_RESTART)) { flags_ |= SVC_DISABLED; } if (flags_ & (SVC_DISABLED | SVC_RESET)) { svc->NotifyStateChange("stopped" ); return true ; } time_t now = gettime();if ((flags_ & SVC_CRITICAL) && !(flags_ & SVC_RESTART)) { if (time_crashed_ + CRITICAL_CRASH_WINDOW >= now) { if (++nr_crashed_ > CRITICAL_CRASH_THRESHOLD) { .......... android_reboot(ANDROID_RB_RESTART2, 0 , "recovery" ); return true ; } } else { time_crashed_ = now; nr_crashed_ = 1 ; } } flags_ &= (~SVC_RESTART); flags_ |= SVC_RESTARTING; onrestart_.ExecuteAllCommands(); svc->NotifyStateChange("restarting" ); return true ;} void Action::ExecuteAllCommands () const {for (const auto & c : commands_) { ExecuteCommand(c); } } void Action::ExecuteCommand (const Command& command) const {Timer t; int result = command.InvokeFunc();........ }
waitpid的函数原型为:
1 pid_t waitpid (pid_t pid, int *status, int options)
其中,第一个参数pid为预等待的子进程的识别码,pid=-1表示等待任何子进程是否发出SIGCHLD。第二个参数status,用于返回子进程的结束状态。第三个参数决定waitpid函数是否处于阻塞处理方式,WNOHANG表示若pid指定的子进程没有结束,则waitpid()函数返回0,不予等待;若子进程结束,则返回子进程的pid。waitpid如果出错,则返回-1。
总结一下:整个signal_handler_init其实就是为了重启子进程用的,上述过程其实最终可以简化为下图:
4.1.10、设置默认系统属性 1 property_load_boot_defaults();
接下来,进程调用property_load_boot_defaults进行默认属性配置相关的工作。
1 2 void property_load_boot_defaults () {load_properties_from_file(PROP_PATH_RAMDISK_DEFAULT, NULL );
如代码所示,property_load_boot_defaults实际上就是调用load_properties_from_file解析配置文件;然后根据解析的结果,设置系统属性。该部分功能较为单一,不再深入分析。
4.1.11、配置属性的服务端 1 2 3 4 5 6 7 8 9 10 11 12 13 start_property_service(); void start_property_service () {property_set_fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0666 , 0 , 0 , NULL ); if (property_set_fd == -1 ) { ERROR("start_property_service socket creation failed: %s\n" , strerror(errno)); exit (1 ); } listen(property_set_fd, 8 ); register_epoll_handler(property_set_fd, handle_property_set_fd); }
我们知道,在create_socket函数返回套接字property_set_fd时,property_set_fd是一个主动连接的套接字。此时,系统假设用户会对这个套接字调用connect函数,期待它主动与其它进程连接。
由于在服务器编程中,用户希望这个套接字可以接受外来的连接请求,也就是被动等待用户来连接,于是需要调用listen函数使用主动连接套接字变为被连接套接字,使得一个进程可以接受其它进程的请求,从而成为一个服务器进程。
因此,调用listen后,init进程成为一个服务进程,其它进程可以通过property_set_fd连接init进程,提交设置系统属性的申请。
listen函数的第二个参数,涉及到一些网络的细节。
在进程处理一个连接请求的时候,可能还存在其它的连接请求。因为TCP连接是一个过程,所以可能存在一种半连接的状态。有时由于同时尝试连接的用户过多,使得服务器进程无法快速地完成连接请求。
因此,内核会在自己的进程空间里维护一个队列,以跟踪那些已完成连接但服务器进程还没有接手处理的用户,或正在进行的连接的用户。这样的一个队列不可能任意大,所以必须有一个上限。listen的第二个参数就是告诉内核使用这个数值作为上限。因此,init进程作为系统属性设置的服务器,最多可以同时为8个试图设置属性的用户提供服务。
在启动配置属性服务的最后,调用函数register_epoll_handler。根据上文所述,我们知道该函数将利用之前创建出的epoll句柄监听property_set_fd。当property_set_fd中有数据到来时,init进程将利用handle_property_set_fd函数进行处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 static void handle_property_set_fd () { .......... if ((s = accept(property_set_fd, (struct sockaddr *) &addr, &addr_size)) < 0 ) { return ; } ........ r = TEMP_FAILURE_RETRY(recv(s, &msg, sizeof (msg), MSG_DONTWAIT)); ......... switch (msg.cmd) { ......... } ......... }
handle_propery_set_fd函数实际上是调用accept函数监听连接请求,接收property_set_fd中到来的数据,然后利用recv函数接受到来的数据,最后根据到来数据的类型,进行设置系统属性等相关操作,在此不做深入分析。
在这一部分的最后,我们简单举例介绍一下,系统属性改变的一些用途。 在init.rc中定义了一些与属性相关的触发器。当某个条件相关的属性被改变时,与该条件相关的触发器就会被触发。举例来说,如下面代码所示,debuggable属性变为1时,将执行启动console进程等操作。
1 2 3 4 5 on property:ro.debuggable=1 # Give writes to anyone for the trace folder on debug builds. # The folder is used to store method traces. chmod 0773 /data/misc/trace start console
总结一下,其它进程修改系统属性时,大致的流程如下图所示:其它的进程像init进程发送请求后,由init进程检查权限后,修改共享内存区。
4.1.12、解析init.rc文件 关于解析init.rc的代码,Android 7.0相对于6.0,作了巨大的修改。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 const BuiltinFunctionMap function_map;Action::set_function_map(&function_map); Parser& parser = Parser::GetInstance(); parser.AddSectionParser("service" ,std ::make_unique<ServiceParser>()); parser.AddSectionParser("on" , std ::make_unique<ActionParser>()); parser.AddSectionParser("import" , std ::make_unique<ImportParser>()); parser.ParseConfig("/init.rc" ); ........
在解析init.rc文件的过程前,我们先来简单介绍一下init.rc文件。 init.rc文件是在init进程启动后执行的启动脚本,文件中记录着init进程需执行的操作。在Android系统中,使用init.rc和init.{ hardware }.rc两个文件。
其中init.rc文件在Android系统运行过程中用于通用的环境设置与进程相关的定义,init.{hardware}.rc(例如,高通有init.qcom.rc,MTK有init.mediatek.rc)用于定义Android在不同平台下的特定进程和环境设置等。
此处解析函数传入的参数为”/init.rc”,解析的是运行时与init进程同在根目录下的init.rc文件。该文件在编译前,定义于system/core/rootdir/init.rc中(与平台相关的rc文件不在这里加载)。
init.rc文件大致分为两大部分,一部分是以”on”关键字开头的动作列表(action list):
1 2 3 4 5 on early-init # Set init and its forked children' s oom_adj. write /proc/1 /oom_score_adj -1000 ......... start ueventd
另一部分是以”service”关键字开头的服务列表(service list):
1 2 3 4 service ueventd /sbin/ueventd class core critical seclabel u : r:ueventd:s0
借助系统环境变量或Linux命令,动作列表用于创建所需目录,以及为某些特定文件指定权限,而服务列表用来记录init进程需要启动的一些子进程。如上面代码所示,service关键字后的第一个字符串表示服务(子进程)的名称,第二个字符串表示服务的执行路径。
接下来,我们从ParseConfig函数入手,逐步分析整个解析过程(函数定义于system/core/init/ init_parser.cpp中):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 bool Parser::ParseConfig (const std ::string & path) { if (is_dir(path.c_str())) { return ParseConfigDir(path); } return ParseConfigFile(path); } bool Parser::ParseConfigDir (const std ::string & path) { ........... std::unique_ptr<DIR, int(*)(DIR*)> config_dir(opendir(path.c_str()), closedir); .......... while ((current_file = readdir(config_dir.get()))) { std ::string current_path = android::base::StringPrintf("%s/%s" , path.c_str(), current_file->d_name); if (current_file->d_type == DT_REG) { if (!ParseConfigFile(current_path)) { ............. } } } }
从上面的代码可以看出,解析init.rc文件的函数是ParseConfigFile:
1 2 3 4 5 6 7 8 9 10 11 12 bool Parser::ParseConfigFile (const std ::string & path) { ........ std ::string data; if (!read_file(path.c_str(), &data)) { return false ; } ......... ParseData(path, data); ......... }
ParseData函数定义于system/core/init/init_parser.cpp中,根据关键字解析出服务和动作。动作与服务会以链表节点的形式注册到service_list与action_list中,service_list与action_list是init进程中声明的全局结构体,其中的关键代码下所示。
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 void Parser::ParseData (const std ::string & filename, const std ::string & data) {....... parse_state state; ....... std ::vector <std ::string > args;for (;;) { switch (next_token(&state)) { case T_EOF: if (section_parser) { section_parser->EndSection(); } return ; case T_NEWLINE: state.line++; if (args.empty()) { break ; } if (section_parsers_.count(args[0 ])) { if (section_parser) { section_parser->EndSection(); } section_parser = section_parsers_[args[0 ]].get(); std ::string ret_err; if (!section_parser->ParseSection(args, &ret_err)) { parse_error(&state, "%s\n" , ret_err.c_str()); section_parser = nullptr ; } } else if (section_parser) { std ::string ret_err; if (!section_parser->ParseLineSection(args, state.filename, state.line, &ret_err)) { parse_error(&state, "%s\n" , ret_err.c_str()); } } args.clear(); break ; case T_TEXT: args.emplace_back(state.text); break ; } } }
这里的解析看起来比较复杂,在6.0以前的版本中,整个解析是面向过程的。init进程统一调用一个函数来进行解析,然后在该函数中利用switch-case的形式,根据解析的内容进行相应的处理。 在Android 7.0中,为了更好地封装及面向对象,对于不同的关键字定义了不同的parser对象,每个对象通过多态实现自己的解析操作。
我们现在回忆一下init进程main函数中,创建parser的代码:
1 2 3 4 5 6 ........... Parser& parser = Parser::GetInstance(); parser.AddSectionParser("service" ,std ::make_unique<ServiceParser>()); parser.AddSectionParser("on" , std ::make_unique<ActionParser>()); parser.AddSectionParser("import" , std ::make_unique<ImportParser>()); ...........
看看三个Parser的定义:
1 2 3 class ServiceParser : public SectionParser {......}class ActionParser : public SectionParser {......}class ImportParser : public SectionParser {.......}
可以看到三个Parser均是继承SectionParser,具体的实现各有不同,我们以比较常用的ServiceParser和ActionParser为例,看看解析的结果如何处理。
4.1.12.1 ServiceParser ServiceParser定义于system/core/init/service.cpp中。从前面的代码,我们知道,解析一个service块,首先需要调用ParseSection函数,接着利用ParseLineSection处理子块,解析完所有数据后,调用EndSection。 因此,我们着重看看ServiceParser的这三个函数:
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 bool ServiceParser::ParseSection (.....) { ....... const std ::string & name = args[1 ]; ....... std ::vector <std ::string > str_args (args.begin() + 2 , args.end()) ; service_ = std ::make_unique<Service>(name, "default" , str_args); return true ; } bool ServiceParser::ParseLineSection (......) const { return service_ ? service_->HandleLine(args, err) : false ; } bool Service::HandleLine (.....) { ........ static const OptionHandlerMap handler_map; auto handler = handler_map.FindFunction(args[0 ], args.size() - 1 , err); if (!handler) { return false ; } return (this ->*handler)(args, err); } class Service : :OptionHandlerMap : public KeywordMap<OptionHandler> { ........... Service::OptionHandlerMap::Map& Service::OptionHandlerMap::map () const { constexpr std ::size_t kMax = std ::numeric_limits<std ::size_t >::max(); static const Map option_handlers = { {"class" , {1 , 1 , &Service::HandleClass}}, {"console" , {0 , 0 , &Service::HandleConsole}}, {"critical" , {0 , 0 , &Service::HandleCritical}}, {"disabled" , {0 , 0 , &Service::HandleDisabled}}, {"group" , {1 , NR_SVC_SUPP_GIDS + 1 , &Service::HandleGroup}}, {"ioprio" , {2 , 2 , &Service::HandleIoprio}}, {"keycodes" , {1 , kMax, &Service::HandleKeycodes}}, {"oneshot" , {0 , 0 , &Service::HandleOneshot}}, {"onrestart" , {1 , kMax, &Service::HandleOnrestart}}, {"seclabel" , {1 , 1 , &Service::HandleSeclabel}}, {"setenv" , {2 , 2 , &Service::HandleSetenv}}, {"socket" , {3 , 6 , &Service::HandleSocket}}, {"user" , {1 , 1 , &Service::HandleUser}}, {"writepid" , {1 , kMax, &Service::HandleWritepid}}, }; return option_handlers; } bool Service::HandleClass (const std ::vector <std ::string >& args, std ::string * err) { classname_ = args[1 ]; return true ; } void ServiceParser::EndSection () { if (service_) { ServiceManager::GetInstance().AddService(std ::move(service_)); } } void ServiceManager::AddService (std ::unique_ptr <Service> service) { Service* old_service = FindServiceByName(service->name()); if (old_service) { ERROR("ignored duplicate definition of service '%s'" , service->name().c_str()); return ; } services_.emplace_back(std ::move(service)); }
从上面的一系列代码,我们可以看出ServiceParser其实就是:首先根据第一行的名字和参数创建出service对象,然后根据选项域的内容填充service对象,最后将创建出的service对象加入到vector类型的service链表中。
4.1.12.2 ActionParser ActionParser定义于system/core/init/action.cpp中。Action的解析过程,其实与Service一样,也是先后调用ParseSection, ParseLineSection和EndSection。
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 bool ActionParser::ParseSection (....) { ........ auto action = std ::make_unique<Action>(false ); if (!action->InitTriggers(triggers, err)) { return false ; } ......... } bool ActionParser::ParseLineSection (.......) const { return action_ ? action_->AddCommand(args, filename, line, err) : false ; } bool Action::AddCommand (.....) { ........ auto function = function_map_->FindFunction(args[0 ], args.size() - 1 , err); ........ AddCommand(function, args, filename, line); return true ; } void Action::AddCommand (......) { commands_.emplace_back(f, args, filename, line); } void ActionParser::EndSection () { if (action_ && action_->NumCommands() > 0 ) { ActionManager::GetInstance().AddAction(std ::move(action_)); } } void ActionManager::AddAction (.....) { ........ auto old_action_it = std ::find_if(actions_.begin(), actions_.end(), [&action] (std ::unique_ptr <Action>& a) { return action->TriggersEqual(*a); }); if (old_action_it != actions_.end()) { (*old_action_it)->CombineAction(*action); } else { actions_.emplace_back(std ::move(action)); } }
从上面的代码可以看出,加载action块的逻辑和service一样,不同的是需要填充trigger和command域。当然,最后解析出的action也需要加入到action链表中。
这里最后还剩下一个问题,那就是哪里定义了Action中command对应处理函数? 实际上,前文已经出现了过了,在init.cpp的main函数中:
1 2 3 4 ....... const BuiltinFunctionMap function_map;Action::set_function_map(&function_map); .......
因此,Action中调用function_map_->FindFunction时,实际上调用的是BuiltinFunctionMap的FindFunction函数。我们已经知道FindFunction是keyword定义的通用函数,重点是重构的map函数。我们看看system/core/init/builtins.cpp:
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 BuiltinFunctionMap::Map& BuiltinFunctionMap::map () const { constexpr std ::size_t kMax = std ::numeric_limits<std ::size_t >::max(); static const Map builtin_functions = { {"bootchart_init" , {0 , 0 , do_bootchart_init}}, {"chmod" , {2 , 2 , do_chmod}}, {"chown" , {2 , 3 , do_chown}}, {"class_reset" , {1 , 1 , do_class_reset}}, {"class_start" , {1 , 1 , do_class_start}}, {"class_stop" , {1 , 1 , do_class_stop}}, {"copy" , {2 , 2 , do_copy}}, {"domainname" , {1 , 1 , do_domainname}}, {"enable" , {1 , 1 , do_enable}}, {"exec" , {1 , kMax, do_exec}}, {"export" , {2 , 2 , do_export}}, {"hostname" , {1 , 1 , do_hostname}}, {"ifup" , {1 , 1 , do_ifup}}, {"init_user0" , {0 , 0 , do_init_user0}}, {"insmod" , {1 , kMax, do_insmod}}, {"installkey" , {1 , 1 , do_installkey}}, {"load_persist_props" , {0 , 0 , do_load_persist_props}}, {"load_system_props" , {0 , 0 , do_load_system_props}}, {"loglevel" , {1 , 1 , do_loglevel}}, {"mkdir" , {1 , 4 , do_mkdir}}, {"mount_all" , {1 , kMax, do_mount_all}}, {"mount" , {3 , kMax, do_mount}}, {"powerctl" , {1 , 1 , do_powerctl}}, {"restart" , {1 , 1 , do_restart}}, {"restorecon" , {1 , kMax, do_restorecon}}, {"restorecon_recursive" , {1 , kMax, do_restorecon_recursive}}, {"rm" , {1 , 1 , do_rm}}, {"rmdir" , {1 , 1 , do_rmdir}}, {"setprop" , {2 , 2 , do_setprop}}, {"setrlimit" , {3 , 3 , do_setrlimit}}, {"start" , {1 , 1 , do_start}}, {"stop" , {1 , 1 , do_stop}}, {"swapon_all" , {1 , 1 , do_swapon_all}}, {"symlink" , {2 , 2 , do_symlink}}, {"sysclktz" , {1 , 1 , do_sysclktz}}, {"trigger" , {1 , 1 , do_trigger}}, {"verity_load_state" , {0 , 0 , do_verity_load_state}}, {"verity_update_state" , {0 , 0 , do_verity_update_state}}, {"wait" , {1 , 2 , do_wait}}, {"write" , {2 , 2 , do_write}}, }; return builtin_functions; }
上述代码的第四项就是Action每个command对应的执行函数。
4.1.13、向执行队列中添加其它action 介绍完init进程解析init.rc文件的过程后,我们继续将视角拉回到init进程的main函数:
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 ActionManager& am = ActionManager::GetInstance(); am.QueueEventTrigger("early-init" ); m.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done" ); am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng" ); am.QueueBuiltinAction(set_mmap_rnd_bits_action, "set_mmap_rnd_bits" ); am.QueueBuiltinAction(keychord_init_action, "keychord_init" ); am.QueueBuiltinAction(console_init_action, "console_init" ); am.QueueEventTrigger("init" ); am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng" ); std ::string bootmode = property_get("ro.bootmode" );if (bootmode == "charger" ) { am.QueueEventTrigger("charger" ); } else { am.QueueEventTrigger("late-init" ); } am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers" );
从上面的代码可以看出,接下来init进程中调用了大量的QueueEventTrigger和QueueBuiltinAction函数。
1 2 3 void ActionManager::QueueEventTrigger (const std ::string & trigger) { trigger_queue_.push(std ::make_unique<EventTrigger>(trigger)); }
处QueueEventTrigger函数就是利用参数构造EventTrigger,然后加入到trigger_queue_中。后续init进程处理trigger事件时,将会触发相应的操作。根据前文的分析,我们知道实际上就是将action_list中,对应trigger与第一个参数匹配的action,加入到运行队列action_queue中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 void ActionManager::QueueBuiltinAction (BuiltinFunction func, const std ::string & name) { auto action = std ::make_unique<Action>(true ); std ::vector <std ::string > name_vector{name}; if (!action->InitSingleTrigger(name)) { return ; } action->AddCommand(func, name_vector); trigger_queue_.push(std ::make_unique<BuiltinTrigger>(action.get())); actions_.emplace_back(std ::move(action)); }
QueueBuiltinAction函数中构造新的action加入到actions_中,第一个参数作为新建action携带cmd的执行函数;第二个参数既作为action的trigger name,也作为action携带cmd的参数。
4.1.14、处理添加到运行队列的事件 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 while (true ) { if (!waiting_for_exec) { am.ExecuteOneCommand(); restart_processes(); } int timeout = -1 ; if (process_needs_restart) { timeout = (process_needs_restart - gettime()) * 1000 ; if (timeout < 0 ) timeout = 0 ; } if (am.HasMoreCommands()) { timeout = 0 ; } bootchart_sample(&timeout); epoll_event ev; int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1 , timeout)); if (nr == -1 ) { ERROR("epoll_wait failed: %s\n" , strerror(errno)); } else if (nr == 1 ) { ((void (*)()) ev.data.ptr)(); } }
从上面代码可以看出,init进程将所有需要操作的action加入运行队列后, 进入无限循环过程,不断处理运行队列中的事件,同时进行重启service等操作。
ExecuteOneCommand中的主要部分如下图所示。
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 void ActionManager::ExecuteOneCommand () { while (current_executing_actions_.empty() && !trigger_queue_.empty()) { for (const auto & action : actions_) { if (trigger_queue_.front()->CheckTriggers(*action)) { current_executing_actions_.emplace(action.get()); } } trigger_queue_.pop(); } if (current_executing_actions_.empty()) { return ; } auto action = current_executing_actions_.front(); if (current_command_ == 0 ) { std ::string trigger_name = action->BuildTriggersString(); INFO("processing action (%s)\n" , trigger_name.c_str()); } action->ExecuteOneCommand(current_command_); ++current_command_; if (current_command_ == action->NumCommands()) { current_executing_actions_.pop(); current_command_ = 0 ; if (action->oneshot()) { auto eraser = [&action] (std ::unique_ptr <Action>& a) { return a.get() == action; }; actions_.erase(std ::remove_if(actions_.begin(), actions_.end(), eraser)); } } }
1 2 3 4 5 6 void Action::ExecuteCommand (const Command& command) const { Timer t; int result = command.InvokeFunc(); ........ }
从代码可以看出,当while循环不断调用ExecuteOneCommand函数时,将按照trigger表的顺序,依次取出action链表中与trigger匹配的action。 每次均执行一个action中的一个command对应函数(一个action可能携带多个command)。 当一个action所有的command均执行完毕后,再执行下一个action。 当一个trigger对应的action均执行完毕后,再执行下一个trigger对应action。
restart_processes函数负责按需重启service,代码如下图所示。
1 2 3 4 5 6 7 8 static void restart_processes () { process_needs_restart = 0 ; ServiceManager::GetInstance().ForEachServiceWithFlags( SVC_RESTARTING, [] (Service* s) { s->RestartIfNeeded(process_needs_restart); }); }
从上面可以看出,该函数轮询service对应的链表,对于有SVC_RESTARING标志的service执行RestartIfNeeded(如上文所述,当子进程终止时,init进程会将可被重启进程的服务标志位置为SVC_RESTARTING)。
如下面代码所示,restart_service_if_needed可以重新启动服务。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 void Service::RestartIfNeeded (time_t & process_needs_restart) (struct service *svc) { time_t next_start_time = svc->time_started + 5 ; if (next_start_time <= gettime()) { svc->flags &= (~SVC_RESTARTING); Start(svc, NULL ); return ; } if ((next_start_time < process_needs_restart) || (process_needs_restart == 0 )) { process_needs_restart = next_start_time; } }
查阅资料发现:Bootchart 是一个能对 GNU/Linux boot 过程进行性能分析并把结果直观化的工具。它在 boot 过程中搜集资源利用情况及进程信息然后以PNG, SVG或EPS格式来显示结果。BootChart 包含数据收集工具和图像产生工具。数据收集工具在原始的BootChart中是独立的shell程序,但在Android中,数据收集工具被集成到了init 程序中。资料与代码基本吻合。
(2)、启动Zygote进程 4.2.1、概述 Zygote是由init进程通过解析init.zygote.rc文件而创建的,zygote所对应的可执行程序app_process,所对应的源文件是App_main.cpp,进程名为zygote。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 service zygote /system/bin/app_process32 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote class main socket zygote stream 660 root system onrestart write /sys/android_power/request_state wake onrestart write /sys/power/state on onrestart restart audioserver onrestart restart cameraserver onrestart restart media onrestart restart netd writepid /dev/cpuset/foreground/tasks service zygote_secondary /system/bin/app_process64 -Xzygote /system/bin --zygote --socket-name=zygote_secondary class main socket zygote_secondary stream 660 root system onrestart restart zygote writepid /dev/cpuset/foreground/tasks
Zygote进程能够重启的地方:
servicemanager进程被杀; (onresart) surfaceflinger进程被杀; (onresart) Zygote进程自己被杀; (oneshot=false) system_server进程被杀; (waitpid) 从App_main()开始,Zygote启动过程的函数调用类大致流程如下:
4.2.2、Zygote启动过程 4.2.2.1、App_main.main() [-> App_main.cpp]
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 int main (int argc, char * const argv[]) { if (prctl(PR_SET_NO_NEW_PRIVS, 1 , 0 , 0 , 0 ) < 0 ) { if (errno != EINVAL) { LOG_ALWAYS_FATAL("PR_SET_NO_NEW_PRIVS failed: %s" , strerror(errno)); return 12 ; } } AppRuntime runtime (argv[0 ], computeArgBlockSize(argc, argv)) ; argc--; argv++; int i; for (i = 0 ; i < argc; i++) { if (argv[i][0 ] != '-' ) { break ; } if (argv[i][1 ] == '-' && argv[i][2 ] == 0 ) { ++i; break ; } runtime.addOption(strdup(argv[i])); } bool zygote = false ; bool startSystemServer = false ; bool application = false ; String8 niceName; String8 className; ++i; 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.setTo(arg + 12 ); } else if (strncmp (arg, "--" , 2 ) != 0 ) { className.setTo(arg); break ; } else { --i; break ; } } Vector<String8> args; if (!className.isEmpty()) { args.add(application ? String8("application" ) : String8("tool" )); runtime.setClassNameAndArgs(className, argc - i, argv + i); } else { 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); for (; i < argc; ++i) { args.add(String8(argv[i])); } } if (!niceName.isEmpty()) { runtime.setArgv0(niceName.string ()); set_process_name(niceName.string ()); } if (zygote) { runtime.start("com.android.internal.os.ZygoteInit" , args, zygote); } else if (className) { 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." ); return 10 ; } }
4.2.2.2、AndroidRuntime.start() [-> AndroidRuntime.cpp]
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 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" ) ;for (size_t i = 0 ; i < options.size(); ++i) { if (options[i] == startSystemServer) { 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 /android does not exist." ); return ; } setenv("ANDROID_ROOT" , rootDir, 1 ); } JniInvocation jni_invocation; jni_invocation.Init(NULL ); JNIEnv* env; if (startVm(&mJavaVM, &env, zygote) != 0 ) { return ; } onVmCreated(env); if (startReg(env) < 0 ) { ALOGE("Unable to register all android natives\n" ); return ; } 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).string ()); assert(optionsStr != NULL ); env->SetObjectArrayElement(strArray, i + 1 , optionsStr); } char * slashClassName = toSlashClassName(className);jclass startClass = env->FindClass(slashClassName); if (startClass == NULL ) { ALOGE("JavaVM unable to locate class '%s'\n" , slashClassName); } else { jmethodID startMeth = env->GetStaticMethodID(startClass, "main" , "([Ljava/lang/String;)V" ); if (startMeth == NULL ) { ALOGE("JavaVM unable to find main() in '%s'\n" , className); } 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" ); }
4.2.2.3、AndroidRuntime.startVm() [–> AndroidRuntime.cpp]
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 int AndroidRuntime::startVm (JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote) { bool checkJni = false ; property_get("dalvik.vm.checkjni" , propBuf, "" ); if (strcmp (propBuf, "true" ) == 0 ) { checkJni = true ; } else if (strcmp (propBuf, "false" ) != 0 ) { property_get("ro.kernel.android.checkjni" , propBuf, "" ); if (propBuf[0 ] == '1' ) { checkJni = true ; } } ALOGD("CheckJNI is %s\n" , checkJni ? "ON" : "OFF" ); if (checkJni) { addOption("-Xcheck:jni" ) } ...... parseRuntimeOption("dalvik.vm.stack-trace-file" , stackTraceFileBuf, "-Xstacktracefile:" ); 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=" ); ... if (!hasFile("/system/etc/preloaded-classes" )) { return -1 ; } if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0 ) { ALOGE("JNI_CreateJavaVM failed\n" ); return -1 ; } }
创建Java虚拟机方法的主要篇幅是关于虚拟机参数的设置,下面只列举部分在调试优化过程中常用参数。
4.2.2.4、AndroidRuntime.startReg() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 int AndroidRuntime::startReg (JNIEnv* env) { androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc); env->PushLocalFrame(200 ); if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0 ) { env->PopLocalFrame(NULL ); return -1 ; } env->PopLocalFrame(NULL ); return 0 ; }
4.2.2.4.1、Threads.androidSetCreateThreadFunc() [-> Threads.cpp]
1 2 3 4 void androidSetCreateThreadFunc (android_create_thread_fn func) { gCreateThreadFn = func; }
虚拟机启动后startReg()过程,会设置线程创建函数指针gCreateThreadFn指向javaCreateThreadEtc.
4.2.2.4.2、register_jni_procs() 1 2 3 4 5 6 7 8 9 static int register_jni_procs (const RegJNIRec array [], size_t count, JNIEnv* env) { for (size_t i = 0 ; i < count; i++) { if (array [i].mProc(env) < 0 ) { return -1 ; } } return 0 ; }
4.2.2.4.3、gRegJNI.mProc 1 2 3 4 5 static const RegJNIRec gRegJNI[] = { REG_JNI(register_com_android_internal_os_RuntimeInit), REG_JNI(register_android_os_Binder), ... };*
array[i]是指gRegJNI数组, 该数组有100多个成员。其中每一项成员都是通过REG_JNI宏定义的:
1 2 3 4 #define REG_JNI(name) { name } struct RegJNIRec { int (*mProc)(JNIEnv*); };
可见,调用mProc,就等价于调用其参数名所指向的函数。 例如REG_JNI(register_com_android_internal_os_RuntimeInit).mProc也就是指进入register_com_android_internal_os_RuntimeInit方法,接下来就继续以此为例来说明:
1 2 3 4 5 int register_com_android_internal_os_RuntimeInit (JNIEnv* env) { return jniRegisterNativeMethods(env, "com/android/internal/os/RuntimeInit" , gMethods, NELEM(gMethods)); }
//gMethods:java层方法名与jni层的方法的一一映射关系
1 2 3 4 5 6 7 8 static JNINativeMethod gMethods[] = { { "nativeFinishInit" , "()V" , (void *) com_android_internal_os_RuntimeInit_nativeFinishInit }, { "nativeZygoteInit" , "()V" , (void *) com_android_internal_os_RuntimeInit_nativeZygoteInit }, { "nativeSetExitWithoutCleanup" , "(Z)V" , (void *) com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup }, };
4.2.2.5、进入Java层 AndroidRuntime.start()执行到最后通过反射调用到ZygoteInit.main(),见下文:
4.2.2.5.1、ZygoteInit.main() 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 public static void main (String argv[]) {try {Init"); //开启DDMS功能 RuntimeInit.enableDdms(); SamplingProfilerIntegration.start(); boolean startSystemServer = false; String socketName = " zygote"; String abiList = null; for (int i = 1; i < argv.length; i++) { if (" start-system-server".equals(argv[i])) { startSystemServer = 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)) { socketName = argv[i].substring(SOCKET_NAME_ARG.length()); } else { throw new RuntimeException(" Unknown command line argument: " + argv[i]); } } ...... //为Zygote注册socket registerZygoteSocket(socketName); preload();// 预加载类和资源 SamplingProfilerIntegration.writeZygoteSnapshot(); gcAndFinalize();//GC操作 Zygote.nativeUnmountStorageOnInit(); ZygoteHooks.stopZygoteNoThreadCreation(); if (startSystemServer) {//启动system_server startSystemServer(abiList, socketName); } runSelectLoop(abiList);//进入循环模式 closeServerSocket(); } catch (MethodAndArgsCaller caller) { caller.run(); } catch (Throwable ex) { closeServerSocket(); throw ex; } }
在异常捕获后调用的方法caller.run(),会在后续的system_server文章会讲到。
4.2.2.5.2、ZygoteInit.registerZygoteSocket() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 private static void registerZygoteSocket (String socketName) {if (sServerSocket == null ) { int fileDesc; final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName; try { String env = System.getenv(fullSocketName); fileDesc = Integer.parseInt(env); } catch (RuntimeException ex) { ... } try { FileDescriptor fd = new FileDescriptor(); fd.setInt$(fileDesc); sServerSocket = new LocalServerSocket(fd); } catch (IOException ex) { ... } } }
4.2.2.5.2、ZygoteInit.preload() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 static void preload () { preloadClasses(); preloadResources(); preloadOpenGL(); preloadSharedLibraries(); preloadTextResources(); WebViewFactory.prepareWebViewInZygote(); }
执行Zygote进程的初始化,对于类加载,采用反射机制Class.forName()方法来加载。对于资源加载,主要是 com.android.internal.R.array.preloaded_drawables和com.android.internal.R.array.preloaded_color_state_lists,在应用程序中以com.android.internal.R.xxx开头的资源,便是此时由Zygote加载到内存的。
zygote进程内加载了preload()方法中的所有资源,当需要fork新进程时,采用copy on write技术,如下:
4.2.2.5.3、ZygoteInit.startSystemServer() 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 private static boolean startSystemServer (String abiList, String socketName) throws MethodAndArgsCaller, RuntimeException { long capabilities = posixCapabilitiesAsBits( OsConstants.CAP_BLOCK_SUSPEND, 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_RESOURCE, OsConstants.CAP_SYS_TIME, OsConstants.CAP_SYS_TTY_CONFIG ); String args[] = { "--setuid=1000" , "--setgid=1000" , "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007" , "--capabilities=" + capabilities + "," + capabilities, "--nice-name=system_server" , "--runtime-args" , "com.android.server.SystemServer" , }; ZygoteConnection.Arguments parsedArgs = null ; int pid; try { parsedArgs = new ZygoteConnection.Arguments(args); ZygoteConnection.applyDebuggerSystemProperty(parsedArgs); ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs); pid = Zygote.forkSystemServer( parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, null , parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities); } catch (IllegalArgumentException ex) { throw new RuntimeException(ex); } if (pid == 0 ) { if (hasSecondZygote(abiList)) { waitForSecondaryZygote(socketName); } handleSystemServerProcess(parsedArgs); } return true ; }
准备参数并fork新进程,从上面可以看出system server进程参数信息为uid=1000,gid=1000,进程名为sytem_server,从zygote进程fork新进程后,需要关闭zygote原有的socket。另外,对于有两个zygote进程情况,需等待第2个zygote创建完成。
4.2.2.5.4、ZygoteInit.runSelectLoop() 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 private static void runSelectLoop (String abiList) throws MethodAndArgsCaller { ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>(); ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>(); fds.add(sServerSocket.getFileDescriptor()); peers.add(null ); while (true ) { StructPollfd[] pollFds = new StructPollfd[fds.size()]; for (int i = 0 ; i < pollFds.length; ++i) { pollFds[i] = new StructPollfd(); pollFds[i].fd = fds.get(i); pollFds[i].events = (short ) POLLIN; } try { Os.poll(pollFds, -1 ); } catch (ErrnoException ex) { ... } for (int i = pollFds.length - 1 ; i >= 0 ; --i) { if ((pollFds[i].revents & POLLIN) == 0 ) { continue ; } if (i == 0 ) { ZygoteConnection newPeer = acceptCommandPeer(abiList); peers.add(newPeer); fds.add(newPeer.getFileDesciptor()); } else { boolean done = peers.get(i).runOnce(); if (done) { peers.remove(i); fds.remove(i); } } } } }
Zygote采用高效的I/O多路复用机制,保证在没有客户端连接请求或数据处理时休眠,否则响应客户端的请求。
4.2.2.5.4、ZygoteConnection.runOnce() 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 boolean runOnce () throws ZygoteInit.MethodAndArgsCaller {String args[]; Arguments parsedArgs = null ; FileDescriptor[] descriptors; try { args = readArgumentList(); descriptors = mSocket.getAncillaryFileDescriptors(); } catch (IOException ex) { ... return true ; } ... try { parsedArgs = new Arguments(args); ... pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo, parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet, parsedArgs.appDataDir); } catch (Exception e) { ... } try { if (pid == 0 ) { IoUtils.closeQuietly(serverPipeFd); serverPipeFd = null ; handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr); return true ; } else { IoUtils.closeQuietly(childPipeFd); childPipeFd = null ; return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs); } } finally { IoUtils.closeQuietly(childPipeFd); IoUtils.closeQuietly(serverPipeFd); }
4.2.2.6、总结 Zygote启动过程的调用流程图:
1、解析init.zygote.rc中的参数,创建AppRuntime并调用AppRuntime.start()方法; 2、 调用AndroidRuntime的startVM()方法创建虚拟机,再调用startReg()注册JNI函数; 3、通过JNI方式调用ZygoteInit.main(),第一次进入Java世界; 4、registerZygoteSocket()建立socket通道,zygote作为通信的服务端,用于响应客户端请求; 5、preload()预加载通用类、drawable和color资源、openGL以及共享库以及WebView,用于提高app启动效率; 6、zygote完毕大部分工作,接下来再通过startSystemServer(),fork得力帮手system_server进程,也是上层framework的运行载体。 7、 zygote功成身退,调用runSelectLoop(),随时待命,当接收到请求创建新进程请求时立即唤醒并执行相应工作。
(3)、启动SystemServer上篇 4.3.1、启动流程 SystemServer的在Android体系中所处的地位,SystemServer由Zygote fork生成的,进程名为system_server,该进程承载着framework的核心服务。 Android系统启动-zygote篇中讲到Zygote启动过程中会调用startSystemServer(),可知startSystemServer()函数是system_server启动流程的起点, 启动流程图如下:
4.3.2、ZygoteInit.startSystemServer() 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 private static boolean startSystemServer (String abiList, String socketName) throws MethodAndArgsCaller, RuntimeException { ... String args[] = { "--setuid=1000" , "--setgid=1000" , "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007" , "--capabilities=" + capabilities + "," + capabilities, "--nice-name=system_server" , "--runtime-args" , "com.android.server.SystemServer" , }; ZygoteConnection.Arguments parsedArgs = null ; int pid; try { parsedArgs = new ZygoteConnection.Arguments(args); ZygoteConnection.applyDebuggerSystemProperty(parsedArgs); ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs); pid = Zygote.forkSystemServer( parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, null , parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities); } catch (IllegalArgumentException ex) { throw new RuntimeException(ex); } if (pid == 0 ) { if (hasSecondZygote(abiList)) { waitForSecondaryZygote(socketName); } handleSystemServerProcess(parsedArgs); } return true ; }
准备参数并fork新进程,从上面可以看出system server进程参数信息为uid=1000,gid=1000,进程名为sytem_server,从zygote进程fork新进程后,需要关闭zygote原有的socket。另外,对于有两个zygote进程情况,需等待第2个zygote创建完成。
4.3.3、Zygote. forkSystemServer() 1 2 3 4 5 6 7 8 9 10 11 12 public static int forkSystemServer (int uid, int gid, int [] gids, int debugFlags, int [][] rlimits, long permittedCapabilities, long effectiveCapabilities) { VM_HOOKS.preFork(); int pid = nativeForkSystemServer( uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities); if (pid == 0 ) { Trace.setTracingEnabled(true ); } VM_HOOKS.postForkCommon(); return pid; }
nativeForkSystemServer()方法在AndroidRuntime.cpp中注册的,调用com_android_internal_os_Zygote.cpp中的register_com_android_internal_os_Zygote()方法建立native方法的映射关系,所以接下来进入如下方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 static jint com_android_internal_os_Zygote_nativeForkSystemServer ( JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids, jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities, jlong effectiveCapabilities) { pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags, rlimits, permittedCapabilities, effectiveCapabilities, MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true , NULL, NULL, NULL); if (pid > 0 ) { gSystemServerPid = pid; int status; if (waitpid(pid, &status, WNOHANG) == pid) { RuntimeAbort(env); } } return pid; }
当system_server进程创建失败时,将会重启zygote进程。这里需要注意,对于Android 5.0以上系统,有两个zygote进程,分别是zygote、zygote64两个进程,system_server的父进程,一般来说64位系统其父进程是zygote64进程
当kill system_server进程后,只重启zygote64和system_server,不重启zygote; 当kill zygote64进程后,只重启zygote64和system_server,也不重启zygote; 当kill zygote进程,则重启zygote、zygote64以及system_server。
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 static pid_t ForkAndSpecializeCommon (JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids, jint debug_flags, jobjectArray javaRlimits, jlong permittedCapabilities, jlong effectiveCapabilities, jint mount_external, jstring java_se_info, jstring java_se_name, bool is_system_server, jintArray fdsToClose, jstring instructionSet, jstring dataDir) { SetSigChldHandler(); pid_t pid = fork(); if (pid == 0 ) { DetachDescriptors(env, fdsToClose); if (!is_system_server) { int rc = createProcessGroup(uid, getpid()); } SetGids(env, javaGids); SetRLimits(env, javaRlimits); int rc = setresgid(gid, gid, gid); rc = setresuid(uid, uid, uid); SetCapabilities(env, permittedCapabilities, effectiveCapabilities); SetSchedulerPolicy(env); rc = selinux_android_setcontext(uid, is_system_server, se_info_c_str, se_name_c_str); if (se_info_c_str == NULL && is_system_server) { se_name_c_str = "system_server" ; } if (se_info_c_str != NULL) { SetThreadName(se_name_c_str); } UnsetSigChldHandler(); env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, debug_flags, is_system_server ? NULL : instructionSet); ... } else if (pid > 0 ) { } return pid; }
fork()创建新进程,采用copy on write方式,这是linux创建进程的标准方法,会有两次return,对于pid==0为子进程的返回,对于pid>0为父进程的返回。 到此system_server进程已完成了创建的所有工作,接下来开始了system_server进程的真正工作。在前面startSystemServer()方法中,zygote进程执行完forkSystemServer()后,新创建出来的system_server进程便进入handleSystemServerProcess()方法。
4.3.5、ZygoteInit.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 private static void handleSystemServerProcess ( ZygoteConnection.Arguments parsedArgs) throws ZygoteInit.MethodAndArgsCaller { closeServerSocket(); Os.umask(S_IRWXG | S_IRWXO); if (parsedArgs.niceName != null ) { Process.setArgV0(parsedArgs.niceName); } final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH" ); if (systemServerClasspath != null ) { performSystemServerDexOpt(systemServerClasspath); } if (parsedArgs.invokeWith != null ) { String[] args = parsedArgs.remainingArgs; if (systemServerClasspath != null ) { String[] amendedArgs = new String[args.length + 2 ]; amendedArgs[0 ] = "-cp" ; amendedArgs[1 ] = systemServerClasspath; System.arraycopy(parsedArgs.remainingArgs, 0 , amendedArgs, 2 , parsedArgs.remainingArgs.length); } WrapperInit.execApplication(parsedArgs.invokeWith, parsedArgs.niceName, parsedArgs.targetSdkVersion, VMRuntime.getCurrentInstructionSet(), null , args); } else { ClassLoader cl = null ; if (systemServerClasspath != null ) { 创建类加载器,并赋予当前线程 cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader()); Thread.currentThread().setContextClassLoader(cl); } RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl); } }
此处systemServerClasspath环境变量主要有/system/framework/目录下的services.jar,ethernet-service.jar, wifi-service.jar这3个文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 private static void performSystemServerDexOpt (String classPath) { final String[] classPathElements = classPath.split(":" ); final InstallerConnection installer = new InstallerConnection(); installer.waitForConnection(); final String instructionSet = VMRuntime.getRuntime().vmInstructionSet(); try { for (String classPathElement : classPathElements) { final int dexoptNeeded = DexFile.getDexOptNeeded( classPathElement, "*" , instructionSet, false ); if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { installer.dexopt(classPathElement, Process.SYSTEM_UID, false , instructionSet, dexoptNeeded); } } } catch (IOException ioe) { throw new RuntimeException("Error starting system_server" , ioe); } finally { installer.disconnect(); } }
将classPath字符串中的apk,分别进行dex优化操作。真正执行优化工作通过socket通信将相应的命令参数,发送给installd来完成。
4.3.7、RuntimeInit.zygoteInit() 1 2 3 4 5 6 7 8 9 10 public static final void zygoteInit (int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit" ); redirectLogStreams(); commonInit(); nativeZygoteInit(); applicationInit(targetSdkVersion, argv, classLoader); }
4.3.8、RuntimeInit.commonInit() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 private static final void commonInit () { Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler()); TimezoneGetter.setInstance(new TimezoneGetter() { @Override public String getId () { return SystemProperties.get("persist.sys.timezone" ); } }); TimeZone.setDefault(null ); LogManager.getLogManager().reset(); new AndroidConfig(); String userAgent = getDefaultUserAgent(); System.setProperty("http.agent" , userAgent); NetworkManagementSocketTagger.install(); }
默认的HTTP User-agent格式,例如:
“Dalvik/1.1.0 (Linux; U; Android 6.0.1;LenovoX3c70 Build/LMY47V)”.
4.3.9、AndroidRuntime.nativeZygoteInit() nativeZygoteInit()方法在AndroidRuntime.cpp中,进行了jni映射,对应下面的方法。
1 2 3 4 5 static void com_android_internal_os_RuntimeInit_nativeZygoteInit (JNIEnv* env, jobject clazz) { gCurRuntime->onZygoteInit(); }
1 2 3 4 5 6 7 [–>app_main.cpp] virtual void onZygoteInit () { sp<ProcessState> proc = ProcessState::self(); proc->startThreadPool(); }
ProcessState::self()是单例模式,主要工作是调用open()打开/dev/binder驱动设备,再利用mmap()映射内核的地址空间,将Binder驱动的fd赋值ProcessState对象中的变量mDriverFD,用于交互操作。startThreadPool()是创建一个新的binder线程,不断进行talkWithDriver(),在binder系列文章中的注册服务(addService) 详细这两个方法的执行原理。
4.3.10、RuntimeInit.applicationInit() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 private static void applicationInit (int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { nativeSetExitWithoutCleanup(true ); VMRuntime.getRuntime().setTargetHeapUtilization(0.75f ); VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion); final Arguments args; try { args = new Arguments(argv); } catch (IllegalArgumentException ex) { return ; } Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); invokeStaticMain(args.startClass, args.startArgs, classLoader); }
在startSystemServer()方法中通过硬编码初始化参数,可知此处args.startClass为”com.android.server.SystemServer”。
4.3.11、RuntimeInit.invokeStaticMain() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 private static void invokeStaticMain (String className, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { Class<?> cl = Class.forName(className, true , classLoader); ... Method m; try { m = cl.getMethod("main" , new Class[] { String[].class }); } catch (NoSuchMethodException ex) { ... } catch (SecurityException ex) { ... } int modifiers = m.getModifiers(); if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) { ... } throw new ZygoteInit.MethodAndArgsCaller(m, argv); }
4.3.12、MethodAndArgsCaller.run() 在Zygote中遗留了一个问题没有讲解,如下:
[–>ZygoteInit.java]
1 2 3 4 5 6 7 8 9 10 11 public static void main (String argv[]) { try { startSystemServer(abiList, socketName); .... } catch (MethodAndArgsCaller caller) { caller.run(); } catch (RuntimeException ex) { closeServerSocket(); throw ex; } }
现在已经很明显了,是invokeStaticMain()方法中抛出的异常MethodAndArgsCaller,从而进入caller.run()方法。
[–>ZygoteInit.java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public static class MethodAndArgsCaller extends Exception implements Runnable { 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); } } }
到此,总算是进入到了SystemServer类的main()方法, 在文章Android系统启动-SystemServer下篇中会紧接着这里开始讲述。
(4)、启动SystemServer下篇 上篇文章Android系统启动-systemServer上篇 从Zygote一路启动到SystemServer的过程。 简单回顾下,在RuntimeInit.java中invokeStaticMain方法通过创建并抛出异常ZygoteInit.MethodAndArgsCaller,在ZygoteInit.java中的main()方法会捕捉该异常,并调用caller.run(),再通过反射便会调用到SystemServer.main()方法,该方法主要执行流程:
1 2 3 4 5 6 7 SystemServer.main SystemServer.run createSystemContext startBootstrapServices(); startCoreServices(); startOtherServices(); Looper.loop();
接下来,从其main方法说起。
4.4.1、SystemServer.main() 1 2 3 4 5 6 7 public final class SystemServer { ... public static void main (String[] args) { new SystemServer().run(); } }
4.4.2、SystemServer.run() 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 private void run () { if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) { SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME); } SystemProperties.set("persist.sys.dalvik.vm.lib.2" , VMRuntime.getRuntime().vmLibrary()); if (SamplingProfilerIntegration.isEnabled()) { ... } VMRuntime.getRuntime().clearGrowthLimit(); VMRuntime.getRuntime().setTargetHeapUtilization(0.8f ); Build.ensureFingerprintProperty(); Environment.setUserRequired(true ); BinderInternal.disableBackgroundScheduling(true ); android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND); android.os.Process.setCanSelfBackground(false ); Looper.prepareMainLooper(); System.loadLibrary("android_servers" ); performPendingShutdown(); createSystemContext(); mSystemServiceManager = new SystemServiceManager(mSystemContext); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); try { startBootstrapServices(); startCoreServices(); startOtherServices(); } catch (Throwable ex) { Slog.e("System" , "************ Failure starting system services" , ex); throw ex; } if (StrictMode.conditionallyEnableDebugLogging()) { Slog.i(TAG, "Enabled StrictMode for system server main thread." ); } Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited" ); }
LocalServices通过用静态Map变量sLocalServiceObjects,来保存以服务类名为key,以具体服务对象为value的Map结构。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 private void performPendingShutdown () { final String shutdownAction = SystemProperties.get( ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "" ); if (shutdownAction != null && shutdownAction.length() > 0 ) { boolean reboot = (shutdownAction.charAt(0 ) == '1' ); final String reason; if (shutdownAction.length() > 1 ) { reason = shutdownAction.substring(1 , shutdownAction.length()); } else { reason = null ; } ShutdownThread.rebootOrShutdown(null , reboot, reason); } }
4.4.4、SystemServer.createSystemContext() 1 2 3 4 5 6 7 private void createSystemContext () { ActivityThread activityThread = ActivityThread.systemMain(); mSystemContext = activityThread.getSystemContext(); mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar); }
理解Application创建过程 已介绍过createSystemContext()过程, 该过程会创建对象有ActivityThread,Instrumentation, ContextImpl,LoadedApk,Application。
4.4.5、SystemServer.startBootstrapServices() 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 private void startBootstrapServices () { Installer installer = mSystemServiceManager.startService(Installer.class); mActivityManagerService = mSystemServiceManager.startService( ActivityManagerService.Lifecycle.class).getService(); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); mActivityManagerService.initPowerManagement(); mSystemServiceManager.startService(LightsService.class); mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class); mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); String cryptState = SystemProperties.get("vold.decrypt" ); if (ENCRYPTING_STATE.equals(cryptState)) { mOnlyCore = true ; } else if (ENCRYPTED_STATE.equals(cryptState)) { mOnlyCore = true ; } mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); mFirstBoot = mPackageManagerService.isFirstBoot(); mPackageManager = mSystemContext.getPackageManager(); ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance()); AttributeCache.init(mSystemContext); mActivityManagerService.setSystemProcess(); startSensorService(); }
该方法所创建的服务:ActivityManagerService, PowerManagerService, LightsService, DisplayManagerService, PackageManagerService, UserManagerService, sensor服务.
4.4.5、SystemServer.startCoreServices() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 private void startCoreServices() { //启动服务BatteryService,用于统计电池电量,需要LightService. mSystemServiceManager.startService(BatteryService.class); //启动服务UsageStatsService,用于统计应用使用情况 mSystemServiceManager.startService(UsageStatsService.class); mActivityManagerService.setUsageStatsManager( LocalServices.getService(UsageStatsManagerInternal.class)); mPackageManagerService.getUsageStatsIfNoPackageUsageInfo(); //启动服务WebViewUpdateService mSystemServiceManager.startService(WebViewUpdateService.class); }
启动服务BatteryService,UsageStatsService,WebViewUpdateService。
4.4.6、SystemServer.startOtherServices() 该方法比较长,有近千行代码,逻辑很简单,主要是启动一系列的服务,这里就不具体列举源码了,在第四节直接对其中的服务进行一个简单分类。
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 private void startOtherServices () { ... SystemConfig.getInstance(); mContentResolver = context.getContentResolver(); ... mActivityManagerService.installSystemProviders(); mSystemServiceManager.startService(AlarmManagerService.class); // alarm watchdog.init(context, mActivityManagerService); inputManager = new InputManagerService(context); wm = WindowManagerService.main(...); inputManager.start(); mDisplayManagerService.windowManagerAndInputReady(); ... mSystemServiceManager.startService(MOUNT_SERVICE_CLASS); mPackageManagerService.performBootDexOpt(); ActivityManagerNative.getDefault().showBootMessage(...); ... statusBar = new StatusBarManagerService(context, wm); ServiceManager.addService(Context.DROPBOX_SERVICE, new DropBoxManagerService(context, new File("/data/system/dropbox" ))); mSystemServiceManager.startService(JobSchedulerService.class); //JobScheduler lockSettings.systemReady(); mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY); mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY); ... wm.systemReady(); mPowerManagerService.systemReady(...); mPackageManagerService.systemReady(); mDisplayManagerService.systemReady(...); mActivityManagerService.systemReady(new Runnable() { public void run () { ... } }); }
4.4.7、服务启动阶段 SystemServiceManager的startBootPhase()贯穿system_server进程的整个启动过程:
其中PHASE_BOOT_COMPLETED=1000,该阶段是发生在Boot完成和home应用启动完毕。系统服务更倾向于监听该阶段,而不是注册广播ACTION_BOOT_COMPLETED,从而降低系统延迟。
各个启动阶段所在源码的大致位置:
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 public final class SystemServer {private void startBootstrapServices () { ... mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); ... } private void startCoreServices () { ... } private void startOtherServices () { ... mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY); mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY); ... mActivityManagerService.systemReady(new Runnable() { public void run () { mSystemServiceManager.startBootPhase( SystemService.PHASE_ACTIVITY_MANAGER_READY); ... mSystemServiceManager.startBootPhase( SystemService.PHASE_THIRD_PARTY_APPS_CAN_START); } } } }
接下来再说说简单每个阶段的大概完成的工作:
4.4.7.1、Phase0 创建四大引导服务:
1 2 3 4 ActivityManagerService PowerManagerService LightsService DisplayManagerService
4.4.7.1.2、Phase100 进入阶段PHASE_WAIT_FOR_DEFAULT_DISPLAY=100回调服务
1 2 3 onBootPhase(100 ) DisplayManagerService
然后创建大量服务下面列举部分:
1 2 3 4 5 6 7 8 PackageManagerService WindowManagerService InputManagerService NetworkManagerService DropBoxManagerService FingerprintService LauncherAppsService …
4.4.7.1.3、Phase480 进入阶段PHASE_LOCK_SETTINGS_READY=480回调服务
1 2 3 onBootPhase(480 ) DevicePolicyManagerService
阶段480后马上就进入阶段500.
4.4.7.1.4、Phase500 PHASE_SYSTEM_SERVICES_READY=500,进入该阶段服务能安全地调用核心系统服务.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 onBootPhase(500 ) AlarmManagerService JobSchedulerService NotificationManagerService BackupManagerService UsageStatsService DeviceIdleController TrustManagerService UiModeManagerService BluetoothService BluetoothManagerService EthernetService WifiP2pService WifiScanningService WifiService RttService
各大服务执行systemReady():
1 2 3 4 WindowManagerService.systemReady(): PowerManagerService.systemReady(): PackageManagerService.systemReady(): DisplayManagerService.systemReady():
接下来就绪AMS.systemReady方法.
4.4.7.1.5、Phase550 PHASE_ACTIVITY_MANAGER_READY=550, AMS.mSystemReady=true, 已准备就绪,进入该阶段服务能广播Intent;但是system_server主线程并没有就绪.
1 2 3 4 5 6 7 8 onBootPhase(550 ) MountService TelecomLoaderService UsbService WebViewUpdateService DockObserver BatteryService
接下来执行: (AMS启动native crash监控, 加载WebView,启动SystemUI等),如下
1 2 3 4 5 6 7 8 9 10 mActivityManagerService.startObservingNativeCrashes(); WebViewFactory.prepareWebViewInSystemServer(); startSystemUi(context); networkScoreF.systemReady(); networkManagementF.systemReady(); networkStatsF.systemReady(); networkPolicyF.systemReady(); connectivityF.systemReady(); audioServiceF.systemReady(); Watchdog.getInstance().start();
4.4.7.1.6、Phase600 PHASE_THIRD_PARTY_APPS_CAN_START=600
onBootPhase(600)
JobSchedulerService NotificationManagerService BackupManagerService AppWidgetService GestureLauncherService DreamManagerService TrustManagerService VoiceInteractionManagerService
接下来,各种服务的systemRunning过程:
WallpaperManagerService、InputMethodManagerService、LocationManagerService、CountryDetectorService、NetworkTimeUpdateService、CommonTimeManagementService、TextServicesManagerService、AssetAtlasService、InputManagerService、TelephonyRegistry、MediaRouterService、MmsServiceBroker这些服务依次执行其systemRunning()方法。
4.4.7.1.7、Phase1000 在经过一系列流程,再调用AMS.finishBooting()时,则进入阶段Phase1000。
到此,系统服务启动阶段完成就绪,system_server进程启动完成则进入Looper.loop()状态,随时待命,等待消息队列MessageQueue中的消息到来,则马上进入执行状态。
4.4.8、服务类别 system_server进程,从源码角度划分为引导服务、核心服务、其他服务3类。 以下这些系统服务的注册过程, 见Android系统服务的注册方式
引导服务(7个):ActivityManagerService、PowerManagerService、LightsService、DisplayManagerService、PackageManagerService、UserManagerService、SensorService; 核心服务(3个):BatteryService、UsageStatsService、WebViewUpdateService; 其他服务(70个+):AlarmManagerService、VibratorService等。 合计总大约80个系统服务:
ActivityManagerService PackageManagerService WindowManagerService PowerManagerService BatteryService BatteryStatsService DreamManagerService DropBoxManagerService SamplingProfilerService UsageStatsService DiskStatsService DeviceStorageMonitorService SchedulingPolicyService AlarmManagerService DeviceIdleController ThermalObserver JobSchedulerService AccessibilityManagerService DisplayManagerService LightsService GraphicsStatsService StatusBarManagerService NotificationManagerService WallpaperManagerService UiModeManagerService AppWidgetService LauncherAppsService TextServicesManagerService ContentService LockSettingsService InputMethodManagerService InputManagerService MountService FingerprintService TvInputManagerService DockObserver NetworkManagementService NetworkScoreService NetworkStatsService NetworkPolicyManagerService ConnectivityService BluetoothService WifiP2pService WifiService WifiScanningService AudioService MediaRouterService VoiceInteractionManagerService MediaProjectionManagerService MediaSessionService DevicePolicyManagerService PrintManagerService BackupManagerService UserManagerService AccountManagerService TrustManagerService SensorService LocationManagerService VibratorService CountryDetectorService GestureLauncherService PersistentDataBlockService EthernetService WebViewUpdateService ClipboardService TelephonyRegistry TelecomLoaderService NsdService UpdateLockService SerialService SearchManagerService CommonTimeManagementService AssetAtlasService ConsumerIrService MidiServiceCameraService TwilightService RestrictionsManagerService MmsServiceBroker RttService UsbService
Service类别众多,其中表中加粗项是指博主挑选的较重要或者较常见的Service,并且在本博客中已经展开或者计划展开讲解的Service,当然如果有精力会讲解更多service,后续再更新。
(5)、启动ActivityManagerService 4.5.1、概述 ActivityManagerService(AMS)是Android中最核心的服务,主要负责系统中四大组件的启动、切换、调度及应用程序的管理和调度等工作。
AMS通信结构如下图所示:
4.5.2、SystemServer.startBootstrapServices() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 private void startBootstrapServices () {... mActivityManagerService = mSystemServiceManager.startService( ActivityManagerService.Lifecycle.class).getService(); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); mActivityManagerService.initPowerManagement(); ... mActivityManagerService.setSystemProcess(); }
4.5.3、启动AMS服务 SystemServiceManager.startService(ActivityManagerService.Lifecycle.class) 功能主要:
创建ActivityManagerService.Lifecycle对象; 调用Lifecycle.onStart()方法。
4.5.4、启动AMS服务 4.5.4.1 AMS.Lifecycle [-> ActivityManagerService.java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public static final class Lifecycle extends SystemService {private final ActivityManagerService mService;public Lifecycle (Context context) { super (context); mService = new ActivityManagerService(context); } @Override public void onStart () { mService.start(); } public ActivityManagerService getService () { return mService; } }
该过程:创建AMS内部类的Lifecycle,已经创建AMS对象,并调用AMS.start();
4.5.4.2 AMS创建
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 public ActivityManagerService (Context systemContext) {mContext = systemContext; mFactoryTest = FactoryTest.getMode(); mSystemThread = ActivityThread.currentActivityThread(); mHandlerThread = new ServiceThread(TAG, android.os.Process.THREAD_PRIORITY_FOREGROUND, false ); mHandlerThread.start(); mHandler = new MainHandler(mHandlerThread.getLooper()); mUiHandler = new UiHandler(); mFgBroadcastQueue = new BroadcastQueue(this , mHandler, "foreground" , BROADCAST_FG_TIMEOUT, false ); mBgBroadcastQueue = new BroadcastQueue(this , mHandler, "background" , BROADCAST_BG_TIMEOUT, true ); mBroadcastQueues[0 ] = mFgBroadcastQueue; mBroadcastQueues[1 ] = mBgBroadcastQueue; mServices = new ActiveServices(this ); mProviderMap = new ProviderMap(this ); File dataDir = Environment.getDataDirectory(); File systemDir = new File(dataDir, "system" ); systemDir.mkdirs(); mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); mBatteryStatsService.getActiveStatistics().readLocked(); ... mProcessStats = new ProcessStatsService(this , new File(systemDir, "procstats" )); mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml" ), mHandler); mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml" )); mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true )); mUserLru.add(UserHandle.USER_OWNER); updateStartedUserArrayLocked(); ... mProcessCpuTracker.init(); ... mRecentTasks = new RecentTasks(this ); mStackSupervisor = new ActivityStackSupervisor(this , mRecentTasks); mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks); mProcessCpuThread = new Thread("CpuTracker" ) { public void run () { while (true ) { try { try { synchronized (this ) { final long now = SystemClock.uptimeMillis(); long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; if (nextWriteDelay < nextCpuDelay) { nextCpuDelay = nextWriteDelay; } if (nextCpuDelay > 0 ) { mProcessCpuMutexFree.set(true ); this .wait(nextCpuDelay); } } } catch (InterruptedException e) { } updateCpuStatsNow(); } catch (Exception e) { } } } }; ... }
4.5.4.3、AMS的start函数
1 2 3 4 5 6 7 8 9 10 11 12 private void start () { Process.removeAllProcessGroups(); mProcessCpuThread.start(); mBatteryStatsService.publish(mContext); mAppOpsService.publish(mContext); Slog.d("AppOps" , "AppOpsService published" ); LocalServices.addService(ActivityManagerInternal.class, new LocalService());
AMS的start函数比较简单,主要是: 1、启动CPU监控线程。该线程将会开始统计不同进程使用CPU的情况。 2、发布一些服务,如BatteryStatsService、AppOpsService(权限管理相关)和本地实现的继承ActivityManagerInternal的服务。
4.5.5 AMS.setSystemProcess() 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 public void setSystemProcess () { try { ServiceManager.addService(Context.ACTIVITY_SERVICE, this , true ); ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); ServiceManager.addService("meminfo" , new MemBinder(this )); ServiceManager.addService("gfxinfo" , new GraphicsBinder(this )); ServiceManager.addService("dbinfo" , new DbBinder(this )); if (MONITOR_CPU_USAGE) { ServiceManager.addService("cpuinfo" , new CpuBinder(this )); } ServiceManager.addService("permission" , new PermissionController(this )); ServiceManager.addService("processinfo" , new ProcessInfoService(this )); ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( "android" , STOCK_PM_FLAGS); mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); synchronized (this ) { ProcessRecord app = newProcessRecordLocked(info, info.processName, false , 0 ); app.persistent = true ; app.pid = MY_PID; app.maxAdj = ProcessList.SYSTEM_ADJ; app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); synchronized (mPidsSelfLocked) { mPidsSelfLocked.put(app.pid, app); } updateLruProcessLocked(app, false , null ); updateOomAdjLocked(); } } catch (PackageManager.NameNotFoundException e) { throw new RuntimeException("" , e); } }
该方法主要工作是注册各种服务。
4.5.5.1 AT.installSystemApplicationInfo()
1 2 3 4 5 6 7 8 public void installSystemApplicationInfo (ApplicationInfo info, ClassLoader classLoader) { synchronized (this ) { getSystemContext().installSystemApplicationInfo(info, classLoader); mProfiler = new Profiler(); } }
该方法调用ContextImpl的nstallSystemApplicationInfo()方法,最终调用LoadedApk的installSystemApplicationInfo,加载名为”android”的package
4.5.5.2 installSystemApplicationInfo() [-> LoadedApk.java]
1 2 3 4 5 void installSystemApplicationInfo (ApplicationInfo info, ClassLoader classLoader) { assert info.packageName.equals("android" ); mApplicationInfo = info; mClassLoader = classLoader; }
4.5.6 startOtherServices() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 private void startOtherServices () { ... mActivityManagerService.installSystemProviders(); ... mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY); mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY); ... mActivityManagerService.systemReady(new Runnable() { public void run () { mSystemServiceManager.startBootPhase( SystemService.PHASE_ACTIVITY_MANAGER_READY); ... mSystemServiceManager.startBootPhase( SystemService.PHASE_THIRD_PARTY_APPS_CAN_START); ... } } }
4.5.6.1 AMS.installSystemProviders()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public final void installSystemProviders () { List<ProviderInfo> providers; synchronized (this ) { ProcessRecord app = mProcessNames.get("system" , Process.SYSTEM_UID); providers = generateApplicationProvidersLocked(app); if (providers != null ) { for (int i=providers.size()-1 ; i>=0 ; i--) { ProviderInfo pi = (ProviderInfo)providers.get(i); if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0 ) { providers.remove(i); } } } } if (providers != null ) { mSystemThread.installSystemProviders(providers); } mCoreSettingsObserver = new CoreSettingsObserver(this ); }
4.5.7、AMS.systemReady() 4.5.7.1、阶段一 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 public void systemReady (final Runnable goingCallback) { synchronized (this ) { .......... mUserController.onSystemReady(); mRecentTasks.onSystemReadyLocked(); mAppOpsService.systemReady(); mSystemReady = true ; } ArrayList<ProcessRecord> procsToKill = null ; synchronized (mPidsSelfLocked) { for (int i=mPidsSelfLocked.size()-1 ; i>=0 ; i--) { ProcessRecord proc = mPidsSelfLocked.valueAt(i); if (!isAllowedWhileBooting(proc.info)){ if (procsToKill == null ) { procsToKill = new ArrayList<ProcessRecord>(); } procsToKill.add(proc); } } } synchronized (this ) { if (procsToKill != null ) { for (int i=procsToKill.size()-1 ; i>=0 ; i--) { ProcessRecord proc = procsToKill.get(i); Slog.i(TAG, "Removing system update proc: " + proc); removeProcessLocked(proc, true , false , "system update done" ); } } mProcessesReady = true ; } ............ retrieveSettings(); final int currentUserId; synchronized (this ) { currentUserId = mUserController.getCurrentUserIdLocked(); readGrantedUriPermissionsLocked(); } ..........
这一部分的工作主要是调用一些关键服务的初始化函数, 然后杀死那些没有FLAG_PERSISTENT却在AMS启动完成前已经存在的进程, 同时获取一些配置参数。 需要注意的是,由于只有Java进程才会向AMS注册,而一般的Native进程不会向AMS注册,因此此处杀死的进程是Java进程。
4.5.7.2、阶段二 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 if (goingCallback != null ) goingCallback.run();.............. mSystemServiceManager.startUser(currentUserId); ............. synchronized (this ) { 2 、启动persistent为1 的application所在的进程 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE); mBooting = true ; if (UserManager.isSplitSystemUser()) { ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class); try { AppGlobals.getPackageManager().setComponentEnabledSetting(cName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0 , UserHandle.USER_SYSTEM); } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } } startHomeActivityLocked(currentUserId, "systemReady" ); try { if (AppGlobals.getPackageManager().hasSystemUidErrors()) { .......... mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget(); } } catch (RemoteException e) { } ............ mStackSupervisor.resumeFocusedStackTopActivityLocked(); ............ } .............
从部分代码来看,主要的工作就是通知一些服务可以进行systemReady相关的工作,并进行启动服务或应用进程的工作。
2.1、调用回调接口 回调接口的具体内容定义与SystemServer.java中,其中会调用大量服务的onBootPhase函数、一些对象的systemReady函数或systemRunning函数。 此处,我们仅截取一些比较特别的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public void run () { ............ try { mActivityManagerService.startObservingNativeCrashes(); } catch (Throwable e) { reportWtf("observing native crashes" , e); } ............ try { startSystemUi(context); } catch (Throwable e) { reportWtf("starting System UI" , e); } ............ Watchdog.getInstance().start(); .................... }
回调接口中的内容较多,不做一一分析。
2.2、启动persistent标志的进程 我们看看startPersistentApps对应的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 private void startPersistentApps (int matchFlags) { ............. synchronized (this ) { try { final List<ApplicationInfo> apps = AppGlobals.getPackageManager() .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList(); for (ApplicationInfo app : apps) { if (!"android" .equals(app.packageName)) { addAppLocked(app, false , null ); } } } catch (RemoteException ex) { } } }
跟进一下addAppLocked函数:
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 final ProcessRecord addAppLocked (ApplicationInfo info, boolean isolated, String abiOverride) { ProcessRecord app; if (!isolated) { app = getProcessRecordLocked(info.processName, info.uid, true ); } else { app = null ; } if (app == null ) { app = newProcessRecordLocked(info, null , isolated, 0 ); updateLruProcessLocked(app, false , null ); updateOomAdjLocked(); } ........... try { AppGlobals.getPackageManager().setPackageStoppedState( info.packageName, false , UserHandle.getUserId(app.uid)); } catch (RemoteException e) { } catch (IllegalArgumentException e) { Slog.w(TAG, "Failed trying to unstop package " + info.packageName + ": " + e); } if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) { app.persistent = true ; app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; } if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0 ) { mPersistentStartingProcesses.add(app); startProcessLocked(app, "added application" , app.processName, abiOverride, null , null ); } return app; }
这里最终将通过startProcessLocked函数,启动实际的应用进程。 正如之前分析zygote进程时,提过的一样,zygote中的server socket将接收消息,然后为应用fork出进程。
总结 对于整个AMS启动过程而言,博客中涉及的内容可能只是极小的一部分。 但即使我们尽可能的简化,整个过程的内容还是非常多。
不过我们回头看看整个过程,还是能比较清晰地将AMS的启动过程分为四步,如上图所示: 1、创建出SystemServer进程的Android运行环境。 在这一部分,SystemServer进程主要创建出对应的ActivityThread和ContextImpl,构成Android运行环境。 AMS的后续工作依赖于SystemServer在此创建出的运行环境。
2、完成AMS的初始化和启动。 在这一部分,单纯地调用AMS的构造函数和start函数,完成AMS的一些初始化工作。
3、将SystemServer进程纳入到AMS的管理体系中。 AMS作为Java世界的进程管理和调度中心,要对所有Java进程一视同仁,因此SystemServer进程也必须被AMS管理。 在这个过程中,AMS加载了SystemServer中framework-res.apk的信息,并启动和注册了SettingsProvider.apk。
4、开始执行AMS启动完毕后才能进行的工作。 系统中的一些服务和进程,必须等待AMS完成启动后,才能展开后续工作。 在这一部分,AMS通过调用systemReady函数,通知系统中的其它服务和进程,可以进行对应工作了。 在这个过程中,值得我们关注的是:Home Activity被启动了。当该Activity被加载完成后,最终会触发ACTION_BOOT_COMPLETED广播。
(6)、启动Launcher(Activity) 看看启动Home Activity对应的startHomeActivityLocked函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 boolean startHomeActivityLocked (int userId, String reason) { .............. Intent intent = getHomeIntent(); ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); if (aInfo != null ) { intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name)); aInfo = new ActivityInfo(aInfo); aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); ProcessRecord app = getProcessRecordLocked(aInfo.processName, aInfo.applicationInfo.uid, true ); if (app == null || app.instrumentationClass == null ) { intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); mActivityStarter.startHomeActivityLocked(intent, aInfo, reason); } } else { .......... } return true ; }
这里暂时先不深究Home Activity启动的具体过程。 从手头的资料来看,当Home Activity启动后, ActivityStackSupervisor中的activityIdleInternalLocked函数将被调用:
1 2 3 4 5 6 7 8 final ActivityRecord activityIdleInternalLocked (final IBinder token, boolean fromTimeout, Configuration config) { ........... if (isFocusedStack(r.task.stack) || fromTimeout) { booting = checkFinishBootingLocked(); } ............ }
在checkFinishBootingLocked函数中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 private boolean checkFinishBootingLocked () { final boolean booting = mService.mBooting; boolean enableScreen = false ; mService.mBooting = false ; if (!mService.mBooted) { mService.mBooted = true ; enableScreen = true ; } if (booting || enableScreen) {、 mService.postFinishBooting(booting, enableScreen); } return booting; }
最终,AMS的finishBooting函数将被调用:
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 final void finishBooting () { ......... IntentFilter pkgFilter = new IntentFilter(); pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); pkgFilter.addDataScheme("package" ); mContext.registerReceiver(new BroadcastReceiver() { @Override public void onReceive (Context context, Intent intent) { String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); if (pkgs != null ) { for (String pkg : pkgs) { synchronized (ActivityManagerService.this ) { if (forceStopPackageLocked(pkg, -1 , false , false , false , false , false , 0 , "query restart" )) { setResultCode(Activity.RESULT_OK); return ; } } } } } }, pkgFilter); ........... mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); synchronized (this ) { final int NP = mProcessesOnHold.size(); if (NP > 0 ) { ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mProcessesOnHold); for (int ip=0 ; ip<NP; ip++) { ................. startProcessLocked(procs.get(ip), "on-hold" , null ); } } } } .............. if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); SystemProperties.set("sys.boot_completed" , "1" ); ................. mUserController.sendBootCompletedLocked(.........); ................. } }
最终,当AMS启动Home Activity结束,并发送ACTION_BOOT_COMPLETED广播时,AMS的启动过程告一段落。
具体启动流程请参考:【Android 7.1.2 (Android N) Activity启动流程分析】
参考文档: Android 7.0 ActivityManagerService 1 - 10 Android Init进程源码分析(1) - jay_richard Android Init进程源码分析(2) - jay_richard Android Zygote进程分析 - jay_richard 图解Android - Zygote, System Server 启动分析 - 漫天尘沙 - 博客园 Android7.0 init进程源码分析 - ZhangJian的博客 - CSDN博客 Android系统启动-SystemServer上篇 - Gityuan博客 | 袁辉辉博客 Android系统启动-Init篇 - Gityuan博客 | 袁辉辉博客 Android系统启动-zygote篇 - Gityuan博客 | 袁辉辉博客 Android系统启动-SystemServer下篇 - Gityuan博客 | 袁辉辉博客 ActivityManagerService启动过程 - Gityuan博客 | 袁辉辉博客 Android Init进程源码分析 - 深入剖析Android系统 - CSDN博客