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

Commit 211876fa authored by Naomi Musgrave's avatar Naomi Musgrave
Browse files

[Partial Screenshare] pause mirroring when the task is in PIP

To avoid malformed transformations due to inaccurate bounds
when the task is in PIP. pause recording entirely when the
task enters PIP and resume when the task leaves PIP.

Bug: 297514518
Test: atest WmTests:ContentRecorderTests
Test: manual MediaProjection smoke tests, change windowing modes
Change-Id: I92ba7a211d0c719e60d8a397f2ba1b250903eb01
parent b2b6b910
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -1015,6 +1015,12 @@
      "group": "WM_DEBUG_REMOTE_ANIMATIONS",
      "at": "com\/android\/server\/wm\/NonAppWindowAnimationAdapter.java"
    },
    "-1152771606": {
      "message": "Content Recording: Display %d was already recording, but pause capture since the task is in PIP",
      "level": "VERBOSE",
      "group": "WM_DEBUG_CONTENT_RECORDING",
      "at": "com\/android\/server\/wm\/ContentRecorder.java"
    },
    "-1145384901": {
      "message": "shouldWaitAnimatingExit: isTransition: %s",
      "level": "DEBUG",
@@ -2323,6 +2329,12 @@
      "group": "WM_DEBUG_SYNC_ENGINE",
      "at": "com\/android\/server\/wm\/WindowState.java"
    },
    "1877956": {
      "message": "Content Recording: Display %d should start recording, but don't yet since the task is in PIP",
      "level": "VERBOSE",
      "group": "WM_DEBUG_CONTENT_RECORDING",
      "at": "com\/android\/server\/wm\/ContentRecorder.java"
    },
    "3593205": {
      "message": "commitVisibility: %s: visible=%b mVisibleRequested=%b",
      "level": "VERBOSE",
+25 −3
Original line number Diff line number Diff line
@@ -151,6 +151,20 @@ final class ContentRecorder implements WindowContainerListener {
                return;
            }

            // TODO(b/297514518) Do not start capture if the app is in PIP, the bounds are
            //  inaccurate.
            if (mContentRecordingSession.getContentToRecord() == RECORD_CONTENT_TASK) {
                final Task capturedTask = mRecordedWindowContainer.asTask();
                if (capturedTask.inPinnedWindowingMode()) {
                    ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
                            "Content Recording: Display %d was already recording, but "
                                    + "pause capture since the task is in PIP",
                            mDisplayContent.getDisplayId());
                    pauseRecording();
                    return;
                }
            }

            ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
                    "Content Recording: Display %d was already recording, so apply "
                            + "transformations if necessary",
@@ -292,6 +306,17 @@ final class ContentRecorder implements WindowContainerListener {
            return;
        }

        // TODO(b/297514518) Do not start capture if the app is in PIP, the bounds are inaccurate.
        if (mContentRecordingSession.getContentToRecord() == RECORD_CONTENT_TASK) {
            if (mRecordedWindowContainer.asTask().inPinnedWindowingMode()) {
                ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
                        "Content Recording: Display %d should start recording, but "
                                + "don't yet since the task is in PIP",
                        mDisplayContent.getDisplayId());
                return;
            }
        }

        final Point surfaceSize = fetchSurfaceSizeIfPresent();
        if (surfaceSize == null) {
            ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
@@ -305,9 +330,6 @@ final class ContentRecorder implements WindowContainerListener {
                        + "state %d",
                mDisplayContent.getDisplayId(), mDisplayContent.getDisplayInfo().state);

        // TODO(b/274790702): Do not start recording if waiting for consent - for now,
        //  go ahead.

        // Create a mirrored hierarchy for the SurfaceControl of the DisplayArea to capture.
        mRecordedSurface = SurfaceControl.mirrorSurface(
                mRecordedWindowContainer.getSurfaceControl());
+75 −0
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package com.android.server.wm;

import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
@@ -359,6 +362,39 @@ public class ContentRecorderTests extends WindowTestsBase {
                recordedWidth, recordedHeight);
    }

    @Test
    public void testTaskWindowingModeChanged_pip_stopsRecording() {
        // WHEN a recording is ongoing.
        mTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
        mContentRecorder.setContentRecordingSession(mTaskSession);
        mContentRecorder.updateRecording();
        assertThat(mContentRecorder.isCurrentlyRecording()).isTrue();

        // WHEN a configuration change arrives, and the task is now pinned.
        mTask.setWindowingMode(WINDOWING_MODE_PINNED);
        Configuration configuration = mTask.getConfiguration();
        mTask.onConfigurationChanged(configuration);

        // THEN recording is paused.
        assertThat(mContentRecorder.isCurrentlyRecording()).isFalse();
    }

    @Test
    public void testTaskWindowingModeChanged_fullscreen_startsRecording() {
        // WHEN a recording is ongoing.
        mTask.setWindowingMode(WINDOWING_MODE_PINNED);
        mContentRecorder.setContentRecordingSession(mTaskSession);
        mContentRecorder.updateRecording();
        assertThat(mContentRecorder.isCurrentlyRecording()).isFalse();

        // WHEN the task is now fullscreen.
        mTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
        mContentRecorder.updateRecording();

        // THEN recording is started.
        assertThat(mContentRecorder.isCurrentlyRecording()).isTrue();
    }

    @Test
    public void testStartRecording_notifiesCallback_taskSession() {
        // WHEN a recording is ongoing.
@@ -383,6 +419,45 @@ public class ContentRecorderTests extends WindowTestsBase {
                .notifyActiveProjectionCapturedContentVisibilityChanged(true);
    }

    @Test
    public void testStartRecording_taskInPIP_recordingNotStarted() {
        // GIVEN a task is in PIP.
        mContentRecorder.setContentRecordingSession(mTaskSession);
        mTask.setWindowingMode(WINDOWING_MODE_PINNED);

        // WHEN a recording tries to start.
        mContentRecorder.updateRecording();

        // THEN recording does not start.
        assertThat(mContentRecorder.isCurrentlyRecording()).isFalse();
    }

    @Test
    public void testStartRecording_taskInSplit_recordingStarted() {
        // GIVEN a task is in PIP.
        mContentRecorder.setContentRecordingSession(mTaskSession);
        mTask.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);

        // WHEN a recording tries to start.
        mContentRecorder.updateRecording();

        // THEN recording does not start.
        assertThat(mContentRecorder.isCurrentlyRecording()).isTrue();
    }

    @Test
    public void testStartRecording_taskInFullscreen_recordingStarted() {
        // GIVEN a task is in PIP.
        mContentRecorder.setContentRecordingSession(mTaskSession);
        mTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);

        // WHEN a recording tries to start.
        mContentRecorder.updateRecording();

        // THEN recording does not start.
        assertThat(mContentRecorder.isCurrentlyRecording()).isTrue();
    }

    @Test
    public void testOnVisibleRequestedChanged_notifiesCallback() {
        // WHEN a recording is ongoing.