diff options
| author | 2023-04-28 18:19:05 +0100 | |
|---|---|---|
| committer | 2023-05-02 18:50:17 +0100 | |
| commit | 77660a446bf86ed6c587920cd586b14b2c75afc3 (patch) | |
| tree | fe9c5a3857f847dad5fd22f32243bc9b78e738fd | |
| parent | 348bb0e22c5f81e1ce4e5f91abda3752bed969ed (diff) | |
Delay boot complete broadcast for main user on HSUM.
This fixes an issue where on a HSUM device, the LOCKED_BOOT_COMPLETE
broadcast occurs before boot actually completes.
We already delay the sending of this broadcast for user 0, but we
need to do the same for the main user because otherwise the
broadcast is sent at the end of user switch, and the switch to the
main user occurs before boot complete.
Bug: 279983151
Test: atest UserControllerTest
Test: build & flash; observe logs during boot
Change-Id: I885954ae57b3c7bc27b2f03b2d2bfa8583c79293
| -rw-r--r-- | services/core/java/com/android/server/am/UserController.java | 15 | ||||
| -rw-r--r-- | services/tests/servicestests/src/com/android/server/am/UserControllerTest.java | 26 |
2 files changed, 33 insertions, 8 deletions
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index b2fdee7a6f89..419962aa8c38 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -646,7 +646,10 @@ class UserController implements Handler.Callback { // user transitions to RUNNING_LOCKED. However, in "headless system user mode", the // system user is explicitly started before the device has finished booting. In // that case, we need to wait until onBootComplete() to send the broadcast. - if (!(mInjector.isHeadlessSystemUserMode() && uss.mHandle.isSystem())) { + // Similarly, this occurs after a user switch, but in HSUM we switch to the main + // user before boot is complete, so again this should be delayed until + // onBootComplete if boot has not yet completed. + if (mAllowUserUnlocking) { // ACTION_LOCKED_BOOT_COMPLETED sendLockedBootCompletedBroadcast(resultTo, userId); } @@ -2617,9 +2620,9 @@ class UserController implements Handler.Callback { // we should *not* transition users out of the BOOTING state using finishUserBoot(), as that // doesn't handle issuing the needed onUserStarting() call, and it would just race with an // explicit start anyway. We do, however, need to send the "locked boot complete" broadcast - // for the system user, as that got skipped earlier due to the *device* boot not being - // complete yet. We also need to try to unlock all started users, since until now explicit - // user starts didn't proceed to unlocking, due to it being too early in the device boot. + // as that got skipped earlier due to the *device* boot not being complete yet. + // We also need to try to unlock all started users, since until now explicit user starts + // didn't proceed to unlocking, due to it being too early in the device boot. // // USER_SYSTEM must be processed first. It will be first in the array, as its ID is lowest. Preconditions.checkArgument(startedUsers.keyAt(0) == UserHandle.USER_SYSTEM); @@ -2629,9 +2632,7 @@ class UserController implements Handler.Callback { if (!mInjector.isHeadlessSystemUserMode()) { finishUserBoot(uss, resultTo); } else { - if (userId == UserHandle.USER_SYSTEM) { - sendLockedBootCompletedBroadcast(resultTo, userId); - } + sendLockedBootCompletedBroadcast(resultTo, userId); maybeUnlockUser(userId); } } diff --git a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java index d12741ac8bd6..fe838e4ebd74 100644 --- a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java @@ -199,6 +199,7 @@ public class UserControllerTest { mUserController.setAllowUserUnlocking(true); setUpUser(TEST_USER_ID, NO_USERINFO_FLAGS); setUpUser(TEST_PRE_CREATED_USER_ID, NO_USERINFO_FLAGS, /* preCreated= */ true, null); + mInjector.mRelevantUser = null; }); } @@ -232,6 +233,25 @@ public class UserControllerTest { } @Test + public void testStartUser_background_duringBootHsum() { + mockIsHeadlessSystemUserMode(true); + mUserController.setAllowUserUnlocking(false); + mInjector.mRelevantUser = TEST_USER_ID; + boolean started = mUserController.startUser(TEST_USER_ID, USER_START_MODE_BACKGROUND); + assertWithMessage("startUser(%s, foreground=false)", TEST_USER_ID).that(started).isTrue(); + + // ACTION_LOCKED_BOOT_COMPLETED not sent yet + startUserAssertions(newArrayList(Intent.ACTION_USER_STARTED, Intent.ACTION_USER_STARTING), + START_BACKGROUND_USER_MESSAGE_CODES); + + mUserController.onBootComplete(null); + + startUserAssertions(newArrayList(Intent.ACTION_USER_STARTED, Intent.ACTION_USER_STARTING, + Intent.ACTION_LOCKED_BOOT_COMPLETED), + START_BACKGROUND_USER_MESSAGE_CODES); + } + + @Test public void testStartUser_sendsNoBroadcastsForSystemUserInNonHeadlessMode() { setUpUser(SYSTEM_USER_ID, UserInfo.FLAG_SYSTEM, /* preCreated= */ false, UserManager.USER_TYPE_FULL_SYSTEM); @@ -1076,6 +1096,8 @@ public class UserControllerTest { private final Context mCtx; + private Integer mRelevantUser; + TestInjector(Context ctx) { super(null); mCtx = ctx; @@ -1162,7 +1184,9 @@ public class UserControllerTest { boolean sticky, int callingPid, int callingUid, int realCallingUid, int realCallingPid, int userId) { Log.i(TAG, "broadcastIntentLocked " + intent); - mSentIntents.add(intent); + if (mRelevantUser == null || mRelevantUser == userId || userId == UserHandle.USER_ALL) { + mSentIntents.add(intent); + } return 0; } |