Merge "Release SurfaceView surface if viewrootimpl surface is not valid" into rvc-dev am: 8089c3867e am: 428bd1f07c

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/11829307

Change-Id: I9f05fb7543e3f01750b486f3e3028fda19e54dc6
This commit is contained in:
TreeHugger Robot
2020-06-11 19:00:58 +00:00
committed by Automerger Merge Worker

View File

@@ -893,12 +893,15 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
}
return;
}
ViewRootImpl viewRoot = getViewRootImpl();
if (viewRoot == null || viewRoot.mSurface == null || !viewRoot.mSurface.isValid()) {
if (DEBUG) {
Log.d(TAG, System.identityHashCode(this)
+ " updateSurface: no valid surface");
}
final ViewRootImpl viewRoot = getViewRootImpl();
if (viewRoot == null) {
return;
}
if (viewRoot.mSurface == null || !viewRoot.mSurface.isValid()) {
notifySurfaceDestroyed();
releaseSurfaces();
return;
}
@@ -1109,28 +1112,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
final boolean surfaceChanged = creating;
if (mSurfaceCreated && (surfaceChanged || (!visible && visibleChanged))) {
mSurfaceCreated = false;
if (mSurface.isValid()) {
if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
+ "visibleChanged -- surfaceDestroyed");
callbacks = getSurfaceCallbacks();
for (SurfaceHolder.Callback c : callbacks) {
c.surfaceDestroyed(mSurfaceHolder);
}
// Since Android N the same surface may be reused and given to us
// again by the system server at a later point. However
// as we didn't do this in previous releases, clients weren't
// necessarily required to clean up properly in
// surfaceDestroyed. This leads to problems for example when
// clients don't destroy their EGL context, and try
// and create a new one on the same surface following reuse.
// Since there is no valid use of the surface in-between
// surfaceDestroyed and surfaceCreated, we force a disconnect,
// so the next connect will always work if we end up reusing
// the surface.
if (mSurface.isValid()) {
mSurface.forceScopedDisconnect();
}
}
notifySurfaceDestroyed();
}
if (creating) {
@@ -1786,6 +1768,31 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
}
}
private void notifySurfaceDestroyed() {
if (mSurface.isValid()) {
if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
+ "surfaceDestroyed");
SurfaceHolder.Callback[] callbacks = getSurfaceCallbacks();
for (SurfaceHolder.Callback c : callbacks) {
c.surfaceDestroyed(mSurfaceHolder);
}
// Since Android N the same surface may be reused and given to us
// again by the system server at a later point. However
// as we didn't do this in previous releases, clients weren't
// necessarily required to clean up properly in
// surfaceDestroyed. This leads to problems for example when
// clients don't destroy their EGL context, and try
// and create a new one on the same surface following reuse.
// Since there is no valid use of the surface in-between
// surfaceDestroyed and surfaceCreated, we force a disconnect,
// so the next connect will always work if we end up reusing
// the surface.
if (mSurface.isValid()) {
mSurface.forceScopedDisconnect();
}
}
}
/**
* Wrapper of accessibility embedded connection for embedded view hierarchy.
*/