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

Commit df40cf14 authored by Adam Bookatz's avatar Adam Bookatz Committed by Android (Google) Code Review
Browse files

Merge "Don't stop current user's profile even if excess" into main

parents 6c4af840 dcca5d8b
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -993,6 +993,13 @@ class UserController implements Handler.Callback {
        if (isCurrentUserLU(userId)) {
            return USER_OP_IS_CURRENT;
        }
        // TODO(b/324647580): Refactor the idea of "force" and clean up. In the meantime...
        final int parentId = mUserProfileGroupIds.get(userId, UserInfo.NO_PROFILE_GROUP_ID);
        if (parentId != UserInfo.NO_PROFILE_GROUP_ID && parentId != userId) {
            if ((UserHandle.USER_SYSTEM == parentId || isCurrentUserLU(parentId)) && !force) {
                return USER_OP_ERROR_RELATED_USERS_CANNOT_STOP;
            }
        }
        TimingsTraceAndSlog t = new TimingsTraceAndSlog();
        int[] usersToStop = getUsersToStopLU(userId);
        // If one of related users is system or current, no related users should be stopped
+82 −0
Original line number Diff line number Diff line
@@ -123,6 +123,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@@ -677,6 +678,87 @@ public class UserControllerTest {
                .lockCeStorage(TEST_USER_ID);
    }

    /**
     * Test that, when exceeding the maximum number of running users, a profile of the current user
     * is not stopped.
     */
    @Test
    public void testStoppingExcessRunningUsersAfterSwitch_currentProfileNotStopped()
            throws Exception {
        mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
                /* maxRunningUsers= */ 5, /* delayUserDataLocking= */ false);

        final int PARENT_ID = 200;
        final int PROFILE1_ID = 201;
        final int PROFILE2_ID = 202;
        final int FG_USER_ID = 300;
        final int BG_USER_ID = 400;

        setUpUser(PARENT_ID, 0).profileGroupId = PARENT_ID;
        setUpUser(PROFILE1_ID, UserInfo.FLAG_PROFILE).profileGroupId = PARENT_ID;
        setUpUser(PROFILE2_ID, UserInfo.FLAG_PROFILE).profileGroupId = PARENT_ID;
        setUpUser(FG_USER_ID, 0).profileGroupId = FG_USER_ID;
        setUpUser(BG_USER_ID, 0).profileGroupId = UserInfo.NO_PROFILE_GROUP_ID;
        mUserController.onSystemReady(); // To set the profileGroupIds in UserController.

        assertEquals(newHashSet(
                SYSTEM_USER_ID),
                new HashSet<>(mUserController.getRunningUsersLU()));

        int numberOfUserSwitches = 1;
        addForegroundUserAndContinueUserSwitch(PARENT_ID, UserHandle.USER_SYSTEM,
                numberOfUserSwitches, false);
        mUserController.finishUserSwitch(mUserStates.get(PARENT_ID));
        waitForHandlerToComplete(mInjector.mHandler, HANDLER_WAIT_TIME_MS);
        assertTrue(mUserController.canStartMoreUsers());
        assertEquals(newHashSet(
                SYSTEM_USER_ID, PARENT_ID),
                new HashSet<>(mUserController.getRunningUsersLU()));

        assertThat(mUserController.startProfile(PROFILE1_ID, true, null)).isTrue();
        assertEquals(newHashSet(
                SYSTEM_USER_ID, PROFILE1_ID, PARENT_ID),
                new HashSet<>(mUserController.getRunningUsersLU()));

        numberOfUserSwitches++;
        addForegroundUserAndContinueUserSwitch(FG_USER_ID, PARENT_ID,
                numberOfUserSwitches, false);
        mUserController.finishUserSwitch(mUserStates.get(FG_USER_ID));
        waitForHandlerToComplete(mInjector.mHandler, HANDLER_WAIT_TIME_MS);
        assertTrue(mUserController.canStartMoreUsers());
        assertEquals(newHashSet(
                SYSTEM_USER_ID, PROFILE1_ID, PARENT_ID, FG_USER_ID),
                new HashSet<>(mUserController.getRunningUsersLU()));

        mUserController.startUser(BG_USER_ID, USER_START_MODE_BACKGROUND);
        assertEquals(newHashSet(
                SYSTEM_USER_ID, PROFILE1_ID, PARENT_ID, BG_USER_ID, FG_USER_ID),
                new HashSet<>(mUserController.getRunningUsersLU()));

        // Now we exceed the maxRunningUsers parameter (of 5):
        assertThat(mUserController.startProfile(PROFILE2_ID, true, null)).isTrue();
        // Currently, starting a profile doesn't trigger evaluating whether we've exceeded max, so
        // we expect no users to be stopped. This policy may change in the future. Log but no fail.
        if (!newHashSet(SYSTEM_USER_ID, PROFILE1_ID, BG_USER_ID, PROFILE2_ID, PARENT_ID, FG_USER_ID)
                .equals(new HashSet<>(mUserController.getRunningUsersLU()))) {
            Log.w(TAG, "Starting a profile that exceeded max running users didn't lead to "
                    + "expectations: " + mUserController.getRunningUsersLU());
        }

        numberOfUserSwitches++;
        addForegroundUserAndContinueUserSwitch(PARENT_ID, FG_USER_ID,
                numberOfUserSwitches, false);
        mUserController.finishUserSwitch(mUserStates.get(PARENT_ID));
        waitForHandlerToComplete(mInjector.mHandler, HANDLER_WAIT_TIME_MS);
        // We've now done a user switch and should notice that we've exceeded the maximum number of
        // users. The oldest background user should be stopped (BG_USER); even though PROFILE1 was
        // older, it should not be stopped since it's a profile of the (new) current user.
        assertFalse(mUserController.canStartMoreUsers());
        assertEquals(newHashSet(
                SYSTEM_USER_ID, PROFILE1_ID, PROFILE2_ID, FG_USER_ID, PARENT_ID),
                new HashSet<>(mUserController.getRunningUsersLU()));
    }

    /**
     * Test that, in getRunningUsersLU, parents come after their profile, even if the profile was
     * started afterwards.