ScreenCaptureListenerWrapper - hold weak ref
This change should reduce the amount of time taken by Java's garbage collection to free hardware buffers.
Without this change, cleaning up hardware buffers via GC required:
* A GC cycle to collect ScreenCaptureListener
* NativeAllocationRegistry to clean up ScreenCaptureListenerWrapper (this can be tens of seconds)
* A second GC cycle to collect the consumer ScreenCaptureListenerWrapper referenced and the hardware buffer the consumer referenced
With this change, ScreenCaptureListenerWrapper no longer holds a global reference to the consumer allowing GC to clean up unreferenced consumers immediately.
The change also includes a small refactor of the interface used to create synchronous ScreenCaptureListeners.
Bug: 283813337
Test: presumbits
Change-Id: I318d73d6cbf2210db5e4386ab57e4ce3a3629166
diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java
index d96a9d1..34f0964 100644
--- a/core/java/android/app/UiAutomationConnection.java
+++ b/core/java/android/app/UiAutomationConnection.java
@@ -39,7 +39,6 @@
import android.os.UserHandle;
import android.permission.IPermissionManager;
import android.util.Log;
-import android.util.Pair;
import android.view.IWindowManager;
import android.view.InputDevice;
import android.view.InputEvent;
@@ -52,7 +51,8 @@
import android.view.accessibility.IAccessibilityManager;
import android.window.ScreenCapture;
import android.window.ScreenCapture.CaptureArgs;
-import android.window.ScreenCapture.ScreenCaptureListener;
+import android.window.ScreenCapture.ScreenshotHardwareBuffer;
+import android.window.ScreenCapture.SynchronousScreenCaptureListener;
import libcore.io.IoUtils;
@@ -235,12 +235,12 @@
final CaptureArgs captureArgs = new CaptureArgs.Builder<>()
.setSourceCrop(crop)
.build();
- Pair<ScreenCaptureListener, ScreenCapture.ScreenshotSync> syncScreenCapture =
+ SynchronousScreenCaptureListener syncScreenCapture =
ScreenCapture.createSyncCaptureListener();
mWindowManager.captureDisplay(DEFAULT_DISPLAY, captureArgs,
- syncScreenCapture.first);
- final ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer =
- syncScreenCapture.second.get();
+ syncScreenCapture);
+ final ScreenshotHardwareBuffer screenshotBuffer =
+ syncScreenCapture.getBuffer();
return screenshotBuffer == null ? null : screenshotBuffer.asBitmap();
} catch (RemoteException re) {
re.rethrowAsRuntimeException();
diff --git a/core/java/android/window/ScreenCapture.java b/core/java/android/window/ScreenCapture.java
index fa7f577..0cc9c64 100644
--- a/core/java/android/window/ScreenCapture.java
+++ b/core/java/android/window/ScreenCapture.java
@@ -27,7 +27,6 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
-import android.util.Pair;
import android.view.SurfaceControl;
import libcore.util.NativeAllocationRegistry;
@@ -73,14 +72,14 @@
*/
public static ScreenshotHardwareBuffer captureDisplay(
DisplayCaptureArgs captureArgs) {
- Pair<ScreenCaptureListener, ScreenshotSync> syncScreenCapture = createSyncCaptureListener();
- int status = captureDisplay(captureArgs, syncScreenCapture.first);
+ SynchronousScreenCaptureListener syncScreenCapture = createSyncCaptureListener();
+ int status = captureDisplay(captureArgs, syncScreenCapture);
if (status != 0) {
return null;
}
try {
- return syncScreenCapture.second.get();
+ return syncScreenCapture.getBuffer();
} catch (Exception e) {
return null;
}
@@ -133,14 +132,14 @@
* @hide
*/
public static ScreenshotHardwareBuffer captureLayers(LayerCaptureArgs captureArgs) {
- Pair<ScreenCaptureListener, ScreenshotSync> syncScreenCapture = createSyncCaptureListener();
- int status = captureLayers(captureArgs, syncScreenCapture.first);
+ SynchronousScreenCaptureListener syncScreenCapture = createSyncCaptureListener();
+ int status = captureLayers(captureArgs, syncScreenCapture);
if (status != 0) {
return null;
}
try {
- return syncScreenCapture.second.get();
+ return syncScreenCapture.getBuffer();
} catch (Exception e) {
return null;
}
@@ -743,14 +742,35 @@
* A helper method to handle the async screencapture callbacks synchronously. This should only
* be used if the screencapture caller doesn't care that it blocks waiting for a screenshot.
*
- * @return a Pair that holds the {@link ScreenCaptureListener} that should be used for capture
- * calls into SurfaceFlinger and a {@link ScreenshotSync} object to retrieve the results.
+ * @return a {@link SynchronousScreenCaptureListener} that should be used for capture
+ * calls into SurfaceFlinger.
*/
- public static Pair<ScreenCaptureListener, ScreenshotSync> createSyncCaptureListener() {
- final ScreenshotSync screenshotSync = new ScreenshotSync();
- final ScreenCaptureListener screenCaptureListener = new ScreenCaptureListener(
- screenshotSync::setScreenshotHardwareBuffer);
- return new Pair<>(screenCaptureListener, screenshotSync);
+ public static SynchronousScreenCaptureListener createSyncCaptureListener() {
+ ScreenshotHardwareBuffer[] bufferRef = new ScreenshotHardwareBuffer[1];
+ CountDownLatch latch = new CountDownLatch(1);
+ Consumer<ScreenshotHardwareBuffer> consumer = buffer -> {
+ bufferRef[0] = buffer;
+ latch.countDown();
+ };
+
+ return new SynchronousScreenCaptureListener(consumer) {
+ // In order to avoid requiring two GC cycles to clean up the consumer and the buffer
+ // it references, the underlying JNI listener holds a weak reference to the consumer.
+ // This property exists to ensure the consumer stays alive during the listener's
+ // lifetime.
+ private Consumer<ScreenshotHardwareBuffer> mConsumer = consumer;
+
+ @Override
+ public ScreenshotHardwareBuffer getBuffer() {
+ try {
+ latch.await(SCREENSHOT_WAIT_TIME_S, TimeUnit.SECONDS);
+ return bufferRef[0];
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to wait for screen capture result", e);
+ return null;
+ }
+ }
+ };
}
/**
@@ -758,28 +778,15 @@
* {@link #captureLayers(LayerCaptureArgs, ScreenCaptureListener)} or
* {@link #captureDisplay(DisplayCaptureArgs, ScreenCaptureListener)}
*/
- public static class ScreenshotSync {
- private final CountDownLatch mCountDownLatch = new CountDownLatch(1);
- private ScreenshotHardwareBuffer mScreenshotHardwareBuffer;
-
- private void setScreenshotHardwareBuffer(
- ScreenshotHardwareBuffer screenshotHardwareBuffer) {
- mScreenshotHardwareBuffer = screenshotHardwareBuffer;
- mCountDownLatch.countDown();
+ public abstract static class SynchronousScreenCaptureListener extends ScreenCaptureListener {
+ SynchronousScreenCaptureListener(Consumer<ScreenshotHardwareBuffer> consumer) {
+ super(consumer);
}
/**
* Get the {@link ScreenshotHardwareBuffer} synchronously. This can be null if the
* screenshot failed or if there was no callback in {@link #SCREENSHOT_WAIT_TIME_S} seconds.
*/
- public ScreenshotHardwareBuffer get() {
- try {
- mCountDownLatch.await(SCREENSHOT_WAIT_TIME_S, TimeUnit.SECONDS);
- return mScreenshotHardwareBuffer;
- } catch (Exception e) {
- Log.e(TAG, "Failed to wait for screen capture result", e);
- return null;
- }
- }
+ public abstract ScreenshotHardwareBuffer getBuffer();
}
}
diff --git a/core/jni/android_window_ScreenCapture.cpp b/core/jni/android_window_ScreenCapture.cpp
index 986dbe9..e729750 100644
--- a/core/jni/android_window_ScreenCapture.cpp
+++ b/core/jni/android_window_ScreenCapture.cpp
@@ -81,22 +81,28 @@
public:
explicit ScreenCaptureListenerWrapper(JNIEnv* env, jobject jobject) {
env->GetJavaVM(&mVm);
- mConsumerObject = env->NewGlobalRef(jobject);
- LOG_ALWAYS_FATAL_IF(!mConsumerObject, "Failed to make global ref");
+ mConsumerWeak = env->NewWeakGlobalRef(jobject);
}
~ScreenCaptureListenerWrapper() {
- if (mConsumerObject) {
- getenv()->DeleteGlobalRef(mConsumerObject);
- mConsumerObject = nullptr;
+ if (mConsumerWeak) {
+ getenv()->DeleteWeakGlobalRef(mConsumerWeak);
+ mConsumerWeak = nullptr;
}
}
binder::Status onScreenCaptureCompleted(
const gui::ScreenCaptureResults& captureResults) override {
JNIEnv* env = getenv();
+
+ ScopedLocalRef<jobject> consumer{env, env->NewLocalRef(mConsumerWeak)};
+ if (consumer == nullptr) {
+ ALOGE("ScreenCaptureListenerWrapper consumer not alive.");
+ return binder::Status::ok();
+ }
+
if (!captureResults.fenceResult.ok() || captureResults.buffer == nullptr) {
- env->CallVoidMethod(mConsumerObject, gConsumerClassInfo.accept, nullptr);
+ env->CallVoidMethod(consumer.get(), gConsumerClassInfo.accept, nullptr);
checkAndClearException(env, "accept");
return binder::Status::ok();
}
@@ -111,7 +117,7 @@
captureResults.capturedSecureLayers,
captureResults.capturedHdrLayers);
checkAndClearException(env, "builder");
- env->CallVoidMethod(mConsumerObject, gConsumerClassInfo.accept, screenshotHardwareBuffer);
+ env->CallVoidMethod(consumer.get(), gConsumerClassInfo.accept, screenshotHardwareBuffer);
checkAndClearException(env, "accept");
env->DeleteLocalRef(jhardwareBuffer);
env->DeleteLocalRef(screenshotHardwareBuffer);
@@ -119,7 +125,7 @@
}
private:
- jobject mConsumerObject;
+ jweak mConsumerWeak;
JavaVM* mVm;
JNIEnv* getenv() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index 3eb9fa2..0fdfbb8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -80,8 +80,7 @@
import android.view.WindowInsets;
import android.view.WindowManager;
import android.window.ScreenCapture;
-import android.window.ScreenCapture.ScreenCaptureListener;
-import android.window.ScreenCapture.ScreenshotSync;
+import android.window.ScreenCapture.SynchronousScreenCaptureListener;
import androidx.annotation.MainThread;
import androidx.annotation.Nullable;
@@ -1222,10 +1221,11 @@
/**
* Performs a screenshot that may exclude the bubble layer, if one is present. The screenshot
- * can be access via the supplied {@link ScreenshotSync#get()} asynchronously.
+ * can be access via the supplied {@link SynchronousScreenCaptureListener#getBuffer()}
+ * asynchronously.
*/
public void getScreenshotExcludingBubble(int displayId,
- Pair<ScreenCaptureListener, ScreenshotSync> screenCaptureListener) {
+ SynchronousScreenCaptureListener screenCaptureListener) {
try {
ScreenCapture.CaptureArgs args = null;
if (mStackView != null) {
@@ -1240,7 +1240,7 @@
}
}
- mWmService.captureDisplay(displayId, args, screenCaptureListener.first);
+ mWmService.captureDisplay(displayId, args, screenCaptureListener);
} catch (RemoteException e) {
Log.e(TAG, "Failed to capture screenshot");
}
@@ -2211,15 +2211,15 @@
@Override
@Nullable
- public ScreenshotSync getScreenshotExcludingBubble(int displayId) {
- Pair<ScreenCaptureListener, ScreenshotSync> screenCaptureListener =
+ public SynchronousScreenCaptureListener getScreenshotExcludingBubble(int displayId) {
+ SynchronousScreenCaptureListener screenCaptureListener =
ScreenCapture.createSyncCaptureListener();
mMainExecutor.execute(
() -> BubbleController.this.getScreenshotExcludingBubble(displayId,
screenCaptureListener));
- return screenCaptureListener.second;
+ return screenCaptureListener;
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
index 259f692..4d329dd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
@@ -16,8 +16,6 @@
package com.android.wm.shell.bubbles;
-import static android.window.ScreenCapture.ScreenshotSync;
-
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.PARAMETER;
@@ -34,6 +32,7 @@
import android.util.Pair;
import android.util.SparseArray;
import android.window.ScreenCapture.ScreenshotHardwareBuffer;
+import android.window.ScreenCapture.SynchronousScreenCaptureListener;
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
@@ -150,13 +149,14 @@
boolean isAppBubbleTaskId(int taskId);
/**
- * @return a {@link ScreenshotSync} after performing a screenshot that may exclude the bubble
- * layer, if one is present. The underlying {@link ScreenshotHardwareBuffer} can be access via
- * {@link ScreenshotSync#get()} asynchronously and care should be taken to
- * {@link HardwareBuffer#close()} the associated
- * {@link ScreenshotHardwareBuffer#getHardwareBuffer()} when no longer required.
+` * @return a {@link SynchronousScreenCaptureListener} after performing a screenshot that may
+ * exclude the bubble layer, if one is present. The underlying
+ * {@link ScreenshotHardwareBuffer} can be accessed via
+ * {@link SynchronousScreenCaptureListener#getBuffer()} asynchronously and care should be taken
+ * to {@link HardwareBuffer#close()} the associated
+ * {@link ScreenshotHardwareBuffer#getHardwareBuffer()} when no longer required.`
*/
- ScreenshotSync getScreenshotExcludingBubble(int displayId);
+ SynchronousScreenCaptureListener getScreenshotExcludingBubble(int displayId);
/**
* @return a bubble that matches the provided shortcutId, if one exists.
diff --git a/packages/Shell/src/com/android/shell/Screenshooter.java b/packages/Shell/src/com/android/shell/Screenshooter.java
index baaddf5..8a5b7da 100644
--- a/packages/Shell/src/com/android/shell/Screenshooter.java
+++ b/packages/Shell/src/com/android/shell/Screenshooter.java
@@ -21,12 +21,10 @@
import android.graphics.Bitmap;
import android.os.RemoteException;
import android.util.Log;
-import android.util.Pair;
import android.view.WindowManagerGlobal;
import android.window.ScreenCapture;
-import android.window.ScreenCapture.ScreenCaptureListener;
import android.window.ScreenCapture.ScreenshotHardwareBuffer;
-import android.window.ScreenCapture.ScreenshotSync;
+import android.window.ScreenCapture.SynchronousScreenCaptureListener;
/**
* Helper class used to take screenshots.
@@ -46,15 +44,15 @@
static Bitmap takeScreenshot() {
Log.d(TAG, "Taking fullscreen screenshot");
// Take the screenshot
- final Pair<ScreenCaptureListener, ScreenshotSync> syncScreenCapture =
+ final SynchronousScreenCaptureListener syncScreenCapture =
ScreenCapture.createSyncCaptureListener();
try {
WindowManagerGlobal.getWindowManagerService().captureDisplay(DEFAULT_DISPLAY, null,
- syncScreenCapture.first);
+ syncScreenCapture);
} catch (RemoteException e) {
e.rethrowAsRuntimeException();
}
- final ScreenshotHardwareBuffer screenshotBuffer = syncScreenCapture.second.get();
+ final ScreenshotHardwareBuffer screenshotBuffer = syncScreenCapture.getBuffer();
final Bitmap screenShot = screenshotBuffer == null ? null : screenshotBuffer.asBitmap();
if (screenShot == null) {
Log.e(TAG, "Failed to take fullscreen screenshot");
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ImageCaptureImpl.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ImageCaptureImpl.kt
index 2e47ab6..24fe7d5 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ImageCaptureImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ImageCaptureImpl.kt
@@ -42,8 +42,8 @@
.setSourceCrop(crop)
.build()
val syncScreenCapture = ScreenCapture.createSyncCaptureListener()
- windowManager.captureDisplay(displayId, captureArgs, syncScreenCapture.first)
- val buffer = syncScreenCapture.second.get()
+ windowManager.captureDisplay(displayId, captureArgs, syncScreenCapture)
+ val buffer = syncScreenCapture.getBuffer()
return buffer?.asBitmap()
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsScreenshotHelperService.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsScreenshotHelperService.java
index 83ff020..4c01315 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsScreenshotHelperService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsScreenshotHelperService.java
@@ -20,7 +20,7 @@
import android.content.Intent;
import android.os.IBinder;
import android.window.ScreenCapture.ScreenshotHardwareBuffer;
-import android.window.ScreenCapture.ScreenshotSync;
+import android.window.ScreenCapture.SynchronousScreenCaptureListener;
import androidx.annotation.Nullable;
@@ -54,9 +54,9 @@
return null;
}
- ScreenshotSync screenshotSync =
+ SynchronousScreenCaptureListener screenshotSync =
mOptionalBubbles.get().getScreenshotExcludingBubble(displayId);
- ScreenshotHardwareBuffer screenshotHardwareBuffer = screenshotSync.get();
+ ScreenshotHardwareBuffer screenshotHardwareBuffer = screenshotSync.getBuffer();
if (screenshotHardwareBuffer == null) {
return null;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsScreenshotHelperServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsScreenshotHelperServiceTest.java
index ab321f1..ba3d392 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsScreenshotHelperServiceTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsScreenshotHelperServiceTest.java
@@ -26,7 +26,7 @@
import android.os.RemoteException;
import android.view.Display;
import android.window.ScreenCapture.ScreenshotHardwareBuffer;
-import android.window.ScreenCapture.ScreenshotSync;
+import android.window.ScreenCapture.SynchronousScreenCaptureListener;
import androidx.test.runner.AndroidJUnit4;
@@ -58,7 +58,7 @@
@Mock private Optional<Bubbles> mBubblesOptional;
@Mock private Bubbles mBubbles;
@Mock private ScreenshotHardwareBuffer mScreenshotHardwareBuffer;
- @Mock private ScreenshotSync mScreenshotSync;
+ @Mock private SynchronousScreenCaptureListener mScreenshotSync;
private AppClipsScreenshotHelperService mAppClipsScreenshotHelperService;
@@ -80,7 +80,7 @@
when(mBubblesOptional.isEmpty()).thenReturn(false);
when(mBubblesOptional.get()).thenReturn(mBubbles);
when(mBubbles.getScreenshotExcludingBubble(DEFAULT_DISPLAY)).thenReturn(mScreenshotSync);
- when(mScreenshotSync.get()).thenReturn(null);
+ when(mScreenshotSync.getBuffer()).thenReturn(null);
assertThat(getInterface().takeScreenshot(DEFAULT_DISPLAY)).isNull();
}
@@ -90,7 +90,7 @@
when(mBubblesOptional.isEmpty()).thenReturn(false);
when(mBubblesOptional.get()).thenReturn(mBubbles);
when(mBubbles.getScreenshotExcludingBubble(DEFAULT_DISPLAY)).thenReturn(mScreenshotSync);
- when(mScreenshotSync.get()).thenReturn(mScreenshotHardwareBuffer);
+ when(mScreenshotSync.getBuffer()).thenReturn(mScreenshotHardwareBuffer);
when(mScreenshotHardwareBuffer.getHardwareBuffer()).thenReturn(FAKE_HARDWARE_BUFFER);
when(mScreenshotHardwareBuffer.getColorSpace()).thenReturn(FAKE_COLOR_SPACE);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 7fc86b0..ef19eef 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -244,6 +244,7 @@
import android.window.DisplayWindowPolicyController;
import android.window.IDisplayAreaOrganizer;
import android.window.ScreenCapture;
+import android.window.ScreenCapture.SynchronousScreenCaptureListener;
import android.window.TransitionRequestInfo;
import com.android.internal.R;
@@ -5088,7 +5089,7 @@
return null;
}
- Pair<ScreenCapture.ScreenCaptureListener, ScreenCapture.ScreenshotSync> syncScreenCapture =
+ SynchronousScreenCaptureListener syncScreenCapture =
ScreenCapture.createSyncCaptureListener();
getBounds(mTmpRect);
@@ -5097,10 +5098,10 @@
new ScreenCapture.LayerCaptureArgs.Builder(getSurfaceControl())
.setSourceCrop(mTmpRect).build();
- ScreenCapture.captureLayers(args, syncScreenCapture.first);
+ ScreenCapture.captureLayers(args, syncScreenCapture);
final ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer =
- syncScreenCapture.second.get();
+ syncScreenCapture.getBuffer();
final Bitmap bitmap = screenshotBuffer == null ? null : screenshotBuffer.asBitmap();
if (bitmap == null) {
Slog.w(TAG_WM, "Failed to take screenshot");
diff --git a/services/tests/wmtests/src/com/android/server/wm/ScreenshotTests.java b/services/tests/wmtests/src/com/android/server/wm/ScreenshotTests.java
index 1ee0959..b181213 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ScreenshotTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ScreenshotTests.java
@@ -43,16 +43,14 @@
import android.os.Looper;
import android.os.ServiceManager;
import android.platform.test.annotations.Presubmit;
-import android.util.Pair;
import android.view.IWindowManager;
import android.view.PointerIcon;
import android.view.SurfaceControl;
import android.view.cts.surfacevalidator.BitmapPixelChecker;
import android.view.cts.surfacevalidator.SaveBitmapHelper;
import android.window.ScreenCapture;
-import android.window.ScreenCapture.ScreenCaptureListener;
import android.window.ScreenCapture.ScreenshotHardwareBuffer;
-import android.window.ScreenCapture.ScreenshotSync;
+import android.window.ScreenCapture.SynchronousScreenCaptureListener;
import androidx.annotation.Nullable;
import androidx.test.filters.SmallTest;
@@ -169,10 +167,10 @@
.setPosition(sc, point.x, point.y)
.apply(true);
- Pair<ScreenCaptureListener, ScreenshotSync> syncScreenCapture =
+ SynchronousScreenCaptureListener syncScreenCapture =
ScreenCapture.createSyncCaptureListener();
- windowManager.captureDisplay(DEFAULT_DISPLAY, null, syncScreenCapture.first);
- ScreenshotHardwareBuffer hardwareBuffer = syncScreenCapture.second.get();
+ windowManager.captureDisplay(DEFAULT_DISPLAY, null, syncScreenCapture);
+ ScreenshotHardwareBuffer hardwareBuffer = syncScreenCapture.getBuffer();
assertNotNull(hardwareBuffer);
Bitmap screenshot = hardwareBuffer.asBitmap();