diff options
author | 2022-09-21 15:27:00 +0000 | |
---|---|---|
committer | 2022-09-21 15:27:00 +0000 | |
commit | 94d707ccef1aaf3b1fbae419955fe0f9f1dc8b8c (patch) | |
tree | 60c2117a4cedb169ef441f67d0d67aa3f51d97d9 | |
parent | e67b6fe8c71297e8d35bf248aec5f2c7d925dddd (diff) | |
parent | d2caa1f0acf79c65c144257f883b76fc80473591 (diff) |
Merge "Convert invalid crop to display bounds for captureDisplay"
4 files changed, 68 insertions, 15 deletions
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 6b9fceb73ec1..067946e90361 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -970,6 +970,10 @@ interface IWindowManager */ boolean isLetterboxBackgroundMultiColored(); + /** + * Captures the entire display specified by the displayId using the args provided. If the args + * are null or if the sourceCrop is invalid or null, the entire display bounds will be captured. + */ oneway void captureDisplay(int displayId, in @nullable ScreenCapture.CaptureArgs captureArgs, in ScreenCapture.ScreenCaptureListener listener); } diff --git a/core/java/android/window/ScreenCapture.java b/core/java/android/window/ScreenCapture.java index c010f2248dc5..b8f39a990cdd 100644 --- a/core/java/android/window/ScreenCapture.java +++ b/core/java/android/window/ScreenCapture.java @@ -255,14 +255,14 @@ public class ScreenCapture { * @hide */ public static class CaptureArgs implements Parcelable { - private final int mPixelFormat; - private final Rect mSourceCrop = new Rect(); - private final float mFrameScaleX; - private final float mFrameScaleY; - private final boolean mCaptureSecureLayers; - private final boolean mAllowProtected; - private final long mUid; - private final boolean mGrayscale; + public final int mPixelFormat; + public final Rect mSourceCrop = new Rect(); + public final float mFrameScaleX; + public final float mFrameScaleY; + public final boolean mCaptureSecureLayers; + public final boolean mAllowProtected; + public final long mUid; + public final boolean mGrayscale; private CaptureArgs(CaptureArgs.Builder<? extends CaptureArgs.Builder<?>> builder) { mPixelFormat = builder.mPixelFormat; diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 9722bb61f2c6..49e7a0c8c745 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -9286,6 +9286,12 @@ public class WindowManagerService extends IWindowManager.Stub throw new SecurityException("Requires READ_FRAME_BUFFER permission"); } + ScreenCapture.captureLayers(getCaptureArgs(displayId, captureArgs), listener); + } + + @VisibleForTesting + ScreenCapture.LayerCaptureArgs getCaptureArgs(int displayId, + @Nullable ScreenCapture.CaptureArgs captureArgs) { final SurfaceControl displaySurfaceControl; synchronized (mGlobalLock) { DisplayContent displayContent = mRoot.getDisplayContent(displayId); @@ -9297,18 +9303,20 @@ public class WindowManagerService extends IWindowManager.Stub displaySurfaceControl = displayContent.getSurfaceControl(); if (captureArgs == null) { - displayContent.getBounds(mTmpRect); - mTmpRect.offsetTo(0, 0); captureArgs = new ScreenCapture.CaptureArgs.Builder<>() - .setSourceCrop(mTmpRect) .build(); } + + if (captureArgs.mSourceCrop.isEmpty()) { + displayContent.getBounds(mTmpRect); + mTmpRect.offsetTo(0, 0); + } else { + mTmpRect.set(captureArgs.mSourceCrop); + } } - ScreenCapture.LayerCaptureArgs args = - new ScreenCapture.LayerCaptureArgs.Builder(displaySurfaceControl, captureArgs) + return new ScreenCapture.LayerCaptureArgs.Builder(displaySurfaceControl, captureArgs) + .setSourceCrop(mTmpRect) .build(); - - ScreenCapture.captureLayers(args, listener); } } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java index 46b4b76dc12f..8b63904baf31 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java @@ -41,6 +41,7 @@ import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_ import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.any; @@ -68,6 +69,7 @@ import android.view.SurfaceControl; import android.view.View; import android.view.WindowManager; import android.window.ClientWindowFrames; +import android.window.ScreenCapture; import android.window.WindowContainerToken; import androidx.test.filters.SmallTest; @@ -423,6 +425,45 @@ public class WindowManagerServiceTests extends WindowTestsBase { LETTERBOX_BACKGROUND_SOLID_COLOR)).isFalse(); } + @Test + public void testCaptureDisplay() { + Rect displayBounds = new Rect(0, 0, 100, 200); + spyOn(mDisplayContent); + when(mDisplayContent.getBounds()).thenReturn(displayBounds); + + // Null captureArgs + ScreenCapture.LayerCaptureArgs resultingArgs = + mWm.getCaptureArgs(DEFAULT_DISPLAY, null /* captureArgs */); + assertEquals(displayBounds, resultingArgs.mSourceCrop); + + // Non null captureArgs, didn't set rect + ScreenCapture.CaptureArgs captureArgs = new ScreenCapture.CaptureArgs.Builder<>().build(); + resultingArgs = mWm.getCaptureArgs(DEFAULT_DISPLAY, captureArgs); + assertEquals(displayBounds, resultingArgs.mSourceCrop); + + // Non null captureArgs, invalid rect + captureArgs = new ScreenCapture.CaptureArgs.Builder<>() + .setSourceCrop(new Rect(0, 0, -1, -1)) + .build(); + resultingArgs = mWm.getCaptureArgs(DEFAULT_DISPLAY, captureArgs); + assertEquals(displayBounds, resultingArgs.mSourceCrop); + + // Non null captureArgs, null rect + captureArgs = new ScreenCapture.CaptureArgs.Builder<>() + .setSourceCrop(null) + .build(); + resultingArgs = mWm.getCaptureArgs(DEFAULT_DISPLAY, captureArgs); + assertEquals(displayBounds, resultingArgs.mSourceCrop); + + // Non null captureArgs, valid rect + Rect validRect = new Rect(0, 0, 10, 50); + captureArgs = new ScreenCapture.CaptureArgs.Builder<>() + .setSourceCrop(validRect) + .build(); + resultingArgs = mWm.getCaptureArgs(DEFAULT_DISPLAY, captureArgs); + assertEquals(validRect, resultingArgs.mSourceCrop); + } + private void setupActivityWithLaunchCookie(IBinder launchCookie, WindowContainerToken wct) { final WindowContainer.RemoteToken remoteToken = mock(WindowContainer.RemoteToken.class); when(remoteToken.toWindowContainerToken()).thenReturn(wct); |