Skip some duplicated tasks when booting from non-system user.
When Automotive boots, CarServiceHelperService "restarts" the system user in the background, to unlock it. Consequently, some boot tasks will be executed twice (triggered from UserController.startUser() and ActivityManager.systemReady()). In the long term, refactoring the boot sequence on headless-system mode should avoid these duplicated events, but for now, we need to tackle them case by case. Test: manual verification # adding system.out statements on automotive Bug: 139502237 Bug: 128904478 Bug: 138956267 Change-Id: Idd8beedf1ea034b47b9756b91404c5a043965c23
This commit is contained in:
@@ -9154,20 +9154,25 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
}
|
||||
t.traceEnd();
|
||||
}
|
||||
t.traceBegin("startHomeOnAllDisplays");
|
||||
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
|
||||
t.traceEnd();
|
||||
// Automotive will re-start system user as background (so its unlocked), then start a
|
||||
// full user as foreground. Hence, we need to skip some steps that would otherwise be
|
||||
// done twice.
|
||||
// TODO(b/138956267): this workdound shouldn't be necessary once we move the
|
||||
// headless-user start logic to UserManager-land
|
||||
final boolean bootingSystemUser = currentUserId == UserHandle.USER_SYSTEM;
|
||||
|
||||
if (bootingSystemUser) {
|
||||
t.traceBegin("startHomeOnAllDisplays");
|
||||
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
|
||||
t.traceEnd();
|
||||
}
|
||||
|
||||
t.traceBegin("showSystemReadyErrorDialogs");
|
||||
mAtmInternal.showSystemReadyErrorDialogsIfNeeded();
|
||||
t.traceEnd();
|
||||
|
||||
// Some systems - like automotive - will explicitly unlock system user then switch
|
||||
// to a secondary user. Hence, we don't want to send duplicate broadcasts for the
|
||||
// system user here.
|
||||
boolean sendSystemUserBroadcasts = currentUserId == UserHandle.USER_SYSTEM;
|
||||
|
||||
if (sendSystemUserBroadcasts) {
|
||||
if (bootingSystemUser) {
|
||||
t.traceBegin("sendUserStartBroadcast");
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final int callingPid = Binder.getCallingPid();
|
||||
@@ -9208,7 +9213,7 @@ public class ActivityManagerService extends IActivityManager.Stub
|
||||
mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
|
||||
t.traceEnd();
|
||||
|
||||
if (sendSystemUserBroadcasts) {
|
||||
if (bootingSystemUser) {
|
||||
t.traceBegin("sendUserSwitchBroadcasts");
|
||||
mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
|
||||
t.traceEnd();
|
||||
|
||||
@@ -1745,13 +1745,24 @@ class UserController implements Handler.Callback {
|
||||
}
|
||||
|
||||
void sendBootCompleted(IIntentReceiver resultTo) {
|
||||
final boolean systemUserFinishedBooting;
|
||||
|
||||
// Get a copy of mStartedUsers to use outside of lock
|
||||
SparseArray<UserState> startedUsers;
|
||||
synchronized (mLock) {
|
||||
systemUserFinishedBooting = mCurrentUserId != UserHandle.USER_SYSTEM;
|
||||
startedUsers = mStartedUsers.clone();
|
||||
}
|
||||
for (int i = 0; i < startedUsers.size(); i++) {
|
||||
UserState uss = startedUsers.valueAt(i);
|
||||
if (systemUserFinishedBooting && uss.mHandle.isSystem()) {
|
||||
// Automotive will re-start system user as background, which in turn will call
|
||||
// finishUserboot(). Hence, we need to check it here to avoid calling it twice.
|
||||
// TODO(b/138956267): this workdound shouldn't be necessary once we move the
|
||||
// headless-user start logic to UserManager-land
|
||||
Slog.d(TAG, "sendBootCompleted(): skipping on non-current system user");
|
||||
continue;
|
||||
}
|
||||
finishUserBoot(uss, resultTo);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user