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

Commit 8e935f77 authored by Alex Johnston's avatar Alex Johnston
Browse files

Modify Screen Capture Disabled APIs

* Previously, setScreenCapturedDisabled and getScreenCaptureDisabled
  did not support explicitly querying the parent profile.
* This CL allows the COPE profile owner call these APIs on the parent
  profile to disable screen capture device-wide.

Bug: 149006854
Test: atest com.android.cts.devicepolicy.OrgOwnedProfileOwnerTest#testScreenCaptureDisabled
      atest com.android.cts.devicepolicy.MixedDeviceOwnerTest#testScreenCaptureDisabled
      atest com.android.cts.devicepolicy.MixedDeviceOwnerTest#testScreenCaptureDisabled_assist
      atest com.android.cts.devicepolicy.MixedManagedProfileOwnerTest#testScreenCaptureDisabled_allowedPrimaryUser
      atest com.android.cts.devicepolicy.MixedDeviceOwnerTest#testCreateAdminSupportIntent

Change-Id: I64469af190577f66f48052c7f0df20067101aac4
parent c22d4531
Loading
Loading
Loading
Loading
+19 −8
Original line number Diff line number Diff line
@@ -5860,21 +5860,27 @@ public class DevicePolicyManager {
     * a secure video output. See {@link android.view.Display#FLAG_SECURE} for more details about
     * secure surfaces and secure displays.
     * <p>
     * The calling device admin must be a device or profile owner. If it is not, a security
     * This method can be called on the {@link DevicePolicyManager} instance, returned by
     * {@link #getParentProfileInstance(ComponentName)}, where the calling device admin must be
     * the profile owner of an organization-owned managed profile. If it is not, a security
     * exception will be thrown.
     * <p>
     * If the caller is device owner or called on the parent instance by a profile owner of an
     * organization-owned managed profile, then the restriction will be applied to all users.
     * <p>
     * From version {@link android.os.Build.VERSION_CODES#M} disabling screen capture also blocks
     * assist requests for all activities of the relevant user.
     *
     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
     * @param disabled Whether screen capture is disabled or not.
     * @throws SecurityException if {@code admin} is not a device or profile owner.
     * @throws SecurityException if {@code admin} is not a device or profile owner or if
     *                           called on the parent profile and the {@code admin} is not a
     *                           profile owner of an organization-owned managed profile.
     */
    public void setScreenCaptureDisabled(@NonNull ComponentName admin, boolean disabled) {
        throwIfParentInstance("setScreenCaptureDisabled");
        if (mService != null) {
            try {
                mService.setScreenCaptureDisabled(admin, disabled);
                mService.setScreenCaptureDisabled(admin, disabled, mParentInstance);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
@@ -5884,11 +5890,16 @@ public class DevicePolicyManager {
    /**
     * Determine whether or not screen capture has been disabled by the calling
     * admin, if specified, or all admins.
     * @param admin The name of the admin component to check, or {@code null} to check whether any admins
     * have disabled screen capture.
     * <p>
     * This method can be called on the {@link DevicePolicyManager} instance,
     * returned by {@link #getParentProfileInstance(ComponentName)}, where the caller must be
     * the profile owner of an organization-owned managed profile (the calling admin must be
     * specified).
     *
     * @param admin The name of the admin component to check, or {@code null} to check whether any
     *              admins have disabled screen capture.
     */
    public boolean getScreenCaptureDisabled(@Nullable ComponentName admin) {
        throwIfParentInstance("getScreenCaptureDisabled");
        return getScreenCaptureDisabled(admin, myUserId());
    }
@@ -5896,7 +5907,7 @@ public class DevicePolicyManager {
    public boolean getScreenCaptureDisabled(@Nullable ComponentName admin, int userHandle) {
        if (mService != null) {
            try {
                return mService.getScreenCaptureDisabled(admin, userHandle);
                return mService.getScreenCaptureDisabled(admin, userHandle, mParentInstance);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
+2 −2
Original line number Diff line number Diff line
@@ -121,8 +121,8 @@ interface IDevicePolicyManager {
    void setCameraDisabled(in ComponentName who, boolean disabled, boolean parent);
    boolean getCameraDisabled(in ComponentName who, int userHandle, boolean parent);

    void setScreenCaptureDisabled(in ComponentName who, boolean disabled);
    boolean getScreenCaptureDisabled(in ComponentName who, int userHandle);
    void setScreenCaptureDisabled(in ComponentName who, boolean disabled, boolean parent);
    boolean getScreenCaptureDisabled(in ComponentName who, int userHandle, boolean parent);

    void setKeyguardDisabledFeatures(in ComponentName who, int which, boolean parent);
    int getKeyguardDisabledFeatures(in ComponentName who, int userHandle, boolean parent);
+25 −19
Original line number Diff line number Diff line
@@ -3957,7 +3957,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
    @Override
    void handleStartUser(int userId) {
        updateScreenCaptureDisabled(userId,
                getScreenCaptureDisabled(null, userId));
                getScreenCaptureDisabled(null, userId, false));
        pushUserRestrictions(userId);
        // When system user is started (device boot), load cache for all users.
        // This is to mitigate the potential race between loading the cache and keyguard
@@ -7566,7 +7566,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
     * Set whether the screen capture is disabled for the user managed by the specified admin.
     */
    @Override
    public void setScreenCaptureDisabled(ComponentName who, boolean disabled) {
    public void setScreenCaptureDisabled(ComponentName who, boolean disabled, boolean parent) {
        if (!mHasFeature) {
            return;
        }
@@ -7574,11 +7574,15 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        final int userHandle = UserHandle.getCallingUserId();
        synchronized (getLockObject()) {
            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
                    DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
                    DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, parent);
            if (parent) {
                enforceProfileOwnerOfOrganizationOwnedDevice(ap);
            }
            if (ap.disableScreenCapture != disabled) {
                ap.disableScreenCapture = disabled;
                saveSettingsLocked(userHandle);
                updateScreenCaptureDisabled(userHandle, disabled);
                final int affectedUserId = parent ? getProfileParentId(userHandle) : userHandle;
                updateScreenCaptureDisabled(affectedUserId, disabled);
            }
        }
        DevicePolicyEventLogger
@@ -7593,20 +7597,25 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
     * active admin (if given admin is null).
     */
    @Override
    public boolean getScreenCaptureDisabled(ComponentName who, int userHandle) {
    public boolean getScreenCaptureDisabled(ComponentName who, int userHandle, boolean parent) {
        if (!mHasFeature) {
            return false;
        }
        synchronized (getLockObject()) {
            if (parent) {
                final ActiveAdmin ap = getActiveAdminForCallerLocked(who,
                        DeviceAdminInfo.USES_POLICY_ORGANIZATION_OWNED_PROFILE_OWNER, parent);
                enforceProfileOwnerOfOrganizationOwnedDevice(ap);
            }
            if (who != null) {
                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
                return (admin != null) ? admin.disableScreenCapture : false;
                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
                return (admin != null) && admin.disableScreenCapture;
            }
            DevicePolicyData policy = getUserData(userHandle);
            final int N = policy.mAdminList.size();
            for (int i = 0; i < N; i++) {
                ActiveAdmin admin = policy.mAdminList.get(i);
            boolean includeParent = isOrganizationOwnedDeviceWithManagedProfile()
                    && !isManagedProfile(userHandle);
            List<ActiveAdmin> admins = getActiveAdminsForAffectedUser(userHandle, includeParent);
            for (ActiveAdmin admin: admins) {
                if (admin.disableScreenCapture) {
                    return true;
                }
@@ -7617,15 +7626,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
    private void updateScreenCaptureDisabled(int userHandle, boolean disabled) {
        mPolicyCache.setScreenCaptureDisabled(userHandle, disabled);
        mHandler.post(new Runnable() {
            @Override
            public void run() {
        mHandler.post(() -> {
            try {
                mInjector.getIWindowManager().refreshScreenCaptureDisabled(userHandle);
            } catch (RemoteException e) {
                Log.w(LOG_TAG, "Unable to notify WindowManager.", e);
            }
            }
        });
    }