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

Commit f94912ab authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes Ic5179113,I57ddb1c3 into main

* changes:
  Don't stop MediaProjection sessions without display
  Allow keyguard capture when screenshare protections are disabled
parents 57ed2386 21b5c2f8
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static android.media.projection.ReviewGrantedConsentResult.RECORD_CANCEL;
import static android.media.projection.ReviewGrantedConsentResult.RECORD_CONTENT_DISPLAY;
import static android.media.projection.ReviewGrantedConsentResult.RECORD_CONTENT_TASK;
import static android.media.projection.ReviewGrantedConsentResult.UNKNOWN;
import static android.provider.Settings.Global.DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;

@@ -73,6 +74,7 @@ import android.os.PermissionEnforcer;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.ArrayMap;
import android.util.Slog;
import android.view.ContentRecordingSession;
@@ -195,6 +197,15 @@ public final class MediaProjectionManagerService extends SystemService
            if (mProjectionGrant == null || mProjectionGrant.packageName == null) {
                return false;
            }
            boolean disableScreenShareProtections = Settings.Global.getInt(
                    getContext().getContentResolver(),
                    DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS, 0) != 0;
            if (disableScreenShareProtections) {
                Slog.v(TAG,
                        "Allowing keyguard capture as screenshare protections are disabled.");
                return true;
            }

            if (mPackageManager.checkPermission(RECORD_SENSITIVE_CONTENT,
                    mProjectionGrant.packageName)
                    == PackageManager.PERMISSION_GRANTED) {
@@ -226,7 +237,8 @@ public final class MediaProjectionManagerService extends SystemService
    void onKeyguardLockedStateChanged(boolean isKeyguardLocked) {
        if (!isKeyguardLocked) return;
        synchronized (mLock) {
            if (mProjectionGrant != null && !canCaptureKeyguard()) {
            if (mProjectionGrant != null && !canCaptureKeyguard()
                    && mProjectionGrant.mVirtualDisplayId != INVALID_DISPLAY) {
                Slog.d(TAG, "Content Recording: Stopped MediaProjection"
                        + " due to keyguard lock");
                mProjectionGrant.stop();
+48 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import static android.media.projection.ReviewGrantedConsentResult.RECORD_CANCEL;
import static android.media.projection.ReviewGrantedConsentResult.RECORD_CONTENT_DISPLAY;
import static android.media.projection.ReviewGrantedConsentResult.RECORD_CONTENT_TASK;
import static android.media.projection.ReviewGrantedConsentResult.UNKNOWN;
import static android.provider.Settings.Global.DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS;
import static android.view.ContentRecordingSession.TARGET_UID_FULL_SCREEN;
import static android.view.ContentRecordingSession.TARGET_UID_UNKNOWN;
import static android.view.ContentRecordingSession.createDisplaySession;
@@ -80,6 +81,7 @@ import android.os.test.TestLooper;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import android.testing.TestableContext;
import android.view.ContentRecordingSession;
import android.view.ContentRecordingSession.RecordContent;
@@ -372,6 +374,50 @@ public class MediaProjectionManagerServiceTest {
        });
    }

    @EnableFlags(android.companion.virtualdevice.flags
            .Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS)
    @Test
    public void testCreateProjection_keyguardLocked_screenshareProtectionsDisabled()
            throws NameNotFoundException {
        MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
        int value = Settings.Global.getInt(mContext.getContentResolver(),
                DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS, 0);
        try {
            Settings.Global.putInt(mContext.getContentResolver(),
                    DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS, 1);
            doReturn(true).when(mKeyguardManager).isKeyguardLocked();

            doReturn(PackageManager.PERMISSION_DENIED).when(mPackageManager).checkPermission(
                    RECORD_SENSITIVE_CONTENT, projection.packageName);

            projection.start(mIMediaProjectionCallback);
            projection.notifyVirtualDisplayCreated(10);

            // The projection was started because it was allowed to capture the keyguard.
            assertThat(mService.getActiveProjectionInfo()).isNotNull();
        } finally {
            Settings.Global.putInt(mContext.getContentResolver(),
                    DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS, value);
        }
    }

    @EnableFlags(android.companion.virtualdevice.flags
            .Flags.FLAG_MEDIA_PROJECTION_KEYGUARD_RESTRICTIONS)
    @Test
    public void testCreateProjection_keyguardLocked_noDisplayCreated()
            throws NameNotFoundException {
        MediaProjectionManagerService.MediaProjection projection = startProjectionPreconditions();
        doReturn(true).when(mKeyguardManager).isKeyguardLocked();

        doReturn(PackageManager.PERMISSION_DENIED).when(mPackageManager).checkPermission(
                RECORD_SENSITIVE_CONTENT, projection.packageName);

        projection.start(mIMediaProjectionCallback);

        // The projection was started because it was allowed to capture the keyguard.
        assertThat(mService.getActiveProjectionInfo()).isNotNull();
    }

    @Test
    public void testCreateProjection_attemptReuse_noPriorProjectionGrant()
            throws NameNotFoundException {
@@ -485,6 +531,7 @@ public class MediaProjectionManagerServiceTest {
        MediaProjectionManagerService.MediaProjection projection =
                startProjectionPreconditions(service);
        projection.start(mIMediaProjectionCallback);
        projection.notifyVirtualDisplayCreated(10);

        assertThat(service.getActiveProjectionInfo()).isNotNull();

@@ -507,6 +554,7 @@ public class MediaProjectionManagerServiceTest {
        MediaProjectionManagerService.MediaProjection projection =
                startProjectionPreconditions(service);
        projection.start(mIMediaProjectionCallback);
        projection.notifyVirtualDisplayCreated(10);

        assertThat(service.getActiveProjectionInfo()).isNotNull();