起点在ActivityManagerService.java
public boolean startUserInBackground(final int userId) {
return mUserController.startUser(userId, /* foreground */ false);
}
UserController.java
boolean startUser(final int userId, final boolean foreground) {
...
final long ident = Binder.clearCallingIdentity();
try {
synchronized (mService) {
final int oldUserId = mCurrentUserId;
if (oldUserId == userId) {
return true;
}
mService.mStackSupervisor.setLockTaskModeLocked(null,
ActivityManager.LOCK_TASK_MODE_NONE, "startUser", false);
final UserInfo userInfo = getUserInfo(userId);
...
if (foreground && userInfo.isManagedProfile()) {
//限制manage profile user只能后台切换
Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
return false;
}
if (foreground) {
//前台切换要进行动画,并冻屏
mService.mWindowManager.startFreezingScreen(
R.anim.screen_user_exit, R.anim.screen_user_enter);
}
...
if (foreground) {
//只有前台切换的时候才会设置mCurrentUserId
mCurrentUserId = userId;
mService.updateUserConfigurationLocked();
mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
updateCurrentProfileIdsLocked();
//前台切换的话要重新启动锁屏,关闭新user不需要的UI
mService.mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
// Once the internal notion of the active user has switched, we lock the device
// with the option to show the user switcher on the keyguard.
mService.mWindowManager.lockNow(null);
} else {
final Integer currentUserIdInt = mCurrentUserId;
updateCurrentProfileIdsLocked();
mService.mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
mUserLru.remove(currentUserIdInt);
mUserLru.add(currentUserIdInt);
}
// Make sure user is in the started state. If it is currently
// stopping, we need to knock that off.
if (uss.state == UserState.STATE_STOPPING) {
// If we are stopping, we haven't sent ACTION_SHUTDOWN,
// so we can just fairly silently bring the user back from
// the almost-dead.
uss.setState(uss.lastState);
getUserManagerInternal().setUserState(userId, uss.state);
updateStartedUserArrayLocked();
needStart = true;
} else if (uss.state == UserState.STATE_SHUTDOWN) {
// This means ACTION_SHUTDOWN has been sent, so we will
// need to treat this as a new boot of the user.
uss.setState(UserState.STATE_BOOTING);
getUserManagerInternal().setUserState(userId, uss.state);
updateStartedUserArrayLocked();
needStart = true;
}
//如果是第一次切换的话会走这里
if (uss.state == UserState.STATE_BOOTING) {
// Give user manager a chance to propagate user restrictions
// to other services and prepare app storage
getUserManager().onBeforeStartUser(userId);
// Booting up a new user, need to tell system services about it.
// Note that this is on the same handler as scheduling of broadcasts,
// which is important because it needs to go first.
mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
}
if (foreground) {
//通过消息处理
mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
oldUserId));
mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
oldUserId, userId, uss));
mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
}
if (needStart) { //Intent.ACTION_USER_STARTED广播
// Send USER_STARTED broadcast
Intent intent = new Intent(Intent.ACTION_USER_STARTED);
...
}
if (foreground) {
moveUserToForegroundLocked(uss, oldUserId, userId);
} else {
mService.mUserController.finishUserBoot(uss);
}
if (needStart) { //Intent.ACTION_USER_STARTING广播,这个广播是发送给所有user的
Intent intent = new Intent(Intent.ACTION_USER_STARTING);
...
}
} finally {
Binder.restoreCallingIdentity(ident);
}
return true;
}
onBeforeStartUser
UserManagerService.java public void onBeforeStartUser(int userId) {
final int userSerial = getUserSerialNumber(userId);
//user data 处理
mPm.prepareUserData(userId, userSerial, StorageManager.FLAG_STORAGE_DE);
mPm.reconcileAppsData(userId, StorageManager.FLAG_STORAGE_DE);
if (userId != UserHandle.USER_SYSTEM) {
synchronized (mRestrictionsLock) {
//非system用户,user要做限制
applyUserRestrictionsLR(userId);
}
}
maybeInitializeDemoMode(userId);
}
建立user相关目录,其中prepareUserData上篇文章已详细分析过。而reconcileAppsData是主要工作是创建app相关目录,创建的核心方法createAppData在上篇文章
点击打开链接中详细分析过
消息处理
SYSTEM_USER_START_MSG
case SYSTEM_USER_START_MSG: {
mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
Integer.toString(msg.arg1), msg.arg1);
mSystemServiceManager.startUser(msg.arg1);
public void startUser(final int userHandle) {
final int serviceLen = mServices.size();
for (int i = 0; i < serviceLen; i++) {
//通知每个SystemService,SystemService都运行在system进程中。
final SystemService service = mServices.get(i);
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onStartUser "
+ service.getClass().getName());
try {
service.onStartUser(userHandle);
} catch (Exception ex) {
Slog.wtf(TAG, "Failure reporting start of user " + userHandle
+ " to service " + service.getClass().getName(), ex);
}
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
通知SystemService user开始启动
REPORT_USER_SWITCH_MSG
注意该消息只有前台切换user才会发送case REPORT_USER_SWITCH_MSG: {
mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
break;
}
void dispatchUserSwitch(final UserState uss, final int oldUserId, final int newUserId) {
Slog.d(TAG, "Dispatch onUserSwitching oldUser #" + oldUserId + " newUser #" + newUserId);
final int observerCount = mUserSwitchObservers.beginBroadcast();
if (observerCount > 0) {
final ArraySet<String> curWaitingUserSwitchCallbacks = new ArraySet<>();
synchronized (mService) {
uss.switching = true;
//这里mCurWaitingUserSwitchCallbacks就是curWaitingUserSwitchCallbacks
mCurWaitingUserSwitchCallbacks = curWaitingUserSwitchCallbacks;
}
final AtomicInteger waitingCallbacksCount = new AtomicInteger(observerCount);
for (int i = 0; i < observerCount; i++) {
try {
// Prepend with unique prefix to guarantee that keys are unique
final String name = "#" + i + " " + mUserSwitchObservers.getBroadcastCookie(i);
synchronized (mService) {
curWaitingUserSwitchCallbacks.add(name);
}
final IRemoteCallback callback = new IRemoteCallback.Stub() {
@Override
public void sendResult(Bundle data) throws RemoteException {
synchronized (mService) {
// Early return if this session is no longer valid
//不一致的话,回调就没有必要继续运行了
if (curWaitingUserSwitchCallbacks
!= mCurWaitingUserSwitchCallbacks) {
return;
}
curWaitingUserSwitchCallbacks.remove(name);
// Continue switching if all callbacks have been notified
if (waitingCallbacksCount.decrementAndGet() == 0) {
sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
}
}
}
};
mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(newUserId, callback);
} catch (RemoteException e) {
}
}
} else {
synchronized (mService) {
sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
}
}
mUserSwitchObservers.finishBroadcast();
}
这里的mUserSwitchObservers是外界通过下面方法注册进来的,能得到user切换的消息
public void registerUserSwitchObserver(IUserSwitchObserver observer,
String name) throws RemoteException
所有观察者通知完毕最后会走sendContinueUserSwitchLocked
void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
mCurWaitingUserSwitchCallbacks = null;
mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
mHandler.sendMessage(mHandler.obtainMessage(ActivityManagerService.CONTINUE_USER_SWITCH_MSG,
oldUserId, newUserId, uss));
}
CONTINUE_USER_SWITCH_MSG
case CONTINUE_USER_SWITCH_MSG: {
mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
break;
}
void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
Slog.d(TAG, "Continue user switch oldUser #" + oldUserId + ", newUser #" + newUserId);
synchronized (mService) {
//冻屏解除
mService.mWindowManager.stopFreezingScreen();
}
uss.switching = false;
mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
newUserId, 0));
//停用Guest或者Ephemeral用户,这两种user都是短暂的,不会往文件中存储
stopGuestOrEphemeralUserIfBackground();
//停用后台用户
stopBackgroundUsersIfEnforced(oldUserId);
}
REPORT_USER_SWITCH_COMPLETE_MSG
case REPORT_USER_SWITCH_COMPLETE_MSG: {
mUserController.dispatchUserSwitchComplete(msg.arg1);
} break;
通知mUserSwitchObservers切换完毕
消息处理大部分的工作是通知外界user的状态。
moveUserToForegroundLocked和finishUserBoot
void moveUserToForegroundLocked(UserState uss, int oldUserId, int newUserId) {
//设置当前要显示的Activity堆栈
boolean homeInFront = mService.mStackSupervisor.switchUserLocked(newUserId, uss);
if (homeInFront) {
mService.startHomeActivityLocked(newUserId, "moveUserToForeground");
} else {
mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
}
EventLogTags.writeAmSwitchUser(newUserId);
//针对后台user发送Intent.ACTION_USER_BACKGROUND,前台user发送Intent.ACTION_USER_FOREGROUND广播
sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
}
两个方法分别对应前台和后台
前台user:调整当前要显示的Activity Stack,并发送Intent.ACTION_USER_FOREGROUND广播
后台user:finishUserBoot设置user的状态,并解锁user的存储。