Android系统开机流程
注意:这篇文章是我直接从md文档复制过来的,所以有很多的符号存在
如果您要有更好的体验可以下载一个Typora,然后将文章复制过去看(强烈推荐这样做)
### Android系统开机流程
[TOC]
#### 一、开机流程
##### 1、启动init进程
###### 1.1 概述
init进程是Linux系统中用户空间的第一个进程,进程号为1。
当用户按下开机按钮,引导芯片加载BootLoader到内存中,开始拉起Linux OS,当kernel启动完毕后,在用户空间启动init进程,再通过init进程来读取`init. rc`中的相关配置,从而启动其他相关进程以及其他操作。
init进程启动胡政尧分为两个阶段:
1. 第一阶段:
- ueventd/watchdog的跳转及环境设置
- 挂载文件系统并创建目录
- 初始化日志输出、挂载分区设备
- 启用SELinux安全策略
- 开始第二阶段前的准备
2. 第二阶段:
- 初始化属性系统
- 执行SELinux第二阶段并恢复一些文件安全上下文
- 新建epoll并初始化子进程终止信号处理函数
- 设置其他系统属性并开启属性服务
###### 1.2 架构
- **init进程的启动**
```mermaid
graph LR
A[kernel_init] -->B[设置体系结构相关的环境]
A --> C[初始化内存结构]
A --> D[初始化设备和驱动等]
A --> E[开启MMU并建立页表]
A --> F[初始化串口]
A --> G[.........]
A --> O[启动init进程]
D --> P[do_basic_steup]
E --> I[numa_default_policy]
O --> II[run_init_process]
```
init 进程是在kernel启动后,启动的第一个用户空间进程,PID为1。
kernel_init启动后,完成一些init的初始化操作,然后去系统根目录下依次找ramdisk_execute_command和execute_command设置的应用程序,如果这两个目录都找不到,就依次去根目录下找 /sbin/init,/etc/init,/bin/init,/bin/sh 这四个应用程序进行启动,只要这些应用程序有一个启动了,其他就不启动了。
- **init启动后**
```mermaid
graph LR
A[mian函数] -->B[ueventd跳转]
A --> C[启动init进程第一阶段 加载文件系统 创建目录]
A --> D[日志初始化]
A --> E[启动SELinux服务]
A --> F[启动init进程第二阶段 启动属性服务 加载进程]
B --> BB[ueventd_main]
C --> CC[FirstStageMain]
D --> DD[InitLogging]
E --> EE[SetupSelinux]
F --> FF[SecondStageMain]
```
Init进程启动后,首先挂载文件系统、再挂载相应的分区,启动SELinux安全策略,启动属性服务,解析rc文件,并启动相应属性服务进程,初始化epoll,依次设置signal、property、keychord这3个fd可读时相对应的回调函数。进入无限循环,用来响应各个进程的变化与重建。
###### 1.3 kernel启动init进程的源码分析
**kernel_init:**
代码路径:kernel-4.9/init/main.c
```c
static int __ref kernel_init(void *unused)
{
kernel_init_freeable(); //进行init进程的一些初始化操作
/* need to finish all async __init code before freeing the memory */
async_synchronize_full();// 等待所有异步调用执行完成,,在释放内存前,必须完成所有的异步 _init代码
free_initmem();// 释放所有init.* 段中的内存
mark_readonly(); //修改页表,保证只读数据段为只读属性read only
system_state = SYSTEM_RUNNING;// 设置系统状态为运行状态
numa_default_policy(); // 设定NUMA作为系统的默认内存访问策略
if (ramdisk_execute_command) { //ramdisk_execute_command的值为"/init"
if (!run_init_process(ramdisk_execute_command)) //运行根目录下的init程序
return 0;
pr_err("Failed to execute %s\n", ramdisk_execute_command);
}
/*
* We try each of these until one succeeds.
*
* The Bourne shell can be used instead of init if we are
* trying to recover a really broken machine.
*/
if (execute_command) { //execute_command的值如果有定义就去根目录下找对应的应用程序,然后启动
if (!run_init_process(execute_command))
return 0;
pr_err("Failed to execute %s. Attempting defaults...\n",
execute_command);
}
if (!run_init_process("/sbin/init") || //如果ramdisk_execute_command和execute_command定义的应用程序都没有找到,
//就到根目录下找 /sbin/init,/etc/init,/bin/init,/bin/sh 这四个应用程序进行启动
!run_init_process("/etc/init") ||
!run_init_process("/bin/init") ||
!run_init_process("/bin/sh"))
return 0;
panic("No init found. Try passing init= option to kernel. "
"See Linux Documentation/init.txt for guidance.");
}
```
**do_basic_setup:**
代码路径:kernel-4.9/init/main.c
```c
static void __init do_basic_setup(void)
{
cpuset_init_smp();//针对SMP系统,初始化内核control group的cpuset子系统。
shmem_init();// 初始化共享内存
driver_init();// 初始化设备驱动
init_irq_proc();//创建/proc/irq目录, 并初始化系统中所有中断对应的子目录
do_ctors();// 执行内核的构造函数
usermodehelper_enable();// 启用usermodehelper
do_initcalls();//遍历initcall_levels数组,调用里面的initcall函数,这里主要是对设备、驱动、文件系统进行初始化,
//之所以将函数封装到数组进行遍历,主要是为了好扩展
}
```
**init进程入口**
代码路径:system/core/init/main.cpp
* ```c
/*
* 1.第一个参数argc表示参数个数,第二个参数是参数列表,也就是具体的参数
* 2.main函数有四个参数入口,
*一是参数中有ueventd,进入ueventd_main
*二是参数中有subcontext,进入InitLogging 和SubcontextMain
*三是参数中有selinux_setup,进入SetupSelinux
*四是参数中有second_stage,进入SecondStageMain
* 3.main的执行顺序如下:
* (1)ueventd_main init进程创建子进程ueventd,
* 并将创建设备节点文件的工作托付给ueventd,ueventd通过两种方式创建设备节点文件
* (2)FirstStageMain 启动第一阶段
* (3)SetupSelinux 加载selinux规则,并设置selinux日志,完成SELinux相关工作
* (4)SecondStageMain 启动第二阶段
*/
int main(int argc, char** argv) {
//当argv[0]的内容为ueventd时,strcmp的值为0,!strcmp为1
//1表示true,也就执行ueventd_main,ueventd主要是负责设备节点的创建、权限设定等一些列工作
if (!strcmp(basename(argv[0]), "ueventd")) {
return ueventd_main(argc, argv);
}
//当传入的参数个数大于1时,执行下面的几个操作
if (argc > 1) {
//参数为subcontext,初始化日志系统,
if (!strcmp(argv[1], "subcontext")) {
android::base::InitLogging(argv, &android::base::KernelLogger);
const BuiltinFunctionMap function_map;
return SubcontextMain(argc, argv, &function_map);
}
//参数为“selinux_setup”,启动Selinux安全策略
if (!strcmp(argv[1], "selinux_setup")) {
return SetupSelinux(argv);
}
//参数为“second_stage”,启动init进程第二阶段
if (!strcmp(argv[1], "second_stage")) {
return SecondStageMain(argc, argv);
}
}
// 默认启动init进程第一阶段
return FirstStageMain(argc, argv);
}
```
**ueventd_main**
代码路径:system/core/init/ueventd.cpp
Android根文件系统的镜像中不存在“/dev”目录,该目录是init进程启动后动态创建的。
因此,建立Android中设备节点文件的重任,也落在了init进程身上。为此,init进程创建子进程ueventd,并将创建设备节点文件的工作托付给ueventd。
ueventd通过两种方式创建设备节点文件。
第一种方式对应“冷插拔”(Cold Plug),即以预先定义的设备信息为基础,当ueventd启动后,统一创建设备节点文件。这一类设备节点文件也被称为静态节点文件。
第二种方式对应“热插拔”(Hot Plug),即在系统运行中,当有设备插入USB端口时,ueventd就会接收到这一事件,为插入的设备动态创建设备节点文件。这一类设备节点文件也被称为动态节点文件。
```cpp
int ueventd_main(int argc, char** argv) {
//设置新建文件的默认值,这个与chmod相反,这里相当于新建文件后的权限为666
umask(000);
//初始化内核日志,位于节点/dev/kmsg, 此时logd、logcat进程还没有起来,
//采用kernel的log系统,打开的设备节点/dev/kmsg, 那么可通过cat /dev/kmsg来获取内核log。
android::base::InitLogging(argv, &android::base::KernelLogger);
//注册selinux相关的用于打印log的回调函数
SelinuxSetupKernelLogging();
SelabelInitialize();
//解析xml,根据不同SOC厂商获取不同的hardware rc文件
auto ueventd_configuration = ParseConfig({"/ueventd.rc", "/vendor/ueventd.rc",
"/odm/ueventd.rc", "/ueventd." + hardware + ".rc"});
//冷启动
if (access(COLDBOOT_DONE, F_OK) != 0) {
ColdBoot cold_boot(uevent_listener, uevent_handlers);
cold_boot.Run();
}
for (auto& uevent_handler : uevent_handlers) {
uevent_handler->ColdbootDone();
}
//忽略子进程终止信号
signal(SIGCHLD, SIG_IGN);
// Reap and pending children that exited between the last call to waitpid() and setting SIG_IGN
// for SIGCHLD above.
//在最后一次调用waitpid()和为上面的sigchld设置SIG_IGN之间退出的获取和挂起的子级
while (waitpid(-1, nullptr, WNOHANG) > 0) {
}
//监听来自驱动的uevent,进行“热插拔”处理
uevent_listener.Poll([&uevent_handlers](const Uevent& uevent) {
for (auto& uevent_handler : uevent_handlers) {
uevent_handler->HandleUevent(uevent); //热启动,创建设备
}
return ListenerAction::kContinue;
});
return 0;
}
```
###### 1.4 init进程启动第一阶段
代码地址:system/core/init/first_stage_init.cpp
init进程第一阶段做的主要工作是挂载分区,创建设备节点和一些关键目录,初始化日志输出系统,启用SELinux安全策略
第一阶段完成以下内容:
/* 01. 创建文件系统目录并挂载相关的文件系统 */
/* 02. 屏蔽标准的输入输出/初始化内核log系统 */
**FirstStageMain**
代码地址:system/core/init/first_stage_init.cpp
```c
int FirstStageMain(int argc, char** argv) {
//init crash时重启引导加载程序
//这个函数主要作用将各种信号量,如SIGABRT,SIGBUS等的行为设置为SA_RESTART,一旦监听到这些信号即执行重启系统
if (REBOOT_BOOTLOADER_ON_PANIC) {
InstallRebootSignalHandlers();
}
//清空文件权限
umask(0);
CHECKCALL(clearenv());
CHECKCALL(setenv("PATH", _PATH_DEFPATH, 1));
//在RAM内存上获取基本的文件系统,剩余的被rc文件所用
CHECKCALL(mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"));
CHECKCALL(mkdir("/dev/pts", 0755));
CHECKCALL(mkdir("/dev/socket", 0755));
CHECKCALL(mount("devpts", "/dev/pts", "devpts", 0, NULL));
#define MAKE_STR(x) __STRING(x)
CHECKCALL(mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC)));
#undef MAKE_STR
// 非特权应用不能使用Andrlid cmdline
CHECKCALL(chmod("/proc/cmdline", 0440));
gid_t groups[] = {AID_READPROC};
CHECKCALL(setgroups(arraysize(groups), groups));
CHECKCALL(mount("sysfs", "/sys", "sysfs", 0, NULL));
CHECKCALL(mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL));
CHECKCALL(mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11)));
if constexpr (WORLD_WRITABLE_KMSG) {
CHECKCALL(mknod("/dev/kmsg_debug", S_IFCHR | 0622, makedev(1, 11)));
}
CHECKCALL(mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8)));
CHECKCALL(mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9)));
//这对于日志包装器是必需的,它在ueventd运行之前被调用
CHECKCALL(mknod("/dev/ptmx", S_IFCHR | 0666, makedev(5, 2)));
CHECKCALL(mknod("/dev/null", S_IFCHR | 0666, makedev(1, 3)));
//在第一阶段挂在tmpfs、mnt/vendor、mount/product分区。其他的分区不需要在第一阶段加载,
//只需要在第二阶段通过rc文件解析来加载。
CHECKCALL(mount("tmpfs", "/mnt", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
"mode=0755,uid=0,gid=1000"));
//创建可供读写的vendor目录
CHECKCALL(mkdir("/mnt/vendor", 0755));
// /mnt/product is used to mount product-specific partitions that can not be
// part of the product partition, e.g. because they are mounted read-write.
CHECKCALL(mkdir("/mnt/product", 0755));
// 挂载APEX,这在Android 10.0中特殊引入,用来解决碎片化问题,类似一种组件方式,对Treble的增强,
// 不写谷歌特殊更新不需要完整升级整个系统版本,只需要像升级APK一样,进行APEX组件升级
CHECKCALL(mount("tmpfs", "/apex", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
"mode=0755,uid=0,gid=0"));
// /debug_ramdisk is used to preserve additional files from the debug ramdisk
CHECKCALL(mount("tmpfs", "/debug_ramdisk", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
"mode=0755,uid=0,gid=0"));
#undef CHECKCALL
//把标准输入、标准输出和标准错误重定向到空设备文件"/dev/null"
SetStdioToDevNull(argv);
//在/dev目录下挂载好 tmpfs 以及 kmsg
//这样就可以初始化 /kernel Log 系统,供用户打印log
InitKernelLogging(argv);
...
/* 初始化一些必须的分区
*主要作用是去解析/proc/device-tree/firmware/android/fstab,
* 然后得到"/system", "/vendor", "/odm"三个目录的挂载信息
*/
if (!DoFirstStageMount()) {
LOG(FATAL) << "Failed to mount required partitions early ...";
}
struct stat new_root_info;
if (stat("/", &new_root_info) != 0) {
PLOG(ERROR) << "Could not stat(\"/\"), not freeing ramdisk";
old_root_dir.reset();
}
if (old_root_dir && old_root_info.st_dev != new_root_info.st_dev) {
FreeRamdisk(old_root_dir.get(), old_root_info.st_dev);
}
SetInitAvbVersionInRecovery();
static constexpr uint32_t kNanosecondsPerMillisecond = 1e6;
uint64_t start_ms = start_time.time_since_epoch().count() / kNanosecondsPerMillisecond;
setenv("INIT_STARTED_AT", std::to_string(start_ms).c_str(), 1);
//启动init进程,传入参数selinux_steup
// 执行命令: /system/bin/init selinux_setup
const char* path = "/system/bin/init";
const char* args[] = {path, "selinux_setup", nullptr};
execv(path, const_cast<char**>(args));
PLOG(FATAL) << "execv(\"" << path << "\") failed";
return 1;
}
```
**加载SELinux规则**
SELinux是「Security-Enhanced Linux」的简称,是美国国家安全局「NSA=The National Security Agency」
和SCC(Secure Computing Corporation)开发的 Linux的一个扩张强制访问控制安全模块。
在这种访问控制体系的限制下,进程只能访问那些在他的任务中所需要文件。
selinux有两种工作模式:
permissive,所有的操作都被允许(即没有MAC),但是如果违反权限的话,会记录日志,一般eng模式用
enforcing,所有操作都会进行权限检查。一般user和user-debug模式用
不管是security_setenforce还是security_getenforce都是去操作/sys/fs/selinux/enforce 文件, 0表示permissive 1表示enforcing
**SetupSelinux**
初始化selinux,加载SELinux规则,配置SELinux相关log输出,并启动第二阶段
代码路径:system\core\init\selinux.cpp
```c
/*此函数初始化selinux,然后执行init以在init selinux中运行*/
int SetupSelinux(char** argv) {
//初始化Kernel日志
InitKernelLogging(argv);
// Debug版本init crash时重启引导加载程序
if (REBOOT_BOOTLOADER_ON_PANIC) {
InstallRebootSignalHandlers();
}
//注册回调,用来设置需要写入kmsg的selinux日志
SelinuxSetupKernelLogging();
//加载SELinux规则
SelinuxInitialize();
/*
*我们在内核域中,希望转换到init域。在其xattrs中存储selabel的文件系统(如ext4)不需要显式restorecon,
*但其他文件系统需要。尤其是对于ramdisk,如对于a/b设备的恢复映像,这是必需要做的一步。
*其实就是当前在内核域中,在加载Seliux后,需要重新执行init切换到C空间的用户态
*/
if (selinux_android_restorecon("/system/bin/init", 0) == -1) {
PLOG(FATAL) << "restorecon failed of /system/bin/init failed";
}
//准备启动innit进程,传入参数second_stage
//执行 /system/bin/init second_stage, 进入第二阶段
const char* path = "/system/bin/init";
const char* args[] = {path, "second_stage", nullptr};
execv(path, const_cast<char**>(args));
PLOG(FATAL) << "execv(\"" << path << "\") failed";
return 1;
}
```
**SelinuxInitialize()**
```c
/*加载selinux 规则*/
void SelinuxInitialize() {
LOG(INFO) << "Loading SELinux policy";
if (!LoadPolicy()) {
LOG(FATAL) << "Unable to load SELinux policy";
}
//获取当前Kernel的工作模式
bool kernel_enforcing = (security_getenforce() == 1);
//获取工作模式的配置
bool is_enforcing = IsEnforcing();
//如果当前的工作模式与配置的不同,就将当前的工作模式改掉
if (kernel_enforcing != is_enforcing) {
if (security_setenforce(is_enforcing)) {
PLOG(FATAL) << "security_setenforce(" << (is_enforcing ? "true" : "false")
<< ") failed";
}
}
if (auto result = WriteFile("/sys/fs/selinux/checkreqprot", "0"); !result) {
LOG(FATAL) << "Unable to write to /sys/fs/selinux/checkreqprot: " << result.error();
}
}
```
```c
/*
*加载SELinux规则
*这里区分了两种情况,这两种情况只是区分从哪里加载安全策略文件,
*第一个是从 /vendor/etc/selinux/precompiled_sepolicy 读取,
*第二个是从 /sepolicy 读取,他们最终都是调用selinux_android_load_policy_from_fd方法
*/
bool LoadPolicy() {
return IsSplitPolicyDevice() ? LoadSplitPolicy() : LoadMonolithicPolicy();
}
```
###### 1.5 init进程启动第二阶段
第二阶段主要内容:
- 创建进程会话密钥并初始化属性系统
- 进行SELinux第二阶段并恢复一些文件安全上下文
- 新建epoll并初始化子进程终止信号处理函数
- 启动匹配属性的服务端
- 解析init.rc等文件,建立rc文件的action 、service,启动其他进程
```mermaid
graph LR
A[SecondStageMain] -->B[创建进程会话并初始化属性系统]
A --> C[进行SELinux第二阶段并恢复一些文件安全上下文]
A --> D[新建epoll并初始化子进程 终止信号处理函数]
A --> E[设置其他系统属性并开启系统属性服务]
A --> F[解析init.rc等文件,建立rc文件的action和service,启动其他进程]
B --> BB[keyctl_get_keyring_ID和property_init]
C --> CC[SelinuxRestoreContext]
D --> DD[InstallSignalFdHandler]
E --> EE[StartProperService]
F --> FF[LoadBootScripts]
```
**SecondStageMain**
代码地址:system/core/init/init.cpp
```c
int SecondStageMain(int argc, char** argv) {
/* 01. 创建进程会话密钥并初始化属性系统 */
keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 1);
//创建 /dev/.booting 文件,就是个标记,表示booting进行中
close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));
// 初始化属性系统,并从指定文件读取属性
property_init();
/* 02. 进行SELinux第二阶段并恢复一些文件安全上下文 */
SelinuxRestoreContext();
/* 03. 新建epoll并初始化子进程终止信号处理函数 */
Epoll epoll;
if (auto result = epoll.Open(); !result) {
PLOG(FATAL) << result.error();
}
InstallSignalFdHandler(&epoll);
/* 04. 设置其他系统属性并开启系统属性服务*/
StartPropertyService(&epoll);
/* 05 解析init.rc等文件,建立rc文件的action 、service,启动其他进程*/
ActionManager& am = ActionManager::GetInstance();
ServiceList& sm = ServiceList::GetInstance();
LoadBootScripts(am, sm);
}
```
代码详解:
```c
int SecondStageMain(int argc, char** argv) {
/*
*init crash时重启引导加载程序
*这个函数主要作用将各种信号量,如SIGABRT,SIGBUS等的行为设置为SA_RESTART,一旦监听到这些信号即执行重启系统
*/
if (REBOOT_BOOTLOADER_ON_PANIC) {
InstallRebootSignalHandlers();
}
//把标准输入、标准输出和标准错误重定向到空设备文件"/dev/null"
SetStdioToDevNull(argv);
//在/dev目录下挂载好 tmpfs 以及 kmsg
//这样就可以初始化 /kernel Log 系统,供用户打印log
InitKernelLogging(argv);
LOG(INFO) << "init second stage started!";
// 01. 创建进程会话密钥并初始化属性系统
keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 1);
//创建 /dev/.booting 文件,就是个标记,表示booting进行中
close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));
// 初始化属性系统,并从指定文件读取属性
property_init();
/*
* 1.如果参数同时从命令行和DT传过来,DT的优先级总是大于命令行的
* 2.DT即device-tree,中文意思是设备树,这里面记录自己的硬件配置和系统运行参数,
*/
process_kernel_dt(); // 处理 DT属性
process_kernel_cmdline(); // 处理命令行属性
// 处理一些其他的属性
export_kernel_boot_props();
// Make the time that init started available for bootstat to log.
property_set("ro.boottime.init", getenv("INIT_STARTED_AT"));
property_set("ro.boottime.init.selinux", getenv("INIT_SELINUX_TOOK"));
// Set libavb version for Framework-only OTA match in Treble build.
const char* avb_version = getenv("INIT_AVB_VERSION");
if (avb_version) property_set("ro.boot.avb_version", avb_version);
// See if need to load debug props to allow adb root, when the device is unlocked.
const char* force_debuggable_env = getenv("INIT_FORCE_DEBUGGABLE");
if (force_debuggable_env && AvbHandle::IsDeviceUnlocked()) {
load_debug_prop = "true"s == force_debuggable_env;
}
// 基于cmdline设置memcg属性
bool memcg_enabled = android::base::GetBoolProperty("ro.boot.memcg",false);
if (memcg_enabled) {
// root memory control cgroup
mkdir("/dev/memcg", 0700);
chown("/dev/memcg",AID_ROOT,AID_SYSTEM);
mount("none", "/dev/memcg", "cgroup", 0, "memory");
// app mem cgroups, used by activity manager, lmkd and zygote
mkdir("/dev/memcg/apps/",0755);
chown("/dev/memcg/apps/",AID_SYSTEM,AID_SYSTEM);
mkdir("/dev/memcg/system",0550);
chown("/dev/memcg/system",AID_SYSTEM,AID_SYSTEM);
}
// 清空这些环境变量,之前已经存到了系统属性中去了
unsetenv("INIT_STARTED_AT");
unsetenv("INIT_SELINUX_TOOK");
unsetenv("INIT_AVB_VERSION");
unsetenv("INIT_FORCE_DEBUGGABLE");
// Now set up SELinux for second stage.
SelinuxSetupKernelLogging();
SelabelInitialize();
/*
* 02. 进行SELinux第二阶段并恢复一些文件安全上下文
* 恢复相关文件的安全上下文,因为这些文件是在SELinux安全机制初始化前创建的,
* 所以需要重新恢复上下文
*/
SelinuxRestoreContext();
/*
* 03. 新建epoll并初始化子进程终止信号处理函数
* 创建epoll实例,并返回epoll的文件描述符
*/
Epoll epoll;
if (auto result = epoll.Open(); !result) {
PLOG(FATAL) << result.error();
}
/*
*主要是创建handler处理子进程终止信号,注册一个signal到epoll进行监听
*进行子继承处理
*/
InstallSignalFdHandler(&epoll);
// 进行默认属性配置相关的工作
property_load_boot_defaults(load_debug_prop);
UmountDebugRamdisk();
fs_mgr_vendor_overlay_mount_all();
export_oem_lock_status();
/*
*04. 设置其他系统属性并开启系统属性服务
*/
StartPropertyService(&epoll);
MountHandler mount_handler(&epoll);
//为USB存储设置udc Contorller, sys/class/udc
set_usb_controller();
// 匹配命令和函数之间的对应关系
const BuiltinFunctionMap function_map;
Action::set_function_map(&function_map);
if (!SetupMountNamespaces()) {
PLOG(FATAL) << "SetupMountNamespaces failed";
}
// 初始化文件上下文
subcontexts = InitializeSubcontexts();
/*
*05 解析init.rc等文件,建立rc文件的action 、service,启动其他进程
*/
ActionManager& am = ActionManager::GetInstance();
ServiceList& sm = ServiceList::GetInstance();
LoadBootScripts(am, sm);
// Turning this on and letting the INFO logging be discarded adds 0.2s to
// Nexus 9 boot time, so it's disabled by default.
if (false) DumpState();
// 当GSI脚本running时,确保GSI状态可用.
if (android::gsi::IsGsiRunning()) {
property_set("ro.gsid.image_running", "1");
} else {
property_set("ro.gsid.image_running", "0");
}
am.QueueBuiltinAction(SetupCgroupsAction, "SetupCgroups");
// 执行rc文件中触发器为 on early-init 的语句
am.QueueEventTrigger("early-init");
// 等冷插拔设备初始化完成
am.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done");
// 开始查询来自 /dev的 action
am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng");
am.QueueBuiltinAction(SetMmapRndBitsAction, "SetMmapRndBits");
am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict");
// 设备组合键的初始化操作
Keychords keychords;
am.QueueBuiltinAction(
[&epoll, &keychords](const BuiltinArguments& args) -> Result<Success> {
for (const auto& svc : ServiceList::GetInstance()) {
keychords.Register(svc->keycodes());
}
keychords.Start(&epoll, HandleKeychord);
return Success();
},
"KeychordInit");
//在屏幕上显示Android 静态LOGO
am.QueueBuiltinAction(console_init_action, "console_init");
// 执行rc文件中触发器为on init的语句
am.QueueEventTrigger("init");
// Starting the BoringSSL self test, for NIAP certification compliance.
am.QueueBuiltinAction(StartBoringSslSelfTest, "StartBoringSslSelfTest");
// Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random
// wasn't ready immediately after wait_for_coldboot_done
am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng");
// Initialize binder before bringing up other system services
am.QueueBuiltinAction(InitBinder, "InitBinder");
// 当设备处于充电模式时,不需要mount文件系统或者启动系统服务
// 充电模式下,将charger假如执行队列,否则把late-init假如执行队列
std::string bootmode = GetProperty("ro.bootmode", "");
if (bootmode == "charger") {
am.QueueEventTrigger("charger");
} else {
am.QueueEventTrigger("late-init");
}
// 基于属性当前状态 运行所有的属性触发器.
am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers");
while (true) {
// By default, sleep until something happens.
auto epoll_timeout = std::optional<std::chrono::milliseconds>{};
if (do_shutdown && !shutting_down) {
do_shutdown = false;
if (HandlePowerctlMessage(shutdown_command)) {
shutting_down = true;
}
}
//依次执行每个action中携带command对应的执行函数
if (!(waiting_for_prop || Service::is_exec_service_running())) {
am.ExecuteOneCommand();
}
if (!(waiting_for_prop || Service::is_exec_service_running())) {
if (!shutting_down) {
auto next_process_action_time = HandleProcessActions();
// If there's a process that needs restarting, wake up in time for that.
if (next_process_action_time) {
epoll_timeout = std::chrono::ceil<std::chrono::milliseconds>(
*next_process_action_time - boot_clock::now());
if (*epoll_timeout < 0ms) epoll_timeout = 0ms;
}
}
// If there's more work to do, wake up again immediately.
if (am.HasMoreCommands()) epoll_timeout = 0ms;
}
// 循环等待事件发生
if (auto result = epoll.Wait(epoll_timeout); !result) {
LOG(ERROR) << result.error();
}
}
return 0;
}
```
**信号处理**
init是一个守护进程,为了防止init的子进程成为僵尸进程(zombie process),需要init在子进程在结束时获取子进程的结束码,通过结束码将程序表中的子进程移除,防止成为僵尸进程的子进程占用程序表的空间(程序表的空间达到上限时,系统就不能再启动新的进程了,会引起严重的系统问题)。
**子进程重启流程:**
```mermaid
graph LR
A[fork子进程] -.->B[终止子线程]
B --产生SIGHLD信号-->C[Init进程]
C --service_start-->A
C -->D{oneshot}
D --Y-->E[放弃启动]
D --N-->F[重启子线程]
```
**信号处理主要工作:**
- 初始化信号signal句柄
- 循环处理子进程
- 注册epoll句柄
- 处理子进程终止
**InstallSignalFdHandler**
在linux当中,父进程是通过捕捉SIGCHLD信号来得知子进程运行结束的情况,SIGCHLD信号会在子进程终止的时候发出。
- 首先,新建一个sigaction结构体,sa_handler是信号处理函数,指向内核指定的函数指针SIG_DFL和Android 9.0及之前的版本不同,这里不再通过socket的读写句柄进行接收信号,改成了内核的信号处理函数SIG_DFL。
- 然后,sigaction(SIGCHLD, &act, nullptr) 这个是建立信号绑定关系,也就是说当监听到SIGCHLD信号时,由act这个sigaction结构体处理
- 最后,RegisterHandler 的作用就是signal_read_fd(之前的s[1])收到信号,触发handle_signal
综上,InstallSignalFdHandler函数的作用就是,接收到SIGCHLD信号时触发HandleSignalFd进行信号处理
**信号处理:**
```mermaid
graph LR
A[终止子进程] --产生SIGCHLD信号-->B[SIG_DFL]
B -->C[signal_fd]
C -->D[epoll_fd]
D -->E[HandleSignalFd]
E -->F[ReapOneProcess]
F -->G[决定是否重启子线程]
```
代码路径:system/core/init/init.cpp
该函数主要的作用是初始化子进程终止信号处理过程
```c
static void InstallSignalFdHandler(Epoll* epoll) {
// SA_NOCLDSTOP使init进程只有在其子进程终止时才会收到SIGCHLD信号
const struct sigaction act { .sa_handler = SIG_DFL, .sa_flags = SA_NOCLDSTOP };
sigaction(SIGCHLD, &act, nullptr);
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask, SIGCHLD);
if (!IsRebootCapable()) {
// 如果init不具有 CAP_SYS_BOOT的能力,则它此时正值容器中运行
// 在这种场景下,接收SIGTERM 将会导致系统关闭
sigaddset(&mask, SIGTERM);
}
if (sigprocmask(SIG_BLOCK, &mask, nullptr) == -1) {
PLOG(FATAL) << "failed to block signals";
}
// 注册处理程序以解除对子进程中的信号的阻止
const int result = pthread_atfork(nullptr, nullptr, &UnblockSignals);
if (result != 0) {
LOG(FATAL) << "Failed to register a fork handler: " << strerror(result);
}
//创建信号句柄
signal_fd = signalfd(-1, &mask, SFD_CLOEXEC);
if (signal_fd == -1) {
PLOG(FATAL) << "failed to create signalfd";
}
//信号注册,当signal_fd收到信号时,触发HandleSignalFd
if (auto result = epoll->RegisterHandler(signal_fd, HandleSignalFd); !result) {
LOG(FATAL) << result.error();
}
}
```
**RegistHandler**
代码路径:system/core/init/epoll.cpp
信号注册,把fd句柄加入到 epoll_fd_的监听队列中
```c
Result<void> Epoll::RegisterHandler(int fd, std::function<void()> handler, uint32_t events) {
if (!events) {
return Error() << "Must specify events";
}
auto [it, inserted] = epoll_handlers_.emplace(fd, std::move(handler));
if (!inserted) {
return Error() << "Cannot specify two epoll handlers for a given FD";
}
epoll_event ev;
ev.events = events;
// std::map's iterators do not get invalidated until erased, so we use the
// pointer to the std::function in the map directly for epoll_ctl.
ev.data.ptr = reinterpret_cast<void*>(&it->second);
// 将fd的可读事件加入到epoll_fd_的监听队列中
if (epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, fd, &ev) == -1) {
Result<void> result = ErrnoError() << "epoll_ctl failed to add fd";
epoll_handlers_.erase(fd);
return result;
}
return {};
}
```
**HandleSignalFd**
代码路径:system/core/init/init.cpp
监控SIGCHLD信号,调用 ReapAnyOutstandingChildren 来 终止出现问题的子进程。
```c
static void HandleSignalFd() {
signalfd_siginfo siginfo;
ssize_t bytes_read = TEMP_FAILURE_RETRY(read(signal_fd, &siginfo, sizeof(siginfo)));
if (bytes_read != sizeof(siginfo)) {
PLOG(ERROR) << "Failed to read siginfo from signal_fd";
return;
}
//监控SIGCHLD信号
switch (siginfo.ssi_signo) {
case SIGCHLD:
ReapAnyOutstandingChildren();
break;
case SIGTERM:
HandleSigtermSignal(siginfo);
break;
default:
PLOG(ERROR) << "signal_fd: received unexpected signal " << siginfo.ssi_signo;
break;
}
}
```
**ReapOneProcess**
代码路径:system/core/init/sigchld_handler.cpp
ReapOneProcess是最终的处理函数了,这个函数先用waitpid找出挂掉进程的pid,然后根据pid找到对应Service,
最后调用Service的Reap方法清除资源,根据进程对应的类型,决定是否重启机器或重启进程
```c
void ReapAnyOutstandingChildren() {
while (ReapOneProcess()) {
}
}
static bool ReapOneProcess() {
siginfo_t siginfo = {};
//用waitpid函数获取状态发生变化的子进程pid
//waitpid的标记为WNOHANG,即非阻塞,返回为正值就说明有进程挂掉了
if (TEMP_FAILURE_RETRY(waitid(P_ALL, 0, &siginfo, WEXITED | WNOHANG | WNOWAIT)) != 0) {
PLOG(ERROR) << "waitid failed";
return false;
}
auto pid = siginfo.si_pid;
if (pid == 0) return false;
// 当我们知道当前有一个僵尸pid,我们使用scopeguard来清楚该pid
auto reaper = make_scope_guard([pid] { TEMP_FAILURE_RETRY(waitpid(pid, nullptr, WNOHANG)); });
std::string name;
std::string wait_string;
Service* service = nullptr;
if (SubcontextChildReap(pid)) {
name = "Subcontext";
} else {
//通过pid找到对应的service
service = ServiceList::GetInstance().FindService(pid, &Service::pid);
if (service) {
name = StringPrintf("Service '%s' (pid %d)", service->name().c_str(), pid);
if (service->flags() & SVC_EXEC) {
auto exec_duration = boot_clock::now() - service->time_started();
auto exec_duration_ms =
std::chrono::duration_cast<std::chrono::milliseconds>(exec_duration).count();
wait_string = StringPrintf(" waiting took %f seconds", exec_duration_ms / 1000.0f);
} else if (service->flags() & SVC_ONESHOT) {
auto exec_duration = boot_clock::now() - service->time_started();
auto exec_duration_ms =
std::chrono::duration_cast<std::chrono::milliseconds>(exec_duration)
.count();
wait_string = StringPrintf(" oneshot service took %f seconds in background",exec_duration_ms / 1000.0f);
}
} else {
name = StringPrintf("Untracked pid %d", pid);
}
}
if (siginfo.si_code == CLD_EXITED) {
LOG(INFO) << name << " exited with status " << siginfo.si_status << wait_string;
} else {
LOG(INFO) << name << " received signal " << siginfo.si_status << wait_string;
}
//没有找到service,说明已经结束了,退出
if (!service) return true;
service->Reap(siginfo);//清除子进程相关的资源
if (service->flags() & SVC_TEMPORARY) {
ServiceList::GetInstance().RemoveService(*service); //移除该service
}
return true;
}
```
###### 1.6 属性服务
不是所有进程都可以随意修改任何的系统属性,Android将属性的设置统一交由init进程管理,其他进程不能直接修改属性,而只能通知init进程来修改,而在这过程中,init进程可以进行权限控制,具体的流程如下:
**property_init**
代码路径:system/core/init/property_service.cpp
作用:
- 初始化属性系统,并从指定文件读取属性,并进行SELinux注册,进行属性权限控制
- 清除缓存,这里主要是清除几个链表以及在内存中的映射,新建property_filename目录,这个目录的值为 /dev/_properties_
- 然后就是调用CreateSerializedPropertyInfo加载一些系统属性的类别信息,最后将加载的链表写入文件并映射到内存
```c
void property_init() {
//设置SELinux回调,进行权限控制
selinux_callback cb;
cb.func_audit = PropertyAuditCallback;
selinux_set_callback(SELINUX_CB_AUDIT, cb);
mkdir("/dev/__properties__", S_IRWXU | S_IXGRP | S_IXOTH);
CreateSerializedPropertyInfo();
if (__system_property_area_init()) {
LOG(FATAL) << "Failed to initialize property area";
}
if (!property_info_area.LoadDefaultPath()) {
LOG(FATAL) << "Failed to load serialized property info file";
}
}
```
**通过CreateSerializedPropertyInfo 来加载以下目录的contexts**:
**1)与SELinux相关**
```
/system/etc/selinux/plat_property_contexts
/vendor/etc/selinux/vendor_property_contexts
/vendor/etc/selinux/nonplat_property_contexts
/product/etc/selinux/product_property_contexts
/odm/etc/selinux/odm_property_contexts
```
**2)与SELinux无关**
```
/plat_property_contexts
/vendor_property_contexts
/nonplat_property_contexts
/product_property_contexts
/odm_property_contexts
```
**StartPropertyService**
代码地址:system/core/init/init.cpp
说明:启动属性服务
首先创建一个socket并返回文件描述符,然后设置最大并发数为8,其他进程可以通过这个socket通知init进程修改系统属性,最后注册epoll事件,也就是当监听到property_set_fd改变时调用handle_property_set_fd
```c
void StartPropertyService(Epoll* epoll) {
property_set("ro.property_service.version", "2");
//建立socket连接
if (auto result = CreateSocket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
false, 0666, 0, 0, {})) {
property_set_fd = *result;
} else {
PLOG(FATAL) << "start_property_service socket creation failed: " << result.error();
}
// 最大监听8个并发
listen(property_set_fd, 8);
// 注册property_set_fd,当收到句柄改变时,通过handle_property_set_fd来处理
if (auto result = epoll->RegisterHandler(property_set_fd, handle_property_set_fd); !result) {
PLOG(FATAL) << result.error();
}
}
```
**handle_proerty_set_fd**
代码路径:system/core/init/property_service.cpp
建立socket连接,然后从socket中读取操作信息,根据不同的操作类型,调用HandlePropertySet做具体的操作
HandlePropertySet是最终的处理函数,以"ctl"开头的key就做一些Service的Start,Stop,Restart操作,其他的就是调用property_set进行属性设置,不管是前者还是后者,都要进行SELinux安全性检查,只有该进程有操作权限才能执行相应操作
```c
static void handle_property_set_fd() {
static constexpr uint32_t kDefaultSocketTimeout = 2000; /* ms */
// 等待客户端连接
int s = accept4(property_set_fd, nullptr, nullptr, SOCK_CLOEXEC);
if (s == -1) {
return;
}
ucred cr;
socklen_t cr_size = sizeof(cr);
// 获取连接到此socket的进程的凭据
if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cr, &cr_size) < 0) {
close(s);
PLOG(ERROR) << "sys_prop: unable to get SO_PEERCRED";
return;
}
// 建立socket连接
SocketConnection socket(s, cr);
uint32_t timeout_ms = kDefaultSocketTimeout;
uint32_t cmd = 0;
// 读取socket中的操作信息
if (!socket.RecvUint32(&cmd, &timeout_ms)) {
PLOG(ERROR) << "sys_prop: error while reading command from the socket";
socket.SendUint32(PROP_ERROR_READ_CMD);
return;
}
// 根据操作信息,执行对应处理,两者区别一个是以char形式读取,一个以String形式读取
switch (cmd) {
case PROP_MSG_SETPROP: {
char prop_name[PROP_NAME_MAX];
char prop_value[PROP_VALUE_MAX];
if (!socket.RecvChars(prop_name, PROP_NAME_MAX, &timeout_ms) ||
!socket.RecvChars(prop_value, PROP_VALUE_MAX, &timeout_ms)) {
PLOG(ERROR) << "sys_prop(PROP_MSG_SETPROP): error while reading name/value from the socket";
return;
}
prop_name[PROP_NAME_MAX-1] = 0;
prop_value[PROP_VALUE_MAX-1] = 0;
std::string source_context;
if (!socket.GetSourceContext(&source_context)) {
PLOG(ERROR) << "Unable to set property '" << prop_name << "': getpeercon() failed";
return;
}
const auto& cr = socket.cred();
std::string error;
uint32_t result = HandlePropertySet(prop_name, prop_value, source_context, cr, &error);
if (result != PROP_SUCCESS) {
LOG(ERROR) << "Unable to set property '" << prop_name << "' from uid:" << cr.uid
<< " gid:" << cr.gid << " pid:" << cr.pid << ": " << error;
}
break;
}
case PROP_MSG_SETPROP2: {
std::string name;
std::string value;
if (!socket.RecvString(&name, &timeout_ms) ||
!socket.RecvString(&value, &timeout_ms)) {
PLOG(ERROR) << "sys_prop(PROP_MSG_SETPROP2): error while reading name/value from the socket";
socket.SendUint32(PROP_ERROR_READ_DATA);
return;
}
std::string source_context;
if (!socket.GetSourceContext(&source_context)) {
PLOG(ERROR) << "Unable to set property '" << name << "': getpeercon() failed";
socket.SendUint32(PROP_ERROR_PERMISSION_DENIED);
return;
}
const auto& cr = socket.cred();
std::string error;
uint32_t result = HandlePropertySet(name, value, source_context, cr, &error);
if (result != PROP_SUCCESS) {
LOG(ERROR) << "Unable to set property '" << name << "' from uid:" << cr.uid
<< " gid:" << cr.gid << " pid:" << cr.pid << ": " << error;
}
socket.SendUint32(result);
break;
}
default:
LOG(ERROR) << "sys_prop: invalid command " << cmd;
socket.SendUint32(PROP_ERROR_INVALID_CMD);
break;
}
}
```
###### 1.7 第三阶段init.rc
当属性服务建立完成后,init的自身功能基本就告一段落,接下来需要来启动其他的进程。
其他进程都是一个二进制文件,我们可以直接通过exec的命令方式来启动,例如 ./system/bin/init second_stage,来启动init进程的第二阶段。但是Android系统有很多的Native进程,如果都通过传exec在代码中一个个的来执行进程,那是一种很糟糕的设计。
在这个基础上Android推出了一个init.rc的机制,即类似通过读取配置文件的方式,来启动不同的进程。
关于init.rc文件:
init.rc文件是一个非常重要的配置文件,它由AIL(Android Init Language)编写,其中定义了六个基本概念、两个基本关键字和多个指令关键字:
> 六个基本概念分别是Section、Action、Service、Trigger、Command、Option。
>
> 两个基本关键字是on和service。
>
> 指令关键字则定义在Trigger、Command和Option中。
>
> 其帮助文档位于/system/core/init/readme.txt,其关键字定义位于/system/core/init/keyword.h。
>
> 关键字on用来声明一个Action。
>
> 关键字service用来声明一个Service。
>
> 每一个Action或者Service都隐含是一个Section,init.rc就是由不同的Section组成的。
>
> Command是最小的功能单位,代表一个Linux命令或者一个方法调用。
>
> Trigger代表一个自定义的触发条件,用来触发Action的执行,也可以认为它是Action的名称。
>
> 一个Action便是由关键字on声明、由Trigger触发的一组Command序列。
>
> Option是Service的修饰符,由它来指定何时、如何启动Service程序。
>
> 每一个Service都是init进程的子进程,由关键字service、服务名、服务对应的命令的路径、命令的参数和Option组成,代表一些要在初始化阶段启动的程序。
```mermaid
graph LR
A[init.rc] -->B[import]
A -->C[on]
A -->D[service]
C -->CC[1.early_Init]
C -->CCC[2.on boot]
C -->CCCC[3.on init]
C -->CCCCC[4.on late_init]
D -->DD[1.Service]
DD -->DDd[name 执行名称]
DD -->DDdd[path 执行路径]
DD -->DDddd[arg 执行参数]
D -->DDD[2.user]
D -->DDDD[3.group]
D -->DDDDD[4.onshot或disable]
```
**Action**
动作表示了一组命令(commands)组成.动作包括一个触发器,决定了何时运行这个动作
Action: 通过触发器trigger,即以on开头的语句来决定执行相应的service的时机,具体有如下时机:
- on early-init; 在初始化早期阶段触发;
- on init; 在初始化阶段触发;
- on late-init; 在初始化晚期阶段触发;
- on boot/charger: 当系统启动/充电时触发;
- on property:\<key>=\<value>: 当属性值满足条件时触发;
**Command**
command是action的命令列表中的命令,或者是service中的选项 onrestart 的参数命令,命令将在所属事件发生时被一个个地执行.
常用命令如下:
- class_start <service_class_name>: 启动属于同一个class的所有服务;
- class_stop <service_class_name> : 停止指定类的服务
- start <service_name>: 启动指定的服务,若已启动则跳过;
- stop <service_name>: 停止正在运行的服务
- setprop \<name> \<value>:设置属性值
- mkdir \<path>:创建指定目录
- symlink \<target> <sym_link>: 创建连接到\<target>的<sym_link>符号链接;
- write \<path> \<string>: 向文件path中写入字符串;
- exec: fork并执行,会阻塞init进程直到程序完毕;
- exprot \<name> \<name>:设定环境变量;
- loglevel \<level>:设置log级别
- hostname \<name> : 设置主机名
- import \<filename> :导入一个额外的init配置文件
**Service**
服务Service,以 service开头,由init进程启动,一般运行在init的一个子进程,所以启动service前需要判断对应的可执行文件是否存在。
**命令:**service \<name>\<pathname> [ \<argument> ]* \<option> \<option>
| 参数 | 含义 |
| :---------: | :--------------------------------------------------: |
| \<name> | 表示此服务的名称 |
| \<pathname> | 此服务所在路径因为是可执行文件,所以一定有存储路径。 |
| \<argument> | 启动服务所带的参数 |
| \<option> | 对此服务的约束选项 |
init生成的子进程,定义在rc文件,其中每一个service在启动时会通过fork方式生成子进程。
**eg:** service servicemanager /system/bin/servicemanager代表的是服务名为servicemanager,服务执行的路径为/system/bin/servicemanager。
**Options**
Options是Service的可选项,与service配合使用
- disabled: 不随class自动启动,只有根据service名才启动;
- oneshot: service退出后不再重启;
- user/group: 设置执行服务的用户/用户组,默认都是root;
- class:设置所属的类名,当所属类启动/退出时,服务也启动/停止,默认为default;
- onrestart:当服务重启时执行相应命令;
- socket: 创建名为/dev/socket/<name>的socket
- critical: 在规定时间内该service不断重启,则系统会重启并进入恢复模式
default: 意味着disabled=false,oneshot=false,critical=false。
**import**
用来导入其他的rc文件
**命令:**import \<filename>
**init.rc解析过程**
- **LoadBootScripts**
代码路径:system/core/init/init.cpp
说明:如果没有特殊配置ro.boot.init_rc,则解析./init.rc
把/system/etc/init,/product/etc/init,/product_services/etc/init,/odm/etc/init,
/vendor/etc/init 这几个路径加入init.rc之后解析的路径,在init.rc解析完成后,解析这些目录里的rc文件
```c
static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
Parser parser = CreateParser(action_manager, service_list);
std::string bootscript = GetProperty("ro.boot.init_rc", "");
if (bootscript.empty()) {
parser.ParseConfig("/init.rc");
if (!parser.ParseConfig("/system/etc/init")) {
late_import_paths.emplace_back("/system/etc/init");
}
if (!parser.ParseConfig("/product/etc/init")) {
late_import_paths.emplace_back("/product/etc/init");
}
if (!parser.ParseConfig("/product_services/etc/init")) {
late_import_paths.emplace_back("/product_services/etc/init");
}
if (!parser.ParseConfig("/odm/etc/init")) {
late_import_paths.emplace_back("/odm/etc/init");
}
if (!parser.ParseConfig("/vendor/etc/init")) {
late_import_paths.emplace_back("/vendor/etc/init");
}
} else {
parser.ParseConfig(bootscript);
}
}
```
**注意:**Android7.0后,init.rc进行了拆分,每个服务都有自己的rc文件,他们基本上都被加载到/system/etc/init,/vendor/etc/init, /odm/etc/init等目录,等init.rc解析完成后,会来解析这些目录中的rc文件,用来执行相关的动作。
代码路径:system/core/init/init.cpp
```c
Parser CreateParser(ActionManager& action_manager, ServiceList& service_list) {
Parser parser;
parser.AddSectionParser(
"service", std::make_unique<ServiceParser>(&service_list, subcontexts, std::nullopt));
parser.AddSectionParser("on", std::make_unique<ActionParser>(&action_manager, subcontexts));
parser.AddSectionParser("import", std::make_unique<ImportParser>(&parser));
return parser;
}
```
- **执行Action动作**
按顺序把相关Action加入触发器队列,按顺序为 early-init -> init -> late-init. 然后在循环中,执行所有触发器队列中Action带Command的执行函数。
```c
am.QueueEventTrigger("early-init");
am.QueueEventTrigger("init");
am.QueueEventTrigger("late-init");
...
while (true) {
if (!(waiting_for_prop || Service::is_exec_service_running())) {
am.ExecuteOneCommand();
}
}
```
- **Zygote启动**
从Android 5.0的版本开始,Android支持64位的编译,因此zygote本身也支持32位和64位。通过属性ro.zygote来控制不同版本的zygote进程启动。
在init.rc的import段我们看到如下代码:
```c
import /init.${ro.zygote}.rc // 可以看出init.rc不再直接引入一个固定的文件,而是根据属性ro.zygote的内容来引入不同的文件
```
init.rc位于/system/core/rootdir下。在这个路径下还包括四个关于zygote的rc文件。
分别是init.zygote32.rc,init.zygote32_64.rc,init.zygote64.rc,init.zygote64_32.rc,由硬件决定调用哪个文件。
这里拿64位处理器为例,init.zygote64.rc的代码如下所示:
```shell
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
class main# class是一个option,指定zygote服务的类型为main
priority -20
user root
group root readproc reserved_disk
socket zygote stream 660 root system # socket关键字表示一个option,创建一个名为dev/socket/zygote,类型为stream,权限为660的socket
socket usap_pool_primary stream 660 root system
onrestart write /sys/android_power/request_state wake # onrestart是一个option,说明在zygote重启时需要执行的command
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
```
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server 解析:
service zygote :init.zygote64.rc 中定义了一个zygote服务。 init进程就是通过这个service名称来创建zygote进程
/system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server解析:
zygote这个服务,通过执行进行/system/bin/app_process64 并传入4个参数随后运行:
- 参数1:-Xzygote 该参数将作为虚拟机启动时所需的参数
- 参数2:/system/bin 代表虚拟机程序所在目录
- 参数3:--zygote 指明以ZygoteInit.java类中的main函数作为虚拟机执行入口
- 参数4:--start-system-server 告诉Zygote进程启动systemServer进程
###### 小结
init进程第一阶段做的主要工作是挂载分区,创建设备节点和一些关键目录,初始化日志输出系统,启用SELinux安全策略。
init进程第二阶段主要工作是初始化属性系统,解析SELinux的匹配规则,处理子进程终止信号,启动系统属性服务,每一项都很关键,如果说第一阶段是为属性系统,SELinux做准备,那么第二阶段就是真正去把这些功能落实。
init进行第三阶段主要是解析init.rc 来启动其他进程,进入无限循环,进行子进程实时监控。
##### 2、Zygote进程
###### 2.1 概述
Init进程启动后,最重要的一个进程就是Zygote进程,Zygote是所有应用的祖先进程。SystemServer和其他所有Dalivik虚拟机进程都是由Zygote fork而来。
Zygote进程由app_process启动,Zygote是一个C/S模型,Zygote进程作为服务端,其他进程作为客户端向它发出“孵化-fork”请求,而Zygote接收到这个请求后就“孵化-fork”出一个新的进程。
由于Zygote进程在启动时会创建Java虚拟机,因此通过fork而创建的应用程序进程和SystemServer进程可以在内部获取一个Java虚拟机的实例拷贝。
###### 2.2 核心源码
```
/system/core/rootdir/init.rc
/system/core/init/main.cpp
/system/core/init/init.cpp
/system/core/rootdir/init.zygote64_32.rc
/frameworks/base/cmds/app_process/app_main.cpp
/frameworks/base/core/jni/AndroidRuntime.cpp
/libnativehelper/JniInvocation.cpp
/frameworks/base/core/java/com/android/internal/os/Zygote.java
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
/frameworks/base/core/java/android/net/LocalServerSocket.java
/system/core/libutils/Threads.cpp
```
###### 2.3 架构
**架构图**
```mermaid
graph LR
A[Phone] -->D[ActivityManagerService]
B[SMS] -->D[ActivityManagerService]
C[Media] -->D[ActivityManagerService]
D -->E[Process.Start]
E -->F[Zygote]
F -->E
G[Init] -->F
```
###### 2.4 Zygote启动源码分析
- rc解析和进程调用
Init进程启动后,会解析init.rc文件,然后创建和加载service字段指定的进程。zygote进程就是以这种方式,被init进程加载的。
在 /system/core/rootdir/init.rc中,通过如下引用来load Zygote的rc:
```
import /init.${ro.zygote}.rc
```
其中${ro.zygote} 由各个厂家使用,现在的主流厂家基本使用zygote64_32,因此,我们的rc文件为 init.zygote64_32.rc
**init.zygote64_32.rc**
第一个Zygote进程:
进程名:zygote
进程通过 /system/bin/app_process64来启动
启动参数:-Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
socket的名称:zygote
```c
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
class main
priority -20
user root //用户为root
group root readproc reserved_disk //访问组支持 root readproc reserved_disk
socket zygote stream 660 root system //创建一个socket,名字叫zygote,以tcp形式 ,可以在/dev/socket 中看到一个 zygote的socket
socket usap_pool_primary stream 660 root system
onrestart write /sys/android_power/request_state wake // onrestart 指当进程重启时执行后面的命令
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
onrestart restart vendor.servicetracker-1-1
writepid /dev/cpuset/foreground/tasks // 创建子进程时,向 /dev/cpuset/foreground/tasks 写入pid
```
第二个zygote进程:
进程通过 /system/bin/app_process32来启动
启动参数:-Xzygote /system/bin --zygote --socket-name=zygote_secondary --enable-lazy-preload
socket的名称:zygote_secondary
```c
service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary --enable-lazy-preload
class main
priority -20
user root
group root readproc reserved_disk
socket zygote_secondary stream 660 root system //创建一个socket,名字叫zygote_secondary,以tcp形式 ,可以在/dev/socket 中看到一个 zygote_secondary的socket
socket usap_pool_secondary stream 660 root system
onrestart restart zygote
writepid /dev/cpuset/foreground/tasks
```
从上面我们可以看出,zygote是通过进程文件 /system/bin/app_process64 和/system/bin/app_process32 来启动的。对应的代码入口为:
**frameworks/base/cmds/app_process/app_main.cpp**
**Zygote进程的重启**
Zygote进程重启,主要查看rc文件中有没有 “restart zygote” 这句话。在整个Android系统工程中**搜索“restart zygote”**,会发现以下文件:
```cpp
/frameworks/native/services/inputflinger/host/inputflinger.rc 对应进程: inputflinger
/frameworks/native/cmds/servicemanager/servicemanager.rc 对应进程: servicemanager
/frameworks/native/services/surfaceflinger/surfaceflinger.rc 对应进程: surfaceflinger
/system/netd/server/netd.rc 对应进程: netd
```
通过上面的文件可知,zygote进程能够重启的时机:
- inputflinger 进程被杀 (onrestart)
- servicemanager 进程被杀 (onrestart)
- surfaceflinger 进程被杀 (onrestart)
- netd 进程被杀 (onrestart)
- zygote进程被杀 (oneshot=false)
- system_server进程被杀(waitpid)
**Zygote启动后**
```sequence
Title: Zygote启动时序图
" "->app_main.cpp:1.main
app_main.cpp->AndroidRuntime: 2.startVm
app_main.cpp->AndroidRuntime: 3.startReg
app_main.cpp->ZygoteInit: 4.main
ZygoteInit->ZygoteServer:5.new ZygoteServer
ZygoteServer->ZygoteInit:6.return ZygoteServer
ZygoteServer->ZygoteInit:7.registerServerSocket
ZygoteInit->ZygoteInit:8.startSystemServer
ZygoteInit->ZygoteServer:9.runSelectLoop
```
1. init进程通过init.zygote64_32.rc来调用/system/bin/app_process64 来启动zygote进程,入口app_main.cpp
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(),随时待命,当接收到请求创建新进程请求时立即唤醒并执行相应工作。
**Zygote启动相关函数**
C相关:
```
[app_main.cpp] main()
[AndroidRuntime.cpp] start()
[JniInvocation.cpp] Init()
[AndroidRuntime.cpp] startVm()
[AndroidRuntime.cpp] startReg()
[Threads.cpp] androidSetCreateThreadFunc
[AndroidRuntime.cpp] register_jni_procs() --> gRegJNI.mProc
```
Java相关:
```
[ZygoteInit.java] main()
[ZygoteInit.java] preload()
[ZygoteServer.java] ZygoteServer
[ZygoteInit.java] forkSystemServer
[Zygote.java] forkSystemServer
[Zygote.java] nativeForkSystemServer
[ZygoteServer.java] runSelectLoop
```
**2.4 Zygote进程启动源码分析**
Zygote启动代码调用流程:
```
init
|
init_zygote64_32.rc //启动两个zygote,一个64位--/system/bin/app_process64;另一个32位--/system/bin/app_process32
|
[app_main.cpp]
main()//入口
|
[AndroidRuntime.cpp]
start()|
||||
|||JniInvacation.Init(NULL)//初始化JNI,加载libart.so
|||//调用dlsym,从libart.so中找到JNI_GetDefaultJavaVMInitArgs
|||//JNI_CreateJavaVM、JNI_GetCreateJavaVMs三个函数地址,赋值给对应成员属性
|||
|||
||startVm()//启动虚拟机
|||
||JNI_CreateJavaVM(); //创建VM并返回JavaVM和JniEnv,pEnv对应于当前线程
||
||
|startReg()//注册JNI函数
|||
||androidSetCreateThreadFunc() //虚拟机启动后startReg()过程,会设置线程创建函数指针gCreateThreadFn指向javaCreateThreadEtc
||
|register_jni_procs()//注册JNI函数数组 --gRegJNI
|||
env->CallstaticVoidMethod() //通过反射,调用JAVA的com.android.internal.os.ZygoteInit ----ZygoteInit.java
|
[ZygoteInit.java] //进入Java层
main()
```
**[app_main.cpp]main()**
```c
int main(int argc, char* const argv[])
{
//zygote传入的参数argv为“-Xzygote /system/bin --zygote --start-system-server --socket-name=zygote”
//zygote_secondary传入的参数argv为“-Xzygote /system/bin --zygote --socket-name=zygote_secondary”
...
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
//对于64位系统nice_name为zygote64; 32位系统为zygote
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == 0) {
//是否需要启动system server
startSystemServer = true;
} else if (strcmp(arg, "--application") == 0) {
//启动进入独立的程序模式
application = true;
} else if (strncmp(arg, "--nice-name=", 12) == 0) {
//niceName 为当前进程别名,区别abi型号
niceName.setTo(arg + 12);
} else if (strncmp(arg, "--", 2) != 0) {
className.setTo(arg);
break;
} else {
--i;
break;
}
}
..
if (!className.isEmpty()) { //className不为空,说明是application启动模式
...
} else {
//进入zygote模式,新建Dalvik的缓存目录:/data/dalvik-cache
maybeCreateDalvikCache();
if (startSystemServer) { //加入start-system-server参数
args.add(String8("start-system-server"));
}
String8 abiFlag("--abi-list=");
abiFlag.append(prop);
args.add(abiFlag);//加入--abi-list=参数
// In zygote mode, pass all remaining arguments to the zygote
// main() method.
for (; i < argc; ++i) {//将剩下的参数加入args
args.add(String8(argv[i]));
}
}
...
if (!niceName.isEmpty()) {
//设置一个“好听的昵称” zygote\zygote64,之前的名称是app_process
runtime.setArgv0(niceName.string(), true /* setProcName */);
}
if (zygote) { //如果是zygote启动模式,则加载ZygoteInit
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {//如果是application启动模式,则加载RuntimeInit
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
//没有指定类名或zygote,参数错误
fprintf(stderr, "Error: no class name or --zygote supplied.\n");
app_usage();
LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
}
}
```
Zygote本身是一个Native的应用程序,刚开始的进程名称为“app_process”,运行过程中,通过调用setArgv0将名字改为zygote 或者 zygote64(根据操作系统而来),最后通过runtime的start()方法来真正的加载虚拟机并进入JAVA世界。
**[AndroidRuntime.cpp] start()**
```c
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
ALOGD(">>>>>> START %s uid %d <<<<<<\n",
className != NULL ? className : "(unknown)", getuid());
...
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
// 虚拟机创建,主要是关于虚拟机参数的设置
if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
return;
}
onVmCreated(env);//空函数,没有任何实现
// 注册JNI方法
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
jclass stringClass;
jobjectArray strArray;
jstring classNameStr;
//等价 strArray= new String[options.size() + 1];
stringClass = env->FindClass("java/lang/String");
assert(stringClass != NULL);
//等价 strArray[0] = "com.android.internal.os.ZygoteInit"
strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
assert(strArray != NULL);
classNameStr = env->NewStringUTF(className);
assert(classNameStr != NULL);
env->SetObjectArrayElement(strArray, 0, classNameStr);
//strArray[1] = "start-system-server";
//strArray[2] = "--abi-list=xxx";
//其中xxx为系统响应的cpu架构类型,比如arm64-v8a.
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);
}
//将"com.android.internal.os.ZygoteInit"转换为"com/android/internal/os/ZygoteInit"
char* slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName);
//找到Zygoteinit类
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
} else {
//找到这个类后就继续找成员函数main方法的Mehtod ID
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
} else {
// 通过反射调用ZygoteInit.main()方法
env->CallStaticVoidMethod(startClass, startMeth, strArray);
}
}
//释放相应对象的内存空间
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");
}
```
start()函数主要做了三件事情,一调用startVm开启虚拟机,二调用startReg注册JNI方法,三就是使用JNI把Zygote进程启动起来。
**[JniInvocation.cpp] Init()**
Init函数主要作用是初始化JNI,具体工作是首先通过dlopen加载libart.so获得其句柄,然后调用dlsym从libart.so中找到
JNI_GetDefaultJavaVMInitArgs、JNI_CreateJavaVM、JNI_GetCreatedJavaVMs三个函数地址,赋值给对应成员属性,这三个函数会在后续虚拟机创建中调用.
```c
bool JniInvocation::Init(const char* library) {
char buffer[PROP_VALUE_MAX];
const int kDlopenFlags = RTLD_NOW | RTLD_NODELETE;
/*
* 1.dlopen功能是以指定模式打开指定的动态链接库文件,并返回一个句柄
* 2.RTLD_NOW表示需要在dlopen返回前,解析出所有未定义符号,如果解析不出来,在dlopen会返回NULL
* 3.RTLD_NODELETE表示在dlclose()期间不卸载库,并且在以后使用dlopen()重新加载库时不初始化库中的静态变量
*/
handle_ = dlopen(library, kDlopenFlags); // 获取libart.so的句柄
if (handle_ == NULL) { //获取失败打印错误日志并尝试再次打开libart.so
if (strcmp(library, kLibraryFallback) == 0) {
// Nothing else to try.
ALOGE("Failed to dlopen %s: %s", library, dlerror());
return false;
}
library = kLibraryFallback;
handle_ = dlopen(library, kDlopenFlags);
if (handle_ == NULL) {
ALOGE("Failed to dlopen %s: %s", library, dlerror());
return false;
}
}
/*
* 1.FindSymbol函数内部实际调用的是dlsym
* 2.dlsym作用是根据 动态链接库 操作句柄(handle)与符号(symbol),返回符号对应的地址
* 3.这里实际就是从libart.so中将JNI_GetDefaultJavaVMInitArgs等对应的地址存入&JNI_GetDefaultJavaVMInitArgs_中
*/
if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetDefaultJavaVMInitArgs_),
"JNI_GetDefaultJavaVMInitArgs")) {
return false;
}
if (!FindSymbol(reinterpret_cast<void**>(&JNI_CreateJavaVM_),
"JNI_CreateJavaVM")) {
return false;
}
if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetCreatedJavaVMs_),
"JNI_GetCreatedJavaVMs")) {
return false;
}
return true;
}
```
**[AndroidRuntime.cpp] startReg()**
startReg首先是设置了Android创建线程的处理函数,然后创建了一个200容量的局部引用作用域,用于确保不会出现OutOfMemoryException,最后就是调用register_jni_procs进行JNI方法的注册
```c
int AndroidRuntime::startReg(JNIEnv* env)
{
ATRACE_NAME("RegisterAndroidNatives");
//设置Android创建线程的函数javaCreateThreadEtc,这个函数内部是通过Linux的clone来创建线程的
androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
ALOGV("--- registering native functions ---\n");
//创建一个200容量的局部引用作用域,这个局部引用其实就是局部变量
env->PushLocalFrame(200);
//注册JNI方法
if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
env->PopLocalFrame(NULL);
return -1;
}
env->PopLocalFrame(NULL); //释放局部引用作用域
return 0;
}
```
**[Thread.cpp] androidSetCreateThreadFunc()**
虚拟机启动startReg()后,会设置线程创建函数指针gCreateThreadFn指向javaCreateThreadEtc
```c
void androidSetCreateThreadFunc(android_create_thread_fn func) {
gCreateThreadFn = func;
}
```
**[AndroidRuntime.cpp] register_jni_procs()**
它处理的是RegJNIRec交给的mProc,RegJNIRec是一个结构体,mProc是一个函数指针
```c
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) {/ /调用gRegJNI的mProc
return -1;
}
}
return 0;
}
```
**[AndroidRuntime.cpp] gRegJNI()**
```c
static const RegJNIRec gRegJNI[] = {
REG_JNI(register_com_android_internal_os_RuntimeInit),
REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit),
REG_JNI(register_android_os_SystemClock),
REG_JNI(register_android_util_EventLog),
REG_JNI(register_android_util_Log),
...
}
#define REG_JNI(name) { name, #name }
struct RegJNIRec {
int (*mProc)(JNIEnv*);
};
gRegJNI 中是一堆函数指针,因此循环调用 gRegJNI 的mProc,即等价于调用其所对应的函数指针。
例如调用: register_com_android_internal_os_RuntimeInit
这是一个JNI函数动态注册的标准方法。
int register_com_android_internal_os_RuntimeInit(JNIEnv* env)
{
const JNINativeMethod methods[] = {
{ "nativeFinishInit", "()V",
(void*) com_android_internal_os_RuntimeInit_nativeFinishInit },
{ "nativeSetExitWithoutCleanup", "(Z)V",
(void*) com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup },
};
//跟Java侧的com/android/internal/os/RuntimeInit.java 的函数nativeFinishInit() 进行一一对应
return jniRegisterNativeMethods(env, "com/android/internal/os/RuntimeInit",
methods, NELEM(methods));
}
```
**Java层Zygote启动的主要代码**
通过JNI调用ZygoteInit的main函数后, Zygote便进入了Java框架层,此前没有任何代码进入过Java框架层,换句换说Zygote开启了Java框架层。
**[ZygoteInit.java]main.cpp**
代码地址:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
main的主要工作:
- 调用preload()来预加载类和资源
- 调用ZygoteServer()创建两个Server端的Socket--/dev/socket/zygote 和 /dev/socket/zygote_secondary,Socket用来等待ActivityManagerService来请求Zygote来创建新的应用程序进程。
- 调用forkSystemServer 来启动SystemServer进程,这样系统的关键服务也会由SystemServer进程启动起来。
- 最后调用runSelectLoop函数来等待客户端请求
```java
public static void main(String argv[]) {
// 1.创建ZygoteServer
ZygoteServer zygoteServer = null;
// 调用native函数,确保当前没有其它线程在运行
ZygoteHooks.startZygoteNoThreadCreation();
//设置pid为0,Zygote进入自己的进程组
Os.setpgid(0, 0);
......
Runnable caller;
try {
......
//得到systrace的监控TAG
String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
Trace.TRACE_TAG_DALVIK);
//通过systradce来追踪 函数ZygoteInit, 可以通过systrace工具来进行分析
//traceBegin 和 traceEnd 要成对出现,而且需要使用同一个tag
bootTimingsTraceLog.traceBegin("ZygoteInit");
//开启DDMS(Dalvik Debug Monitor Service)功能
//注册所有已知的Java VM的处理块的监听器。线程监听、内存监听、native 堆内存监听、debug模式监听等等
RuntimeInit.enableDdms();
boolean startSystemServer = false;
String zygoteSocketName = "zygote";
String abiList = null;
boolean enableLazyPreload = false;
//2. 解析app_main.cpp - start()传入的参数
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true; //启动zygote时,才会传入参数:start-system-server
} else if ("--enable-lazy-preload".equals(argv[i])) {
enableLazyPreload = true; //启动zygote_secondary时,才会传入参数:enable-lazy-preload
} else if (argv[i].startsWith(ABI_LIST_ARG)) { //通过属性ro.product.cpu.abilist64\ro.product.cpu.abilist32 从C空间传来的值
abiList = argv[i].substring(ABI_LIST_ARG.length());
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length()); //会有两种值:zygote和zygote_secondary
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}
// 根据传入socket name来决定是创建socket还是zygote_secondary
final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);
// 在第一次zygote启动时,enableLazyPreload为false,执行preload
if (!enableLazyPreload) {
//systrace 追踪 ZygotePreload
bootTimingsTraceLog.traceBegin("ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
// 3.加载进程的资源和类
preload(bootTimingsTraceLog);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
//systrae结束 ZygotePreload的追踪
bootTimingsTraceLog.traceEnd(); // ZygotePreload
} else {
// 延迟预加载, 变更Zygote进程优先级为NORMAL级别,第一次fork时才会preload
Zygote.resetNicePriority();
}
//结束ZygoteInit的systrace追踪
bootTimingsTraceLog.traceEnd(); // ZygoteInit
//禁用systrace追踪,以便fork的进程不会从zygote继承过时的跟踪标记
Trace.setTracingEnabled(false, 0);
// 4.调用ZygoteServer 构造函数,创建socket,会根据传入的参数,
// 创建两个socket:/dev/socket/zygote 和 /dev/socket/zygote_secondary
zygoteServer = new ZygoteServer(isPrimaryZygote);
if (startSystemServer) {
//5. fork出system server
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
// 启动SystemServer
if (r != null) {
r.run();
return;
}
}
// 6. zygote进程进入无限循环,处理请求
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
if (zygoteServer != null) {
zygoteServer.closeServerSocket();
}
}
// 7.在子进程中退出了选择循环。继续执行命令
if (caller != null) {
caller.run();
}
}
```
日志:reboot_log/mobilelog/APLog_2020_0527_111424\__3/boot\__normal/main_log_1__2020_0527_111424
关键字:**Zygote**
```verilog
05-27 11:13:47.145963 422 422 D Zygote : begin preload
05-27 11:13:47.146014 422 422 I Zygote : Calling ZygoteHooks.beginPreload()
05-27 11:13:47.161358 422 422 I Zygote : Preloading classes...
05-27 11:13:48.017474 422 422 I Zygote : ...preloaded 7590 classes in 856ms.
05-27 11:13:48.268421 422 422 I Zygote : Preloading resources...
05-27 11:13:48.345627 422 422 I Zygote : ...preloaded 64 resources in 77ms.
05-27 11:13:48.357019 422 422 I Zygote : ...preloaded 41 resources in 9ms.
05-27 11:13:48.881796 422 422 I Zygote : Preloading shared libraries...
05-27 11:13:48.897045 422 422 I Zygote : Called ZygoteHooks.endPreload()
05-27 11:13:48.898210 422 422 I Zygote : Installed AndroidKeyStoreProvider in 1ms.
05-27 11:13:48.961988 422 422 I Zygote : Warmed up JCA providers in 64ms.
05-27 11:13:48.962687 422 422 D Zygote : end preload
05-27 11:13:49.203818 421 421 D Zygote : Forked child process 1241
05-27 11:13:49.705212 422 422 D Zygote : Forked child process 1284
05-27 11:13:49.745990 421 421 D Zygote : Forked child process 1291
05-27 11:13:49.848341 421 421 D Zygote : Forked child process 1332
05-27 11:13:50.123459 421 421 D Zygote : Forked child process 1374
05-27 11:13:50.278760 422 422 D Zygote : Forked child process 1412
05-27 11:13:50.279845 422 422 I Zygote : Process 1284 exited cleanly (0)
05-27 11:13:50.297478 421 421 I Zygote : Process 1291 exited cleanly (0)
05-27 11:13:50.398452 421 421 D Zygote : Forked child process 1448
05-27 11:13:50.825943 421 421 D Zygote : Forked child process 1510
05-27 11:13:51.294073 421 421 D Zygote : Forked child process 1577
05-27 11:13:51.397776 421 421 D Zygote : Forked child process 1608
05-27 11:13:56.386450 421 421 D Zygote : Forked child process 1891
05-27 11:13:56.451562 421 421 D Zygote : Forked child process 1909
05-27 11:13:56.771389 421 421 D Zygote : Forked child process 1952
05-27 11:13:57.061047 421 421 D Zygote : Forked child process 1991
05-27 11:13:59.239336 421 421 D Zygote : Forked child process 2083
05-27 11:14:02.603439 421 421 D Zygote : Forked child process 2139
05-27 11:14:02.743785 421 421 D Zygote : Forked child process 2164
05-27 11:14:03.681056 421 421 D Zygote : Forked child process 2257
05-27 11:14:04.155033 421 421 D Zygote : Forked child process 2293
05-27 11:14:04.904368 421 421 D Zygote : Forked child process 2347
05-27 11:14:05.156937 421 421 D Zygote : Forked child process 2377
05-27 11:14:05.269683 421 421 D Zygote : Forked child process 2392
05-27 11:14:05.348930 421 421 D Zygote : Forked child process 2419
05-27 11:14:05.660315 421 421 D Zygote : Forked child process 2454
05-27 11:14:06.439079 421 421 D Zygote : Forked child process 2522
05-27 11:14:06.585562 421 421 D Zygote : Forked child process 2539
05-27 11:14:06.677364 422 422 D Zygote : Forked child process 2556
05-27 11:14:07.106202 421 421 D Zygote : Forked child process 2611
05-27 11:14:07.786845 421 421 D Zygote : Forked child process 2663
05-27 11:14:07.980175 421 421 D Zygote : Forked child process 2671
05-27 11:14:08.588646 421 421 D Zygote : Forked child process 2726
05-27 11:14:10.305557 421 421 D Zygote : Forked child process 2867
05-27 11:14:12.432055 421 421 D Zygote : Forked child process 2979
05-27 11:14:12.810294 421 421 D Zygote : Forked child process 3021
05-27 11:14:13.046852 421 421 D Zygote : Forked child process 3044
05-27 11:14:15.587206 421 421 D Zygote : Forked child process 3212
```
**[ZygoteInit.java] preload()**
```java
static void preload(TimingsTraceLog bootTimingsTraceLog) {
Log.d(TAG, "begin preload");
beginPreload(); // Pin ICU Data, 获取字符集转换资源等
//预加载类的列表---/system/etc/preloaded-classes, 在版本:/frameworks/base/config/preloaded-classes 中,Android10.0中预计有7603左右个类
//从下面的log看,成功加载了7587个类
preloadClasses();
preloadResources(); //加载图片、颜色等资源文件,部分定义在 /frameworks/base/core/res/res/values/arrays.xml中
......
preloadSharedLibraries(); // 加载 android、compiler_rt、jnigraphics等library
preloadTextResources(); //用于初始化文字资源
WebViewFactory.prepareWebViewInZygote(); //用于初始化webview;
endPreload(); //预加载完成,可以查看下面的log
warmUpJcaProviders();
Log.d(TAG, "end preload");
sPreloadComplete = true;
}
```
**什么是预加载:**
预加载是指在zygote进程启动的时候就加载,这样系统只在zygote执行一次加载操作,所有APP用到该资源不需要再重新加载,减少资源加载时间,加快了应用启动速度,一般情况下,系统中App共享的资源会被列为预加载资源。
zygote fork子进程时,根据fork的copy-on-write机制可知,有些类如果不做改变,甚至都不用复制,子进程可以和父进程共享这部分数据,从而省去不少内存的占用。
**预加载的原理:**
zygote进程启动后将资源读取出来,保存到Resources一个全局静态变量中,下次读取系统资源的时候优先从静态变量中查找。
地址:frameworks/base/config/preloaded-classes
```
# This file has been derived for mainline phone (and tablet) usage.
#
android.R$styleable
android.accessibilityservice.AccessibilityServiceInfo$1
android.accessibilityservice.AccessibilityServiceInfo
android.accounts.Account$1
android.accounts.Account
android.accounts.AccountManager$10
android.accounts.AccountManager$11
android.accounts.AccountManager$18
android.accounts.AccountManager$1
android.accounts.AccountManager$20
android.accounts.AccountManager$2
android.accounts.AccountManager$AmsTask$1
android.accounts.AccountManager$AmsTask$Response
android.accounts.AccountManager$AmsTask
android.accounts.AccountManager$BaseFutureTask$1
android.accounts.AccountManager$BaseFutureTask$Response
android.accounts.AccountManager$BaseFutureTask
android.accounts.AccountManager$Future2Task$1
android.accounts.AccountManager$Future2Task
android.accounts.AccountManager
android.accounts.AccountManagerCallback
android.accounts.AccountManagerFuture
............
```
**相关日志:**
```verilog
05-27 11:13:47.145963 422 422 D Zygote : begin preload
05-27 11:13:47.146014 422 422 I Zygote : Calling ZygoteHooks.beginPreload()
05-27 11:13:47.161358 422 422 I Zygote : Preloading classes...
05-27 11:13:48.017474 422 422 I Zygote : ...preloaded 7590 classes in 856ms.
05-27 11:13:48.268421 422 422 I Zygote : Preloading resources...
05-27 11:13:48.345627 422 422 I Zygote : ...preloaded 64 resources in 77ms.
05-27 11:13:48.357019 422 422 I Zygote : ...preloaded 41 resources in 9ms.
05-27 11:13:48.881796 422 422 I Zygote : Preloading shared libraries...
05-27 11:13:48.897045 422 422 I Zygote : Called ZygoteHooks.endPreload()
05-27 11:13:48.898210 422 422 I Zygote : Installed AndroidKeyStoreProvider in 1ms.
05-27 11:13:48.961988 422 422 I Zygote : Warmed up JCA providers in 64ms.
05-27 11:13:48.962687 422 422 D Zygote : end preload
```
**[ZygoteServer.java] ZygoteServer()**
代码地址:frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
作用:ZygoteServer 构造函数初始化时,根据传入的参数,利用LocalServerSocket 创建了4个本地服务端的socket,用来建立连接。
分别是:zygote、usap_pool_primary、zygote_secondary、usap_pool_secondary
```Java
private LocalServerSocket mZygoteSocket;
private LocalServerSocket mUsapPoolSocket;
//创建zygote的socket
ZygoteServer(boolean isPrimaryZygote) {
mUsapPoolEventFD = Zygote.getUsapPoolEventFD();
if (isPrimaryZygote) {
//创建socket,并获取socket对象,socketname: zygote
mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME);
//创建socket,并获取socket对象,socketname:usap_pool_primary
mUsapPoolSocket =
Zygote.createManagedSocketFromInitSocket(
Zygote.USAP_POOL_PRIMARY_SOCKET_NAME);
} else {
//创建socket,并获取socket对象,socketname: zygote_secondary
mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.SECONDARY_SOCKET_NAME);
//创建socket,并获取socket对象,socketname: usap_pool_secondary
mUsapPoolSocket =
Zygote.createManagedSocketFromInitSocket(
Zygote.USAP_POOL_SECONDARY_SOCKET_NAME);
}
fetchUsapPoolPolicyProps();
mUsapPoolSupported = true;
}
static LocalServerSocket createManagedSocketFromInitSocket(String socketName) {
int fileDesc;
// ANDROID_SOCKET_PREFIX为"ANDROID_SOCKET_"
//加入传入参数为zygote,则fullSocketName:ANDROID_SOCKET_zygote
final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
try {
//init.zygote64_32.rc启动时,指定了4个socket:
//分别是zygote、usap_pool_primary、zygote_secondary、usap_pool_secondary
// 在进程被创建时,就会创建对应的文件描述符,并加入到环境变量中
// 这里取出对应的环境变量
String env = System.getenv(fullSocketName);
fileDesc = Integer.parseInt(env);
} catch (RuntimeException ex) {
throw new RuntimeException("Socket unset or invalid: " + fullSocketName, ex);
}
try {
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc); // 获取zygote socket的文件描述符
return new LocalServerSocket(fd); // 创建Socket的本地服务端
} catch (IOException ex) {
throw new RuntimeException(
"Error building socket from file descriptor: " + fileDesc, ex);
}
}
path: \frameworks\base\core\java\android\net\LocalServerSocket.java
public LocalServerSocket(FileDescriptor fd) throws IOException
{
impl = new LocalSocketImpl(fd);
impl.listen(LISTEN_BACKLOG);
localAddress = impl.getSockAddress();
}
```
**[ZygoteInit.java] forkSystemServer()**
```java
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
long capabilities = posixCapabilitiesAsBits(
OsConstants.CAP_IPC_LOCK,
OsConstants.CAP_KILL,
OsConstants.CAP_NET_ADMIN,
OsConstants.CAP_NET_BIND_SERVICE,
OsConstants.CAP_NET_BROADCAST,
OsConstants.CAP_NET_RAW,
OsConstants.CAP_SYS_MODULE,
OsConstants.CAP_SYS_NICE,
OsConstants.CAP_SYS_PTRACE,
OsConstants.CAP_SYS_TIME,
OsConstants.CAP_SYS_TTY_CONFIG,
OsConstants.CAP_WAKE_ALARM,
OsConstants.CAP_BLOCK_SUSPEND
);
......
//参数准备
/* Hardcoded command line to start the system server */
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010
,1018,1021,1023,"
+ "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"--target-sdk-version=" + VMRuntime.
SDK_VERSION_CUR_DEVELOPMENT,
"com.android.server.SystemServer",
};
ZygoteArguments parsedArgs = null;
int pid;
try {
//将上面准备的参数,按照ZygoteArguments的风格进行封装
parsedArgs = new ZygoteArguments(args);
Zygote.applyDebuggerSystemProperty(parsedArgs);
Zygote.applyInvokeWithSystemProperty(parsedArgs);
boolean profileSystemServer = SystemProperties.getBoolean(
"dalvik.vm.profilesystemserver", false);
if (profileSystemServer) {
parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
}
//通过fork"分裂"出子进程system_server
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
//进入子进程system_server
/* For child process */
if (pid == 0) {
// 处理32_64和64_32的情况
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
// fork时会copy socket,system server需要主动关闭
zygoteServer.closeServerSocket();
// system server进程处理自己的工作
return handleSystemServerProcess(parsedArgs);
}
return null;
}
```
**[ZygoteServer.java] runSelectLoop()**
代码路径:frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
```java
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> socketFDs = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
// 首先将server socket加入到fds
socketFDs.add(mZygoteSocket.getFileDescriptor());
peers.add(null);
while (true) {
fetchUsapPoolPolicyPropsWithMinInterval();
int[] usapPipeFDs = null;
StructPollfd[] pollFDs = null;
// 每次循环,都重新创建需要监听的pollFds
// Allocate enough space for the poll structs, taking into account
// the state of the USAP pool for this Zygote (could be a
// regular Zygote, a WebView Zygote, or an AppZygote).
if (mUsapPoolEnabled) {
usapPipeFDs = Zygote.getUsapPipeFDs();
pollFDs = new StructPollfd[socketFDs.size() + 1 + usapPipeFDs.length];
} else {
pollFDs = new StructPollfd[socketFDs.size()];
}
/*
* For reasons of correctness the USAP pool pipe and event FDs
* must be processed before the session and server sockets. This
* is to ensure that the USAP pool accounting information is
* accurate when handling other requests like API blacklist
* exemptions.
*/
int pollIndex = 0;
for (FileDescriptor socketFD : socketFDs) {
// 关注事件到来
pollFDs[pollIndex] = new StructPollfd();
pollFDs[pollIndex].fd = socketFD;
pollFDs[pollIndex].events = (short) POLLIN;
++pollIndex;
}
final int usapPoolEventFDIndex = pollIndex;
if (mUsapPoolEnabled) {
pollFDs[pollIndex] = new StructPollfd();
pollFDs[pollIndex].fd = mUsapPoolEventFD;
pollFDs[pollIndex].events = (short) POLLIN;
++pollIndex;
for (int usapPipeFD : usapPipeFDs) {
FileDescriptor managedFd = new FileDescriptor();
managedFd.setInt$(usapPipeFD);
pollFDs[pollIndex] = new StructPollfd();
pollFDs[pollIndex].fd = managedFd;
pollFDs[pollIndex].events = (short) POLLIN;
++pollIndex;
}
}
try {
// 等待事件到来
Os.poll(pollFDs, -1);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
boolean usapPoolFDRead = false;
//倒序处理,即优先处理已建立链接的信息,后处理新建链接的请求
while (--pollIndex >= 0) {
if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
continue;
}
// server socket最先加入fds, 因此这里是server socket收到数据
if (pollIndex == 0) {
// 收到新的建立通信的请求,建立通信连接
ZygoteConnection newPeer = acceptCommandPeer(abiList);
// 加入到peers和fds, 即下一次也开始监听
peers.add(newPeer);
socketFDs.add(newPeer.getFileDescriptor());
} else if (pollIndex < usapPoolEventFDIndex) {
//说明接收到AMS发送过来创建应用程序的请求,调用processOneCommand
//来创建新的应用程序进程
// Session socket accepted from the Zygote server socket
try {
//有socket连接,创建ZygoteConnection对象,并添加到fds。
ZygoteConnection connection = peers.get(pollIndex);
//处理连接
final Runnable command = connection.processOneCommand(this);
// TODO (chriswailes): Is this extra check necessary?
if (mIsForkChild) {
// We're in the child. We should always have a command to run at this
// stage if processOneCommand hasn't called "exec".
if (command == null) {
throw new IllegalStateException("command == null");
}
return command;
} else {
// We're in the server - we should never have any commands to run.
if (command != null) {
throw new IllegalStateException("command != null");
}
// We don't know whether the remote side of the socket was closed or
// not until we attempt to read from it from processOneCommand. This
// shows up as a regular POLLIN event in our regular processing loop.
if (connection.isClosedByPeer()) {
connection.closeSocket();
peers.remove(pollIndex);
socketFDs.remove(pollIndex); //处理完则从fds中移除该文件描述符
}
}
} catch (Exception e) {
......
} finally {
mIsForkChild = false;
}
} else {
//处理USAP pool的事件
// Either the USAP pool event FD or a USAP reporting pipe.
// If this is the event FD the payload will be the number of USAPs removed.
// If this is a reporting pipe FD the payload will be the PID of the USAP
// that was just specialized.
long messagePayload = -1;
try {
byte[] buffer = new byte[Zygote.USAP_MANAGEMENT_MESSAGE_BYTES];
int readBytes = Os.read(pollFDs[pollIndex].fd, buffer, 0, buffer.length);
if (readBytes == Zygote.USAP_MANAGEMENT_MESSAGE_BYTES) {
DataInputStream inputStream =
new DataInputStream(new ByteArrayInputStream(buffer));
messagePayload = inputStream.readLong();
} else {
Log.e(TAG, "Incomplete read from USAP management FD of size "
+ readBytes);
continue;
}
} catch (Exception ex) {
if (pollIndex == usapPoolEventFDIndex) {
Log.e(TAG, "Failed to read from USAP pool event FD: "
+ ex.getMessage());
} else {
Log.e(TAG, "Failed to read from USAP reporting pipe: "
+ ex.getMessage());
}
continue;
}
if (pollIndex > usapPoolEventFDIndex) {
Zygote.removeUsapTableEntry((int) messagePayload);
}
usapPoolFDRead = true;
}
}
// Check to see if the USAP pool needs to be refilled.
if (usapPoolFDRead) {
int[] sessionSocketRawFDs =
socketFDs.subList(1, socketFDs.size())
.stream()
.mapToInt(fd -> fd.getInt$())
.toArray();
final Runnable command = fillUsapPool(sessionSocketRawFDs);
if (command != null) {
return command;
}
}
}
}
```
**[ZygoteConnection.java] processOneCommand()**
```java
Runnable processOneCommand(ZygoteServer zygoteServer) {
...
//fork子进程
pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal,
parsedArgs.mSeInfo,
parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.
mStartChildZygote,
parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs
.mTargetSdkVersion);
if (pid == 0) {
// 子进程执行
zygoteServer.setForkChild();
//进入子进程流程
return handleChildProc(parsedArgs, descriptors, childPipeFd,
parsedArgs.mStartChildZygote);
} else {
//父进程执行
// In the parent. A pid < 0 indicates a failure and will be handled in
//handleParentProc.
handleParentProc(pid, descriptors, serverPipeFd);
return null;
}
...
}
```
**[ZygoteConnection.java] handleChildProc()**
```java
private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, boolean isZygote) {
...
if (parsedArgs.mInvokeWith != null) {
...
throw new IllegalStateException("WrapperInit.execApplication
unexpectedly returned");
} else {
if (!isZygote) {
// App进程将会调用到这里,执行目标类的main()方法
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */);
}
}
}
```
###### 问题分析
**为什么SystemServer和Zygote之间通信要采用Socket**
进程间通信我们常用的是binder,为什么这里要采用socket呢。
主要是为了解决fork的问题:
UNIX上C++程序设计守则3:多线程程序里不准使用fork
Binder通讯是需要多线程操作的,代理对象对Binder的调用是在Binder线程,需要再通过Handler调用主线程来操作。
比如AMS与应用进程通讯,AMS的本地代理IApplicationThread通过调用ScheduleLaunchActivity,调用到的应用进程ApplicationThread的ScheduleLaunchActivity是在Binder线程,需要再把参数封装为一个ActivityClientRecord,sendMessage发送给H类(主线程Handler,ActivityThread内部类)
主要原因:害怕父进程binder线程有锁,然后子进程的主线程一直在等其子线程(从父进程拷贝过来的子进程)的资源,但是其实父进程的子进程并没有被拷贝过来,造成死锁。
所以fork不允许存在多线程。而Binder通讯偏偏就是多线程,所以干脆父进程(Zygote)这个时候就不使用binder线程
**为什么一个java应用一个虚拟机?**
- android的VM(vm==Virtual Machine )也是类似`JRE`(*Java运行环境(Java Runtime Environment,简称JRE)是一个软件, JRE可以让计算机系统运行Java应用程序(Java Application);JRE的内部有一个Java虚拟机(Java Virtual Machine,JVM*)以及一些标准的类别函数库(Class Library))的东西,当然,各方面都截然不同,不过有一个作用都是一样的,为app提供了运行环境
- android为每个程序提供一个vm,可以使每个app都运行在独立的运行环境,使稳定性提高。
- vm的设计可以有更好的兼容性。android apk都被编译成字节码(bytecode),在运行的时候,vm是先将字节码编译真正可执行的代码,否则不同硬件设备的兼容是很大的麻烦。
- android(非ROOT)没有windows下键盘钩子之类的东西,每个程序一个虚拟机,各个程序之间也不可以随意访问内存,所以此类木马病毒几乎没有。
**什么是Zygote资源预加载**
预加载是指在zygote进程启动的时候就加载,这样系统只在zygote执行一次加载操作,所有APP用到该资源不需要再重新加载,减少资源加载时间,加快了应用启动速度,一般情况下,系统中App共享的资源会被列为预加载资源。
zygote fork子进程时,根据fork的copy-on-write机制可知,有些类如果不做改变,甚至都不用复制,子进程可以和父进程共享这部分数据,从而省去不少内存的占用。
**Zygote为什么要预加载**
应用程序都从Zygote孵化出来,应用程序都会继承Zygote的所有内容。
如果在Zygote启动的时候加载这些类和资源,这些孵化的应用程序就继承Zygote的类和资源,这样启动应用程序的时候就不需要加载类和资源了,启动的速度就会快很多。
开机的次数不多,但是启动应用程序的次数非常多。
**Zygote 预加载的原理是什么?**
zygote进程启动后将资源读取出来,保存到Resources一个全局静态变量中,下次读取系统资源的时候优先从静态变量中查找。
###### 小结
Zygote启动流程结束,Zygote进程共做了如下几件事:
- 解析init.zygote64_32.rc,创建AppRuntime并调用其start方法,启动Zygote进程。
- 创建JavaVM并为JavaVM注册JNI.
- 通过JNI调用ZygoteInit的main函数进入Zygote的Java框架层。
- 通过ZygoteServer创建服务端Socket,预加载类和资源,并通过runSelectLoop函数等待如ActivityManagerService等的请求。
- 启动SystemServer进程。
##### 3、SystemServer进程
###### 3.1 概述
Zygote是所有应用的鼻祖。SystemServer和其他所有Dalivik虚拟机进程都是由Zygote fork而来。Zygote fork的第一个进程就是SystemServer,其在手机中的进程名为 system_server。
system_server 进程承载着整个framework的核心服务,例如创建 ActivityManagerService、PowerManagerService、DisplayManagerService、PackageManagerService、WindowManagerService、LauncherAppsService等核心系统服务。这些服务以不同的线程方式存在于system_server这个进程中。
下面来分析一下SystemServer的整个启动过程。
###### 3.2 架构
SystemServer 被Zygote进程fork出来后,用来创建ActivityManagerService、PowerManagerService、DisplayManagerService、PackageManagerService、WindowManagerService、LauncherAppsService等多个核心系统服务
```mermaid
graph TB
A[Init进程] -->B[Zygote进程]
B --1-->C[启动ART or Dalivk虚拟机]
B --3 Fork-->E[启动SystemServer]
B --2-->D[注册JNI]
E --1-->F[启动Boot服务]
E --2-->G[启动核心服务]
E --3-->H[启动其他服务]
```
###### 3.3 服务启动
```mermaid
graph LR
E[SystemServer] --1-->F[启动Boot服务]
E --2-->G[启动核心服务]
E --3-->H[启动其他服务]
F -->FF[ActivityManagerService]
F -->FG[PowerManagerService]
F -->FH[PackageManagerService]
F -->FA[DisplayManagerService]
F -->FB[UserManagerSevice]
F -->FC[LightsService]
F -->FV[SensorService]
G -->GA[WebViewUpdateService]
G -->GB[UsageStatsService]
G -->GC[BatteryService]
H -->HA[AlarmManagerService]
H -->HB[VibratorService]
H -->HC[DynamicSystemService]
H -->HD[ConsumerIrService]
H -->HE[.......]
```
###### 3.4 源码分析
**[ZygoteInit.java] main()**
**说明:**Zygote进程,通过fork()函数,最终孵化出system_server的进程,通过反射的方法启动SystemServer.java的main()方法
```Java
public static void main(String argv[]) {
ZygoteServer zygoteServer = null;
...
try {
zygoteServer = new ZygoteServer(isPrimaryZygote);
if (startSystemServer) {
//fork system_server
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
if (r != null) {
r.run(); //启动SystemServer.java的main()
return; //Android 8.0之前是通过抛异常的方式来启动,这里是直接return出去,用来清空栈,提高栈帧利用率
}
}
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
if (zygoteServer != null) {
zygoteServer.closeServerSocket();
}
}
if (caller != null) {
caller.run();
}
...
}
```
**[ZygoteInit.java] forkSystemServer()**
说明:准备参数,用来进行system_server的fork,从参数可知,pid=1000,gid=1000,进程名nick-name=system_server
当有两个Zygote进程时,需要等待第二个Zygote创建完成。由于fork时会拷贝socket,因此,在fork出system_server进程后,
需要关闭Zygote原有的socket
```Java
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
......
//参数准备,uid和gid都是为1000
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
+ "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
"com.android.server.SystemServer",
};
ZygoteArguments parsedArgs = null;
int pid;
try {
//将上面准备的参数,按照ZygoteArguments的风格进行封装
parsedArgs = new ZygoteArguments(args);
Zygote.applyDebuggerSystemProperty(parsedArgs);
Zygote.applyInvokeWithSystemProperty(parsedArgs);
//通过fork"分裂"出子进程system_server
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
//进入子进程system_server
if (pid == 0) {
// 处理32_64和64_32的情况
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName); //需要等待第二个Zygote创建完成
}
// fork时会copy socket,Zygote原有的socket需要关闭
zygoteServer.closeServerSocket();
// system server进程处理自己的工作
return handleSystemServerProcess(parsedArgs);
}
return null;
}
```
**[Zygote.java] forkSystemServer()**
**说明:**这里的nativeForkSystemServer()最终是通过JNI,调用Nativate C空间的com_android_internal_os_Zygote_nativeForkSystemServer()
来fork system_server
```Java
public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
ZygoteHooks.preFork();
// Resets nice priority for zygote process.
resetNicePriority();
//调用native的方法来fork system_server
//最终调用native的方法:com_android_internal_os_Zygote_nativeForkSystemServer
int pid = nativeForkSystemServer(
uid, gid, gids, runtimeFlags, rlimits,
permittedCapabilities, effectiveCapabilities);
// Enable tracing as soon as we enter the system_server.
if (pid == 0) {
Trace.setTracingEnabled(true, runtimeFlags);
}
ZygoteHooks.postForkCommon();
return pid;
}
```
**[com_android_internal_os_Zygote.cpp]**
**说明:**JNI注册的映射关系
```java
static const JNINativeMethod gMethods[] = {
{ "nativeForkSystemServer", "(II[II[[IJJ)I",
(void *) com_android_internal_os_Zygote_nativeForkSystemServer },
}
```
**[com_android_internal_os_Zygote.cpp] com_android_internal_os_Zygote_nativeForkSystemServer()**
说明:通过 SpecializeCommon进行fork,pid返回0时,表示当前为system_server子进程当pid >0 时,是进入父进程,即Zygote进程,通过waitpid 的WNOHANG 非阻塞方式来监控system_server进程挂掉,如果挂掉,则重启Zygote进程。
<u>现在使用的Android系统大部分情况下是64位的,会存在两个Zygote,当system_server挂掉后,只启动Zygote64这个父进程。</u>
```Java
static jint com_android_internal_os_Zygote_nativeForkSystemServer(
JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities,
jlong effective_capabilities) {
pid_t pid = ForkCommon(env, true,
fds_to_close,
fds_to_ignore);
if (pid == 0) {
//进入子进程
SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
permitted_capabilities, effective_capabilities,
MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,
false, nullptr, nullptr);
} else if (pid > 0) {
//进入父进程,即zygote进程
ALOGI("System server process %d has been created", pid);
int status;
//用waitpid函数获取状态发生变化的子进程pid
//waitpid的标记为WNOHANG,即非阻塞,返回为正值就说明有进程挂掉了
if (waitpid(pid, &status, WNOHANG) == pid) {
//当system_server进程死亡后,重启zygote进程
ALOGE("System server process %d has died. Restarting Zygote!", pid);
RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");
}
...
}
return pid;
}
```
**[com_android_internal_os_Zygote.cpp] ForkCommon**
**说明:**从Zygote孵化出一个进程的使用程序
```Java
static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
const std::vector<int>& fds_to_close,
const std::vector<int>& fds_to_ignore) {
//设置子进程的signal
SetSignalHandlers();
//在fork的过程中,临时锁住SIGCHLD
BlockSignal(SIGCHLD, fail_fn);
//fork子进程,采用copy on write方式,这里执行一次,会返回两次
//pid=0 表示Zygote fork SystemServer这个子进程成功
//pid > 0 表示SystemServer 的真正的PID
pid_t pid = fork();
if (pid == 0) {
//进入子进程
// The child process.
PreApplicationInit();
// 关闭并清除文件描述符
// Clean up any descriptors which must be closed immediately
DetachDescriptors(env, fds_to_close, fail_fn);
...
} else {
ALOGD("Forked child process %d", pid);
}
//fork结束,解锁
UnblockSignal(SIGCHLD, fail_fn);
return pid;
}
```
**[Zygcom_android_internal_os_Zygoteote.cpp] SpecializeCommon**
**说明:**system_server进程的一些调度配置
```Java
static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids,
jint runtime_flags, jobjectArray rlimits,
jlong permitted_capabilities, jlong effective_capabilities,
jint mount_external, jstring managed_se_info,
jstring managed_nice_name, bool is_system_server,
bool is_child_zygote, jstring managed_instruction_set,
jstring managed_app_data_dir) {
...
bool use_native_bridge = !is_system_server &&
instruction_set.has_value() &&
android::NativeBridgeAvailable() &&
android::NeedsNativeBridge(instruction_set.value().c_str());
if (!is_system_server && getuid() == 0) {
//对于非system_server子进程,则创建进程组
const int rc = createProcessGroup(uid, getpid());
if (rc == -EROFS) {
ALOGW("createProcessGroup failed, kernel missing CONFIG_CGROUP_CPUACCT?");
} else if (rc != 0) {
ALOGE("createProcessGroup(%d, %d) failed: %s", uid, /* pid= */ 0, strerror(-rc));
}
}
SetGids(env, gids, fail_fn); //设置group
SetRLimits(env, rlimits, fail_fn); //设置资源limit
if (use_native_bridge) {
// Due to the logic behind use_native_bridge we know that both app_data_dir
// and instruction_set contain values.
android::PreInitializeNativeBridge(app_data_dir.value().c_str(),
instruction_set.value().c_str());
}
if (setresgid(gid, gid, gid) == -1) {
fail_fn(CREATE_ERROR("setresgid(%d) failed: %s", gid, strerror(errno)));
}
...
//selinux上下文
if (selinux_android_setcontext(uid, is_system_server, se_info_ptr, nice_name_ptr) == -1) {
fail_fn(CREATE_ERROR("selinux_android_setcontext(%d, %d, \"%s\", \"%s\") failed",
uid, is_system_server, se_info_ptr, nice_name_ptr));
}
//设置线程名为system_server,方便调试
if (nice_name.has_value()) {
SetThreadName(nice_name.value());
} else if (is_system_server) {
SetThreadName("system_server");
}
// Unset the SIGCHLD handler, but keep ignoring SIGHUP (rationale in SetSignalHandlers).
//设置子进程的signal信号处理函数为默认函数
UnsetChldSignalHandler();
if (is_system_server) {
//对应 Zygote.java 的callPostForkSystemServerHooks()
env->CallStaticVoidMethod(gZygoteClass, gCallPostForkSystemServerHooks);
if (env->ExceptionCheck()) {
fail_fn("Error calling post fork system server hooks.");
}
//对应ZygoteInit.java 的 createSystemServerClassLoader()
//预取系统服务器的类加载器。这样做是为了尽早地绑定适当的系统服务器selinux域。
env->CallStaticVoidMethod(gZygoteInitClass, gCreateSystemServerClassLoader);
if (env->ExceptionCheck()) {
// Be robust here. The Java code will attempt to create the classloader
// at a later point (but may not have rights to use AoT artifacts).
env->ExceptionClear();
}
...
}
//等价于调用zygote.java 的callPostForkChildHooks()
env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, runtime_flags,
is_system_server, is_child_zygote, managed_instruction_set);
if (env->ExceptionCheck()) {
fail_fn("Error calling post fork hooks.");
}
}
```
**[ZygoteInit.java] handleSystemServerProcess**
说明:创建类加载器,并赋予当前线程,其中环境变量SYSTEMSERVERCLASSPATH,主要是service.jar、ethernet-service.jar和wifi-service.jar这三个jar包
```
export SYSTEMSERVERCLASSPATH=/system/framework/services.jar:/system/framework/ethernet-service.jar:/system/framework/wifi-service.jar
```
```java
private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
if (parsedArgs.mNiceName != null) {
Process.setArgV0(parsedArgs.mNiceName); //设置当前进程名为"system_server"
}
final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
if (systemServerClasspath != null) {
//执行dex优化操作
if (performSystemServerDexOpt(systemServerClasspath)) {
sCachedSystemServerClassLoader = null;
}
...
}
if (parsedArgs.mInvokeWith != null) {
String[] args = parsedArgs.mRemainingArgs;
//如果我们有一个非空系统服务器类路径,我们将不得不复制现有的参数并将类路径附加到它。
//当我们执行一个新进程时,ART将正确地处理类路径。
if (systemServerClasspath != null) {
String[] amendedArgs = new String[args.length + 2];
amendedArgs[0] = "-cp";
amendedArgs[1] = systemServerClasspath;
System.arraycopy(args, 0, amendedArgs, 2, args.length);
args = amendedArgs;
}
//启动应用进程
WrapperInit.execApplication(parsedArgs.mInvokeWith,
parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
VMRuntime.getCurrentInstructionSet(), null, args);
throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
} else {
// 创建类加载器,并赋予当前线程
createSystemServerClassLoader();
ClassLoader cl = sCachedSystemServerClassLoader;
if (cl != null) {
Thread.currentThread().setContextClassLoader(cl);
}
//system_server进入此分支
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, cl);
}
}
```
**[ZygoteInit.java] zygoteInit**
**说明:**基础配置,并进行应用初始化,返回对象
```java
protected static final void commonInit() {
LoggingHandler loggingHandler = new LoggingHandler();
// 设置默认的未捕捉异常处理方法
RuntimeHooks.setUncaughtExceptionPreHandler(loggingHandler);
Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler));
// 设置时区,通过属性读出中国时区为"Asia/Shanghai"
RuntimeHooks.setTimeZoneIdSupplier(() -> SystemProperties.get("persist.sys.timezone"));
//重置log配置
LogManager.getLogManager().reset();
new AndroidConfig();
//设置默认的HTTP User-agent格式,用于 HttpURLConnection
String userAgent = getDefaultUserAgent();
System.setProperty("http.agent", userAgent);
/*
* Wire socket tagging to traffic stats.
*/
//设置socket的tag,用于网络流量统计
NetworkManagementSocketTagger.install();
...
}
```
**[ZygoteInit.java] nativeZygoteInit**
**说明:**nativeZygoteInit 通过反射,进入com_android_internal_os_ZygoteInit_nativeZygoteInit
```c
[AndroidRuntime.cpp]
int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env)
{
const JNINativeMethod methods[] = {
{ "nativeZygoteInit", "()V",
(void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },
};
return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",
methods, NELEM(methods));
}
gCurRuntime = this;
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
//此处的gCurRuntime为AppRuntime,是在AndroidRuntime.cpp中定义的
gCurRuntime->onZygoteInit();
}
[app_main.cpp]
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool(); //启动新binder线程
}
```
**[RuntimeInit.java] applicationInit**
**说明:**通过参数解析,得到args.startClass = com.android.server.SystemServer
```java
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
//true代表应用程序退出时不调用AppRuntime.onExit(),否则会在退出前调用
nativeSetExitWithoutCleanup(true);
// We want to be fairly aggressive about heap utilization, to avoid
// holding on to a lot of memory that isn't needed.
//设置虚拟机的内存利用率参数值为0.75
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
final Arguments args = new Arguments(argv); //解析参数
...
// Remaining arguments are passed to the start class's static main
//调用startClass的static方法 main()
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
```
**[RuntimeInit.java] findStaticMain**
**说明:**拿到SystemServer的main()方法,并返回 MethodAndArgsCaller()对象
```java
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
//拿到com.android.server.SystemServer 的类对象
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
//得到SystemServer的main()方法,
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}
//把MethodAndArgsCaller的对象返回给ZygoteInit.main()。这样做好处是能清空栈帧,提高栈帧利用率
//清除了设置进程所需的所有堆栈帧
return new MethodAndArgsCaller(m, argv);
}
```
**[RuntimeInit.java] MethodAndArgsCaller**
**说明:**最终在ZygoteInit.java的main(),调用这里的run()来启动SystemServer.java的main(),真正进入SystemServer进程
```java
static class MethodAndArgsCaller implements Runnable {
/** method to call */
private final Method mMethod;
/** argument array */
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
//根据传递过来的参数,可知此处通过反射机制调用的是SystemServer.main()方法
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);
}
}
}
```
###### 3.5 SystemServer启动后
**[SystemServer.java] main**
**说明:**main函数由Zygote进程 fork后运行,作用是new 一个SystemServer对象,再调用该对象的run()方法
```Java
public static void main(String[] args) {
//new 一个SystemServer对象,再调用该对象的run()方法
new SystemServer().run();
}
```
**[SystemServer.java] run**
**说明:**先初始化一些系统变量,加载类库,创建Context对象,创建SystemServiceManager对象等候再启动服务,启动引导服务、核心服务和其他服务
```Java
private void run() {
try {
traceBeginAndSlog("InitBeforeStartServices");
// Record the process start information in sys props.
//从属性中读取system_server进程的一些信息
SystemProperties.set(SYSPROP_START_COUNT, String.valueOf(mStartCount));
SystemProperties.set(SYSPROP_START_ELAPSED, String.valueOf(mRuntimeStartElapsedTime));
SystemProperties.set(SYSPROP_START_UPTIME, String.valueOf(mRuntimeStartUptime));
EventLog.writeEvent(EventLogTags.SYSTEM_SERVER_START,
mStartCount, mRuntimeStartUptime, mRuntimeStartElapsedTime);
//如果一个设备的时钟是在1970年之前(0年之前),
//那么很多api 都会因为处理负数而崩溃,尤其是java.io.File#setLastModified
//所以把时间设置为1970
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
Slog.w(TAG, "System clock is before 1970; setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
//如果时区不存在,设置时区为GMT
String timezoneProperty = SystemProperties.get("persist.sys.timezone");
if (timezoneProperty == null || timezoneProperty.isEmpty()) {
Slog.w(TAG, "Timezone not set; setting to GMT.");
SystemProperties.set("persist.sys.timezone", "GMT");
}
//变更虚拟机的库文件,对于Android 10.0默认采用的是libart.so
SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
// Mmmmmm... more memory!
//清除vm内存增长上限,由于启动过程需要较多的虚拟机内存空间
VMRuntime.getRuntime().clearGrowthLimit();
...
//系统服务器必须一直运行,所以它需要尽可能高效地使用内存
//设置内存的可能有效使用率为0.8
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
//一些设备依赖于运行时指纹生成,所以在进一步启动之前,请确保我们已经定义了它。
Build.ensureFingerprintProperty();
//访问环境变量前,需要明确地指定用户
//在system_server中,任何传入的包都应该被解除,以避免抛出BadParcelableException。
BaseBundle.setShouldDefuse(true);
//在system_server中,当打包异常时,信息需要包含堆栈跟踪
Parcel.setStackTraceParceling(true);
//确保当前系统进程的binder调用,总是运行在前台优先级(foreground priority)
BinderInternal.disableBackgroundScheduling(true);
//设置system_server中binder线程的最大数量,最大值为31
BinderInternal.setMaxThreads(sMaxBinderThreads);
//准备主线程lopper,即在当前线程运行
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
Looper.prepareMainLooper();
Looper.getMainLooper().setSlowLogThresholdMs(
SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
//加载android_servers.so库,初始化native service
System.loadLibrary("android_servers");
// Debug builds - allow heap profiling.
//如果是Debug版本,允许堆内存分析
if (Build.IS_DEBUGGABLE) {
initZygoteChildHeapProfiling();
}
//检测上次关机过程是否失败,这个调用可能不会返回
performPendingShutdown();
//初始化系统上下文
createSystemContext();
//创建系统服务管理--SystemServiceManager
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart,
mRuntimeStartElapsedTime, mRuntimeStartUptime);
//将mSystemServiceManager添加到本地服务的成员sLocalServiceObjects
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Prepare the thread pool for init tasks that can be parallelized
//为可以并行化的init任务准备线程池
SystemServerInitThreadPool.get();
} finally {
traceEnd(); // InitBeforeStartServices
}
// Start services.
//启动服务
try {
traceBeginAndSlog("StartServices");
startBootstrapServices(); // 启动引导服务
startCoreServices(); // 启动核心服务
startOtherServices(); // 启动其他服务
SystemServerInitThreadPool.shutdown(); //停止线程池
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
traceEnd();
}
//为当前的虚拟机初始化VmPolicy
StrictMode.initVmDefaults(null);
...
// Loop forever.
//死循环执行
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
```
**[SystemServer.java] performPendingShutdown**
**说明:**检测上次关机过程是否失败,这个调用可能不会返回
```java
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;
}
//如果需要重新启动才能应用更新,一定要确保uncrypt在需要时正确执行。
//如果'/cache/recovery/block.map'还没有创建,停止重新启动,它肯定会失败,
//并有机会捕获一个bugreport时,这仍然是可行的。
if (reason != null && reason.startsWith(PowerManager.REBOOT_RECOVERY_UPDATE)) {
File packageFile = new File(UNCRYPT_PACKAGE_FILE);
if (packageFile.exists()) {
String filename = null;
try {
filename = FileUtils.readTextFile(packageFile, 0, null);
} catch (IOException e) {
Slog.e(TAG, "Error reading uncrypt package file", e);
}
if (filename != null && filename.startsWith("/data")) {
if (!new File(BLOCK_MAP_FILE).exists()) {
Slog.e(TAG, "Can't find block map file, uncrypt failed or " +
"unexpected runtime restart?");
return;
}
}
}
}
Runnable runnable = new Runnable() {
@Override
public void run() {
synchronized (this) {
//当属性sys.shutdown.requested的值为1时,会重启
//当属性的值不为空,且不为1时,会关机
ShutdownThread.rebootOrShutdown(null, reboot, reason);
}
}
};
// ShutdownThread must run on a looper capable of displaying the UI.
//ShutdownThread必须在一个能够显示UI的looper上运行
//即UI线程启动ShutdownThread的rebootOrShutdown
Message msg = Message.obtain(UiThread.getHandler(), runnable);
msg.setAsynchronous(true);
UiThread.getHandler().sendMessage(msg);
}
}
```
**[SystemServer.java] createSystemContext**
**说明:**初始化系统上下文, 该过程会创建对象有ActivityThread,Instrumentation, ContextImpl,LoadedApk,Application
```Java
private void createSystemContext() {
//创建system_server进程的上下文信息
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
//设置主题
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
//获取systemui上下文信息,并设置主题
final Context systemUiContext = activityThread.getSystemUiContext();
systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
```
**[SystemServer.java] startBootstrapServices**
说明:用于启动系统Boot级服务,有ActivityManagerService, PowerManagerService, LightsService, DisplayManagerService, PackageManagerService, UserManagerService, sensor服务.
```Java
private void startBootstrapServices() {
traceBeginAndSlog("StartWatchdog");
//启动watchdog
//尽早启动watchdog,如果在早起启动时发生死锁,我们可以让system_server
//崩溃,从而进行详细分析
final Watchdog watchdog = Watchdog.getInstance();
watchdog.start();
traceEnd();
...
//添加PLATFORM_COMPAT_SERVICE,Platform compat服务被ActivityManagerService、PackageManagerService
//以及将来可能出现的其他服务使用。
traceBeginAndSlog("PlatformCompat");
ServiceManager.addService(Context.PLATFORM_COMPAT_SERVICE,
new PlatformCompat(mSystemContext));
traceEnd();
//阻塞等待installd完成启动,以便有机会创建具有适当权限的关键目录,如/data/user。
//我们需要在初始化其他服务之前完成此任务。
traceBeginAndSlog("StartInstaller");
Installer installer = mSystemServiceManager.startService(Installer.class);
traceEnd();
...
//启动服务ActivityManagerService,并为其设置mSystemServiceManager和installer
traceBeginAndSlog("StartActivityManager");
ActivityTaskManagerService atm = mSystemServiceManager.startService(
ActivityTaskManagerService.Lifecycle.class).getService();
mActivityManagerService = ActivityManagerService.Lifecycle.startService(mSystemServiceManager, atm);
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
mWindowManagerGlobalLock = atm.getGlobalLock();
traceEnd();
//启动服务PowerManagerService
//Power manager需要尽早启动,因为其他服务需要它。
//本机守护进程可能正在监视它的注册,
//因此它必须准备好立即处理传入的绑定器调用(包括能够验证这些调用的权限)
。
traceBeginAndSlog("StartPowerManager");
mPowerManagerService = mSystemServiceManager.startService(
PowerManagerService.class);
traceEnd();
...
//初始化power management
traceBeginAndSlog("InitPowerManagement");
mActivityManagerService.initPowerManagement();
traceEnd();
//启动recovery system,以防需要重新启动
traceBeginAndSlog("StartRecoverySystemService");
mSystemServiceManager.startService(RecoverySystemService.class);
traceEnd();
...
//启动服务LightsService
//管理led和显示背光,所以我们需要它来打开显示
traceBeginAndSlog("StartLightsService");
mSystemServiceManager.startService(LightsService.class);
traceEnd();
...
//启动服务DisplayManagerService
//显示管理器需要在包管理器之前提供显示指标
traceBeginAndSlog("StartDisplayManager");
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
traceEnd();
// Boot Phases: Phase100: 在初始化package manager之前,需要默认的显示.
traceBeginAndSlog("WaitForDisplay");
mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
traceEnd();
//当设备正在加密时,仅运行核心
String cryptState = VoldProperties.decrypt().orElse("");
if (ENCRYPTING_STATE.equals(cryptState)) {
Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
mOnlyCore = true;
} else if (ENCRYPTED_STATE.equals(cryptState)) {
Slog.w(TAG, "Device encrypted - only parsing core apps");
mOnlyCore = true;
}
...
//启动服务PackageManagerService
traceBeginAndSlog("StartPackageManagerService");
try {
Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
} finally {
Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
}
...
//启动服务UserManagerService,新建目录/data/user/
traceBeginAndSlog("StartUserManagerService");
mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
traceEnd();
// Set up the Application instance for the system process and get started.
//为系统进程设置应用程序实例并开始。
//设置AMS
traceBeginAndSlog("SetSystemProcess");
mActivityManagerService.setSystemProcess();
traceEnd();
//使用一个ActivityManager实例完成watchdog设置并监听重启,
//只有在ActivityManagerService作为一个系统进程正确启动后才能这样做
traceBeginAndSlog("InitWatchdog");
watchdog.init(mSystemContext, mActivityManagerService);
traceEnd();
//传感器服务需要访问包管理器服务、app ops服务和权限服务,
//因此我们在它们之后启动它。
//在单独的线程中启动传感器服务。在使用它之前应该检查完成情况。
mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> {
TimingsTraceLog traceLog = new TimingsTraceLog(
SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.
TRACE_TAG_SYSTEM_SERVER);
traceLog.traceBegin(START_SENSOR_SERVICE);
startSensorService(); //启动传感器服务
traceLog.traceEnd();
}, START_SENSOR_SERVICE);
}
```
**[SystemServer.java] startCoreServices**
**说明:**启动核心服务BatteryService,UsageStatsService,WebViewUpdateService、BugreportManagerService、GpuService等
```Java
private void startCoreServices() {
//启动服务BatteryService,用于统计电池电量,需要LightService.
mSystemServiceManager.startService(BatteryService.class);
//启动服务UsageStatsService,用于统计应用使用情况
mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));
//启动服务WebViewUpdateService
//跟踪可更新的WebView是否处于就绪状态,并监视更新安装
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
}
//启动CachedDeviceStateService,跟踪和缓存设备状态
mSystemServiceManager.startService(CachedDeviceStateService.class);
//启动BinderCallsStatsService, 跟踪在绑定器调用中花费的cpu时间
traceBeginAndSlog("StartBinderCallsStatsService");
mSystemServiceManager.startService(BinderCallsStatsService.LifeCycle.class);
traceEnd();
//启动LooperStatsService,跟踪处理程序中处理消息所花费的时间。
traceBeginAndSlog("StartLooperStatsService");
mSystemServiceManager.startService(LooperStatsService.Lifecycle.class);
traceEnd();
//启动RollbackManagerService,管理apk回滚
mSystemServiceManager.startService(RollbackManagerService.class);
//启动BugreportManagerService,捕获bugreports的服务
mSystemServiceManager.startService(BugreportManagerService.class);
//启动GpuService,为GPU和GPU驱动程序提供服务。
mSystemServiceManager.startService(GpuService.class);
}
```
**[SystemServer.java] startOtherServices**
**说明:**启动其他的服务,开始处理一大堆尚未重构和整理的东西,这里的服务太多,大体启动过程类似,
```Java
private void startOtherServices() {
...
//启动TelecomLoaderService,通话相关核心服务
mSystemServiceManager.startService(TelecomLoaderService.class);
//启动TelephonyRegistry
telephonyRegistry = new TelephonyRegistry(context);
ServiceManager.addService("telephony.registry", telephonyRegistry);
...
//启动AlarmManagerService,时钟管理
mSystemServiceManager.startService(new AlarmManagerService(context));
...
//启动InputManagerService
inputManager = new InputManagerService(context);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
...
inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback());
inputManager.start();
...
//Phase480:在接收到此启动阶段后,服务可以获得锁设置数据
mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
//Phase500:在接收到这个启动阶段之后,服务可以安全地调用核心系统服务,
//如PowerManager或PackageManager。
mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
mActivityManagerService.systemReady(() -> {
//Phase550:在接收到此引导阶段后,服务可以广播意图。
mSystemServiceManager.startBootPhase(
SystemService.PHASE_ACTIVITY_MANAGER_READY);
//Phase600:在接收到这个启动阶段后,服务可以启动/绑定到第三方应用程序。
//此时,应用程序将能够对服务进行绑定调用。
mSystemServiceManager.startBootPhase(
SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
}
}
```
###### 小结
- Zygote启动后fork的第一个进程为SystemServer,在手机中的进程别名为"system_server",主要用来启动系统中的服务
- Zygote fork后,进入SystemServer的main()
- SystemServer在启动过程中,先初始化一些系统变量,加载类库,创建Context对象,创建SystemServiceManager对象等候再启动服务
- 启动的服务分为 引导服务(Boot Service)、核心服务(Core Service)和其他服务(Other Service)三大类,共90多个服务
- SystemServer在启动服务前,会尝试与Zygote建立Socket通信,通信成功后才去启动服务
- 启动的服务都单独运行在SystemServer的各自线程中,同属于SystemServer进程
##### 4、ActivityMnagerService-AMS启动流程
###### 4.1 概述
ActivityManagerService简称AMS,具有管理Activity行为、控制activity的生命周期、派发消息事件、内存管理等功能。
###### 4.2 架构
ActivityManagerService启动共分为以下4个阶段:
阶段1:为SystemSerer进程创建Android运行环境。AMS运行与SystemServer进程中,它的许多工作依赖于该运行环境
```
createSystemContext() -> new ActvityThread()-->attach ->getSystemContext ->createSystemContext
```
阶段2:启动AMS,主要进行一些初始化工作
```java
new ActivityManagerService()
start()
```
阶段3:将SystemServer进程纳入到AMS的进程管理体系中
```Java
setSystemProcess() //将framework-res.apk的信息加入到SystemServer进程的LoadedApk中;构建SystemServer进程的ProcessRecord,保存到AMS中,以便AMS进程统一管理
installSystemProvider() //安装SystemServer进程中的SettingsProvider.apk
```
阶段4:AMS启动完成,通知服务或应用完成后续的工作,或直接启动一些进程
```Java
AMS.systemReady() //许多服务或应用进程必须等待AMS完成启动工作后,才能启动或进行一些后续工作;AMS就是在systemReady中,通知或者启动这些等待的服务和应用进程,例如启动桌面等。
```
###### 4.3 AMS启动流程源码分析
从Zygote启动SystemServer,再到SystemServer启动AMS等服务
- 初始化 SystemContext
- 创建SystemServiceManager 对象,用来启动后面的服务
- 启动系统服务,共分为三种系统服务:系统引导服务(Boot Service)、核心服务(Core Service)和其他服务(Other Service)
- 在引导服务(Boot Service)中启动ATM、AMS服务
- 在其他服务(Other Service)中完成AMS的最后工作systemReady
**[SystemServer.java]**
```java
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
...
//1.初始化 System Context
createSystemContext();
//2.创建 SystemServiceManager 对象,用来启动后面的服务
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart,
mRuntimeStartElapsedTime, mRuntimeStartUptime);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
...
//3.启动服务
startBootstrapServices(); //启动引导服务
startCoreServices(); //启动核心服务
startOtherServices(); //启动其他服务
...
}
```
**[SystemServer.java] startBootstrapServices()**
**说明:**启动引导服务,在其中启动了ATM和AMS服务,通过AMS安装Installer、初始化Power,设置系统进程等。
```java
private void startBootstrapServices() {
...
//启动ActivityTaskManagerService服务,简称ATM,Android10新引入功能,用来管理Activity的启动、调度等功能
atm = mSystemServiceManager.startService(
ActivityTaskManagerService.Lifecycle.class).getService();
//启动服务 ActivityManagerService,简称AMS
mActivityManagerService = ActivityManagerService.Lifecycle.startService(
mSystemServiceManager, atm);
//安装Installer
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
//初始化PowerManager
mActivityManagerService.initPowerManagement();
//设置系统进程
mActivityManagerService.setSystemProcess();
}
```
**[SystemServer.java] startOtherServices**
**说明:**启动其他服务,AMS启动后,完成后续桌面启动等操作
```java
private void startOtherServices() {
...
//安装SettingsProvider.apk
mActivityManagerService.installSystemProviders();
mActivityManagerService.setWindowManager(wm);
//AMS启动完成,完成后续的工作,例如启动桌面等
mActivityManagerService.systemReady(() -> {
...
}, BOOT_TIMINGS_TRACE_LOG);
...
}
```
###### 4.4 System Context初始化
**说明:** 在SystemServer的run函数中,在启动AMS之前,调用了createSystemContext函,主要用来是初始化 System Context和SystemUi Context,并设置主题
当SystemServer 调用createSystemContext()完毕后,完成以下两个内容:
- 得到了一个ActivityThread对象,它代表当前进程 (此时为系统进程) 的主线程;
- 得到了一个Context对象,对于SystemServer而言,它包含的Application运行环境与framework-res.apk有关。
**[ActivityThread.java] systemMain()**
**说明:** 创建ActivityThread对象,然后调用该对象的attach函数。
```java
public static ActivityThread systemMain() {
// The system process on low-memory devices do not get to use hardware
// accelerated drawing, since this can add too much overhead to the
// process.
if (!ActivityManager.isHighEndGfx()) {
ThreadedRenderer.disable(true);
} else {
ThreadedRenderer.enableForegroundTrimming();
}
//获取ActivityThread对象
ActivityThread thread = new ActivityThread();
thread.attach(true, 0);
return thread;
}
```
**ActivityThread 对象创建**
**说明:**ActivityThread是Android Framework中一个非常重要的类,它代表一个应用进程的主线程,其职责就是调度及执行在该线程中运行的四大组件。
注意到此处的ActivityThread创建于SystemServer进程中。
由于SystemServer中也运行着一些系统APK,例如framework-res.apk、SettingsProvider.apk等,因此也可以认为SystemServer是一个特殊的应用进程。
AMS负责管理和调度进程,因此AMS需要通过Binder机制和应用进程通信。
为此,Android提供了一个IApplicationThread接口,该接口定义了AMS和应用进程之间的交互函数。
ActivityThread的构造函数比较简单,获取ResourcesManager的单例对象,比较关键的是它的成员变量:
```java
public final class ActivityThread extends ClientTransactionHandler {
...
//定义了AMS与应用通信的接口,拿到ApplicationThread的对象
final ApplicationThread mAppThread = new ApplicationThread();
//拥有自己的looper,说明ActivityThread确实可以代表事件处理线程
final Looper mLooper = Looper.myLooper();
//H继承Handler,ActivityThread中大量事件处理依赖此Handler
final H mH = new H();
//用于保存该进程的ActivityRecord
final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
//用于保存进程中的Service
final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();
////用于保存进程中的Application
final ArrayList<Application> mAllApplications
= new ArrayList<Application>();
//构造函数
@UnsupportedAppUsage
ActivityThread() {
mResourcesManager = ResourcesManager.getInstance();
}
}
```
**[ActivityThread.java] attach**
**说明:**对于系统进程而言,ActivityThread的attach函数最重要的工作就是创建了Instrumentation、Application和Context
**调用:**attach(true, 0),传入的system为0
```java
private void attach(boolean system, long startSeq) {
mSystemThread = system;
//传入的system为0
if (!system) {
//应用进程的处理流程
...
} else {
//系统进程的处理流程,该情况只在SystemServer中处理
//创建ActivityThread中的重要成员:Instrumentation、 Application 和 Context
mInstrumentation = new Instrumentation();
mInstrumentation.basicInit(this);
//创建系统的Context
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
//调用LoadedApk的makeApplication函数
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
}
}
```
**Instrumentation**
Instrumentation是Android中的一个工具类,当该类被启用时,它将优先于应用中其它的类被初始化。
此时,系统先创建它,再通过它创建其它组件。
```java
mInstrumentation = new Instrumentation();
mInstrumentation.basicInit(this);
```
**Context**
Context是Android中的一个抽象类,用于维护应用运行环境的全局信息。
通过Context可以访问应用的资源和类,甚至进行系统级的操作,例如启动Activity、发送广播等。
ActivityThread的attach函数中,通过下面的代码创建出系统应用对应的Context:
```java
ContextImpl context = ContextImpl.createAppContext(this, getSystemContext().mPackageInfo);
```
**Application**
Android中Application类用于保存应用的全局状态。
在ActivityThread中,针对系统进程,通过下面的代码创建了初始的Application:
```java
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
```
**[ContextImpl.java] getSystemContext()**
**说明:**创建并返回System Context
```java
public ContextImpl getSystemContext() {
synchronized (this) {
if (mSystemContext == null) {
//调用ContextImpl的静态函数createSystemContext
mSystemContext = ContextImpl.createSystemContext(this);
}
return mSystemContext;
}
}
```
**说明:**createSystemContext的内容就是创建一个LoadedApk,然后初始化一个ContextImpl对象。
注意到createSystemContext函数中,创建的LoadApk对应packageName为”android”,也就是framwork-res.apk。
由于该APK仅供SystemServer进程使用,因此创建的Context被定义为System Context。
现在该LoadedApk还没有得到framwork-res.apk实际的信息。
当PKMS启动,完成对应的解析后,AMS将重新设置这个LoadedApk。
```java
static ContextImpl createSystemContext(ActivityThread mainThread) {
//创建LoadedApk类,代表一个加载到系统中的APK
//注意此时的LoadedApk只是一个空壳
//PKMS还没有启动,无法得到有效的ApplicationInfo
LoadedApk packageInfo = new LoadedApk(mainThread);
//拿到ContextImpl 的对象
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
null, null);
//初始化资源信息
context.setResources(packageInfo.getResources());
context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
context.mResourcesManager.getDisplayMetrics());
return context;
}
```
**SystemServiceManager 创建**
**说明:** 通过 SystemServiceManager 的构造方法创建一个 SystemServiceManager 对象,并将该对象添加到 LocalServices 中。
```java
private void run() {
...
//1.创建SystemServiceManager对象
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart,
mRuntimeStartElapsedTime, mRuntimeStartUptime);
//2.启动SystemServiceManager服务
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
...
}
```
**[SystemServiceManager.java] SystemServiceManager()**
**说明:**SystemServiceManager 对象主要用于管理 SystemService 的创建、启动等生命周期,SystemService 类是一个抽象类
在 SystemServiceManager 中都是通过反射创建 SystemService 中对象的,而且在 startService(@NonNull final SystemService service) 方法中,会将 SystemService 添加到 mServices 中,并调用 onStart() 方法
SystemServiceManager构造函数没有多少内容,主要是把传进来的system Context赋值给 mContext,供后续服务创建使用
```java
public class SystemServiceManager {
...
private final Context mContext;
private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();
...
SystemServiceManager(Context context) {
mContext = context;
}
public SystemService startService(String className) {
final Class<SystemService> serviceClass;
try {
//通过反射根据类名,拿到类对象
serviceClass = (Class<SystemService>)Class.forName(className);
} catch (ClassNotFoundException ex) {
Slog.i(TAG, "Starting " + className);
...
}
return startService(serviceClass);
}
public <T extends SystemService> T startService(Class<T> serviceClass) {
try {
final String name = serviceClass.getName();
// Create the service.
final T service;
...
service = constructor.newInstance(mContext);
...
startService(service);
return service;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
public void startService(@NonNull final SystemService service) {
// Register it.
mServices.add(service);
// Start it.
long time = SystemClock.elapsedRealtime();
try {
service.onStart(); //调用各个服务中的onStart()方法完成服务启动
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + service.getClass().getName()
+ ": onStart threw an exception", ex);
}
}
}
```
**[LocalServices.java] addService(SystemServiceManager.class, mSystemServiceManager);**
**说明:**把SystemServiceManager的对象加入到本地服务的全局注册表中
```java
public final class LocalServices {
private LocalServices() {}
private static final ArrayMap<Class<?>, Object> sLocalServiceObjects =
new ArrayMap<Class<?>, Object>();
//返回实现指定接口的本地服务实例对象
@SuppressWarnings("unchecked")
public static <T> T getService(Class<T> type) {
synchronized (sLocalServiceObjects) {
return (T) sLocalServiceObjects.get(type);
}
}
//将指定接口的服务实例添加到本地服务的全局注册表中
public static <T> void addService(Class<T> type, T service) {
synchronized (sLocalServiceObjects) {
if (sLocalServiceObjects.containsKey(type)) {
throw new IllegalStateException("Overriding service registration");
}
sLocalServiceObjects.put(type, service);
}
}
//删除服务实例,只能在测试中使用。
public static <T> void removeServiceForTest(Class<T> type) {
synchronized (sLocalServiceObjects) {
sLocalServiceObjects.remove(type);
}
}
}
```
**ActivityTaskManagerService 服务启动**
**说明:**ActivityTaskManagerService简称ATM,Android10中引入新功能,用来管理Activity的启动、调度等功能
```java
private void startBootstrapServices() {
...
//启动ATM
atm = mSystemServiceManager.startService(
ActivityTaskManagerService.Lifecycle.class).getService();
...
}
```
**ATM服务启动过程**
**说明:**我们知道SystemServiceManager.startService最终调用的是启动对象中的onStart方法
因此ATM启动,最终会调用ActivityTaskManagerService.Lifecycle.onStart()来启动ATM服务
```java
public static final class Lifecycle extends SystemService {
private final ActivityTaskManagerService mService;
public Lifecycle(Context context) {
super(context);
//1.创建ActivityTaskManagerService,得到对象
mService = new ActivityTaskManagerService(context);
}
@Override
public void onStart() {
publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
//2.启动ATM服务
mService.start();
}
...
public ActivityTaskManagerService getService() {
return mService;
}
}
```
**ActivityTaskManagerService 对象创建**
**说明:**ActivityTaskManagerService简称ATM, Android10新引入功能,用来管理Activity的启动、调度等功能
Android10 中把原先在AMS中activity的管理移动到ATM中
从Android 10的代码路径可以看出,管理Activity的ATM被放入到的wm路径中,这个路径原先归WindowManagerService -WMS控制,谷歌的目的也是希望在将来把activity和window融合在一起,减少冗余代码以及AMS和WMS的协调工作
**ATM的路径为:**frameworks\base\services\core\java\com\android\server\wm
**AMS的路径为:**frameworks\base\services\core\java\com\android\server\am
```java
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
final Context mUiContext;
final ActivityThread mSystemThread;
final ActivityTaskManagerInternal mInternal;
//ActivityStackSupervisor 是ATM中用来管理Activity启动和调度的核心类
public ActivityStackSupervisor mStackSupervisor;
//Activity 容器的根节点
RootActivityContainer mRootActivityContainer;
//WMS 负责窗口的管理
WindowManagerService mWindowManager;
//这是我们目前认为是"Home" Activity的过程
WindowProcessController mHomeProcess;
public ActivityTaskManagerService(Context context) {
//拿到System Context
mContext = context;
mFactoryTest = FactoryTest.getMode();
//取出的是ActivityThread的静态变量sCurrentActivityThread
//这意味着mSystemThread与SystemServer中的ActivityThread一致
mSystemThread = ActivityThread.currentActivityThread();
//拿到System UI Context
mUiContext = mSystemThread.getSystemUiContext();
mLifecycleManager = new ClientLifecycleManager();
//拿到LocalService的对象
mInternal = new LocalService();
GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", GL_ES_VERSION_UNDEFINED);
}
}
```
**[ActivityTaskManagerService.java] start()**
**说明:**将 ActivityTaskManagerInternal添加到本地服务的全局注册表中,ActivityTaskManagerInternal为抽象类
```java
private void start() {
LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
}
```
**ActivityManagerService 服务启动**
**说明:**ActivityManagerService简称AMS,在Android 10的版本中,Activity的管理和调度移到ATM中,AMS负责 service,broadcast,provider的管理和调度
```java
private void startBootstrapServices() {
...
//启动AMS
mActivityManagerService = ActivityManagerService.Lifecycle.startService(mSystemServiceManager, atm);
...
}
```
**AMS服务启动过程**
说明:从4.3.1 中我们知道SystemServiceManager.startService最终调用的是启动对象中的onStart方法
因此AMS服务启动,最终会调用ActivityManagerService.Lifecycle.onStart()来启动ATM服务
```java
public static final class Lifecycle extends SystemService {
private final ActivityManagerService mService;
private static ActivityTaskManagerService sAtm;
public Lifecycle(Context context) {
super(context);
//1.创建ActivityManagerService,得到对象,传入ATM的对象
mService = new ActivityManagerService(context, sAtm);
}
@Override
public void onStart() {
mService.start();
}
...
public ActivityManagerService getService() {
return mService;
}
}
```
**AMS 对象创建**
说明:Android10中,Activity的管理和调度放入到ATM中执行,AMS中保留 service,broadcast,provider的管理和调度
构造函数初始化主要工作就是初始化一些变量,供之后的service,broadcast,provider的管理和调度
```java
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) {
...
//AMS的运行上下文与SystemServer一致
mContext = systemContext;
...
//取出的是ActivityThread的静态变量sCurrentActivityThread
//这意味着mSystemThread与SystemServer中的ActivityThread一致
mSystemThread = ActivityThread.currentActivityThread();
mUiContext = mSystemThread.getSystemUiContext();
mHandlerThread = new ServiceThread(TAG,
THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
mHandlerThread.start();
//处理AMS中消息的主力
mHandler = new MainHandler(mHandlerThread.getLooper());
//UiHandler对应于Android中的UiThread
mUiHandler = mInjector.getUiHandler(this);
//创建 BroadcastQueue 前台广播对象,处理超时时长是 10s
mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
"foreground", foreConstants, false);
//创建 BroadcastQueue 后台广播对象,处理超时时长是 60s
mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
"background", backConstants, true);
//创建 BroadcastQueue 分流广播对象,处理超时时长是 60s
mOffloadBroadcastQueue = new BroadcastQueue(this, mHandler,
"offload", offloadConstants, true);
mBroadcastQueues[0] = mFgBroadcastQueue;
mBroadcastQueues[1] = mBgBroadcastQueue;
mBroadcastQueues[2] = mOffloadBroadcastQueue;
// 创建 ActiveServices 对象,用于管理 ServiceRecord 对象
mServices = new ActiveServices(this);
// 创建 ProviderMap 对象,用于管理 ContentProviderRecord 对象
mProviderMap = new ProviderMap(this);
//得到ATM的对象,调用ATM.initialize
mActivityTaskManager = atm;
mActivityTaskManager.initialize(mIntentFirewall, mPendingIntentController,
DisplayThread.get().getLooper());
//得到ATM的服务信息
mAtmInternal = LocalServices.getService(
ActivityTaskManagerInternal.class);
//加入Watchdog的监控
Watchdog.getInstance().addMonitor(this);
Watchdog.getInstance().addThread(mHandler);
}
}
```
**[ActivityManagerService.java] start()**
**说明:**start中做了两件事
1)启动 CPU 监控线程,在启动 CPU 监控线程之前,首先将进程复位
2)注册电池状态服务和权限管理服务
```java
private void start() {
//1.移除所有的进程组
removeAllProcessGroups();
//启动 CPU 监控线程
mProcessCpuThread.start();
//2.注册电池状态和权限管理服务
mBatteryStatsService.publish();
mAppOpsService.publish(mContext);
Slog.d("AppOps", "AppOpsService published");
LocalServices.addService(ActivityManagerInternal.class, new LocalService());
mActivityTaskManager.onActivityManagerInternalAdded();
mUgmInternal.onActivityManagerInternalAdded();
mPendingIntentController.onActivityManagerInternalAdded();
// Wait for the synchronized block started in mProcessCpuThread,
// so that any other access to mProcessCpuTracker from main thread
// will be blocked during mProcessCpuTracker initialization.
try {
mProcessCpuInitLatch.await();
} catch (InterruptedException e) {
Slog.wtf(TAG, "Interrupted wait during start", e);
Thread.currentThread().interrupt();
throw new IllegalStateException("Interrupted wait during start");
}
}
```
**[SystemServer.java] setSystemProcess()**
**说明:**为系统进程设置应用程序实例并开始
```java
private void startOtherServices() {
Set up the Application instance for the system process and get started.
mActivityManagerService.setSystemProcess();
}
```
**[ActivityManagerService.java] setSystemProcess()**
**说明:**AMS的setSystemProcess主要有五个主要的功能:
- 注册一些服务:包括 activity、procstats、meminfo、gfxinfo、dbinfo、permission、processinfo
- 获取package名为“android”的应用的 ApplicationInfo;
- 为ActivityThread 安装 system application相关信息,将framework-res.apk对应的ApplicationInfo安装到LoadedApk中的mApplicationInfo
- 为systemserver 主进程开辟一个ProcessRecord来维护进程的相关信息
- AMS进程管理相关的操作。
```java
public void setSystemProcess() {
try {
//1.注册一些服务到ServiceManager:包括 activity、procstats、meminfo、gfxinfo、dbinfo、permission、processinfo
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_HIGH);
ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
ServiceManager.addService("dbinfo", new DbBinder(this));
if (MONITOR_CPU_USAGE) {
ServiceManager.addService("cpuinfo", new CpuBinder(this),
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
}
ServiceManager.addService("permission", new PermissionController(this));
ServiceManager.addService("processinfo", new ProcessInfoService(this));
//2.通过解析framework-res.apk里的AndroidManifest.xml获得ApplicationInfo
ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
"android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
//3.为ActivityThread 安装 system application相关信息,将framework-res.apk对应的ApplicationInfo安装到LoadedApk中的mApplicationInfo
mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
//4.为systemserver 主进程开辟一个ProcessRecord来维护进程的相关信息
synchronized (this) {
ProcessRecord app = mProcessList.newProcessRecordLocked(info, info.processName,
false,
0,
new HostingRecord("system"));
app.setPersistent(true); //设置进程常驻
app.pid = MY_PID; //为ProcessRecord赋值当前进程ID,即system_server进程ID
app.getWindowProcessController().setPid(MY_PID);
app.maxAdj = ProcessList.SYSTEM_ADJ;
app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
mPidsSelfLocked.put(app); //将ProcessRecord放到mPidSelfLocked里统一管理
mProcessList.updateLruProcessLocked(app, false, null);
updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_NONE);
}
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
"Unable to find android system package", e);
}
// Start watching app ops after we and the package manager are up and running.
mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
new IAppOpsCallback.Stub() {
@Override public void opChanged(int op, int uid, String packageName) {
if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
if (mAppOpsService.checkOperation(op, uid, packageName)
!= AppOpsManager.MODE_ALLOWED) {
runInBackgroundDisabled(uid);
}
}
}
});
}
```
**完成ActivityManagerService 最后工作[ActivityManagerService.java] systemReady()**
**说明:** AMS的systemReady 处理分为三个阶段
- 阶段1:主要是调用一些关键服务的初始化函数, 然后杀死那些没有FLAG_PERSISTENT却在AMS启动完成前已经存在的进程,
同时获取一些配置参数。 需要注意的是,由于只有Java进程才会向AMS注册,而一般的Native进程不会向AMS注册,因此此处杀死的进程是Java进程。
- 阶段2:执行goingCallback的处理,主要的工作就是通知一些服务可以进行systemReady、systemRunning相关的工作,并进行启动服务或应用进程的工作
- 阶段3:启动Home Activity,当启动结束,并发送ACTION_BOOT_COMPLETED广播时,AMS的启动过程告一段落
```java
private void startOtherServices() {
mActivityManagerService.systemReady(() -> {xxxxxgoingCallbackxxx,
BOOT_TIMINGS_TRACE_LOG);
}
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
阶段1:关键服务的初始化
阶段2:goingCallback处理
阶段3:启动Home Activity,完成AMS启动
}
```
**systemReady 阶段1**
**说明:**主要是调用一些关键服务的初始化函数, 然后杀死那些没有 FLAG_PERSISTENT 却在AMS启动完成前已经存在的进程, 同时获取一些配置参数。 需要注意的是,由于只有Java进程才会向AMS注册,而一般的Native进程不会向AMS注册,因此此处杀死的进程是Java进程。
```java
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
synchronized(this) {
//第一次进入mSystemReady 为false,不走该流程
if (mSystemReady) {
if (goingCallback != null) {
goingCallback.run();
}
return;
}
/** PowerSaveMode_start */
Settings.System.putInt(mContext.getContentResolver(),
ActivityTaskManagerService.SUPER_POWER_SAVE_MODE,
ActivityTaskManagerService.SUPER_POWER_SAVE_MODE_NORMAL);
/** PowerSaveMode_end */
//这一部分主要是调用一些关键服务SystemReady相关的函数,
//进行一些等待AMS初始完,才能进行的工作
mActivityTaskManager.onSystemReady();
mUserController.onSystemReady();
mAppOpsService.systemReady();
...
mSystemReady = true;
}
try {
sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
.getSerial();
} catch (RemoteException e) {}
ArrayList<ProcessRecord> procsToKill = null;
synchronized(mPidsSelfLocked) {
//mPidsSelfLocked 中保存当前正在运行的所有进程的信息
for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
ProcessRecord proc = mPidsSelfLocked.valueAt(i);
//在AMS启动完成前,如果没有FLAG_PERSISTENT标志的进程已经启动了,
//就将这个进程加入到procsToKill中
if (!isAllowedWhileBooting(proc.info)){
if (procsToKill == null) {
procsToKill = new ArrayList<ProcessRecord>();
}
procsToKill.add(proc);
}
}
}
//收集已经启动的进程并杀死,排除persistent常驻进程
synchronized(this) {
//利用removeProcessLocked关闭procsToKill中的进程
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);
mProcessList.removeProcessLocked(proc, true, false, "system update done");
}
}
//至此系统准备完毕
mProcessesReady = true;
}
...
mUgmInternal.onSystemReady();
}
```
**systemReady 阶段2**
**说明:**执行goingCallback的处理,主要工作就是通知一些服务可以进行systemReady的相关工作,并进行启动服务或应用进程的工作。
```Java
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
...
//1.调用参数传入的runnable对象,SystemServer中有具体的定义
if (goingCallback != null) goingCallback.run();
...
//调用所有系统服务的onStartUser接口
mSystemServiceManager.startUser(currentUserId);
synchronized (this) {
//启动persistent为1的application所在的进程
startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
// Start up initial activity.
mBooting = true;
...
}
```
**goingCallback.run()**
**说明:**监控Native的crash,启动WebView,执行一些服务的systemReady 和systemRunning方法
```Java
private void startOtherServices() {
mActivityManagerService.systemReady(() -> {
//阶段 550
mSystemServiceManager.startBootPhase(
SystemService.PHASE_ACTIVITY_MANAGER_READY);
...
//监控Native的crash
mActivityManagerService.startObservingNativeCrashes();
, BOOT_TIMINGS_TRACE_LOG);
...
//启动WebView
mWebViewUpdateService.prepareWebViewInSystemServer();
//启动systemUI
startSystemUi(context, windowManagerF);
// 执行一系列服务的systemReady方法
networkManagementF.systemReady();
ipSecServiceF.systemReady();
networkStatsF.systemReady();
connectivityF.systemReady();
networkPolicyF.systemReady(networkPolicyInitReadySignal);
...
//阶段 600
mSystemServiceManager.startBootPhase(
SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
//执行一系列服务的systemRunning方法
locationF.systemRunning();
countryDetectorF.systemRunning();
networkTimeUpdaterF.systemRunning();
inputManagerF.systemRunning();
telephonyRegistryF.systemRunning();
mediaRouterF.systemRunning();
mmsServiceF.systemRunning();
...
}
```
**[ActivityManagerService.java] startPersistentApps**
**说明:**启动persistent为1的application所在的进程
```Java
void startPersistentApps(int matchFlags) {
if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
synchronized (this) {
try {
//从PKMS中得到persistent为1的ApplicationInfo
final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
.getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
for (ApplicationInfo app : apps) {
//由于framework-res.apk已经由系统启动,所以此处不再启动它
if (!"android".equals(app.packageName)) {
//addAppLocked中将启动application所在进程
addAppLocked(app, null, false, null /* ABI override */);
}
}
} catch (RemoteException ex) {
}
}
}
```
**启动systemUI startSystemUi**
**说明:**启动system UI, 启动服务,服务名称”com.android.systemui/.SystemUIService”
```java
private static void startSystemUi(Context context, WindowManagerService windowManager) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.systemui",
"com.android.systemui.SystemUIService"));
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
//Slog.d(TAG, "Starting service: " + intent);
context.startServiceAsUser(intent, UserHandle.SYSTEM);
windowManager.onSystemUiStarted();
}
```
**systemReady 阶段3**
**说明:**启动Home Activity,当启动结束,并发送ACTION_BOOT_COMPLETED广播时,AMS的启动过程告一段落
```java
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
...
//1.通过ATM,启动Home Activity
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
...
//2.发送一些广播消息
try {
//system发送广播 ACTION_USER_STARTED = "android.intent.action.USER_STARTED";
Intent intent = new Intent(Intent.ACTION_USER_STARTED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
| Intent.FLAG_RECEIVER_FOREGROUND);
intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
broadcastIntentLocked(null, null, intent,
null, null, 0, null, null, null, OP_NONE,
null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid,
currentUserId);
//system发送广播 ACTION_USER_STARTING= "android.intent.action.USER_STARTING";
intent = new Intent(Intent.ACTION_USER_STARTING);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
broadcastIntentLocked(null, null, intent,
null, new IIntentReceiver.Stub() {
@Override
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser)
throws RemoteException {
}
}, 0, null, null,
new String[] {INTERACT_ACROSS_USERS}, OP_NONE,
null, true, false, MY_PID, SYSTEM_UID, callingUid, callingPid,
UserHandle.USER_ALL);
} catch (Throwable t) {
Slog.wtf(TAG, "Failed sending first user broadcasts", t);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
```
**[ActivityTaskManagerService] startHomeOnAllDisplays**
**说明:**启动Home Activity
**[ActivityTaskManagerService.java]**
```java
public boolean startHomeOnAllDisplays(int userId, String reason) {
synchronized (mGlobalLock) {
//调用RootActivityContainer的startHomeOnAllDisplays(),最终到startHomeOnDisplay()
return mRootActivityContainer.startHomeOnAllDisplays(userId, reason);
}
}
```
**[RootActivityContainer.java]**
```Java
boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
boolean fromHomeKey) {
// Fallback to top focused display if the displayId is invalid.
if (displayId == INVALID_DISPLAY) {
displayId = getTopDisplayFocusedStack().mDisplayId;
}
Intent homeIntent = null;
ActivityInfo aInfo = null;
if (displayId == DEFAULT_DISPLAY) {
//home intent有CATEGORY_HOME
homeIntent = mService.getHomeIntent();
//根据intent中携带的ComponentName,利用PKMS得到ActivityInfo
aInfo = resolveHomeActivity(userId, homeIntent);
} else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) {
Pair<ActivityInfo, Intent> info =
RootActivityContainerMifavor.resolveSecondaryHomeActivityPcMode(this, userId, displayId);
aInfo = info.first;
homeIntent = info.second;
}
if (aInfo == null || homeIntent == null) {
return false;
}
if (!canStartHomeOnDisplay(aInfo, displayId, allowInstrumenting)) {
return false;
}
// Updates the home component of the intent.
homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
// Updates the extra information of the intent.
if (fromHomeKey) {
homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);
}
// Update the reason for ANR debugging to verify if the user activity is the one that
// actually launched.
final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
aInfo.applicationInfo.uid) + ":" + displayId;
//启动Home Activity--Luncher
mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
displayId);
return true;
}
```
###### 小结:
**AMS的启动主要经历了如下几个阶段:**
- 为SystemServer进程创建Android运行环境,例如System Context
- 启动AMS,做一些初始化的工作
- 将SystemServer进程纳入到AMS的进程管理体系中
- AMS启动完成,通知服务或应用完成后续的工作,调用一些服务的systemReady()方法
- 启动Luncher,完成AMS的启动工作
##### 5、Launcher(桌面)启动流程
###### 5.1 概述
Launcher不支持桌面小工具动画效果,Launcher2添加了动画效果和3D初步效果支持,从Android 4.4 (KK)开始Launcher默认使用Launcher3,Launcher3加入了透明状态栏,增加overview模式,可以调整workspace上页面的前后顺序,可以动态管理屏幕数量,widget列表与app list分开显示等功能。
###### 5.2 核心源码
```
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
/frameworks/base/core/java/com/android/internal/os/Zygote.java
/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
/frameworks/base/services/java/com/android/server/SystemServer.java
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
/frameworks/base/services/core/java/com/android/server/am/ProcessList.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
/frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
/frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
/frameworks/base/core/java/android/os/Process.java
/frameworks/base/core/java/android/os/ZygoteProcess.java
/frameworks/base/core/java/android/app/ActivityThread.java
/frameworks/base/core/java/android/app/Activity.java
/frameworks/base/core/java/android/app/ActivityManagerInternal.java
/frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
/frameworks/base/core/java/android/app/servertransaction/ClientTransaction.aidl
/frameworks/base/core/java/android/app/ClientTransactionHandler.java
/frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
/frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
/frameworks/base/core/java/android/app/Instrumentation.java
/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
```
从上面的代码路径可以看出,Android10.0中 Activity的相关功能被放到了wm的目录中,在Android9.0中是在am目录中,Google 最终的目的是把activity 和window融合,在Android10中只是做了简单的代码路径的变更,正式的功能还要到后面的版本才能慢慢融合。
**主要代码作用:**
- Instrumentation:
负责调用Activity和Application生命周期。
- ActivityTaskManagerService:
负责Activity管理和调度等工作。
ATM是Android10中新增内容
- ActivityManagerService:
负责管理四大组件和进程,包括生命周期和状态切换。
- ActivityTaskManagerInternal:
是由ActivityTaskManagerService对外提供的一个抽象类,真正的实现是在 ActivityTaskManagerService#LocalService
- ActivityThread:
管理应用程序进程中主线程的执行
- ActivityStackSupervisor:
负责所有Activity栈的管理
- TransactionExecutor:
主要作用是执行ClientTransaction
- ClientLifecycleManager:
生命周期的管理调用
###### 5.3 架构
```mermaid
graph TB
A[Boot ROM]-->B[BootLoader]
B--加载内核-->C[Kernel]
C--启动-->D[init]
D--解析文件-->E[init.rc]
E-->F[loop]
E-.启动进程.->EA[Zygote]
E-.->EB[service_manager]
E-.->EC[SurfaceFlinger]
E-.->ED[MediaServer]
EA--启动-->EAA[虚拟机]
EAA-->EAB[fork]
EAB-->EAC[loop]
EAB-.->EABA[system_server]
EABA--启动-->EABC[系统服务]
EABC--显示-->EABD[启动界面]
EABD--启动-->EABE[Launcher]
EABE-.->EAB
EAB-.fork.->EABF[Launcher]
EABF--显示-->EABG[桌面]
EB-->EBA[Binder]
EBA-->EBC[loop]
EC-->ECA[FrameBuffer]
ECA-->ECB[loop]
ED-->EDA[AudioFlinger]
EDA-->EDB[CameraService]
EDB-->EDD[MediaPlayerService]
EDD-->EDE[loop]
ECA-.->EBA
EABC-->EABCA(系统服务 AMS PMS InputManagerService WMS)
EABCA-.->EBA
```
###### 5.4 源码分析
AMS启动完成前,在systemReady()中会去调用startHomeOnAllDisplays()来启动Launcher,所以从startHomeOnAllDisplays()函数入口,对Launcher启动过程进行分析。
```Java
[ActivityManagerService.java]
public void systemReady(final Runnable goingCallback, TimingsTraceLog
traceLog) {
...
//启动Home Activity
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
...
}
```
**Launcher的启动由三部分启动:**
- SystemServer完成启动Launcher Activity的调用
- Zygote()进行Launcher进程的Fork操作
- 进入ActivityThread的main(),完成最终Launcher的onCreate操作
###### 5.5第一阶段SystemServer 启动HomeActivity的调用阶段
**[ActivityTaskManagerService.java] startHomeOnAllDisplays()**
**说明:**ActivityTaskManagerInternal是 ActivityTaskManagerService的一个抽象类,真正的实现是在ActivityTaskManagerService的LocalService,所以mAtmInternal.startHomeOnAllDisplays()最终调用的是ActivityTaskManagerService的startHomeOnAllDisplays()方法
```java
public boolean startHomeOnAllDisplays(int userId, String reason) {
synchronized (mGlobalLock) {
//一路调用到 RootActivityContainer 的startHomeOnDisplay()方法
return mRootActivityContainer.startHomeOnAllDisplays(userId, reason);
}
}
```
**[RootActivityContainer.java] startHomeOnDisplay()**
**说明:**在`startHomeOnAllDisplays`中,获取的displayId为DEFAULT_DISPLAY, 首先通过getHomeIntent 来构建一个category为CATEGORY_HOME的Intent,表明是Home Activity;然后通过resolveHomeActivity()从系统所用已安装的引用中,找到一个符合HomeItent的Activity,最终调用startHomeActivity()来启动Activity
```Java
boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
boolean fromHomeKey) {
...
if (displayId == DEFAULT_DISPLAY) {
//构建一个category为CATEGORY_HOME的Intent,表明是Home Activity
homeIntent = mService.getHomeIntent();
//通过PKMS从系统所用已安装的引用中,找到一个符合HomeItent的Activity
aInfo = resolveHomeActivity(userId, homeIntent);
}
...
//启动Home Activity
mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
displayId);
return true;
}
```
**[ActivityTaskManagerService.java] getHomeIntent()**
**说明:**构建一个category为CATEGORY_HOME的Intent,表明是Home Activity。
Intent.CATEGORY_HOME = "android.intent.category.HOME"
这个category会在Launcher3的 AndroidManifest.xml中配置,表明是Home Acivity
```Java
Intent getHomeIntent() {
Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
intent.setComponent(mTopComponent);
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
//不是生产模式,add一个CATEGORY_HOME
if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
intent.addCategory(Intent.CATEGORY_HOME);
}
return intent;
}
```
**[RootActivityContainer.java] resolveHomeActivity()**
**说明:**通过Binder跨进程通知PackageManagerService从系统所有已安装的引用中,找到一个符合HomeItent的Activity
```Java
ActivityInfo resolveHomeActivity(int userId, Intent homeIntent) {
final int flags = ActivityManagerService.STOCK_PM_FLAGS;
final ComponentName comp = homeIntent.getComponent(); //系统正常启动时,component为null
ActivityInfo aInfo = null;
...
if (comp != null) {
// Factory test.
aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
} else {
//系统正常启动时,走该流程
final String resolvedType =
homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
//resolveIntent做了两件事:1.通过queryIntentActivities来查找符合HomeIntent需求的Activities
// 2.通过chooseBestActivity找到最符合Intent需求的Activity信息
final ResolveInfo info = AppGlobals.getPackageManager()
.resolveIntent(homeIntent, resolvedType, flags, userId);
if (info != null) {
aInfo = info.activityInfo;
}
}
...
aInfo = new ActivityInfo(aInfo);
aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId);
return aInfo;
}
```
**[ActivityStartController.java ] startHomeActivity()**
**说明:**启动的Home Activity入口。obtainStarter() 方法返回的是 ActivityStarter 对象,它负责 Activity 的启动,一系列 setXXX() 方法传入启动所需的各种参数,最后的 execute() 是真正的启动逻辑。另外如果home activity处于顶层的resume activity中,则Home Activity 将被初始化,但不会被恢复。并将保持这种状态,直到有东西再次触发它。我们需要进行一次恢复。
```Java
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) {
....
//返回一个 ActivityStarter 对象,它负责 Activity 的启动
//一系列 setXXX() 方法传入启动所需的各种参数,最后的 execute() 是真正的启动逻辑
//最后执行 ActivityStarter的execute方法
mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
.setOutActivity(tmpOutRecord)
.setCallingUid(0)
.setActivityInfo(aInfo)
.setActivityOptions(options.toBundle())
.execute();
mLastHomeActivityStartRecord = tmpOutRecord[0];
final ActivityDisplay display =
mService.mRootActivityContainer.getActivityDisplay(displayId);
final ActivityStack homeStack = display != null ? display.getHomeStack() : null;
if (homeStack != null && homeStack.mInResumeTopActivity) {
//如果home activity 处于顶层的resume activity中,则Home Activity 将被初始化,但不会被恢复(以避免递归恢复),
//并将保持这种状态,直到有东西再次触发它。我们需要进行另一次恢复。
mSupervisor.scheduleResumeTopActivities();
}
}
```
**[ActivityStarter.java] execute()**
**说明:**在startHomeActivity中obtainStarter没有调用setMayWait的方法,因此mRequest.mayWait为false,走startActivity流程
```Java
int execute() {
...
if (mRequest.mayWait) {
return startActivityMayWait(...)
} else {
return startActivity(...) //走这里
}
...
}
```
**[ActivityStarter.java] startActivity()**
**说明:**延时布局,然后通过startActivityUnchecked()来处理启动标记 flag ,要启动的任务栈等,最后恢复布局
```Java
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity, boolean restrictedBgActivity) {
...
try {
//延时布局
mService.mWindowManager.deferSurfaceLayout();
//调用 startActivityUnchecked ,一路调用到resumeFocusedStacksTopActivities()
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
} finally {
//恢复布局
mService.mWindowManager.continueSurfaceLayout();
}
...
}
```
**[RootActivityContainer.java] resumeFocusedStacksTopActivities()**
**说明:**获取栈顶的Activity,恢复它
```Java
boolean resumeFocusedStacksTopActivities(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
...
//如果秒表栈就是栈顶Activity,启动resumeTopActivityUncheckedLocked()
if (targetStack != null && (targetStack.isTopStackOnDisplay()
|| getTopDisplayFocusedStack() == targetStack)) {
result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
...
if (!resumedOnDisplay) {
// 获取 栈顶的 ActivityRecord
final ActivityStack focusedStack = display.getFocusedStack();
if (focusedStack != null) {
//最终调用startSpecificActivityLocked()
focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
}
}
}
```
**[ActivityStackSupervisor.java] startSpecificActivityLocked()**
**说明:**发布消息以启动进程,以避免在ATM锁保持的情况下调用AMS时可能出现死锁,最终调用到ATM的startProcess()
```Java
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
...
//发布消息以启动进程,以避免在ATM锁保持的情况下调用AMS时可能出现死锁
//最终调用到AMS的startProcess()
final Message msg = PooledLambda.obtainMessage(
ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
mService.mH.sendMessage(msg);
...
}
```
**[ActivityManagerService.java] startProcess()**
**说明:**一路调用Process start(),最终到ZygoteProcess的attemptUsapSendArgsAndGetResult(),用来fork一个新的Launcher的进程
```Java
public void startProcess(String processName, ApplicationInfo info,
boolean knownToBeDead, String hostingType, ComponentName hostingName) {
..
//同步操作,避免死锁
synchronized (ActivityManagerService.this) {
//调用startProcessLocked,然后到 Process的start,最终到ZygoteProcess的attemptUsapSendArgsAndGetResult()
//用来fork一个新的Launcher的进程
startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
new HostingRecord(hostingType, hostingName),
false /* allowWhileBooting */, false /* isolated */,
true /* keepIfLarge */);
}
...
}
```
**[ZygoteProcess.java] attemptZygoteSendArgsAndGetResult()**
**说明:**通过Socket连接Zygote进程,把之前组装的msg发给Zygote,其中processClass ="android.app.ActivityThread",通过Zygote进程来Fork出一个新的进程,并执行 "android.app.ActivityThread"的main方法
```Java
private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
try {
//传入的zygoteState为openZygoteSocketIfNeeded(),里面会通过abi来检查是第一个zygote还是第二个
final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
zygoteWriter.write(msgStr); //把应用进程的一些参数写给前面连接的zygote进程,包括前面的processClass ="android.app.ActivityThread"
zygoteWriter.flush(); //进入Zygote进程,处于阻塞状态
//从socket中得到zygote创建的应用pid,赋值给 ProcessStartResult的对象
Process.ProcessStartResult result = new Process.ProcessStartResult();
result.pid = zygoteInputStream.readInt();
result.usingWrapper = zygoteInputStream.readBoolean();
if (result.pid < 0) {
throw new ZygoteStartFailedEx("fork() failed");
}
return result;
} catch (IOException ex) {
zygoteState.close();
Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
+ ex.toString());
throw new ZygoteStartFailedEx(ex);
}
}
```
###### 5.6 第二阶段Zygote fork一个Launcher进程的阶段
**说明:**Zygote的启动过程前面有详细讲到过。SystemServer的AMS服务向启动Home Activity发起一个fork请求,Zygote进程通过Linux的fork函数,孵化出一个新的进程。
由于Zygote进程在启动时会创建Java虚拟机,因此通过fork而创建的Launcher程序进程可以在内部获取一个Java虚拟机的实例拷贝。fork采用copy-on-write机制,有些类如果不做改变,甚至都不用复制,子进程可以和父进程共享这部分数据,从而省去不少内存的占用。
**[ZygoteInit.java] main()**
**说明:**Zygote先fork出SystemServer进程,接着进入循环等待,用来接收Socket发来的消息,用来fork出其他应用进程,比如Launcher
```Java
public static void main(String argv[]) {
...
Runnable caller;
....
if (startSystemServer) {
//Zygote Fork出的第一个进程 SystmeServer
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
if (r != null) {
r.run();
return;
}
}
...
//循环等待fork出其他的应用进程,比如Launcher
//最终通过调用processOneCommand()来进行进程的处理
caller = zygoteServer.runSelectLoop(abiList);
...
if (caller != null) {
caller.run(); //执行返回的Runnable对象,进入子进程
}
}
```
**[ZygoteConnection.java] processOneCommand()**
**说明:**通过forkAndSpecialize()来fork出Launcher的子进程,并执行handleChildProc,进入子进程的处理
```Java
Runnable processOneCommand(ZygoteServer zygoteServer) {
int pid = -1;
...
//Fork子进程,得到一个新的pid
/fork子进程,采用copy on write方式,这里执行一次,会返回两次
///pid=0 表示Zygote fork子进程成功
//pid > 0 表示子进程 的真正的PID
pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion);
...
if (pid == 0) {
// in child, fork成功,第一次返回的pid = 0
...
//执行handleChildProc,进入子进程的处理
return handleChildProc(parsedArgs, descriptors, childPipeFd,
parsedArgs.mStartChildZygote);
} else {
//in parent
...
childPipeFd = null;
handleParentProc(pid, descriptors, serverPipeFd);
return null;
}
}
```
**[ZygoteConnection.java] handleChildProc()**
**说明:**进行子进程的操作,最终获得需要执行的ActivityThread的main()
```Java
private Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors,
FileDescriptor pipeFd, boolean isZygote) {
...
if (parsedArgs.mInvokeWith != null) {
...
throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
} else {
if (!isZygote) {
// App进程将会调用到这里,执行目标类的main()方法
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */);
}
}
}
```
zygoteInit 进行一些环境的初始化、启动Binder进程等操作:
```Java
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
RuntimeInit.commonInit(); //初始化运行环境
ZygoteInit.nativeZygoteInit(); //启动Binder线程池
//调用程序入口函数
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
```
把之前传来的"android.app.ActivityThread" 传递给findStaticMain:
```Java
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
...
// startClass: 如果AMS通过socket传递过来的是 ActivityThread
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
```
通过反射,拿到ActivityThread的main()方法:
```Java
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}
return new MethodAndArgsCaller(m, argv);
}
```
把反射得来的ActivityThread main()入口返回给ZygoteInit的main,通过caller.run()进行调用:
```Java
static class MethodAndArgsCaller implements Runnable {
/** method to call */
private final Method mMethod;
/** argument array */
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
//调用ActivityThread的main()
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);
}
}
}
```
###### 5.7 第三个阶段,Launcher在自己的进程中进行onCreate等后面的动作
从第二个阶段可以看到,Zygote fork出了Launcher的进程,并把接下来的Launcher启动任务交给了ActivityThread来进行,接下来就从ActivityThread main()来分析Launcher的创建过程。
**[ActivityThread.java] main()**
**说明:**主线程处理, 创建ActivityThread对象,调用attach进行处理,最终进入Looper循环
```Java
public static void main(String[] args) {
// 安装选择性的系统调用拦截
AndroidOs.install();
...
//主线程处理
Looper.prepareMainLooper();
...
//之前SystemServer调用attach传入的是true,这里的应用进程传入false就行
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
...
//一直循环,如果退出,说明程序关闭
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
```
调用ActivityThread的attach进行处理
```Java
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
//应用进程启动,走该流程
...
RuntimeInit.setApplicationObject(mAppThread.asBinder());
//获取AMS的本地代理类
final IActivityManager mgr = ActivityManager.getService();
try {
//通过Binder调用AMS的attachApplication方法
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
} else {
//通过system_server启动ActivityThread对象
...
}
// 为 ViewRootImpl 设置配置更新回调,
当系统资源配置(如:系统字体)发生变化时,通知系统配置发生变化
ViewRootImpl.ConfigChangedCallback configChangedCallback
= (Configuration globalConfig) -> {
synchronized (mResourcesManager) {
...
}
};
ViewRootImpl.addConfigCallback(configChangedCallback);
}
```
**[ActivityManagerService.java] attachApplication()**
**说明:**清除一些无用的记录,最终调用ActivityStackSupervisor.java的 realStartActivityLocked(),进行Activity的启动
```Java
public final void attachApplication(IApplicationThread thread, long startSeq) {
synchronized (this) {
//通过Binder获取传入的pid信息
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
Binder.restoreCallingIdentity(origId);
}
}
```
```Java
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid, int callingUid, long startSeq) {
...
//如果当前的Application记录仍然依附到之前的进程中,则清理掉
if (app.thread != null) {
handleAppDiedLocked(app, true, true);
}·
//mProcessesReady这个变量在AMS的 systemReady 中被赋值为true,
//所以这里的normalMode也为true
boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
...
//上面说到,这里为true,进入StackSupervisor的attachApplication方法
//去真正启动Activity
if (normalMode) {
...
//调用ATM的attachApplication(),最终层层调用到ActivityStackSupervisor.java的 realStartActivityLocked()
//参考[4.5.3]
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
...
}
...
return true;
}
```
**[ActivityStackSupervisor.java] realStartActivityLocked()**
**说明:**真正准备去启动Activity,通过clientTransaction.addCallback把LaunchActivityItem的obtain作为回调参数加进去,再调用
ClientLifecycleManager.scheduleTransaction()得到
LaunchActivityItem的execute()方法进行最终的执行
```Java
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
// 直到所有的 onPause() 执行结束才会去启动新的 activity
if (!mRootActivityContainer.allPausedActivitiesComplete()) {
...
return false;
}
try {
// Create activity launch transaction.
// 添加 LaunchActivityItem
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);
//LaunchActivityItem.obtain(new Intent(r.intent)作为回调参数
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global
// and override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
r.icicle, r.persistentState, results, newIntents,
dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
r.assistToken));
...
// 设置生命周期状态
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// Schedule transaction.
// 重点关注:调用 ClientLifecycleManager.scheduleTransaction(),得到上面addCallback的LaunchActivityItem的execute()方法
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
} catch (RemoteException e) {
if (r.launchFailed) {
// 第二次启动失败,finish activity
stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
"2nd-crash", false);
return false;
}
// 第一次失败,重启进程并重试
r.launchFailed = true;
proc.removeActivity(r);
throw e;
}
} finally {
endDeferResume();
}
...
return true;
}
```
**[TransactionExecutor.java] execute()**
**说明**:执行之前realStartActivityLocked()中的
clientTransaction.addCallback
```Java
public void execute(ClientTransaction transaction) {
...
// 执行 callBack,参考上面的调用栈,执行回调方法,
//最终调用到ActivityThread的handleLaunchActivity()参考[4.5.5]
executeCallbacks(transaction);
// 执行生命周期状态
executeLifecycleState(transaction);
mPendingActions.clear();
}
```
**[ActivityThread.java] handleLaunchActivity()**
**说明:**主要干了两件事,第一件:初始化WindowManagerGlobal;第二件:调用performLaunchActivity方法
```Java
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
...
//初始化WindowManagerGlobal
WindowManagerGlobal.initialize();
...
//调用performLaunchActivity,来处理Activity
final Activity a = performLaunchActivity(r, customIntent);
..
return a;
}
```
**[ActivityThread.java] performLaunchActivity()**
**说明:**获取ComponentName、Context,反射创建Activity,设置Activity的一些内容,比如主题等; 最终调用callActivityOnCreate()来执行Activity的onCreate()方法
```Java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// 获取 ComponentName
ComponentName component = r.intent.getComponent();
...
// 获取 Context
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
// 反射创建 Activity
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
...
}
try {
// 获取 Application
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
...
//Activity的一些处理
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback,
r.assistToken);
if (customIntent != null) {
activity.mIntent = customIntent;
}
...
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
// 设置主题
activity.setTheme(theme);
}
activity.mCalled = false;
// 执行 onCreate()
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
r.activity = activity;
}
//当前状态为ON_CREATE
r.setState(ON_CREATE);
...
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
...
}
return activity;
}
```
callActivityOnCreate先执行activity onCreate的预处理,再去调用Activity的onCreate,最终完成Create创建后的内容处理
```Java
public void callActivityOnCreate(Activity activity, Bundle icicle,
PersistableBundle persistentState) {
prePerformCreate(activity); //activity onCreate的预处理
activity.performCreate(icicle, persistentState);//执行onCreate()
postPerformCreate(activity); //activity onCreate创建后的一些信息处理
}
```
performCreate()主要调用Activity的onCreate()
```Java
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
...
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
...
}
```
至此,看到了我们最熟悉的Activity的onCreate(),Launcher的启动完成,Launcher被真正创建起来。
###### 小结
看到onCreate()后,进入到我们最熟悉的Activity的入口,Launcher的启动告一段落。整个Android的启动流程,我们也完整的分析完成。
Launcher的启动经过了三个阶段:
- 第一个阶段:SystemServer完成启动Launcher Activity的调用
- 第二个阶段:Zygote()进行Launcher进程的Fork操作
- 第三个阶段:进入ActivityThread的main(),完成最终Launcher的onCreate操作
##### 总结
- - 第一步:手机开机后,引导芯片启动,引导芯片开始从固化在ROM里的预设代码执行,加载引导程序到到RAM,bootloader检查RAM,初始化硬件参数等功能;
- 第二步:硬件等参数初始化完成后,进入到Kernel层,Kernel层主要加载一些硬件设备驱动,初始化进程管理等操作。在Kernel中首先启动swapper进程(pid=0),用于初始化进程管理、内管管理、加载Driver等操作,再启动kthread进程(pid=2),这些linux系统的内核进程,kthread是所有内核进程的鼻祖;
- 第三步:Kernel层加载完毕后,硬件设备驱动与HAL层进行交互。初始化进程管理等操作会启动INIT进程 ,这些在Native层中;
- 第四步:init进程(pid=1,init进程是所有进程的鼻祖,第一个启动)启动后,会启动adbd,logd等用户守护进程,并且会启动servicemanager(binder服务管家)等重要服务,同时孵化出zygote进程,这里属于C++ Framework,代码为C++程序;
- 第五步:zygote进程是由init进程解析init.rc文件后fork生成,它会加载虚拟机,启动System Server(zygote孵化的第一个进程);System Server负责启动和管理整个Java Framework,包含ActivityManager,WindowManager,PackageManager,PowerManager等服务;
- 第六步:zygote同时会启动相关的APP进程,它启动的第一个APP进程为Launcher,然后启动Email,SMS等进程,所有的APP进程都由zygote fork生成。
### Android系统开机流程
[TOC]
#### 一、开机流程
##### 1、启动init进程
###### 1.1 概述
init进程是Linux系统中用户空间的第一个进程,进程号为1。
当用户按下开机按钮,引导芯片加载BootLoader到内存中,开始拉起Linux OS,当kernel启动完毕后,在用户空间启动init进程,再通过init进程来读取`init. rc`中的相关配置,从而启动其他相关进程以及其他操作。
init进程启动胡政尧分为两个阶段:
1. 第一阶段: - ueventd/watchdog的跳转及环境设置 - 挂载文件系统并创建目录 - 初始化日志输出、挂载分区设备 - 启用SELinux安全策略 - 开始第二阶段前的准备2. 第二阶段: - 初始化属性系统 - 执行SELinux第二阶段并恢复一些文件安全上下文 - 新建epoll并初始化子进程终止信号处理函数 - 设置其他系统属性并开启属性服务
###### 1.2 架构
- **init进程的启动**
```mermaid graph LR A[kernel_init] -->B[设置体系结构相关的环境] A --> C[初始化内存结构] A --> D[初始化设备和驱动等] A --> E[开启MMU并建立页表] A --> F[初始化串口] A --> G[.........] A --> O[启动init进程] D --> P[do_basic_steup] E --> I[numa_default_policy] O --> II[run_init_process] ```
init 进程是在kernel启动后,启动的第一个用户空间进程,PID为1。
kernel_init启动后,完成一些init的初始化操作,然后去系统根目录下依次找ramdisk_execute_command和execute_command设置的应用程序,如果这两个目录都找不到,就依次去根目录下找 /sbin/init,/etc/init,/bin/init,/bin/sh 这四个应用程序进行启动,只要这些应用程序有一个启动了,其他就不启动了。
- **init启动后**
```mermaidgraph LRA[mian函数] -->B[ueventd跳转] A --> C[启动init进程第一阶段 加载文件系统 创建目录] A --> D[日志初始化] A --> E[启动SELinux服务] A --> F[启动init进程第二阶段 启动属性服务 加载进程] B --> BB[ueventd_main] C --> CC[FirstStageMain] D --> DD[InitLogging] E --> EE[SetupSelinux] F --> FF[SecondStageMain]```
Init进程启动后,首先挂载文件系统、再挂载相应的分区,启动SELinux安全策略,启动属性服务,解析rc文件,并启动相应属性服务进程,初始化epoll,依次设置signal、property、keychord这3个fd可读时相对应的回调函数。进入无限循环,用来响应各个进程的变化与重建。
###### 1.3 kernel启动init进程的源码分析
**kernel_init:**
代码路径:kernel-4.9/init/main.c
```cstatic int __ref kernel_init(void *unused){kernel_init_freeable(); //进行init进程的一些初始化操作/* need to finish all async __init code before freeing the memory */async_synchronize_full();// 等待所有异步调用执行完成,,在释放内存前,必须完成所有的异步 _init代码free_initmem();// 释放所有init.* 段中的内存mark_readonly(); //修改页表,保证只读数据段为只读属性read onlysystem_state = SYSTEM_RUNNING;// 设置系统状态为运行状态numa_default_policy(); // 设定NUMA作为系统的默认内存访问策略 if (ramdisk_execute_command) { //ramdisk_execute_command的值为"/init"if (!run_init_process(ramdisk_execute_command)) //运行根目录下的init程序return 0;pr_err("Failed to execute %s\n", ramdisk_execute_command);} /* * We try each of these until one succeeds. * * The Bourne shell can be used instead of init if we are * trying to recover a really broken machine. */if (execute_command) { //execute_command的值如果有定义就去根目录下找对应的应用程序,然后启动if (!run_init_process(execute_command))return 0;pr_err("Failed to execute %s. Attempting defaults...\n",execute_command);}if (!run_init_process("/sbin/init") || //如果ramdisk_execute_command和execute_command定义的应用程序都没有找到,//就到根目录下找 /sbin/init,/etc/init,/bin/init,/bin/sh 这四个应用程序进行启动 !run_init_process("/etc/init") || !run_init_process("/bin/init") || !run_init_process("/bin/sh"))return 0; panic("No init found. Try passing init= option to kernel. " "See Linux Documentation/init.txt for guidance.");}```
**do_basic_setup:**
代码路径:kernel-4.9/init/main.c
```cstatic void __init do_basic_setup(void){cpuset_init_smp();//针对SMP系统,初始化内核control group的cpuset子系统。shmem_init();// 初始化共享内存driver_init();// 初始化设备驱动init_irq_proc();//创建/proc/irq目录, 并初始化系统中所有中断对应的子目录do_ctors();// 执行内核的构造函数usermodehelper_enable();// 启用usermodehelperdo_initcalls();//遍历initcall_levels数组,调用里面的initcall函数,这里主要是对设备、驱动、文件系统进行初始化,//之所以将函数封装到数组进行遍历,主要是为了好扩展}```
**init进程入口**
代码路径:system/core/init/main.cpp
* ```c /* * 1.第一个参数argc表示参数个数,第二个参数是参数列表,也就是具体的参数 * 2.main函数有四个参数入口, *一是参数中有ueventd,进入ueventd_main *二是参数中有subcontext,进入InitLogging 和SubcontextMain *三是参数中有selinux_setup,进入SetupSelinux *四是参数中有second_stage,进入SecondStageMain * 3.main的执行顺序如下: * (1)ueventd_main init进程创建子进程ueventd, * 并将创建设备节点文件的工作托付给ueventd,ueventd通过两种方式创建设备节点文件 * (2)FirstStageMain 启动第一阶段 * (3)SetupSelinux 加载selinux规则,并设置selinux日志,完成SELinux相关工作 * (4)SecondStageMain 启动第二阶段 */ int main(int argc, char** argv) { //当argv[0]的内容为ueventd时,strcmp的值为0,!strcmp为1 //1表示true,也就执行ueventd_main,ueventd主要是负责设备节点的创建、权限设定等一些列工作 if (!strcmp(basename(argv[0]), "ueventd")) { return ueventd_main(argc, argv); } //当传入的参数个数大于1时,执行下面的几个操作 if (argc > 1) { //参数为subcontext,初始化日志系统, if (!strcmp(argv[1], "subcontext")) { android::base::InitLogging(argv, &android::base::KernelLogger); const BuiltinFunctionMap function_map; return SubcontextMain(argc, argv, &function_map); } //参数为“selinux_setup”,启动Selinux安全策略 if (!strcmp(argv[1], "selinux_setup")) { return SetupSelinux(argv); } //参数为“second_stage”,启动init进程第二阶段 if (!strcmp(argv[1], "second_stage")) { return SecondStageMain(argc, argv); } } // 默认启动init进程第一阶段 return FirstStageMain(argc, argv); } ```
**ueventd_main**
代码路径:system/core/init/ueventd.cpp
Android根文件系统的镜像中不存在“/dev”目录,该目录是init进程启动后动态创建的。
因此,建立Android中设备节点文件的重任,也落在了init进程身上。为此,init进程创建子进程ueventd,并将创建设备节点文件的工作托付给ueventd。
ueventd通过两种方式创建设备节点文件。
第一种方式对应“冷插拔”(Cold Plug),即以预先定义的设备信息为基础,当ueventd启动后,统一创建设备节点文件。这一类设备节点文件也被称为静态节点文件。
第二种方式对应“热插拔”(Hot Plug),即在系统运行中,当有设备插入USB端口时,ueventd就会接收到这一事件,为插入的设备动态创建设备节点文件。这一类设备节点文件也被称为动态节点文件。
```cpp int ueventd_main(int argc, char** argv) { //设置新建文件的默认值,这个与chmod相反,这里相当于新建文件后的权限为666 umask(000); //初始化内核日志,位于节点/dev/kmsg, 此时logd、logcat进程还没有起来, //采用kernel的log系统,打开的设备节点/dev/kmsg, 那么可通过cat /dev/kmsg来获取内核log。 android::base::InitLogging(argv, &android::base::KernelLogger); //注册selinux相关的用于打印log的回调函数 SelinuxSetupKernelLogging(); SelabelInitialize(); //解析xml,根据不同SOC厂商获取不同的hardware rc文件 auto ueventd_configuration = ParseConfig({"/ueventd.rc", "/vendor/ueventd.rc", "/odm/ueventd.rc", "/ueventd." + hardware + ".rc"}); //冷启动 if (access(COLDBOOT_DONE, F_OK) != 0) { ColdBoot cold_boot(uevent_listener, uevent_handlers); cold_boot.Run(); } for (auto& uevent_handler : uevent_handlers) { uevent_handler->ColdbootDone(); } //忽略子进程终止信号 signal(SIGCHLD, SIG_IGN); // Reap and pending children that exited between the last call to waitpid() and setting SIG_IGN // for SIGCHLD above. //在最后一次调用waitpid()和为上面的sigchld设置SIG_IGN之间退出的获取和挂起的子级 while (waitpid(-1, nullptr, WNOHANG) > 0) { } //监听来自驱动的uevent,进行“热插拔”处理 uevent_listener.Poll([&uevent_handlers](const Uevent& uevent) { for (auto& uevent_handler : uevent_handlers) { uevent_handler->HandleUevent(uevent); //热启动,创建设备 } return ListenerAction::kContinue; }); return 0; } ```
###### 1.4 init进程启动第一阶段
代码地址:system/core/init/first_stage_init.cpp
init进程第一阶段做的主要工作是挂载分区,创建设备节点和一些关键目录,初始化日志输出系统,启用SELinux安全策略
第一阶段完成以下内容:
/* 01. 创建文件系统目录并挂载相关的文件系统 */
/* 02. 屏蔽标准的输入输出/初始化内核log系统 */
**FirstStageMain**
代码地址:system/core/init/first_stage_init.cpp
```cint FirstStageMain(int argc, char** argv) { //init crash时重启引导加载程序 //这个函数主要作用将各种信号量,如SIGABRT,SIGBUS等的行为设置为SA_RESTART,一旦监听到这些信号即执行重启系统 if (REBOOT_BOOTLOADER_ON_PANIC) { InstallRebootSignalHandlers(); } //清空文件权限 umask(0); CHECKCALL(clearenv()); CHECKCALL(setenv("PATH", _PATH_DEFPATH, 1)); //在RAM内存上获取基本的文件系统,剩余的被rc文件所用 CHECKCALL(mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755")); CHECKCALL(mkdir("/dev/pts", 0755)); CHECKCALL(mkdir("/dev/socket", 0755)); CHECKCALL(mount("devpts", "/dev/pts", "devpts", 0, NULL));#define MAKE_STR(x) __STRING(x) CHECKCALL(mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC)));#undef MAKE_STR // 非特权应用不能使用Andrlid cmdline CHECKCALL(chmod("/proc/cmdline", 0440)); gid_t groups[] = {AID_READPROC}; CHECKCALL(setgroups(arraysize(groups), groups)); CHECKCALL(mount("sysfs", "/sys", "sysfs", 0, NULL)); CHECKCALL(mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL)); CHECKCALL(mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11))); if constexpr (WORLD_WRITABLE_KMSG) { CHECKCALL(mknod("/dev/kmsg_debug", S_IFCHR | 0622, makedev(1, 11))); } CHECKCALL(mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8))); CHECKCALL(mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9))); //这对于日志包装器是必需的,它在ueventd运行之前被调用 CHECKCALL(mknod("/dev/ptmx", S_IFCHR | 0666, makedev(5, 2))); CHECKCALL(mknod("/dev/null", S_IFCHR | 0666, makedev(1, 3))); //在第一阶段挂在tmpfs、mnt/vendor、mount/product分区。其他的分区不需要在第一阶段加载, //只需要在第二阶段通过rc文件解析来加载。 CHECKCALL(mount("tmpfs", "/mnt", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV, "mode=0755,uid=0,gid=1000")); //创建可供读写的vendor目录 CHECKCALL(mkdir("/mnt/vendor", 0755)); // /mnt/product is used to mount product-specific partitions that can not be // part of the product partition, e.g. because they are mounted read-write. CHECKCALL(mkdir("/mnt/product", 0755)); // 挂载APEX,这在Android 10.0中特殊引入,用来解决碎片化问题,类似一种组件方式,对Treble的增强, // 不写谷歌特殊更新不需要完整升级整个系统版本,只需要像升级APK一样,进行APEX组件升级 CHECKCALL(mount("tmpfs", "/apex", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV, "mode=0755,uid=0,gid=0")); // /debug_ramdisk is used to preserve additional files from the debug ramdisk CHECKCALL(mount("tmpfs", "/debug_ramdisk", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV, "mode=0755,uid=0,gid=0"));#undef CHECKCALL //把标准输入、标准输出和标准错误重定向到空设备文件"/dev/null" SetStdioToDevNull(argv); //在/dev目录下挂载好 tmpfs 以及 kmsg //这样就可以初始化 /kernel Log 系统,供用户打印log InitKernelLogging(argv); ... /* 初始化一些必须的分区 *主要作用是去解析/proc/device-tree/firmware/android/fstab, * 然后得到"/system", "/vendor", "/odm"三个目录的挂载信息 */ if (!DoFirstStageMount()) { LOG(FATAL) << "Failed to mount required partitions early ..."; } struct stat new_root_info; if (stat("/", &new_root_info) != 0) { PLOG(ERROR) << "Could not stat(\"/\"), not freeing ramdisk"; old_root_dir.reset(); } if (old_root_dir && old_root_info.st_dev != new_root_info.st_dev) { FreeRamdisk(old_root_dir.get(), old_root_info.st_dev); } SetInitAvbVersionInRecovery(); static constexpr uint32_t kNanosecondsPerMillisecond = 1e6; uint64_t start_ms = start_time.time_since_epoch().count() / kNanosecondsPerMillisecond; setenv("INIT_STARTED_AT", std::to_string(start_ms).c_str(), 1); //启动init进程,传入参数selinux_steup // 执行命令: /system/bin/init selinux_setup const char* path = "/system/bin/init"; const char* args[] = {path, "selinux_setup", nullptr}; execv(path, const_cast<char**>(args)); PLOG(FATAL) << "execv(\"" << path << "\") failed"; return 1;}```
**加载SELinux规则**
SELinux是「Security-Enhanced Linux」的简称,是美国国家安全局「NSA=The National Security Agency」
和SCC(Secure Computing Corporation)开发的 Linux的一个扩张强制访问控制安全模块。
在这种访问控制体系的限制下,进程只能访问那些在他的任务中所需要文件。
selinux有两种工作模式:
permissive,所有的操作都被允许(即没有MAC),但是如果违反权限的话,会记录日志,一般eng模式用enforcing,所有操作都会进行权限检查。一般user和user-debug模式用不管是security_setenforce还是security_getenforce都是去操作/sys/fs/selinux/enforce 文件, 0表示permissive 1表示enforcing
**SetupSelinux**
初始化selinux,加载SELinux规则,配置SELinux相关log输出,并启动第二阶段
代码路径:system\core\init\selinux.cpp
```c/*此函数初始化selinux,然后执行init以在init selinux中运行*/int SetupSelinux(char** argv) { //初始化Kernel日志 InitKernelLogging(argv); // Debug版本init crash时重启引导加载程序 if (REBOOT_BOOTLOADER_ON_PANIC) { InstallRebootSignalHandlers(); } //注册回调,用来设置需要写入kmsg的selinux日志 SelinuxSetupKernelLogging(); //加载SELinux规则 SelinuxInitialize(); /* *我们在内核域中,希望转换到init域。在其xattrs中存储selabel的文件系统(如ext4)不需要显式restorecon, *但其他文件系统需要。尤其是对于ramdisk,如对于a/b设备的恢复映像,这是必需要做的一步。 *其实就是当前在内核域中,在加载Seliux后,需要重新执行init切换到C空间的用户态 */ if (selinux_android_restorecon("/system/bin/init", 0) == -1) { PLOG(FATAL) << "restorecon failed of /system/bin/init failed"; } //准备启动innit进程,传入参数second_stage //执行 /system/bin/init second_stage, 进入第二阶段 const char* path = "/system/bin/init"; const char* args[] = {path, "second_stage", nullptr}; execv(path, const_cast<char**>(args)); PLOG(FATAL) << "execv(\"" << path << "\") failed"; return 1;}```
**SelinuxInitialize()**
```c/*加载selinux 规则*/void SelinuxInitialize() { LOG(INFO) << "Loading SELinux policy"; if (!LoadPolicy()) { LOG(FATAL) << "Unable to load SELinux policy"; } //获取当前Kernel的工作模式 bool kernel_enforcing = (security_getenforce() == 1); //获取工作模式的配置 bool is_enforcing = IsEnforcing(); //如果当前的工作模式与配置的不同,就将当前的工作模式改掉 if (kernel_enforcing != is_enforcing) { if (security_setenforce(is_enforcing)) { PLOG(FATAL) << "security_setenforce(" << (is_enforcing ? "true" : "false") << ") failed"; } } if (auto result = WriteFile("/sys/fs/selinux/checkreqprot", "0"); !result) { LOG(FATAL) << "Unable to write to /sys/fs/selinux/checkreqprot: " << result.error(); }}```
```c/* *加载SELinux规则 *这里区分了两种情况,这两种情况只是区分从哪里加载安全策略文件, *第一个是从 /vendor/etc/selinux/precompiled_sepolicy 读取, *第二个是从 /sepolicy 读取,他们最终都是调用selinux_android_load_policy_from_fd方法 */bool LoadPolicy() { return IsSplitPolicyDevice() ? LoadSplitPolicy() : LoadMonolithicPolicy();}```
###### 1.5 init进程启动第二阶段
第二阶段主要内容:
- 创建进程会话密钥并初始化属性系统- 进行SELinux第二阶段并恢复一些文件安全上下文- 新建epoll并初始化子进程终止信号处理函数- 启动匹配属性的服务端- 解析init.rc等文件,建立rc文件的action 、service,启动其他进程
```mermaidgraph LRA[SecondStageMain] -->B[创建进程会话并初始化属性系统] A --> C[进行SELinux第二阶段并恢复一些文件安全上下文] A --> D[新建epoll并初始化子进程 终止信号处理函数] A --> E[设置其他系统属性并开启系统属性服务] A --> F[解析init.rc等文件,建立rc文件的action和service,启动其他进程] B --> BB[keyctl_get_keyring_ID和property_init] C --> CC[SelinuxRestoreContext] D --> DD[InstallSignalFdHandler] E --> EE[StartProperService] F --> FF[LoadBootScripts]```
**SecondStageMain**
代码地址:system/core/init/init.cpp
```cint SecondStageMain(int argc, char** argv) { /* 01. 创建进程会话密钥并初始化属性系统 */ keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 1); //创建 /dev/.booting 文件,就是个标记,表示booting进行中 close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000)); // 初始化属性系统,并从指定文件读取属性 property_init(); /* 02. 进行SELinux第二阶段并恢复一些文件安全上下文 */ SelinuxRestoreContext(); /* 03. 新建epoll并初始化子进程终止信号处理函数 */ Epoll epoll; if (auto result = epoll.Open(); !result) { PLOG(FATAL) << result.error(); } InstallSignalFdHandler(&epoll); /* 04. 设置其他系统属性并开启系统属性服务*/ StartPropertyService(&epoll); /* 05 解析init.rc等文件,建立rc文件的action 、service,启动其他进程*/ ActionManager& am = ActionManager::GetInstance(); ServiceList& sm = ServiceList::GetInstance(); LoadBootScripts(am, sm);}```
代码详解:
```cint SecondStageMain(int argc, char** argv) { /* *init crash时重启引导加载程序 *这个函数主要作用将各种信号量,如SIGABRT,SIGBUS等的行为设置为SA_RESTART,一旦监听到这些信号即执行重启系统 */ if (REBOOT_BOOTLOADER_ON_PANIC) { InstallRebootSignalHandlers(); } //把标准输入、标准输出和标准错误重定向到空设备文件"/dev/null" SetStdioToDevNull(argv); //在/dev目录下挂载好 tmpfs 以及 kmsg //这样就可以初始化 /kernel Log 系统,供用户打印log InitKernelLogging(argv); LOG(INFO) << "init second stage started!"; // 01. 创建进程会话密钥并初始化属性系统 keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 1); //创建 /dev/.booting 文件,就是个标记,表示booting进行中 close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000)); // 初始化属性系统,并从指定文件读取属性 property_init(); /* * 1.如果参数同时从命令行和DT传过来,DT的优先级总是大于命令行的 * 2.DT即device-tree,中文意思是设备树,这里面记录自己的硬件配置和系统运行参数, */ process_kernel_dt(); // 处理 DT属性 process_kernel_cmdline(); // 处理命令行属性 // 处理一些其他的属性 export_kernel_boot_props(); // Make the time that init started available for bootstat to log. property_set("ro.boottime.init", getenv("INIT_STARTED_AT")); property_set("ro.boottime.init.selinux", getenv("INIT_SELINUX_TOOK")); // Set libavb version for Framework-only OTA match in Treble build. const char* avb_version = getenv("INIT_AVB_VERSION"); if (avb_version) property_set("ro.boot.avb_version", avb_version); // See if need to load debug props to allow adb root, when the device is unlocked. const char* force_debuggable_env = getenv("INIT_FORCE_DEBUGGABLE"); if (force_debuggable_env && AvbHandle::IsDeviceUnlocked()) { load_debug_prop = "true"s == force_debuggable_env; } // 基于cmdline设置memcg属性 bool memcg_enabled = android::base::GetBoolProperty("ro.boot.memcg",false); if (memcg_enabled) { // root memory control cgroup mkdir("/dev/memcg", 0700); chown("/dev/memcg",AID_ROOT,AID_SYSTEM); mount("none", "/dev/memcg", "cgroup", 0, "memory"); // app mem cgroups, used by activity manager, lmkd and zygote mkdir("/dev/memcg/apps/",0755); chown("/dev/memcg/apps/",AID_SYSTEM,AID_SYSTEM); mkdir("/dev/memcg/system",0550); chown("/dev/memcg/system",AID_SYSTEM,AID_SYSTEM); } // 清空这些环境变量,之前已经存到了系统属性中去了 unsetenv("INIT_STARTED_AT"); unsetenv("INIT_SELINUX_TOOK"); unsetenv("INIT_AVB_VERSION"); unsetenv("INIT_FORCE_DEBUGGABLE"); // Now set up SELinux for second stage. SelinuxSetupKernelLogging(); SelabelInitialize(); /* * 02. 进行SELinux第二阶段并恢复一些文件安全上下文 * 恢复相关文件的安全上下文,因为这些文件是在SELinux安全机制初始化前创建的, * 所以需要重新恢复上下文 */ SelinuxRestoreContext(); /* * 03. 新建epoll并初始化子进程终止信号处理函数 * 创建epoll实例,并返回epoll的文件描述符 */ Epoll epoll; if (auto result = epoll.Open(); !result) { PLOG(FATAL) << result.error(); } /* *主要是创建handler处理子进程终止信号,注册一个signal到epoll进行监听 *进行子继承处理 */ InstallSignalFdHandler(&epoll); // 进行默认属性配置相关的工作 property_load_boot_defaults(load_debug_prop); UmountDebugRamdisk(); fs_mgr_vendor_overlay_mount_all(); export_oem_lock_status(); /* *04. 设置其他系统属性并开启系统属性服务 */ StartPropertyService(&epoll); MountHandler mount_handler(&epoll); //为USB存储设置udc Contorller, sys/class/udc set_usb_controller(); // 匹配命令和函数之间的对应关系 const BuiltinFunctionMap function_map; Action::set_function_map(&function_map); if (!SetupMountNamespaces()) { PLOG(FATAL) << "SetupMountNamespaces failed"; } // 初始化文件上下文 subcontexts = InitializeSubcontexts(); /* *05 解析init.rc等文件,建立rc文件的action 、service,启动其他进程 */ ActionManager& am = ActionManager::GetInstance(); ServiceList& sm = ServiceList::GetInstance(); LoadBootScripts(am, sm); // Turning this on and letting the INFO logging be discarded adds 0.2s to // Nexus 9 boot time, so it's disabled by default. if (false) DumpState(); // 当GSI脚本running时,确保GSI状态可用. if (android::gsi::IsGsiRunning()) { property_set("ro.gsid.image_running", "1"); } else { property_set("ro.gsid.image_running", "0"); } am.QueueBuiltinAction(SetupCgroupsAction, "SetupCgroups"); // 执行rc文件中触发器为 on early-init 的语句 am.QueueEventTrigger("early-init"); // 等冷插拔设备初始化完成 am.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done"); // 开始查询来自 /dev的 action am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng"); am.QueueBuiltinAction(SetMmapRndBitsAction, "SetMmapRndBits"); am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict"); // 设备组合键的初始化操作 Keychords keychords; am.QueueBuiltinAction( [&epoll, &keychords](const BuiltinArguments& args) -> Result<Success> { for (const auto& svc : ServiceList::GetInstance()) { keychords.Register(svc->keycodes()); } keychords.Start(&epoll, HandleKeychord); return Success(); }, "KeychordInit"); //在屏幕上显示Android 静态LOGO am.QueueBuiltinAction(console_init_action, "console_init"); // 执行rc文件中触发器为on init的语句 am.QueueEventTrigger("init"); // Starting the BoringSSL self test, for NIAP certification compliance. am.QueueBuiltinAction(StartBoringSslSelfTest, "StartBoringSslSelfTest"); // Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random // wasn't ready immediately after wait_for_coldboot_done am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng"); // Initialize binder before bringing up other system services am.QueueBuiltinAction(InitBinder, "InitBinder"); // 当设备处于充电模式时,不需要mount文件系统或者启动系统服务 // 充电模式下,将charger假如执行队列,否则把late-init假如执行队列 std::string bootmode = GetProperty("ro.bootmode", ""); if (bootmode == "charger") { am.QueueEventTrigger("charger"); } else { am.QueueEventTrigger("late-init"); } // 基于属性当前状态 运行所有的属性触发器. am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers"); while (true) { // By default, sleep until something happens. auto epoll_timeout = std::optional<std::chrono::milliseconds>{}; if (do_shutdown && !shutting_down) { do_shutdown = false; if (HandlePowerctlMessage(shutdown_command)) { shutting_down = true; } } //依次执行每个action中携带command对应的执行函数 if (!(waiting_for_prop || Service::is_exec_service_running())) { am.ExecuteOneCommand(); } if (!(waiting_for_prop || Service::is_exec_service_running())) { if (!shutting_down) { auto next_process_action_time = HandleProcessActions(); // If there's a process that needs restarting, wake up in time for that. if (next_process_action_time) { epoll_timeout = std::chrono::ceil<std::chrono::milliseconds>( *next_process_action_time - boot_clock::now()); if (*epoll_timeout < 0ms) epoll_timeout = 0ms; } } // If there's more work to do, wake up again immediately. if (am.HasMoreCommands()) epoll_timeout = 0ms; } // 循环等待事件发生 if (auto result = epoll.Wait(epoll_timeout); !result) { LOG(ERROR) << result.error(); } } return 0;}```
**信号处理**
init是一个守护进程,为了防止init的子进程成为僵尸进程(zombie process),需要init在子进程在结束时获取子进程的结束码,通过结束码将程序表中的子进程移除,防止成为僵尸进程的子进程占用程序表的空间(程序表的空间达到上限时,系统就不能再启动新的进程了,会引起严重的系统问题)。**子进程重启流程:**
```mermaidgraph LRA[fork子进程] -.->B[终止子线程] B --产生SIGHLD信号-->C[Init进程] C --service_start-->A C -->D{oneshot} D --Y-->E[放弃启动] D --N-->F[重启子线程] ```
**信号处理主要工作:**
- 初始化信号signal句柄- 循环处理子进程- 注册epoll句柄- 处理子进程终止
**InstallSignalFdHandler**
在linux当中,父进程是通过捕捉SIGCHLD信号来得知子进程运行结束的情况,SIGCHLD信号会在子进程终止的时候发出。
- 首先,新建一个sigaction结构体,sa_handler是信号处理函数,指向内核指定的函数指针SIG_DFL和Android 9.0及之前的版本不同,这里不再通过socket的读写句柄进行接收信号,改成了内核的信号处理函数SIG_DFL。- 然后,sigaction(SIGCHLD, &act, nullptr) 这个是建立信号绑定关系,也就是说当监听到SIGCHLD信号时,由act这个sigaction结构体处理- 最后,RegisterHandler 的作用就是signal_read_fd(之前的s[1])收到信号,触发handle_signal
综上,InstallSignalFdHandler函数的作用就是,接收到SIGCHLD信号时触发HandleSignalFd进行信号处理
**信号处理:**
```mermaidgraph LRA[终止子进程] --产生SIGCHLD信号-->B[SIG_DFL] B -->C[signal_fd] C -->D[epoll_fd] D -->E[HandleSignalFd] E -->F[ReapOneProcess] F -->G[决定是否重启子线程]```
代码路径:system/core/init/init.cpp
该函数主要的作用是初始化子进程终止信号处理过程
```cstatic void InstallSignalFdHandler(Epoll* epoll) { // SA_NOCLDSTOP使init进程只有在其子进程终止时才会收到SIGCHLD信号 const struct sigaction act { .sa_handler = SIG_DFL, .sa_flags = SA_NOCLDSTOP }; sigaction(SIGCHLD, &act, nullptr); sigset_t mask; sigemptyset(&mask); sigaddset(&mask, SIGCHLD); if (!IsRebootCapable()) { // 如果init不具有 CAP_SYS_BOOT的能力,则它此时正值容器中运行 // 在这种场景下,接收SIGTERM 将会导致系统关闭 sigaddset(&mask, SIGTERM); } if (sigprocmask(SIG_BLOCK, &mask, nullptr) == -1) { PLOG(FATAL) << "failed to block signals"; } // 注册处理程序以解除对子进程中的信号的阻止 const int result = pthread_atfork(nullptr, nullptr, &UnblockSignals); if (result != 0) { LOG(FATAL) << "Failed to register a fork handler: " << strerror(result); } //创建信号句柄 signal_fd = signalfd(-1, &mask, SFD_CLOEXEC); if (signal_fd == -1) { PLOG(FATAL) << "failed to create signalfd"; } //信号注册,当signal_fd收到信号时,触发HandleSignalFd if (auto result = epoll->RegisterHandler(signal_fd, HandleSignalFd); !result) { LOG(FATAL) << result.error(); }}```
**RegistHandler**
代码路径:system/core/init/epoll.cpp
信号注册,把fd句柄加入到 epoll_fd_的监听队列中
```cResult<void> Epoll::RegisterHandler(int fd, std::function<void()> handler, uint32_t events) { if (!events) { return Error() << "Must specify events"; } auto [it, inserted] = epoll_handlers_.emplace(fd, std::move(handler)); if (!inserted) { return Error() << "Cannot specify two epoll handlers for a given FD"; } epoll_event ev; ev.events = events; // std::map's iterators do not get invalidated until erased, so we use the // pointer to the std::function in the map directly for epoll_ctl. ev.data.ptr = reinterpret_cast<void*>(&it->second); // 将fd的可读事件加入到epoll_fd_的监听队列中 if (epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, fd, &ev) == -1) { Result<void> result = ErrnoError() << "epoll_ctl failed to add fd"; epoll_handlers_.erase(fd); return result; } return {};}```
**HandleSignalFd**
代码路径:system/core/init/init.cpp
监控SIGCHLD信号,调用 ReapAnyOutstandingChildren 来 终止出现问题的子进程。
```cstatic void HandleSignalFd() { signalfd_siginfo siginfo; ssize_t bytes_read = TEMP_FAILURE_RETRY(read(signal_fd, &siginfo, sizeof(siginfo))); if (bytes_read != sizeof(siginfo)) { PLOG(ERROR) << "Failed to read siginfo from signal_fd"; return; } //监控SIGCHLD信号 switch (siginfo.ssi_signo) { case SIGCHLD: ReapAnyOutstandingChildren(); break; case SIGTERM: HandleSigtermSignal(siginfo); break; default: PLOG(ERROR) << "signal_fd: received unexpected signal " << siginfo.ssi_signo; break; }}```
**ReapOneProcess**
代码路径:system/core/init/sigchld_handler.cpp
ReapOneProcess是最终的处理函数了,这个函数先用waitpid找出挂掉进程的pid,然后根据pid找到对应Service,
最后调用Service的Reap方法清除资源,根据进程对应的类型,决定是否重启机器或重启进程
```cvoid ReapAnyOutstandingChildren() { while (ReapOneProcess()) { }} static bool ReapOneProcess() { siginfo_t siginfo = {}; //用waitpid函数获取状态发生变化的子进程pid //waitpid的标记为WNOHANG,即非阻塞,返回为正值就说明有进程挂掉了 if (TEMP_FAILURE_RETRY(waitid(P_ALL, 0, &siginfo, WEXITED | WNOHANG | WNOWAIT)) != 0) { PLOG(ERROR) << "waitid failed"; return false; } auto pid = siginfo.si_pid; if (pid == 0) return false; // 当我们知道当前有一个僵尸pid,我们使用scopeguard来清楚该pid auto reaper = make_scope_guard([pid] { TEMP_FAILURE_RETRY(waitpid(pid, nullptr, WNOHANG)); }); std::string name; std::string wait_string; Service* service = nullptr; if (SubcontextChildReap(pid)) { name = "Subcontext"; } else { //通过pid找到对应的service service = ServiceList::GetInstance().FindService(pid, &Service::pid); if (service) { name = StringPrintf("Service '%s' (pid %d)", service->name().c_str(), pid); if (service->flags() & SVC_EXEC) { auto exec_duration = boot_clock::now() - service->time_started(); auto exec_duration_ms = std::chrono::duration_cast<std::chrono::milliseconds>(exec_duration).count(); wait_string = StringPrintf(" waiting took %f seconds", exec_duration_ms / 1000.0f); } else if (service->flags() & SVC_ONESHOT) { auto exec_duration = boot_clock::now() - service->time_started(); auto exec_duration_ms = std::chrono::duration_cast<std::chrono::milliseconds>(exec_duration) .count(); wait_string = StringPrintf(" oneshot service took %f seconds in background",exec_duration_ms / 1000.0f); } } else { name = StringPrintf("Untracked pid %d", pid); } } if (siginfo.si_code == CLD_EXITED) { LOG(INFO) << name << " exited with status " << siginfo.si_status << wait_string; } else { LOG(INFO) << name << " received signal " << siginfo.si_status << wait_string; } //没有找到service,说明已经结束了,退出 if (!service) return true; service->Reap(siginfo);//清除子进程相关的资源 if (service->flags() & SVC_TEMPORARY) { ServiceList::GetInstance().RemoveService(*service); //移除该service } return true;}```
###### 1.6 属性服务
不是所有进程都可以随意修改任何的系统属性,Android将属性的设置统一交由init进程管理,其他进程不能直接修改属性,而只能通知init进程来修改,而在这过程中,init进程可以进行权限控制,具体的流程如下:
**property_init**
代码路径:system/core/init/property_service.cpp
作用:
- 初始化属性系统,并从指定文件读取属性,并进行SELinux注册,进行属性权限控制
- 清除缓存,这里主要是清除几个链表以及在内存中的映射,新建property_filename目录,这个目录的值为 /dev/_properties_
- 然后就是调用CreateSerializedPropertyInfo加载一些系统属性的类别信息,最后将加载的链表写入文件并映射到内存
```c void property_init() { //设置SELinux回调,进行权限控制 selinux_callback cb; cb.func_audit = PropertyAuditCallback; selinux_set_callback(SELINUX_CB_AUDIT, cb); mkdir("/dev/__properties__", S_IRWXU | S_IXGRP | S_IXOTH); CreateSerializedPropertyInfo(); if (__system_property_area_init()) { LOG(FATAL) << "Failed to initialize property area"; } if (!property_info_area.LoadDefaultPath()) { LOG(FATAL) << "Failed to load serialized property info file"; } } ```
**通过CreateSerializedPropertyInfo 来加载以下目录的contexts**:
**1)与SELinux相关**
```/system/etc/selinux/plat_property_contexts/vendor/etc/selinux/vendor_property_contexts/vendor/etc/selinux/nonplat_property_contexts/product/etc/selinux/product_property_contexts/odm/etc/selinux/odm_property_contexts```
**2)与SELinux无关**
```/plat_property_contexts/vendor_property_contexts/nonplat_property_contexts/product_property_contexts/odm_property_contexts```
**StartPropertyService**
代码地址:system/core/init/init.cpp
说明:启动属性服务
首先创建一个socket并返回文件描述符,然后设置最大并发数为8,其他进程可以通过这个socket通知init进程修改系统属性,最后注册epoll事件,也就是当监听到property_set_fd改变时调用handle_property_set_fd
```cvoid StartPropertyService(Epoll* epoll) { property_set("ro.property_service.version", "2"); //建立socket连接 if (auto result = CreateSocket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, false, 0666, 0, 0, {})) { property_set_fd = *result; } else { PLOG(FATAL) << "start_property_service socket creation failed: " << result.error(); } // 最大监听8个并发 listen(property_set_fd, 8); // 注册property_set_fd,当收到句柄改变时,通过handle_property_set_fd来处理 if (auto result = epoll->RegisterHandler(property_set_fd, handle_property_set_fd); !result) { PLOG(FATAL) << result.error(); }}```
**handle_proerty_set_fd**
代码路径:system/core/init/property_service.cpp
建立socket连接,然后从socket中读取操作信息,根据不同的操作类型,调用HandlePropertySet做具体的操作
HandlePropertySet是最终的处理函数,以"ctl"开头的key就做一些Service的Start,Stop,Restart操作,其他的就是调用property_set进行属性设置,不管是前者还是后者,都要进行SELinux安全性检查,只有该进程有操作权限才能执行相应操作
```cstatic void handle_property_set_fd() { static constexpr uint32_t kDefaultSocketTimeout = 2000; /* ms */ // 等待客户端连接 int s = accept4(property_set_fd, nullptr, nullptr, SOCK_CLOEXEC); if (s == -1) { return; } ucred cr; socklen_t cr_size = sizeof(cr); // 获取连接到此socket的进程的凭据 if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cr, &cr_size) < 0) { close(s); PLOG(ERROR) << "sys_prop: unable to get SO_PEERCRED"; return; } // 建立socket连接 SocketConnection socket(s, cr); uint32_t timeout_ms = kDefaultSocketTimeout; uint32_t cmd = 0; // 读取socket中的操作信息 if (!socket.RecvUint32(&cmd, &timeout_ms)) { PLOG(ERROR) << "sys_prop: error while reading command from the socket"; socket.SendUint32(PROP_ERROR_READ_CMD); return; } // 根据操作信息,执行对应处理,两者区别一个是以char形式读取,一个以String形式读取 switch (cmd) { case PROP_MSG_SETPROP: { char prop_name[PROP_NAME_MAX]; char prop_value[PROP_VALUE_MAX]; if (!socket.RecvChars(prop_name, PROP_NAME_MAX, &timeout_ms) || !socket.RecvChars(prop_value, PROP_VALUE_MAX, &timeout_ms)) { PLOG(ERROR) << "sys_prop(PROP_MSG_SETPROP): error while reading name/value from the socket"; return; } prop_name[PROP_NAME_MAX-1] = 0; prop_value[PROP_VALUE_MAX-1] = 0; std::string source_context; if (!socket.GetSourceContext(&source_context)) { PLOG(ERROR) << "Unable to set property '" << prop_name << "': getpeercon() failed"; return; } const auto& cr = socket.cred(); std::string error; uint32_t result = HandlePropertySet(prop_name, prop_value, source_context, cr, &error); if (result != PROP_SUCCESS) { LOG(ERROR) << "Unable to set property '" << prop_name << "' from uid:" << cr.uid << " gid:" << cr.gid << " pid:" << cr.pid << ": " << error; } break; } case PROP_MSG_SETPROP2: { std::string name; std::string value; if (!socket.RecvString(&name, &timeout_ms) || !socket.RecvString(&value, &timeout_ms)) { PLOG(ERROR) << "sys_prop(PROP_MSG_SETPROP2): error while reading name/value from the socket"; socket.SendUint32(PROP_ERROR_READ_DATA); return; } std::string source_context; if (!socket.GetSourceContext(&source_context)) { PLOG(ERROR) << "Unable to set property '" << name << "': getpeercon() failed"; socket.SendUint32(PROP_ERROR_PERMISSION_DENIED); return; } const auto& cr = socket.cred(); std::string error; uint32_t result = HandlePropertySet(name, value, source_context, cr, &error); if (result != PROP_SUCCESS) { LOG(ERROR) << "Unable to set property '" << name << "' from uid:" << cr.uid << " gid:" << cr.gid << " pid:" << cr.pid << ": " << error; } socket.SendUint32(result); break; } default: LOG(ERROR) << "sys_prop: invalid command " << cmd; socket.SendUint32(PROP_ERROR_INVALID_CMD); break; }}```
###### 1.7 第三阶段init.rc
当属性服务建立完成后,init的自身功能基本就告一段落,接下来需要来启动其他的进程。
其他进程都是一个二进制文件,我们可以直接通过exec的命令方式来启动,例如 ./system/bin/init second_stage,来启动init进程的第二阶段。但是Android系统有很多的Native进程,如果都通过传exec在代码中一个个的来执行进程,那是一种很糟糕的设计。
在这个基础上Android推出了一个init.rc的机制,即类似通过读取配置文件的方式,来启动不同的进程。
关于init.rc文件:
init.rc文件是一个非常重要的配置文件,它由AIL(Android Init Language)编写,其中定义了六个基本概念、两个基本关键字和多个指令关键字:
> 六个基本概念分别是Section、Action、Service、Trigger、Command、Option。>> 两个基本关键字是on和service。>> 指令关键字则定义在Trigger、Command和Option中。>> 其帮助文档位于/system/core/init/readme.txt,其关键字定义位于/system/core/init/keyword.h。>> 关键字on用来声明一个Action。>> 关键字service用来声明一个Service。>> 每一个Action或者Service都隐含是一个Section,init.rc就是由不同的Section组成的。>> Command是最小的功能单位,代表一个Linux命令或者一个方法调用。>> Trigger代表一个自定义的触发条件,用来触发Action的执行,也可以认为它是Action的名称。>> 一个Action便是由关键字on声明、由Trigger触发的一组Command序列。>> Option是Service的修饰符,由它来指定何时、如何启动Service程序。>> 每一个Service都是init进程的子进程,由关键字service、服务名、服务对应的命令的路径、命令的参数和Option组成,代表一些要在初始化阶段启动的程序。
```mermaidgraph LRA[init.rc] -->B[import]A -->C[on]A -->D[service]C -->CC[1.early_Init]C -->CCC[2.on boot]C -->CCCC[3.on init]C -->CCCCC[4.on late_init]D -->DD[1.Service]DD -->DDd[name 执行名称]DD -->DDdd[path 执行路径]DD -->DDddd[arg 执行参数]D -->DDD[2.user]D -->DDDD[3.group]D -->DDDDD[4.onshot或disable]```
**Action**
动作表示了一组命令(commands)组成.动作包括一个触发器,决定了何时运行这个动作
Action: 通过触发器trigger,即以on开头的语句来决定执行相应的service的时机,具体有如下时机:
- on early-init; 在初始化早期阶段触发;- on init; 在初始化阶段触发;- on late-init; 在初始化晚期阶段触发;- on boot/charger: 当系统启动/充电时触发;- on property:\<key>=\<value>: 当属性值满足条件时触发;
**Command**
command是action的命令列表中的命令,或者是service中的选项 onrestart 的参数命令,命令将在所属事件发生时被一个个地执行.
常用命令如下:
- class_start <service_class_name>: 启动属于同一个class的所有服务;- class_stop <service_class_name> : 停止指定类的服务- start <service_name>: 启动指定的服务,若已启动则跳过;- stop <service_name>: 停止正在运行的服务- setprop \<name> \<value>:设置属性值- mkdir \<path>:创建指定目录- symlink \<target> <sym_link>: 创建连接到\<target>的<sym_link>符号链接;- write \<path> \<string>: 向文件path中写入字符串;- exec: fork并执行,会阻塞init进程直到程序完毕;- exprot \<name> \<name>:设定环境变量;- loglevel \<level>:设置log级别- hostname \<name> : 设置主机名- import \<filename> :导入一个额外的init配置文件
**Service**
服务Service,以 service开头,由init进程启动,一般运行在init的一个子进程,所以启动service前需要判断对应的可执行文件是否存在。
**命令:**service \<name>\<pathname> [ \<argument> ]* \<option> \<option>
| 参数 | 含义 || :---------: | :--------------------------------------------------: || \<name> | 表示此服务的名称 || \<pathname> | 此服务所在路径因为是可执行文件,所以一定有存储路径。 || \<argument> | 启动服务所带的参数 || \<option> | 对此服务的约束选项 |
init生成的子进程,定义在rc文件,其中每一个service在启动时会通过fork方式生成子进程。
**eg:** service servicemanager /system/bin/servicemanager代表的是服务名为servicemanager,服务执行的路径为/system/bin/servicemanager。
**Options**
Options是Service的可选项,与service配合使用
- disabled: 不随class自动启动,只有根据service名才启动;- oneshot: service退出后不再重启;- user/group: 设置执行服务的用户/用户组,默认都是root;- class:设置所属的类名,当所属类启动/退出时,服务也启动/停止,默认为default;- onrestart:当服务重启时执行相应命令;- socket: 创建名为/dev/socket/<name>的socket- critical: 在规定时间内该service不断重启,则系统会重启并进入恢复模式
default: 意味着disabled=false,oneshot=false,critical=false。
**import**
用来导入其他的rc文件
**命令:**import \<filename>
**init.rc解析过程**
- **LoadBootScripts**
代码路径:system/core/init/init.cpp
说明:如果没有特殊配置ro.boot.init_rc,则解析./init.rc
把/system/etc/init,/product/etc/init,/product_services/etc/init,/odm/etc/init,
/vendor/etc/init 这几个路径加入init.rc之后解析的路径,在init.rc解析完成后,解析这些目录里的rc文件
```c static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) { Parser parser = CreateParser(action_manager, service_list); std::string bootscript = GetProperty("ro.boot.init_rc", ""); if (bootscript.empty()) { parser.ParseConfig("/init.rc"); if (!parser.ParseConfig("/system/etc/init")) { late_import_paths.emplace_back("/system/etc/init"); } if (!parser.ParseConfig("/product/etc/init")) { late_import_paths.emplace_back("/product/etc/init"); } if (!parser.ParseConfig("/product_services/etc/init")) { late_import_paths.emplace_back("/product_services/etc/init"); } if (!parser.ParseConfig("/odm/etc/init")) { late_import_paths.emplace_back("/odm/etc/init"); } if (!parser.ParseConfig("/vendor/etc/init")) { late_import_paths.emplace_back("/vendor/etc/init"); } } else { parser.ParseConfig(bootscript); } } ```
**注意:**Android7.0后,init.rc进行了拆分,每个服务都有自己的rc文件,他们基本上都被加载到/system/etc/init,/vendor/etc/init, /odm/etc/init等目录,等init.rc解析完成后,会来解析这些目录中的rc文件,用来执行相关的动作。
代码路径:system/core/init/init.cpp
```c Parser CreateParser(ActionManager& action_manager, ServiceList& service_list) { Parser parser; parser.AddSectionParser( "service", std::make_unique<ServiceParser>(&service_list, subcontexts, std::nullopt)); parser.AddSectionParser("on", std::make_unique<ActionParser>(&action_manager, subcontexts)); parser.AddSectionParser("import", std::make_unique<ImportParser>(&parser)); return parser; } ```
- **执行Action动作**
按顺序把相关Action加入触发器队列,按顺序为 early-init -> init -> late-init. 然后在循环中,执行所有触发器队列中Action带Command的执行函数。
```c am.QueueEventTrigger("early-init"); am.QueueEventTrigger("init"); am.QueueEventTrigger("late-init"); ... while (true) { if (!(waiting_for_prop || Service::is_exec_service_running())) { am.ExecuteOneCommand(); } } ```
- **Zygote启动**
从Android 5.0的版本开始,Android支持64位的编译,因此zygote本身也支持32位和64位。通过属性ro.zygote来控制不同版本的zygote进程启动。
在init.rc的import段我们看到如下代码:
```cimport /init.${ro.zygote}.rc // 可以看出init.rc不再直接引入一个固定的文件,而是根据属性ro.zygote的内容来引入不同的文件```
init.rc位于/system/core/rootdir下。在这个路径下还包括四个关于zygote的rc文件。
分别是init.zygote32.rc,init.zygote32_64.rc,init.zygote64.rc,init.zygote64_32.rc,由硬件决定调用哪个文件。
这里拿64位处理器为例,init.zygote64.rc的代码如下所示:
```shellservice zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server class main# class是一个option,指定zygote服务的类型为main priority -20 user root group root readproc reserved_disk socket zygote stream 660 root system # socket关键字表示一个option,创建一个名为dev/socket/zygote,类型为stream,权限为660的socket socket usap_pool_primary stream 660 root system onrestart write /sys/android_power/request_state wake # onrestart是一个option,说明在zygote重启时需要执行的command onrestart write /sys/power/state on onrestart restart audioserver onrestart restart cameraserver onrestart restart media onrestart restart netd onrestart restart wificond writepid /dev/cpuset/foreground/tasks```
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server 解析:
service zygote :init.zygote64.rc 中定义了一个zygote服务。 init进程就是通过这个service名称来创建zygote进程
/system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server解析:
zygote这个服务,通过执行进行/system/bin/app_process64 并传入4个参数随后运行:
- 参数1:-Xzygote 该参数将作为虚拟机启动时所需的参数- 参数2:/system/bin 代表虚拟机程序所在目录- 参数3:--zygote 指明以ZygoteInit.java类中的main函数作为虚拟机执行入口- 参数4:--start-system-server 告诉Zygote进程启动systemServer进程
###### 小结
init进程第一阶段做的主要工作是挂载分区,创建设备节点和一些关键目录,初始化日志输出系统,启用SELinux安全策略。
init进程第二阶段主要工作是初始化属性系统,解析SELinux的匹配规则,处理子进程终止信号,启动系统属性服务,每一项都很关键,如果说第一阶段是为属性系统,SELinux做准备,那么第二阶段就是真正去把这些功能落实。
init进行第三阶段主要是解析init.rc 来启动其他进程,进入无限循环,进行子进程实时监控。
##### 2、Zygote进程
###### 2.1 概述
Init进程启动后,最重要的一个进程就是Zygote进程,Zygote是所有应用的祖先进程。SystemServer和其他所有Dalivik虚拟机进程都是由Zygote fork而来。
Zygote进程由app_process启动,Zygote是一个C/S模型,Zygote进程作为服务端,其他进程作为客户端向它发出“孵化-fork”请求,而Zygote接收到这个请求后就“孵化-fork”出一个新的进程。
由于Zygote进程在启动时会创建Java虚拟机,因此通过fork而创建的应用程序进程和SystemServer进程可以在内部获取一个Java虚拟机的实例拷贝。
###### 2.2 核心源码
```/system/core/rootdir/init.rc/system/core/init/main.cpp/system/core/init/init.cpp/system/core/rootdir/init.zygote64_32.rc/frameworks/base/cmds/app_process/app_main.cpp/frameworks/base/core/jni/AndroidRuntime.cpp/libnativehelper/JniInvocation.cpp/frameworks/base/core/java/com/android/internal/os/Zygote.java/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java/frameworks/base/core/java/android/net/LocalServerSocket.java/system/core/libutils/Threads.cpp```
###### 2.3 架构
**架构图**
```mermaidgraph LRA[Phone] -->D[ActivityManagerService]B[SMS] -->D[ActivityManagerService]C[Media] -->D[ActivityManagerService]D -->E[Process.Start]E -->F[Zygote]F -->EG[Init] -->F```
###### 2.4 Zygote启动源码分析
- rc解析和进程调用
Init进程启动后,会解析init.rc文件,然后创建和加载service字段指定的进程。zygote进程就是以这种方式,被init进程加载的。
在 /system/core/rootdir/init.rc中,通过如下引用来load Zygote的rc:
``` import /init.${ro.zygote}.rc ```
其中${ro.zygote} 由各个厂家使用,现在的主流厂家基本使用zygote64_32,因此,我们的rc文件为 init.zygote64_32.rc
**init.zygote64_32.rc**
第一个Zygote进程:
进程名:zygote
进程通过 /system/bin/app_process64来启动
启动参数:-Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
socket的名称:zygote
```cservice zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote class main priority -20 user root //用户为root group root readproc reserved_disk //访问组支持 root readproc reserved_disk socket zygote stream 660 root system //创建一个socket,名字叫zygote,以tcp形式 ,可以在/dev/socket 中看到一个 zygote的socket socket usap_pool_primary stream 660 root system onrestart write /sys/android_power/request_state wake // onrestart 指当进程重启时执行后面的命令 onrestart write /sys/power/state on onrestart restart audioserver onrestart restart cameraserver onrestart restart media onrestart restart netd onrestart restart wificond onrestart restart vendor.servicetracker-1-1 writepid /dev/cpuset/foreground/tasks // 创建子进程时,向 /dev/cpuset/foreground/tasks 写入pid```
第二个zygote进程:
进程通过 /system/bin/app_process32来启动
启动参数:-Xzygote /system/bin --zygote --socket-name=zygote_secondary --enable-lazy-preload
socket的名称:zygote_secondary
```c service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary --enable-lazy-preload class main priority -20 user root group root readproc reserved_disk socket zygote_secondary stream 660 root system //创建一个socket,名字叫zygote_secondary,以tcp形式 ,可以在/dev/socket 中看到一个 zygote_secondary的socket socket usap_pool_secondary stream 660 root system onrestart restart zygote writepid /dev/cpuset/foreground/tasks```
从上面我们可以看出,zygote是通过进程文件 /system/bin/app_process64 和/system/bin/app_process32 来启动的。对应的代码入口为:
**frameworks/base/cmds/app_process/app_main.cpp**
**Zygote进程的重启**
Zygote进程重启,主要查看rc文件中有没有 “restart zygote” 这句话。在整个Android系统工程中**搜索“restart zygote”**,会发现以下文件:
```cpp/frameworks/native/services/inputflinger/host/inputflinger.rc 对应进程: inputflinger/frameworks/native/cmds/servicemanager/servicemanager.rc 对应进程: servicemanager/frameworks/native/services/surfaceflinger/surfaceflinger.rc 对应进程: surfaceflinger/system/netd/server/netd.rc 对应进程: netd```
通过上面的文件可知,zygote进程能够重启的时机:
- inputflinger 进程被杀 (onrestart)- servicemanager 进程被杀 (onrestart)- surfaceflinger 进程被杀 (onrestart)- netd 进程被杀 (onrestart)- zygote进程被杀 (oneshot=false)- system_server进程被杀(waitpid)
**Zygote启动后**
```sequenceTitle: Zygote启动时序图" "->app_main.cpp:1.mainapp_main.cpp->AndroidRuntime: 2.startVmapp_main.cpp->AndroidRuntime: 3.startRegapp_main.cpp->ZygoteInit: 4.mainZygoteInit->ZygoteServer:5.new ZygoteServerZygoteServer->ZygoteInit:6.return ZygoteServerZygoteServer->ZygoteInit:7.registerServerSocketZygoteInit->ZygoteInit:8.startSystemServerZygoteInit->ZygoteServer:9.runSelectLoop```
1. init进程通过init.zygote64_32.rc来调用/system/bin/app_process64 来启动zygote进程,入口app_main.cpp2. 调用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(),随时待命,当接收到请求创建新进程请求时立即唤醒并执行相应工作。
**Zygote启动相关函数**
C相关:
```[app_main.cpp] main()[AndroidRuntime.cpp] start()[JniInvocation.cpp] Init()[AndroidRuntime.cpp] startVm()[AndroidRuntime.cpp] startReg()[Threads.cpp] androidSetCreateThreadFunc[AndroidRuntime.cpp] register_jni_procs() --> gRegJNI.mProc```
Java相关:
```[ZygoteInit.java] main()[ZygoteInit.java] preload()[ZygoteServer.java] ZygoteServer[ZygoteInit.java] forkSystemServer[Zygote.java] forkSystemServer[Zygote.java] nativeForkSystemServer[ZygoteServer.java] runSelectLoop```
**2.4 Zygote进程启动源码分析**
Zygote启动代码调用流程:
```init|init_zygote64_32.rc //启动两个zygote,一个64位--/system/bin/app_process64;另一个32位--/system/bin/app_process32|[app_main.cpp]main()//入口|[AndroidRuntime.cpp]start()||||||||JniInvacation.Init(NULL)//初始化JNI,加载libart.so|||//调用dlsym,从libart.so中找到JNI_GetDefaultJavaVMInitArgs|||//JNI_CreateJavaVM、JNI_GetCreateJavaVMs三个函数地址,赋值给对应成员属性||||||||startVm()//启动虚拟机|||||JNI_CreateJavaVM(); //创建VM并返回JavaVM和JniEnv,pEnv对应于当前线程|||||startReg()//注册JNI函数|||||androidSetCreateThreadFunc() //虚拟机启动后startReg()过程,会设置线程创建函数指针gCreateThreadFn指向javaCreateThreadEtc|||register_jni_procs()//注册JNI函数数组 --gRegJNI|||env->CallstaticVoidMethod() //通过反射,调用JAVA的com.android.internal.os.ZygoteInit ----ZygoteInit.java| [ZygoteInit.java] //进入Java层 main()```
**[app_main.cpp]main()**
```cint main(int argc, char* const argv[]){ //zygote传入的参数argv为“-Xzygote /system/bin --zygote --start-system-server --socket-name=zygote” //zygote_secondary传入的参数argv为“-Xzygote /system/bin --zygote --socket-name=zygote_secondary”... while (i < argc) { const char* arg = argv[i++]; if (strcmp(arg, "--zygote") == 0) { zygote = true;//对于64位系统nice_name为zygote64; 32位系统为zygote niceName = ZYGOTE_NICE_NAME; } else if (strcmp(arg, "--start-system-server") == 0) { //是否需要启动system server startSystemServer = true; } else if (strcmp(arg, "--application") == 0) {//启动进入独立的程序模式 application = true; } else if (strncmp(arg, "--nice-name=", 12) == 0) {//niceName 为当前进程别名,区别abi型号 niceName.setTo(arg + 12); } else if (strncmp(arg, "--", 2) != 0) { className.setTo(arg); break; } else { --i; break; } }..if (!className.isEmpty()) { //className不为空,说明是application启动模式...} else { //进入zygote模式,新建Dalvik的缓存目录:/data/dalvik-cache maybeCreateDalvikCache();if (startSystemServer) { //加入start-system-server参数 args.add(String8("start-system-server")); }String8 abiFlag("--abi-list=");abiFlag.append(prop);args.add(abiFlag);//加入--abi-list=参数// In zygote mode, pass all remaining arguments to the zygote// main() method.for (; i < argc; ++i) {//将剩下的参数加入argsargs.add(String8(argv[i]));}}... if (!niceName.isEmpty()) {//设置一个“好听的昵称” zygote\zygote64,之前的名称是app_process runtime.setArgv0(niceName.string(), true /* setProcName */); } if (zygote) { //如果是zygote启动模式,则加载ZygoteInit runtime.start("com.android.internal.os.ZygoteInit", args, zygote); } else if (className) {//如果是application启动模式,则加载RuntimeInit runtime.start("com.android.internal.os.RuntimeInit", args, zygote); } else {//没有指定类名或zygote,参数错误 fprintf(stderr, "Error: no class name or --zygote supplied.\n"); app_usage(); LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied."); }}```
Zygote本身是一个Native的应用程序,刚开始的进程名称为“app_process”,运行过程中,通过调用setArgv0将名字改为zygote 或者 zygote64(根据操作系统而来),最后通过runtime的start()方法来真正的加载虚拟机并进入JAVA世界。
**[AndroidRuntime.cpp] start()**
```cvoid AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote){ ALOGD(">>>>>> START %s uid %d <<<<<<\n", className != NULL ? className : "(unknown)", getuid());... JniInvocation jni_invocation; jni_invocation.Init(NULL); JNIEnv* env; // 虚拟机创建,主要是关于虚拟机参数的设置 if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) { return; } onVmCreated(env);//空函数,没有任何实现 // 注册JNI方法 if (startReg(env) < 0) { ALOGE("Unable to register all android natives\n"); return; } jclass stringClass; jobjectArray strArray; jstring classNameStr; //等价 strArray= new String[options.size() + 1]; stringClass = env->FindClass("java/lang/String"); assert(stringClass != NULL);//等价 strArray[0] = "com.android.internal.os.ZygoteInit" strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL); assert(strArray != NULL); classNameStr = env->NewStringUTF(className); assert(classNameStr != NULL); env->SetObjectArrayElement(strArray, 0, classNameStr); //strArray[1] = "start-system-server"; //strArray[2] = "--abi-list=xxx"; //其中xxx为系统响应的cpu架构类型,比如arm64-v8a. 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); } //将"com.android.internal.os.ZygoteInit"转换为"com/android/internal/os/ZygoteInit" char* slashClassName = toSlashClassName(className != NULL ? className : ""); jclass startClass = env->FindClass(slashClassName);//找到Zygoteinit类 if (startClass == NULL) { ALOGE("JavaVM unable to locate class '%s'\n", slashClassName); } else {//找到这个类后就继续找成员函数main方法的Mehtod ID jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V"); if (startMeth == NULL) { ALOGE("JavaVM unable to find main() in '%s'\n", className); } else {// 通过反射调用ZygoteInit.main()方法 env->CallStaticVoidMethod(startClass, startMeth, strArray); } }//释放相应对象的内存空间 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");}```
start()函数主要做了三件事情,一调用startVm开启虚拟机,二调用startReg注册JNI方法,三就是使用JNI把Zygote进程启动起来。
**[JniInvocation.cpp] Init()**
Init函数主要作用是初始化JNI,具体工作是首先通过dlopen加载libart.so获得其句柄,然后调用dlsym从libart.so中找到JNI_GetDefaultJavaVMInitArgs、JNI_CreateJavaVM、JNI_GetCreatedJavaVMs三个函数地址,赋值给对应成员属性,这三个函数会在后续虚拟机创建中调用.
```cbool JniInvocation::Init(const char* library) { char buffer[PROP_VALUE_MAX]; const int kDlopenFlags = RTLD_NOW | RTLD_NODELETE; /* * 1.dlopen功能是以指定模式打开指定的动态链接库文件,并返回一个句柄 * 2.RTLD_NOW表示需要在dlopen返回前,解析出所有未定义符号,如果解析不出来,在dlopen会返回NULL * 3.RTLD_NODELETE表示在dlclose()期间不卸载库,并且在以后使用dlopen()重新加载库时不初始化库中的静态变量 */ handle_ = dlopen(library, kDlopenFlags); // 获取libart.so的句柄 if (handle_ == NULL) { //获取失败打印错误日志并尝试再次打开libart.so if (strcmp(library, kLibraryFallback) == 0) { // Nothing else to try. ALOGE("Failed to dlopen %s: %s", library, dlerror()); return false; } library = kLibraryFallback; handle_ = dlopen(library, kDlopenFlags); if (handle_ == NULL) { ALOGE("Failed to dlopen %s: %s", library, dlerror()); return false; } } /* * 1.FindSymbol函数内部实际调用的是dlsym * 2.dlsym作用是根据 动态链接库 操作句柄(handle)与符号(symbol),返回符号对应的地址 * 3.这里实际就是从libart.so中将JNI_GetDefaultJavaVMInitArgs等对应的地址存入&JNI_GetDefaultJavaVMInitArgs_中 */ if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetDefaultJavaVMInitArgs_), "JNI_GetDefaultJavaVMInitArgs")) { return false; } if (!FindSymbol(reinterpret_cast<void**>(&JNI_CreateJavaVM_), "JNI_CreateJavaVM")) { return false; } if (!FindSymbol(reinterpret_cast<void**>(&JNI_GetCreatedJavaVMs_), "JNI_GetCreatedJavaVMs")) { return false; } return true;}```
**[AndroidRuntime.cpp] startReg()**
startReg首先是设置了Android创建线程的处理函数,然后创建了一个200容量的局部引用作用域,用于确保不会出现OutOfMemoryException,最后就是调用register_jni_procs进行JNI方法的注册
```cint AndroidRuntime::startReg(JNIEnv* env){ ATRACE_NAME("RegisterAndroidNatives");//设置Android创建线程的函数javaCreateThreadEtc,这个函数内部是通过Linux的clone来创建线程的 androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc); ALOGV("--- registering native functions ---\n"); //创建一个200容量的局部引用作用域,这个局部引用其实就是局部变量 env->PushLocalFrame(200); //注册JNI方法 if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) { env->PopLocalFrame(NULL); return -1; } env->PopLocalFrame(NULL); //释放局部引用作用域 return 0;}```
**[Thread.cpp] androidSetCreateThreadFunc()**
虚拟机启动startReg()后,会设置线程创建函数指针gCreateThreadFn指向javaCreateThreadEtc
```cvoid androidSetCreateThreadFunc(android_create_thread_fn func) { gCreateThreadFn = func;}```
**[AndroidRuntime.cpp] register_jni_procs()**
它处理的是RegJNIRec交给的mProc,RegJNIRec是一个结构体,mProc是一个函数指针
```cstatic 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) {/ /调用gRegJNI的mProc return -1; } } return 0;}```
**[AndroidRuntime.cpp] gRegJNI()**
```cstatic const RegJNIRec gRegJNI[] = { REG_JNI(register_com_android_internal_os_RuntimeInit), REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit), REG_JNI(register_android_os_SystemClock), REG_JNI(register_android_util_EventLog), REG_JNI(register_android_util_Log),...} #define REG_JNI(name) { name, #name } struct RegJNIRec { int (*mProc)(JNIEnv*); };gRegJNI 中是一堆函数指针,因此循环调用 gRegJNI 的mProc,即等价于调用其所对应的函数指针。例如调用: register_com_android_internal_os_RuntimeInit这是一个JNI函数动态注册的标准方法。 int register_com_android_internal_os_RuntimeInit(JNIEnv* env){ const JNINativeMethod methods[] = { { "nativeFinishInit", "()V", (void*) com_android_internal_os_RuntimeInit_nativeFinishInit }, { "nativeSetExitWithoutCleanup", "(Z)V", (void*) com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup }, }; //跟Java侧的com/android/internal/os/RuntimeInit.java 的函数nativeFinishInit() 进行一一对应 return jniRegisterNativeMethods(env, "com/android/internal/os/RuntimeInit", methods, NELEM(methods));}```
**Java层Zygote启动的主要代码**
通过JNI调用ZygoteInit的main函数后, Zygote便进入了Java框架层,此前没有任何代码进入过Java框架层,换句换说Zygote开启了Java框架层。
**[ZygoteInit.java]main.cpp**
代码地址:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
main的主要工作:
- 调用preload()来预加载类和资源
- 调用ZygoteServer()创建两个Server端的Socket--/dev/socket/zygote 和 /dev/socket/zygote_secondary,Socket用来等待ActivityManagerService来请求Zygote来创建新的应用程序进程。
- 调用forkSystemServer 来启动SystemServer进程,这样系统的关键服务也会由SystemServer进程启动起来。
- 最后调用runSelectLoop函数来等待客户端请求
```java public static void main(String argv[]) { // 1.创建ZygoteServer ZygoteServer zygoteServer = null; // 调用native函数,确保当前没有其它线程在运行 ZygoteHooks.startZygoteNoThreadCreation(); //设置pid为0,Zygote进入自己的进程组 Os.setpgid(0, 0); ...... Runnable caller; try { ...... //得到systrace的监控TAG String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing"; TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag, Trace.TRACE_TAG_DALVIK); //通过systradce来追踪 函数ZygoteInit, 可以通过systrace工具来进行分析 //traceBegin 和 traceEnd 要成对出现,而且需要使用同一个tag bootTimingsTraceLog.traceBegin("ZygoteInit"); //开启DDMS(Dalvik Debug Monitor Service)功能 //注册所有已知的Java VM的处理块的监听器。线程监听、内存监听、native 堆内存监听、debug模式监听等等 RuntimeInit.enableDdms(); boolean startSystemServer = false; String zygoteSocketName = "zygote"; String abiList = null; boolean enableLazyPreload = false; //2. 解析app_main.cpp - start()传入的参数 for (int i = 1; i < argv.length; i++) { if ("start-system-server".equals(argv[i])) { startSystemServer = true; //启动zygote时,才会传入参数:start-system-server } else if ("--enable-lazy-preload".equals(argv[i])) { enableLazyPreload = true; //启动zygote_secondary时,才会传入参数:enable-lazy-preload } else if (argv[i].startsWith(ABI_LIST_ARG)) { //通过属性ro.product.cpu.abilist64\ro.product.cpu.abilist32 从C空间传来的值 abiList = argv[i].substring(ABI_LIST_ARG.length()); } else if (argv[i].startsWith(SOCKET_NAME_ARG)) { zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length()); //会有两种值:zygote和zygote_secondary } else { throw new RuntimeException("Unknown command line argument: " + argv[i]); } } // 根据传入socket name来决定是创建socket还是zygote_secondary final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME); // 在第一次zygote启动时,enableLazyPreload为false,执行preload if (!enableLazyPreload) { //systrace 追踪 ZygotePreload bootTimingsTraceLog.traceBegin("ZygotePreload"); EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock.uptimeMillis()); // 3.加载进程的资源和类 preload(bootTimingsTraceLog); EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis()); //systrae结束 ZygotePreload的追踪 bootTimingsTraceLog.traceEnd(); // ZygotePreload } else { // 延迟预加载, 变更Zygote进程优先级为NORMAL级别,第一次fork时才会preload Zygote.resetNicePriority(); } //结束ZygoteInit的systrace追踪 bootTimingsTraceLog.traceEnd(); // ZygoteInit //禁用systrace追踪,以便fork的进程不会从zygote继承过时的跟踪标记 Trace.setTracingEnabled(false, 0); // 4.调用ZygoteServer 构造函数,创建socket,会根据传入的参数, // 创建两个socket:/dev/socket/zygote 和 /dev/socket/zygote_secondary zygoteServer = new ZygoteServer(isPrimaryZygote); if (startSystemServer) { //5. fork出system server Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer); // 启动SystemServer if (r != null) { r.run(); return; } } // 6. zygote进程进入无限循环,处理请求 caller = zygoteServer.runSelectLoop(abiList); } catch (Throwable ex) { Log.e(TAG, "System zygote died with exception", ex); throw ex; } finally { if (zygoteServer != null) { zygoteServer.closeServerSocket(); } } // 7.在子进程中退出了选择循环。继续执行命令 if (caller != null) { caller.run(); } } ```
日志:reboot_log/mobilelog/APLog_2020_0527_111424\__3/boot\__normal/main_log_1__2020_0527_111424
关键字:**Zygote**
```verilog05-27 11:13:47.145963 422 422 D Zygote : begin preload05-27 11:13:47.146014 422 422 I Zygote : Calling ZygoteHooks.beginPreload()05-27 11:13:47.161358 422 422 I Zygote : Preloading classes...05-27 11:13:48.017474 422 422 I Zygote : ...preloaded 7590 classes in 856ms.05-27 11:13:48.268421 422 422 I Zygote : Preloading resources...05-27 11:13:48.345627 422 422 I Zygote : ...preloaded 64 resources in 77ms.05-27 11:13:48.357019 422 422 I Zygote : ...preloaded 41 resources in 9ms.05-27 11:13:48.881796 422 422 I Zygote : Preloading shared libraries...05-27 11:13:48.897045 422 422 I Zygote : Called ZygoteHooks.endPreload()05-27 11:13:48.898210 422 422 I Zygote : Installed AndroidKeyStoreProvider in 1ms.05-27 11:13:48.961988 422 422 I Zygote : Warmed up JCA providers in 64ms.05-27 11:13:48.962687 422 422 D Zygote : end preload05-27 11:13:49.203818 421 421 D Zygote : Forked child process 124105-27 11:13:49.705212 422 422 D Zygote : Forked child process 128405-27 11:13:49.745990 421 421 D Zygote : Forked child process 129105-27 11:13:49.848341 421 421 D Zygote : Forked child process 133205-27 11:13:50.123459 421 421 D Zygote : Forked child process 137405-27 11:13:50.278760 422 422 D Zygote : Forked child process 141205-27 11:13:50.279845 422 422 I Zygote : Process 1284 exited cleanly (0)05-27 11:13:50.297478 421 421 I Zygote : Process 1291 exited cleanly (0)05-27 11:13:50.398452 421 421 D Zygote : Forked child process 144805-27 11:13:50.825943 421 421 D Zygote : Forked child process 151005-27 11:13:51.294073 421 421 D Zygote : Forked child process 157705-27 11:13:51.397776 421 421 D Zygote : Forked child process 160805-27 11:13:56.386450 421 421 D Zygote : Forked child process 189105-27 11:13:56.451562 421 421 D Zygote : Forked child process 190905-27 11:13:56.771389 421 421 D Zygote : Forked child process 195205-27 11:13:57.061047 421 421 D Zygote : Forked child process 199105-27 11:13:59.239336 421 421 D Zygote : Forked child process 208305-27 11:14:02.603439 421 421 D Zygote : Forked child process 213905-27 11:14:02.743785 421 421 D Zygote : Forked child process 216405-27 11:14:03.681056 421 421 D Zygote : Forked child process 225705-27 11:14:04.155033 421 421 D Zygote : Forked child process 229305-27 11:14:04.904368 421 421 D Zygote : Forked child process 234705-27 11:14:05.156937 421 421 D Zygote : Forked child process 237705-27 11:14:05.269683 421 421 D Zygote : Forked child process 239205-27 11:14:05.348930 421 421 D Zygote : Forked child process 241905-27 11:14:05.660315 421 421 D Zygote : Forked child process 245405-27 11:14:06.439079 421 421 D Zygote : Forked child process 252205-27 11:14:06.585562 421 421 D Zygote : Forked child process 253905-27 11:14:06.677364 422 422 D Zygote : Forked child process 255605-27 11:14:07.106202 421 421 D Zygote : Forked child process 261105-27 11:14:07.786845 421 421 D Zygote : Forked child process 266305-27 11:14:07.980175 421 421 D Zygote : Forked child process 267105-27 11:14:08.588646 421 421 D Zygote : Forked child process 272605-27 11:14:10.305557 421 421 D Zygote : Forked child process 286705-27 11:14:12.432055 421 421 D Zygote : Forked child process 297905-27 11:14:12.810294 421 421 D Zygote : Forked child process 302105-27 11:14:13.046852 421 421 D Zygote : Forked child process 304405-27 11:14:15.587206 421 421 D Zygote : Forked child process 3212```
**[ZygoteInit.java] preload()**
```javastatic void preload(TimingsTraceLog bootTimingsTraceLog) { Log.d(TAG, "begin preload"); beginPreload(); // Pin ICU Data, 获取字符集转换资源等 //预加载类的列表---/system/etc/preloaded-classes, 在版本:/frameworks/base/config/preloaded-classes 中,Android10.0中预计有7603左右个类 //从下面的log看,成功加载了7587个类 preloadClasses(); preloadResources(); //加载图片、颜色等资源文件,部分定义在 /frameworks/base/core/res/res/values/arrays.xml中 ...... preloadSharedLibraries(); // 加载 android、compiler_rt、jnigraphics等library preloadTextResources(); //用于初始化文字资源 WebViewFactory.prepareWebViewInZygote(); //用于初始化webview; endPreload(); //预加载完成,可以查看下面的log warmUpJcaProviders(); Log.d(TAG, "end preload"); sPreloadComplete = true; }```
**什么是预加载:**
预加载是指在zygote进程启动的时候就加载,这样系统只在zygote执行一次加载操作,所有APP用到该资源不需要再重新加载,减少资源加载时间,加快了应用启动速度,一般情况下,系统中App共享的资源会被列为预加载资源。
zygote fork子进程时,根据fork的copy-on-write机制可知,有些类如果不做改变,甚至都不用复制,子进程可以和父进程共享这部分数据,从而省去不少内存的占用。
**预加载的原理:**
zygote进程启动后将资源读取出来,保存到Resources一个全局静态变量中,下次读取系统资源的时候优先从静态变量中查找。
地址:frameworks/base/config/preloaded-classes
```# This file has been derived for mainline phone (and tablet) usage.#android.R$styleableandroid.accessibilityservice.AccessibilityServiceInfo$1android.accessibilityservice.AccessibilityServiceInfoandroid.accounts.Account$1android.accounts.Accountandroid.accounts.AccountManager$10android.accounts.AccountManager$11android.accounts.AccountManager$18android.accounts.AccountManager$1android.accounts.AccountManager$20android.accounts.AccountManager$2android.accounts.AccountManager$AmsTask$1android.accounts.AccountManager$AmsTask$Responseandroid.accounts.AccountManager$AmsTaskandroid.accounts.AccountManager$BaseFutureTask$1android.accounts.AccountManager$BaseFutureTask$Responseandroid.accounts.AccountManager$BaseFutureTaskandroid.accounts.AccountManager$Future2Task$1android.accounts.AccountManager$Future2Taskandroid.accounts.AccountManagerandroid.accounts.AccountManagerCallbackandroid.accounts.AccountManagerFuture............```
**相关日志:**
```verilog05-27 11:13:47.145963 422 422 D Zygote : begin preload05-27 11:13:47.146014 422 422 I Zygote : Calling ZygoteHooks.beginPreload()05-27 11:13:47.161358 422 422 I Zygote : Preloading classes...05-27 11:13:48.017474 422 422 I Zygote : ...preloaded 7590 classes in 856ms.05-27 11:13:48.268421 422 422 I Zygote : Preloading resources...05-27 11:13:48.345627 422 422 I Zygote : ...preloaded 64 resources in 77ms.05-27 11:13:48.357019 422 422 I Zygote : ...preloaded 41 resources in 9ms.05-27 11:13:48.881796 422 422 I Zygote : Preloading shared libraries...05-27 11:13:48.897045 422 422 I Zygote : Called ZygoteHooks.endPreload()05-27 11:13:48.898210 422 422 I Zygote : Installed AndroidKeyStoreProvider in 1ms.05-27 11:13:48.961988 422 422 I Zygote : Warmed up JCA providers in 64ms.05-27 11:13:48.962687 422 422 D Zygote : end preload```
**[ZygoteServer.java] ZygoteServer()**
代码地址:frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
作用:ZygoteServer 构造函数初始化时,根据传入的参数,利用LocalServerSocket 创建了4个本地服务端的socket,用来建立连接。 分别是:zygote、usap_pool_primary、zygote_secondary、usap_pool_secondary
```Javaprivate LocalServerSocket mZygoteSocket; private LocalServerSocket mUsapPoolSocket; //创建zygote的socket ZygoteServer(boolean isPrimaryZygote) { mUsapPoolEventFD = Zygote.getUsapPoolEventFD(); if (isPrimaryZygote) { //创建socket,并获取socket对象,socketname: zygote mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME); //创建socket,并获取socket对象,socketname:usap_pool_primary mUsapPoolSocket = Zygote.createManagedSocketFromInitSocket( Zygote.USAP_POOL_PRIMARY_SOCKET_NAME); } else { //创建socket,并获取socket对象,socketname: zygote_secondary mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.SECONDARY_SOCKET_NAME); //创建socket,并获取socket对象,socketname: usap_pool_secondary mUsapPoolSocket = Zygote.createManagedSocketFromInitSocket( Zygote.USAP_POOL_SECONDARY_SOCKET_NAME); } fetchUsapPoolPolicyProps(); mUsapPoolSupported = true; } static LocalServerSocket createManagedSocketFromInitSocket(String socketName) { int fileDesc; // ANDROID_SOCKET_PREFIX为"ANDROID_SOCKET_" //加入传入参数为zygote,则fullSocketName:ANDROID_SOCKET_zygote final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName; try { //init.zygote64_32.rc启动时,指定了4个socket: //分别是zygote、usap_pool_primary、zygote_secondary、usap_pool_secondary // 在进程被创建时,就会创建对应的文件描述符,并加入到环境变量中 // 这里取出对应的环境变量 String env = System.getenv(fullSocketName); fileDesc = Integer.parseInt(env); } catch (RuntimeException ex) { throw new RuntimeException("Socket unset or invalid: " + fullSocketName, ex); } try { FileDescriptor fd = new FileDescriptor(); fd.setInt$(fileDesc); // 获取zygote socket的文件描述符 return new LocalServerSocket(fd); // 创建Socket的本地服务端 } catch (IOException ex) { throw new RuntimeException( "Error building socket from file descriptor: " + fileDesc, ex); } } path: \frameworks\base\core\java\android\net\LocalServerSocket.java public LocalServerSocket(FileDescriptor fd) throws IOException { impl = new LocalSocketImpl(fd); impl.listen(LISTEN_BACKLOG); localAddress = impl.getSockAddress(); }```
**[ZygoteInit.java] forkSystemServer()**
```javaprivate static Runnable forkSystemServer(String abiList, String socketName, ZygoteServer zygoteServer) { long capabilities = posixCapabilitiesAsBits( OsConstants.CAP_IPC_LOCK, OsConstants.CAP_KILL, OsConstants.CAP_NET_ADMIN, OsConstants.CAP_NET_BIND_SERVICE, OsConstants.CAP_NET_BROADCAST, OsConstants.CAP_NET_RAW, OsConstants.CAP_SYS_MODULE, OsConstants.CAP_SYS_NICE, OsConstants.CAP_SYS_PTRACE, OsConstants.CAP_SYS_TIME, OsConstants.CAP_SYS_TTY_CONFIG, OsConstants.CAP_WAKE_ALARM, OsConstants.CAP_BLOCK_SUSPEND ); ...... //参数准备 /* Hardcoded command line to start the system server */ String args[] = { "--setuid=1000", "--setgid=1000", "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023," + "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010", "--capabilities=" + capabilities + "," + capabilities, "--nice-name=system_server", "--runtime-args", "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT, "com.android.server.SystemServer", }; ZygoteArguments parsedArgs = null; int pid; try { //将上面准备的参数,按照ZygoteArguments的风格进行封装 parsedArgs = new ZygoteArguments(args); Zygote.applyDebuggerSystemProperty(parsedArgs); Zygote.applyInvokeWithSystemProperty(parsedArgs); boolean profileSystemServer = SystemProperties.getBoolean( "dalvik.vm.profilesystemserver", false); if (profileSystemServer) { parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER; } //通过fork"分裂"出子进程system_server /* Request to fork the system server process */ pid = Zygote.forkSystemServer( parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids, parsedArgs.mRuntimeFlags, null, parsedArgs.mPermittedCapabilities, parsedArgs.mEffectiveCapabilities); } catch (IllegalArgumentException ex) { throw new RuntimeException(ex); } //进入子进程system_server /* For child process */ if (pid == 0) { // 处理32_64和64_32的情况 if (hasSecondZygote(abiList)) { waitForSecondaryZygote(socketName); } // fork时会copy socket,system server需要主动关闭 zygoteServer.closeServerSocket(); // system server进程处理自己的工作 return handleSystemServerProcess(parsedArgs); } return null; }```
**[ZygoteServer.java] runSelectLoop()**
代码路径:frameworks/base/core/java/com/android/internal/os/ZygoteServer.java
```javaRunnable runSelectLoop(String abiList) { ArrayList<FileDescriptor> socketFDs = new ArrayList<FileDescriptor>(); ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>(); // 首先将server socket加入到fds socketFDs.add(mZygoteSocket.getFileDescriptor()); peers.add(null); while (true) { fetchUsapPoolPolicyPropsWithMinInterval(); int[] usapPipeFDs = null; StructPollfd[] pollFDs = null; // 每次循环,都重新创建需要监听的pollFds // Allocate enough space for the poll structs, taking into account // the state of the USAP pool for this Zygote (could be a // regular Zygote, a WebView Zygote, or an AppZygote). if (mUsapPoolEnabled) { usapPipeFDs = Zygote.getUsapPipeFDs(); pollFDs = new StructPollfd[socketFDs.size() + 1 + usapPipeFDs.length]; } else { pollFDs = new StructPollfd[socketFDs.size()]; } /* * For reasons of correctness the USAP pool pipe and event FDs * must be processed before the session and server sockets. This * is to ensure that the USAP pool accounting information is * accurate when handling other requests like API blacklist * exemptions. */ int pollIndex = 0; for (FileDescriptor socketFD : socketFDs) { // 关注事件到来 pollFDs[pollIndex] = new StructPollfd(); pollFDs[pollIndex].fd = socketFD; pollFDs[pollIndex].events = (short) POLLIN; ++pollIndex; } final int usapPoolEventFDIndex = pollIndex; if (mUsapPoolEnabled) { pollFDs[pollIndex] = new StructPollfd(); pollFDs[pollIndex].fd = mUsapPoolEventFD; pollFDs[pollIndex].events = (short) POLLIN; ++pollIndex; for (int usapPipeFD : usapPipeFDs) { FileDescriptor managedFd = new FileDescriptor(); managedFd.setInt$(usapPipeFD); pollFDs[pollIndex] = new StructPollfd(); pollFDs[pollIndex].fd = managedFd; pollFDs[pollIndex].events = (short) POLLIN; ++pollIndex; } } try { // 等待事件到来 Os.poll(pollFDs, -1); } catch (ErrnoException ex) { throw new RuntimeException("poll failed", ex); } boolean usapPoolFDRead = false; //倒序处理,即优先处理已建立链接的信息,后处理新建链接的请求 while (--pollIndex >= 0) { if ((pollFDs[pollIndex].revents & POLLIN) == 0) { continue; } // server socket最先加入fds, 因此这里是server socket收到数据 if (pollIndex == 0) { // 收到新的建立通信的请求,建立通信连接 ZygoteConnection newPeer = acceptCommandPeer(abiList); // 加入到peers和fds, 即下一次也开始监听 peers.add(newPeer); socketFDs.add(newPeer.getFileDescriptor()); } else if (pollIndex < usapPoolEventFDIndex) { //说明接收到AMS发送过来创建应用程序的请求,调用processOneCommand //来创建新的应用程序进程 // Session socket accepted from the Zygote server socket try { //有socket连接,创建ZygoteConnection对象,并添加到fds。 ZygoteConnection connection = peers.get(pollIndex); //处理连接 final Runnable command = connection.processOneCommand(this); // TODO (chriswailes): Is this extra check necessary? if (mIsForkChild) { // We're in the child. We should always have a command to run at this // stage if processOneCommand hasn't called "exec". if (command == null) { throw new IllegalStateException("command == null"); } return command; } else { // We're in the server - we should never have any commands to run. if (command != null) { throw new IllegalStateException("command != null"); } // We don't know whether the remote side of the socket was closed or // not until we attempt to read from it from processOneCommand. This // shows up as a regular POLLIN event in our regular processing loop. if (connection.isClosedByPeer()) { connection.closeSocket(); peers.remove(pollIndex); socketFDs.remove(pollIndex); //处理完则从fds中移除该文件描述符 } } } catch (Exception e) { ...... } finally { mIsForkChild = false; } } else { //处理USAP pool的事件 // Either the USAP pool event FD or a USAP reporting pipe. // If this is the event FD the payload will be the number of USAPs removed. // If this is a reporting pipe FD the payload will be the PID of the USAP // that was just specialized. long messagePayload = -1; try { byte[] buffer = new byte[Zygote.USAP_MANAGEMENT_MESSAGE_BYTES]; int readBytes = Os.read(pollFDs[pollIndex].fd, buffer, 0, buffer.length); if (readBytes == Zygote.USAP_MANAGEMENT_MESSAGE_BYTES) { DataInputStream inputStream = new DataInputStream(new ByteArrayInputStream(buffer)); messagePayload = inputStream.readLong(); } else { Log.e(TAG, "Incomplete read from USAP management FD of size " + readBytes); continue; } } catch (Exception ex) { if (pollIndex == usapPoolEventFDIndex) { Log.e(TAG, "Failed to read from USAP pool event FD: " + ex.getMessage()); } else { Log.e(TAG, "Failed to read from USAP reporting pipe: " + ex.getMessage()); } continue; } if (pollIndex > usapPoolEventFDIndex) { Zygote.removeUsapTableEntry((int) messagePayload); } usapPoolFDRead = true; } } // Check to see if the USAP pool needs to be refilled. if (usapPoolFDRead) { int[] sessionSocketRawFDs = socketFDs.subList(1, socketFDs.size()) .stream() .mapToInt(fd -> fd.getInt$()) .toArray(); final Runnable command = fillUsapPool(sessionSocketRawFDs); if (command != null) { return command; } } }}```
**[ZygoteConnection.java] processOneCommand()**
```javaRunnable processOneCommand(ZygoteServer zygoteServer) { ... //fork子进程 pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids, parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo, parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote, parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion); if (pid == 0) { // 子进程执行 zygoteServer.setForkChild(); //进入子进程流程 return handleChildProc(parsedArgs, descriptors, childPipeFd, parsedArgs.mStartChildZygote); } else { //父进程执行 // In the parent. A pid < 0 indicates a failure and will be handled in //handleParentProc. handleParentProc(pid, descriptors, serverPipeFd); return null; } ...}```
**[ZygoteConnection.java] handleChildProc()**
```javaprivate Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, boolean isZygote) { ... if (parsedArgs.mInvokeWith != null) { ... throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned"); } else { if (!isZygote) { // App进程将会调用到这里,执行目标类的main()方法 return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion, parsedArgs.mRemainingArgs, null /* classLoader */); } else { return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion, parsedArgs.mRemainingArgs, null /* classLoader */); } } }```
###### 问题分析
**为什么SystemServer和Zygote之间通信要采用Socket**
进程间通信我们常用的是binder,为什么这里要采用socket呢。主要是为了解决fork的问题:
UNIX上C++程序设计守则3:多线程程序里不准使用forkBinder通讯是需要多线程操作的,代理对象对Binder的调用是在Binder线程,需要再通过Handler调用主线程来操作。比如AMS与应用进程通讯,AMS的本地代理IApplicationThread通过调用ScheduleLaunchActivity,调用到的应用进程ApplicationThread的ScheduleLaunchActivity是在Binder线程,需要再把参数封装为一个ActivityClientRecord,sendMessage发送给H类(主线程Handler,ActivityThread内部类)主要原因:害怕父进程binder线程有锁,然后子进程的主线程一直在等其子线程(从父进程拷贝过来的子进程)的资源,但是其实父进程的子进程并没有被拷贝过来,造成死锁。
所以fork不允许存在多线程。而Binder通讯偏偏就是多线程,所以干脆父进程(Zygote)这个时候就不使用binder线程
**为什么一个java应用一个虚拟机?**
- android的VM(vm==Virtual Machine )也是类似`JRE`(*Java运行环境(Java Runtime Environment,简称JRE)是一个软件, JRE可以让计算机系统运行Java应用程序(Java Application);JRE的内部有一个Java虚拟机(Java Virtual Machine,JVM*)以及一些标准的类别函数库(Class Library))的东西,当然,各方面都截然不同,不过有一个作用都是一样的,为app提供了运行环境- android为每个程序提供一个vm,可以使每个app都运行在独立的运行环境,使稳定性提高。- vm的设计可以有更好的兼容性。android apk都被编译成字节码(bytecode),在运行的时候,vm是先将字节码编译真正可执行的代码,否则不同硬件设备的兼容是很大的麻烦。- android(非ROOT)没有windows下键盘钩子之类的东西,每个程序一个虚拟机,各个程序之间也不可以随意访问内存,所以此类木马病毒几乎没有。
**什么是Zygote资源预加载**预加载是指在zygote进程启动的时候就加载,这样系统只在zygote执行一次加载操作,所有APP用到该资源不需要再重新加载,减少资源加载时间,加快了应用启动速度,一般情况下,系统中App共享的资源会被列为预加载资源。zygote fork子进程时,根据fork的copy-on-write机制可知,有些类如果不做改变,甚至都不用复制,子进程可以和父进程共享这部分数据,从而省去不少内存的占用。
**Zygote为什么要预加载**应用程序都从Zygote孵化出来,应用程序都会继承Zygote的所有内容。如果在Zygote启动的时候加载这些类和资源,这些孵化的应用程序就继承Zygote的类和资源,这样启动应用程序的时候就不需要加载类和资源了,启动的速度就会快很多。开机的次数不多,但是启动应用程序的次数非常多。
**Zygote 预加载的原理是什么?**
zygote进程启动后将资源读取出来,保存到Resources一个全局静态变量中,下次读取系统资源的时候优先从静态变量中查找。
###### 小结
Zygote启动流程结束,Zygote进程共做了如下几件事:
- 解析init.zygote64_32.rc,创建AppRuntime并调用其start方法,启动Zygote进程。- 创建JavaVM并为JavaVM注册JNI.- 通过JNI调用ZygoteInit的main函数进入Zygote的Java框架层。- 通过ZygoteServer创建服务端Socket,预加载类和资源,并通过runSelectLoop函数等待如ActivityManagerService等的请求。- 启动SystemServer进程。
##### 3、SystemServer进程
###### 3.1 概述
Zygote是所有应用的鼻祖。SystemServer和其他所有Dalivik虚拟机进程都是由Zygote fork而来。Zygote fork的第一个进程就是SystemServer,其在手机中的进程名为 system_server。
system_server 进程承载着整个framework的核心服务,例如创建 ActivityManagerService、PowerManagerService、DisplayManagerService、PackageManagerService、WindowManagerService、LauncherAppsService等核心系统服务。这些服务以不同的线程方式存在于system_server这个进程中。
下面来分析一下SystemServer的整个启动过程。
###### 3.2 架构
SystemServer 被Zygote进程fork出来后,用来创建ActivityManagerService、PowerManagerService、DisplayManagerService、PackageManagerService、WindowManagerService、LauncherAppsService等多个核心系统服务
```mermaidgraph TBA[Init进程] -->B[Zygote进程]B --1-->C[启动ART or Dalivk虚拟机]B --3 Fork-->E[启动SystemServer]B --2-->D[注册JNI]E --1-->F[启动Boot服务]E --2-->G[启动核心服务]E --3-->H[启动其他服务]
```
###### 3.3 服务启动
```mermaidgraph LRE[SystemServer] --1-->F[启动Boot服务]E --2-->G[启动核心服务]E --3-->H[启动其他服务]F -->FF[ActivityManagerService]F -->FG[PowerManagerService]F -->FH[PackageManagerService]F -->FA[DisplayManagerService]F -->FB[UserManagerSevice]F -->FC[LightsService]F -->FV[SensorService]G -->GA[WebViewUpdateService]G -->GB[UsageStatsService]G -->GC[BatteryService]H -->HA[AlarmManagerService]H -->HB[VibratorService]H -->HC[DynamicSystemService]H -->HD[ConsumerIrService]H -->HE[.......]```
###### 3.4 源码分析
**[ZygoteInit.java] main()**
**说明:**Zygote进程,通过fork()函数,最终孵化出system_server的进程,通过反射的方法启动SystemServer.java的main()方法
```Javapublic static void main(String argv[]) {ZygoteServer zygoteServer = null; ...try {zygoteServer = new ZygoteServer(isPrimaryZygote);if (startSystemServer) {//fork system_serverRunnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer); // {@code r == null} in the parent (zygote) process, and {@code r != null} in the// child (system_server) process.if (r != null) {r.run(); //启动SystemServer.java的main()return; //Android 8.0之前是通过抛异常的方式来启动,这里是直接return出去,用来清空栈,提高栈帧利用率}} caller = zygoteServer.runSelectLoop(abiList); } catch (Throwable ex) { Log.e(TAG, "System zygote died with exception", ex); throw ex; } finally { if (zygoteServer != null) { zygoteServer.closeServerSocket(); } }if (caller != null) { caller.run(); }...}```
**[ZygoteInit.java] forkSystemServer()**
说明:准备参数,用来进行system_server的fork,从参数可知,pid=1000,gid=1000,进程名nick-name=system_server
当有两个Zygote进程时,需要等待第二个Zygote创建完成。由于fork时会拷贝socket,因此,在fork出system_server进程后,
需要关闭Zygote原有的socket
```Javaprivate static Runnable forkSystemServer(String abiList, String socketName, ZygoteServer zygoteServer) { ...... //参数准备,uid和gid都是为1000 String args[] = { "--setuid=1000", "--setgid=1000", "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023," + "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010", "--capabilities=" + capabilities + "," + capabilities, "--nice-name=system_server", "--runtime-args", "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT, "com.android.server.SystemServer", }; ZygoteArguments parsedArgs = null; int pid; try { //将上面准备的参数,按照ZygoteArguments的风格进行封装 parsedArgs = new ZygoteArguments(args); Zygote.applyDebuggerSystemProperty(parsedArgs); Zygote.applyInvokeWithSystemProperty(parsedArgs); //通过fork"分裂"出子进程system_server /* Request to fork the system server process */ pid = Zygote.forkSystemServer( parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids, parsedArgs.mRuntimeFlags, null, parsedArgs.mPermittedCapabilities, parsedArgs.mEffectiveCapabilities); } catch (IllegalArgumentException ex) { throw new RuntimeException(ex); } //进入子进程system_server if (pid == 0) { // 处理32_64和64_32的情况 if (hasSecondZygote(abiList)) { waitForSecondaryZygote(socketName); //需要等待第二个Zygote创建完成 } // fork时会copy socket,Zygote原有的socket需要关闭 zygoteServer.closeServerSocket(); // system server进程处理自己的工作 return handleSystemServerProcess(parsedArgs); } return null;}```
**[Zygote.java] forkSystemServer()**
**说明:**这里的nativeForkSystemServer()最终是通过JNI,调用Nativate C空间的com_android_internal_os_Zygote_nativeForkSystemServer()
来fork system_server
```Javapublic static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags, int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) { ZygoteHooks.preFork(); // Resets nice priority for zygote process. resetNicePriority(); //调用native的方法来fork system_server //最终调用native的方法:com_android_internal_os_Zygote_nativeForkSystemServer int pid = nativeForkSystemServer( uid, gid, gids, runtimeFlags, rlimits, permittedCapabilities, effectiveCapabilities); // Enable tracing as soon as we enter the system_server. if (pid == 0) { Trace.setTracingEnabled(true, runtimeFlags); } ZygoteHooks.postForkCommon(); return pid;}```
**[com_android_internal_os_Zygote.cpp]**
**说明:**JNI注册的映射关系
```javastatic const JNINativeMethod gMethods[] = { { "nativeForkSystemServer", "(II[II[[IJJ)I", (void *) com_android_internal_os_Zygote_nativeForkSystemServer },}```
**[com_android_internal_os_Zygote.cpp] com_android_internal_os_Zygote_nativeForkSystemServer()**
说明:通过 SpecializeCommon进行fork,pid返回0时,表示当前为system_server子进程当pid >0 时,是进入父进程,即Zygote进程,通过waitpid 的WNOHANG 非阻塞方式来监控system_server进程挂掉,如果挂掉,则重启Zygote进程。
<u>现在使用的Android系统大部分情况下是64位的,会存在两个Zygote,当system_server挂掉后,只启动Zygote64这个父进程。</u>
```Javastatic jint com_android_internal_os_Zygote_nativeForkSystemServer( JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities, jlong effective_capabilities) { pid_t pid = ForkCommon(env, true, fds_to_close, fds_to_ignore); if (pid == 0) { //进入子进程 SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, permitted_capabilities, effective_capabilities, MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true, false, nullptr, nullptr); } else if (pid > 0) { //进入父进程,即zygote进程 ALOGI("System server process %d has been created", pid); int status; //用waitpid函数获取状态发生变化的子进程pid //waitpid的标记为WNOHANG,即非阻塞,返回为正值就说明有进程挂掉了 if (waitpid(pid, &status, WNOHANG) == pid) { //当system_server进程死亡后,重启zygote进程 ALOGE("System server process %d has died. Restarting Zygote!", pid); RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!"); } ... } return pid;}```
**[com_android_internal_os_Zygote.cpp] ForkCommon**
**说明:**从Zygote孵化出一个进程的使用程序
```Javastatic pid_t ForkCommon(JNIEnv* env, bool is_system_server, const std::vector<int>& fds_to_close, const std::vector<int>& fds_to_ignore) { //设置子进程的signal SetSignalHandlers(); //在fork的过程中,临时锁住SIGCHLD BlockSignal(SIGCHLD, fail_fn); //fork子进程,采用copy on write方式,这里执行一次,会返回两次 //pid=0 表示Zygote fork SystemServer这个子进程成功 //pid > 0 表示SystemServer 的真正的PID pid_t pid = fork(); if (pid == 0) { //进入子进程 // The child process. PreApplicationInit(); // 关闭并清除文件描述符 // Clean up any descriptors which must be closed immediately DetachDescriptors(env, fds_to_close, fail_fn);... } else { ALOGD("Forked child process %d", pid); } //fork结束,解锁 UnblockSignal(SIGCHLD, fail_fn); return pid;}```
**[Zygcom_android_internal_os_Zygoteote.cpp] SpecializeCommon**
**说明:**system_server进程的一些调度配置
```Javastatic void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities, jlong effective_capabilities, jint mount_external, jstring managed_se_info, jstring managed_nice_name, bool is_system_server, bool is_child_zygote, jstring managed_instruction_set, jstring managed_app_data_dir) { ... bool use_native_bridge = !is_system_server && instruction_set.has_value() && android::NativeBridgeAvailable() && android::NeedsNativeBridge(instruction_set.value().c_str()); if (!is_system_server && getuid() == 0) { //对于非system_server子进程,则创建进程组 const int rc = createProcessGroup(uid, getpid()); if (rc == -EROFS) { ALOGW("createProcessGroup failed, kernel missing CONFIG_CGROUP_CPUACCT?"); } else if (rc != 0) { ALOGE("createProcessGroup(%d, %d) failed: %s", uid, /* pid= */ 0, strerror(-rc)); } } SetGids(env, gids, fail_fn); //设置group SetRLimits(env, rlimits, fail_fn); //设置资源limit if (use_native_bridge) { // Due to the logic behind use_native_bridge we know that both app_data_dir // and instruction_set contain values. android::PreInitializeNativeBridge(app_data_dir.value().c_str(), instruction_set.value().c_str()); } if (setresgid(gid, gid, gid) == -1) { fail_fn(CREATE_ERROR("setresgid(%d) failed: %s", gid, strerror(errno))); } ... //selinux上下文 if (selinux_android_setcontext(uid, is_system_server, se_info_ptr, nice_name_ptr) == -1) { fail_fn(CREATE_ERROR("selinux_android_setcontext(%d, %d, \"%s\", \"%s\") failed", uid, is_system_server, se_info_ptr, nice_name_ptr)); } //设置线程名为system_server,方便调试 if (nice_name.has_value()) { SetThreadName(nice_name.value()); } else if (is_system_server) { SetThreadName("system_server"); } // Unset the SIGCHLD handler, but keep ignoring SIGHUP (rationale in SetSignalHandlers). //设置子进程的signal信号处理函数为默认函数 UnsetChldSignalHandler(); if (is_system_server) { //对应 Zygote.java 的callPostForkSystemServerHooks() env->CallStaticVoidMethod(gZygoteClass, gCallPostForkSystemServerHooks); if (env->ExceptionCheck()) { fail_fn("Error calling post fork system server hooks."); } //对应ZygoteInit.java 的 createSystemServerClassLoader()//预取系统服务器的类加载器。这样做是为了尽早地绑定适当的系统服务器selinux域。 env->CallStaticVoidMethod(gZygoteInitClass, gCreateSystemServerClassLoader); if (env->ExceptionCheck()) { // Be robust here. The Java code will attempt to create the classloader // at a later point (but may not have rights to use AoT artifacts). env->ExceptionClear(); }... } //等价于调用zygote.java 的callPostForkChildHooks() env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, runtime_flags, is_system_server, is_child_zygote, managed_instruction_set); if (env->ExceptionCheck()) { fail_fn("Error calling post fork hooks."); }}```
**[ZygoteInit.java] handleSystemServerProcess**说明:创建类加载器,并赋予当前线程,其中环境变量SYSTEMSERVERCLASSPATH,主要是service.jar、ethernet-service.jar和wifi-service.jar这三个jar包
```export SYSTEMSERVERCLASSPATH=/system/framework/services.jar:/system/framework/ethernet-service.jar:/system/framework/wifi-service.jar```
```java private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) { if (parsedArgs.mNiceName != null) { Process.setArgV0(parsedArgs.mNiceName); //设置当前进程名为"system_server" } final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH"); if (systemServerClasspath != null) { //执行dex优化操作 if (performSystemServerDexOpt(systemServerClasspath)) { sCachedSystemServerClassLoader = null; }... } if (parsedArgs.mInvokeWith != null) { String[] args = parsedArgs.mRemainingArgs;//如果我们有一个非空系统服务器类路径,我们将不得不复制现有的参数并将类路径附加到它。//当我们执行一个新进程时,ART将正确地处理类路径。 if (systemServerClasspath != null) { String[] amendedArgs = new String[args.length + 2]; amendedArgs[0] = "-cp"; amendedArgs[1] = systemServerClasspath; System.arraycopy(args, 0, amendedArgs, 2, args.length); args = amendedArgs; } //启动应用进程 WrapperInit.execApplication(parsedArgs.mInvokeWith, parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion, VMRuntime.getCurrentInstructionSet(), null, args); throw new IllegalStateException("Unexpected return from WrapperInit.execApplication"); } else { // 创建类加载器,并赋予当前线程 createSystemServerClassLoader(); ClassLoader cl = sCachedSystemServerClassLoader; if (cl != null) { Thread.currentThread().setContextClassLoader(cl); } //system_server进入此分支 return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion, parsedArgs.mRemainingArgs, cl); }}```
**[ZygoteInit.java] zygoteInit**
**说明:**基础配置,并进行应用初始化,返回对象
```java protected static final void commonInit() {LoggingHandler loggingHandler = new LoggingHandler(); // 设置默认的未捕捉异常处理方法 RuntimeHooks.setUncaughtExceptionPreHandler(loggingHandler); Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler)); // 设置时区,通过属性读出中国时区为"Asia/Shanghai" RuntimeHooks.setTimeZoneIdSupplier(() -> SystemProperties.get("persist.sys.timezone")); //重置log配置 LogManager.getLogManager().reset(); new AndroidConfig(); //设置默认的HTTP User-agent格式,用于 HttpURLConnection String userAgent = getDefaultUserAgent(); System.setProperty("http.agent", userAgent); /* * Wire socket tagging to traffic stats. */ //设置socket的tag,用于网络流量统计 NetworkManagementSocketTagger.install();...}```
**[ZygoteInit.java] nativeZygoteInit**
**说明:**nativeZygoteInit 通过反射,进入com_android_internal_os_ZygoteInit_nativeZygoteInit
```c [AndroidRuntime.cpp]int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env){ const JNINativeMethod methods[] = { { "nativeZygoteInit", "()V", (void*) com_android_internal_os_ZygoteInit_nativeZygoteInit }, }; return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit", methods, NELEM(methods));} gCurRuntime = this;static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz){ //此处的gCurRuntime为AppRuntime,是在AndroidRuntime.cpp中定义的 gCurRuntime->onZygoteInit();} [app_main.cpp]virtual void onZygoteInit(){ sp<ProcessState> proc = ProcessState::self(); ALOGV("App process: starting thread pool.\n"); proc->startThreadPool(); //启动新binder线程}```
**[RuntimeInit.java] applicationInit**
**说明:**通过参数解析,得到args.startClass = com.android.server.SystemServer
```javaprotected static Runnable applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) { //true代表应用程序退出时不调用AppRuntime.onExit(),否则会在退出前调用 nativeSetExitWithoutCleanup(true); // We want to be fairly aggressive about heap utilization, to avoid // holding on to a lot of memory that isn't needed. //设置虚拟机的内存利用率参数值为0.75 VMRuntime.getRuntime().setTargetHeapUtilization(0.75f); VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion); final Arguments args = new Arguments(argv); //解析参数... // Remaining arguments are passed to the start class's static main //调用startClass的static方法 main() return findStaticMain(args.startClass, args.startArgs, classLoader);}```
**[RuntimeInit.java] findStaticMain**
**说明:**拿到SystemServer的main()方法,并返回 MethodAndArgsCaller()对象
```javaprotected static Runnable findStaticMain(String className, String[] argv, ClassLoader classLoader) { Class<?> cl; try {//拿到com.android.server.SystemServer 的类对象 cl = Class.forName(className, true, classLoader); } catch (ClassNotFoundException ex) { throw new RuntimeException( "Missing class when invoking static main " + className, ex); } Method m; try { //得到SystemServer的main()方法, m = cl.getMethod("main", new Class[] { String[].class }); } catch (NoSuchMethodException ex) { throw new RuntimeException( "Missing static main on " + className, ex); } catch (SecurityException ex) { throw new RuntimeException( "Problem getting static main on " + className, ex); } int modifiers = m.getModifiers(); if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) { throw new RuntimeException( "Main method is not public and static on " + className); } //把MethodAndArgsCaller的对象返回给ZygoteInit.main()。这样做好处是能清空栈帧,提高栈帧利用率//清除了设置进程所需的所有堆栈帧 return new MethodAndArgsCaller(m, argv);}```
**[RuntimeInit.java] MethodAndArgsCaller**
**说明:**最终在ZygoteInit.java的main(),调用这里的run()来启动SystemServer.java的main(),真正进入SystemServer进程
```java static class MethodAndArgsCaller implements Runnable { /** method to call */ private final Method mMethod; /** argument array */ private final String[] mArgs; public MethodAndArgsCaller(Method method, String[] args) { mMethod = method; mArgs = args; } public void run() { try { //根据传递过来的参数,可知此处通过反射机制调用的是SystemServer.main()方法 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); } }}```
###### 3.5 SystemServer启动后
**[SystemServer.java] main**
**说明:**main函数由Zygote进程 fork后运行,作用是new 一个SystemServer对象,再调用该对象的run()方法
```Javapublic static void main(String[] args) { //new 一个SystemServer对象,再调用该对象的run()方法 new SystemServer().run();}```
**[SystemServer.java] run**
**说明:**先初始化一些系统变量,加载类库,创建Context对象,创建SystemServiceManager对象等候再启动服务,启动引导服务、核心服务和其他服务
```Javaprivate void run() { try { traceBeginAndSlog("InitBeforeStartServices"); // Record the process start information in sys props. //从属性中读取system_server进程的一些信息 SystemProperties.set(SYSPROP_START_COUNT, String.valueOf(mStartCount)); SystemProperties.set(SYSPROP_START_ELAPSED, String.valueOf(mRuntimeStartElapsedTime)); SystemProperties.set(SYSPROP_START_UPTIME, String.valueOf(mRuntimeStartUptime)); EventLog.writeEvent(EventLogTags.SYSTEM_SERVER_START, mStartCount, mRuntimeStartUptime, mRuntimeStartElapsedTime); //如果一个设备的时钟是在1970年之前(0年之前), //那么很多api 都会因为处理负数而崩溃,尤其是java.io.File#setLastModified //所以把时间设置为1970 if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) { Slog.w(TAG, "System clock is before 1970; setting to 1970."); SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME); } //如果时区不存在,设置时区为GMT String timezoneProperty = SystemProperties.get("persist.sys.timezone"); if (timezoneProperty == null || timezoneProperty.isEmpty()) { Slog.w(TAG, "Timezone not set; setting to GMT."); SystemProperties.set("persist.sys.timezone", "GMT"); } //变更虚拟机的库文件,对于Android 10.0默认采用的是libart.so SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary()); // Mmmmmm... more memory! //清除vm内存增长上限,由于启动过程需要较多的虚拟机内存空间 VMRuntime.getRuntime().clearGrowthLimit();... //系统服务器必须一直运行,所以它需要尽可能高效地使用内存 //设置内存的可能有效使用率为0.8 VMRuntime.getRuntime().setTargetHeapUtilization(0.8f); //一些设备依赖于运行时指纹生成,所以在进一步启动之前,请确保我们已经定义了它。 Build.ensureFingerprintProperty(); //访问环境变量前,需要明确地指定用户 //在system_server中,任何传入的包都应该被解除,以避免抛出BadParcelableException。 BaseBundle.setShouldDefuse(true); //在system_server中,当打包异常时,信息需要包含堆栈跟踪 Parcel.setStackTraceParceling(true); //确保当前系统进程的binder调用,总是运行在前台优先级(foreground priority) BinderInternal.disableBackgroundScheduling(true); //设置system_server中binder线程的最大数量,最大值为31 BinderInternal.setMaxThreads(sMaxBinderThreads); //准备主线程lopper,即在当前线程运行 android.os.Process.setThreadPriority( android.os.Process.THREAD_PRIORITY_FOREGROUND); android.os.Process.setCanSelfBackground(false); Looper.prepareMainLooper(); Looper.getMainLooper().setSlowLogThresholdMs( SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS); //加载android_servers.so库,初始化native service System.loadLibrary("android_servers"); // Debug builds - allow heap profiling. //如果是Debug版本,允许堆内存分析 if (Build.IS_DEBUGGABLE) { initZygoteChildHeapProfiling(); } //检测上次关机过程是否失败,这个调用可能不会返回 performPendingShutdown(); //初始化系统上下文 createSystemContext(); //创建系统服务管理--SystemServiceManager mSystemServiceManager = new SystemServiceManager(mSystemContext); mSystemServiceManager.setStartInfo(mRuntimeRestart, mRuntimeStartElapsedTime, mRuntimeStartUptime); //将mSystemServiceManager添加到本地服务的成员sLocalServiceObjects LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); // Prepare the thread pool for init tasks that can be parallelized //为可以并行化的init任务准备线程池 SystemServerInitThreadPool.get(); } finally { traceEnd(); // InitBeforeStartServices } // Start services. //启动服务 try { traceBeginAndSlog("StartServices"); startBootstrapServices(); // 启动引导服务 startCoreServices(); // 启动核心服务 startOtherServices(); // 启动其他服务 SystemServerInitThreadPool.shutdown(); //停止线程池 } catch (Throwable ex) { Slog.e("System", "******************************************"); Slog.e("System", "************ Failure starting system services", ex); throw ex; } finally { traceEnd(); } //为当前的虚拟机初始化VmPolicy StrictMode.initVmDefaults(null);... // Loop forever. //死循环执行 Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited");}```
**[SystemServer.java] performPendingShutdown**
**说明:**检测上次关机过程是否失败,这个调用可能不会返回
```javaprivate 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; } //如果需要重新启动才能应用更新,一定要确保uncrypt在需要时正确执行。 //如果'/cache/recovery/block.map'还没有创建,停止重新启动,它肯定会失败, //并有机会捕获一个bugreport时,这仍然是可行的。 if (reason != null && reason.startsWith(PowerManager.REBOOT_RECOVERY_UPDATE)) { File packageFile = new File(UNCRYPT_PACKAGE_FILE); if (packageFile.exists()) { String filename = null; try { filename = FileUtils.readTextFile(packageFile, 0, null); } catch (IOException e) { Slog.e(TAG, "Error reading uncrypt package file", e); } if (filename != null && filename.startsWith("/data")) { if (!new File(BLOCK_MAP_FILE).exists()) { Slog.e(TAG, "Can't find block map file, uncrypt failed or " + "unexpected runtime restart?"); return; } } } } Runnable runnable = new Runnable() { @Override public void run() { synchronized (this) { //当属性sys.shutdown.requested的值为1时,会重启 //当属性的值不为空,且不为1时,会关机 ShutdownThread.rebootOrShutdown(null, reboot, reason); } } }; // ShutdownThread must run on a looper capable of displaying the UI. //ShutdownThread必须在一个能够显示UI的looper上运行 //即UI线程启动ShutdownThread的rebootOrShutdown Message msg = Message.obtain(UiThread.getHandler(), runnable); msg.setAsynchronous(true); UiThread.getHandler().sendMessage(msg); }}```
**[SystemServer.java] createSystemContext**
**说明:**初始化系统上下文, 该过程会创建对象有ActivityThread,Instrumentation, ContextImpl,LoadedApk,Application
```Javaprivate void createSystemContext() { //创建system_server进程的上下文信息 ActivityThread activityThread = ActivityThread.systemMain(); mSystemContext = activityThread.getSystemContext(); //设置主题 mSystemContext.setTheme(DEFAULT_SYSTEM_THEME); //获取systemui上下文信息,并设置主题 final Context systemUiContext = activityThread.getSystemUiContext(); systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);}```
**[SystemServer.java] startBootstrapServices**说明:用于启动系统Boot级服务,有ActivityManagerService, PowerManagerService, LightsService, DisplayManagerService, PackageManagerService, UserManagerService, sensor服务.
```Javaprivate void startBootstrapServices() { traceBeginAndSlog("StartWatchdog"); //启动watchdog //尽早启动watchdog,如果在早起启动时发生死锁,我们可以让system_server //崩溃,从而进行详细分析 final Watchdog watchdog = Watchdog.getInstance(); watchdog.start(); traceEnd(); ... //添加PLATFORM_COMPAT_SERVICE,Platform compat服务被ActivityManagerService、PackageManagerService //以及将来可能出现的其他服务使用。 traceBeginAndSlog("PlatformCompat"); ServiceManager.addService(Context.PLATFORM_COMPAT_SERVICE, new PlatformCompat(mSystemContext)); traceEnd(); //阻塞等待installd完成启动,以便有机会创建具有适当权限的关键目录,如/data/user。 //我们需要在初始化其他服务之前完成此任务。 traceBeginAndSlog("StartInstaller"); Installer installer = mSystemServiceManager.startService(Installer.class); traceEnd();... //启动服务ActivityManagerService,并为其设置mSystemServiceManager和installer traceBeginAndSlog("StartActivityManager"); ActivityTaskManagerService atm = mSystemServiceManager.startService( ActivityTaskManagerService.Lifecycle.class).getService(); mActivityManagerService = ActivityManagerService.Lifecycle.startService(mSystemServiceManager, atm); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); mWindowManagerGlobalLock = atm.getGlobalLock(); traceEnd(); //启动服务PowerManagerService //Power manager需要尽早启动,因为其他服务需要它。 //本机守护进程可能正在监视它的注册, //因此它必须准备好立即处理传入的绑定器调用(包括能够验证这些调用的权限)。 traceBeginAndSlog("StartPowerManager"); mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); traceEnd(); ... //初始化power management traceBeginAndSlog("InitPowerManagement"); mActivityManagerService.initPowerManagement(); traceEnd(); //启动recovery system,以防需要重新启动 traceBeginAndSlog("StartRecoverySystemService"); mSystemServiceManager.startService(RecoverySystemService.class); traceEnd();... //启动服务LightsService //管理led和显示背光,所以我们需要它来打开显示 traceBeginAndSlog("StartLightsService"); mSystemServiceManager.startService(LightsService.class); traceEnd();... //启动服务DisplayManagerService //显示管理器需要在包管理器之前提供显示指标 traceBeginAndSlog("StartDisplayManager"); mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class); traceEnd(); // Boot Phases: Phase100: 在初始化package manager之前,需要默认的显示. traceBeginAndSlog("WaitForDisplay"); mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); traceEnd(); //当设备正在加密时,仅运行核心 String cryptState = VoldProperties.decrypt().orElse(""); if (ENCRYPTING_STATE.equals(cryptState)) { Slog.w(TAG, "Detected encryption in progress - only parsing core apps"); mOnlyCore = true; } else if (ENCRYPTED_STATE.equals(cryptState)) { Slog.w(TAG, "Device encrypted - only parsing core apps"); mOnlyCore = true; }... //启动服务PackageManagerService traceBeginAndSlog("StartPackageManagerService"); try { Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain"); mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); } finally { Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain"); }... //启动服务UserManagerService,新建目录/data/user/ traceBeginAndSlog("StartUserManagerService"); mSystemServiceManager.startService(UserManagerService.LifeCycle.class); traceEnd(); // Set up the Application instance for the system process and get started. //为系统进程设置应用程序实例并开始。 //设置AMS traceBeginAndSlog("SetSystemProcess"); mActivityManagerService.setSystemProcess(); traceEnd(); //使用一个ActivityManager实例完成watchdog设置并监听重启,//只有在ActivityManagerService作为一个系统进程正确启动后才能这样做 traceBeginAndSlog("InitWatchdog"); watchdog.init(mSystemContext, mActivityManagerService); traceEnd(); //传感器服务需要访问包管理器服务、app ops服务和权限服务, //因此我们在它们之后启动它。 //在单独的线程中启动传感器服务。在使用它之前应该检查完成情况。 mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> { TimingsTraceLog traceLog = new TimingsTraceLog( SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER); traceLog.traceBegin(START_SENSOR_SERVICE); startSensorService(); //启动传感器服务 traceLog.traceEnd(); }, START_SENSOR_SERVICE);}```
**[SystemServer.java] startCoreServices**
**说明:**启动核心服务BatteryService,UsageStatsService,WebViewUpdateService、BugreportManagerService、GpuService等
```Javaprivate void startCoreServices() { //启动服务BatteryService,用于统计电池电量,需要LightService. mSystemServiceManager.startService(BatteryService.class); //启动服务UsageStatsService,用于统计应用使用情况 mSystemServiceManager.startService(UsageStatsService.class); mActivityManagerService.setUsageStatsManager( LocalServices.getService(UsageStatsManagerInternal.class)); //启动服务WebViewUpdateService //跟踪可更新的WebView是否处于就绪状态,并监视更新安装 if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) { mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class); } //启动CachedDeviceStateService,跟踪和缓存设备状态 mSystemServiceManager.startService(CachedDeviceStateService.class); //启动BinderCallsStatsService, 跟踪在绑定器调用中花费的cpu时间 traceBeginAndSlog("StartBinderCallsStatsService"); mSystemServiceManager.startService(BinderCallsStatsService.LifeCycle.class); traceEnd(); //启动LooperStatsService,跟踪处理程序中处理消息所花费的时间。 traceBeginAndSlog("StartLooperStatsService"); mSystemServiceManager.startService(LooperStatsService.Lifecycle.class); traceEnd(); //启动RollbackManagerService,管理apk回滚 mSystemServiceManager.startService(RollbackManagerService.class); //启动BugreportManagerService,捕获bugreports的服务 mSystemServiceManager.startService(BugreportManagerService.class); //启动GpuService,为GPU和GPU驱动程序提供服务。 mSystemServiceManager.startService(GpuService.class);}```
**[SystemServer.java] startOtherServices**
**说明:**启动其他的服务,开始处理一大堆尚未重构和整理的东西,这里的服务太多,大体启动过程类似,
```Javaprivate void startOtherServices() {... //启动TelecomLoaderService,通话相关核心服务 mSystemServiceManager.startService(TelecomLoaderService.class); //启动TelephonyRegistry telephonyRegistry = new TelephonyRegistry(context); ServiceManager.addService("telephony.registry", telephonyRegistry);...//启动AlarmManagerService,时钟管理mSystemServiceManager.startService(new AlarmManagerService(context));...//启动InputManagerServiceinputManager = new InputManagerService(context);ServiceManager.addService(Context.INPUT_SERVICE, inputManager, /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);...inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback()); inputManager.start();...//Phase480:在接收到此启动阶段后,服务可以获得锁设置数据 mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY); //Phase500:在接收到这个启动阶段之后,服务可以安全地调用核心系统服务, //如PowerManager或PackageManager。 mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);mActivityManagerService.systemReady(() -> { //Phase550:在接收到此引导阶段后,服务可以广播意图。 mSystemServiceManager.startBootPhase( SystemService.PHASE_ACTIVITY_MANAGER_READY); //Phase600:在接收到这个启动阶段后,服务可以启动/绑定到第三方应用程序。 //此时,应用程序将能够对服务进行绑定调用。 mSystemServiceManager.startBootPhase( SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);}}```
###### 小结
- Zygote启动后fork的第一个进程为SystemServer,在手机中的进程别名为"system_server",主要用来启动系统中的服务- Zygote fork后,进入SystemServer的main()- SystemServer在启动过程中,先初始化一些系统变量,加载类库,创建Context对象,创建SystemServiceManager对象等候再启动服务- 启动的服务分为 引导服务(Boot Service)、核心服务(Core Service)和其他服务(Other Service)三大类,共90多个服务- SystemServer在启动服务前,会尝试与Zygote建立Socket通信,通信成功后才去启动服务- 启动的服务都单独运行在SystemServer的各自线程中,同属于SystemServer进程
##### 4、ActivityMnagerService-AMS启动流程
###### 4.1 概述
ActivityManagerService简称AMS,具有管理Activity行为、控制activity的生命周期、派发消息事件、内存管理等功能。
###### 4.2 架构
ActivityManagerService启动共分为以下4个阶段:
阶段1:为SystemSerer进程创建Android运行环境。AMS运行与SystemServer进程中,它的许多工作依赖于该运行环境
```createSystemContext() -> new ActvityThread()-->attach ->getSystemContext ->createSystemContext```
阶段2:启动AMS,主要进行一些初始化工作
```javanew ActivityManagerService()start()```
阶段3:将SystemServer进程纳入到AMS的进程管理体系中
```JavasetSystemProcess() //将framework-res.apk的信息加入到SystemServer进程的LoadedApk中;构建SystemServer进程的ProcessRecord,保存到AMS中,以便AMS进程统一管理installSystemProvider() //安装SystemServer进程中的SettingsProvider.apk```
阶段4:AMS启动完成,通知服务或应用完成后续的工作,或直接启动一些进程
```JavaAMS.systemReady() //许多服务或应用进程必须等待AMS完成启动工作后,才能启动或进行一些后续工作;AMS就是在systemReady中,通知或者启动这些等待的服务和应用进程,例如启动桌面等。```
###### 4.3 AMS启动流程源码分析
从Zygote启动SystemServer,再到SystemServer启动AMS等服务
- 初始化 SystemContext- 创建SystemServiceManager 对象,用来启动后面的服务- 启动系统服务,共分为三种系统服务:系统引导服务(Boot Service)、核心服务(Core Service)和其他服务(Other Service)- 在引导服务(Boot Service)中启动ATM、AMS服务- 在其他服务(Other Service)中完成AMS的最后工作systemReady
**[SystemServer.java]**
```java public static void main(String[] args) { new SystemServer().run();} private void run() { ... //1.初始化 System Context createSystemContext(); //2.创建 SystemServiceManager 对象,用来启动后面的服务 mSystemServiceManager = new SystemServiceManager(mSystemContext); mSystemServiceManager.setStartInfo(mRuntimeRestart, mRuntimeStartElapsedTime, mRuntimeStartUptime); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); ... //3.启动服务 startBootstrapServices(); //启动引导服务 startCoreServices(); //启动核心服务 startOtherServices(); //启动其他服务 ...}```
**[SystemServer.java] startBootstrapServices()**
**说明:**启动引导服务,在其中启动了ATM和AMS服务,通过AMS安装Installer、初始化Power,设置系统进程等。
```javaprivate void startBootstrapServices() { ... //启动ActivityTaskManagerService服务,简称ATM,Android10新引入功能,用来管理Activity的启动、调度等功能 atm = mSystemServiceManager.startService( ActivityTaskManagerService.Lifecycle.class).getService(); //启动服务 ActivityManagerService,简称AMS mActivityManagerService = ActivityManagerService.Lifecycle.startService( mSystemServiceManager, atm); //安装Installer mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); //初始化PowerManager mActivityManagerService.initPowerManagement(); //设置系统进程 mActivityManagerService.setSystemProcess(); }```
**[SystemServer.java] startOtherServices**
**说明:**启动其他服务,AMS启动后,完成后续桌面启动等操作
```javaprivate void startOtherServices() { ... //安装SettingsProvider.apk mActivityManagerService.installSystemProviders(); mActivityManagerService.setWindowManager(wm); //AMS启动完成,完成后续的工作,例如启动桌面等 mActivityManagerService.systemReady(() -> { ... }, BOOT_TIMINGS_TRACE_LOG); ...}```
###### 4.4 System Context初始化
**说明:** 在SystemServer的run函数中,在启动AMS之前,调用了createSystemContext函,主要用来是初始化 System Context和SystemUi Context,并设置主题
当SystemServer 调用createSystemContext()完毕后,完成以下两个内容:
- 得到了一个ActivityThread对象,它代表当前进程 (此时为系统进程) 的主线程; - 得到了一个Context对象,对于SystemServer而言,它包含的Application运行环境与framework-res.apk有关。
**[ActivityThread.java] systemMain()**
**说明:** 创建ActivityThread对象,然后调用该对象的attach函数。
```java public static ActivityThread systemMain() { // The system process on low-memory devices do not get to use hardware // accelerated drawing, since this can add too much overhead to the // process. if (!ActivityManager.isHighEndGfx()) { ThreadedRenderer.disable(true); } else { ThreadedRenderer.enableForegroundTrimming(); } //获取ActivityThread对象 ActivityThread thread = new ActivityThread(); thread.attach(true, 0); return thread;}```
**ActivityThread 对象创建****说明:**ActivityThread是Android Framework中一个非常重要的类,它代表一个应用进程的主线程,其职责就是调度及执行在该线程中运行的四大组件。
注意到此处的ActivityThread创建于SystemServer进程中。
由于SystemServer中也运行着一些系统APK,例如framework-res.apk、SettingsProvider.apk等,因此也可以认为SystemServer是一个特殊的应用进程。
AMS负责管理和调度进程,因此AMS需要通过Binder机制和应用进程通信。
为此,Android提供了一个IApplicationThread接口,该接口定义了AMS和应用进程之间的交互函数。
ActivityThread的构造函数比较简单,获取ResourcesManager的单例对象,比较关键的是它的成员变量:
```javapublic final class ActivityThread extends ClientTransactionHandler { ... //定义了AMS与应用通信的接口,拿到ApplicationThread的对象 final ApplicationThread mAppThread = new ApplicationThread(); //拥有自己的looper,说明ActivityThread确实可以代表事件处理线程 final Looper mLooper = Looper.myLooper(); //H继承Handler,ActivityThread中大量事件处理依赖此Handler final H mH = new H(); //用于保存该进程的ActivityRecord final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>(); //用于保存进程中的Service final ArrayMap<IBinder, Service> mServices = new ArrayMap<>(); ////用于保存进程中的Application final ArrayList<Application> mAllApplications = new ArrayList<Application>(); //构造函数 @UnsupportedAppUsage ActivityThread() { mResourcesManager = ResourcesManager.getInstance(); }}```
**[ActivityThread.java] attach****说明:**对于系统进程而言,ActivityThread的attach函数最重要的工作就是创建了Instrumentation、Application和Context
**调用:**attach(true, 0),传入的system为0
```javaprivate void attach(boolean system, long startSeq) { mSystemThread = system; //传入的system为0 if (!system) { //应用进程的处理流程 ... } else { //系统进程的处理流程,该情况只在SystemServer中处理 //创建ActivityThread中的重要成员:Instrumentation、 Application 和 Context mInstrumentation = new Instrumentation(); mInstrumentation.basicInit(this); //创建系统的Context ContextImpl context = ContextImpl.createAppContext( this, getSystemContext().mPackageInfo); //调用LoadedApk的makeApplication函数 mInitialApplication = context.mPackageInfo.makeApplication(true, null); mInitialApplication.onCreate(); } }```
**Instrumentation**
Instrumentation是Android中的一个工具类,当该类被启用时,它将优先于应用中其它的类被初始化。
此时,系统先创建它,再通过它创建其它组件。
```javamInstrumentation = new Instrumentation();mInstrumentation.basicInit(this);```
**Context**
Context是Android中的一个抽象类,用于维护应用运行环境的全局信息。
通过Context可以访问应用的资源和类,甚至进行系统级的操作,例如启动Activity、发送广播等。
ActivityThread的attach函数中,通过下面的代码创建出系统应用对应的Context:
```javaContextImpl context = ContextImpl.createAppContext(this, getSystemContext().mPackageInfo);```
**Application**
Android中Application类用于保存应用的全局状态。
在ActivityThread中,针对系统进程,通过下面的代码创建了初始的Application:
```java mInitialApplication = context.mPackageInfo.makeApplication(true, null);mInitialApplication.onCreate();```
**[ContextImpl.java] getSystemContext()****说明:**创建并返回System Context
```javapublic ContextImpl getSystemContext() { synchronized (this) { if (mSystemContext == null) { //调用ContextImpl的静态函数createSystemContext mSystemContext = ContextImpl.createSystemContext(this); } return mSystemContext; }}```
**说明:**createSystemContext的内容就是创建一个LoadedApk,然后初始化一个ContextImpl对象。 注意到createSystemContext函数中,创建的LoadApk对应packageName为”android”,也就是framwork-res.apk。 由于该APK仅供SystemServer进程使用,因此创建的Context被定义为System Context。 现在该LoadedApk还没有得到framwork-res.apk实际的信息。当PKMS启动,完成对应的解析后,AMS将重新设置这个LoadedApk。
```javastatic ContextImpl createSystemContext(ActivityThread mainThread) { //创建LoadedApk类,代表一个加载到系统中的APK //注意此时的LoadedApk只是一个空壳 //PKMS还没有启动,无法得到有效的ApplicationInfo LoadedApk packageInfo = new LoadedApk(mainThread); //拿到ContextImpl 的对象 ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0, null, null); //初始化资源信息 context.setResources(packageInfo.getResources()); context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(), context.mResourcesManager.getDisplayMetrics()); return context;}```
**SystemServiceManager 创建**
**说明:** 通过 SystemServiceManager 的构造方法创建一个 SystemServiceManager 对象,并将该对象添加到 LocalServices 中。
```javaprivate void run() { ... //1.创建SystemServiceManager对象 mSystemServiceManager = new SystemServiceManager(mSystemContext); mSystemServiceManager.setStartInfo(mRuntimeRestart, mRuntimeStartElapsedTime, mRuntimeStartUptime); //2.启动SystemServiceManager服务 LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); ...}```
**[SystemServiceManager.java] SystemServiceManager()****说明:**SystemServiceManager 对象主要用于管理 SystemService 的创建、启动等生命周期,SystemService 类是一个抽象类
在 SystemServiceManager 中都是通过反射创建 SystemService 中对象的,而且在 startService(@NonNull final SystemService service) 方法中,会将 SystemService 添加到 mServices 中,并调用 onStart() 方法
SystemServiceManager构造函数没有多少内容,主要是把传进来的system Context赋值给 mContext,供后续服务创建使用
```javapublic class SystemServiceManager { ... private final Context mContext; private final ArrayList<SystemService> mServices = new ArrayList<SystemService>(); ... SystemServiceManager(Context context) { mContext = context; } public SystemService startService(String className) { final Class<SystemService> serviceClass; try { //通过反射根据类名,拿到类对象 serviceClass = (Class<SystemService>)Class.forName(className); } catch (ClassNotFoundException ex) { Slog.i(TAG, "Starting " + className); ... } return startService(serviceClass); } public <T extends SystemService> T startService(Class<T> serviceClass) { try { final String name = serviceClass.getName(); // Create the service. final T service; ... service = constructor.newInstance(mContext); ... startService(service); return service; } finally { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } } public void startService(@NonNull final SystemService service) { // Register it. mServices.add(service); // Start it. long time = SystemClock.elapsedRealtime(); try { service.onStart(); //调用各个服务中的onStart()方法完成服务启动 } catch (RuntimeException ex) { throw new RuntimeException("Failed to start service " + service.getClass().getName() + ": onStart threw an exception", ex); } }}```
**[LocalServices.java] addService(SystemServiceManager.class, mSystemServiceManager);**
**说明:**把SystemServiceManager的对象加入到本地服务的全局注册表中
```javapublic final class LocalServices { private LocalServices() {} private static final ArrayMap<Class<?>, Object> sLocalServiceObjects = new ArrayMap<Class<?>, Object>(); //返回实现指定接口的本地服务实例对象 @SuppressWarnings("unchecked") public static <T> T getService(Class<T> type) { synchronized (sLocalServiceObjects) { return (T) sLocalServiceObjects.get(type); } } //将指定接口的服务实例添加到本地服务的全局注册表中 public static <T> void addService(Class<T> type, T service) { synchronized (sLocalServiceObjects) { if (sLocalServiceObjects.containsKey(type)) { throw new IllegalStateException("Overriding service registration"); } sLocalServiceObjects.put(type, service); } } //删除服务实例,只能在测试中使用。 public static <T> void removeServiceForTest(Class<T> type) { synchronized (sLocalServiceObjects) { sLocalServiceObjects.remove(type); } }}```
**ActivityTaskManagerService 服务启动**
**说明:**ActivityTaskManagerService简称ATM,Android10中引入新功能,用来管理Activity的启动、调度等功能
```javaprivate void startBootstrapServices() { ... //启动ATM atm = mSystemServiceManager.startService( ActivityTaskManagerService.Lifecycle.class).getService(); ...}```
**ATM服务启动过程****说明:**我们知道SystemServiceManager.startService最终调用的是启动对象中的onStart方法
因此ATM启动,最终会调用ActivityTaskManagerService.Lifecycle.onStart()来启动ATM服务
```javapublic static final class Lifecycle extends SystemService { private final ActivityTaskManagerService mService; public Lifecycle(Context context) { super(context); //1.创建ActivityTaskManagerService,得到对象 mService = new ActivityTaskManagerService(context); } @Override public void onStart() { publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService); //2.启动ATM服务 mService.start(); } ... public ActivityTaskManagerService getService() { return mService; } }```
**ActivityTaskManagerService 对象创建****说明:**ActivityTaskManagerService简称ATM, Android10新引入功能,用来管理Activity的启动、调度等功能
Android10 中把原先在AMS中activity的管理移动到ATM中
从Android 10的代码路径可以看出,管理Activity的ATM被放入到的wm路径中,这个路径原先归WindowManagerService -WMS控制,谷歌的目的也是希望在将来把activity和window融合在一起,减少冗余代码以及AMS和WMS的协调工作
**ATM的路径为:**frameworks\base\services\core\java\com\android\server\wm
**AMS的路径为:**frameworks\base\services\core\java\com\android\server\am
```javapublic class ActivityTaskManagerService extends IActivityTaskManager.Stub { final Context mUiContext; final ActivityThread mSystemThread; final ActivityTaskManagerInternal mInternal; //ActivityStackSupervisor 是ATM中用来管理Activity启动和调度的核心类 public ActivityStackSupervisor mStackSupervisor; //Activity 容器的根节点 RootActivityContainer mRootActivityContainer; //WMS 负责窗口的管理 WindowManagerService mWindowManager; //这是我们目前认为是"Home" Activity的过程 WindowProcessController mHomeProcess; public ActivityTaskManagerService(Context context) { //拿到System Context mContext = context; mFactoryTest = FactoryTest.getMode(); //取出的是ActivityThread的静态变量sCurrentActivityThread //这意味着mSystemThread与SystemServer中的ActivityThread一致 mSystemThread = ActivityThread.currentActivityThread(); //拿到System UI Context mUiContext = mSystemThread.getSystemUiContext(); mLifecycleManager = new ClientLifecycleManager(); //拿到LocalService的对象 mInternal = new LocalService(); GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", GL_ES_VERSION_UNDEFINED); }}```
**[ActivityTaskManagerService.java] start()**
**说明:**将 ActivityTaskManagerInternal添加到本地服务的全局注册表中,ActivityTaskManagerInternal为抽象类
```javaprivate void start() { LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);}```
**ActivityManagerService 服务启动**
**说明:**ActivityManagerService简称AMS,在Android 10的版本中,Activity的管理和调度移到ATM中,AMS负责 service,broadcast,provider的管理和调度
```javaprivate void startBootstrapServices() { ... //启动AMS mActivityManagerService = ActivityManagerService.Lifecycle.startService(mSystemServiceManager, atm); ...}```
**AMS服务启动过程**说明:从4.3.1 中我们知道SystemServiceManager.startService最终调用的是启动对象中的onStart方法
因此AMS服务启动,最终会调用ActivityManagerService.Lifecycle.onStart()来启动ATM服务
```javapublic static final class Lifecycle extends SystemService { private final ActivityManagerService mService; private static ActivityTaskManagerService sAtm; public Lifecycle(Context context) { super(context); //1.创建ActivityManagerService,得到对象,传入ATM的对象 mService = new ActivityManagerService(context, sAtm); } @Override public void onStart() { mService.start(); } ... public ActivityManagerService getService() { return mService; }}```
**AMS 对象创建**说明:Android10中,Activity的管理和调度放入到ATM中执行,AMS中保留 service,broadcast,provider的管理和调度
构造函数初始化主要工作就是初始化一些变量,供之后的service,broadcast,provider的管理和调度
```javapublic class ActivityManagerService extends IActivityManager.Stub implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) { ... //AMS的运行上下文与SystemServer一致 mContext = systemContext; ... //取出的是ActivityThread的静态变量sCurrentActivityThread //这意味着mSystemThread与SystemServer中的ActivityThread一致 mSystemThread = ActivityThread.currentActivityThread(); mUiContext = mSystemThread.getSystemUiContext(); mHandlerThread = new ServiceThread(TAG, THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); mHandlerThread.start(); //处理AMS中消息的主力 mHandler = new MainHandler(mHandlerThread.getLooper()); //UiHandler对应于Android中的UiThread mUiHandler = mInjector.getUiHandler(this); //创建 BroadcastQueue 前台广播对象,处理超时时长是 10s mFgBroadcastQueue = new BroadcastQueue(this, mHandler, "foreground", foreConstants, false); //创建 BroadcastQueue 后台广播对象,处理超时时长是 60s mBgBroadcastQueue = new BroadcastQueue(this, mHandler, "background", backConstants, true); //创建 BroadcastQueue 分流广播对象,处理超时时长是 60s mOffloadBroadcastQueue = new BroadcastQueue(this, mHandler, "offload", offloadConstants, true); mBroadcastQueues[0] = mFgBroadcastQueue; mBroadcastQueues[1] = mBgBroadcastQueue; mBroadcastQueues[2] = mOffloadBroadcastQueue; // 创建 ActiveServices 对象,用于管理 ServiceRecord 对象 mServices = new ActiveServices(this); // 创建 ProviderMap 对象,用于管理 ContentProviderRecord 对象 mProviderMap = new ProviderMap(this); //得到ATM的对象,调用ATM.initialize mActivityTaskManager = atm; mActivityTaskManager.initialize(mIntentFirewall, mPendingIntentController, DisplayThread.get().getLooper()); //得到ATM的服务信息 mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class); //加入Watchdog的监控 Watchdog.getInstance().addMonitor(this); Watchdog.getInstance().addThread(mHandler); }}```
**[ActivityManagerService.java] start()**
**说明:**start中做了两件事
1)启动 CPU 监控线程,在启动 CPU 监控线程之前,首先将进程复位
2)注册电池状态服务和权限管理服务
```javaprivate void start() { //1.移除所有的进程组 removeAllProcessGroups(); //启动 CPU 监控线程 mProcessCpuThread.start(); //2.注册电池状态和权限管理服务 mBatteryStatsService.publish(); mAppOpsService.publish(mContext); Slog.d("AppOps", "AppOpsService published"); LocalServices.addService(ActivityManagerInternal.class, new LocalService()); mActivityTaskManager.onActivityManagerInternalAdded(); mUgmInternal.onActivityManagerInternalAdded(); mPendingIntentController.onActivityManagerInternalAdded(); // Wait for the synchronized block started in mProcessCpuThread, // so that any other access to mProcessCpuTracker from main thread // will be blocked during mProcessCpuTracker initialization. try { mProcessCpuInitLatch.await(); } catch (InterruptedException e) { Slog.wtf(TAG, "Interrupted wait during start", e); Thread.currentThread().interrupt(); throw new IllegalStateException("Interrupted wait during start"); }}```
**[SystemServer.java] setSystemProcess()**
**说明:**为系统进程设置应用程序实例并开始
```java private void startOtherServices() { Set up the Application instance for the system process and get started. mActivityManagerService.setSystemProcess(); }```
**[ActivityManagerService.java] setSystemProcess()****说明:**AMS的setSystemProcess主要有五个主要的功能:
- 注册一些服务:包括 activity、procstats、meminfo、gfxinfo、dbinfo、permission、processinfo- 获取package名为“android”的应用的 ApplicationInfo; - 为ActivityThread 安装 system application相关信息,将framework-res.apk对应的ApplicationInfo安装到LoadedApk中的mApplicationInfo - 为systemserver 主进程开辟一个ProcessRecord来维护进程的相关信息- AMS进程管理相关的操作。
```javapublic void setSystemProcess() { try { //1.注册一些服务到ServiceManager:包括 activity、procstats、meminfo、gfxinfo、dbinfo、permission、processinfo ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true, DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO); ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_HIGH); ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); ServiceManager.addService("dbinfo", new DbBinder(this)); if (MONITOR_CPU_USAGE) { ServiceManager.addService("cpuinfo", new CpuBinder(this), /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL); } ServiceManager.addService("permission", new PermissionController(this)); ServiceManager.addService("processinfo", new ProcessInfoService(this)); //2.通过解析framework-res.apk里的AndroidManifest.xml获得ApplicationInfo ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY); //3.为ActivityThread 安装 system application相关信息,将framework-res.apk对应的ApplicationInfo安装到LoadedApk中的mApplicationInfo mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); //4.为systemserver 主进程开辟一个ProcessRecord来维护进程的相关信息 synchronized (this) { ProcessRecord app = mProcessList.newProcessRecordLocked(info, info.processName, false, 0, new HostingRecord("system")); app.setPersistent(true); //设置进程常驻 app.pid = MY_PID; //为ProcessRecord赋值当前进程ID,即system_server进程ID app.getWindowProcessController().setPid(MY_PID); app.maxAdj = ProcessList.SYSTEM_ADJ; app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); mPidsSelfLocked.put(app); //将ProcessRecord放到mPidSelfLocked里统一管理 mProcessList.updateLruProcessLocked(app, false, null); updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_NONE); } } catch (PackageManager.NameNotFoundException e) { throw new RuntimeException( "Unable to find android system package", e); } // Start watching app ops after we and the package manager are up and running. mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null, new IAppOpsCallback.Stub() { @Override public void opChanged(int op, int uid, String packageName) { if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) { if (mAppOpsService.checkOperation(op, uid, packageName) != AppOpsManager.MODE_ALLOWED) { runInBackgroundDisabled(uid); } } } }); }```
**完成ActivityManagerService 最后工作[ActivityManagerService.java] systemReady()****说明:** AMS的systemReady 处理分为三个阶段
- 阶段1:主要是调用一些关键服务的初始化函数, 然后杀死那些没有FLAG_PERSISTENT却在AMS启动完成前已经存在的进程,
同时获取一些配置参数。 需要注意的是,由于只有Java进程才会向AMS注册,而一般的Native进程不会向AMS注册,因此此处杀死的进程是Java进程。
- 阶段2:执行goingCallback的处理,主要的工作就是通知一些服务可以进行systemReady、systemRunning相关的工作,并进行启动服务或应用进程的工作
- 阶段3:启动Home Activity,当启动结束,并发送ACTION_BOOT_COMPLETED广播时,AMS的启动过程告一段落
```java private void startOtherServices() { mActivityManagerService.systemReady(() -> {xxxxxgoingCallbackxxx, BOOT_TIMINGS_TRACE_LOG); } public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) { 阶段1:关键服务的初始化 阶段2:goingCallback处理 阶段3:启动Home Activity,完成AMS启动 } ```
**systemReady 阶段1****说明:**主要是调用一些关键服务的初始化函数, 然后杀死那些没有 FLAG_PERSISTENT 却在AMS启动完成前已经存在的进程, 同时获取一些配置参数。 需要注意的是,由于只有Java进程才会向AMS注册,而一般的Native进程不会向AMS注册,因此此处杀死的进程是Java进程。
```javapublic void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) { synchronized(this) { //第一次进入mSystemReady 为false,不走该流程 if (mSystemReady) { if (goingCallback != null) { goingCallback.run(); } return; } /** PowerSaveMode_start */ Settings.System.putInt(mContext.getContentResolver(), ActivityTaskManagerService.SUPER_POWER_SAVE_MODE, ActivityTaskManagerService.SUPER_POWER_SAVE_MODE_NORMAL); /** PowerSaveMode_end */ //这一部分主要是调用一些关键服务SystemReady相关的函数, //进行一些等待AMS初始完,才能进行的工作 mActivityTaskManager.onSystemReady(); mUserController.onSystemReady(); mAppOpsService.systemReady(); ... mSystemReady = true; } try { sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface( ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE)) .getSerial(); } catch (RemoteException e) {} ArrayList<ProcessRecord> procsToKill = null; synchronized(mPidsSelfLocked) { //mPidsSelfLocked 中保存当前正在运行的所有进程的信息 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { ProcessRecord proc = mPidsSelfLocked.valueAt(i); //在AMS启动完成前,如果没有FLAG_PERSISTENT标志的进程已经启动了, //就将这个进程加入到procsToKill中 if (!isAllowedWhileBooting(proc.info)){ if (procsToKill == null) { procsToKill = new ArrayList<ProcessRecord>(); } procsToKill.add(proc); } } } //收集已经启动的进程并杀死,排除persistent常驻进程 synchronized(this) { //利用removeProcessLocked关闭procsToKill中的进程 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); mProcessList.removeProcessLocked(proc, true, false, "system update done"); } } //至此系统准备完毕 mProcessesReady = true; } ... mUgmInternal.onSystemReady(); }```
**systemReady 阶段2**
**说明:**执行goingCallback的处理,主要工作就是通知一些服务可以进行systemReady的相关工作,并进行启动服务或应用进程的工作。
```Javapublic void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) { ... //1.调用参数传入的runnable对象,SystemServer中有具体的定义 if (goingCallback != null) goingCallback.run(); ... //调用所有系统服务的onStartUser接口 mSystemServiceManager.startUser(currentUserId); synchronized (this) { //启动persistent为1的application所在的进程 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE); // Start up initial activity. mBooting = true; ...}```
**goingCallback.run()**
**说明:**监控Native的crash,启动WebView,执行一些服务的systemReady 和systemRunning方法
```Javaprivate void startOtherServices() { mActivityManagerService.systemReady(() -> { //阶段 550 mSystemServiceManager.startBootPhase( SystemService.PHASE_ACTIVITY_MANAGER_READY); ... //监控Native的crash mActivityManagerService.startObservingNativeCrashes(); , BOOT_TIMINGS_TRACE_LOG); ... //启动WebView mWebViewUpdateService.prepareWebViewInSystemServer(); //启动systemUI startSystemUi(context, windowManagerF); // 执行一系列服务的systemReady方法 networkManagementF.systemReady(); ipSecServiceF.systemReady(); networkStatsF.systemReady(); connectivityF.systemReady(); networkPolicyF.systemReady(networkPolicyInitReadySignal); ... //阶段 600 mSystemServiceManager.startBootPhase( SystemService.PHASE_THIRD_PARTY_APPS_CAN_START); //执行一系列服务的systemRunning方法 locationF.systemRunning(); countryDetectorF.systemRunning(); networkTimeUpdaterF.systemRunning(); inputManagerF.systemRunning(); telephonyRegistryF.systemRunning(); mediaRouterF.systemRunning(); mmsServiceF.systemRunning(); ...}```
**[ActivityManagerService.java] startPersistentApps**
**说明:**启动persistent为1的application所在的进程
```Javavoid startPersistentApps(int matchFlags) { if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return; synchronized (this) { try { //从PKMS中得到persistent为1的ApplicationInfo final List<ApplicationInfo> apps = AppGlobals.getPackageManager() .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList(); for (ApplicationInfo app : apps) { //由于framework-res.apk已经由系统启动,所以此处不再启动它 if (!"android".equals(app.packageName)) { //addAppLocked中将启动application所在进程 addAppLocked(app, null, false, null /* ABI override */); } } } catch (RemoteException ex) { } }}```
**启动systemUI startSystemUi**
**说明:**启动system UI, 启动服务,服务名称”com.android.systemui/.SystemUIService”
```javaprivate static void startSystemUi(Context context, WindowManagerService windowManager) { Intent intent = new Intent(); intent.setComponent(new ComponentName("com.android.systemui", "com.android.systemui.SystemUIService")); intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING); //Slog.d(TAG, "Starting service: " + intent); context.startServiceAsUser(intent, UserHandle.SYSTEM); windowManager.onSystemUiStarted();}```
**systemReady 阶段3**
**说明:**启动Home Activity,当启动结束,并发送ACTION_BOOT_COMPLETED广播时,AMS的启动过程告一段落
```javapublic void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) { ... //1.通过ATM,启动Home Activity mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady"); ... //2.发送一些广播消息 try { //system发送广播 ACTION_USER_STARTED = "android.intent.action.USER_STARTED"; Intent intent = new Intent(Intent.ACTION_USER_STARTED); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND); intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId); broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, OP_NONE, null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid, currentUserId); //system发送广播 ACTION_USER_STARTING= "android.intent.action.USER_STARTING"; intent = new Intent(Intent.ACTION_USER_STARTING); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId); broadcastIntentLocked(null, null, intent, null, new IIntentReceiver.Stub() { @Override public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) throws RemoteException { } }, 0, null, null, new String[] {INTERACT_ACROSS_USERS}, OP_NONE, null, true, false, MY_PID, SYSTEM_UID, callingUid, callingPid, UserHandle.USER_ALL); } catch (Throwable t) { Slog.wtf(TAG, "Failed sending first user broadcasts", t); } finally { Binder.restoreCallingIdentity(ident); }}```
**[ActivityTaskManagerService] startHomeOnAllDisplays**
**说明:**启动Home Activity
**[ActivityTaskManagerService.java]**
```javapublic boolean startHomeOnAllDisplays(int userId, String reason) { synchronized (mGlobalLock) { //调用RootActivityContainer的startHomeOnAllDisplays(),最终到startHomeOnDisplay() return mRootActivityContainer.startHomeOnAllDisplays(userId, reason); }}```
**[RootActivityContainer.java]**
```Javaboolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting, boolean fromHomeKey) { // Fallback to top focused display if the displayId is invalid. if (displayId == INVALID_DISPLAY) { displayId = getTopDisplayFocusedStack().mDisplayId; } Intent homeIntent = null; ActivityInfo aInfo = null; if (displayId == DEFAULT_DISPLAY) { //home intent有CATEGORY_HOME homeIntent = mService.getHomeIntent(); //根据intent中携带的ComponentName,利用PKMS得到ActivityInfo aInfo = resolveHomeActivity(userId, homeIntent); } else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) { Pair<ActivityInfo, Intent> info = RootActivityContainerMifavor.resolveSecondaryHomeActivityPcMode(this, userId, displayId); aInfo = info.first; homeIntent = info.second; } if (aInfo == null || homeIntent == null) { return false; } if (!canStartHomeOnDisplay(aInfo, displayId, allowInstrumenting)) { return false; } // Updates the home component of the intent. homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name)); homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK); // Updates the extra information of the intent. if (fromHomeKey) { homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true); } // Update the reason for ANR debugging to verify if the user activity is the one that // actually launched. final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId( aInfo.applicationInfo.uid) + ":" + displayId; //启动Home Activity--Luncher mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason, displayId); return true;}```
###### 小结:
**AMS的启动主要经历了如下几个阶段:**
- 为SystemServer进程创建Android运行环境,例如System Context- 启动AMS,做一些初始化的工作- 将SystemServer进程纳入到AMS的进程管理体系中- AMS启动完成,通知服务或应用完成后续的工作,调用一些服务的systemReady()方法- 启动Luncher,完成AMS的启动工作
##### 5、Launcher(桌面)启动流程
###### 5.1 概述
Launcher不支持桌面小工具动画效果,Launcher2添加了动画效果和3D初步效果支持,从Android 4.4 (KK)开始Launcher默认使用Launcher3,Launcher3加入了透明状态栏,增加overview模式,可以调整workspace上页面的前后顺序,可以动态管理屏幕数量,widget列表与app list分开显示等功能。
###### 5.2 核心源码
```/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java/frameworks/base/core/java/com/android/internal/os/ZygoteServer.java/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java/frameworks/base/core/java/com/android/internal/os/Zygote.java/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java/frameworks/base/services/java/com/android/server/SystemServer.java/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java/frameworks/base/services/core/java/com/android/server/am/ProcessList.java/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java/frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java/frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java/frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java/frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java/frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java/frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java/frameworks/base/core/java/android/os/Process.java/frameworks/base/core/java/android/os/ZygoteProcess.java/frameworks/base/core/java/android/app/ActivityThread.java/frameworks/base/core/java/android/app/Activity.java/frameworks/base/core/java/android/app/ActivityManagerInternal.java/frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java/frameworks/base/core/java/android/app/servertransaction/ClientTransaction.aidl/frameworks/base/core/java/android/app/ClientTransactionHandler.java/frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java/frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java/frameworks/base/core/java/android/app/Instrumentation.java/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java```
从上面的代码路径可以看出,Android10.0中 Activity的相关功能被放到了wm的目录中,在Android9.0中是在am目录中,Google 最终的目的是把activity 和window融合,在Android10中只是做了简单的代码路径的变更,正式的功能还要到后面的版本才能慢慢融合。
**主要代码作用:**
- Instrumentation: 负责调用Activity和Application生命周期。
- ActivityTaskManagerService: 负责Activity管理和调度等工作。 ATM是Android10中新增内容
- ActivityManagerService: 负责管理四大组件和进程,包括生命周期和状态切换。
- ActivityTaskManagerInternal: 是由ActivityTaskManagerService对外提供的一个抽象类,真正的实现是在 ActivityTaskManagerService#LocalService
- ActivityThread: 管理应用程序进程中主线程的执行
- ActivityStackSupervisor: 负责所有Activity栈的管理
- TransactionExecutor: 主要作用是执行ClientTransaction
- ClientLifecycleManager: 生命周期的管理调用
###### 5.3 架构
```mermaidgraph TBA[Boot ROM]-->B[BootLoader]B--加载内核-->C[Kernel]C--启动-->D[init]D--解析文件-->E[init.rc]E-->F[loop]E-.启动进程.->EA[Zygote]E-.->EB[service_manager]E-.->EC[SurfaceFlinger]E-.->ED[MediaServer]EA--启动-->EAA[虚拟机]EAA-->EAB[fork]EAB-->EAC[loop]EAB-.->EABA[system_server]EABA--启动-->EABC[系统服务]EABC--显示-->EABD[启动界面]EABD--启动-->EABE[Launcher]EABE-.->EABEAB-.fork.->EABF[Launcher]EABF--显示-->EABG[桌面]EB-->EBA[Binder]EBA-->EBC[loop]EC-->ECA[FrameBuffer]ECA-->ECB[loop]ED-->EDA[AudioFlinger]EDA-->EDB[CameraService]EDB-->EDD[MediaPlayerService]EDD-->EDE[loop]ECA-.->EBAEABC-->EABCA(系统服务 AMS PMS InputManagerService WMS)EABCA-.->EBA```
###### 5.4 源码分析
AMS启动完成前,在systemReady()中会去调用startHomeOnAllDisplays()来启动Launcher,所以从startHomeOnAllDisplays()函数入口,对Launcher启动过程进行分析。
```Java[ActivityManagerService.java]public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) { ... //启动Home Activity mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady"); ...}```
**Launcher的启动由三部分启动:**
- SystemServer完成启动Launcher Activity的调用- Zygote()进行Launcher进程的Fork操作- 进入ActivityThread的main(),完成最终Launcher的onCreate操作
###### 5.5第一阶段SystemServer 启动HomeActivity的调用阶段
**[ActivityTaskManagerService.java] startHomeOnAllDisplays()**
**说明:**ActivityTaskManagerInternal是 ActivityTaskManagerService的一个抽象类,真正的实现是在ActivityTaskManagerService的LocalService,所以mAtmInternal.startHomeOnAllDisplays()最终调用的是ActivityTaskManagerService的startHomeOnAllDisplays()方法
```javapublic boolean startHomeOnAllDisplays(int userId, String reason) { synchronized (mGlobalLock) { //一路调用到 RootActivityContainer 的startHomeOnDisplay()方法 return mRootActivityContainer.startHomeOnAllDisplays(userId, reason); }}```
**[RootActivityContainer.java] startHomeOnDisplay()**
**说明:**在`startHomeOnAllDisplays`中,获取的displayId为DEFAULT_DISPLAY, 首先通过getHomeIntent 来构建一个category为CATEGORY_HOME的Intent,表明是Home Activity;然后通过resolveHomeActivity()从系统所用已安装的引用中,找到一个符合HomeItent的Activity,最终调用startHomeActivity()来启动Activity
```Javaboolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting, boolean fromHomeKey) { ... if (displayId == DEFAULT_DISPLAY) { //构建一个category为CATEGORY_HOME的Intent,表明是Home Activity homeIntent = mService.getHomeIntent(); //通过PKMS从系统所用已安装的引用中,找到一个符合HomeItent的Activity aInfo = resolveHomeActivity(userId, homeIntent); } ... //启动Home Activity mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason, displayId); return true;}```
**[ActivityTaskManagerService.java] getHomeIntent()**
**说明:**构建一个category为CATEGORY_HOME的Intent,表明是Home Activity。
Intent.CATEGORY_HOME = "android.intent.category.HOME"
这个category会在Launcher3的 AndroidManifest.xml中配置,表明是Home Acivity
```JavaIntent getHomeIntent() { Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); intent.setComponent(mTopComponent); intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING); //不是生产模式,add一个CATEGORY_HOME if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { intent.addCategory(Intent.CATEGORY_HOME); } return intent;}```
**[RootActivityContainer.java] resolveHomeActivity()**
**说明:**通过Binder跨进程通知PackageManagerService从系统所有已安装的引用中,找到一个符合HomeItent的Activity
```JavaActivityInfo resolveHomeActivity(int userId, Intent homeIntent) { final int flags = ActivityManagerService.STOCK_PM_FLAGS; final ComponentName comp = homeIntent.getComponent(); //系统正常启动时,component为null ActivityInfo aInfo = null; ... if (comp != null) { // Factory test. aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); } else { //系统正常启动时,走该流程 final String resolvedType = homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver()); //resolveIntent做了两件事:1.通过queryIntentActivities来查找符合HomeIntent需求的Activities // 2.通过chooseBestActivity找到最符合Intent需求的Activity信息 final ResolveInfo info = AppGlobals.getPackageManager() .resolveIntent(homeIntent, resolvedType, flags, userId); if (info != null) { aInfo = info.activityInfo; } } ... aInfo = new ActivityInfo(aInfo); aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId); return aInfo;}```
**[ActivityStartController.java ] startHomeActivity()**
**说明:**启动的Home Activity入口。obtainStarter() 方法返回的是 ActivityStarter 对象,它负责 Activity 的启动,一系列 setXXX() 方法传入启动所需的各种参数,最后的 execute() 是真正的启动逻辑。另外如果home activity处于顶层的resume activity中,则Home Activity 将被初始化,但不会被恢复。并将保持这种状态,直到有东西再次触发它。我们需要进行一次恢复。
```Javavoid startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) { .... //返回一个 ActivityStarter 对象,它负责 Activity 的启动 //一系列 setXXX() 方法传入启动所需的各种参数,最后的 execute() 是真正的启动逻辑 //最后执行 ActivityStarter的execute方法 mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason) .setOutActivity(tmpOutRecord) .setCallingUid(0) .setActivityInfo(aInfo) .setActivityOptions(options.toBundle()) .execute(); mLastHomeActivityStartRecord = tmpOutRecord[0]; final ActivityDisplay display = mService.mRootActivityContainer.getActivityDisplay(displayId); final ActivityStack homeStack = display != null ? display.getHomeStack() : null; if (homeStack != null && homeStack.mInResumeTopActivity) { //如果home activity 处于顶层的resume activity中,则Home Activity 将被初始化,但不会被恢复(以避免递归恢复), //并将保持这种状态,直到有东西再次触发它。我们需要进行另一次恢复。 mSupervisor.scheduleResumeTopActivities(); }}```
**[ActivityStarter.java] execute()**
**说明:**在startHomeActivity中obtainStarter没有调用setMayWait的方法,因此mRequest.mayWait为false,走startActivity流程
```Javaint execute() { ... if (mRequest.mayWait) { return startActivityMayWait(...) } else { return startActivity(...) //走这里 } ...}```
**[ActivityStarter.java] startActivity()**
**说明:**延时布局,然后通过startActivityUnchecked()来处理启动标记 flag ,要启动的任务栈等,最后恢复布局
```Javaprivate int startActivity(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity, boolean restrictedBgActivity) { ... try { //延时布局 mService.mWindowManager.deferSurfaceLayout(); //调用 startActivityUnchecked ,一路调用到resumeFocusedStacksTopActivities() result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, doResume, options, inTask, outActivity, restrictedBgActivity); } finally { //恢复布局 mService.mWindowManager.continueSurfaceLayout(); } ...}```
**[RootActivityContainer.java] resumeFocusedStacksTopActivities()**
**说明:**获取栈顶的Activity,恢复它
```Javaboolean resumeFocusedStacksTopActivities( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) { ... //如果秒表栈就是栈顶Activity,启动resumeTopActivityUncheckedLocked() if (targetStack != null && (targetStack.isTopStackOnDisplay() || getTopDisplayFocusedStack() == targetStack)) { result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); ... if (!resumedOnDisplay) { // 获取 栈顶的 ActivityRecord final ActivityStack focusedStack = display.getFocusedStack(); if (focusedStack != null) { //最终调用startSpecificActivityLocked() focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions); } } }}```
**[ActivityStackSupervisor.java] startSpecificActivityLocked()**
**说明:**发布消息以启动进程,以避免在ATM锁保持的情况下调用AMS时可能出现死锁,最终调用到ATM的startProcess()
```Javavoid startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) { ... //发布消息以启动进程,以避免在ATM锁保持的情况下调用AMS时可能出现死锁 //最终调用到AMS的startProcess() final Message msg = PooledLambda.obtainMessage( ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName, r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent()); mService.mH.sendMessage(msg); ...}```
**[ActivityManagerService.java] startProcess()**
**说明:**一路调用Process start(),最终到ZygoteProcess的attemptUsapSendArgsAndGetResult(),用来fork一个新的Launcher的进程
```Javapublic void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead, String hostingType, ComponentName hostingName) { .. //同步操作,避免死锁 synchronized (ActivityManagerService.this) { //调用startProcessLocked,然后到 Process的start,最终到ZygoteProcess的attemptUsapSendArgsAndGetResult() //用来fork一个新的Launcher的进程 startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */, new HostingRecord(hostingType, hostingName), false /* allowWhileBooting */, false /* isolated */, true /* keepIfLarge */); } ...}```
**[ZygoteProcess.java] attemptZygoteSendArgsAndGetResult()**
**说明:**通过Socket连接Zygote进程,把之前组装的msg发给Zygote,其中processClass ="android.app.ActivityThread",通过Zygote进程来Fork出一个新的进程,并执行 "android.app.ActivityThread"的main方法
```Javaprivate Process.ProcessStartResult attemptZygoteSendArgsAndGetResult( ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx { try { //传入的zygoteState为openZygoteSocketIfNeeded(),里面会通过abi来检查是第一个zygote还是第二个 final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter; final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream; zygoteWriter.write(msgStr); //把应用进程的一些参数写给前面连接的zygote进程,包括前面的processClass ="android.app.ActivityThread" zygoteWriter.flush(); //进入Zygote进程,处于阻塞状态 //从socket中得到zygote创建的应用pid,赋值给 ProcessStartResult的对象 Process.ProcessStartResult result = new Process.ProcessStartResult(); result.pid = zygoteInputStream.readInt(); result.usingWrapper = zygoteInputStream.readBoolean(); if (result.pid < 0) { throw new ZygoteStartFailedEx("fork() failed"); } return result; } catch (IOException ex) { zygoteState.close(); Log.e(LOG_TAG, "IO Exception while communicating with Zygote - " + ex.toString()); throw new ZygoteStartFailedEx(ex); }}```
###### 5.6 第二阶段Zygote fork一个Launcher进程的阶段
**说明:**Zygote的启动过程前面有详细讲到过。SystemServer的AMS服务向启动Home Activity发起一个fork请求,Zygote进程通过Linux的fork函数,孵化出一个新的进程。
由于Zygote进程在启动时会创建Java虚拟机,因此通过fork而创建的Launcher程序进程可以在内部获取一个Java虚拟机的实例拷贝。fork采用copy-on-write机制,有些类如果不做改变,甚至都不用复制,子进程可以和父进程共享这部分数据,从而省去不少内存的占用。
**[ZygoteInit.java] main()**
**说明:**Zygote先fork出SystemServer进程,接着进入循环等待,用来接收Socket发来的消息,用来fork出其他应用进程,比如Launcher
```Javapublic static void main(String argv[]) { ... Runnable caller; .... if (startSystemServer) { //Zygote Fork出的第一个进程 SystmeServer Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer); if (r != null) { r.run(); return; } } ... //循环等待fork出其他的应用进程,比如Launcher //最终通过调用processOneCommand()来进行进程的处理 caller = zygoteServer.runSelectLoop(abiList); ... if (caller != null) { caller.run(); //执行返回的Runnable对象,进入子进程 }}```
**[ZygoteConnection.java] processOneCommand()**
**说明:**通过forkAndSpecialize()来fork出Launcher的子进程,并执行handleChildProc,进入子进程的处理
```JavaRunnable processOneCommand(ZygoteServer zygoteServer) { int pid = -1; ... //Fork子进程,得到一个新的pid /fork子进程,采用copy on write方式,这里执行一次,会返回两次 ///pid=0 表示Zygote fork子进程成功 //pid > 0 表示子进程 的真正的PID pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids, parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo, parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote, parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion); ... if (pid == 0) { // in child, fork成功,第一次返回的pid = 0 ... //执行handleChildProc,进入子进程的处理 return handleChildProc(parsedArgs, descriptors, childPipeFd, parsedArgs.mStartChildZygote); } else { //in parent ... childPipeFd = null; handleParentProc(pid, descriptors, serverPipeFd); return null; }}```
**[ZygoteConnection.java] handleChildProc()**
**说明:**进行子进程的操作,最终获得需要执行的ActivityThread的main()
```Javaprivate Runnable handleChildProc(ZygoteArguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, boolean isZygote) { ... if (parsedArgs.mInvokeWith != null) { ... throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned"); } else { if (!isZygote) { // App进程将会调用到这里,执行目标类的main()方法 return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion, parsedArgs.mRemainingArgs, null /* classLoader */); } else { return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion, parsedArgs.mRemainingArgs, null /* classLoader */); } }}```
zygoteInit 进行一些环境的初始化、启动Binder进程等操作:
```Javapublic static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) { RuntimeInit.commonInit(); //初始化运行环境 ZygoteInit.nativeZygoteInit(); //启动Binder线程池 //调用程序入口函数 return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);}```
把之前传来的"android.app.ActivityThread" 传递给findStaticMain:
```Javaprotected static Runnable applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) { ... // startClass: 如果AMS通过socket传递过来的是 ActivityThread return findStaticMain(args.startClass, args.startArgs, classLoader);}```
通过反射,拿到ActivityThread的main()方法:
```Javaprotected static Runnable findStaticMain(String className, String[] argv, ClassLoader classLoader) { Class<?> cl; try { cl = Class.forName(className, true, classLoader); } catch (ClassNotFoundException ex) { throw new RuntimeException( "Missing class when invoking static main " + className, ex); } Method m; try { m = cl.getMethod("main", new Class[] { String[].class }); } catch (NoSuchMethodException ex) { throw new RuntimeException( "Missing static main on " + className, ex); } catch (SecurityException ex) { throw new RuntimeException( "Problem getting static main on " + className, ex); } int modifiers = m.getModifiers(); if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) { throw new RuntimeException( "Main method is not public and static on " + className); } return new MethodAndArgsCaller(m, argv);}```
把反射得来的ActivityThread main()入口返回给ZygoteInit的main,通过caller.run()进行调用:
```Javastatic class MethodAndArgsCaller implements Runnable { /** method to call */ private final Method mMethod; /** argument array */ private final String[] mArgs; public MethodAndArgsCaller(Method method, String[] args) { mMethod = method; mArgs = args; } //调用ActivityThread的main() 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); } }}```
###### 5.7 第三个阶段,Launcher在自己的进程中进行onCreate等后面的动作
从第二个阶段可以看到,Zygote fork出了Launcher的进程,并把接下来的Launcher启动任务交给了ActivityThread来进行,接下来就从ActivityThread main()来分析Launcher的创建过程。
**[ActivityThread.java] main()**
**说明:**主线程处理, 创建ActivityThread对象,调用attach进行处理,最终进入Looper循环
```Javapublic static void main(String[] args) { // 安装选择性的系统调用拦截 AndroidOs.install(); ... //主线程处理 Looper.prepareMainLooper(); ... //之前SystemServer调用attach传入的是true,这里的应用进程传入false就行 ActivityThread thread = new ActivityThread(); thread.attach(false, startSeq); ... //一直循环,如果退出,说明程序关闭 Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited");}```
调用ActivityThread的attach进行处理
```Javaprivate void attach(boolean system, long startSeq) { sCurrentActivityThread = this; mSystemThread = system; if (!system) { //应用进程启动,走该流程 ... RuntimeInit.setApplicationObject(mAppThread.asBinder()); //获取AMS的本地代理类 final IActivityManager mgr = ActivityManager.getService(); try { //通过Binder调用AMS的attachApplication方法 mgr.attachApplication(mAppThread, startSeq); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } ... } else { //通过system_server启动ActivityThread对象 ... } // 为 ViewRootImpl 设置配置更新回调, 当系统资源配置(如:系统字体)发生变化时,通知系统配置发生变化 ViewRootImpl.ConfigChangedCallback configChangedCallback = (Configuration globalConfig) -> { synchronized (mResourcesManager) { ... } }; ViewRootImpl.addConfigCallback(configChangedCallback);}```
**[ActivityManagerService.java] attachApplication()**
**说明:**清除一些无用的记录,最终调用ActivityStackSupervisor.java的 realStartActivityLocked(),进行Activity的启动
```Javapublic final void attachApplication(IApplicationThread thread, long startSeq) { synchronized (this) { //通过Binder获取传入的pid信息 int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); attachApplicationLocked(thread, callingPid, callingUid, startSeq); Binder.restoreCallingIdentity(origId); }}```
```Javaprivate final boolean attachApplicationLocked(IApplicationThread thread, int pid, int callingUid, long startSeq) { ... //如果当前的Application记录仍然依附到之前的进程中,则清理掉 if (app.thread != null) { handleAppDiedLocked(app, true, true); }· //mProcessesReady这个变量在AMS的 systemReady 中被赋值为true, //所以这里的normalMode也为true boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); ... //上面说到,这里为true,进入StackSupervisor的attachApplication方法 //去真正启动Activity if (normalMode) { ... //调用ATM的attachApplication(),最终层层调用到ActivityStackSupervisor.java的 realStartActivityLocked() //参考[4.5.3] didSomething = mAtmInternal.attachApplication(app.getWindowProcessController()); ... } ... return true;}```
**[ActivityStackSupervisor.java] realStartActivityLocked()**
**说明:**真正准备去启动Activity,通过clientTransaction.addCallback把LaunchActivityItem的obtain作为回调参数加进去,再调用
ClientLifecycleManager.scheduleTransaction()得到
LaunchActivityItem的execute()方法进行最终的执行
```Javaboolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc, boolean andResume, boolean checkConfig) throws RemoteException { // 直到所有的 onPause() 执行结束才会去启动新的 activity if (!mRootActivityContainer.allPausedActivitiesComplete()) { ... return false; } try { // Create activity launch transaction. // 添加 LaunchActivityItem final ClientTransaction clientTransaction = ClientTransaction.obtain( proc.getThread(), r.appToken); //LaunchActivityItem.obtain(new Intent(r.intent)作为回调参数 clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent), System.identityHashCode(r), r.info, // TODO: Have this take the merged configuration instead of separate global // and override configs. mergedConfiguration.getGlobalConfiguration(), mergedConfiguration.getOverrideConfiguration(), r.compat, r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(), r.icicle, r.persistentState, results, newIntents, dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(), r.assistToken)); ... // 设置生命周期状态 final ActivityLifecycleItem lifecycleItem; if (andResume) { lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward()); } else { lifecycleItem = PauseActivityItem.obtain(); } clientTransaction.setLifecycleStateRequest(lifecycleItem); // Schedule transaction. // 重点关注:调用 ClientLifecycleManager.scheduleTransaction(),得到上面addCallback的LaunchActivityItem的execute()方法 mService.getLifecycleManager().scheduleTransaction(clientTransaction); } catch (RemoteException e) { if (r.launchFailed) { // 第二次启动失败,finish activity stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, "2nd-crash", false); return false; } // 第一次失败,重启进程并重试 r.launchFailed = true; proc.removeActivity(r); throw e; } } finally { endDeferResume(); } ... return true;}```
**[TransactionExecutor.java] execute()**
**说明**:执行之前realStartActivityLocked()中的
clientTransaction.addCallback
```Javapublic void execute(ClientTransaction transaction) { ... // 执行 callBack,参考上面的调用栈,执行回调方法, //最终调用到ActivityThread的handleLaunchActivity()参考[4.5.5] executeCallbacks(transaction); // 执行生命周期状态 executeLifecycleState(transaction); mPendingActions.clear();}```
**[ActivityThread.java] handleLaunchActivity()**
**说明:**主要干了两件事,第一件:初始化WindowManagerGlobal;第二件:调用performLaunchActivity方法
```Javapublic Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) { ... //初始化WindowManagerGlobal WindowManagerGlobal.initialize(); ... //调用performLaunchActivity,来处理Activity final Activity a = performLaunchActivity(r, customIntent); .. return a;}```
**[ActivityThread.java] performLaunchActivity()**
**说明:**获取ComponentName、Context,反射创建Activity,设置Activity的一些内容,比如主题等; 最终调用callActivityOnCreate()来执行Activity的onCreate()方法
```Javaprivate Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { // 获取 ComponentName ComponentName component = r.intent.getComponent(); ... // 获取 Context ContextImpl appContext = createBaseContextForActivity(r); Activity activity = null; try { // 反射创建 Activity java.lang.ClassLoader cl = appContext.getClassLoader(); activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); StrictMode.incrementExpectedActivityCount(activity.getClass()); r.intent.setExtrasClassLoader(cl); r.intent.prepareToEnterProcess(); if (r.state != null) { r.state.setClassLoader(cl); } } catch (Exception e) { ... } try { // 获取 Application Application app = r.packageInfo.makeApplication(false, mInstrumentation); if (activity != null) { ... //Activity的一些处理 activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances, config, r.referrer, r.voiceInteractor, window, r.configCallback, r.assistToken); if (customIntent != null) { activity.mIntent = customIntent; } ... int theme = r.activityInfo.getThemeResource(); if (theme != 0) { // 设置主题 activity.setTheme(theme); } activity.mCalled = false; // 执行 onCreate() if (r.isPersistable()) { mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } ... r.activity = activity; } //当前状态为ON_CREATE r.setState(ON_CREATE); ... } catch (SuperNotCalledException e) { throw e; } catch (Exception e) { ... } return activity;}```
callActivityOnCreate先执行activity onCreate的预处理,再去调用Activity的onCreate,最终完成Create创建后的内容处理
```Javapublic void callActivityOnCreate(Activity activity, Bundle icicle, PersistableBundle persistentState) { prePerformCreate(activity); //activity onCreate的预处理 activity.performCreate(icicle, persistentState);//执行onCreate() postPerformCreate(activity); //activity onCreate创建后的一些信息处理}```
performCreate()主要调用Activity的onCreate()
```Javafinal void performCreate(Bundle icicle, PersistableBundle persistentState) { ... if (persistentState != null) { onCreate(icicle, persistentState); } else { onCreate(icicle); } ...}```
至此,看到了我们最熟悉的Activity的onCreate(),Launcher的启动完成,Launcher被真正创建起来。
###### 小结
看到onCreate()后,进入到我们最熟悉的Activity的入口,Launcher的启动告一段落。整个Android的启动流程,我们也完整的分析完成。
Launcher的启动经过了三个阶段:
- 第一个阶段:SystemServer完成启动Launcher Activity的调用
- 第二个阶段:Zygote()进行Launcher进程的Fork操作
- 第三个阶段:进入ActivityThread的main(),完成最终Launcher的onCreate操作
##### 总结
- 第一步:手机开机后,引导芯片启动,引导芯片开始从固化在ROM里的预设代码执行,加载引导程序到到RAM,bootloader检查RAM,初始化硬件参数等功能;- 第二步:硬件等参数初始化完成后,进入到Kernel层,Kernel层主要加载一些硬件设备驱动,初始化进程管理等操作。在Kernel中首先启动swapper进程(pid=0),用于初始化进程管理、内管管理、加载Driver等操作,再启动kthread进程(pid=2),这些linux系统的内核进程,kthread是所有内核进程的鼻祖;- 第三步:Kernel层加载完毕后,硬件设备驱动与HAL层进行交互。初始化进程管理等操作会启动INIT进程 ,这些在Native层中;- 第四步:init进程(pid=1,init进程是所有进程的鼻祖,第一个启动)启动后,会启动adbd,logd等用户守护进程,并且会启动servicemanager(binder服务管家)等重要服务,同时孵化出zygote进程,这里属于C++ Framework,代码为C++程序;- 第五步:zygote进程是由init进程解析init.rc文件后fork生成,它会加载虚拟机,启动System Server(zygote孵化的第一个进程);System Server负责启动和管理整个Java Framework,包含ActivityManager,WindowManager,PackageManager,PowerManager等服务;- 第六步:zygote同时会启动相关的APP进程,它启动的第一个APP进程为Launcher,然后启动Email,SMS等进程,所有的APP进程都由zygote fork生成。