Loading core/java/android/app/admin/DevicePolicyManager.java +3 −3 Original line number Diff line number Diff line Loading @@ -10427,7 +10427,7 @@ public class DevicePolicyManager { @WorkerThread public void setApplicationRestrictions(@Nullable ComponentName admin, String packageName, Bundle settings) { if (!Flags.dmrhCanSetAppRestriction()) { if (!Flags.dmrhSetAppRestrictions()) { throwIfParentInstance("setApplicationRestrictions"); } Loading Loading @@ -11835,7 +11835,7 @@ public class DevicePolicyManager { @WorkerThread public @NonNull Bundle getApplicationRestrictions( @Nullable ComponentName admin, String packageName) { if (!Flags.dmrhCanSetAppRestriction()) { if (!Flags.dmrhSetAppRestrictions()) { throwIfParentInstance("getApplicationRestrictions"); } Loading Loading @@ -14120,7 +14120,7 @@ public class DevicePolicyManager { public @NonNull DevicePolicyManager getParentProfileInstance(@NonNull ComponentName admin) { throwIfParentInstance("getParentProfileInstance"); try { if (Flags.dmrhCanSetAppRestriction()) { if (Flags.dmrhSetAppRestrictions()) { UserManager um = mContext.getSystemService(UserManager.class); if (!um.isManagedProfile()) { throw new SecurityException("The current user does not have a parent profile."); core/java/android/app/admin/flags/flags.aconfig +4 −1 Original line number Diff line number Diff line Loading @@ -244,10 +244,13 @@ flag { } flag { name: "dmrh_can_set_app_restriction" name: "dmrh_set_app_restrictions" namespace: "enterprise" description: "Allow DMRH to set application restrictions (both on the profile and the parent)" bug: "328758346" metadata { purpose: PURPOSE_BUGFIX } } flag { Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java +14 −9 Original line number Diff line number Diff line Loading @@ -217,7 +217,7 @@ final class DevicePolicyEngine { <V> void setLocalPolicy( @NonNull PolicyDefinition<V> policyDefinition, @NonNull EnforcingAdmin enforcingAdmin, @Nullable PolicyValue<V> value, @NonNull PolicyValue<V> value, int userId, boolean skipEnforcePolicy) { Objects.requireNonNull(policyDefinition); Loading Loading @@ -313,6 +313,7 @@ final class DevicePolicyEngine { } updateDeviceAdminServiceOnPolicyAddLocked(enforcingAdmin); write(); applyToInheritableProfiles(policyDefinition, enforcingAdmin, value, userId); } // TODO: add more documentation on broadcasts/callbacks to use to get current enforced values Loading Loading @@ -400,7 +401,7 @@ final class DevicePolicyEngine { * else remove the policy from child. */ private <V> void applyToInheritableProfiles(PolicyDefinition<V> policyDefinition, EnforcingAdmin enforcingAdmin, PolicyValue<V> value, int userId) { EnforcingAdmin enforcingAdmin, @Nullable PolicyValue<V> value, int userId) { if (policyDefinition.isInheritable()) { Binder.withCleanCallingIdentity(() -> { List<UserInfo> userInfos = mUserManager.getProfiles(userId); Loading Loading @@ -1742,15 +1743,18 @@ final class DevicePolicyEngine { } } <V> void reapplyAllPoliciesLocked() { <V> void reapplyAllPoliciesOnBootLocked() { for (PolicyKey policy : mGlobalPolicies.keySet()) { PolicyState<?> policyState = mGlobalPolicies.get(policy); // Policy definition and value will always be of the same type PolicyDefinition<V> policyDefinition = (PolicyDefinition<V>) policyState.getPolicyDefinition(); PolicyValue<V> policyValue = (PolicyValue<V>) policyState.getCurrentResolvedPolicy(); if (!policyDefinition.shouldSkipEnforcementIfNotChanged()) { PolicyValue<V> policyValue = (PolicyValue<V>) policyState.getCurrentResolvedPolicy(); enforcePolicy(policyDefinition, policyValue, UserHandle.USER_ALL); } } for (int i = 0; i < mLocalPolicies.size(); i++) { int userId = mLocalPolicies.keyAt(i); for (PolicyKey policy : mLocalPolicies.get(userId).keySet()) { Loading @@ -1758,10 +1762,11 @@ final class DevicePolicyEngine { // Policy definition and value will always be of the same type PolicyDefinition<V> policyDefinition = (PolicyDefinition<V>) policyState.getPolicyDefinition(); if (!policyDefinition.shouldSkipEnforcementIfNotChanged()) { PolicyValue<V> policyValue = (PolicyValue<V>) policyState.getCurrentResolvedPolicy(); enforcePolicy(policyDefinition, policyValue, userId); } } } } Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +10 −9 Original line number Diff line number Diff line Loading @@ -3351,7 +3351,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { break; case SystemService.PHASE_SYSTEM_SERVICES_READY: synchronized (getLockObject()) { mDevicePolicyEngine.reapplyAllPoliciesLocked(); mDevicePolicyEngine.reapplyAllPoliciesOnBootLocked(); } break; case SystemService.PHASE_ACTIVITY_MANAGER_READY: Loading Loading @@ -11443,7 +11443,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } setBackwardsCompatibleAppRestrictions( caller, packageName, restrictions, caller.getUserHandle()); } else if (Flags.dmrhCanSetAppRestriction()) { } else if (Flags.dmrhSetAppRestrictions()) { final boolean isRoleHolder; if (who != null) { // DO or PO Loading Loading @@ -11484,10 +11484,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { new BundlePolicyValue(restrictions), affectedUserId); } Intent changeIntent = new Intent(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED); changeIntent.setPackage(packageName); changeIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); mContext.sendBroadcastAsUser(changeIntent, UserHandle.of(affectedUserId)); } else { mInjector.binderWithCleanCallingIdentity(() -> { mUserManager.setApplicationRestrictions(packageName, restrictions, Loading Loading @@ -12845,7 +12841,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return Bundle.EMPTY; } return policies.get(enforcingAdmin).getValue(); } else if (Flags.dmrhCanSetAppRestriction()) { } else if (Flags.dmrhSetAppRestrictions()) { final boolean isRoleHolder; if (who != null) { // Caller is DO or PO. They cannot call this on parent Loading Loading @@ -15770,8 +15766,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { PolicyDefinition.APPLICATION_RESTRICTIONS(packageName), userId); List<Bundle> restrictions = new ArrayList<>(); for (EnforcingAdmin admin : policies.keySet()) { restrictions.add(policies.get(admin).getValue()); for (PolicyValue<Bundle> policyValue: policies.values()) { Bundle value = policyValue.getValue(); // Probably not necessary since setApplicationRestrictions only sets non-empty // Bundle, but just in case. if (value != null && !value.isEmpty()) { restrictions.add(value); } } return mInjector.binderWithCleanCallingIdentity(() -> { services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java +17 −7 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; final class PolicyDefinition<V> { Loading Loading @@ -82,6 +83,10 @@ final class PolicyDefinition<V> { // them. private static final int POLICY_FLAG_USER_RESTRICTION_POLICY = 1 << 4; // Only invoke the policy enforcer callback when the policy value changes, and do not invoke the // callback in other cases such as device reboots. private static final int POLICY_FLAG_SKIP_ENFORCEMENT_IF_UNCHANGED = 1 << 5; private static final MostRestrictive<Boolean> FALSE_MORE_RESTRICTIVE = new MostRestrictive<>( List.of(new BooleanPolicyValue(false), new BooleanPolicyValue(true))); Loading Loading @@ -231,11 +236,11 @@ final class PolicyDefinition<V> { // 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. new MostRecent<>(), POLICY_FLAG_LOCAL_ONLY_POLICY | POLICY_FLAG_NON_COEXISTABLE_POLICY, // Application restrictions are now stored and retrieved from DPMS, so no // enforcing is required, however DPMS calls into UM to set restrictions for // backwards compatibility. (Bundle value, Context context, Integer userId, PolicyKey policyKey) -> true, // Only invoke the enforcement callback during policy change and not other state POLICY_FLAG_LOCAL_ONLY_POLICY | POLICY_FLAG_INHERITABLE | POLICY_FLAG_NON_COEXISTABLE_POLICY | POLICY_FLAG_SKIP_ENFORCEMENT_IF_UNCHANGED, PolicyEnforcerCallbacks::setApplicationRestrictions, new BundlePolicySerializer()); /** Loading Loading @@ -581,6 +586,10 @@ final class PolicyDefinition<V> { return (mPolicyFlags & POLICY_FLAG_USER_RESTRICTION_POLICY) != 0; } boolean shouldSkipEnforcementIfNotChanged() { return (mPolicyFlags & POLICY_FLAG_SKIP_ENFORCEMENT_IF_UNCHANGED) != 0; } @Nullable PolicyValue<V> resolvePolicy(LinkedHashMap<EnforcingAdmin, PolicyValue<V>> adminsPolicy) { return mResolutionMechanism.resolve(adminsPolicy); Loading Loading @@ -610,7 +619,7 @@ final class PolicyDefinition<V> { * {@link Object#equals} implementation. */ private PolicyDefinition( PolicyKey key, @NonNull PolicyKey key, ResolutionMechanism<V> resolutionMechanism, QuadFunction<V, Context, Integer, PolicyKey, Boolean> policyEnforcerCallback, PolicySerializer<V> policySerializer) { Loading @@ -622,11 +631,12 @@ final class PolicyDefinition<V> { * {@link Object#equals} and {@link Object#hashCode()} implementation. */ private PolicyDefinition( PolicyKey policyKey, @NonNull PolicyKey policyKey, ResolutionMechanism<V> resolutionMechanism, int policyFlags, QuadFunction<V, Context, Integer, PolicyKey, Boolean> policyEnforcerCallback, PolicySerializer<V> policySerializer) { Objects.requireNonNull(policyKey); mPolicyKey = policyKey; mResolutionMechanism = resolutionMechanism; mPolicyFlags = policyFlags; Loading Loading
core/java/android/app/admin/DevicePolicyManager.java +3 −3 Original line number Diff line number Diff line Loading @@ -10427,7 +10427,7 @@ public class DevicePolicyManager { @WorkerThread public void setApplicationRestrictions(@Nullable ComponentName admin, String packageName, Bundle settings) { if (!Flags.dmrhCanSetAppRestriction()) { if (!Flags.dmrhSetAppRestrictions()) { throwIfParentInstance("setApplicationRestrictions"); } Loading Loading @@ -11835,7 +11835,7 @@ public class DevicePolicyManager { @WorkerThread public @NonNull Bundle getApplicationRestrictions( @Nullable ComponentName admin, String packageName) { if (!Flags.dmrhCanSetAppRestriction()) { if (!Flags.dmrhSetAppRestrictions()) { throwIfParentInstance("getApplicationRestrictions"); } Loading Loading @@ -14120,7 +14120,7 @@ public class DevicePolicyManager { public @NonNull DevicePolicyManager getParentProfileInstance(@NonNull ComponentName admin) { throwIfParentInstance("getParentProfileInstance"); try { if (Flags.dmrhCanSetAppRestriction()) { if (Flags.dmrhSetAppRestrictions()) { UserManager um = mContext.getSystemService(UserManager.class); if (!um.isManagedProfile()) { throw new SecurityException("The current user does not have a parent profile.");
core/java/android/app/admin/flags/flags.aconfig +4 −1 Original line number Diff line number Diff line Loading @@ -244,10 +244,13 @@ flag { } flag { name: "dmrh_can_set_app_restriction" name: "dmrh_set_app_restrictions" namespace: "enterprise" description: "Allow DMRH to set application restrictions (both on the profile and the parent)" bug: "328758346" metadata { purpose: PURPOSE_BUGFIX } } flag { Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java +14 −9 Original line number Diff line number Diff line Loading @@ -217,7 +217,7 @@ final class DevicePolicyEngine { <V> void setLocalPolicy( @NonNull PolicyDefinition<V> policyDefinition, @NonNull EnforcingAdmin enforcingAdmin, @Nullable PolicyValue<V> value, @NonNull PolicyValue<V> value, int userId, boolean skipEnforcePolicy) { Objects.requireNonNull(policyDefinition); Loading Loading @@ -313,6 +313,7 @@ final class DevicePolicyEngine { } updateDeviceAdminServiceOnPolicyAddLocked(enforcingAdmin); write(); applyToInheritableProfiles(policyDefinition, enforcingAdmin, value, userId); } // TODO: add more documentation on broadcasts/callbacks to use to get current enforced values Loading Loading @@ -400,7 +401,7 @@ final class DevicePolicyEngine { * else remove the policy from child. */ private <V> void applyToInheritableProfiles(PolicyDefinition<V> policyDefinition, EnforcingAdmin enforcingAdmin, PolicyValue<V> value, int userId) { EnforcingAdmin enforcingAdmin, @Nullable PolicyValue<V> value, int userId) { if (policyDefinition.isInheritable()) { Binder.withCleanCallingIdentity(() -> { List<UserInfo> userInfos = mUserManager.getProfiles(userId); Loading Loading @@ -1742,15 +1743,18 @@ final class DevicePolicyEngine { } } <V> void reapplyAllPoliciesLocked() { <V> void reapplyAllPoliciesOnBootLocked() { for (PolicyKey policy : mGlobalPolicies.keySet()) { PolicyState<?> policyState = mGlobalPolicies.get(policy); // Policy definition and value will always be of the same type PolicyDefinition<V> policyDefinition = (PolicyDefinition<V>) policyState.getPolicyDefinition(); PolicyValue<V> policyValue = (PolicyValue<V>) policyState.getCurrentResolvedPolicy(); if (!policyDefinition.shouldSkipEnforcementIfNotChanged()) { PolicyValue<V> policyValue = (PolicyValue<V>) policyState.getCurrentResolvedPolicy(); enforcePolicy(policyDefinition, policyValue, UserHandle.USER_ALL); } } for (int i = 0; i < mLocalPolicies.size(); i++) { int userId = mLocalPolicies.keyAt(i); for (PolicyKey policy : mLocalPolicies.get(userId).keySet()) { Loading @@ -1758,10 +1762,11 @@ final class DevicePolicyEngine { // Policy definition and value will always be of the same type PolicyDefinition<V> policyDefinition = (PolicyDefinition<V>) policyState.getPolicyDefinition(); if (!policyDefinition.shouldSkipEnforcementIfNotChanged()) { PolicyValue<V> policyValue = (PolicyValue<V>) policyState.getCurrentResolvedPolicy(); enforcePolicy(policyDefinition, policyValue, userId); } } } } Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +10 −9 Original line number Diff line number Diff line Loading @@ -3351,7 +3351,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { break; case SystemService.PHASE_SYSTEM_SERVICES_READY: synchronized (getLockObject()) { mDevicePolicyEngine.reapplyAllPoliciesLocked(); mDevicePolicyEngine.reapplyAllPoliciesOnBootLocked(); } break; case SystemService.PHASE_ACTIVITY_MANAGER_READY: Loading Loading @@ -11443,7 +11443,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } setBackwardsCompatibleAppRestrictions( caller, packageName, restrictions, caller.getUserHandle()); } else if (Flags.dmrhCanSetAppRestriction()) { } else if (Flags.dmrhSetAppRestrictions()) { final boolean isRoleHolder; if (who != null) { // DO or PO Loading Loading @@ -11484,10 +11484,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { new BundlePolicyValue(restrictions), affectedUserId); } Intent changeIntent = new Intent(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED); changeIntent.setPackage(packageName); changeIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); mContext.sendBroadcastAsUser(changeIntent, UserHandle.of(affectedUserId)); } else { mInjector.binderWithCleanCallingIdentity(() -> { mUserManager.setApplicationRestrictions(packageName, restrictions, Loading Loading @@ -12845,7 +12841,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return Bundle.EMPTY; } return policies.get(enforcingAdmin).getValue(); } else if (Flags.dmrhCanSetAppRestriction()) { } else if (Flags.dmrhSetAppRestrictions()) { final boolean isRoleHolder; if (who != null) { // Caller is DO or PO. They cannot call this on parent Loading Loading @@ -15770,8 +15766,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { PolicyDefinition.APPLICATION_RESTRICTIONS(packageName), userId); List<Bundle> restrictions = new ArrayList<>(); for (EnforcingAdmin admin : policies.keySet()) { restrictions.add(policies.get(admin).getValue()); for (PolicyValue<Bundle> policyValue: policies.values()) { Bundle value = policyValue.getValue(); // Probably not necessary since setApplicationRestrictions only sets non-empty // Bundle, but just in case. if (value != null && !value.isEmpty()) { restrictions.add(value); } } return mInjector.binderWithCleanCallingIdentity(() -> {
services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java +17 −7 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; final class PolicyDefinition<V> { Loading Loading @@ -82,6 +83,10 @@ final class PolicyDefinition<V> { // them. private static final int POLICY_FLAG_USER_RESTRICTION_POLICY = 1 << 4; // Only invoke the policy enforcer callback when the policy value changes, and do not invoke the // callback in other cases such as device reboots. private static final int POLICY_FLAG_SKIP_ENFORCEMENT_IF_UNCHANGED = 1 << 5; private static final MostRestrictive<Boolean> FALSE_MORE_RESTRICTIVE = new MostRestrictive<>( List.of(new BooleanPolicyValue(false), new BooleanPolicyValue(true))); Loading Loading @@ -231,11 +236,11 @@ final class PolicyDefinition<V> { // 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. new MostRecent<>(), POLICY_FLAG_LOCAL_ONLY_POLICY | POLICY_FLAG_NON_COEXISTABLE_POLICY, // Application restrictions are now stored and retrieved from DPMS, so no // enforcing is required, however DPMS calls into UM to set restrictions for // backwards compatibility. (Bundle value, Context context, Integer userId, PolicyKey policyKey) -> true, // Only invoke the enforcement callback during policy change and not other state POLICY_FLAG_LOCAL_ONLY_POLICY | POLICY_FLAG_INHERITABLE | POLICY_FLAG_NON_COEXISTABLE_POLICY | POLICY_FLAG_SKIP_ENFORCEMENT_IF_UNCHANGED, PolicyEnforcerCallbacks::setApplicationRestrictions, new BundlePolicySerializer()); /** Loading Loading @@ -581,6 +586,10 @@ final class PolicyDefinition<V> { return (mPolicyFlags & POLICY_FLAG_USER_RESTRICTION_POLICY) != 0; } boolean shouldSkipEnforcementIfNotChanged() { return (mPolicyFlags & POLICY_FLAG_SKIP_ENFORCEMENT_IF_UNCHANGED) != 0; } @Nullable PolicyValue<V> resolvePolicy(LinkedHashMap<EnforcingAdmin, PolicyValue<V>> adminsPolicy) { return mResolutionMechanism.resolve(adminsPolicy); Loading Loading @@ -610,7 +619,7 @@ final class PolicyDefinition<V> { * {@link Object#equals} implementation. */ private PolicyDefinition( PolicyKey key, @NonNull PolicyKey key, ResolutionMechanism<V> resolutionMechanism, QuadFunction<V, Context, Integer, PolicyKey, Boolean> policyEnforcerCallback, PolicySerializer<V> policySerializer) { Loading @@ -622,11 +631,12 @@ final class PolicyDefinition<V> { * {@link Object#equals} and {@link Object#hashCode()} implementation. */ private PolicyDefinition( PolicyKey policyKey, @NonNull PolicyKey policyKey, ResolutionMechanism<V> resolutionMechanism, int policyFlags, QuadFunction<V, Context, Integer, PolicyKey, Boolean> policyEnforcerCallback, PolicySerializer<V> policySerializer) { Objects.requireNonNull(policyKey); mPolicyKey = policyKey; mResolutionMechanism = resolutionMechanism; mPolicyFlags = policyFlags; Loading