阅读须知
本文源码基于 Android 10
。
Questions
- 如何处理系统服务启动的依赖关系?
- 如何发布系统服务,让其对其他应用或服务可见?
SystemServer
在 Zygote
一文中简单的提到了 Zygote
启动后会去启动 SystemServer
。本文将从源码的角度对 SystemServer
做一个详细的分析。
本文的大致流程如下图所示。
启动 SystemServer
首先看看 SystemServer
的启动。这里主要做了如下事情:
- 给
Zygote
设置SigChld
信号处理; - 通过
fork()
孵化出system_server
。
还记得 ZygoteInit.main()
里启动 SystemServer
的代码吗?
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
if (r != null) {
r.run();
return;
}
}
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
// 参数组装
String args[] = {
// ...
"com.android.server.SystemServer",
};
ZygoteArguments parsedArgs = null;
parsedArgs = new ZygoteArguments(args);
// 启动 system_server 进程
pid = Zygote.forkSystemServer(
parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);
}
注意这里启动 SystemServer
传递的参数 com.android.server.SystemServer
,后面会用到。这里的调用链如下图所示。
设置 SigChld 信号处理
在 ForkCommon()
中首先会给 Zygote
设置 SigChld
信号处理。
// frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
const std::vector& fds_to_close,
const std::vector& fds_to_ignore) {
// 设置 SigChld 信号处理
SetSignalHandlers();
}
static void SetSignalHandlers() {
struct sigaction sig_chld = {};
// 当收到 SigChld 信号的时候调用 SigChldHandler
sig_chld.sa_handler = SigChldHandler;
}
static void SigChldHandler(int /*signal_number*/) {
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
// 当 system_server 进程挂掉了,则把 zygote 干掉,让 init 去重启 zygote
if (pid == gSystemServerPid) {
kill(getpid(), SIGKILL);
}
}
}
当 system_server
挂掉时 Zygote
会收到 SigChld
信号,然后 Zygote
会 kill
自身,让 init
来重启 Zygote
。
这里的 gSystemServerPid
即 system_server
的 pid
,它是在 ForkCommon()
调用后赋值的。
// frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
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) {
// 这里调用的 FormCommon()
pid_t pid = ForkCommon(env, true,
fds_to_close,
fds_to_ignore);
if (pid == 0) {
// pid == 0 表示在 system_server 进程
} else if (pid > 0) {
// pid > 0 表示在父进程,这里 gSystemServerPid 赋值为 system_server 的进程id
gSystemServerPid = pid;
}
return pid;
}
孵化 system_server 进程
设置完 SigChld
信号处理后,就通过 fork()
孵化 system_server
进程。
// frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
const std::vector& fds_to_close,
const std::vector& fds_to_ignore) {
// fork system_server 进程
pid_t pid = fork();
}
关于 fork()
,这里简单说明一下,它被调用一次,会返回两次,有 3 种不同的返回值:
- 在父进程中,
fork()
返回子进程的pid
; - 在子进程中,
fork()
返回 0; - 当
fork
子进程报错时返回负值。
因为当进程调用 fork()
后,控制转移到内核中的 fork()
代码,内核会做 4 件事情:
- 分配新的内存块和内核数据结构给子进程;
- 将父进程部分数据结构内容拷贝至子进程;
- 添加子进程到系统进程列表当中;
-
fork()
返回,开始调度器调度。
所以当程序执行 pid = fork()
时,由于在复制时子进程复制了父进程的堆栈段或相应的变量与数据结构,所以两个进程都停留在 fork()
中,等待返回。
因此 fork()
会返回两次,一次是在父进程中返回,另一次是在子进程中返回,这两次的返回值是不一样的。
准备工作
fork
出 system_server
后,会做一些初始化工作。主要包括:
- 一些常规的初始化,然后启动
binder
线程; - 查找并调用
SystemServer.main()
;
回到 ZygoteInit
接着 forkSystemServer()
往下看。
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
// fork system_server
pid = Zygote.forkSystemServer(
parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);
// pid == 0 表示在 system_server 进程
if (pid == 0) {
// 调用 handleSystemServerProcess 做一些初始化工作
return handleSystemServerProcess(parsedArgs);
}
}
这里 pid == 0
即在 system_server
进程,其调用链如下图红框所示。
启动 binder 线程
在 zygoteInit()
中会先做一些常规的初始化操作,然后开启 binder
线程。
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
ZygoteInit.nativeZygoteInit();
}
// frameworks/base/core/jni/AndroidRuntime.cpp
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
// gCurRuntime 即 AppRuntime
gCurRuntime->onZygoteInit();
}
// frameworks/base/cmds/app_process/app_main.cpp
virtual void onZygoteInit()
{
sp proc = ProcessState::self();
// 开启 binder 线程
proc->startThreadPool();
}
这里的 gCurRuntime
就是 AppRuntime
,它是在 Zygote
的入口函数 app_main.main()
被赋值的。
// frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[])
{
// AppRuntime 继承了 AndroidRuntime
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
}
// frameworks/base/core/jni/AndroidRuntime.cpp
AndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) :
mExitWithoutCleanup(false),
mArgBlockStart(argBlockStart),
mArgBlockLength(argBlockLength)
{
// 在 AndroidRuntime 构造器里面会将 gCurRuntime 赋值为 AppRuntime
gCurRuntime = this;
}
查找并调用 SystemServer.main()
启动 binder
线程后,紧接着会去查找并调用 com.android.server.SystemServer
(前面提到过的参数)的 static main()
。
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
// frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class> cl;
try {
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
}
// 反射查找 main()
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
} catch (SecurityException ex) {
}
// 判断是不是 public static
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);
}
static class MethodAndArgsCaller implements Runnable {
public void run() {
try {
// 调用 main()
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
} catch (InvocationTargetException ex) {
}
}
}
SystemServer工作流程
进入 SystemServer.main()
后就开始 SystemServer
的工作流程了。这里主要会做如下事情:
- 初始化主线程
Looper
; - 加载
android_servers.so
库; - 初始化系统上下文;
- 创建系统服务管理者
SystemServiceManager
; - 分批次分阶段性的启动服务;
- 进入
loop()
循环等待和处理请求。
SystemServer.main()
简单粗暴,直接创建 SystemServer
,然后调用其 run()
。
// frameworks/base/services/java/com/android/server/SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}
初始化主线程 Looper
首先会初始化主线程 Looper
。
// frameworks/base/services/java/com/android/server/SystemServer.java
private void run() {
Looper.prepareMainLooper();
}
加载 android_servers.so
接着加载 android_servers.so
库,该库包含的源码位于 frameworks/base/services/core/jni
下。
// frameworks/base/services/java/com/android/server/SystemServer.java
private void run() {
System.loadLibrary("android_servers");
}
初始化系统上下文
接着会初始化系统上下文。
// frameworks/base/services/java/com/android/server/SystemServer.java
private void run() {
createSystemContext();
}
其调用链如下图所示,它和应用进程类似,也会创建 ActivityThread
,调用其 attach()
,创建 Application
等。
构建包名为 android 的 LoadedApk
这里主要看下 ContextImpl.createSystemContext()
。
// frameworks/base/core/java/android/app/ContextImpl.java
static ContextImpl createSystemContext(ActivityThread mainThread) {
// 构建包名为 android 的 LoadedApk
LoadedApk packageInfo = new LoadedApk(mainThread);
// 构建 ContextImpl
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
null, null);
return context;
}
// frameworks/base/core/java/android/app/LoadedApk.java
LoadedApk(ActivityThread activityThread) {
mActivityThread = activityThread;
mApplicationInfo = new ApplicationInfo();
// 包名为 android
mApplicationInfo.packageName = "android";
mPackageName = "android";
}
可以看到这里构建了一个包名为 android
的 LoadedApk
。
构建 Resources
接着会创建 ResourcesImpl
。
// frameworks/base/core/java/android/app/LoadedApk.java
LoadedApk(ActivityThread activityThread) {
mResources = Resources.getSystem();
}
// frameworks/base/core/java/android/content/res/Resources.java
private Resources() {
// 创建 ResourceImpl,并调用 AssetManager.getSystem()
mResourcesImpl = new ResourcesImpl(AssetManager.getSystem(), metrics, config,
new DisplayAdjustments());
}
加载 framework-res.apk
在创建 ResourceImpl
时调用了 AssetManager.getSystem()
,这里会加载 framework-res.apk
,并创建 AssetManager
。
// frameworks/base/core/java/android/content/res/AssetManager.java
// frameowrk-res.apk 路径
private static final String FRAMEWORK_APK_PATH = "/system/framework/framework-res.apk";
static AssetManager sSystem = null;
public static AssetManager getSystem() {
synchronized (sSync) {
// 这里会加载 framework-res.apk
createSystemAssetsInZygoteLocked();
return sSystem;
}
}
private static void createSystemAssetsInZygoteLocked() {
final ArrayList apkAssets = new ArrayList<>();
// 加载 framework-res.apk
apkAssets.add(ApkAssets.loadFromPath(FRAMEWORK_APK_PATH, true /*system*/));
sSystemApkAssets = apkAssets.toArray(new ApkAssets[apkAssets.size()]);
// 创建 AssetManager
sSystem = new AssetManager(true /*sentinel*/);
// 设置 apk 资源
sSystem.setApkAssets(sSystemApkAssets, false /*invalidateCaches*/);
}
创建 SystemServiceManager
接着会创建 SystemServiceManager
。
// frameworks/base/services/java/com/android/server/SystemServer.java
private void run() {
mSystemServiceManager = new SystemServiceManager(mSystemContext);
}
SystemServiceManager
SystemServiceManager
是用来管理系统服务(继承自 SystemService
的类)的创建、启动和其他生命周期事件。
关于 SystemServiceManager
主要关注其两个方法 startService()
和 startBootPhase()
。
startService()
startService()
是用来创建系统服务,并将系统服务添加到 mServices
集合中进行统一的管理,最后调用系统服务的 onStart()
。
// frameworks/base/services/java/com/android/server/SystemService.java
// 对 SystemService 进行统一的管理
private final ArrayList mServices = new ArrayList();
public SystemService startService(String className) {
final Class serviceClass;
try {
serviceClass = (Class)Class.forName(className);
} catch (ClassNotFoundException ex) {
}
return startService(serviceClass);
}
public T startService(Class serviceClass) {
final String name = serviceClass.getName();
// 判断是否是继承自 SystemService
if (!SystemService.class.isAssignableFrom(serviceClass)) {
throw new RuntimeException("Failed to create " + name
+ ": service must extend " + SystemService.class.getName());
}
// 反射创建
final T service;
try {
Constructor constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (NoSuchMethodException ex) {
} catch (InvocationTargetException ex) {
}
startService(service);
return service;
}
public void startService(@NonNull final SystemService service) {
// 注册服务
mServices.add(service);
// 调用其 onStart()
service.onStart();
}
startBootPhase()
Android
系统的系统服务是非常之多的,这些系统服务之间或多或少会存在一些依赖关系,如何去保证这些系统服务都能够正常有序的启动就成了一个问题。SystemServer
通过分批分阶段的方式来解决这个问题。
当启动到达不同阶段的时候 SystemServer
会调用 startBootPhase()
,这时 SystemServiceManager
就会通知已经添加到 mServices
中系统服务,这样系统服务只需要在不同的阶段做不同的事情即可。
// frameworks/base/services/java/com/android/server/SystemService.java
private int mCurrentPhase = -1;
public void startBootPhase(final int phase) {
// 保存当前所处阶段
if (phase <= mCurrentPhase) {
throw new IllegalArgumentException("Next phase must be larger than previous");
}
mCurrentPhase = phase;
try {
// 遍历 mServices 中的系统服务并调用其 onBootPhase()
final int serviceLen = mServices.size();
for (int i = 0; i < serviceLen; i++) {
final SystemService service = mServices.get(i);
try {
service.onBootPhase(mCurrentPhase);
} catch (Exception ex) {
}
}
} finally {
}
}
SystemService
SystemService
是系统服务的基类。
关于 SystemService
主要关注其几个生命周期方法,onStart()
,publishBinderService()
和 onBootPhase
。
onStart()
当服务启动后应调用此方法,一般会在里面发布服务。
// frameworks/base/services/core/java/com/android/server/SystemService.java
public abstract void onStart();
publishBinderService()
publishBinderService()
用于发布服务。
系统服务通过此方法将自己的 IBinder
发布到 ServiceManager
中,这样其他应用或服务就可以访问到它。
// frameworks/base/services/core/java/com/android/server/SystemService.java
protected final void publishBinderService(String name, IBinder service) {
publishBinderService(name, service, false);
}
protected final void publishBinderService(String name, IBinder service,
boolean allowIsolated) {
publishBinderService(name, service, allowIsolated, DUMP_FLAG_PRIORITY_DEFAULT);
}
protected final void publishBinderService(String name, IBinder service,
boolean allowIsolated, int dumpPriority) {
ServiceManager.addService(name, service, allowIsolated, dumpPriority);
}
onBootPhase()
前面说了当到达不同阶段时,SystemServer
会通过 SystemServiceManager
的 startBootPhase()
来通知系统服务,那系统服务可以通过重写 onBootPhase()
来接受不同阶段事件,并在所关心的阶段处理对应的事情。
// frameworks/base/services/core/java/com/android/server/SystemService.java
public abstract class SystemService {
public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100;
public static final int PHASE_LOCK_SETTINGS_READY = 480;
public static final int PHASE_SYSTEM_SERVICES_READY = 500;
public static final int PHASE_DEVICE_SPECIFIC_SERVICES_READY = 520;
public static final int PHASE_ACTIVITY_MANAGER_READY = 550;
public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;
public static final int PHASE_BOOT_COMPLETED = 1000;
public void onBootPhase(int phase) {}
}
启动服务
创建完 SystemServiceManager
后,就开始启动服务。前面说过 SystemServer
通过分批分阶段的方式来启动服务,系统服务被分为引导服务、核心服务和其他服务三批进行启动,分别对应 startBootstrapServices()
、startCoreServices()
和 startOtherServices()
。
启动引导服务
startBootstrapServices()
会启动引导服务,包括我们所熟知的 ActivityManagerService
,PackageManagerService
等。
// frameworks/base/services/java/com/android/server/SystemServer.java
private void startBootstrapServices() {
// 启动 ActivityManagerService
ActivityTaskManagerService atm = mSystemServiceManager.startService(
ActivityTaskManagerService.Lifecycle.class).getService();
mActivityManagerService = ActivityManagerService.Lifecycle.startService(
mSystemServiceManager, atm);
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
// 通知 SystemServiceManager 到了 PHASE_WAIT_FOR_DEFAULT_DISPLAY 阶段
mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
// 启动 PackageManagerService
try {
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
} finally {
}
mActivityManagerService.setSystemProcess();
}
关于 ActivityManagerService
后面有文章做详细的分析。
启动核心服务
startCoreServices()
会启动核心服务,包括 BatteryService
、GpuService
等等。
// frameworks/base/services/java/com/android/server/SystemServer.java
private void startCoreServices() {
// BatterService
mSystemServiceManager.startService(BatteryService.class);
// GpuService
mSystemServiceManager.startService(GpuService.class);
}
启动其他服务
startOtherServices()
会分阶段启动其他服务,方法很长,感兴趣的自行去研究。
// frameworks/base/services/java/com/android/server/SystemServer.java
private void startOtherServices() {
// VibratorService
vibrator = new VibratorService(context);
ServiceManager.addService("vibrator", vibrator);
// AlarmManagerService
mSystemServiceManager.startService(new AlarmManagerService(context));
inputManager = new InputManagerService(context);
// WindowManagerService
wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
// InputManagerService
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
mActivityManagerService.setWindowManager(wm);
// AccessibilityManagerService
try {
mSystemServiceManager.startService(ACCESSIBILITY_MANAGER_SERVICE_CLASS);
} catch (Throwable e) {
reportWtf("starting Accessibility Manager", e);
}
// JobSchedulerService
mSystemServiceManager.startService(JobSchedulerService.class);
// 通知 SystemServiceManager 到达 PHASE_LOCK_SETTINGS_READY 阶段
mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
// 通知 SystemServiceManager 到达 PHASE_SYSTEM_SERVICES_READY 阶段
mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
final Configuration config = wm.computeNewConfiguration(DEFAULT_DISPLAY);
DisplayMetrics metrics = new DisplayMetrics();
WindowManager w = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
w.getDefaultDisplay().getMetrics(metrics);
context.getResources().updateConfiguration(config, metrics);
mPackageManagerService.systemReady();
// 通知 SystemServiceManager 到达 PHASE_DEVICE_SPECIFIC_SERVICES_READY 阶段
mSystemServiceManager.startBootPhase(SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY);
// 调用 AMS 的 systemReady()
mActivityManagerService.systemReady(() -> {
// 通知 SystemServiceManager 到达 PHASE_ACTIVITY_MANAGER_READY 阶段
mSystemServiceManager.startBootPhase(
SystemService.PHASE_ACTIVITY_MANAGER_READY);
}
// 通知 SystemServiceManager 到达 PHASE_THIRD_PARTY_APPS_CAN_START 阶段
mSystemServiceManager.startBootPhase(
SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
}
进入 loop() 循环
最后会调用主线程 Looper
的 loop()
进入循环等待处理请求。
// frameworks/base/services/java/com/android/server/SystemServer.java
private void run() {
Looper.loop();
}
Answers
至此 SystemServer
就分析完了,接下来回过头看看前面的问题。
如何处理系统服务启动的依赖关系?
SystemServer
通过分批分阶段的方式来启动 ServiceManager
。
分批是指将系统服务分为三批:
- 启动引导服务,
startBootstrapServices()
; - 启动核心服务,
startCoreServices()
; - 启动其他服务,
startOtherServices()
。
分阶段是 SystemServer
在不同的阶段会通过 startBootPhase()
通知 SystemServiceManager
,进而通过 onBootPhase()
通知系统服务。
如何发布系统服务,让其对其他应用或服务可见?
发布服务最终是通过 ServiceManager
的 addService()
。
继承自 SystemService
的系统服务可以在 onStart()
中通过 publishBinderService()
发布服务,其底层还是调用的 ServiceManager
的 addService()
。