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

Commit 266d7ce6 authored by Kholoud Mohamed's avatar Kholoud Mohamed Committed by Automerger Merge Worker
Browse files

Merge "Use DPMS lock for the policy engine" into udc-dev am: 98c8c131

parents 4d657a56 98c8c131
Loading
Loading
Loading
Loading
+119 −106
Original line number Diff line number Diff line
@@ -101,7 +101,7 @@ final class DevicePolicyEngine {
    private final UserManager mUserManager;

    // TODO(b/256849338): add more granular locks
    private final Object mLock = new Object();
    private final Object mLock;

    /**
     * Map of <userId, Map<policyKey, policyState>>
@@ -122,9 +122,11 @@ final class DevicePolicyEngine {

    DevicePolicyEngine(
            @NonNull Context context,
            @NonNull DeviceAdminServiceController deviceAdminServiceController) {
            @NonNull DeviceAdminServiceController deviceAdminServiceController,
            @NonNull Object lock) {
        mContext = Objects.requireNonNull(context);
        mDeviceAdminServiceController = Objects.requireNonNull(deviceAdminServiceController);
        mLock = Objects.requireNonNull(lock);
        mUserManager = mContext.getSystemService(UserManager.class);
        mLocalPolicies = new SparseArray<>();
        mGlobalPolicies = new HashMap<>();
@@ -152,8 +154,8 @@ final class DevicePolicyEngine {
            PolicyState<V> localPolicyState = getLocalPolicyStateLocked(policyDefinition, userId);

            if (policyDefinition.isNonCoexistablePolicy()) {
                setNonCoexistableLocalPolicy(policyDefinition, localPolicyState, enforcingAdmin,
                        value, userId, skipEnforcePolicy);
                setNonCoexistableLocalPolicyLocked(policyDefinition, localPolicyState,
                        enforcingAdmin, value, userId, skipEnforcePolicy);
                return;
            }

@@ -173,7 +175,7 @@ final class DevicePolicyEngine {
            // the data structures.
            if (!skipEnforcePolicy) {
                if (policyChanged) {
                    onLocalPolicyChanged(policyDefinition, enforcingAdmin, userId);
                    onLocalPolicyChangedLocked(policyDefinition, enforcingAdmin, userId);
                }
                boolean policyEnforced = Objects.equals(
                        localPolicyState.getCurrentResolvedPolicy(), value);
@@ -211,7 +213,7 @@ final class DevicePolicyEngine {
     *
     * <p>Passing a {@code null} value means the policy set by this admin should be removed.
     */
    private <V> void setNonCoexistableLocalPolicy(
    private <V> void setNonCoexistableLocalPolicyLocked(
            PolicyDefinition<V> policyDefinition,
            PolicyState<V> localPolicyState,
            EnforcingAdmin enforcingAdmin,
@@ -266,8 +268,8 @@ final class DevicePolicyEngine {
            PolicyState<V> localPolicyState = getLocalPolicyStateLocked(policyDefinition, userId);

            if (policyDefinition.isNonCoexistablePolicy()) {
                setNonCoexistableLocalPolicy(policyDefinition, localPolicyState, enforcingAdmin,
                        /* value= */ null, userId, /* skipEnforcePolicy= */ false);
                setNonCoexistableLocalPolicyLocked(policyDefinition, localPolicyState,
                        enforcingAdmin, /* value= */ null, userId, /* skipEnforcePolicy= */ false);
                return;
            }

@@ -282,7 +284,7 @@ final class DevicePolicyEngine {
            }

            if (policyChanged) {
                onLocalPolicyChanged(policyDefinition, enforcingAdmin, userId);
                onLocalPolicyChangedLocked(policyDefinition, enforcingAdmin, userId);
            }

            // For a removePolicy to be enforced, it means no current policy exists
@@ -348,7 +350,7 @@ final class DevicePolicyEngine {
    /**
     * Enforces the new policy and notifies relevant admins.
     */
    private <V> void onLocalPolicyChanged(
    private <V> void onLocalPolicyChangedLocked(
            @NonNull PolicyDefinition<V> policyDefinition,
            @NonNull EnforcingAdmin enforcingAdmin,
            int userId) {
@@ -358,7 +360,7 @@ final class DevicePolicyEngine {
                policyDefinition, localPolicyState.getCurrentResolvedPolicy(), userId);

        // Send policy updates to admins who've set it locally
        sendPolicyChangedToAdmins(
        sendPolicyChangedToAdminsLocked(
                localPolicyState,
                enforcingAdmin,
                policyDefinition,
@@ -369,7 +371,7 @@ final class DevicePolicyEngine {
        // Send policy updates to admins who've set it globally
        if (hasGlobalPolicyLocked(policyDefinition)) {
            PolicyState<V> globalPolicyState = getGlobalPolicyStateLocked(policyDefinition);
            sendPolicyChangedToAdmins(
            sendPolicyChangedToAdminsLocked(
                    globalPolicyState,
                    enforcingAdmin,
                    policyDefinition,
@@ -424,7 +426,7 @@ final class DevicePolicyEngine {
            // the data structures.
            if (!skipEnforcePolicy) {
                if (policyChanged) {
                    onGlobalPolicyChanged(policyDefinition, enforcingAdmin);
                    onGlobalPolicyChangedLocked(policyDefinition, enforcingAdmin);
                }

                boolean policyAppliedGlobally = Objects.equals(
@@ -473,7 +475,7 @@ final class DevicePolicyEngine {
            boolean policyChanged = policyState.removePolicy(enforcingAdmin);

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

            applyGlobalPolicyOnUsersWithLocalPoliciesLocked(policyDefinition, enforcingAdmin,
@@ -499,7 +501,7 @@ final class DevicePolicyEngine {
    /**
     * Enforces the new policy globally and notifies relevant admins.
     */
    private <V> void onGlobalPolicyChanged(
    private <V> void onGlobalPolicyChangedLocked(
            @NonNull PolicyDefinition<V> policyDefinition,
            @NonNull EnforcingAdmin enforcingAdmin) {
        PolicyState<V> policyState = getGlobalPolicyStateLocked(policyDefinition);
@@ -507,7 +509,7 @@ final class DevicePolicyEngine {
        enforcePolicy(policyDefinition, policyState.getCurrentResolvedPolicy(),
                UserHandle.USER_ALL);

        sendPolicyChangedToAdmins(
        sendPolicyChangedToAdminsLocked(
                policyState,
                enforcingAdmin,
                policyDefinition,
@@ -552,7 +554,7 @@ final class DevicePolicyEngine {
                        policyDefinition,
                        localPolicyState.getCurrentResolvedPolicy(),
                        userId);
                sendPolicyChangedToAdmins(
                sendPolicyChangedToAdminsLocked(
                        localPolicyState,
                        enforcingAdmin,
                        policyDefinition,
@@ -745,6 +747,7 @@ final class DevicePolicyEngine {
    }

    <V> void transferPolicies(EnforcingAdmin oldAdmin, EnforcingAdmin newAdmin) {
        synchronized (mLock) {
            Set<PolicyKey> globalPolicies = new HashSet<>(mGlobalPolicies.keySet());
            for (PolicyKey policy : globalPolicies) {
                PolicyState<?> policyState = mGlobalPolicies.get(policy);
@@ -772,7 +775,7 @@ final class DevicePolicyEngine {
                    }
                }
            }

        }
        removePoliciesForAdmin(oldAdmin);
    }

@@ -836,7 +839,7 @@ final class DevicePolicyEngine {
            mLocalPolicies.get(userId).put(
                    policyDefinition.getPolicyKey(), new PolicyState<>(policyDefinition));
        }
        return getPolicyState(mLocalPolicies.get(userId), policyDefinition);
        return getPolicyStateLocked(mLocalPolicies.get(userId), policyDefinition);
    }

    private <V> void removeLocalPolicyStateLocked(
@@ -858,14 +861,14 @@ final class DevicePolicyEngine {
            mGlobalPolicies.put(
                    policyDefinition.getPolicyKey(), new PolicyState<>(policyDefinition));
        }
        return getPolicyState(mGlobalPolicies, policyDefinition);
        return getPolicyStateLocked(mGlobalPolicies, policyDefinition);
    }

    private <V> void removeGlobalPolicyStateLocked(PolicyDefinition<V> policyDefinition) {
        mGlobalPolicies.remove(policyDefinition.getPolicyKey());
    }

    private static <V> PolicyState<V> getPolicyState(
    private static <V> PolicyState<V> getPolicyStateLocked(
            Map<PolicyKey, PolicyState<?>> policies, PolicyDefinition<V> policyDefinition) {
        try {
            // This will not throw an exception because policyDefinition is of type V, so unless
@@ -935,7 +938,7 @@ final class DevicePolicyEngine {
    }

    // TODO(b/261430877): Finalise the decision on which admins to send the updates to.
    private <V> void sendPolicyChangedToAdmins(
    private <V> void sendPolicyChangedToAdminsLocked(
            PolicyState<V> policyState,
            EnforcingAdmin callingAdmin,
            PolicyDefinition<V> policyDefinition,
@@ -1210,17 +1213,19 @@ final class DevicePolicyEngine {
            if (parentInfo == null || parentInfo.getUserHandle().getIdentifier() == userId) {
                return;
            }
            synchronized (mLock) {
                if (!mLocalPolicies.contains(parentInfo.getUserHandle().getIdentifier())) {
                    return;
                }
                for (Map.Entry<PolicyKey, PolicyState<?>> entry : mLocalPolicies.get(
                        parentInfo.getUserHandle().getIdentifier()).entrySet()) {
                enforcePolicyOnUser(userId, entry.getValue());
                    enforcePolicyOnUserLocked(userId, entry.getValue());
                }
            }
        });
    }

    private <V> void enforcePolicyOnUser(int userId, PolicyState<V> policyState) {
    private <V> void enforcePolicyOnUserLocked(int userId, PolicyState<V> policyState) {
        if (!policyState.getPolicyDefinition().isInheritable()) {
            return;
        }
@@ -1239,6 +1244,7 @@ final class DevicePolicyEngine {
     */
    @NonNull
    DevicePolicyState getDevicePolicyState() {
        synchronized (mLock) {
            Map<UserHandle, Map<PolicyKey, android.app.admin.PolicyState<?>>> policies =
                    new HashMap<>();
            for (int i = 0; i < mLocalPolicies.size(); i++) {
@@ -1260,12 +1266,14 @@ final class DevicePolicyEngine {
            }
            return new DevicePolicyState(policies);
        }
    }


    /**
     * Removes all local and global policies set by that admin.
     */
    void removePoliciesForAdmin(EnforcingAdmin admin) {
        synchronized (mLock) {
            Set<PolicyKey> globalPolicies = new HashSet<>(mGlobalPolicies.keySet());
            for (PolicyKey policy : globalPolicies) {
                PolicyState<?> policyState = mGlobalPolicies.get(policy);
@@ -1287,11 +1295,13 @@ final class DevicePolicyEngine {
                }
            }
        }
    }

    /**
     * Removes all local policies for the provided {@code userId}.
     */
    private void removeLocalPoliciesForUser(int userId) {
        synchronized (mLock) {
            if (!mLocalPolicies.contains(userId)) {
                // No policies on user
                return;
@@ -1310,6 +1320,7 @@ final class DevicePolicyEngine {

            mLocalPolicies.remove(userId);
        }
    }

    /**
     * Removes all local and global policies for admins installed in the provided
@@ -1376,7 +1387,7 @@ final class DevicePolicyEngine {
     */
    private void updateDeviceAdminServiceOnPolicyRemoveLocked(
            @NonNull EnforcingAdmin enforcingAdmin) {
        if (doesAdminHavePolicies(enforcingAdmin)) {
        if (doesAdminHavePoliciesLocked(enforcingAdmin)) {
            return;
        }
        int userId = enforcingAdmin.getUserId();
@@ -1399,7 +1410,7 @@ final class DevicePolicyEngine {
                /* actionForLog= */ "policy-removed");
    }

    private boolean doesAdminHavePolicies(@NonNull EnforcingAdmin enforcingAdmin) {
    private boolean doesAdminHavePoliciesLocked(@NonNull EnforcingAdmin enforcingAdmin) {
        for (PolicyKey policy : mGlobalPolicies.keySet()) {
            PolicyState<?> policyState = mGlobalPolicies.get(policy);
            if (policyState.getPoliciesSetByAdmins().containsKey(enforcingAdmin)) {
@@ -1420,14 +1431,18 @@ final class DevicePolicyEngine {

    @NonNull
    private Set<EnforcingAdmin> getEnforcingAdminsOnUser(int userId) {
        synchronized (mLock) {
            return mEnforcingAdmins.contains(userId)
                    ? mEnforcingAdmins.get(userId) : Collections.emptySet();
        }
    }

    private void write() {
        synchronized (mLock) {
            Log.d(TAG, "Writing device policies to file.");
            new DevicePoliciesReaderWriter().writeToFileLocked();
        }
    }

    // TODO(b/256852787): trigger resolving logic after loading policies as roles are recalculated
    //  and could result in a different enforced policy
@@ -1436,11 +1451,11 @@ final class DevicePolicyEngine {
        synchronized (mLock) {
            clear();
            new DevicePoliciesReaderWriter().readFromFileLocked();
            reapplyAllPolicies();
            reapplyAllPoliciesLocked();
        }
    }

    private <V> void reapplyAllPolicies() {
    private <V> void reapplyAllPoliciesLocked() {
        for (PolicyKey policy : mGlobalPolicies.keySet()) {
            PolicyState<?> policyState = mGlobalPolicies.get(policy);
            // Policy definition and value will always be of the same type
@@ -1470,11 +1485,9 @@ final class DevicePolicyEngine {
     * <p>Note that this doesn't clear any enforcements, it only clears the data structures.
     */
    void clearAllPolicies() {
        synchronized (mLock) {
        clear();
        write();
    }
    }
    private void clear() {
        synchronized (mLock) {
            mGlobalPolicies.clear();
+2 −1
Original line number Diff line number Diff line
@@ -2093,7 +2093,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        mUserData = new SparseArray<>();
        mOwners = makeOwners(injector, pathProvider);
        mDevicePolicyEngine = new DevicePolicyEngine(mContext, mDeviceAdminServiceController);
        mDevicePolicyEngine = new DevicePolicyEngine(
                mContext, mDeviceAdminServiceController, getLockObject());
        if (!mHasFeature) {
            // Skip the rest of the initialization