From 47e36a3e270ff3e94750d730ac2a9f0bdfe96c04 Mon Sep 17 00:00:00 2001 From: Chong Zhang Date: Mon, 29 Feb 2016 16:44:33 -0800 Subject: Force disconnect when the surface is about to be saved. Some client will not disconnect, and if we're saving the surface (instead of destroying it), we need to make sure the surface is disconnected. Otherwise the client won't be able to reconnect to the same surface. bug: 27295820 Change-Id: I471b8fbe8f590c900e17a017167466fc8a70b87a --- core/java/android/view/SurfaceControl.java | 10 ++++++++++ core/jni/android_view_SurfaceControl.cpp | 9 +++++++++ services/core/java/com/android/server/wm/WindowState.java | 6 ++++++ .../com/android/server/wm/WindowSurfaceController.java | 14 ++++++++++++++ 4 files changed, 39 insertions(+) diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index b58c68f782ee..aa86c03c53c7 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -36,6 +36,7 @@ public class SurfaceControl { throws OutOfResourcesException; private static native void nativeRelease(long nativeObject); private static native void nativeDestroy(long nativeObject); + private static native void nativeDisconnect(long nativeObject); private static native Bitmap nativeScreenshot(IBinder displayToken, Rect sourceCrop, int width, int height, int minLayer, int maxLayer, @@ -341,6 +342,15 @@ public class SurfaceControl { mCloseGuard.close(); } + /** + * Disconnect any client still connected to the surface. + */ + public void disconnect() { + if (mNativeObject != 0) { + nativeDisconnect(mNativeObject); + } + } + private void checkNotReleased() { if (mNativeObject == 0) throw new NullPointerException( "mNativeObject is null. Have you called release() already?"); diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 1dfe40a324b3..c838d038c4c2 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -110,6 +110,13 @@ static void nativeDestroy(JNIEnv* env, jclass clazz, jlong nativeObject) { ctrl->decStrong((void *)nativeCreate); } +static void nativeDisconnect(JNIEnv* env, jclass clazz, jlong nativeObject) { + SurfaceControl* const ctrl = reinterpret_cast(nativeObject); + if (ctrl != NULL) { + ctrl->disconnect(); + } +} + static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject displayTokenObj, jobject sourceCropObj, jint width, jint height, jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform, @@ -595,6 +602,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeRelease }, {"nativeDestroy", "(J)V", (void*)nativeDestroy }, + {"nativeDisconnect", "(J)V", + (void*)nativeDisconnect }, {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZI)Landroid/graphics/Bitmap;", (void*)nativeScreenshotBitmap }, {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;Landroid/graphics/Rect;IIIIZZ)V", diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 40b6b50da6dd..e8f1b5d8d326 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -1902,6 +1902,12 @@ final class WindowState implements WindowManagerPolicy.WindowState { mWinAnimator.hide("saved surface"); mWinAnimator.mDrawState = WindowStateAnimator.NO_SURFACE; setHasSurface(false); + // The client should have disconnected at this point, but if it doesn't, + // we need to make sure it's disconnected. Otherwise when we reuse the surface + // the client can't reconnect to the buffer queue, and rendering will fail. + if (mWinAnimator.mSurfaceController != null) { + mWinAnimator.mSurfaceController.disconnectInTransaction(); + } } else { mWinAnimator.destroySurfaceLocked(); } diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java index 2972a248b00d..2cdf471c1420 100644 --- a/services/core/java/com/android/server/wm/WindowSurfaceController.java +++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java @@ -152,6 +152,20 @@ class WindowSurfaceController { } } + void disconnectInTransaction() { + if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) { + Slog.i(TAG, "Disconnecting client: " + this); + } + + try { + if (mSurfaceControl != null) { + mSurfaceControl.disconnect(); + } + } catch (RuntimeException e) { + Slog.w(TAG, "Error disconnecting surface in: " + this, e); + } + } + void setCropInTransaction(Rect clipRect, boolean recoveringMemory) { if (SHOW_TRANSACTIONS) logSurface( "CROP " + clipRect.toShortString(), null); -- cgit v1.2.3-59-g8ed1b