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

Commit d4b249ed authored by jovanak's avatar jovanak
Browse files

Don't fire any ACTION_USER_* broadcasts for precreated users.

Fixes: 145167416
Test: atest UserControllerTest + manual checks for bcasts
Change-Id: I82af3bf810dca2b98e78b5f9310f60c0c18c7526
parent 305c7391
Loading
Loading
Loading
Loading
+47 −30
Original line number Diff line number Diff line
@@ -517,6 +517,7 @@ class UserController implements Handler.Callback {
        }
        mInjector.installEncryptionUnawareProviders(userId);

        if (!mInjector.getUserManager().isPreCreated(userId)) {
            // Dispatch unlocked to external apps
            final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED);
            unlockedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
@@ -525,6 +526,7 @@ class UserController implements Handler.Callback {
            mInjector.broadcastIntent(unlockedIntent, null, null, 0, null,
                    null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
                    Binder.getCallingUid(), Binder.getCallingPid(), userId);
        }

        if (getUserInfo(userId).isManagedProfile()) {
            UserInfo parent = mInjector.getUserManager().getProfileParent(userId);
@@ -581,9 +583,12 @@ class UserController implements Handler.Callback {
        // Remember that we logged in
        mInjector.getUserManager().onUserLoggedIn(userId);

        Runnable initializeUser = () -> mInjector.getUserManager().makeInitialized(userInfo.id);
        if (!userInfo.isInitialized()) {
            if (userId != UserHandle.USER_SYSTEM) {
            Slog.d(TAG, "Initializing user #" + userId);
            if (userInfo.preCreated) {
                initializeUser.run();
            } else if (userId != UserHandle.USER_SYSTEM) {
                Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
                intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
                        | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
@@ -594,7 +599,7 @@ class UserController implements Handler.Callback {
                                    String data, Bundle extras, boolean ordered,
                                    boolean sticky, int sendingUser) {
                                // Note: performReceive is called with mService lock held
                                mInjector.getUserManager().makeInitialized(userInfo.id);
                                initializeUser.run();
                            }
                        }, 0, null, null, null, AppOpsManager.OP_NONE,
                        null, true, false, MY_PID, SYSTEM_UID, Binder.getCallingUid(),
@@ -792,7 +797,15 @@ class UserController implements Handler.Callback {
            mInjector.getUserManagerInternal().setUserState(userId, uss.state);
            updateStartedUserArrayLU();

            final boolean allowDelayyLockingCopied = allowDelayedLocking;
            final boolean allowDelayedLockingCopied = allowDelayedLocking;
            Runnable finishUserStoppingAsync = () ->
                    mHandler.post(() -> finishUserStopping(userId, uss, allowDelayedLockingCopied));

            if (mInjector.getUserManager().isPreCreated(userId)) {
                finishUserStoppingAsync.run();
                return;
            }

            // Post to handler to obtain amLock
            mHandler.post(() -> {
                // We are going to broadcast ACTION_USER_STOPPING and then
@@ -807,8 +820,7 @@ class UserController implements Handler.Callback {
                    @Override
                    public void performReceive(Intent intent, int resultCode, String data,
                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
                        mHandler.post(() -> finishUserStopping(userId, uss,
                                allowDelayyLockingCopied));
                        finishUserStoppingAsync.run();
                    }
                };

@@ -827,22 +839,6 @@ class UserController implements Handler.Callback {
    void finishUserStopping(final int userId, final UserState uss,
            final boolean allowDelayedLocking) {
        Slog.d(TAG, "UserController event: finishUserStopping(" + userId + ")");
        // On to the next.
        final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
        // This is the result receiver for the final shutdown broadcast.
        final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
            @Override
            public void performReceive(Intent intent, int resultCode, String data,
                    Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        finishUserStopped(uss, allowDelayedLocking);
                    }
                });
            }
        };

        synchronized (mLock) {
            if (uss.state != UserState.STATE_STOPPING) {
                // Whoops, we are being started back up.  Abort, abort!
@@ -857,6 +853,23 @@ class UserController implements Handler.Callback {
                Integer.toString(userId), userId);
        mInjector.getSystemServiceManager().stopUser(userId);

        Runnable finishUserStoppedAsync = () ->
                mHandler.post(() -> finishUserStopped(uss, allowDelayedLocking));
        if (mInjector.getUserManager().isPreCreated(userId)) {
            finishUserStoppedAsync.run();
            return;
        }

        // Fire the shutdown intent.
        final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
        // This is the result receiver for the final shutdown broadcast.
        final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
            @Override
            public void performReceive(Intent intent, int resultCode, String data,
                    Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
                finishUserStoppedAsync.run();
            }
        };
        mInjector.broadcastIntent(shutdownIntent,
                null, shutdownReceiver, 0, null, null, null,
                AppOpsManager.OP_NONE,
@@ -1016,6 +1029,10 @@ class UserController implements Handler.Callback {

    private void forceStopUser(@UserIdInt int userId, String reason) {
        mInjector.activityManagerForceStopPackage(userId, reason);
        if (mInjector.getUserManager().isPreCreated(userId)) {
            // Don't fire intent for precreated.
            return;
        }
        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
                | Intent.FLAG_RECEIVER_FOREGROUND);
+13 −0
Original line number Diff line number Diff line
@@ -3756,6 +3756,19 @@ public class UserManagerService extends IUserManager.Stub {

    void finishRemoveUser(final @UserIdInt int userId) {
        if (DBG) Slog.i(LOG_TAG, "finishRemoveUser " + userId);

        UserInfo user;
        synchronized (mUsersLock) {
            user = getUserInfoLU(userId);
        }
        if (user != null && user.preCreated) {
            Slog.i(LOG_TAG, "Removing a precreated user with user id: " + userId);
            // Don't want to fire ACTION_USER_REMOVED, so cleanup the state and exit early.
            LocalServices.getService(ActivityTaskManagerInternal.class).onUserStopped(userId);
            removeUserState(userId);
            return;
        }

        // Let other services shutdown any activity and clean up their state before completely
        // wiping the user's system directory and removing from the user list
        long ident = Binder.clearCallingIdentity();
+4 −0
Original line number Diff line number Diff line
@@ -206,11 +206,15 @@ public class UserControllerTest {
    @Test
    public void testStartPreCreatedUser_foreground() {
        assertFalse(mUserController.startUser(TEST_PRE_CREATED_USER_ID, /* foreground= */ true));
        // Make sure no intents have been fired for pre-created users.
        assertTrue(mInjector.mSentIntents.isEmpty());
    }

    @Test
    public void testStartPreCreatedUser_background() throws Exception {
        assertTrue(mUserController.startUser(TEST_PRE_CREATED_USER_ID, /* foreground= */ false));
        // Make sure no intents have been fired for pre-created users.
        assertTrue(mInjector.mSentIntents.isEmpty());

        verify(mInjector.getWindowManager(), never()).startFreezingScreen(anyInt(), anyInt());
        verify(mInjector.getWindowManager(), never()).setSwitchingUser(anyBoolean());