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

am: dafec11e69

* commit 'dafec11e698daf054730cfb04db64f3e31a0c9ff':
  Don't allow deactivating DAs when the user is not unlocked
This commit is contained in:
Makoto Onuki
2016-02-16 20:53:03 +00:00
committed by android-build-merger
3 changed files with 92 additions and 5 deletions

View File

@@ -99,6 +99,20 @@ public class Preconditions {
return reference;
}
/**
* 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
* @param message exception message
* @throws IllegalStateException if {@code expression} is false
*/
public static void checkState(final boolean expression, String message) {
if (!expression) {
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.
@@ -107,9 +121,7 @@ public class Preconditions {
* @throws IllegalStateException if {@code expression} is false
*/
public static void checkState(final boolean expression) {
if (!expression) {
throw new IllegalStateException();
}
checkState(expression, null);
}
/**

View File

@@ -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");

View File

@@ -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