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

Commit dafec11e authored by Makoto Onuki's avatar Makoto Onuki Committed by Android (Google) Code Review
Browse files

Merge "Don't allow deactivating DAs when the user is not unlocked" into nyc-dev

parents 61def3e4 1a5ee776
Loading
Loading
Loading
Loading
+14 −2
Original line number Diff line number Diff line
@@ -104,12 +104,24 @@ public class Preconditions {
     * instance, but not involving any parameters to the calling method.
     *
     * @param expression a boolean expression
     * @param message exception message
     * @throws IllegalStateException if {@code expression} is false
     */
    public static void checkState(final boolean expression) {
    public static void checkState(final boolean expression, String message) {
        if (!expression) {
            throw new IllegalStateException();
            throw new IllegalStateException(message);
        }
    }

    /**
     * Ensures the truth of an expression involving the state of the calling
     * instance, but not involving any parameters to the calling method.
     *
     * @param expression a boolean expression
     * @throws IllegalStateException if {@code expression} is false
     */
    public static void checkState(final boolean expression) {
        checkState(expression, null);
    }

    /**
+10 −0
Original line number Diff line number Diff line
@@ -2818,6 +2818,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            return;
        }
        enforceFullCrossUsersPermission(userHandle);
        enforceUserUnlocked(userHandle);
        synchronized (this) {
            ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver, userHandle);
            if (admin == null) {
@@ -5531,6 +5532,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                throw new SecurityException(
                        "clearDeviceOwner can only be called by the device owner");
            }
            enforceUserUnlocked(deviceOwnerUserId);

            final ActiveAdmin admin = getDeviceOwnerAdminLocked();
            if (admin != null) {
@@ -5585,6 +5587,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        final UserHandle callingUser = mInjector.binderGetCallingUserHandle();
        final int userId = callingUser.getIdentifier();
        enforceNotManagedProfile(userId, "clear profile owner");
        enforceUserUnlocked(userId);
        // Check if this is the profile owner who is calling
        final ActiveAdmin admin =
                getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
@@ -5960,6 +5963,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        }
    }

    private void enforceUserUnlocked(int userId) {
        Preconditions.checkState(mUserManager.isUserUnlocked(userId),
                "User must be running and unlocked");
    }

    private void enforceManageUsers() {
        final int callingUid = mInjector.binderGetCallingUid();
        if (!(isCallerWithSystemUid() || callingUid == Process.ROOT_UID)) {
@@ -8540,6 +8548,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {

        final int userId = mInjector.userHandleGetCallingUserId();

        enforceUserUnlocked(userId);

        final ComponentName profileOwner = getProfileOwner(userId);
        if (profileOwner != null && packageName.equals(profileOwner.getPackageName())) {
            throw new IllegalArgumentException("Cannot uninstall a package with a profile owner");
+67 −2
Original line number Diff line number Diff line
@@ -46,7 +46,6 @@ import org.mockito.stubbing.Answer;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -94,6 +93,9 @@ public class DevicePolicyManagerTest extends DpmTestBase {
        when(mContext.packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
                .thenReturn(true);

        // By default, pretend all users are running and unlocked.
        when(mContext.userManager.isUserUnlocked(anyInt())).thenReturn(true);

        initializeDpms();

        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID);
@@ -414,6 +416,45 @@ public class DevicePolicyManagerTest extends DpmTestBase {
        }
    }

    /**
     * {@link DevicePolicyManager#removeActiveAdmin} should fail with the user is not unlocked
     * (because we can't send the remove broadcast).
     */
    public void testRemoveActiveAdmin_userNotRunningOrLocked() {
        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);

        mContext.binder.callingUid = DpmMockContext.CALLER_UID;

        // Add admin.

        dpm.setActiveAdmin(admin1, /* replace =*/ false);

        assertTrue(dpm.isAdminActive(admin1));

        assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));

        // 1. User not unlocked.
        when(mContext.userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE)))
                .thenReturn(false);
        try {
            dpm.removeActiveAdmin(admin1);
            fail("Didn't throw IllegalStateException");
        } catch (IllegalStateException expected) {
            MoreAsserts.assertContainsRegex(
                    "User must be running and unlocked", expected.getMessage());
        }

        assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));

        // 2. User unlocked.
        when(mContext.userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE)))
                .thenReturn(true);

        dpm.removeActiveAdmin(admin1);

        assertTrue(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
    }

    /**
     * Test for:
     * {@link DevicePolicyManager#removeActiveAdmin}
@@ -782,6 +823,18 @@ public class DevicePolicyManagerTest extends DpmTestBase {
        doReturn(DpmMockContext.CALLER_SYSTEM_USER_UID).when(mContext.packageManager).getPackageUidAsUser(
                eq(admin1.getPackageName()),
                anyInt());

        // But first pretend the user is locked.  Then it should fail.
        when(mContext.userManager.isUserUnlocked(anyInt())).thenReturn(false);
        try {
            dpm.clearDeviceOwnerApp(admin1.getPackageName());
            fail("Didn't throw IllegalStateException");
        } catch (IllegalStateException expected) {
            MoreAsserts.assertContainsRegex(
                    "User must be running and unlocked", expected.getMessage());
        }

        when(mContext.userManager.isUserUnlocked(anyInt())).thenReturn(true);
        reset(mContext.userManagerInternal);
        dpm.clearDeviceOwnerApp(admin1.getPackageName());

@@ -869,7 +922,19 @@ public class DevicePolicyManagerTest extends DpmTestBase {
        assertTrue(dpm.isProfileOwnerApp(admin1.getPackageName()));
        assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));

        // Clear
        // First try when the user is locked, which should fail.
        when(mContext.userManager.isUserUnlocked(anyInt()))
                .thenReturn(false);
        try {
            dpm.clearProfileOwner(admin1);
            fail("Didn't throw IllegalStateException");
        } catch (IllegalStateException expected) {
            MoreAsserts.assertContainsRegex(
                    "User must be running and unlocked", expected.getMessage());
        }
        // Clear, really.
        when(mContext.userManager.isUserUnlocked(anyInt()))
                .thenReturn(true);
        dpm.clearProfileOwner(admin1);

        // Check