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

Commit 9c146bfe authored by Adam Powell's avatar Adam Powell
Browse files

Refinement for onVisibilityAggregated

Change the args for onVisibilityAggregated to a single boolean for
visibility to the user. Also fix an ordering bug that could trigger a
view background drawable call to setVisible before the view would
respond true to verifyDrawable, which caused issues with some apps.

Bug 27461617
Bug 27689884

Change-Id: I58bdc7c4364264f7fa0863689ba2b76df904ef81
parent 83d0078f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -42597,7 +42597,7 @@ package android.view {
    method public void onStartTemporaryDetach();
    method public boolean onTouchEvent(android.view.MotionEvent);
    method public boolean onTrackballEvent(android.view.MotionEvent);
    method public void onVisibilityAggregated(android.view.View, int);
    method public void onVisibilityAggregated(boolean);
    method protected void onVisibilityChanged(android.view.View, int);
    method public void onWindowFocusChanged(boolean);
    method public void onWindowSystemUiVisibilityChanged(int);
+1 −1
Original line number Diff line number Diff line
@@ -45351,7 +45351,7 @@ package android.view {
    method public void onStartTemporaryDetach();
    method public boolean onTouchEvent(android.view.MotionEvent);
    method public boolean onTrackballEvent(android.view.MotionEvent);
    method public void onVisibilityAggregated(android.view.View, int);
    method public void onVisibilityAggregated(boolean);
    method protected void onVisibilityChanged(android.view.View, int);
    method public void onWindowFocusChanged(boolean);
    method public void onWindowSystemUiVisibilityChanged(int);
+1 −1
Original line number Diff line number Diff line
@@ -42671,7 +42671,7 @@ package android.view {
    method public void onStartTemporaryDetach();
    method public boolean onTouchEvent(android.view.MotionEvent);
    method public boolean onTrackballEvent(android.view.MotionEvent);
    method public void onVisibilityAggregated(android.view.View, int);
    method public void onVisibilityAggregated(boolean);
    method protected void onVisibilityChanged(android.view.View, int);
    method public void onWindowFocusChanged(boolean);
    method public void onWindowSystemUiVisibilityChanged(int);
+43 −32
Original line number Diff line number Diff line
@@ -10210,44 +10210,38 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     * ViewGroup. Intended to only be called when {@link #isAttachedToWindow()},
     * {@link #getWindowVisibility()} is {@link #VISIBLE} and this view's parent {@link #isShown()}.
     *
     * @param changedView the view that changed, either <code>this</code> or an ancestor
     * @param visibility aggregated visibility of this view's parent or changedView, whichever
     *                   is closer
     * @return the aggregated visibility for this view
     * @param isVisible true if this view's visibility to the user is uninterrupted by its
     *                  ancestors or by window visibility
     * @return true if this view is visible to the user, not counting clipping or overlapping
     */
    int dispatchVisibilityAggregated(View changedView, @Visibility int visibility) {
        visibility = Math.max(visibility, getVisibility());
        onVisibilityAggregated(changedView, visibility);
        return visibility;
    @Visibility boolean dispatchVisibilityAggregated(boolean isVisible) {
        final boolean thisVisible = getVisibility() == VISIBLE;
        if (thisVisible) {
            onVisibilityAggregated(isVisible);
        }
        return thisVisible && isVisible;
    }
    /**
     * Called when the user-visibility of this View is potentially affected by a change
     * to this view itself, an ancestor view or the window this view is attached to.
     *
     * <p>The visibility value reported will be one of {@link #VISIBLE}, {@link #INVISIBLE}
     * or {@link #GONE}, reflecting this view's aggregated visibility within its window.
     * The visibility parameter takes this view's own visibility into account.
     * Calls to this method may be repeated with the same visibility values; implementations
     * should ensure that work done is not duplicated unnecessarily.</p>
     *
     * @param changedView the view that changed; may be <code>this</code> or an ancestor
     * @param visibility the visibility of this view in the context of the full window
     * @param isVisible true if this view and all of its ancestors are {@link #VISIBLE}
     *                  and this view's window is also visible
     */
    @CallSuper
    public void onVisibilityAggregated(View changedView, @Visibility int visibility) {
        final boolean visible = visibility == VISIBLE && getVisibility() == VISIBLE;
        if (visible && mAttachInfo != null) {
    public void onVisibilityAggregated(boolean isVisible) {
        if (isVisible && mAttachInfo != null) {
            initialAwakenScrollBars();
        }
        final Drawable dr = mBackground;
        if (dr != null && visible != dr.isVisible()) {
            dr.setVisible(visible, false);
        if (dr != null && isVisible != dr.isVisible()) {
            dr.setVisible(isVisible, false);
        }
        final Drawable fg = mForegroundInfo != null ? mForegroundInfo.mDrawable : null;
        if (fg != null && visible != fg.isVisible()) {
            fg.setVisible(visible, false);
        if (fg != null && isVisible != fg.isVisible()) {
            fg.setVisible(isVisible, false);
        }
    }
@@ -11376,7 +11370,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                // to change animation states.
                if (mParent != null && getWindowVisibility() == VISIBLE &&
                        ((!(mParent instanceof ViewGroup)) || ((ViewGroup) mParent).isShown())) {
                    dispatchVisibilityAggregated(this, newVisibility);
                    dispatchVisibilityAggregated(newVisibility == VISIBLE);
                }
                notifySubtreeAccessibilityStateChangedIfNeeded();
            }
@@ -15289,7 +15283,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        if (vis != GONE) {
            onWindowVisibilityChanged(vis);
            if (isShown()) {
                onVisibilityAggregated(this, vis);
                // Calling onVisibilityChanged directly here since the subtree will also
                // receive dispatchAttachedToWindow and this same call
                onVisibilityAggregated(vis == VISIBLE);
            }
        }
@@ -15312,7 +15308,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            if (vis != GONE) {
                onWindowVisibilityChanged(GONE);
                if (isShown()) {
                    onVisibilityAggregated(this, GONE);
                    // Invoking onVisibilityAggregated directly here since the subtree
                    // will also receive detached from window
                    onVisibilityAggregated(false);
                }
            }
        }
@@ -18001,12 +17999,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        /*
         * Regardless of whether we're setting a new background or not, we want
         * to clear the previous drawable.
         * to clear the previous drawable. setVisible first while we still have the callback set.
         */
        if (mBackground != null) {
            if (isAttachedToWindow()) {
                mBackground.setVisible(false, false);
            }
            mBackground.setCallback(null);
            unscheduleDrawable(mBackground);
            mBackground.setVisible(false, false);
        }
        if (background != null) {
@@ -18043,12 +18043,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                requestLayout = true;
            }
            // Set mBackground before we set this as the callback and start making other
            // background drawable state change calls. In particular, the setVisible call below
            // can result in drawables attempting to start animations or otherwise invalidate,
            // which requires the view set as the callback (us) to recognize the drawable as
            // belonging to it as per verifyDrawable.
            mBackground = background;
            background.setCallback(this);
            if (background.isStateful()) {
                background.setState(getDrawableState());
            }
            if (isAttachedToWindow()) {
                background.setVisible(getWindowVisibility() == VISIBLE && isShown(), false);
            mBackground = background;
            }
            applyBackgroundTint();
@@ -18227,9 +18234,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        }
        if (mForegroundInfo.mDrawable != null) {
            if (isAttachedToWindow()) {
                mForegroundInfo.mDrawable.setVisible(false, false);
            }
            mForegroundInfo.mDrawable.setCallback(null);
            unscheduleDrawable(mForegroundInfo.mDrawable);
            mForegroundInfo.mDrawable.setVisible(false, false);
        }
        mForegroundInfo.mDrawable = foreground;
@@ -18244,7 +18253,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                foreground.setState(getDrawableState());
            }
            applyForegroundTint();
            if (isAttachedToWindow()) {
                foreground.setVisible(getWindowVisibility() == VISIBLE && isShown(), false);
            }
        } else if ((mViewFlags & WILL_NOT_DRAW) != 0 && mBackground == null) {
            mPrivateFlags |= PFLAG_SKIP_DRAW;
        }
+8 −9
Original line number Diff line number Diff line
@@ -1291,20 +1291,19 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
    }

    @Override
    int dispatchVisibilityAggregated(View changedView, @Visibility int visibility) {
        visibility = super.dispatchVisibilityAggregated(changedView, visibility);
    boolean dispatchVisibilityAggregated(boolean isVisible) {
        isVisible = super.dispatchVisibilityAggregated(isVisible);
        final int count = mChildrenCount;
        final View[] children = mChildren;
        for (int i = 0; i < count; i++) {
            // Only dispatch to children with at least the same level of visibility
            // that we're reporting, otherwise it won't affect that child/subtree at all
            // so it's not worth telling them about it. Note that we use <= here
            // because VISIBLE < INVISIBLE < GONE as constant values.
            if (children[i].getVisibility() <= visibility) {
                children[i].dispatchVisibilityAggregated(changedView, visibility);
            // Only dispatch to visible children. Not visible children and their subtrees already
            // know that they aren't visible and that's not going to change as a result of
            // whatever triggered this dispatch.
            if (children[i].getVisibility() == VISIBLE) {
                children[i].dispatchVisibilityAggregated(isVisible);
            }
        }
        return visibility;
        return isVisible;
    }

    @Override
Loading