fallbackHome监听ACTION_USER_UNLOCKED广播,然后调用maybeFinish()方法,里面构建homeIntent,查询,如果查到的包名还是自己
就继续循环发延时消息,否则就finish自己
registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_USER_UNLOCKED));
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
maybeFinish();
}
};
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
maybeFinish();
}
};
private void maybeFinish() {
if (getSystemService(UserManager.class).isUserUnlocked()) {
final Intent homeIntent = new Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_HOME);
final ResolveInfo homeInfo = getPackageManager().resolveActivity(homeIntent, 0);
if (Objects.equals(getPackageName(), homeInfo.activityInfo.packageName)) {
Log.d(TAG, "User unlocked but no home; let's hope someone enables one soon?");
mHandler.sendEmptyMessageDelayed(0, 500);
} else {
Log.d(TAG, "User unlocked and real home found; let's go!");
getSystemService(PowerManager.class).userActivity(
SystemClock.uptimeMillis(), false);
finish();
}
}
}
下面分析ACTION_USER_UNLOCKED广播在哪儿发送
/frameworks/base/services/core/java/com/android/server/am/UserController.java里面的finishUserUnlocked方法
if (!mInjector.getUserManager().isPreCreated(userId)) {
// Dispatch unlocked to external apps
final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED);
unlockedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
unlockedIntent.addFlags(
Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
mInjector.broadcastIntent(unlockedIntent, null, null, 0, null,
null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
Binder.getCallingUid(), Binder.getCallingPid(), userId);
}
然后会执行finishUserUnlockedCompleted方法里面执行了:
mHandler.obtainMessage(USER_UNLOCKED_MSG, userId, 0).sendToTarget()
下面搜索USER_UNLOCKED_MSG
mInjector.getSystemServiceManager().onUserUnlocked(msg.arg1);
logUserLifecycleEvent(msg.arg1, USER_LIFECYCLE_EVENT_UNLOCKED_USER,
USER_LIFECYCLE_EVENT_STATE_FINISH);
clearSessionId(msg.arg1);
break;
搜索SystemServiceManager.java的onUserUnlocked方法
onUserUnlocked方法里面调用了onUser(USER_UNLOCKED, userId);
private void onUser(@NonNull TimingsTraceAndSlog t, @NonNull String onWhat,
@Nullable TargetUser prevUser, @NonNull TargetUser curUser) {
final int curUserId = curUser.getUserIdentifier();
// NOTE: do not change label below, or it might break performance tests that rely on it.
t.traceBegin("ssm." + onWhat + "User-" + curUserId);
Slog.i(TAG, "Calling on" + onWhat + "User " + curUserId
+ (prevUser != null ? " (from " + prevUser + ")" : ""));
final int serviceLen = mServices.size();
for (int i = 0; i < serviceLen; i++) {
final SystemService service = mServices.get(i);
final String serviceName = service.getClass().getName();
boolean supported = service.isUserSupported(curUser);
// Must check if either curUser or prevUser is supported (for example, if switching from
// unsupported to supported, we still need to notify the services)
if (!supported && prevUser != null) {
supported = service.isUserSupported(prevUser);
}
if (!supported) {
if (DEBUG) {
Slog.d(TAG, "Skipping " + onWhat + "User-" + curUserId + " on service "
+ serviceName + " because it's not supported (curUser: "
+ curUser + ", prevUser:" + prevUser + ")");
} else {
Slog.i(TAG, "Skipping " + onWhat + "User-" + curUserId + " on "
+ serviceName);
}
continue;
}
t.traceBegin("ssm.on" + onWhat + "User-" + curUserId + "_" + serviceName);
long time = SystemClock.elapsedRealtime();
try {
switch (onWhat) {
case USER_SWITCHING:
service.onUserSwitching(prevUser, curUser);
break;
case USER_STARTING:
service.onUserStarting(curUser);
break;
case USER_UNLOCKING:
service.onUserUnlocking(curUser);
break;
case USER_UNLOCKED:
service.onUserUnlocked(curUser);
break;
case USER_STOPPING:
service.onUserStopping(curUser);
break;
case USER_STOPPED:
service.onUserStopped(curUser);
break;
default:
throw new IllegalArgumentException(onWhat + " what?");
}
} catch (Exception ex) {
Slog.wtf(TAG, "Failure reporting " + onWhat + " of user " + curUser
+ " to service " + serviceName, ex);
}
warnIfTooLong(SystemClock.elapsedRealtime() - time, service,
"on" + onWhat + "User-" + curUserId);
t.traceEnd(); // what on service
}
t.traceEnd(); // main entry
}
可以发现里面有一个for循环,会调用每一个SystemService的onUserUnlocked方法
查看ATMS代码,发现里面有一个静态内部类Lifecycle
public static final class Lifecycle extends SystemService {
private final ActivityTaskManagerService mService;
public Lifecycle(Context context) {
super(context);
mService = new ActivityTaskManagerService(context);
}
@Override
public void onStart() {
publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
mService.start();
}
@Override
public void onUserUnlocked(@NonNull TargetUser user) {
synchronized (mService.getGlobalLock()) {
mService.mTaskSupervisor.onUserUnlocked(user.getUserIdentifier());
}
}
@Override
public void onUserStopped(@NonNull TargetUser user) {
synchronized (mService.getGlobalLock()) {
mService.mTaskSupervisor.mLaunchParamsPersister
.onCleanupUser(user.getUserIdentifier());
}
}
public ActivityTaskManagerService getService() {
return mService;
}
}
所以会调用该类的onUserUnlocked方法,最终调用到ActivityTaskSupervisor.java的onUserUnlocked方法
void onUserUnlocked(int userId) {
// Only start persisting when the first user is unlocked. The method call is
// idempotent so there is no side effect to call it again when the second user is
// unlocked.
mPersisterQueue.startPersisting();
mLaunchParamsPersister.onUnlockUser(userId);
// Need to launch home again for those displays that do not have encryption aware home app.
scheduleStartHome("userUnlocked");
}
private void scheduleStartHome(String reason) {
if (!mHandler.hasMessages(START_HOME_MSG)) {
mHandler.obtainMessage(START_HOME_MSG, reason).sendToTarget();
}
}
然后搜索START_HOME_MSG
case START_HOME_MSG: {
mHandler.removeMessages(START_HOME_MSG);
// Start home activities on displays with no activities.
mRootWindowContainer.startHomeOnEmptyDisplays((String) msg.obj);
} break;
然后调用到RootWindowContainer.java的startHomeOnEmptyDisplays方法
void startHomeOnEmptyDisplays(String reason) {
forAllTaskDisplayAreas(taskDisplayArea -> {
if (taskDisplayArea.topRunningActivity() == null) {
startHomeOnTaskDisplayArea(mCurrentUser, reason, taskDisplayArea,
false /* allowInstrumenting */, false /* fromHomeKey */);
}
});
}
最后调用到startHomeOnTaskDisplayArea方法里面启动launcher