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

Commit 4e14f566 authored by Kholoud Mohamed's avatar Kholoud Mohamed Committed by Android (Google) Code Review
Browse files

Merge "Migrate screen capture disabled to the policy engine" into udc-dev

parents be630d36 3b2c9426
Loading
Loading
Loading
Loading
+38 −3
Original line number Diff line number Diff line
@@ -25,7 +25,9 @@ import android.util.SparseIntArray;

import com.android.internal.annotations.GuardedBy;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

/**
@@ -48,6 +50,13 @@ public class DevicePolicyCacheImpl extends DevicePolicyCache {
    @GuardedBy("mLock")
    private int mScreenCaptureDisallowedUser = UserHandle.USER_NULL;

    /**
     * Indicates if screen capture is disallowed on a specific user or all users if
     * it contains {@link UserHandle#USER_ALL}.
     */
    @GuardedBy("mLock")
    private Set<Integer> mScreenCaptureDisallowedUsers = new HashSet<>();

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

@@ -70,11 +79,23 @@ public class DevicePolicyCacheImpl extends DevicePolicyCache {

    @Override
    public boolean isScreenCaptureAllowed(int userHandle) {
        if (DevicePolicyManagerService.isPolicyEngineForFinanceFlagEnabled()) {
            return isScreenCaptureAllowedInPolicyEngine(userHandle);
        } else {
            synchronized (mLock) {
                return mScreenCaptureDisallowedUser != UserHandle.USER_ALL
                        && mScreenCaptureDisallowedUser != userHandle;
            }
        }
    }

    private boolean isScreenCaptureAllowedInPolicyEngine(int userHandle) {
        // This won't work if resolution mechanism is not strictest applies, but it's ok for now.
        synchronized (mLock) {
            return !mScreenCaptureDisallowedUsers.contains(userHandle)
                    && !mScreenCaptureDisallowedUsers.contains(UserHandle.USER_ALL);
        }
    }

    public int getScreenCaptureDisallowedUser() {
        synchronized (mLock) {
@@ -88,6 +109,16 @@ public class DevicePolicyCacheImpl extends DevicePolicyCache {
        }
    }

    public void setScreenCaptureDisallowedUser(int userHandle, boolean disallowed) {
        synchronized (mLock) {
            if (disallowed) {
                mScreenCaptureDisallowedUsers.add(userHandle);
            } else {
                mScreenCaptureDisallowedUsers.remove(userHandle);
            }
        }
    }

    @Override
    public int getPasswordQuality(@UserIdInt int userHandle) {
        synchronized (mLock) {
@@ -151,7 +182,11 @@ public class DevicePolicyCacheImpl extends DevicePolicyCache {
        synchronized (mLock) {
            pw.println("Device policy cache:");
            pw.increaseIndent();
            if (DevicePolicyManagerService.isPolicyEngineForFinanceFlagEnabled()) {
                pw.println("Screen capture disallowed users: " + mScreenCaptureDisallowedUsers);
            } else {
                pw.println("Screen capture disallowed user: " + mScreenCaptureDisallowedUser);
            }
            pw.println("Password quality: " + mPasswordQuality);
            pw.println("Permission policy: " + mPermissionPolicy);
            pw.println("Admin can grant sensors permission: " + mCanGrantSensorsPermissions.get());
+1 −2
Original line number Diff line number Diff line
@@ -546,8 +546,7 @@ final class DevicePolicyEngine {
            if (hasLocalPolicyLocked(policyDefinition, userId)) {
                resolvedValue = getLocalPolicyStateLocked(
                        policyDefinition, userId).getCurrentResolvedPolicy();
            }
            if (hasGlobalPolicyLocked(policyDefinition)) {
            } else if (hasGlobalPolicyLocked(policyDefinition)) {
                resolvedValue = getGlobalPolicyStateLocked(
                        policyDefinition).getCurrentResolvedPolicy();
            }
+74 −31
Original line number Diff line number Diff line
@@ -8642,7 +8642,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        }
        CallerIdentity caller;
        if (isPermissionCheckFlagEnabled()) {
        if (isPolicyEngineForFinanceFlagEnabled()) {
            caller = getCallerIdentity(who, callerPackage);
        } else {
            Objects.requireNonNull(who, "ComponentName is null");
@@ -8656,25 +8656,49 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            }
        }
        synchronized (getLockObject()) {
            ActiveAdmin ap;
            if (isPermissionCheckFlagEnabled()) {
        if (isPolicyEngineForFinanceFlagEnabled()) {
            int callerUserId = Binder.getCallingUserHandle().getIdentifier();
            int targetUserId = parent ? getProfileParentId(callerUserId) : callerUserId;
                ap = enforcePermissionAndGetEnforcingAdmin(
            EnforcingAdmin admin = enforcePermissionAndGetEnforcingAdmin(
                    who, MANAGE_DEVICE_POLICY_SCREEN_CAPTURE, caller.getPackageName(),
                        targetUserId).getActiveAdmin();
                    targetUserId);
            if ((parent && isProfileOwnerOfOrganizationOwnedDevice(caller))
                    || isDefaultDeviceOwner(caller)) {
                if (disabled) {
                    mDevicePolicyEngine.setGlobalPolicy(
                            PolicyDefinition.SCREEN_CAPTURE_DISABLED,
                            admin,
                            new BooleanPolicyValue(disabled));
                } else {
                ap = getParentOfAdminIfRequired(
                        getProfileOwnerOrDefaultDeviceOwnerLocked(caller.getUserId()), parent);
                    mDevicePolicyEngine.removeGlobalPolicy(
                            PolicyDefinition.SCREEN_CAPTURE_DISABLED,
                            admin);
                }
            } else {
                if (disabled) {
                    mDevicePolicyEngine.setLocalPolicy(
                            PolicyDefinition.SCREEN_CAPTURE_DISABLED,
                            admin,
                            new BooleanPolicyValue(disabled),
                            callerUserId);
                } else {
                    mDevicePolicyEngine.removeLocalPolicy(
                            PolicyDefinition.SCREEN_CAPTURE_DISABLED,
                            admin,
                            callerUserId);
                }
            }
        } else {
            synchronized (getLockObject()) {
                ActiveAdmin ap = getParentOfAdminIfRequired(
                        getProfileOwnerOrDefaultDeviceOwnerLocked(caller.getUserId()), parent);
                if (ap.disableScreenCapture != disabled) {
                    ap.disableScreenCapture = disabled;
                    saveSettingsLocked(caller.getUserId());
                    pushScreenCapturePolicy(caller.getUserId());
                }
            }
        }
        DevicePolicyEventLogger
                .createEvent(DevicePolicyEnums.SET_SCREEN_CAPTURE_DISABLED)
                .setAdmin(caller.getPackageName())
@@ -8686,6 +8710,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
    // DO or COPE PO on the parent profile, then this takes precedence as screen capture will
    // be disabled device-wide.
    private void pushScreenCapturePolicy(int adminUserId) {
        if (isPolicyEngineForFinanceFlagEnabled()) {
            return;
        }
        // Update screen capture device-wide if disabled by the DO or COPE PO on the parent profile.
        // TODO(b/261999445): remove
        ActiveAdmin admin;
@@ -8727,8 +8754,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
    }
    /**
     * Returns whether or not screen capture is disabled for a given admin, or disabled for any
     * active admin (if given admin is null).
     * Returns whether or not screen capture is disabled for  any active admin.
     */
    @Override
    public boolean getScreenCaptureDisabled(ComponentName who, int userHandle, boolean parent) {
@@ -8742,8 +8768,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            Preconditions.checkCallAuthorization(
                    isProfileOwnerOfOrganizationOwnedDevice(getCallerIdentity().getUserId()));
        }
        if (isPolicyEngineForFinanceFlagEnabled()) {
            Boolean disallowed = mDevicePolicyEngine.getResolvedPolicy(
                    PolicyDefinition.SCREEN_CAPTURE_DISABLED,
                    userHandle);
            return disallowed != null && disallowed;
        } else {
            return !mPolicyCache.isScreenCaptureAllowed(userHandle);
        }
    }
    private void updateScreenCaptureDisabled() {
        mHandler.post(() -> {
@@ -16306,6 +16339,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                return result;
            }
        } else if (DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE.equals(restriction)) {
            if (isPolicyEngineForFinanceFlagEnabled()) {
                Boolean value = mDevicePolicyEngine.getResolvedPolicy(
                        PolicyDefinition.SCREEN_CAPTURE_DISABLED, userId);
                if (value != null && value) {
                    result = new Bundle();
                    result.putInt(Intent.EXTRA_USER_ID, userId);
                    return result;
                }
            } else {
                synchronized (getLockObject()) {
                    final DevicePolicyData policy = getUserData(userId);
                    final int N = policy.mAdminList.size();
@@ -16320,6 +16362,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                        }
                    }
                }
            }
        } else if (DevicePolicyManager.POLICY_DISABLE_CAMERA.equals(restriction)) {
            if (isPolicyEngineForFinanceFlagEnabled()) {
                PolicyDefinition<Boolean> policyDefinition =
@@ -23646,7 +23689,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                DEFAULT_VALUE_PERMISSION_BASED_ACCESS_FLAG);
    }
    private boolean isPolicyEngineForFinanceFlagEnabled() {
    static boolean isPolicyEngineForFinanceFlagEnabled() {
        return DeviceConfig.getBoolean(
                NAMESPACE_DEVICE_POLICY_MANAGER,
                ENABLE_DEVICE_POLICY_ENGINE_FOR_FINANCE_FLAG,
+10 −0
Original line number Diff line number Diff line
@@ -315,6 +315,14 @@ final class PolicyDefinition<V> {
            (Set<String> value, Context context, Integer userId, PolicyKey policyKey) -> true,
            new StringSetPolicySerializer());


    static PolicyDefinition<Boolean> SCREEN_CAPTURE_DISABLED = new PolicyDefinition<>(
            new NoArgsPolicyKey(DevicePolicyIdentifiers.SCREEN_CAPTURE_DISABLED_POLICY),
            TRUE_MORE_RESTRICTIVE,
            /* flags= */ 0,
            PolicyEnforcerCallbacks::setScreenCaptureDisabled,
            new BooleanPolicySerializer());

    private static final Map<String, PolicyDefinition<?>> POLICY_DEFINITIONS = new HashMap<>();
    private static Map<String, Integer> USER_RESTRICTION_FLAGS = new HashMap<>();

@@ -342,6 +350,8 @@ final class PolicyDefinition<V> {
                GENERIC_ACCOUNT_MANAGEMENT_DISABLED);
        POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.PERMITTED_INPUT_METHODS_POLICY,
                PERMITTED_INPUT_METHODS);
        POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.SCREEN_CAPTURE_DISABLED_POLICY,
                SCREEN_CAPTURE_DISABLED);

        // User Restriction Policies
        USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_MODIFY_ACCOUNTS, /* flags= */ 0);
+31 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.devicepolicy;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppGlobals;
import android.app.admin.DevicePolicyCache;
import android.app.admin.DevicePolicyManager;
import android.app.admin.IntentFilterPolicyKey;
import android.app.admin.LockTaskPolicy;
@@ -35,13 +36,16 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.os.Binder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.permission.AdminPermissionControlParams;
import android.permission.PermissionControllerManager;
import android.provider.Settings;
import android.util.ArraySet;
import android.util.Slog;
import android.view.IWindowManager;

import com.android.internal.os.BackgroundThread;
import com.android.server.LocalServices;
import com.android.server.pm.UserManagerInternal;
import com.android.server.utils.Slogf;
@@ -244,4 +248,31 @@ final class PolicyEnforcerCallbacks {
                    packageName, hide != null && hide, userId);
        }));
    }

    static boolean setScreenCaptureDisabled(
            @Nullable Boolean disabled, @NonNull Context context, int userId,
            @NonNull PolicyKey policyKey) {
        Binder.withCleanCallingIdentity(() -> {
            DevicePolicyCache cache = DevicePolicyCache.getInstance();
            if (cache instanceof DevicePolicyCacheImpl) {
                DevicePolicyCacheImpl parsedCache = (DevicePolicyCacheImpl) cache;
                parsedCache.setScreenCaptureDisallowedUser(
                        userId, disabled != null && disabled);
                updateScreenCaptureDisabled();
            }
        });
        return true;
    }

    private static void updateScreenCaptureDisabled() {
        BackgroundThread.getHandler().post(() -> {
            try {
                IWindowManager.Stub
                        .asInterface(ServiceManager.getService(Context.WINDOW_SERVICE))
                        .refreshScreenCaptureDisabled();
            } catch (RemoteException e) {
                Slogf.w(LOG_TAG, "Unable to notify WindowManager.", e);
            }
        });
    }
}