Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 109a8663 authored by Robert Carr's avatar Robert Carr
Browse files

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
parent 4f4df1d7
Loading
Loading
Loading
Loading
+152 −63
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.graphics.Region;
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 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
    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 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
        }
    }

    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 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
                    updateOpaqueFlag();
                    final String name = "SurfaceView - " + viewRoot.getTitle().toString();

                    mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession)
                        .setName(name)
                        .setOpaque((mSurfaceFlags & SurfaceControl.OPAQUE) != 0)
                    mSurfaceControl = new SurfaceControlWithBackground(
                            name,
                            (mSurfaceFlags & SurfaceControl.OPAQUE) != 0,
                            new SurfaceControl.Builder(mSurfaceSession)
                                    .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();

                                    .setFlags(mSurfaceFlags));
                } else if (mSurfaceControl == null) {
                    return;
                }
@@ -607,13 +577,11 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
                    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 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
                    }

                    if (creating) {
                        mSurface.copyFrom(mSurfaceControl);
                        mSurface.copyFrom(mSurfaceControl.mForegroundControl);
                    }

                    if (sizeChanged && getContext().getApplicationInfo().targetSdkVersion
@@ -709,7 +677,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
                        // 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 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
                    if (mSurfaceControl != null && !mSurfaceCreated) {
                        mSurface.release();

                        releaseSurfaces();
                        mSurfaceControl.remove();
                        mSurfaceControl = null;
                    }
                }
            } catch (Exception ex) {
@@ -857,7 +826,8 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
    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 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
            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 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
     * @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 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
     * @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();
            }
        }
    }
}