Merge "Skip some duplicated tasks when booting from non-system user."
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 5c0fe4e..84f5530 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -9154,20 +9154,25 @@
}
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 @@
mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
t.traceEnd();
- if (sendSystemUserBroadcasts) {
+ if (bootingSystemUser) {
t.traceBegin("sendUserSwitchBroadcasts");
mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
t.traceEnd();
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 8448042..2b4cc3c 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -1744,13 +1744,24 @@
}
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);
}
}