Loading data/etc/services.core.protolog.json +6 −0 Original line number Diff line number Diff line Loading @@ -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", Loading services/core/java/com/android/server/wm/ContentRecorder.java +11 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -84,6 +85,7 @@ final class ContentRecorder implements WindowContainerListener { /** * The last configuration orientation. */ @Configuration.Orientation private int mLastOrientation = ORIENTATION_UNDEFINED; ContentRecorder(@NonNull DisplayContent displayContent) { Loading Loading @@ -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(); Loading Loading @@ -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: Loading Loading @@ -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). Loading services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java +58 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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. Loading @@ -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); Loading Loading @@ -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()); Loading @@ -259,13 +266,54 @@ public class ContentRecorderTests extends WindowTestsBase { anyFloat(), anyFloat()); } @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(), Loading @@ -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. Loading Loading
data/etc/services.core.protolog.json +6 −0 Original line number Diff line number Diff line Loading @@ -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", Loading
services/core/java/com/android/server/wm/ContentRecorder.java +11 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -84,6 +85,7 @@ final class ContentRecorder implements WindowContainerListener { /** * The last configuration orientation. */ @Configuration.Orientation private int mLastOrientation = ORIENTATION_UNDEFINED; ContentRecorder(@NonNull DisplayContent displayContent) { Loading Loading @@ -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(); Loading Loading @@ -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: Loading Loading @@ -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). Loading
services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java +58 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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. Loading @@ -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); Loading Loading @@ -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()); Loading @@ -259,13 +266,54 @@ public class ContentRecorderTests extends WindowTestsBase { anyFloat(), anyFloat()); } @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(), Loading @@ -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. Loading