diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java index 7eeb51c842003..d4f4b72fbb2bd 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java @@ -23,7 +23,6 @@ import static android.app.admin.PolicyUpdateResult.RESULT_FAILURE_HARDWARE_LIMIT import static android.app.admin.PolicyUpdateResult.RESULT_POLICY_CLEARED; import static android.app.admin.PolicyUpdateResult.RESULT_POLICY_SET; import static android.content.pm.UserProperties.INHERIT_DEVICE_POLICY_FROM_PARENT; -import static android.provider.DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER; import android.Manifest; import android.annotation.NonNull; @@ -47,7 +46,6 @@ import android.os.Bundle; import android.os.Environment; import android.os.UserHandle; import android.os.UserManager; -import android.provider.DeviceConfig; import android.telephony.TelephonyManager; import android.util.AtomicFile; import android.util.Log; @@ -86,9 +84,6 @@ final class DevicePolicyEngine { DevicePolicyIdentifiers.getIdentifierForUserRestriction( UserManager.DISALLOW_CELLULAR_2G); - private static final String ENABLE_COEXISTENCE_FLAG = "enable_coexistence"; - private static final boolean DEFAULT_ENABLE_COEXISTENCE_FLAG = true; - private final Context mContext; private final UserManager mUserManager; @@ -771,28 +766,31 @@ final class DevicePolicyEngine { Intent intent = new Intent(PolicyUpdateReceiver.ACTION_DEVICE_POLICY_SET_RESULT); intent.setPackage(admin.getPackageName()); - List receivers = mContext.getPackageManager().queryBroadcastReceiversAsUser( - intent, - PackageManager.ResolveInfoFlags.of(PackageManager.GET_RECEIVERS), - admin.getUserId()); - if (receivers.isEmpty()) { - Log.i(TAG, "Couldn't find any receivers that handle ACTION_DEVICE_POLICY_SET_RESULT" - + "in package " + admin.getPackageName()); - return; - } + Binder.withCleanCallingIdentity(() -> { + List receivers = + mContext.getPackageManager().queryBroadcastReceiversAsUser( + intent, + PackageManager.ResolveInfoFlags.of(PackageManager.GET_RECEIVERS), + admin.getUserId()); + if (receivers.isEmpty()) { + Log.i(TAG, "Couldn't find any receivers that handle ACTION_DEVICE_POLICY_SET_RESULT" + + "in package " + admin.getPackageName()); + return; + } - Bundle extras = new Bundle(); - policyDefinition.getPolicyKey().writeToBundle(extras); - extras.putInt( - EXTRA_POLICY_TARGET_USER_ID, - getTargetUser(admin.getUserId(), userId)); - extras.putInt( - EXTRA_POLICY_UPDATE_RESULT_KEY, - result); + Bundle extras = new Bundle(); + policyDefinition.getPolicyKey().writeToBundle(extras); + extras.putInt( + EXTRA_POLICY_TARGET_USER_ID, + getTargetUser(admin.getUserId(), userId)); + extras.putInt( + EXTRA_POLICY_UPDATE_RESULT_KEY, + result); - intent.putExtras(extras); + intent.putExtras(extras); - maybeSendIntentToAdminReceivers(intent, UserHandle.of(admin.getUserId()), receivers); + maybeSendIntentToAdminReceivers(intent, UserHandle.of(admin.getUserId()), receivers); + }); } // TODO(b/261430877): Finalise the decision on which admins to send the updates to. @@ -821,27 +819,30 @@ final class DevicePolicyEngine { Intent intent = new Intent(PolicyUpdateReceiver.ACTION_DEVICE_POLICY_CHANGED); intent.setPackage(admin.getPackageName()); - List receivers = mContext.getPackageManager().queryBroadcastReceiversAsUser( - intent, - PackageManager.ResolveInfoFlags.of(PackageManager.GET_RECEIVERS), - admin.getUserId()); - if (receivers.isEmpty()) { - Log.i(TAG, "Couldn't find any receivers that handle ACTION_DEVICE_POLICY_CHANGED" - + "in package " + admin.getPackageName()); - return; - } + Binder.withCleanCallingIdentity(() -> { + List receivers = + mContext.getPackageManager().queryBroadcastReceiversAsUser( + intent, + PackageManager.ResolveInfoFlags.of(PackageManager.GET_RECEIVERS), + admin.getUserId()); + if (receivers.isEmpty()) { + Log.i(TAG, "Couldn't find any receivers that handle ACTION_DEVICE_POLICY_CHANGED" + + "in package " + admin.getPackageName()); + return; + } - Bundle extras = new Bundle(); - policyDefinition.getPolicyKey().writeToBundle(extras); - extras.putInt( - EXTRA_POLICY_TARGET_USER_ID, - getTargetUser(admin.getUserId(), userId)); - extras.putInt(EXTRA_POLICY_UPDATE_RESULT_KEY, reason); - intent.putExtras(extras); - intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); + Bundle extras = new Bundle(); + policyDefinition.getPolicyKey().writeToBundle(extras); + extras.putInt( + EXTRA_POLICY_TARGET_USER_ID, + getTargetUser(admin.getUserId(), userId)); + extras.putInt(EXTRA_POLICY_UPDATE_RESULT_KEY, reason); + intent.putExtras(extras); + intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); - maybeSendIntentToAdminReceivers( - intent, UserHandle.of(admin.getUserId()), receivers); + maybeSendIntentToAdminReceivers( + intent, UserHandle.of(admin.getUserId()), receivers); + }); } private void maybeSendIntentToAdminReceivers( @@ -1146,38 +1147,6 @@ final class DevicePolicyEngine { return mEnforcingAdmins.size() > 0; } - /** - * Returns {@code true} if the coexistence flag is enabled or: - *
    - *
  • If the provided package is an admin with existing policies - *
  • A new admin and no other admin have policies set - *
  • More than one admin have policies set - */ - boolean canAdminAddPolicies(String packageName, int userId) { - if (isCoexistenceFlagEnabled()) { - return true; - } - - if (mEnforcingAdmins.contains(userId) - && mEnforcingAdmins.get(userId).stream().anyMatch(admin -> - admin.getPackageName().equals(packageName))) { - return true; - } - - int numOfEnforcingAdmins = 0; - for (int i = 0; i < mEnforcingAdmins.size(); i++) { - numOfEnforcingAdmins += mEnforcingAdmins.get(i).size(); - } - return numOfEnforcingAdmins == 0 || numOfEnforcingAdmins > 1; - } - - private boolean isCoexistenceFlagEnabled() { - return DeviceConfig.getBoolean( - NAMESPACE_DEVICE_POLICY_MANAGER, - ENABLE_COEXISTENCE_FLAG, - DEFAULT_ENABLE_COEXISTENCE_FLAG); - } - private boolean checkFor2gFailure(@NonNull PolicyDefinition policyDefinition, @NonNull EnforcingAdmin enforcingAdmin) { if (!policyDefinition.getPolicyKey().getIdentifier().equals( diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 39337660c55c1..7388c766f1f2f 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -836,18 +836,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { + "management app's authentication policy"; private static final String NOT_SYSTEM_CALLER_MSG = "Only the system can %s"; - // ENABLE_DEVICE_POLICY_ENGINE_FLAG must be enabled before this could be enabled. private static final String PERMISSION_BASED_ACCESS_EXPERIMENT_FLAG = "enable_permission_based_access"; private static final boolean DEFAULT_VALUE_PERMISSION_BASED_ACCESS_FLAG = false; - // This must be enabled before PERMISSION_BASED_ACCESS_EXPERIMENT_FLAG is enabled, the reason - // we're not just relying on PERMISSION_BASED_ACCESS_EXPERIMENT_FLAG to enable the policy engine - // is that we might want to enable it before the permission changes are ready if we want to test - // it on DPCs. - // Once this is enabled, it can no longer be disabled in production - private static final String ENABLE_DEVICE_POLICY_ENGINE_FLAG = "enable_device_policy_engine"; - private static final boolean DEFAULT_ENABLE_DEVICE_POLICY_ENGINE_FLAG = false; + private static final String ENABLE_DEVICE_POLICY_ENGINE_FOR_FINANCE_FLAG = + "enable_device_policy_engine"; + private static final boolean DEFAULT_ENABLE_DEVICE_POLICY_ENGINE_FOR_FINANCE_FLAG = false; // TODO(b/265683382) remove the flag after rollout. private static final String KEEP_PROFILES_RUNNING_FLAG = "enable_keep_profiles_running"; @@ -1414,10 +1409,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { && (owner.getPackageName().equals(packageName))) { startOwnerService(userHandle, "package-broadcast"); } - if (shouldMigrateToDevicePolicyEngine()) { - migratePoliciesToDevicePolicyEngine(); - } - if (isDevicePolicyEngineEnabled()) { + if (isPermissionCheckFlagEnabled()) { mDevicePolicyEngine.handlePackageChanged(packageName, userHandle); } // Persist updates if the removed package was an admin or delegate. @@ -2121,7 +2113,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mUserManagerInternal.addUserLifecycleListener(new UserLifecycleListener()); mDeviceManagementResourcesProvider.load(); - if (isDevicePolicyEngineEnabled()) { + if (isPermissionCheckFlagEnabled()) { mDevicePolicyEngine.load(); } @@ -2617,7 +2609,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ActiveAdmin profileOwner, boolean newOwner) { if (newOwner || mInjector.settingsSecureGetIntForUser( Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED, 0, userId) != 0) { - if (isDevicePolicyEngineEnabled()) { + if (isPermissionCheckFlagEnabled()) { mDevicePolicyEngine.setLocalPolicy( PolicyDefinition.getPolicyDefinitionForUserRestriction( UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES), @@ -2645,7 +2637,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (defaultRestrictions.equals(admin.defaultEnabledRestrictionsAlreadySet)) { return; // The same set of default restrictions has been already applied. } - if (isDevicePolicyEngineEnabled()) { + if (isPermissionCheckFlagEnabled()) { for (String restriction : defaultRestrictions) { mDevicePolicyEngine.setLocalPolicy( PolicyDefinition.getPolicyDefinitionForUserRestriction(restriction), @@ -3561,7 +3553,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } startOwnerService(userId, "start-user"); - if (isDevicePolicyEngineEnabled()) { + if (isPermissionCheckFlagEnabled()) { mDevicePolicyEngine.handleStartUser(userId); } } @@ -3588,7 +3580,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { void handleUnlockUser(int userId) { startOwnerService(userId, "unlock-user"); - if (isDevicePolicyEngineEnabled()) { + if (isPermissionCheckFlagEnabled()) { mDevicePolicyEngine.handleUnlockUser(userId); } } @@ -3600,7 +3592,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { void handleStopUser(int userId) { updateNetworkPreferenceForUser(userId, List.of(PreferentialNetworkServiceConfig.DEFAULT)); mDeviceAdminServiceController.stopServicesForUser(userId, /* actionForLog= */ "stop-user"); - if (isDevicePolicyEngineEnabled()) { + if (isPermissionCheckFlagEnabled()) { mDevicePolicyEngine.handleStopUser(userId); } } @@ -3726,11 +3718,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { synchronized (getLockObject()) { checkActiveAdminPrecondition(adminReceiver, info, policy); mInjector.binderWithCleanCallingIdentity(() -> { - if (!canAddActiveAdminIfPolicyEngineEnabled( - adminReceiver.getPackageName(), userHandle)) { - throw new IllegalStateException("Can't add non-coexistable admin."); - } - final ActiveAdmin existingAdmin = getActiveAdminUncheckedLocked(adminReceiver, userHandle); if (!refreshing && existingAdmin != null) { @@ -7482,7 +7469,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return; } CallerIdentity caller; - if (isPermissionCheckFlagEnabled()) { + if (isPolicyEngineForFinanceFlagEnabled()) { caller = getCallerIdentity(callerPackageName); } else { caller = getCallerIdentity(); @@ -7491,7 +7478,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { boolean calledByProfileOwnerOnOrgOwnedDevice = isProfileOwnerOfOrganizationOwnedDevice(caller.getUserId()); - if (isPermissionCheckFlagEnabled()) { + if (isPolicyEngineForFinanceFlagEnabled()) { EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin( /*admin=*/ null, MANAGE_DEVICE_POLICY_WIPE_DATA, @@ -8848,7 +8835,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { caller = getCallerIdentity(who); } - if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) { + if (isPermissionCheckFlagEnabled()) { // The effect of this policy is device-wide. EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin( who, @@ -9192,7 +9179,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { final int userHandle = caller.getUserId(); int affectedUserId = parent ? getProfileParentId(userHandle) : userHandle; synchronized (getLockObject()) { - if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) { + if (isPermissionCheckFlagEnabled()) { // SUPPORT USES_POLICY_DISABLE_KEYGUARD_FEATURES EnforcingAdmin admin = enforcePermissionAndGetEnforcingAdmin( who, MANAGE_DEVICE_POLICY_KEYGUARD, caller.getPackageName(), @@ -9271,7 +9258,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { synchronized (getLockObject()) { if (who != null) { - if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) { + if (isPermissionCheckFlagEnabled()) { EnforcingAdmin admin = getEnforcingAdminForCaller( who, who.getPackageName()); Integer features = mDevicePolicyEngine.getLocalPolicySetByAdmin( @@ -9285,7 +9272,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } - if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) { + if (isPermissionCheckFlagEnabled()) { Integer features = mDevicePolicyEngine.getResolvedPolicy( PolicyDefinition.KEYGUARD_DISABLED_FEATURES, affectedUserId); @@ -11211,14 +11198,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { public void addPersistentPreferredActivity(ComponentName who, String callerPackageName, IntentFilter filter, ComponentName activity) { CallerIdentity caller; - if (isPermissionCheckFlagEnabled()) { + if (isPolicyEngineForFinanceFlagEnabled()) { caller = getCallerIdentity(who, callerPackageName); } else { caller = getCallerIdentity(who); } final int userId = caller.getUserId(); - if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) { + if (isPolicyEngineForFinanceFlagEnabled()) { EnforcingAdmin enforcingAdmin; if (who == null) { enforcingAdmin = enforcePermissionAndGetEnforcingAdmin( @@ -11266,14 +11253,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { public void clearPackagePersistentPreferredActivities(ComponentName who, String callerPackageName, String packageName) { CallerIdentity caller; - if (isPermissionCheckFlagEnabled()) { + if (isPolicyEngineForFinanceFlagEnabled()) { caller = getCallerIdentity(who, callerPackageName); } else { caller = getCallerIdentity(who); } final int userId = caller.getUserId(); - if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) { + if (isPolicyEngineForFinanceFlagEnabled()) { EnforcingAdmin enforcingAdmin; if (who == null) { enforcingAdmin = enforcePermissionAndGetEnforcingAdmin( @@ -11465,7 +11452,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { final CallerIdentity caller = getCallerIdentity(who, callerPackage); checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_APPLICATION_RESTRICTIONS); - if (useDevicePolicyEngine(caller, DELEGATION_APP_RESTRICTIONS)) { + if (isPermissionCheckFlagEnabled()) { EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin( who, MANAGE_DEVICE_POLICY_APP_RESTRICTIONS, @@ -12461,7 +12448,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { final int userId = user.id; - if (isDevicePolicyEngineEnabled()) { + if (isPermissionCheckFlagEnabled()) { mDevicePolicyEngine.handleUserCreated(user); } @@ -12830,7 +12817,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { String packageName) { final CallerIdentity caller = getCallerIdentity(who, callerPackage); - if (useDevicePolicyEngine(caller, DELEGATION_APP_RESTRICTIONS)) { + if (isPermissionCheckFlagEnabled()) { EnforcingAdmin enforcingAdmin = enforceCanQueryAndGetEnforcingAdmin( who, MANAGE_DEVICE_POLICY_APP_RESTRICTIONS, @@ -13059,7 +13046,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { boolean parent) { CallerIdentity caller; - if (isPermissionCheckFlagEnabled()) { + if (isPolicyEngineForFinanceFlagEnabled()) { caller = getCallerIdentity(who, callerPackage); } else { caller = getCallerIdentity(who); @@ -13071,7 +13058,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_USER_RESTRICTION); - if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) { + if (isPolicyEngineForFinanceFlagEnabled()) { int affectedUserId = parent ? getProfileParentId(userId) : userId; EnforcingAdmin admin = enforcePermissionForUserRestriction( who, @@ -13171,14 +13158,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return; } - int userHandle = caller.getUserId(); checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_USER_RESTRICTION); - if (!useDevicePolicyEngine(caller, /* delegateScope= */ null)) { - throw new IllegalStateException("One or more admins are not targeting Android 14."); + if (!isPolicyEngineForFinanceFlagEnabled()) { + throw new IllegalStateException("Feature flag is not enabled."); } + EnforcingAdmin admin = enforcePermissionForUserRestriction( - /*who=*/ null, + /* who= */ null, key, caller.getPackageName(), caller.getUserId() @@ -13211,7 +13198,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } private void saveUserRestrictionsLocked(int userId) { - if (isDevicePolicyEngineEnabled()) { + if (isPolicyEngineForFinanceFlagEnabled()) { // User restrictions are handled in the policy engine return; } @@ -13229,6 +13216,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { * will be the target user id. */ private void pushUserRestrictions(int originatingUserId) { + if (isPolicyEngineForFinanceFlagEnabled()) { + // User restrictions are handled in the policy engine + return; + } final Bundle global; final RestrictionsSet local = new RestrictionsSet(); final boolean isDeviceOwner; @@ -13281,13 +13272,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return null; } CallerIdentity caller; - if (isPermissionCheckFlagEnabled()) { + if (isPolicyEngineForFinanceFlagEnabled()) { caller = getCallerIdentity(who, callerPackage); } else { caller = getCallerIdentity(who); } - if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) { + if (isPolicyEngineForFinanceFlagEnabled()) { EnforcingAdmin admin = getEnforcingAdminForCaller(who, callerPackage); return getUserRestrictionsFromPolicyEngine( admin, @@ -13475,8 +13466,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return null; } final CallerIdentity caller = getCallerIdentity(callerPackage); - if (!useDevicePolicyEngine(caller, /* delegateScope= */ null)) { - throw new IllegalStateException("One or more admins are not targeting Android 14."); + if (!isPolicyEngineForFinanceFlagEnabled()) { + throw new IllegalStateException("Feature flag is not enabled."); } EnforcingAdmin admin = getEnforcingAdminForCaller(/*who=*/ null, caller.getPackageName()); @@ -13544,8 +13535,31 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { Slogf.v(LOG_TAG, "calling pm.setApplicationHiddenSettingAsUser(%s, %b, %d)", packageName, hidden, userId); } - result = mInjector.binderWithCleanCallingIdentity(() -> mIPackageManager - .setApplicationHiddenSettingAsUser(packageName, hidden, userId)); + if (isPermissionCheckFlagEnabled()) { + EnforcingAdmin admin = getEnforcingAdminForCaller(who, callerPackage); + mDevicePolicyEngine.setLocalPolicy( + PolicyDefinition.APPLICATION_HIDDEN(packageName), + admin, + new BooleanPolicyValue(hidden), + userId); + Boolean resolvedPolicy = mDevicePolicyEngine.getResolvedPolicy( + PolicyDefinition.APPLICATION_HIDDEN(packageName), userId); + result = mInjector.binderWithCleanCallingIdentity(() -> { + try { + // This is a best effort to continue returning the same value that was + // returned before the policy engine migration. + return mInjector.getIPackageManager().getPackageInfo( + packageName, MATCH_UNINSTALLED_PACKAGES, userId) != null + && (mIPackageManager.getApplicationHiddenSettingAsUser( + packageName, userId) == hidden); + } catch (RemoteException e) { + return false; + } + }); + } else { + result = mInjector.binderWithCleanCallingIdentity(() -> mIPackageManager + .setApplicationHiddenSettingAsUser(packageName, hidden, userId)); + } } DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_APPLICATION_HIDDEN) @@ -13861,7 +13875,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { boolean uninstallBlocked) { final CallerIdentity caller = getCallerIdentity(who, callerPackage); - if (useDevicePolicyEngine(caller, DELEGATION_BLOCK_UNINSTALL)) { + if (isPolicyEngineForFinanceFlagEnabled()) { EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin( who, MANAGE_DEVICE_POLICY_APPS_CONTROL, @@ -14415,14 +14429,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { throws SecurityException { Objects.requireNonNull(packages, "packages is null"); CallerIdentity caller; - if (isPermissionCheckFlagEnabled()) { + if (isPolicyEngineForFinanceFlagEnabled()) { caller = getCallerIdentity(who, callerPackageName); } else { caller = getCallerIdentity(who); } checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_LOCK_TASK_PACKAGES); - if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) { + if (isPolicyEngineForFinanceFlagEnabled()) { EnforcingAdmin enforcingAdmin; synchronized (getLockObject()) { enforcingAdmin = enforceCanCallLockTaskLocked(who, callerPackageName); @@ -14473,14 +14487,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public String[] getLockTaskPackages(ComponentName who, String callerPackageName) { CallerIdentity caller; - if (isPermissionCheckFlagEnabled()) { + if (isPolicyEngineForFinanceFlagEnabled()) { caller = getCallerIdentity(who, callerPackageName); } else { caller = getCallerIdentity(who); } final int userHandle = caller.getUserId(); - if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) { + if (isPolicyEngineForFinanceFlagEnabled()) { synchronized (getLockObject()) { enforceCanQueryLockTaskLocked(who, caller.getPackageName()); } @@ -14513,8 +14527,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } final int userId = mInjector.userHandleGetCallingUserId(); - // Is it ok to just check that no active policies exist currently? - if (isDevicePolicyEngineFlagEnabled() && mDevicePolicyEngine.hasActivePolicies()) { + if (isPermissionCheckFlagEnabled()) { LockTaskPolicy policy = mDevicePolicyEngine.getResolvedPolicy( PolicyDefinition.LOCK_TASK, userId); if (policy == null) { @@ -14540,7 +14553,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { "Cannot use LOCK_TASK_FEATURE_NOTIFICATIONS without LOCK_TASK_FEATURE_HOME"); CallerIdentity caller; - if (isPermissionCheckFlagEnabled()) { + if (isPolicyEngineForFinanceFlagEnabled()) { caller = getCallerIdentity(who, callerPackageName); } else { caller = getCallerIdentity(who); @@ -14550,7 +14563,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_LOCK_TASK_FEATURES); } - if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) { + if (isPolicyEngineForFinanceFlagEnabled()) { EnforcingAdmin enforcingAdmin; synchronized (getLockObject()) { enforcingAdmin = enforceCanCallLockTaskLocked(who, @@ -14593,14 +14606,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public int getLockTaskFeatures(ComponentName who, String callerPackageName) { CallerIdentity caller; - if (isPermissionCheckFlagEnabled()) { + if (isPolicyEngineForFinanceFlagEnabled()) { caller = getCallerIdentity(who, callerPackageName); } else { caller = getCallerIdentity(who); } final int userHandle = caller.getUserId(); - if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) { + if (isPolicyEngineForFinanceFlagEnabled()) { synchronized (getLockObject()) { enforceCanQueryLockTaskLocked(who, caller.getPackageName()); } @@ -16360,7 +16373,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { enforcePermissionGrantStateOnFinancedDevice(packageName, permission); } } - if (useDevicePolicyEngine(caller, DELEGATION_PERMISSION_GRANT)) { + if (isPermissionCheckFlagEnabled()) { EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin( admin, MANAGE_DEVICE_POLICY_RUNTIME_PERMISSIONS, @@ -17865,11 +17878,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // The removed admin might have disabled camera, so update user // restrictions. pushUserRestrictions(userHandle); - - // The removed admin might've been stopping the migration if it was targeting pre Android U - if (shouldMigrateToDevicePolicyEngine()) { - migratePoliciesToDevicePolicyEngine(); - } } @Override @@ -18547,7 +18555,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } final int userId = caller.getUserId(); - if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) { + if (isPermissionCheckFlagEnabled()) { EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin( admin, MANAGE_DEVICE_POLICY_RESET_PASSWORD, @@ -18611,7 +18619,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { final int userId = caller.getUserId(); boolean result = false; - if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) { + if (isPermissionCheckFlagEnabled()) { EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin( admin, MANAGE_DEVICE_POLICY_RESET_PASSWORD, @@ -18657,7 +18665,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } int userId = caller.getUserId(); - if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) { + if (isPermissionCheckFlagEnabled()) { EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin( admin, MANAGE_DEVICE_POLICY_RESET_PASSWORD, @@ -18709,7 +18717,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { boolean result = false; final String password = passwordOrNull != null ? passwordOrNull : ""; - if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) { + if (isPermissionCheckFlagEnabled()) { EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin( admin, MANAGE_DEVICE_POLICY_RESET_PASSWORD, @@ -19898,7 +19906,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { List packages) { Objects.requireNonNull(packages, "packages is null"); CallerIdentity caller; - if (isPermissionCheckFlagEnabled()) { + if (isPolicyEngineForFinanceFlagEnabled()) { caller = getCallerIdentity(who, callerPackageName); } else { caller = getCallerIdentity(who); @@ -19906,7 +19914,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { checkCanExecuteOrThrowUnsafe( DevicePolicyManager.OPERATION_SET_USER_CONTROL_DISABLED_PACKAGES); - if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) { + if (isPolicyEngineForFinanceFlagEnabled()) { EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin( who, MANAGE_DEVICE_POLICY_APPS_CONTROL, @@ -19980,13 +19988,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { public List getUserControlDisabledPackages(ComponentName who, String callerPackageName) { CallerIdentity caller; - if (isPermissionCheckFlagEnabled()) { + if (isPolicyEngineForFinanceFlagEnabled()) { caller = getCallerIdentity(who, callerPackageName); } else { caller = getCallerIdentity(who); } - if (useDevicePolicyEngine(caller, /* delegateScope= */ null)) { + if (isPolicyEngineForFinanceFlagEnabled()) { enforceCanQuery( MANAGE_DEVICE_POLICY_APPS_CONTROL, caller.getPackageName(), @@ -22069,7 +22077,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } private void handleFinancedDeviceKioskRoleChange() { - if (!isDevicePolicyEngineEnabled()) { + if (!isPermissionCheckFlagEnabled()) { return; } Slog.i(LOG_TAG, "Handling action " + ACTION_DEVICE_FINANCING_STATE_CHANGED); @@ -22848,6 +22856,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { DEFAULT_VALUE_PERMISSION_BASED_ACCESS_FLAG); } + private boolean isPolicyEngineForFinanceFlagEnabled() { + return DeviceConfig.getBoolean( + NAMESPACE_DEVICE_POLICY_MANAGER, + ENABLE_DEVICE_POLICY_ENGINE_FOR_FINANCE_FLAG, + DEFAULT_ENABLE_DEVICE_POLICY_ENGINE_FOR_FINANCE_FLAG); + } + private static boolean isKeepProfilesRunningFlagEnabled() { return DeviceConfig.getBoolean( NAMESPACE_DEVICE_POLICY_MANAGER, @@ -23186,36 +23201,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { }); } - // TODO(b/266808047): handle DeviceAdmin migration when there is no DPCs on the device private boolean shouldMigrateToDevicePolicyEngine() { - return mInjector.binderWithCleanCallingIdentity(() -> { - if (!isDevicePolicyEngineFlagEnabled()) { - return false; - } - if (mOwners.isMigratedToPolicyEngine()) { - return false; - } - // We're only checking if existing DPCs are not targeting U, regardless of what - // DeviceAdmins are targeting, as they can access very limited APIs, and we'll ensure - // that these APIs maintain the current behaviour of strictest applies. - boolean hasDPCs = false; - for (UserInfo userInfo : mUserManager.getUsers()) { - List activeAdmins = getActiveAdmins(userInfo.id); - if (activeAdmins == null) { - continue; - } - for (ComponentName admin : activeAdmins) { - if ((isProfileOwner(admin, userInfo.id) || isDeviceOwner(admin, userInfo.id))) { - if (!mInjector.isChangeEnabled(ENABLE_COEXISTENCE_CHANGE, - admin.getPackageName(), userInfo.id)) { - return false; - } - hasDPCs = true; - } - } - } - return hasDPCs; - }); + return mInjector.binderWithCleanCallingIdentity(() -> + isPermissionCheckFlagEnabled() && !mOwners.isMigratedToPolicyEngine()); } /** @@ -23429,40 +23417,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return admins; } - private boolean useDevicePolicyEngine(CallerIdentity caller, @Nullable String delegateScope) { - return isDevicePolicyEngineEnabled(); - } - - private boolean isDevicePolicyEngineEnabled() { - return isDevicePolicyEngineFlagEnabled() && isPermissionCheckFlagEnabled(); - } - - private boolean isDevicePolicyEngineFlagEnabled() { - return DeviceConfig.getBoolean( - NAMESPACE_DEVICE_POLICY_MANAGER, - ENABLE_DEVICE_POLICY_ENGINE_FLAG, - DEFAULT_ENABLE_DEVICE_POLICY_ENGINE_FLAG); - } - - private boolean hasDPCsNotSupportingCoexistence() { - return mInjector.binderWithCleanCallingIdentity(() -> { - for (UserInfo userInfo : mUserManager.getUsers()) { - List activeAdmins = getActiveAdmins(userInfo.id); - if (activeAdmins == null) { - continue; - } - for (ComponentName admin : activeAdmins) { - if ((isProfileOwner(admin, userInfo.id) || isDeviceOwner(admin, userInfo.id)) - && !mInjector.isChangeEnabled(ENABLE_COEXISTENCE_CHANGE, - admin.getPackageName(), userInfo.id)) { - return true; - } - } - } - return false; - }); - } - // TODO: this can actually accept an EnforcingAdmin that gets created in the permission // check method. private boolean isCallerActiveAdminOrDelegate( @@ -23500,25 +23454,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } - // TODO(b/266808047): This will return false for DeviceAdmins not targetting U, which is - // inconsistent with the migration logic that allows migration with old DeviceAdmins. - private boolean canAddActiveAdminIfPolicyEngineEnabled(String packageName, int userId) { - if (!isDevicePolicyEngineFlagEnabled()) { - return true; - } - if (hasDPCsNotSupportingCoexistence()) { - return true; - } - if (mInjector.isChangeEnabled(ENABLE_COEXISTENCE_CHANGE, packageName, userId)) { - // This will always return true unless we turn off coexistence, in which case it will - // return true if no current admins exist, or more than one admin exist - return mDevicePolicyEngine.canAdminAddPolicies(packageName, userId); - } - // Is it ok to just check that no active policies exist currently, or should we return false - // if the policy engine was ever used? - return !mDevicePolicyEngine.hasActivePolicies(); - } - @Override public boolean isDeviceFinanced(String callerPackageName) { CallerIdentity caller = getCallerIdentity(callerPackageName); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java index 8812c3d3c5576..a15aa53be96ca 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java @@ -226,8 +226,7 @@ final class PolicyDefinition { * Passing in {@code null} for {@code packageName} will return * {@link #GENERIC_APPLICATION_RESTRICTIONS}. */ - static PolicyDefinition APPLICATION_RESTRICTIONS( - String packageName) { + static PolicyDefinition APPLICATION_RESTRICTIONS(String packageName) { if (packageName == null) { return GENERIC_APPLICATION_RESTRICTIONS; } @@ -254,6 +253,34 @@ final class PolicyDefinition { (Integer value, Context context, Integer userId, PolicyKey policyKey) -> true, new IntegerPolicySerializer()); + // This is saved in the static map sPolicyDefinitions so that we're able to reconstruct the + // actual policy with the correct arguments (i.e. packageName) when reading the policies from + // xml. + static PolicyDefinition GENERIC_APPLICATION_HIDDEN = + new PolicyDefinition<>( + new PackagePolicyKey( + DevicePolicyIdentifiers.APPLICATION_HIDDEN_POLICY), + // TODO(b/276713779): Don't need to take in a resolution mechanism since its + // never used, but might need some refactoring to not always assume a non-null + // mechanism. + TRUE_MORE_RESTRICTIVE, + POLICY_FLAG_LOCAL_ONLY_POLICY, + PolicyEnforcerCallbacks::setApplicationHidden, + new BooleanPolicySerializer()); + + /** + * Passing in {@code null} for {@code packageName} will return + * {@link #GENERIC_APPLICATION_HIDDEN}. + */ + static PolicyDefinition APPLICATION_HIDDEN(String packageName) { + if (packageName == null) { + return GENERIC_APPLICATION_HIDDEN; + } + return GENERIC_APPLICATION_HIDDEN.createPolicyDefinition( + new PackagePolicyKey( + DevicePolicyIdentifiers.APPLICATION_HIDDEN_POLICY, packageName)); + } + private static final Map> POLICY_DEFINITIONS = new HashMap<>(); private static Map USER_RESTRICTION_FLAGS = new HashMap<>(); @@ -272,6 +299,10 @@ final class PolicyDefinition { GENERIC_APPLICATION_RESTRICTIONS); POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.RESET_PASSWORD_TOKEN_POLICY, RESET_PASSWORD_TOKEN); + POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.KEYGUARD_DISABLED_FEATURES_POLICY, + KEYGUARD_DISABLED_FEATURES); + POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.APPLICATION_HIDDEN_POLICY, + GENERIC_APPLICATION_HIDDEN); // User Restriction Policies USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_MODIFY_ACCOUNTS, /* flags= */ 0); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java index fd91249fac627..d65d366e4476f 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java @@ -73,7 +73,7 @@ final class PolicyEnforcerCallbacks { return Boolean.TRUE.equals(Binder.withCleanCallingIdentity(() -> { if (!(policyKey instanceof PackagePermissionPolicyKey)) { throw new IllegalArgumentException("policyKey is not of type " - + "PermissionGrantStatePolicyKey"); + + "PermissionGrantStatePolicyKey, passed in policyKey is: " + policyKey); } PackagePermissionPolicyKey parsedKey = (PackagePermissionPolicyKey) policyKey; Objects.requireNonNull(parsedKey.getPermissionName()); @@ -165,7 +165,7 @@ final class PolicyEnforcerCallbacks { try { if (!(policyKey instanceof IntentFilterPolicyKey)) { throw new IllegalArgumentException("policyKey is not of type " - + "IntentFilterPolicyKey"); + + "IntentFilterPolicyKey, passed in policyKey is: " + policyKey); } IntentFilterPolicyKey parsedKey = (IntentFilterPolicyKey) policyKey; @@ -193,7 +193,7 @@ final class PolicyEnforcerCallbacks { return Boolean.TRUE.equals(Binder.withCleanCallingIdentity(() -> { if (!(policyKey instanceof PackagePolicyKey)) { throw new IllegalArgumentException("policyKey is not of type " - + "PackagePolicyKey"); + + "PackagePolicyKey, passed in policyKey is: " + policyKey); } PackagePolicyKey parsedKey = (PackagePolicyKey) policyKey; String packageName = Objects.requireNonNull(parsedKey.getPackageName()); @@ -211,7 +211,7 @@ final class PolicyEnforcerCallbacks { return Boolean.TRUE.equals(Binder.withCleanCallingIdentity(() -> { if (!(policyKey instanceof UserRestrictionPolicyKey)) { throw new IllegalArgumentException("policyKey is not of type " - + "UserRestrictionPolicyKey"); + + "UserRestrictionPolicyKey, passed in policyKey is: " + policyKey); } UserRestrictionPolicyKey parsedKey = (UserRestrictionPolicyKey) policyKey; @@ -221,4 +221,20 @@ final class PolicyEnforcerCallbacks { return true; })); } + + static boolean setApplicationHidden( + @Nullable Boolean hide, @NonNull Context context, int userId, + @NonNull PolicyKey policyKey) { + return Boolean.TRUE.equals(Binder.withCleanCallingIdentity(() -> { + if (!(policyKey instanceof PackagePolicyKey)) { + throw new IllegalArgumentException("policyKey is not of type " + + "PackagePolicyKey, passed in policyKey is: " + policyKey); + } + PackagePolicyKey parsedKey = (PackagePolicyKey) policyKey; + String packageName = Objects.requireNonNull(parsedKey.getPackageName()); + IPackageManager packageManager = AppGlobals.getPackageManager(); + return packageManager.setApplicationHiddenSettingAsUser( + packageName, hide != null && hide, userId); + })); + } }