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

This commit is contained in:
Kholoud Mohamed
2023-05-04 09:03:48 +00:00
committed by Android (Google) Code Review
5 changed files with 154 additions and 36 deletions

View File

@@ -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,9 +79,21 @@ 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 mScreenCaptureDisallowedUser != UserHandle.USER_ALL
&& mScreenCaptureDisallowedUser != userHandle;
return !mScreenCaptureDisallowedUsers.contains(userHandle)
&& !mScreenCaptureDisallowedUsers.contains(UserHandle.USER_ALL);
}
}
@@ -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();
pw.println("Screen capture disallowed user: " + mScreenCaptureDisallowedUser);
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());

View File

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

View File

@@ -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,23 +8656,47 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
synchronized (getLockObject()) {
ActiveAdmin ap;
if (isPermissionCheckFlagEnabled()) {
int callerUserId = Binder.getCallingUserHandle().getIdentifier();
int targetUserId = parent ? getProfileParentId(callerUserId) : callerUserId;
ap = enforcePermissionAndGetEnforcingAdmin(
who, MANAGE_DEVICE_POLICY_SCREEN_CAPTURE, caller.getPackageName(),
targetUserId).getActiveAdmin();
if (isPolicyEngineForFinanceFlagEnabled()) {
int callerUserId = Binder.getCallingUserHandle().getIdentifier();
int targetUserId = parent ? getProfileParentId(callerUserId) : callerUserId;
EnforcingAdmin admin = enforcePermissionAndGetEnforcingAdmin(
who, MANAGE_DEVICE_POLICY_SCREEN_CAPTURE, caller.getPackageName(),
targetUserId);
if ((parent && isProfileOwnerOfOrganizationOwnedDevice(caller))
|| isDefaultDeviceOwner(caller)) {
if (disabled) {
mDevicePolicyEngine.setGlobalPolicy(
PolicyDefinition.SCREEN_CAPTURE_DISABLED,
admin,
new BooleanPolicyValue(disabled));
} else {
mDevicePolicyEngine.removeGlobalPolicy(
PolicyDefinition.SCREEN_CAPTURE_DISABLED,
admin);
}
} else {
ap = getParentOfAdminIfRequired(
getProfileOwnerOrDefaultDeviceOwnerLocked(caller.getUserId()), parent);
if (disabled) {
mDevicePolicyEngine.setLocalPolicy(
PolicyDefinition.SCREEN_CAPTURE_DISABLED,
admin,
new BooleanPolicyValue(disabled),
callerUserId);
} else {
mDevicePolicyEngine.removeLocalPolicy(
PolicyDefinition.SCREEN_CAPTURE_DISABLED,
admin,
callerUserId);
}
}
if (ap.disableScreenCapture != disabled) {
ap.disableScreenCapture = disabled;
saveSettingsLocked(caller.getUserId());
pushScreenCapturePolicy(caller.getUserId());
} else {
synchronized (getLockObject()) {
ActiveAdmin ap = getParentOfAdminIfRequired(
getProfileOwnerOrDefaultDeviceOwnerLocked(caller.getUserId()), parent);
if (ap.disableScreenCapture != disabled) {
ap.disableScreenCapture = disabled;
saveSettingsLocked(caller.getUserId());
pushScreenCapturePolicy(caller.getUserId());
}
}
}
DevicePolicyEventLogger
@@ -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,7 +8768,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
Preconditions.checkCallAuthorization(
isProfileOwnerOfOrganizationOwnedDevice(getCallerIdentity().getUserId()));
}
return !mPolicyCache.isScreenCaptureAllowed(userHandle);
if (isPolicyEngineForFinanceFlagEnabled()) {
Boolean disallowed = mDevicePolicyEngine.getResolvedPolicy(
PolicyDefinition.SCREEN_CAPTURE_DISABLED,
userHandle);
return disallowed != null && disallowed;
} else {
return !mPolicyCache.isScreenCaptureAllowed(userHandle);
}
}
private void updateScreenCaptureDisabled() {
@@ -16306,17 +16339,27 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return result;
}
} else if (DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE.equals(restriction)) {
synchronized (getLockObject()) {
final DevicePolicyData policy = getUserData(userId);
final int N = policy.mAdminList.size();
for (int i = 0; i < N; i++) {
final ActiveAdmin admin = policy.mAdminList.get(i);
if (admin.disableScreenCapture) {
result = new Bundle();
result.putInt(Intent.EXTRA_USER_ID, userId);
result.putParcelable(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
admin.info.getComponent());
return result;
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();
for (int i = 0; i < N; i++) {
final ActiveAdmin admin = policy.mAdminList.get(i);
if (admin.disableScreenCapture) {
result = new Bundle();
result.putInt(Intent.EXTRA_USER_ID, userId);
result.putParcelable(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
admin.info.getComponent());
return result;
}
}
}
}
@@ -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,

View File

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

View File

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