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

Commit 452fc28c authored by Nino Jagar's avatar Nino Jagar
Browse files

Cache content protection policy to be read early without deadlocks

Bug: 323038815
Test: End-to-end with TestDPC
Change-Id: Ia61e0b3e46360e73e95e5fc630f94f262d8ab0bf
parent 70331c8b
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -15,6 +15,9 @@
 */
package android.app.admin;

import static android.app.admin.DevicePolicyManager.CONTENT_PROTECTION_DISABLED;
import static android.app.admin.DevicePolicyManager.ContentProtectionPolicy;

import android.annotation.UserIdInt;

import com.android.server.LocalServices;
@@ -58,6 +61,12 @@ public abstract class DevicePolicyCache {
     */
    public abstract int getPermissionPolicy(@UserIdInt int userHandle);

    /**
     * Caches {@link DevicePolicyManager#getContentProtectionPolicy(android.content.ComponentName)}
     * of the given user.
     */
    public abstract @ContentProtectionPolicy int getContentProtectionPolicy(@UserIdInt int userId);

    /**
     * True if there is an admin on the device who can grant sensor permissions.
     */
@@ -91,6 +100,11 @@ public abstract class DevicePolicyCache {
            return DevicePolicyManager.PERMISSION_POLICY_PROMPT;
        }

        @Override
        public @ContentProtectionPolicy int getContentProtectionPolicy(@UserIdInt int userId) {
            return CONTENT_PROTECTION_DISABLED;
        }

        @Override
        public boolean canAdminGrantSensorsPermissions() {
            return false;
+27 −0
Original line number Diff line number Diff line
@@ -15,6 +15,10 @@
 */
package com.android.server.devicepolicy;

import static android.app.admin.DevicePolicyManager.CONTENT_PROTECTION_DISABLED;
import static android.app.admin.DevicePolicyManager.ContentProtectionPolicy;

import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.admin.DevicePolicyCache;
import android.app.admin.DevicePolicyManager;
@@ -70,10 +74,14 @@ public class DevicePolicyCacheImpl extends DevicePolicyCache {
    /** Maps to {@code ActiveAdmin.mAdminCanGrantSensorsPermissions}. */
    private final AtomicBoolean mCanGrantSensorsPermissions = new AtomicBoolean(false);

    @GuardedBy("mLock")
    private final SparseIntArray mContentProtectionPolicy = new SparseIntArray();

    public void onUserRemoved(int userHandle) {
        synchronized (mLock) {
            mPasswordQuality.delete(userHandle);
            mPermissionPolicy.delete(userHandle);
            mContentProtectionPolicy.delete(userHandle);
        }
    }

@@ -142,6 +150,24 @@ public class DevicePolicyCacheImpl extends DevicePolicyCache {
        }
    }

    @Override
    public @ContentProtectionPolicy int getContentProtectionPolicy(@UserIdInt int userId) {
        synchronized (mLock) {
            return mContentProtectionPolicy.get(userId, CONTENT_PROTECTION_DISABLED);
        }
    }

    /** Update the content protection policy for the given user. */
    public void setContentProtectionPolicy(@UserIdInt int userId, @Nullable Integer value) {
        synchronized (mLock) {
            if (value == null) {
                mContentProtectionPolicy.delete(userId);
            } else {
                mContentProtectionPolicy.put(userId, value);
            }
        }
    }

    @Override
    public boolean canAdminGrantSensorsPermissions() {
        return mCanGrantSensorsPermissions.get();
@@ -178,6 +204,7 @@ public class DevicePolicyCacheImpl extends DevicePolicyCache {
            pw.println("Screen capture disallowed users: " + mScreenCaptureDisallowedUsers);
            pw.println("Password quality: " + mPasswordQuality);
            pw.println("Permission policy: " + mPermissionPolicy);
            pw.println("Content protection policy: " + mContentProtectionPolicy);
            pw.println("Admin can grant sensors permission: " + mCanGrantSensorsPermissions.get());
            pw.print("Shortcuts overrides: ");
            pw.println(mLauncherShortcutOverrides);
+7 −0
Original line number Diff line number Diff line
@@ -3580,6 +3580,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                userId == UserHandle.USER_SYSTEM ? UserHandle.USER_ALL : userId);
        updatePermissionPolicyCache(userId);
        updateAdminCanGrantSensorsPermissionCache(userId);
        updateContentProtectionPolicyCache(userId);
        final List<PreferentialNetworkServiceConfig> preferentialNetworkServiceConfigs;
        synchronized (getLockObject()) {
@@ -23287,6 +23288,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        }
    }
    private void updateContentProtectionPolicyCache(@UserIdInt int userId) {
        mPolicyCache.setContentProtectionPolicy(
                userId,
                mDevicePolicyEngine.getResolvedPolicy(PolicyDefinition.CONTENT_PROTECTION, userId));
    }
    @Override
    public ManagedSubscriptionsPolicy getManagedSubscriptionsPolicy() {
        synchronized (getLockObject()) {
+1 −1
Original line number Diff line number Diff line
@@ -345,7 +345,7 @@ final class PolicyDefinition<V> {
            new NoArgsPolicyKey(DevicePolicyIdentifiers.CONTENT_PROTECTION_POLICY),
            new MostRecent<>(),
            POLICY_FLAG_LOCAL_ONLY_POLICY,
            (Integer value, Context context, Integer userId, PolicyKey policyKey) -> true,
            PolicyEnforcerCallbacks::setContentProtectionPolicy,
            new IntegerPolicySerializer());

    private static final Map<String, PolicyDefinition<?>> POLICY_DEFINITIONS = new HashMap<>();
+16 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.devicepolicy;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.AppGlobals;
import android.app.admin.DevicePolicyCache;
import android.app.admin.DevicePolicyManager;
@@ -265,6 +266,21 @@ final class PolicyEnforcerCallbacks {
        return true;
    }

    static boolean setContentProtectionPolicy(
            @Nullable Integer value,
            @NonNull Context context,
            @UserIdInt Integer userId,
            @NonNull PolicyKey policyKey) {
        Binder.withCleanCallingIdentity(
                () -> {
                    DevicePolicyCache cache = DevicePolicyCache.getInstance();
                    if (cache instanceof DevicePolicyCacheImpl cacheImpl) {
                        cacheImpl.setContentProtectionPolicy(userId, value);
                    }
                });
        return true;
    }

    private static void updateScreenCaptureDisabled() {
        BackgroundThread.getHandler().post(() -> {
            try {