Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +20 −4 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.AsyncTask; import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.FileUtils; Loading Loading @@ -1721,7 +1722,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } public DeviceAdminInfo findAdmin(ComponentName adminName, int userHandle) { public DeviceAdminInfo findAdmin(ComponentName adminName, int userHandle, boolean throwForMissiongPermission) { if (!mHasFeature) { return null; } Loading @@ -1736,8 +1738,20 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { throw new IllegalArgumentException("Unknown admin: " + adminName); } final ResolveInfo ri = infos.get(0); if (!permission.BIND_DEVICE_ADMIN.equals(ri.activityInfo.permission)) { final String message = "DeviceAdminReceiver " + adminName + " must be protected with" + permission.BIND_DEVICE_ADMIN; Slog.w(LOG_TAG, message); if (throwForMissiongPermission && ri.activityInfo.applicationInfo.targetSdkVersion > Build.VERSION_CODES.M) { throw new IllegalArgumentException(message); } } try { return new DeviceAdminInfo(mContext, infos.get(0)); return new DeviceAdminInfo(mContext, ri); } catch (XmlPullParserException e) { Slog.w(LOG_TAG, "Bad device admin requested for user=" + userHandle + ": " + adminName, e); Loading Loading @@ -1928,7 +1942,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { String name = parser.getAttributeValue(null, "name"); try { DeviceAdminInfo dai = findAdmin( ComponentName.unflattenFromString(name), userHandle); ComponentName.unflattenFromString(name), userHandle, /* throwForMissionPermission= */ false); if (VERBOSE_LOG && (UserHandle.getUserId(dai.getActivityInfo().applicationInfo.uid) != userHandle)) { Loading Loading @@ -2319,7 +2334,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { enforceCrossUserPermission(userHandle); DevicePolicyData policy = getUserData(userHandle); DeviceAdminInfo info = findAdmin(adminReceiver, userHandle); DeviceAdminInfo info = findAdmin(adminReceiver, userHandle, /* throwForMissionPermission= */ true); if (info == null) { throw new IllegalArgumentException("Bad admin: " + adminReceiver); } Loading services/tests/servicestests/AndroidManifest.xml +8 −0 Original line number Diff line number Diff line Loading @@ -94,6 +94,14 @@ </intent-filter> </receiver> <receiver android:name="com.android.server.devicepolicy.DummyDeviceAdmins$AdminNoPerm"> <meta-data android:name="android.app.device_admin" android:resource="@xml/device_admin_sample" /> <intent-filter> <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" /> </intent-filter> </receiver> </application> <instrumentation Loading services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +30 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ import android.content.BroadcastReceiver; 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; Loading Loading @@ -85,6 +87,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID); setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID); setUpPackageManagerForAdmin(admin3, DpmMockContext.CALLER_UID); setUpPackageManagerForAdmin(adminNoPerm, DpmMockContext.CALLER_UID); setUpUserManager(); } Loading Loading @@ -336,6 +339,33 @@ public class DevicePolicyManagerTest extends DpmTestBase { } } /** * 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} Loading services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java +30 −18 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ public abstract class DpmTestBase extends AndroidTestCase { public ComponentName admin1; public ComponentName admin2; public ComponentName admin3; public ComponentName adminNoPerm; @Override protected void setUp() throws Exception { Loading @@ -56,6 +57,7 @@ public abstract class DpmTestBase extends AndroidTestCase { 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 Loading @@ -67,11 +69,36 @@ public abstract class DpmTestBase extends AndroidTestCase { 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(). Loading @@ -88,7 +115,7 @@ public abstract class DpmTestBase extends AndroidTestCase { 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), Loading @@ -96,21 +123,6 @@ public abstract class DpmTestBase extends AndroidTestCase { | 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( Loading @@ -118,7 +130,7 @@ public abstract class DpmTestBase extends AndroidTestCase { admin.getPackageName(), 0)); assertTrue(pi.applicationInfo.flags != 0); pi.applicationInfo.uid = packageUid; pi.applicationInfo = ai; doReturn(pi).when(mMockContext.ipackageManager).getPackageInfo( eq(admin.getPackageName()), Loading services/tests/servicestests/src/com/android/server/devicepolicy/DummyDeviceAdmins.java +2 −0 Original line number Diff line number Diff line Loading @@ -24,4 +24,6 @@ public class DummyDeviceAdmins { } public static class Admin3 extends DeviceAdminReceiver { } public static class AdminNoPerm extends DeviceAdminReceiver { } } Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +20 −4 Original line number Diff line number Diff line Loading @@ -75,6 +75,7 @@ import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.AsyncTask; import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.FileUtils; Loading Loading @@ -1721,7 +1722,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } public DeviceAdminInfo findAdmin(ComponentName adminName, int userHandle) { public DeviceAdminInfo findAdmin(ComponentName adminName, int userHandle, boolean throwForMissiongPermission) { if (!mHasFeature) { return null; } Loading @@ -1736,8 +1738,20 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { throw new IllegalArgumentException("Unknown admin: " + adminName); } final ResolveInfo ri = infos.get(0); if (!permission.BIND_DEVICE_ADMIN.equals(ri.activityInfo.permission)) { final String message = "DeviceAdminReceiver " + adminName + " must be protected with" + permission.BIND_DEVICE_ADMIN; Slog.w(LOG_TAG, message); if (throwForMissiongPermission && ri.activityInfo.applicationInfo.targetSdkVersion > Build.VERSION_CODES.M) { throw new IllegalArgumentException(message); } } try { return new DeviceAdminInfo(mContext, infos.get(0)); return new DeviceAdminInfo(mContext, ri); } catch (XmlPullParserException e) { Slog.w(LOG_TAG, "Bad device admin requested for user=" + userHandle + ": " + adminName, e); Loading Loading @@ -1928,7 +1942,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { String name = parser.getAttributeValue(null, "name"); try { DeviceAdminInfo dai = findAdmin( ComponentName.unflattenFromString(name), userHandle); ComponentName.unflattenFromString(name), userHandle, /* throwForMissionPermission= */ false); if (VERBOSE_LOG && (UserHandle.getUserId(dai.getActivityInfo().applicationInfo.uid) != userHandle)) { Loading Loading @@ -2319,7 +2334,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { enforceCrossUserPermission(userHandle); DevicePolicyData policy = getUserData(userHandle); DeviceAdminInfo info = findAdmin(adminReceiver, userHandle); DeviceAdminInfo info = findAdmin(adminReceiver, userHandle, /* throwForMissionPermission= */ true); if (info == null) { throw new IllegalArgumentException("Bad admin: " + adminReceiver); } Loading
services/tests/servicestests/AndroidManifest.xml +8 −0 Original line number Diff line number Diff line Loading @@ -94,6 +94,14 @@ </intent-filter> </receiver> <receiver android:name="com.android.server.devicepolicy.DummyDeviceAdmins$AdminNoPerm"> <meta-data android:name="android.app.device_admin" android:resource="@xml/device_admin_sample" /> <intent-filter> <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" /> </intent-filter> </receiver> </application> <instrumentation Loading
services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +30 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ import android.content.BroadcastReceiver; 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; Loading Loading @@ -85,6 +87,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID); setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID); setUpPackageManagerForAdmin(admin3, DpmMockContext.CALLER_UID); setUpPackageManagerForAdmin(adminNoPerm, DpmMockContext.CALLER_UID); setUpUserManager(); } Loading Loading @@ -336,6 +339,33 @@ public class DevicePolicyManagerTest extends DpmTestBase { } } /** * 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} Loading
services/tests/servicestests/src/com/android/server/devicepolicy/DpmTestBase.java +30 −18 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ public abstract class DpmTestBase extends AndroidTestCase { public ComponentName admin1; public ComponentName admin2; public ComponentName admin3; public ComponentName adminNoPerm; @Override protected void setUp() throws Exception { Loading @@ -56,6 +57,7 @@ public abstract class DpmTestBase extends AndroidTestCase { 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 Loading @@ -67,11 +69,36 @@ public abstract class DpmTestBase extends AndroidTestCase { 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(). Loading @@ -88,7 +115,7 @@ public abstract class DpmTestBase extends AndroidTestCase { 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), Loading @@ -96,21 +123,6 @@ public abstract class DpmTestBase extends AndroidTestCase { | 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( Loading @@ -118,7 +130,7 @@ public abstract class DpmTestBase extends AndroidTestCase { admin.getPackageName(), 0)); assertTrue(pi.applicationInfo.flags != 0); pi.applicationInfo.uid = packageUid; pi.applicationInfo = ai; doReturn(pi).when(mMockContext.ipackageManager).getPackageInfo( eq(admin.getPackageName()), Loading
services/tests/servicestests/src/com/android/server/devicepolicy/DummyDeviceAdmins.java +2 −0 Original line number Diff line number Diff line Loading @@ -24,4 +24,6 @@ public class DummyDeviceAdmins { } public static class Admin3 extends DeviceAdminReceiver { } public static class AdminNoPerm extends DeviceAdminReceiver { } }