diff options
2 files changed, 92 insertions, 67 deletions
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 7e5d5aae06e4..44cf9321e717 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -160,6 +160,7 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; +import static android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT; import static android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED; import static android.app.admin.DevicePolicyManager.PERSONAL_APPS_NOT_SUSPENDED; import static android.app.admin.DevicePolicyManager.PERSONAL_APPS_SUSPENDED_EXPLICITLY; @@ -533,7 +534,6 @@ import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; @@ -1186,9 +1186,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // Resume logging if all remaining users are affiliated. maybeResumeDeviceWideLoggingLocked(); } - if (isPolicyEngineForFinanceFlagEnabled() || isPermissionCheckFlagEnabled()) { - mDevicePolicyEngine.handleUserRemoved(userHandle); - } + } + if (isPolicyEngineForFinanceFlagEnabled() || isPermissionCheckFlagEnabled()) { + mDevicePolicyEngine.handleUserRemoved(userHandle); } } else if (Intent.ACTION_USER_STARTED.equals(action)) { sendDeviceOwnerUserCommand(DeviceAdminReceiver.ACTION_USER_STARTED, userHandle); @@ -4157,8 +4157,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_REMOVE_ACTIVE_ADMIN); enforceUserUnlocked(userHandle); + ActiveAdmin admin; synchronized (getLockObject()) { - ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver, userHandle); + admin = getActiveAdminUncheckedLocked(adminReceiver, userHandle); if (admin == null) { return; } @@ -4169,14 +4170,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { + adminReceiver); return; } - mInjector.binderWithCleanCallingIdentity(() -> removeActiveAdminLocked(adminReceiver, userHandle)); - if (isPolicyEngineForFinanceFlagEnabled() || isPermissionCheckFlagEnabled()) { - mDevicePolicyEngine.removePoliciesForAdmin( - EnforcingAdmin.createEnterpriseEnforcingAdmin( - adminReceiver, userHandle, admin)); - } + } + if (isPolicyEngineForFinanceFlagEnabled() || isPermissionCheckFlagEnabled()) { + mDevicePolicyEngine.removePoliciesForAdmin( + EnforcingAdmin.createEnterpriseEnforcingAdmin( + adminReceiver, userHandle, admin)); } } @@ -16661,8 +16661,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { enforcePermissionGrantStateOnFinancedDevice(packageName, permission); } } + EnforcingAdmin enforcingAdmin; if (isPermissionCheckFlagEnabled()) { - EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin( + enforcingAdmin = enforcePermissionAndGetEnforcingAdmin( admin, MANAGE_DEVICE_POLICY_RUNTIME_PERMISSIONS, callerPackage, @@ -16686,17 +16687,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { callback.sendResult(null); return; } - // TODO(b/266924257): decide how to handle the internal state if the package doesn't - // exist, or the permission isn't requested by the app, because we could end up with - // inconsistent state between the policy engine and package manager. Also a package - // might get removed or has it's permission updated after we've set the policy. - mDevicePolicyEngine.setLocalPolicy( - PolicyDefinition.PERMISSION_GRANT(packageName, permission), - enforcingAdmin, - new IntegerPolicyValue(grantState), - caller.getUserId()); - // TODO: update javadoc to reflect that callback no longer return success/failure - callback.sendResult(Bundle.EMPTY); } else { Preconditions.checkCallAuthorization((caller.hasAdminComponent() && (isProfileOwner(caller) || isDefaultDeviceOwner(caller) @@ -16704,51 +16694,81 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { || (caller.hasPackage() && isCallerDelegate(caller, DELEGATION_PERMISSION_GRANT))); synchronized (getLockObject()) { - long ident = mInjector.binderClearCallingIdentity(); - try { - boolean isPostQAdmin = getTargetSdk(caller.getPackageName(), caller.getUserId()) - >= android.os.Build.VERSION_CODES.Q; - if (!isPostQAdmin) { - // Legacy admins assume that they cannot control pre-M apps - if (getTargetSdk(packageName, caller.getUserId()) - < android.os.Build.VERSION_CODES.M) { + long ident = mInjector.binderClearCallingIdentity(); + try { + boolean isPostQAdmin = getTargetSdk(caller.getPackageName(), caller.getUserId()) + >= android.os.Build.VERSION_CODES.Q; + if (!isPostQAdmin) { + // Legacy admins assume that they cannot control pre-M apps + if (getTargetSdk(packageName, caller.getUserId()) + < android.os.Build.VERSION_CODES.M) { + callback.sendResult(null); + return; + } + } + if (!isRuntimePermission(permission)) { callback.sendResult(null); return; } - } - if (!isRuntimePermission(permission)) { + } catch (SecurityException e) { + Slogf.e(LOG_TAG, "Could not set permission grant state", e); callback.sendResult(null); - return; + } finally { + mInjector.binderRestoreCallingIdentity(ident); } - if (grantState == PERMISSION_GRANT_STATE_GRANTED - || grantState == DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED - || grantState == DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT) { - AdminPermissionControlParams permissionParams = - new AdminPermissionControlParams(packageName, permission, - grantState, - canAdminGrantSensorsPermissions()); - mInjector.getPermissionControllerManager(caller.getUserHandle()) - .setRuntimePermissionGrantStateByDeviceAdmin( - caller.getPackageName(), - permissionParams, mContext.getMainExecutor(), - (permissionWasSet) -> { - if (isPostQAdmin && !permissionWasSet) { - callback.sendResult(null); - return; - } - - DevicePolicyEventLogger - .createEvent(DevicePolicyEnums - .SET_PERMISSION_GRANT_STATE) - .setAdmin(caller.getPackageName()) - .setStrings(permission) - .setInt(grantState) - .setBoolean( - /* isDelegate */ isCallerDelegate(caller)) - .write(); - - callback.sendResult(Bundle.EMPTY); - }); + } + } + // TODO(b/278710449): enable when we stop policy enforecer callback from blocking the main + // thread + if (false) { + // TODO(b/266924257): decide how to handle the internal state if the package doesn't + // exist, or the permission isn't requested by the app, because we could end up with + // inconsistent state between the policy engine and package manager. Also a package + // might get removed or has it's permission updated after we've set the policy. + if (grantState == PERMISSION_GRANT_STATE_DEFAULT) { + mDevicePolicyEngine.removeLocalPolicy( + PolicyDefinition.PERMISSION_GRANT(packageName, permission), + enforcingAdmin, + caller.getUserId()); + } else { + mDevicePolicyEngine.setLocalPolicy( + PolicyDefinition.PERMISSION_GRANT(packageName, permission), + enforcingAdmin, + new IntegerPolicyValue(grantState), + caller.getUserId()); + } + int newState = mInjector.binderWithCleanCallingIdentity(() -> + getPermissionGrantStateForUser( + packageName, permission, caller, caller.getUserId())); + if (newState == grantState) { + callback.sendResult(Bundle.EMPTY); + } else { + callback.sendResult(null); + } + } else { + synchronized (getLockObject()) { + long ident = mInjector.binderClearCallingIdentity(); + try { + boolean isPostQAdmin = getTargetSdk(caller.getPackageName(), caller.getUserId()) + >= android.os.Build.VERSION_CODES.Q; + if (grantState == PERMISSION_GRANT_STATE_GRANTED + || grantState == DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED + || grantState == DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT) { + AdminPermissionControlParams permissionParams = + new AdminPermissionControlParams(packageName, permission, + grantState, + canAdminGrantSensorsPermissions()); + mInjector.getPermissionControllerManager(caller.getUserHandle()) + .setRuntimePermissionGrantStateByDeviceAdmin( + caller.getPackageName(), + permissionParams, mContext.getMainExecutor(), + (permissionWasSet) -> { + if (isPostQAdmin && !permissionWasSet) { + callback.sendResult(null); + return; + } + callback.sendResult(Bundle.EMPTY); + }); } } catch (SecurityException e) { Slogf.e(LOG_TAG, "Could not set permission grant state", e); @@ -16759,6 +16779,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } } + DevicePolicyEventLogger.createEvent(DevicePolicyEnums.SET_PERMISSION_GRANT_STATE) + .setAdmin(caller.getPackageName()) + .setStrings(permission) + .setInt(grantState) + .setBoolean(/* isDelegate */ isCallerDelegate(caller)) + .write(); } private static final List<String> SENSOR_PERMISSIONS = new ArrayList<>(); @@ -16822,10 +16848,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (isFinancedDeviceOwner(caller)) { enforcePermissionGrantStateOnFinancedDevice(packageName, permission); } - return mInjector.binderWithCleanCallingIdentity(() -> { - return getPermissionGrantStateForUser( - packageName, permission, caller, caller.getUserId()); - }); + return mInjector.binderWithCleanCallingIdentity(() -> getPermissionGrantStateForUser( + packageName, permission, caller, caller.getUserId())); } } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java index d65d366e4476..12a8a75317e5 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java @@ -84,6 +84,7 @@ final class PolicyEnforcerCallbacks { ? DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT : grantState; + // TODO(b/278710449): stop blocking in the main thread BlockingCallback callback = new BlockingCallback(); // TODO: remove canAdminGrantSensorPermissions once we expose a new method in // permissionController that doesn't need it. |