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

Commit 290d6f35 authored by lumark's avatar lumark Committed by android-build-merger
Browse files

DO NOT MERGE: Fix ActivityView surface can't visible for ActivityViewTest

am: dc9b3190

Change-Id: Iedaebd2888f402e382a4eaf0d7385df2c17d0bdd
parents ba3add6b dc9b3190
Loading
Loading
Loading
Loading
+16 −2
Original line number Diff line number Diff line
@@ -120,7 +120,10 @@ public class ActivityView extends ViewGroup {

        mActivityTaskManager = ActivityTaskManager.getService();
        mSurfaceView = new SurfaceView(context);
        mSurfaceView.setAlpha(0f);
        // Since ActivityView#getAlpha has been overridden, we should use parent class's alpha
        // as master to synchronize surface view's alpha value.
        mSurfaceView.setAlpha(super.getAlpha());
        mSurfaceView.setUseAlpha();
        mSurfaceCallback = new SurfaceCallback();
        mSurfaceView.getHolder().addCallback(mSurfaceCallback);
        addView(mSurfaceView);
@@ -347,10 +350,21 @@ public class ActivityView extends ViewGroup {
        mSurfaceView.layout(0 /* left */, 0 /* top */, r - l /* right */, b - t /* bottom */);
    }

    /**
     * Sets the alpha value when the content of {@link SurfaceView} needs to show or hide.
     * <p>Note: The surface view may ignore the alpha value in some cases. Refer to
     * {@link SurfaceView#setAlpha} for more details.
     *
     * @param alpha The opacity of the view.
     */
    @Override
    public void setAlpha(float alpha) {
        super.setAlpha(alpha);

        if (mSurfaceView != null) {
            mSurfaceView.setAlpha(alpha);
        }
    }

    @Override
    public float getAlpha() {
+190 −30
Original line number Diff line number Diff line
@@ -100,6 +100,7 @@ import java.util.concurrent.locks.ReentrantLock;
public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallback {
    private static final String TAG = "SurfaceView";
    private static final boolean DEBUG = false;
    private static final boolean DEBUG_POSITION = false;

    @UnsupportedAppUsage
    final ArrayList<SurfaceHolder.Callback> mCallbacks
@@ -126,6 +127,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
    // we need to preserve the old one until the new one has drawn.
    SurfaceControl mDeferredDestroySurfaceControl;
    SurfaceControl mBackgroundControl;
    final Object mSurfaceControlLock = new Object();
    final Rect mTmpRect = new Rect();
    final Configuration mConfiguration = new Configuration();

@@ -173,6 +175,9 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
    @UnsupportedAppUsage
    int mRequestedFormat = PixelFormat.RGB_565;

    boolean mUseAlpha = false;
    float mSurfaceAlpha = 1f;

    @UnsupportedAppUsage
    boolean mHaveFrame = false;
    boolean mSurfaceCreated = false;
@@ -200,6 +205,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
    private int mPendingReportDraws;

    private SurfaceControl.Transaction mRtTransaction = new SurfaceControl.Transaction();
    private SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction();

    public SurfaceView(Context context) {
        this(context, null);
@@ -288,6 +294,152 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
        updateSurface();
    }

    /**
     * Make alpha value of this view reflect onto the surface. This can only be called from at most
     * one SurfaceView within a view tree.
     *
     * <p class="note"><strong>Note:</strong> Alpha value of the view is ignored and the underlying
     * surface is rendered opaque by default.</p>
     *
     * @hide
     */
    public void setUseAlpha() {
        if (!mUseAlpha) {
            mUseAlpha = true;
            updateSurfaceAlpha();
        }
    }

    @Override
    public void setAlpha(float alpha) {
        // Sets the opacity of the view to a value, where 0 means the view is completely transparent
        // and 1 means the view is completely opaque.
        //
        // Note: Alpha value of this view is ignored by default. To enable alpha blending, you need
        // to call setUseAlpha() as well.
        // This view doesn't support translucent opacity if the view is located z-below, since the
        // logic to punch a hole in the view hierarchy cannot handle such case. See also
        // #clearSurfaceViewPort(Canvas)
        if (DEBUG) {
            Log.d(TAG, System.identityHashCode(this)
                    + " setAlpha: mUseAlpha = " + mUseAlpha + " alpha=" + alpha);
        }
        super.setAlpha(alpha);
        updateSurfaceAlpha();
    }

    private float getFixedAlpha() {
        // Compute alpha value to be set on the underlying surface.
        final float alpha = getAlpha();
        return mUseAlpha && (mSubLayer > 0 || alpha == 0f) ? alpha : 1f;
    }

    private void updateSurfaceAlpha() {
        if (!mUseAlpha) {
            if (DEBUG) {
                Log.d(TAG, System.identityHashCode(this)
                        + " updateSurfaceAlpha: setUseAlpha() is not called, ignored.");
            }
            return;
        }
        final float viewAlpha = getAlpha();
        if (mSubLayer < 0 && 0f < viewAlpha && viewAlpha < 1f) {
            Log.w(TAG, System.identityHashCode(this)
                    + " updateSurfaceAlpha:"
                    + " translucent color is not supported for a surface placed z-below.");
        }
        if (!mHaveFrame) {
            if (DEBUG) {
                Log.d(TAG, System.identityHashCode(this)
                        + " updateSurfaceAlpha: has no surface.");
            }
            return;
        }
        final ViewRootImpl viewRoot = getViewRootImpl();
        if (viewRoot == null) {
            if (DEBUG) {
                Log.d(TAG, System.identityHashCode(this)
                        + " updateSurfaceAlpha: ViewRootImpl not available.");
            }
            return;
        }
        if (mSurfaceControl == null) {
            if (DEBUG) {
                Log.d(TAG, System.identityHashCode(this)
                        + "updateSurfaceAlpha:"
                        + " surface is not yet created, or already released.");
            }
            return;
        }
        final Surface parent = viewRoot.mSurface;
        if (parent == null || !parent.isValid()) {
            if (DEBUG) {
                Log.d(TAG, System.identityHashCode(this)
                        + " updateSurfaceAlpha: ViewRootImpl has no valid surface");
            }
            return;
        }
        final float alpha = getFixedAlpha();
        if (alpha != mSurfaceAlpha) {
            if (isHardwareAccelerated()) {
                /*
                 * Schedule a callback that reflects an alpha value onto the underlying surfaces.
                 * This gets called on a RenderThread worker thread, so members accessed here must
                 * be protected by a lock.
                 */
                viewRoot.registerRtFrameCallback(frame -> {
                    try {
                        final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
                        synchronized (mSurfaceControlLock) {
                            if (!parent.isValid()) {
                                if (DEBUG) {
                                    Log.d(TAG, System.identityHashCode(this)
                                            + " updateSurfaceAlpha RT:"
                                            + " ViewRootImpl has no valid surface");
                                }
                                return;
                            }
                            if (mSurfaceControl == null) {
                                if (DEBUG) {
                                    Log.d(TAG, System.identityHashCode(this)
                                            + "updateSurfaceAlpha RT:"
                                            + " mSurfaceControl has already released");
                                }
                                return;
                            }
                            if (DEBUG) {
                                Log.d(TAG, System.identityHashCode(this)
                                        + " updateSurfaceAlpha RT: set alpha=" + alpha);
                            }
                            t.setAlpha(mSurfaceControl, alpha);
                            t.deferTransactionUntilSurface(mSurfaceControl, parent, frame);
                        }
                        // It's possible that mSurfaceControl is released in the UI thread before
                        // the transaction completes. If that happens, an exception is thrown, which
                        // must be caught immediately.
                        t.apply();
                    } catch (Exception e) {
                        Log.e(TAG, System.identityHashCode(this)
                                + "updateSurfaceAlpha RT: Exception during surface transaction", e);
                    }
                });
                damageInParent();
            } else {
                if (DEBUG) {
                    Log.d(TAG, System.identityHashCode(this)
                            + " updateSurfaceAlpha: set alpha=" + alpha);
                }
                SurfaceControl.openTransaction();
                try {
                    mSurfaceControl.setAlpha(alpha);
                } finally {
                    SurfaceControl.closeTransaction();
                }
            }
            mSurfaceAlpha = alpha;
        }
    }

    private void performDrawFinished() {
        if (mPendingReportDraws > 0) {
            mDrawFinished = true;
@@ -337,11 +489,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
        mRequestedVisible = false;

        updateSurface();
        if (mSurfaceControl != null) {
            mSurfaceControl.remove();
        }
        mSurfaceControl = null;

        releaseSurfaces();
        mHaveFrame = false;

        super.onDetachedFromWindow();
@@ -510,15 +658,6 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
        }
    }

    private Rect getParentSurfaceInsets() {
        final ViewRootImpl root = getViewRootImpl();
        if (root == null) {
            return null;
        } else {
            return root.mWindowAttributes.surfaceInsets;
        }
    }

    private void updateBackgroundVisibilityInTransaction(SurfaceControl viewRoot) {
        if (mBackgroundControl == null) {
            return;
@@ -532,23 +671,34 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
    }

    private void releaseSurfaces() {
        synchronized (mSurfaceControlLock) {
            if (mSurfaceControl != null) {
            mSurfaceControl.remove();
                mTmpTransaction.remove(mSurfaceControl);
                mSurfaceControl = null;
            }
            if (mBackgroundControl != null) {
            mBackgroundControl.remove();
                mTmpTransaction.remove(mBackgroundControl);
                mBackgroundControl = null;
            }
            mTmpTransaction.apply();
        }
        mSurfaceAlpha = 1f;
    }

    /** @hide */
    protected void updateSurface() {
        if (!mHaveFrame) {
            if (DEBUG) {
                Log.d(TAG, System.identityHashCode(this) + " updateSurface: has no frame");
            }
            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");
            }
            return;
        }

@@ -562,20 +712,25 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
        int myHeight = mRequestedHeight;
        if (myHeight <= 0) myHeight = getHeight();

        final float alpha = getFixedAlpha();
        final boolean formatChanged = mFormat != mRequestedFormat;
        final boolean visibleChanged = mVisible != mRequestedVisible;
        final boolean alphaChanged = mSurfaceAlpha != alpha;
        final boolean creating = (mSurfaceControl == null || formatChanged || visibleChanged)
                && mRequestedVisible;
        final boolean sizeChanged = mSurfaceWidth != myWidth || mSurfaceHeight != myHeight;
        final boolean windowVisibleChanged = mWindowVisibility != mLastWindowVisibility;
        boolean redrawNeeded = false;

        if (creating || formatChanged || sizeChanged || visibleChanged || windowVisibleChanged) {
        if (creating || formatChanged || sizeChanged || visibleChanged || (mUseAlpha
                && alphaChanged) || windowVisibleChanged) {
            getLocationInWindow(mLocation);

            if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
                    + "Changes: creating=" + creating
                    + " format=" + formatChanged + " size=" + sizeChanged
                    + " visible=" + visibleChanged + " alpha=" + alphaChanged
                    + " mUseAlpha=" + mUseAlpha
                    + " visible=" + visibleChanged
                    + " left=" + (mWindowSpaceLeft != mLocation[0])
                    + " top=" + (mWindowSpaceTop != mLocation[1]));
@@ -597,7 +752,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
                    mTranslator.translateRectInAppWindowToScreen(mScreenRect);
                }

                final Rect surfaceInsets = getParentSurfaceInsets();
                final Rect surfaceInsets = viewRoot.mWindowAttributes.surfaceInsets;
                mScreenRect.offset(surfaceInsets.left, surfaceInsets.top);

                if (creating) {
@@ -646,6 +801,10 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
                            mSurfaceControl.hide();
                        }
                        updateBackgroundVisibilityInTransaction(viewRoot.getSurfaceControl());
                        if (mUseAlpha) {
                            mSurfaceControl.setAlpha(alpha);
                            mSurfaceAlpha = alpha;
                        }

                        // While creating the surface, we will set it's initial
                        // geometry. Outside of that though, we should generally
@@ -788,7 +947,6 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
                    mIsCreating = false;
                    if (mSurfaceControl != null && !mSurfaceCreated) {
                        mSurface.release();

                        releaseSurfaces();
                    }
                }
@@ -828,10 +986,13 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb

                if (!isHardwareAccelerated() || !mRtHandlingPositionUpdates) {
                    try {
                        if (DEBUG) Log.d(TAG, String.format("%d updateSurfacePosition UI, " +
                                "postion = [%d, %d, %d, %d]", System.identityHashCode(this),
                        if (DEBUG_POSITION) {
                            Log.d(TAG, String.format("%d updateSurfacePosition UI, "
                                            + "position = [%d, %d, %d, %d]",
                                    System.identityHashCode(this),
                                    mScreenRect.left, mScreenRect.top,
                                    mScreenRect.right, mScreenRect.bottom));
                        }
                        setParentSpaceRectangle(mScreenRect, -1);
                    } catch (Exception ex) {
                        Log.e(TAG, "Exception configuring surface", ex);
@@ -884,7 +1045,6 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
        if (mViewVisibility) {
            mRtTransaction.show(surface);
        }

    }

    private void setParentSpaceRectangle(Rect position, long frameNumber) {
@@ -925,7 +1085,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
                return;
            }
            try {
                if (DEBUG) {
                if (DEBUG_POSITION) {
                    Log.d(TAG, String.format(
                            "%d updateSurfacePosition RenderWorker, frameNr = %d, "
                                    + "postion = [%d, %d, %d, %d]",
+1 −1
Original line number Diff line number Diff line
@@ -182,7 +182,7 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList

        mActivityView = new ActivityView(mContext, null /* attrs */, 0 /* defStyle */,
                true /* singleTaskInstance */);

        // Set ActivityView's alpha value as zero, since there is no view content to be shown.
        setContentVisibility(false);
        addView(mActivityView);