diff options
| author | 2016-02-29 16:44:33 -0800 | |
|---|---|---|
| committer | 2016-02-29 16:51:59 -0800 | |
| commit | 47e36a3e270ff3e94750d730ac2a9f0bdfe96c04 (patch) | |
| tree | 83de5b5eeae728976f6b276891779cb795df0905 | |
| parent | 1db8850b793109da0fc4a65ec837b1a329072b07 (diff) | |
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
4 files changed, 39 insertions, 0 deletions
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<SurfaceControl *>(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); |