Convert invalid crop to display bounds for captureDisplay

If the crop value passed in the args for captureDisplay is invalid, use
the display bounds instead.

Test: WindowManagerServiceTests#testCaptureDisplay
Bug: 242714168
Change-Id: Iebe42fd35c5f49b6e711699aa1b986a556a5a5f8
This commit is contained in:
Chavi Weingarten
2022-09-20 19:13:33 +00:00
parent 5473b217d7
commit d2caa1f0ac
4 changed files with 68 additions and 15 deletions

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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) {
captureArgs = new ScreenCapture.CaptureArgs.Builder<>()
.build();
}
if (captureArgs.mSourceCrop.isEmpty()) {
displayContent.getBounds(mTmpRect);
mTmpRect.offsetTo(0, 0);
captureArgs = new ScreenCapture.CaptureArgs.Builder<>()
.setSourceCrop(mTmpRect)
.build();
} 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);
}
}

View File

@@ -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);