Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f13851d6 authored by Felipe Leme's avatar Felipe Leme
Browse files

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
parent a3662b91
Loading
Loading
Loading
Loading
+14 −9
Original line number Diff line number Diff line
@@ -9154,20 +9154,25 @@ public class ActivityManagerService extends IActivityManager.Stub
                }
                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();
+11 −0
Original line number Diff line number Diff line
@@ -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);
        }
    }