diff options
3 files changed, 56 insertions, 2 deletions
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index c95e0113e801..b8b9793c39a0 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -6317,7 +6317,7 @@ public class DevicePolicyManager { * @see #setPermissionGrantState(ComponentName, String, String, int) * @see PackageManager#checkPermission(String, String) */ - public int getPermissionGrantState(@NonNull ComponentName admin, String packageName, + public int getPermissionGrantState(@Nullable ComponentName admin, String packageName, String permission) { throwIfParentInstance("getPermissionGrantState"); try { diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index ec5491d725cd..8d8934e4ef09 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -6783,6 +6783,18 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { enforceManageUsers(); } + private void enforceProfileOwnerOrSystemUser(ComponentName admin) { + synchronized (this) { + if (getActiveAdminWithPolicyForUidLocked(admin, + DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, mInjector.binderGetCallingUid()) + != null) { + return; + } + } + Preconditions.checkState(isCallerWithSystemUid(), + "Only profile owner, device owner and system may call this method."); + } + private void ensureCallerPackage(@Nullable String packageName) { if (packageName == null) { Preconditions.checkState(isCallerWithSystemUid(), @@ -8913,8 +8925,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { PackageManager packageManager = mInjector.getPackageManager(); UserHandle user = mInjector.binderGetCallingUserHandle(); + enforceProfileOwnerOrSystemUser(admin); synchronized (this) { - getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); long ident = mInjector.binderClearCallingIdentity(); try { int granted = mIPackageManager.checkPermission(permission, 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 c3eb09d6af0d..f1eaf9b5eda3 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -3207,6 +3207,48 @@ public class DevicePolicyManagerTest extends DpmTestBase { } } + public void testGetPermissionGrantState() throws Exception { + final String permission = "some.permission"; + final String app1 = "com.example.app1"; + final String app2 = "com.example.app2"; + + when(mContext.ipackageManager.checkPermission(eq(permission), eq(app1), anyInt())) + .thenReturn(PackageManager.PERMISSION_GRANTED); + doReturn(PackageManager.FLAG_PERMISSION_POLICY_FIXED).when(mContext.packageManager) + .getPermissionFlags(permission, app1, UserHandle.SYSTEM); + when(mContext.packageManager.getPermissionFlags(permission, app1, + UserHandle.of(DpmMockContext.CALLER_USER_HANDLE))) + .thenReturn(PackageManager.FLAG_PERMISSION_POLICY_FIXED); + when(mContext.ipackageManager.checkPermission(eq(permission), eq(app2), anyInt())) + .thenReturn(PackageManager.PERMISSION_DENIED); + doReturn(0).when(mContext.packageManager).getPermissionFlags(permission, app2, + UserHandle.SYSTEM); + when(mContext.packageManager.getPermissionFlags(permission, app2, + UserHandle.of(DpmMockContext.CALLER_USER_HANDLE))).thenReturn(0); + + // System can retrieve permission grant state. + mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; + assertEquals(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED, + dpm.getPermissionGrantState(null, app1, permission)); + assertEquals(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT, + dpm.getPermissionGrantState(null, app2, permission)); + + // A regular app cannot retrieve permission grant state. + mMockContext.binder.callingUid = DpmMockContext.CALLER_UID; + try { + dpm.getPermissionGrantState(null, app1, permission); + fail("Didn't throw IllegalStateException"); + } catch (IllegalStateException expected) { + } + + // Profile owner can retrieve permission grant state. + setAsProfileOwner(admin1); + assertEquals(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED, + dpm.getPermissionGrantState(admin1, app1, permission)); + assertEquals(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT, + dpm.getPermissionGrantState(admin1, app2, permission)); + } + private void setUserSetupCompleteForUser(boolean isUserSetupComplete, int userhandle) { when(mContext.settings.settingsSecureGetIntForUser(Settings.Secure.USER_SETUP_COMPLETE, 0, userhandle)).thenReturn(isUserSetupComplete ? 1 : 0); |