OSDN Git Service

SurfaceView: Avoid initializing Surface from an invalid
authorRobert Carr <racarr@google.com>
Thu, 6 Jul 2017 22:28:34 +0000 (15:28 -0700)
committerandroid-build-team Robot <android-build-team-robot@google.com>
Fri, 7 Jul 2017 03:11:36 +0000 (03:11 +0000)
commitf0d3d3c06dd71453457035914a41872421f2932d
tree9b9fbb8b8620a59069f36a9d830c6b3a9b682709
parent1c47a6ca8533ec1650b4aac25c1cf45d3fcaf2bf
SurfaceView: Avoid initializing Surface from an invalid
SurfaceControl.

In a recent CL we introduced a call to Surface#createFrom, in order to
recreate the Surface object from the underlying SurfaceControl, as a
workaround to emulate when it was parcelled over binder in the past.
However this is causing BufferQueue abandoned errors when stopping and
resuming some applications. To understand them, we need to revisit the
SurfaceView destruction process when handling onStop.

First mWindowStopped will be set to true (SurfaceView#windowStopped),
and we should then enter updateSurface. Our requested visibility will
now be false and so we emit the Surface destroyed callbacks. Notice in
the finally block in mUpdateSurface, we will release mSurface, but we
will NOT null mSurfaceControl. Inline documentation explains why.

In the case that the activity is not actually being destroyed, it's
possible that we may not get a dispatchDetachedFromWindow. This means
that we will not null mSurfaceControl. Now if the activity is
un-stopped and we re-enter updateSurface we encounter a problem
state. "creating" will be set to false since mSurfaceControl != null,
however mSurfaceControl will not point to a valid surface.

Prior to the introduction of the #createFrom call, this unwanted state
didn't cause any problems. Because mSurface was released back in the
finally block as we were stopping we now fall out of the
mSurface.isValid() block in updateSurface. As we reach the finally
block again, we would now set mSurfaceControl=null since the app was
no longer stopped. Later when we reach updateSurface again (which
tends to happen quite often) it will now be null and we will correctly
set creating=true, create a valid SurfaceControl, and move along
happily. However following, the introduction of this
Surface#createFrom call we will now reinitialize the Surface from an
invalid underlying SurfaceControl. This means we will enter the
mSurface.isValid block, but will proceed to emit an invalid Surface to
the client in the callbacks.

We avoid this state by making creating=true even if
SurfaceControl=non-null when the calculated visibility changes from
invisible to visible.

Bug: 63251745
Test: Manual of app from bug and apps from previous related bugs. go/wm-smoke. Additional manual testing of many SV apps.
Change-Id: Icc32a34cac239d65267da705cc23feb23e1ceb67
(cherry picked from commit 7c67b7d097bbf4a32e7b97689f97139a4b71007b)
core/java/android/view/SurfaceView.java