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

Commit 6790739d authored by Yasin Kilicdere's avatar Yasin Kilicdere
Browse files

Set user state to STATE_BOOTING before UC.startUserInternal returns.

UserController.startUserInternal method was broken into two parts after
ag/31995061, executing the first half on the caller's thread,
and the last half on the UserController.mHandler thread, in order
to make sure onBeforeUserSwitching event is called for the
UserSwitchObservers on UserController.mHandler thread, and to be synced
with the other events of UserSwitchObservers. Otherwise, it was causing
a race condition. More info can be found on the commit message of the
CL with the Change-Id I3b9de74fc74fc586656ea962b4efafc2442cf5d1

While that CL was fixing the race condition, it was changing the behavior
of the UserController.startUserInternal method. Before the CL, the
method was setting the user state to STATE_BOOTING before returning. But
now, the user state can be null for a short period of time, which can
lead to some unexpected results for the already existing parts of the
platform.

This CL makes the behavior of the UserController.startUserInternal method
more similar to how it was before ag/31995061, without losing the fix.

Bug: 396564030
Test: atest UserControllerTest
Flag: EXEMPT bugfix
Change-Id: I78eea7fbf1c8d507a2575796b1bafe2d443b6ec7
parent e492f8a6
Loading
Loading
Loading
Loading
+50 −47
Original line number Diff line number Diff line
@@ -1907,27 +1907,6 @@ class UserController implements Handler.Callback {
                return false;
            }

            final Runnable continueStartUserInternal = () -> continueStartUserInternal(userInfo,
                    oldUserId, userStartMode, unlockListener, callingUid, callingPid);
            if (foreground) {
                mHandler.post(() -> dispatchOnBeforeUserSwitching(userId, () ->
                        mHandler.post(continueStartUserInternal)));
            } else {
                continueStartUserInternal.run();
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }

        return true;
    }

    private void continueStartUserInternal(UserInfo userInfo, int oldUserId, int userStartMode,
            IProgressListener unlockListener, int callingUid, int callingPid) {
        final TimingsTraceAndSlog t = new TimingsTraceAndSlog();
        final boolean foreground = userStartMode == USER_START_MODE_FOREGROUND;
        final int userId = userInfo.id;

            boolean needStart = false;
            boolean updateUmState = false;
            UserState uss;
@@ -1951,7 +1930,7 @@ class UserController implements Handler.Callback {
                    mPendingUserStarts.add(new PendingUserStart(userId, userStartMode,
                            unlockListener));
                    t.traceEnd(); // updateStartedUserArrayStarting
                return;
                    return true;
                }
            }

@@ -1973,6 +1952,30 @@ class UserController implements Handler.Callback {
                mInjector.getUserManagerInternal().setUserState(userId, uss.state);
                t.traceEnd();
            }

            UserState finalUss = uss;
            boolean finalNeedStart = needStart;
            final Runnable continueStartUserInternal = () -> continueStartUserInternal(userInfo,
                    oldUserId, userStartMode, finalUss, finalNeedStart, callingUid, callingPid);
            if (foreground) {
                mHandler.post(() -> dispatchOnBeforeUserSwitching(userId, () ->
                        mHandler.post(continueStartUserInternal)));
            } else {
                continueStartUserInternal.run();
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }

        return true;
    }

    private void continueStartUserInternal(UserInfo userInfo, int oldUserId, int userStartMode,
            UserState uss, boolean needStart, int callingUid, int callingPid) {
        final TimingsTraceAndSlog t = new TimingsTraceAndSlog();
        final boolean foreground = userStartMode == USER_START_MODE_FOREGROUND;
        final int userId = userInfo.id;

        t.traceBegin("updateConfigurationAndProfileIds");
        if (foreground) {
            // Make sure the old user is no longer considering the display to be on.