Revert SurfaceView background implementation.
We changed the SurfaceView background to be a boundless
child layer. However this was a semantic change. Each SurfaceView now
has its own background behind it instead of the backgrounds being
behind all SurfaceView. This causes an issue with some apps which
have an invisible SurfaceView hanging out for no particular reason.
Revert "SurfaceView: Correct comparison operator.",
"SurfaceView: Only show background when behind ViewRoot.",
"SurfaceView: Check correct OPAQUE flag for background visibility.",
"Correct SurfaceView background visibility.",
"Replace SurfaceView background with boundless color layer."
Bug: 123920952
Test: SurfaceViewTest. SurfaceViewSurfaceValidatorTest
Change-Id: I88ff31542ee0139d15c84ed2d6791c5cd455604b
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index bbb9053..1812d29 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -33,6 +33,7 @@
import android.graphics.RenderNode;
import android.os.Build;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Looper;
import android.os.SystemClock;
import android.util.AttributeSet;
@@ -119,11 +120,10 @@
final Rect mScreenRect = new Rect();
SurfaceSession mSurfaceSession;
- SurfaceControl mSurfaceControl;
+ SurfaceControlWithBackground mSurfaceControl;
// In the case of format changes we switch out the surface in-place
// we need to preserve the old one until the new one has drawn.
- SurfaceControl mDeferredDestroySurfaceControl;
- SurfaceControl mBackgroundControl;
+ SurfaceControlWithBackground mDeferredDestroySurfaceControl;
final Rect mTmpRect = new Rect();
final Configuration mConfiguration = new Configuration();
@@ -487,29 +487,6 @@
}
}
- private void updateBackgroundVisibilityInTransaction() {
- if (mBackgroundControl == null) {
- return;
- }
- if ((mSubLayer < 0) && ((mSurfaceFlags & SurfaceControl.OPAQUE) != 0)) {
- mBackgroundControl.show();
- mBackgroundControl.setLayer(Integer.MIN_VALUE);
- } else {
- mBackgroundControl.hide();
- }
- }
-
- private void releaseSurfaces() {
- if (mSurfaceControl != null) {
- mSurfaceControl.remove();
- mSurfaceControl = null;
- }
- if (mBackgroundControl != null) {
- mBackgroundControl.remove();
- mBackgroundControl = null;
- }
- }
-
/** @hide */
protected void updateSurface() {
if (!mHaveFrame) {
@@ -576,21 +553,14 @@
updateOpaqueFlag();
final String name = "SurfaceView - " + viewRoot.getTitle().toString();
- mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession)
- .setName(name)
- .setOpaque((mSurfaceFlags & SurfaceControl.OPAQUE) != 0)
- .setBufferSize(mSurfaceWidth, mSurfaceHeight)
- .setFormat(mFormat)
- .setParent(viewRoot.getSurfaceControl())
- .setFlags(mSurfaceFlags)
- .build();
- mBackgroundControl = new SurfaceControl.Builder(mSurfaceSession)
- .setName("Background for -" + name)
- .setOpaque(true)
- .setColorLayer()
- .setParent(mSurfaceControl)
- .build();
-
+ mSurfaceControl = new SurfaceControlWithBackground(
+ name,
+ (mSurfaceFlags & SurfaceControl.OPAQUE) != 0,
+ new SurfaceControl.Builder(mSurfaceSession)
+ .setBufferSize(mSurfaceWidth, mSurfaceHeight)
+ .setFormat(mFormat)
+ .setParent(viewRoot.getSurfaceControl())
+ .setFlags(mSurfaceFlags));
} else if (mSurfaceControl == null) {
return;
}
@@ -607,13 +577,11 @@
SurfaceControl.openTransaction();
try {
mSurfaceControl.setLayer(mSubLayer);
-
if (mViewVisibility) {
mSurfaceControl.show();
} else {
mSurfaceControl.hide();
}
- updateBackgroundVisibilityInTransaction();
// While creating the surface, we will set it's initial
// geometry. Outside of that though, we should generally
@@ -699,7 +667,7 @@
}
if (creating) {
- mSurface.copyFrom(mSurfaceControl);
+ mSurface.copyFrom(mSurfaceControl.mForegroundControl);
}
if (sizeChanged && getContext().getApplicationInfo().targetSdkVersion
@@ -709,7 +677,7 @@
// existing {@link Surface} will be ignored when the size changes.
// Therefore, we must explicitly recreate the {@link Surface} in these
// cases.
- mSurface.createFrom(mSurfaceControl);
+ mSurface.createFrom(mSurfaceControl.mForegroundControl);
}
if (visible && mSurface.isValid()) {
@@ -756,7 +724,8 @@
if (mSurfaceControl != null && !mSurfaceCreated) {
mSurface.release();
- releaseSurfaces();
+ mSurfaceControl.remove();
+ mSurfaceControl = null;
}
}
} catch (Exception ex) {
@@ -857,7 +826,8 @@
private void setParentSpaceRectangle(Rect position, long frameNumber) {
final ViewRootImpl viewRoot = getViewRootImpl();
- applySurfaceTransforms(mSurfaceControl, position, frameNumber);
+ applySurfaceTransforms(mSurfaceControl.mForegroundControl, position, frameNumber);
+ applySurfaceTransforms(mSurfaceControl.mBackgroundControl, position, frameNumber);
applyChildSurfaceTransaction_renderWorker(mRtTransaction, viewRoot.mSurface,
frameNumber);
@@ -922,10 +892,13 @@
if (frameNumber > 0) {
final ViewRootImpl viewRoot = getViewRootImpl();
- mRtTransaction.deferTransactionUntilSurface(mSurfaceControl, viewRoot.mSurface,
+ mRtTransaction.deferTransactionUntilSurface(mSurfaceControl.mForegroundControl, viewRoot.mSurface,
+ frameNumber);
+ mRtTransaction.deferTransactionUntilSurface(mSurfaceControl.mBackgroundControl, viewRoot.mSurface,
frameNumber);
}
- mRtTransaction.hide(mSurfaceControl);
+ mRtTransaction.hide(mSurfaceControl.mForegroundControl);
+ mRtTransaction.hide(mSurfaceControl.mBackgroundControl);
mRtTransaction.apply();
}
};
@@ -972,19 +945,7 @@
* @hide
*/
public void setResizeBackgroundColor(int bgColor) {
- if (mBackgroundControl == null) {
- return;
- }
-
- final float[] colorComponents = new float[] { Color.red(bgColor) / 255.f,
- Color.green(bgColor) / 255.f, Color.blue(bgColor) / 255.f };
-
- SurfaceControl.openTransaction();
- try {
- mBackgroundControl.setColor(colorComponents);
- } finally {
- SurfaceControl.closeTransaction();
- }
+ mSurfaceControl.setBackgroundColor(bgColor);
}
@UnsupportedAppUsage
@@ -1168,6 +1129,134 @@
* @return The SurfaceControl for this SurfaceView.
*/
public SurfaceControl getSurfaceControl() {
- return mSurfaceControl;
+ return mSurfaceControl.mForegroundControl;
+ }
+
+ class SurfaceControlWithBackground {
+ SurfaceControl mForegroundControl;
+ SurfaceControl mBackgroundControl;
+ private boolean mOpaque = true;
+ public boolean mVisible = false;
+
+ public SurfaceControlWithBackground(String name, boolean opaque, SurfaceControl.Builder b)
+ throws Exception {
+ mForegroundControl = b.setName(name).build();
+ mBackgroundControl = b.setName("Background for -" + name)
+ // Unset the buffer size of the background color layer.
+ .setBufferSize(0, 0)
+ .setColorLayer()
+ .build();
+
+ mOpaque = opaque;
+ }
+
+ public void setAlpha(float alpha) {
+ mForegroundControl.setAlpha(alpha);
+ mBackgroundControl.setAlpha(alpha);
+ }
+
+ public void setLayer(int zorder) {
+ mForegroundControl.setLayer(zorder);
+ // -3 is below all other child layers as SurfaceView never goes below -2
+ mBackgroundControl.setLayer(-3);
+ }
+
+ public void setPosition(float x, float y) {
+ mForegroundControl.setPosition(x, y);
+ mBackgroundControl.setPosition(x, y);
+ }
+
+ public void setBufferSize(int w, int h) {
+ mForegroundControl.setBufferSize(w, h);
+ // The background surface is a color layer so we do not set a size.
+ }
+
+ public void setWindowCrop(Rect crop) {
+ mForegroundControl.setWindowCrop(crop);
+ mBackgroundControl.setWindowCrop(crop);
+ }
+
+ public void setWindowCrop(int width, int height) {
+ mForegroundControl.setWindowCrop(width, height);
+ mBackgroundControl.setWindowCrop(width, height);
+ }
+
+ public void setLayerStack(int layerStack) {
+ mForegroundControl.setLayerStack(layerStack);
+ mBackgroundControl.setLayerStack(layerStack);
+ }
+
+ public void setOpaque(boolean isOpaque) {
+ mForegroundControl.setOpaque(isOpaque);
+ mOpaque = isOpaque;
+ updateBackgroundVisibility();
+ }
+
+ public void setSecure(boolean isSecure) {
+ mForegroundControl.setSecure(isSecure);
+ }
+
+ public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
+ mForegroundControl.setMatrix(dsdx, dtdx, dsdy, dtdy);
+ mBackgroundControl.setMatrix(dsdx, dtdx, dsdy, dtdy);
+ }
+
+ public void hide() {
+ mForegroundControl.hide();
+ mVisible = false;
+ updateBackgroundVisibility();
+ }
+
+ public void show() {
+ mForegroundControl.show();
+ mVisible = true;
+ updateBackgroundVisibility();
+ }
+
+ public void remove() {
+ mForegroundControl.remove();
+ mBackgroundControl.remove();
+ }
+
+ public void release() {
+ mForegroundControl.release();
+ mBackgroundControl.release();
+ }
+
+ public void setTransparentRegionHint(Region region) {
+ mForegroundControl.setTransparentRegionHint(region);
+ mBackgroundControl.setTransparentRegionHint(region);
+ }
+
+ public void deferTransactionUntil(IBinder handle, long frame) {
+ mForegroundControl.deferTransactionUntil(handle, frame);
+ mBackgroundControl.deferTransactionUntil(handle, frame);
+ }
+
+ public void deferTransactionUntil(Surface barrier, long frame) {
+ mForegroundControl.deferTransactionUntil(barrier, frame);
+ mBackgroundControl.deferTransactionUntil(barrier, frame);
+ }
+
+ /** Set the color to fill the background with. */
+ private void setBackgroundColor(int bgColor) {
+ final float[] colorComponents = new float[] { Color.red(bgColor) / 255.f,
+ Color.green(bgColor) / 255.f, Color.blue(bgColor) / 255.f };
+
+ SurfaceControl.openTransaction();
+ try {
+ mBackgroundControl.setColor(colorComponents);
+ } finally {
+ SurfaceControl.closeTransaction();
+ }
+ }
+
+ void updateBackgroundVisibility() {
+ if (mOpaque && mVisible) {
+ mBackgroundControl.show();
+ } else {
+ mBackgroundControl.hide();
+ }
+ }
}
}