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

Commit 1cd4a1d6 authored by Rubin Xu's avatar Rubin Xu Committed by Automerger Merge Worker
Browse files

Merge changes I4d700bc4,I14fdac19,I66159f36 into udc-dev am: 430789ea am:...

Merge changes I4d700bc4,I14fdac19,I66159f36 into udc-dev am: 430789ea am: 4ba7124b am: 2e91b677

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/25557600



Change-Id: I232b371b7ee3e1ae1c9b982309f5645191be7645
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 812cea99 2e91b677
Loading
Loading
Loading
Loading
+66 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppGlobals;
import android.app.BroadcastOptions;
import android.app.admin.BooleanPolicyValue;
import android.app.admin.DevicePolicyIdentifiers;
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyState;
@@ -133,6 +134,67 @@ final class DevicePolicyEngine {
        mEnforcingAdmins = new SparseArray<>();
    }

    private void maybeForceEnforcementRefreshLocked(@NonNull PolicyDefinition<?> policyDefinition) {
        try {
            if (shouldForceEnforcementRefresh(policyDefinition)) {
                // This is okay because it's only true for user restrictions which are all <Boolean>
                forceEnforcementRefreshLocked((PolicyDefinition<Boolean>) policyDefinition);
            }
        } catch (Throwable e) {
            // Catch any possible exceptions just to be on the safe side
            Log.e(TAG, "Exception throw during maybeForceEnforcementRefreshLocked", e);
        }
    }

    private boolean shouldForceEnforcementRefresh(@NonNull PolicyDefinition<?> policyDefinition) {
        // These are all "not nullable" but for the purposes of maximum safety for a lightly tested
        // change we check here
        if (policyDefinition == null) {
            return false;
        }
        PolicyKey policyKey = policyDefinition.getPolicyKey();
        if (policyKey == null) {
            return false;
        }

        if (policyKey instanceof UserRestrictionPolicyKey) {
            // b/307481299 We must force all user restrictions to re-sync local
            // + global on each set/clear
            return true;
        }

        return false;
    }

    private void forceEnforcementRefreshLocked(PolicyDefinition<Boolean> policyDefinition) {
        Binder.withCleanCallingIdentity(() -> {
            // Sync global state
            PolicyValue<Boolean> globalValue = new BooleanPolicyValue(false);
            try {
                PolicyState<Boolean> policyState = getGlobalPolicyStateLocked(policyDefinition);
                globalValue = policyState.getCurrentResolvedPolicy();
            } catch (IllegalArgumentException e) {
                // Expected for local-only policies
            }

            enforcePolicy(policyDefinition, globalValue, UserHandle.USER_ALL);

            // Loop through each user and sync that user's state
            for (UserInfo user : mUserManager.getUsers()) {
                PolicyValue<Boolean> localValue = new BooleanPolicyValue(false);
                try {
                    PolicyState<Boolean> localPolicyState = getLocalPolicyStateLocked(
                            policyDefinition, user.id);
                    localValue = localPolicyState.getCurrentResolvedPolicy();
                } catch (IllegalArgumentException e) {
                    // Expected for global-only policies
                }

                enforcePolicy(policyDefinition, localValue, user.id);
            }
        });
    }

    /**
     * Set the policy for the provided {@code policyDefinition} (see {@link PolicyDefinition}) and
     * {@code enforcingAdmin} to the provided {@code value}.
@@ -174,6 +236,7 @@ final class DevicePolicyEngine {
            // No need to notify admins as no new policy is actually enforced, we're just filling in
            // the data structures.
            if (!skipEnforcePolicy) {
                maybeForceEnforcementRefreshLocked(policyDefinition);
                if (policyChanged) {
                    onLocalPolicyChangedLocked(policyDefinition, enforcingAdmin, userId);
                }
@@ -262,6 +325,7 @@ final class DevicePolicyEngine {
        Objects.requireNonNull(enforcingAdmin);

        synchronized (mLock) {
            maybeForceEnforcementRefreshLocked(policyDefinition);
            if (!hasLocalPolicyLocked(policyDefinition, userId)) {
                return;
            }
@@ -425,6 +489,7 @@ final class DevicePolicyEngine {
            // No need to notify admins as no new policy is actually enforced, we're just filling in
            // the data structures.
            if (!skipEnforcePolicy) {
                maybeForceEnforcementRefreshLocked(policyDefinition);
                if (policyChanged) {
                    onGlobalPolicyChangedLocked(policyDefinition, enforcingAdmin);
                }
@@ -474,6 +539,7 @@ final class DevicePolicyEngine {
            PolicyState<V> policyState = getGlobalPolicyStateLocked(policyDefinition);
            boolean policyChanged = policyState.removePolicy(enforcingAdmin);

            maybeForceEnforcementRefreshLocked(policyDefinition);
            if (policyChanged) {
                onGlobalPolicyChangedLocked(policyDefinition, enforcingAdmin);
            }