summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorchaviw <chaviw@google.com>2020-08-18 16:06:40 -0700
committerchaviw <chaviw@google.com>2020-09-08 09:59:50 -0700
commit3510924a6de6ad44160de44051d28df87593edd3 (patch)
tree1d547c3c90b165a509d26a7f9deeb70783224791 /core/java/android
parent25953d498f68ac3cdc3b7f4c0a33946725ac960d (diff)
Send ScreenCaptureListener to native screen capture requests.
Allow for asynchronous screenshot by sending a ScreenCaptureListener to handle screenshot callbacks. All existing calls are still synchronous since the SurfaceControl method will block the caller until the results from SurfaceFlinger are ready. Test: power + volume down Test: adb shell screencap Bug: 162367424 Change-Id: I54c34003c0786b585dd20530a06dbd4b266e178c
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/view/SurfaceControl.java96
1 files changed, 87 insertions, 9 deletions
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 6ef086b55c41..3af8958368dc 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -65,6 +65,9 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Objects;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
/**
* Handle to an on-screen Surface managed by the system compositor. The SurfaceControl is
@@ -87,10 +90,10 @@ public final class SurfaceControl implements Parcelable {
private static native void nativeWriteToParcel(long nativeObject, Parcel out);
private static native void nativeRelease(long nativeObject);
private static native void nativeDisconnect(long nativeObject);
- private static native ScreenshotHardwareBuffer nativeCaptureDisplay(
- DisplayCaptureArgs captureArgs);
- private static native ScreenshotHardwareBuffer nativeCaptureLayers(
- LayerCaptureArgs captureArgs);
+ private static native int nativeCaptureDisplay(DisplayCaptureArgs captureArgs,
+ ScreenCaptureListener captureListener);
+ private static native int nativeCaptureLayers(LayerCaptureArgs captureArgs,
+ ScreenCaptureListener captureListener);
private static native long nativeMirrorSurface(long mirrorOfObject);
private static native long nativeCreateTransaction();
private static native long nativeGetNativeTransactionFinalizer();
@@ -493,6 +496,8 @@ public final class SurfaceControl implements Parcelable {
private static final int INTERNAL_DATASPACE_DISPLAY_P3 = 143261696;
private static final int INTERNAL_DATASPACE_SCRGB = 411107328;
+ private static final int SCREENSHOT_WAIT_TIME_S = 1;
+
private void assignNativeObject(long nativeObject, String callsite) {
if (mNativeObject != 0) {
release();
@@ -611,6 +616,13 @@ public final class SurfaceControl implements Parcelable {
}
/**
+ * @hide
+ */
+ public abstract static class ScreenCaptureListener {
+ abstract void onScreenCaptureComplete(ScreenshotHardwareBuffer hardwareBuffer);
+ }
+
+ /**
* A common arguments class used for various screenshot requests. This contains arguments that
* are shared between {@link DisplayCaptureArgs} and {@link LayerCaptureArgs}
* @hide
@@ -685,7 +697,7 @@ public final class SurfaceControl implements Parcelable {
/**
* The arguments class used to make display capture requests.
*
- * @see #nativeCaptureDisplay(DisplayCaptureArgs)
+ * @see #nativeCaptureDisplay(DisplayCaptureArgs, ScreenCaptureListener)
* @hide
*/
public static class DisplayCaptureArgs extends CaptureArgs {
@@ -2226,13 +2238,46 @@ public final class SurfaceControl implements Parcelable {
}
/**
+ * @param captureArgs Arguments about how to take the screenshot
+ * @param captureListener A listener to receive the screenshot callback
+ * @hide
+ */
+ public static int captureDisplay(@NonNull DisplayCaptureArgs captureArgs,
+ @NonNull ScreenCaptureListener captureListener) {
+ return nativeCaptureDisplay(captureArgs, captureListener);
+ }
+
+ /**
* Captures all the surfaces in a display and returns a {@link ScreenshotHardwareBuffer} with
* the content.
*
* @hide
*/
public static ScreenshotHardwareBuffer captureDisplay(DisplayCaptureArgs captureArgs) {
- return nativeCaptureDisplay(captureArgs);
+ final AtomicReference<ScreenshotHardwareBuffer> outHardwareBuffer =
+ new AtomicReference<>(null);
+
+ final CountDownLatch countDownLatch = new CountDownLatch(1);
+ ScreenCaptureListener screenCaptureListener = new ScreenCaptureListener() {
+ @Override
+ void onScreenCaptureComplete(ScreenshotHardwareBuffer hardwareBuffer) {
+ outHardwareBuffer.set(hardwareBuffer);
+ countDownLatch.countDown();
+ }
+ };
+
+ int status = captureDisplay(captureArgs, screenCaptureListener);
+ if (status != 0) {
+ return null;
+ }
+
+ try {
+ countDownLatch.await(SCREENSHOT_WAIT_TIME_S, TimeUnit.SECONDS);
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to wait for captureDisplay result", e);
+ }
+
+ return outHardwareBuffer.get();
}
/**
@@ -2277,14 +2322,37 @@ public final class SurfaceControl implements Parcelable {
.setPixelFormat(format)
.build();
- return nativeCaptureLayers(captureArgs);
+ return captureLayers(captureArgs);
}
/**
* @hide
*/
public static ScreenshotHardwareBuffer captureLayers(LayerCaptureArgs captureArgs) {
- return nativeCaptureLayers(captureArgs);
+ final AtomicReference<ScreenshotHardwareBuffer> outHardwareBuffer =
+ new AtomicReference<>(null);
+
+ final CountDownLatch countDownLatch = new CountDownLatch(1);
+ ScreenCaptureListener screenCaptureListener = new ScreenCaptureListener() {
+ @Override
+ void onScreenCaptureComplete(ScreenshotHardwareBuffer hardwareBuffer) {
+ outHardwareBuffer.set(hardwareBuffer);
+ countDownLatch.countDown();
+ }
+ };
+
+ int status = captureLayers(captureArgs, screenCaptureListener);
+ if (status != 0) {
+ return null;
+ }
+
+ try {
+ countDownLatch.await(SCREENSHOT_WAIT_TIME_S, TimeUnit.SECONDS);
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to wait for captureLayers result", e);
+ }
+
+ return outHardwareBuffer.get();
}
/**
@@ -2301,7 +2369,17 @@ public final class SurfaceControl implements Parcelable {
.setExcludeLayers(exclude)
.build();
- return nativeCaptureLayers(captureArgs);
+ return captureLayers(captureArgs);
+ }
+
+ /**
+ * @param captureArgs Arguments about how to take the screenshot
+ * @param captureListener A listener to receive the screenshot callback
+ * @hide
+ */
+ public static int captureLayers(@NonNull LayerCaptureArgs captureArgs,
+ @NonNull ScreenCaptureListener captureListener) {
+ return nativeCaptureLayers(captureArgs, captureListener);
}
/**