android版本:android-11.0.0_r21
http://aospxref.com/android-11.0.0_r21/
一、主用户primary user的创建
开机后kernel启动第一个用户态进程init,init进程fork出zygote进程。zygote又fork出system server进程。
http://aospxref.com/android-11.0.0_r21/xref/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java#920
832 public static void main(String argv[]) {
833 ZygoteServer zygoteServer = null;
834
……
916
917 zygoteServer = new ZygoteServer(isPrimaryZygote);
918
919 if (startSystemServer) {
920 Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
921
922 // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
923 // child (system_server) process.
924 if (r != null) {
925 r.run();
926 return;
927 }
928 }
920行,fork system server进程,925行运行子进程system server。system server入口代码如下:
http://aospxref.com/android-11.0.0_r21/xref/frameworks/base/services/java/com/android/server/SystemServer.java#main
410 /**
411 * The main entry point from zygote.
412 */
413 public static void main(String[] args) {
414 new SystemServer().run();
415 }
SystemServer().run()会启动各种service:
http://aospxref.com/android-11.0.0_r21/xref/frameworks/base/services/java/com/android/server/SystemServer.java#run
436 private void run() {
……
592
593 // Start services.
594 try {
595 t.traceBegin("StartServices");
596 startBootstrapServices(t);
597 startCoreServices(t);
598 startOtherServices(t);
599 } catch (Throwable ex) {
600 Slog.e("System", "******************************************");
601 Slog.e("System", "************ Failure starting system services", ex);
602 throw ex;
603 } finally {
604 t.traceEnd(); // StartServices
605 }
596行启动一些列的service:
http://aospxref.com/android-11.0.0_r21/xref/frameworks/base/services/java/com/android/server/SystemServer.java#startBootstrapServices
710 private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
……
760
761 // Activity manager runs the show.
762 t.traceBegin("StartActivityManager");
763 // TODO: Might need to move after migration to WM.
764 ActivityTaskManagerService atm = mSystemServiceManager.startService(
765 ActivityTaskManagerService.Lifecycle.class).getService();
766 mActivityManagerService = ActivityManagerService.Lifecycle.startService(
767 mSystemServiceManager, atm);
768 mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
769 mActivityManagerService.setInstaller(installer);
在启动 ActivityManagerService 时,SystemServer 会等待 ActivityManagerService 初始化完成并绑定到系统服务中心(System Service Manager)。然后,SystemServer 会调用 ActivityManagerService 的 systemReady() 方法:
http://aospxref.com/android-11.0.0_r21/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java#systemReady
9515 public void systemReady(final Runnable goingCallback, @NonNull TimingsTraceAndSlog t) {
……
9640 // headless-user start logic to UserManager-land
9641 final boolean bootingSystemUser = currentUserId == UserHandle.USER_SYSTEM;
9642
9643 if (bootingSystemUser) {
9644 mSystemServiceManager.startUser(t, currentUserId);
9645 }
9644行执行SystemServiceManager::startUser
http://aospxref.com/android-11.0.0_r21/xref/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java#startUser
254 /**
255 * Starts the given user.
256 */
257 public void startUser(final @NonNull TimingsTraceAndSlog t, final @UserIdInt int userHandle) {
258 onUser(t, START, userHandle);
259 }
258行,会发送START消息,系统中的多个模块会接收并处理该消息,包括Zygote、PackageManagerService和ActivityManagerService本身等。其中,Zygote进程会根据用户ID创建新的应用程序进程;PackageManagerService会根据用户信息和应用程序信息初始化和加载应用程序;而ActivityManagerService则会负责协调和管理用户进程的生命周期。
当primary user和各种service启动后,SystemServiceManager发送H_BOOT_COMPLETED消息,这个消息的处理见第二部分。
二、处理H_BOOT_COMPLETED消息
开机后,StorageManagerService收到开机广播消息H_BOOT_COMPLETED,按时间顺序完成以下4件事情:
- init用户目录的加密状态
- reset external storage service
- reset vold service
- 添加用户
代码整体逻辑如下:
1,init用户目录的加密状态
代码路径:StorageManagerServiceHandler::handleMessage --> handleBootCompleted --> initIfBootedAndConnected
分两种情况:
1)用户目录采用硬件加解密(native encryption),此阶段什么事也不做,函数直接返回
2)用户目录采用软件加解密(enmulated encryption),执行lock encryption key(用户目录已加密的情况)或者unlock encryption key(用户目录未加密的情况)
从安全性、性能角度看,硬件加解密更好。
现在的手机基本都是硬件加解密方式,通过adb shell getprop ro.crypto.state可查询手机用的是哪种加解密方式。
adb shell getprop ro.crypto.state | |
返回字符串 | 加解密方式 |
"encrypted" | native encryption(硬件加解密) |
"unencrypted" 或 "unsupported" | enmulated encryption(软件加解密) |
"default" | 手机还没有加密过 |
handleMessage处理H_BOOT_COMPLETED:
StorageManagerService.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/StorageManagerService.java
707 class StorageManagerServiceHandler extends Handler {
713 public void handleMessage(Message msg) {
714 switch (msg.what) {
719 case H_BOOT_COMPLETED: {
720 handleBootCompleted();
721 break;
722 }
收到H_BOOT_COMPLETED广播消息后, 执行719行分支,handleBootCompleted函数如下:
2076 private void handleBootCompleted() {
2077 initIfBootedAndConnected();
2078 resetIfBootedAndConnected();
2079 }
initIfBootedAndConnected函数处理enmulated encryption场景,如果用户目录是加密状态,那么lock encryption key,否则就unlock encryption key。
StorageManagerService.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/StorageManagerService.java
1061 private void initIfBootedAndConnected() {
1064 if (mBootCompleted && mDaemonConnected
1065 && !StorageManager.isFileEncryptedNativeOnly()) {
1069 final boolean initLocked = StorageManager.isFileEncryptedEmulatedOnly();
1071 final List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
1072 for (UserInfo user : users) {
1073 try {
1074 if (initLocked) {
1075 mVold.lockUserKey(user.id);
1076 } else {
1077 mVold.unlockUserKey(user.id, user.serialNumber, encodeBytes(null),
……
1065行StorageManager.isFileEncryptedNativeOnly(),判断设备是不是硬件加解密。如果是硬件加解密,则什么也不做,退出函数。设备用软件加解密时,进入1066行分支处理,根据StorageManager.isFileEncryptedEmulatedOnly()获取到的用户目录加密状态,执行lock 或者unlock encryption key操作。
2,reset external service
代码路径:StorageManagerServiceHandler::handleMessage --> handleBootCompleted --> resetIfBootedAndConnected --> StorageSessionController::onReset
external storage service是一个由名为com.android.providers.media.module的package提供的服务,用于管理外部存储设备(sd卡、u盘等),服务名称为com.android.providers.media.fuse.ExternalStorageServiceImpl。external storage service负责挂载/卸载外部存储设备、管理存储设备上的文件系统、处理app访问外部存储的请求。可通过adb shell dumpsys activity services com.android.providers.media.module/com.android.providers.media.fuse.ExternalStorageServiceImpl命令查看service详细信息。
app访问外部存储时,调用framework提供的接口(比如函数getExternalFilesDir、getExternalStorageDirectory、Environment.getExternalStoragePublicDirectory),然后这些函数再通过external storage service去访问外部存储。出于安全考虑,只有用户connect到external storage service后,也即该用户是被认可的,用户名下的app才允许访问外部存储。
reset external service主要完成2件事:
1)umount外部存储
2)关闭连接至external storage service的所有connection
一般情况下,外部存储还没有挂载成功,所以不需要卸载任何存储,也不需要关闭任何connection。不过下面还是过一下代码:
StorageManagerService.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/StorageManagerService.java
1087 private void resetIfBootedAndConnected() {
1090 if (mBootCompleted && mDaemonConnected) {
1091 final UserManager userManager = mContext.getSystemService(UserManager.class);
1092 final List<UserInfo> users = userManager.getUsers();
1093
1094 if (mIsFuseEnabled) {
1095 mStorageSessionController.onReset(mVold, () -> {
1096 mHandler.removeCallbacksAndMessages(null);
1097 });
1098 } else {
1099 killMediaProvider(users);
1100 }
……
1095行umount外部存储并关闭connection,mStorageSessionController.onReset函数如下:
StorageSessionController.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/storage/StorageSessionController.java
240 public void onReset(IVold vold, Runnable resetHandlerRunnable) {
245 SparseArray<StorageUserConnection> connections = new SparseArray();
246 synchronized (mLock) {
247 mIsResetting = true;
248 Slog.i(TAG, "Started resetting external storage service...");
249 for (int i = 0; i < mConnections.size(); i++) {
250 connections.put(mConnections.keyAt(i), mConnections.valueAt(i));
251 }
252 }
253
254 for (int i = 0; i < connections.size(); i++) {
255 StorageUserConnection connection = connections.valueAt(i);
256 for (String sessionId : connection.getAllSessionIds()) {
259 vold.unmount(sessionId);
……
268 connection.removeSessionAndWait(sessionId);
279 connection.close();
259行vold.unmount(即VoldNativeService::mount函数,参考StorageManagerService.java中的mVold.mount_geshifei的博客-CSDN博客)卸载外部存储设备,不过,在开机流程不会执行到这个函数。
279行关闭connection。
3,reset vold service
代码路径:StorageManagerServiceHandler::handleMessage --> handleBootCompleted --> resetIfBootedAndConnected --> mVold.reset
这个阶段主要完成3件事:
- 销毁volume
- 重置disk对象
- 清空用户
StorageManagerService.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/StorageManagerService.java
1087 private void resetIfBootedAndConnected() {
/* reset external service,
* umount外部存储并关闭external storage service所有connection
*/
1095 mStorageSessionController.onReset(mVold, () -> {
1096 mHandler.removeCallbacksAndMessages(null);
1097 });
1101
1115 // TODO(b/135341433): Remove paranoid logging when FUSE is stable
1116 Slog.i(TAG, "Resetting vold...");
1117 mVold.reset();
1118 Slog.i(TAG, "Reset vold");
1112 }
1117行,mVold.reset()执行VoldNativeService::reset。
VoldNativeService.cpp - OpenGrok cross reference for /system/vold/VoldNativeService.cpp
164 binder::Status VoldNativeService::reset() {
165 ENFORCE_SYSTEM_OR_ROOT;
166 ACQUIRE_LOCK;
167
168 return translate(VolumeManager::Instance()->reset());
169 }
168行,执行VolumeManager::reset函数。
VolumeManager.cpp - OpenGrok cross reference for /system/vold/VolumeManager.cpp
912 int VolumeManager::reset() {
913 // Tear down all existing disks/volumes and start from a blank slate so
914 // newly connected framework hears all events.
915 for (const auto& vol : mInternalEmulatedVolumes) {
916 vol->destroy();
917 }
918 mInternalEmulatedVolumes.clear();
919
920 for (const auto& disk : mDisks) {
921 disk->destroy();
922 disk->create();
923 }
924 updateVirtualDisk();
925 mAddedUsers.clear();
926 mStartedUsers.clear();
927 return 0;
928 }
916行销毁volume(vol->destroy --> VolumeBase::destroy --> doDestroy)。
920行如果创建了disk对象(此时一般没有创建任何disk),就重置disk(先disk->destroy --> Disk:destory销毁disk对象,再disk->create --> Disk::create创建disk对象)。
925行,清空mAddedUsers中保存的所有用户ID,即删除所有已添加的用户。
926行,清空mStartedUsers中保存的所有用户ID,即删除所有已启动的用户。
4,在mAddedUsers中记录用户信息
代码路径:StorageManagerServiceHandler::handleMessage --> handleBootCompleted --> resetIfBootedAndConnected --> mVold.onUserAdded
mAddedUsers 是 VolumeManager 用于跟踪已添加的用户信息的数据结构,当系统启动时,它会将记录在其中的用户信息发送给 vold,以确保 vold 了解系统中所有用户的存在。这样可以确保 vold 能够正确地管理卷和磁盘。android支持多用户,用户外部存储挂载点为/storage/emulated/用户id,如果某个用户在连接设备后注销了系统,VolumeManager将记录在mAddedUsers中该用户信息发送给vold,vold就可以正确地卸个载设备上的卷或文件系统。
StorageManagerService.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/StorageManagerService.java
1087 private void resetIfBootedAndConnected() {
/* reset external service,
* umount外部存储并关闭external storage service所有connection
*/
1095 mStorageSessionController.onReset(mVold, () -> {
1096 mHandler.removeCallbacksAndMessages(null);
1097 });
/* reset vold service,
* 销毁volume,重置disk,清空用户
1117 mVold.reset();
/* 在mAddedUsers中 记录用户信息 */
1121 for (UserInfo user : users) {
1122 mVold.onUserAdded(user.id, user.serialNumber);
1123 }
1124 for (int userId : systemUnlockedUsers) {
1125 mVold.onUserStarted(userId);
1126 mStoraged.onUserStarted(userId);
1127 }
1128 if (mIsAutomotive) {
1129 restoreAllUnlockedUsers(userManager, users, systemUnlockedUsers);
1130 }
1131 mVold.onSecureKeyguardStateChanged(mSecureKeyguardShowing);
1132 mStorageManagerInternal.onReset(mVold);
1133
1122行mVold.onUserAdded,调用VoldNativeService::onUserAdded,代码VoldNativeService.cpp - OpenGrok cross reference for /system/vold/VoldNativeService.cpp
185 binder::Status VoldNativeService::onUserAdded(int32_t userId, int32_t userSerial) {
186 ENFORCE_SYSTEM_OR_ROOT;
187 ACQUIRE_LOCK;
188
189 return translate(VolumeManager::Instance()->onUserAdded(userId, userSerial));
190 }
189行执行的是VolumeManager::onUserAdded,代码VolumeManager.cpp - OpenGrok cross reference for /system/vold/VolumeManager.cpp
455 int VolumeManager::onUserAdded(userid_t userId, int userSerialNumber) {
456 LOG(INFO) << "onUserAdded: " << userId;
457
458 mAddedUsers[userId] = userSerialNumber;
459 return 0;
460 }
458行将user信息添加到mAddedUsers中。
回到resetIfBootedAndConnected函数,看一下1124行分支:
1087 private void resetIfBootedAndConnected() {
/* reset external service,
* umount外部存储并关闭external storage service所有connection
*/
1095 mStorageSessionController.onReset(mVold, () -> {
1096 mHandler.removeCallbacksAndMessages(null);
1097 });
/* reset vold service,
* 销毁volume,重置disk,清空用户
1117 mVold.reset();
/* 在mAddedUsers中 记录用户信息 */
1121 for (UserInfo user : users) {
1122 mVold.onUserAdded(user.id, user.serialNumber);
1123 }
1124 for (int userId : systemUnlockedUsers) {
1125 mVold.onUserStarted(userId);
1126 mStoraged.onUserStarted(userId);
1127 }
1128 if (mIsAutomotive) {
1129 restoreAllUnlockedUsers(userManager, users, systemUnlockedUsers);
1130 }
1131 mVold.onSecureKeyguardStateChanged(mSecureKeyguardShowing);
1132 mStorageManagerInternal.onReset(mVold);
1133
systemUnlockedUsers"数组包含已经解锁的用户ID。当设备启动时,通常只有一个用户(User 0)被解锁,而其他用户(如果有的话)会在后续解锁后被添加到数组中。所以,对于开机流程,mVold.onUserStarted(userId)不会执行。
在某些情况下,例如设备支持多用户功能并且用户在设置中添加了一个或多个额外的用户,或者设备已经解锁并且用户在后续的操作中解锁了其他用户,则systemUnlockedUsers数组中就会包含多个用户ID。
那么,什么时间触发mVold.onUserStarted启动用户,为用户创建、挂载相关目录呢?看下一篇文章分析。