diff options
3 files changed, 75 insertions, 10 deletions
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index 71e9263915ee..b6c39c67954d 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -3055,6 +3055,12 @@ "group": "WM_DEBUG_REMOTE_ANIMATIONS", "at": "com\/android\/server\/wm\/RemoteAnimationController.java" }, + "643263584": { + "message": "Content Recording: Apply transformations of shift %d x %d, scale %f, crop %d x %d for display %d", + "level": "VERBOSE", + "group": "WM_DEBUG_CONTENT_RECORDING", + "at": "com\/android\/server\/wm\/ContentRecorder.java" + }, "644675193": { "message": "Real start recents", "level": "DEBUG", diff --git a/services/core/java/com/android/server/wm/ContentRecorder.java b/services/core/java/com/android/server/wm/ContentRecorder.java index 5aa7c97ecb08..f0e4149a9159 100644 --- a/services/core/java/com/android/server/wm/ContentRecorder.java +++ b/services/core/java/com/android/server/wm/ContentRecorder.java @@ -35,6 +35,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.provider.DeviceConfig; import android.view.ContentRecordingSession; +import android.view.ContentRecordingSession.RecordContent; import android.view.Display; import android.view.SurfaceControl; @@ -84,6 +85,7 @@ final class ContentRecorder implements WindowContainerListener { /** * The last configuration orientation. */ + @Configuration.Orientation private int mLastOrientation = ORIENTATION_UNDEFINED; ContentRecorder(@NonNull DisplayContent displayContent) { @@ -156,7 +158,8 @@ final class ContentRecorder implements WindowContainerListener { // Retrieve the size of the region to record, and continue with the update // if the bounds or orientation has changed. final Rect recordedContentBounds = mRecordedWindowContainer.getBounds(); - int recordedContentOrientation = mRecordedWindowContainer.getOrientation(); + @Configuration.Orientation int recordedContentOrientation = + mRecordedWindowContainer.getConfiguration().orientation; if (!mLastRecordedBounds.equals(recordedContentBounds) || lastOrientation != recordedContentOrientation) { Point surfaceSize = fetchSurfaceSizeIfPresent(); @@ -356,7 +359,7 @@ final class ContentRecorder implements WindowContainerListener { */ @Nullable private WindowContainer retrieveRecordedWindowContainer() { - final int contentToRecord = mContentRecordingSession.getContentToRecord(); + @RecordContent final int contentToRecord = mContentRecordingSession.getContentToRecord(); final IBinder tokenToRecord = mContentRecordingSession.getTokenToRecord(); switch (contentToRecord) { case RECORD_CONTENT_DISPLAY: @@ -472,6 +475,12 @@ final class ContentRecorder implements WindowContainerListener { shiftedY = (surfaceSize.y - scaledHeight) / 2; } + ProtoLog.v(WM_DEBUG_CONTENT_RECORDING, + "Content Recording: Apply transformations of shift %d x %d, scale %f, crop %d x " + + "%d for display %d", + shiftedX, shiftedY, scale, recordedContentBounds.width(), + recordedContentBounds.height(), mDisplayContent.getDisplayId()); + transaction // Crop the area to capture to exclude the 'extra' wallpaper that is used // for parallax (b/189930234). diff --git a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java index bbec091b9924..aa2b93506f8e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java @@ -16,6 +16,8 @@ package com.android.server.wm; +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; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; @@ -76,6 +78,7 @@ import java.util.concurrent.CountDownLatch; @RunWith(WindowTestRunner.class) public class ContentRecorderTests extends WindowTestsBase { private static IBinder sTaskWindowContainerToken; + private DisplayContent mVirtualDisplayContent; private Task mTask; private final ContentRecordingSession mDisplaySession = ContentRecordingSession.createDisplaySession(DEFAULT_DISPLAY); @@ -106,11 +109,11 @@ public class ContentRecorderTests extends WindowTestsBase { displayInfo.logicalWidth = sSurfaceSize.x; displayInfo.logicalHeight = sSurfaceSize.y; displayInfo.state = STATE_ON; - final DisplayContent virtualDisplayContent = createNewDisplay(displayInfo); - final int displayId = virtualDisplayContent.getDisplayId(); - mContentRecorder = new ContentRecorder(virtualDisplayContent, + mVirtualDisplayContent = createNewDisplay(displayInfo); + final int displayId = mVirtualDisplayContent.getDisplayId(); + mContentRecorder = new ContentRecorder(mVirtualDisplayContent, mMediaProjectionManagerWrapper); - spyOn(virtualDisplayContent); + spyOn(mVirtualDisplayContent); // GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to // record. @@ -118,7 +121,7 @@ public class ContentRecorderTests extends WindowTestsBase { mDisplaySession.setDisplayToRecord(mDefaultDisplay.mDisplayId); // GIVEN there is a window token associated with a task to record. - sTaskWindowContainerToken = setUpTaskWindowContainerToken(virtualDisplayContent); + sTaskWindowContainerToken = setUpTaskWindowContainerToken(mVirtualDisplayContent); mTaskSession = ContentRecordingSession.createTaskSession(sTaskWindowContainerToken); mTaskSession.setVirtualDisplayId(displayId); @@ -251,7 +254,11 @@ public class ContentRecorderTests extends WindowTestsBase { public void testOnConfigurationChanged_resizesSurface() { mContentRecorder.setContentRecordingSession(mDisplaySession); mContentRecorder.updateRecording(); - mContentRecorder.onConfigurationChanged(ORIENTATION_PORTRAIT); + // Ensure a different orientation when we check if something has changed. + @Configuration.Orientation final int lastOrientation = + mDisplayContent.getConfiguration().orientation == ORIENTATION_PORTRAIT + ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT; + mContentRecorder.onConfigurationChanged(lastOrientation); verify(mTransaction, atLeast(2)).setPosition(eq(mRecordedSurface), anyFloat(), anyFloat()); @@ -260,12 +267,53 @@ public class ContentRecorderTests extends WindowTestsBase { } @Test + public void testOnConfigurationChanged_resizesVirtualDisplay() { + final int newWidth = 55; + mContentRecorder.setContentRecordingSession(mDisplaySession); + mContentRecorder.updateRecording(); + + // The user rotates the device, so the host app resizes the virtual display for the capture. + resizeDisplay(mDisplayContent, newWidth, sSurfaceSize.y); + resizeDisplay(mVirtualDisplayContent, newWidth, sSurfaceSize.y); + mContentRecorder.onConfigurationChanged(mDisplayContent.getConfiguration().orientation); + + verify(mTransaction, atLeast(2)).setPosition(eq(mRecordedSurface), anyFloat(), + anyFloat()); + verify(mTransaction, atLeast(2)).setMatrix(eq(mRecordedSurface), anyFloat(), anyFloat(), + anyFloat(), anyFloat()); + } + + @Test + public void testOnConfigurationChanged_rotateVirtualDisplay() { + mContentRecorder.setContentRecordingSession(mDisplaySession); + mContentRecorder.updateRecording(); + + // Change a value that we shouldn't rely upon; it has the wrong type. + mVirtualDisplayContent.setOverrideOrientation(SCREEN_ORIENTATION_FULL_SENSOR); + mContentRecorder.onConfigurationChanged( + mVirtualDisplayContent.getConfiguration().orientation); + + // No resize is issued, only the initial transformations when we started recording. + verify(mTransaction).setPosition(eq(mRecordedSurface), anyFloat(), + anyFloat()); + verify(mTransaction).setMatrix(eq(mRecordedSurface), anyFloat(), anyFloat(), + anyFloat(), anyFloat()); + } + + @Test public void testOnTaskOrientationConfigurationChanged_resizesSurface() { mContentRecorder.setContentRecordingSession(mTaskSession); mContentRecorder.updateRecording(); Configuration config = mTask.getConfiguration(); - config.orientation = ORIENTATION_PORTRAIT; + // Ensure a different orientation when we compare. + @Configuration.Orientation final int orientation = + config.orientation == ORIENTATION_PORTRAIT ? ORIENTATION_LANDSCAPE + : ORIENTATION_PORTRAIT; + final Rect lastBounds = config.windowConfiguration.getBounds(); + config.orientation = orientation; + config.windowConfiguration.setBounds( + new Rect(0, 0, lastBounds.height(), lastBounds.width())); mTask.onConfigurationChanged(config); verify(mTransaction, atLeast(2)).setPosition(eq(mRecordedSurface), anyFloat(), @@ -278,13 +326,15 @@ public class ContentRecorderTests extends WindowTestsBase { public void testOnTaskBoundsConfigurationChanged_notifiesCallback() { mTask.getRootTask().setWindowingMode(WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW); + final int minWidth = 222; + final int minHeight = 777; final int recordedWidth = 333; final int recordedHeight = 999; final ActivityInfo info = new ActivityInfo(); info.windowLayout = new ActivityInfo.WindowLayout(-1 /* width */, -1 /* widthFraction */, -1 /* height */, -1 /* heightFraction */, - Gravity.NO_GRAVITY, recordedWidth, recordedHeight); + Gravity.NO_GRAVITY, minWidth, minHeight); mTask.setMinDimensions(info); // WHEN a recording is ongoing. |