DA receiver should be protected with BIND_DEVICE_ADMIN.
- DPM.setActiveAdmin() will not accept DAs without BIND_DEVICE_ADMIN
when it's targeting NYC or above.
- DAs without BIND_DEVICE_ADMIN targeting MNC or below will still be
accepted. (with a logcat warning)
- DAs that are already set on a device without BIND_DEVICE_ADMIN
will still be accepted regardless of the target API level, even when
it's upgraded to a version targeting NYC.
Bug 24168653
Change-Id: I1914c2ec99135d9dd8cbac3f6914f9e43bafacc8
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 0159356..565ef4b 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -27,6 +27,8 @@
import android.content.ComponentName;
import android.content.pm.PackageManager;
import android.net.wifi.WifiInfo;
+import android.os.Build;
+import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.Process;
import android.os.UserHandle;
@@ -85,6 +87,7 @@
setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID);
setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID);
setUpPackageManagerForAdmin(admin3, DpmMockContext.CALLER_UID);
+ setUpPackageManagerForAdmin(adminNoPerm, DpmMockContext.CALLER_UID);
setUpUserManager();
}
@@ -338,6 +341,33 @@
/**
* Test for:
+ * {@link DevicePolicyManager#setActiveAdmin} when the admin isn't protected with
+ * BIND_DEVICE_ADMIN.
+ */
+ public void testSetActiveAdmin_permissionCheck() throws Exception {
+ // 1. Make sure the caller has proper permissions.
+ mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
+
+ try {
+ dpm.setActiveAdmin(adminNoPerm, /* replace =*/ false);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ assertTrue(expected.getMessage().contains(permission.BIND_DEVICE_ADMIN));
+ }
+ assertFalse(dpm.isAdminActive(adminNoPerm));
+
+ // Change the target API level to MNC. Now it can be set as DA.
+ setUpPackageManagerForAdmin(adminNoPerm, DpmMockContext.CALLER_UID, null,
+ VERSION_CODES.M);
+ dpm.setActiveAdmin(adminNoPerm, /* replace =*/ false);
+ assertTrue(dpm.isAdminActive(adminNoPerm));
+
+ // TODO Test the "load from the file" case where DA will still be loaded even without
+ // BIND_DEVICE_ADMIN and target API is N.
+ }
+
+ /**
+ * Test for:
* {@link DevicePolicyManager#removeActiveAdmin}
*/
public void testRemoveActiveAdmin_SecurityException() {
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
index e11f3fb..5b33e4d 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java
@@ -43,6 +43,7 @@
public ComponentName admin1;
public ComponentName admin2;
public ComponentName admin3;
+ public ComponentName adminNoPerm;
@Override
protected void setUp() throws Exception {
@@ -56,6 +57,7 @@
admin1 = new ComponentName(mRealTestContext, DummyDeviceAdmins.Admin1.class);
admin2 = new ComponentName(mRealTestContext, DummyDeviceAdmins.Admin2.class);
admin3 = new ComponentName(mRealTestContext, DummyDeviceAdmins.Admin3.class);
+ adminNoPerm = new ComponentName(mRealTestContext, DummyDeviceAdmins.AdminNoPerm.class);
}
@Override
@@ -67,11 +69,36 @@
protected void setUpPackageManagerForAdmin(ComponentName admin, int packageUid)
throws Exception {
setUpPackageManagerForAdmin(admin, packageUid,
- PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED);
+ /* enabledSetting =*/ null, /* appTargetSdk = */ null);
}
protected void setUpPackageManagerForAdmin(ComponentName admin, int packageUid,
int enabledSetting) throws Exception {
+ setUpPackageManagerForAdmin(admin, packageUid, enabledSetting, /* appTargetSdk = */ null);
+ }
+
+ protected void setUpPackageManagerForAdmin(ComponentName admin, int packageUid,
+ Integer enabledSetting, Integer appTargetSdk) throws Exception {
+
+ // Set up getApplicationInfo().
+
+ final ApplicationInfo ai = DpmTestUtils.cloneParcelable(
+ mRealTestContext.getPackageManager().getApplicationInfo(
+ admin.getPackageName(),
+ PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS));
+
+ ai.enabledSetting = enabledSetting == null
+ ? PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
+ : enabledSetting;
+ if (appTargetSdk != null) {
+ ai.targetSdkVersion = appTargetSdk;
+ }
+ ai.uid = packageUid;
+
+ doReturn(ai).when(mMockContext.ipackageManager).getApplicationInfo(
+ eq(admin.getPackageName()),
+ eq(PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS),
+ eq(UserHandle.getUserId(packageUid)));
// Set up queryBroadcastReceivers().
@@ -88,7 +115,7 @@
realResolveInfo.set(0, DpmTestUtils.cloneParcelable(realResolveInfo.get(0)));
// We need to rewrite the UID in the activity info.
- realResolveInfo.get(0).activityInfo.applicationInfo.uid = packageUid;
+ realResolveInfo.get(0).activityInfo.applicationInfo = ai;
doReturn(realResolveInfo).when(mMockContext.packageManager).queryBroadcastReceivers(
MockUtils.checkIntentComponent(admin),
@@ -96,21 +123,6 @@
| PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS),
eq(UserHandle.getUserId(packageUid)));
- // Set up getApplicationInfo().
-
- final ApplicationInfo ai = DpmTestUtils.cloneParcelable(
- mRealTestContext.getPackageManager().getApplicationInfo(
- admin.getPackageName(),
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS));
-
- ai.enabledSetting = enabledSetting;
- ai.uid = packageUid;
-
- doReturn(ai).when(mMockContext.ipackageManager).getApplicationInfo(
- eq(admin.getPackageName()),
- eq(PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS),
- eq(UserHandle.getUserId(packageUid)));
-
// Set up getPackageInfo().
final PackageInfo pi = DpmTestUtils.cloneParcelable(
@@ -118,7 +130,7 @@
admin.getPackageName(), 0));
assertTrue(pi.applicationInfo.flags != 0);
- pi.applicationInfo.uid = packageUid;
+ pi.applicationInfo = ai;
doReturn(pi).when(mMockContext.ipackageManager).getPackageInfo(
eq(admin.getPackageName()),
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DummyDeviceAdmins.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DummyDeviceAdmins.java
index 08293a2..a0f4d97 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DummyDeviceAdmins.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DummyDeviceAdmins.java
@@ -24,4 +24,6 @@
}
public static class Admin3 extends DeviceAdminReceiver {
}
+ public static class AdminNoPerm extends DeviceAdminReceiver {
+ }
}