From e9953b1752a583058e639ef3de456988ab6ef7bf Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Mon, 23 May 2016 20:52:04 -0700 Subject: [PATCH] Force pending transactions to flush before screenshot. Following 14e54ba747 (ag/1043009) we need to push an empty synchronous transaction if we want to ensure all previous transactions have occured before taking a screenshot. In light of Bug 7552304 it seems wise to do this before screenshoting applications. Bug: 27098060 Bug: 7552304 Change-Id: I6d7dfbe634a288c55449d2f1d6fbbfc13bab08ad --- core/java/android/view/SurfaceControl.java | 8 ++++++-- core/jni/android_view_SurfaceControl.cpp | 7 ++++--- .../java/com/android/server/wm/WindowManagerService.java | 5 +++++ 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 7b01267b63886..b4131b44263aa 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -46,7 +46,7 @@ public class SurfaceControl { boolean allLayers, boolean useIdentityTransform); private static native void nativeOpenTransaction(); - private static native void nativeCloseTransaction(); + private static native void nativeCloseTransaction(boolean sync); private static native void nativeSetAnimationTransaction(); private static native void nativeSetLayer(long nativeObject, int zorder); @@ -372,7 +372,11 @@ public class SurfaceControl { /** end a transaction */ public static void closeTransaction() { - nativeCloseTransaction(); + nativeCloseTransaction(false); + } + + public static void closeTransactionSync() { + nativeCloseTransaction(true); } public void deferTransactionUntil(IBinder handle, long frame) { diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 864a0bfe6f5dd..a9ed9dce590e9 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -223,8 +223,9 @@ static void nativeOpenTransaction(JNIEnv* env, jclass clazz) { SurfaceComposerClient::openGlobalTransaction(); } -static void nativeCloseTransaction(JNIEnv* env, jclass clazz) { - SurfaceComposerClient::closeGlobalTransaction(); + +static void nativeCloseTransaction(JNIEnv* env, jclass clazz, jboolean sync) { + SurfaceComposerClient::closeGlobalTransaction(sync); } static void nativeSetAnimationTransaction(JNIEnv* env, jclass clazz) { @@ -649,7 +650,7 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeScreenshot }, {"nativeOpenTransaction", "()V", (void*)nativeOpenTransaction }, - {"nativeCloseTransaction", "()V", + {"nativeCloseTransaction", "(Z)V", (void*)nativeCloseTransaction }, {"nativeSetAnimationTransaction", "()V", (void*)nativeSetAnimationTransaction }, diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 82cd0fa0c25d6..d60e8d6aa0829 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -6381,6 +6381,11 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_SCREENSHOT && inRotation) Slog.v(TAG_WM, "Taking screenshot while rotating"); + // We force pending transactions to flush before taking + // the screenshot by pushing an empty synchronous transaction. + SurfaceControl.openTransaction(); + SurfaceControl.closeTransactionSync(); + bm = SurfaceControl.screenshot(crop, width, height, minLayer, maxLayer, inRotation, rot); if (bm == null) {