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

Commit f76de3d6 authored by Nikhil Kumar's avatar Nikhil Kumar Committed by Android (Google) Code Review
Browse files

Merge "Add restriction to remove main user"

parents b1932400 a09a8f1c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -10416,6 +10416,7 @@ package android.os {
    field public static final String DISALLOW_RUN_IN_BACKGROUND = "no_run_in_background";
    field public static final int REMOVE_RESULT_ALREADY_BEING_REMOVED = 2; // 0x2
    field public static final int REMOVE_RESULT_DEFERRED = 1; // 0x1
    field public static final int REMOVE_RESULT_ERROR_MAIN_USER_PERMANENT_ADMIN = -5; // 0xfffffffb
    field public static final int REMOVE_RESULT_ERROR_SYSTEM_USER = -4; // 0xfffffffc
    field public static final int REMOVE_RESULT_ERROR_UNKNOWN = -1; // 0xffffffff
    field public static final int REMOVE_RESULT_ERROR_USER_NOT_FOUND = -3; // 0xfffffffd
+13 −2
Original line number Diff line number Diff line
@@ -1826,6 +1826,15 @@ public class UserManager {
    @SystemApi
    public static final int REMOVE_RESULT_ERROR_SYSTEM_USER = -4;

    /**
     * A response code from {@link #removeUserWhenPossible(UserHandle, boolean)} indicating that
     * user being removed is a  {@link UserInfo#FLAG_MAIN}  user and can't be removed because
     * system property {@link com.android.internal.R.bool.isMainUserPermanentAdmin} is true.
     * @hide
     */
    @SystemApi
    public static final int REMOVE_RESULT_ERROR_MAIN_USER_PERMANENT_ADMIN = -5;

    /**
     * Possible response codes from {@link #removeUserWhenPossible(UserHandle, boolean)}.
     *
@@ -1838,6 +1847,7 @@ public class UserManager {
            REMOVE_RESULT_ERROR_USER_RESTRICTION,
            REMOVE_RESULT_ERROR_USER_NOT_FOUND,
            REMOVE_RESULT_ERROR_SYSTEM_USER,
            REMOVE_RESULT_ERROR_MAIN_USER_PERMANENT_ADMIN,
            REMOVE_RESULT_ERROR_UNKNOWN,
    })
    @Retention(RetentionPolicy.SOURCE)
@@ -5236,8 +5246,9 @@ public class UserManager {
     * @return the {@link RemoveResult} code: {@link #REMOVE_RESULT_REMOVED},
     * {@link #REMOVE_RESULT_DEFERRED}, {@link #REMOVE_RESULT_ALREADY_BEING_REMOVED},
     * {@link #REMOVE_RESULT_ERROR_USER_RESTRICTION}, {@link #REMOVE_RESULT_ERROR_USER_NOT_FOUND},
     * {@link #REMOVE_RESULT_ERROR_SYSTEM_USER}, or {@link #REMOVE_RESULT_ERROR_UNKNOWN}. All error
     * codes have negative values.
     * {@link #REMOVE_RESULT_ERROR_SYSTEM_USER},
     * {@link #REMOVE_RESULT_ERROR_MAIN_USER_PERMANENT_ADMIN}, or
     * {@link #REMOVE_RESULT_ERROR_UNKNOWN}. All error codes have negative values.
     *
     * @hide
     */
+4 −0
Original line number Diff line number Diff line
@@ -3023,6 +3023,10 @@ class PackageManagerShellCommand extends ShellCommand {
            case UserManager.REMOVE_RESULT_ALREADY_BEING_REMOVED:
                getOutPrintWriter().printf("Success: user %d is already being removed\n", userId);
                return 0;
            case UserManager.REMOVE_RESULT_ERROR_MAIN_USER_PERMANENT_ADMIN:
                getOutPrintWriter().printf("Error: user %d is a permanent admin main user\n",
                        userId);
                return 1;
            default:
                getErrPrintWriter().printf("Error: couldn't remove or mark ephemeral user id %d\n",
                        userId);
+35 −5
Original line number Diff line number Diff line
@@ -5442,6 +5442,12 @@ public class UserManagerService extends IUserManager.Stub {
                        return false;
                    }

                    if (isNonRemovableMainUser(userData.info)) {
                        Slog.e(LOG_TAG, "Main user cannot be removed when "
                                + "it's a permanent admin user.");
                        return false;
                    }

                    if (mRemovingUserIds.get(userId)) {
                        Slog.e(LOG_TAG, TextUtils.formatSimple(
                                "User %d is already scheduled for removal.", userId));
@@ -5546,6 +5552,12 @@ public class UserManagerService extends IUserManager.Stub {
                        return UserManager.REMOVE_RESULT_ERROR_USER_NOT_FOUND;
                    }

                    if (isNonRemovableMainUser(userData.info)) {
                        Slog.e(LOG_TAG, "Main user cannot be removed when "
                                + "it's a permanent admin user.");
                        return UserManager.REMOVE_RESULT_ERROR_MAIN_USER_PERMANENT_ADMIN;
                    }

                    if (mRemovingUserIds.get(userId)) {
                        Slog.e(LOG_TAG, "User " + userId + " is already scheduled for removal.");
                        return UserManager.REMOVE_RESULT_ALREADY_BEING_REMOVED;
@@ -6764,7 +6776,7 @@ public class UserManagerService extends IUserManager.Stub {
        public void removeAllUsers() {
            if (UserHandle.USER_SYSTEM == getCurrentUserId()) {
                // Remove the non-system users straight away.
                removeNonSystemUsers();
                removeAllUsersExceptSystemAndPermanentAdminMain();
            } else {
                // Switch to the system user first and then remove the other users.
                BroadcastReceiver userSwitchedReceiver = new BroadcastReceiver() {
@@ -6776,7 +6788,7 @@ public class UserManagerService extends IUserManager.Stub {
                            return;
                        }
                        mContext.unregisterReceiver(this);
                        removeNonSystemUsers();
                        removeAllUsersExceptSystemAndPermanentAdminMain();
                    }
                };
                IntentFilter userSwitchedFilter = new IntentFilter();
@@ -7129,14 +7141,14 @@ public class UserManagerService extends IUserManager.Stub {
        throw new UserManager.CheckedUserOperationException(message, userOperationResult);
    }

    /* Remove all the users except of the system one. */
    private void removeNonSystemUsers() {
    /* Remove all the users except the system and permanent admin main.*/
    private void removeAllUsersExceptSystemAndPermanentAdminMain() {
        ArrayList<UserInfo> usersToRemove = new ArrayList<>();
        synchronized (mUsersLock) {
            final int userSize = mUsers.size();
            for (int i = 0; i < userSize; i++) {
                UserInfo ui = mUsers.valueAt(i).info;
                if (ui.id != UserHandle.USER_SYSTEM) {
                if (ui.id != UserHandle.USER_SYSTEM && !isNonRemovableMainUser(ui)) {
                    usersToRemove.add(ui);
                }
            }
@@ -7265,4 +7277,22 @@ public class UserManagerService extends IUserManager.Stub {
        return mAmInternal;
    }

    /**
     * Returns true, when user has {@link UserInfo#FLAG_MAIN} and system property
     * {@link com.android.internal.R.bool.isMainUserPermanentAdmin} is true.
     */
    private boolean isNonRemovableMainUser(UserInfo userInfo) {
        return userInfo.isMain() && isMainUserPermanentAdmin();
    }

    /**
     * Returns true, when {@link com.android.internal.R.bool.isMainUserPermanentAdmin} is true.
     * If the main user is a permanent admin user it can't be deleted
     * or downgraded to non-admin status.
     */
    private static boolean isMainUserPermanentAdmin() {
        return Resources.getSystem()
                .getBoolean(com.android.internal.R.bool.config_isMainUserPermanentAdmin);
    }

}
+29 −0
Original line number Diff line number Diff line
@@ -373,6 +373,29 @@ public final class UserManagerTest {
        assertThat(hasUser(UserHandle.USER_SYSTEM)).isTrue();
    }

    @MediumTest
    @Test
    public void testRemoveUserWhenPossible_permanentAdminMainUserReturnsError() throws Exception {
        assumeHeadlessModeEnabled();
        assumeTrue("Main user is not permanent admin", isMainUserPermanentAdmin());

        int currentUser = ActivityManager.getCurrentUser();
        final UserInfo otherUser = createUser("User 1", /* flags= */ UserInfo.FLAG_ADMIN);
        UserHandle mainUser = mUserManager.getMainUser();

        switchUser(otherUser.id, null, true);

        assertThat(mUserManager.removeUserWhenPossible(mainUser,
                /* overrideDevicePolicy= */ false))
                .isEqualTo(UserManager.REMOVE_RESULT_ERROR_MAIN_USER_PERMANENT_ADMIN);


        assertThat(hasUser(mainUser.getIdentifier())).isTrue();

        // Switch back to the starting user.
        switchUser(currentUser, null, true);
    }

    @MediumTest
    @Test
    public void testRemoveUserWhenPossible_invalidUserReturnsError() throws Exception {
@@ -1423,4 +1446,10 @@ public final class UserManagerTest {
    private static UserHandle asHandle(int userId) {
        return new UserHandle(userId);
    }

    private boolean isMainUserPermanentAdmin() {
        return Resources.getSystem()
                .getBoolean(com.android.internal.R.bool.config_isMainUserPermanentAdmin);
    }

}