From e02d4e358bded3ee13ebe28d31cdd1df2026986c Mon Sep 17 00:00:00 2001 From: Eran Messeri Date: Mon, 1 Feb 2021 16:50:05 +0000 Subject: [PATCH] Cache permission policy Since the Permission Controller calls into DPM, to avoid a potential circular dependency (where the DPMS holds a lock while the Permission Controller calls it), cache the permission policy. Bug: 158735247 Test: atest com.android.cts.devicepolicy.MixedProfileOwnerTest#testDelegation com.android.cts.devicepolicy.MixedDeviceOwnerTest#testDelegation com.android.cts.devicepolicy.MixedManagedProfileOwnerTest#testDelegation Test: atest com.android.cts.devicepolicy.MixedProfileOwnerTest#testPermissionAppUpdate com.android.cts.devicepolicy.MixedProfileOwnerTest#testPermissionPolicy com.android.cts.devicepolicy.MixedDeviceOwnerTest#testPermissionAppUpdate com.android.cts.devicepolicy.MixedDeviceOwnerTest#testPermissionPolicy com.android.cts.devicepolicy.MixedManagedProfileOwnerTest#testPermissionAppUpdate com.android.cts.devicepolicy.MixedManagedProfileOwnerTest#testPermissionPolicy Change-Id: I6cfc027b063f43053d1ff4cc42d37935491064ff --- .../android/app/admin/DevicePolicyCache.java | 11 ++++++++++ .../devicepolicy/DevicePolicyCacheImpl.java | 20 +++++++++++++++++++ .../DevicePolicyManagerService.java | 19 ++++++++++++------ 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/core/java/android/app/admin/DevicePolicyCache.java b/core/java/android/app/admin/DevicePolicyCache.java index 15ff531b445d9..8b0c7061925f0 100644 --- a/core/java/android/app/admin/DevicePolicyCache.java +++ b/core/java/android/app/admin/DevicePolicyCache.java @@ -50,6 +50,12 @@ public abstract class DevicePolicyCache { */ public abstract int getPasswordQuality(@UserIdInt int userHandle); + /** + * Caches {@link DevicePolicyManager#getPermissionPolicy(android.content.ComponentName)} of + * the given user. + */ + public abstract int getPermissionPolicy(@UserIdInt int userHandle); + /** * Empty implementation. */ @@ -66,5 +72,10 @@ public abstract class DevicePolicyCache { public int getPasswordQuality(int userHandle) { return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; } + + @Override + public int getPermissionPolicy(int userHandle) { + return DevicePolicyManager.PERMISSION_POLICY_PROMPT; + } } } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java index 15bc93e0419a1..8b2beb22bead6 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyCacheImpl.java @@ -43,10 +43,14 @@ public class DevicePolicyCacheImpl extends DevicePolicyCache { @GuardedBy("mLock") private final SparseIntArray mPasswordQuality = new SparseIntArray(); + @GuardedBy("mLock") + private final SparseIntArray mPermissionPolicy = new SparseIntArray(); + public void onUserRemoved(int userHandle) { synchronized (mLock) { mScreenCaptureDisabled.delete(userHandle); mPasswordQuality.delete(userHandle); + mPermissionPolicy.delete(userHandle); } } @@ -78,12 +82,28 @@ public class DevicePolicyCacheImpl extends DevicePolicyCache { } } + @Override + public int getPermissionPolicy(@UserIdInt int userHandle) { + synchronized (mLock) { + return mPermissionPolicy.get(userHandle, + DevicePolicyManager.PERMISSION_POLICY_PROMPT); + } + } + + /** Update the permission policy for the given user. */ + public void setPermissionPolicy(@UserIdInt int userHandle, int policy) { + synchronized (mLock) { + mPermissionPolicy.put(userHandle, policy); + } + } + /** Dump content */ public void dump(IndentingPrintWriter pw) { pw.println("Device policy cache:"); pw.increaseIndent(); pw.println("Screen capture disabled: " + mScreenCaptureDisabled.toString()); pw.println("Password quality: " + mPasswordQuality.toString()); + pw.println("Permission policy: " + mPermissionPolicy.toString()); pw.decreaseIndent(); } } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index c3bb757634c28..74b88f1c59d7e 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -2942,6 +2942,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { // reading the value during user switch, due to onStartUser() being asynchronous. updatePasswordQualityCacheForUserGroup( userId == UserHandle.USER_SYSTEM ? UserHandle.USER_ALL : userId); + updatePermissionPolicyCache(userId); startOwnerService(userId, "start-user"); } @@ -12498,11 +12499,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { || (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_PERMISSION_GRANT))); checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_PERMISSION_POLICY); + final int forUser = caller.getUserId(); synchronized (getLockObject()) { - DevicePolicyData userPolicy = getUserData(caller.getUserId()); + DevicePolicyData userPolicy = getUserData(forUser); if (userPolicy.mPermissionPolicy != policy) { userPolicy.mPermissionPolicy = policy; - saveSettingsLocked(caller.getUserId()); + mPolicyCache.setPermissionPolicy(forUser, policy); + saveSettingsLocked(forUser); } } DevicePolicyEventLogger @@ -12513,13 +12516,17 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { .write(); } + private void updatePermissionPolicyCache(int userId) { + synchronized (getLockObject()) { + DevicePolicyData userPolicy = getUserData(userId); + mPolicyCache.setPermissionPolicy(userId, userPolicy.mPermissionPolicy); + } + } + @Override public int getPermissionPolicy(ComponentName admin) throws RemoteException { int userId = UserHandle.getCallingUserId(); - synchronized (getLockObject()) { - DevicePolicyData userPolicy = getUserData(userId); - return userPolicy.mPermissionPolicy; - } + return mPolicyCache.getPermissionPolicy(userId); } @Override