Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ad53f383 authored by Rubin Xu's avatar Rubin Xu Committed by Android (Google) Code Review
Browse files

Merge "Fix setApplicationRestrictions on parent user" into main

parents c80cb5ed 0650b410
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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");
        }
@@ -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");
        }
@@ -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.");
+4 −1
Original line number Diff line number Diff line
@@ -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 {
+14 −9
Original line number Diff line number Diff line
@@ -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);
@@ -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
@@ -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);
@@ -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()) {
@@ -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);

                }
            }
        }
    }
+10 −9
Original line number Diff line number Diff line
@@ -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:
@@ -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
@@ -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,
@@ -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
@@ -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(() -> {
+17 −7
Original line number Diff line number Diff line
@@ -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> {
@@ -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)));

@@ -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());

    /**
@@ -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);
@@ -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) {
@@ -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