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

Commit b88267cb authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Revert "Remove background drawing behind notifications""

parents 80ff5c11 53f5af9e
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -357,6 +357,9 @@
         the notification is not swiped enough to dismiss it. -->
    <bool name="config_showNotificationGear">true</bool>

    <!-- Whether or not a background should be drawn behind a notification. -->
    <bool name="config_drawNotificationBackground">true</bool>

    <!-- Whether or the notifications can be shown and dismissed with a drag. -->
    <bool name="config_enableNotificationShadeDrag">true</bool>

+18 −0
Original line number Diff line number Diff line
@@ -82,6 +82,9 @@ public class AmbientState {
    private ExpandableNotificationRow mTrackedHeadsUpRow;
    private float mAppearFraction;

    /** Tracks the state from AlertingNotificationManager#hasNotifications() */
    private boolean mHasAlertEntries;

    public AmbientState(
            Context context,
            @NonNull SectionProvider sectionProvider) {
@@ -365,10 +368,21 @@ public class AmbientState {
        mPanelTracking = panelTracking;
    }

    public boolean hasPulsingNotifications() {
        return mPulsing && mHasAlertEntries;
    }

    public void setPulsing(boolean hasPulsing) {
        mPulsing = hasPulsing;
    }

    /**
     * @return if we're pulsing in general
     */
    public boolean isPulsing() {
        return mPulsing;
    }

    public boolean isPulsing(NotificationEntry entry) {
        return mPulsing && entry.isAlerting();
    }
@@ -527,4 +541,8 @@ public class AmbientState {
    public float getAppearFraction() {
        return mAppearFraction;
    }

    public void setHasAlertEntries(boolean hasAlertEntries) {
        mHasAlertEntries = hasAlertEntries;
    }
}
+244 −2
Original line number Diff line number Diff line
@@ -31,22 +31,175 @@ import com.android.systemui.statusbar.notification.ShadeViewRefactor;
import com.android.systemui.statusbar.notification.row.ExpandableView;

/**
 * Represents the priority of a notification section and tracks first and last visible children.
 * Represents the bounds of a section of the notification shade and handles animation when the
 * bounds change.
 */
public class NotificationSection {
    private @PriorityBucket int mBucket;
    private View mOwningView;
    private Rect mBounds = new Rect();
    private Rect mCurrentBounds = new Rect(-1, -1, -1, -1);
    private Rect mStartAnimationRect = new Rect();
    private Rect mEndAnimationRect = new Rect();
    private ObjectAnimator mTopAnimator = null;
    private ObjectAnimator mBottomAnimator = null;
    private ExpandableView mFirstVisibleChild;
    private ExpandableView mLastVisibleChild;

    NotificationSection(@PriorityBucket int bucket) {
    NotificationSection(View owningView, @PriorityBucket int bucket) {
        mOwningView = owningView;
        mBucket = bucket;
    }

    public void cancelAnimators() {
        if (mBottomAnimator != null) {
            mBottomAnimator.cancel();
        }
        if (mTopAnimator != null) {
            mTopAnimator.cancel();
        }
    }

    public Rect getCurrentBounds() {
        return mCurrentBounds;
    }

    public Rect getBounds() {
        return mBounds;
    }

    public boolean didBoundsChange() {
        return !mCurrentBounds.equals(mBounds);
    }

    public boolean areBoundsAnimating() {
        return mBottomAnimator != null || mTopAnimator != null;
    }

    @PriorityBucket
    public int getBucket() {
        return mBucket;
    }

    public void startBackgroundAnimation(boolean animateTop, boolean animateBottom) {
        // Left and right bounds are always applied immediately.
        mCurrentBounds.left = mBounds.left;
        mCurrentBounds.right = mBounds.right;
        startBottomAnimation(animateBottom);
        startTopAnimation(animateTop);
    }


    @ShadeViewRefactor(ShadeViewRefactor.RefactorComponent.STATE_RESOLVER)
    private void startTopAnimation(boolean animate) {
        int previousEndValue = mEndAnimationRect.top;
        int newEndValue = mBounds.top;
        ObjectAnimator previousAnimator = mTopAnimator;
        if (previousAnimator != null && previousEndValue == newEndValue) {
            return;
        }
        if (!animate) {
            // just a local update was performed
            if (previousAnimator != null) {
                // we need to increase all animation keyframes of the previous animator by the
                // relative change to the end value
                int previousStartValue = mStartAnimationRect.top;
                PropertyValuesHolder[] values = previousAnimator.getValues();
                values[0].setIntValues(previousStartValue, newEndValue);
                mStartAnimationRect.top = previousStartValue;
                mEndAnimationRect.top = newEndValue;
                previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
                return;
            } else {
                // no new animation needed, let's just apply the value
                setBackgroundTop(newEndValue);
                return;
            }
        }
        if (previousAnimator != null) {
            previousAnimator.cancel();
        }
        ObjectAnimator animator = ObjectAnimator.ofInt(this, "backgroundTop",
                mCurrentBounds.top, newEndValue);
        Interpolator interpolator = Interpolators.FAST_OUT_SLOW_IN;
        animator.setInterpolator(interpolator);
        animator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
        // remove the tag when the animation is finished
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mStartAnimationRect.top = -1;
                mEndAnimationRect.top = -1;
                mTopAnimator = null;
            }
        });
        animator.start();
        mStartAnimationRect.top = mCurrentBounds.top;
        mEndAnimationRect.top = newEndValue;
        mTopAnimator = animator;
    }

    @ShadeViewRefactor(ShadeViewRefactor.RefactorComponent.STATE_RESOLVER)
    private void startBottomAnimation(boolean animate) {
        int previousStartValue = mStartAnimationRect.bottom;
        int previousEndValue = mEndAnimationRect.bottom;
        int newEndValue = mBounds.bottom;
        ObjectAnimator previousAnimator = mBottomAnimator;
        if (previousAnimator != null && previousEndValue == newEndValue) {
            return;
        }
        if (!animate) {
            // just a local update was performed
            if (previousAnimator != null) {
                // we need to increase all animation keyframes of the previous animator by the
                // relative change to the end value
                PropertyValuesHolder[] values = previousAnimator.getValues();
                values[0].setIntValues(previousStartValue, newEndValue);
                mStartAnimationRect.bottom = previousStartValue;
                mEndAnimationRect.bottom = newEndValue;
                previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
                return;
            } else {
                // no new animation needed, let's just apply the value
                setBackgroundBottom(newEndValue);
                return;
            }
        }
        if (previousAnimator != null) {
            previousAnimator.cancel();
        }
        ObjectAnimator animator = ObjectAnimator.ofInt(this, "backgroundBottom",
                mCurrentBounds.bottom, newEndValue);
        Interpolator interpolator = Interpolators.FAST_OUT_SLOW_IN;
        animator.setInterpolator(interpolator);
        animator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
        // remove the tag when the animation is finished
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mStartAnimationRect.bottom = -1;
                mEndAnimationRect.bottom = -1;
                mBottomAnimator = null;
            }
        });
        animator.start();
        mStartAnimationRect.bottom = mCurrentBounds.bottom;
        mEndAnimationRect.bottom = newEndValue;
        mBottomAnimator = animator;
    }

    @ShadeViewRefactor(ShadeViewRefactor.RefactorComponent.SHADE_VIEW)
    private void setBackgroundTop(int top) {
        mCurrentBounds.top = top;
        mOwningView.invalidate();
    }

    @ShadeViewRefactor(ShadeViewRefactor.RefactorComponent.SHADE_VIEW)
    private void setBackgroundBottom(int bottom) {
        mCurrentBounds.bottom = bottom;
        mOwningView.invalidate();
    }

    public ExpandableView getFirstVisibleChild() {
        return mFirstVisibleChild;
    }
@@ -66,4 +219,93 @@ public class NotificationSection {
        mLastVisibleChild = child;
        return changed;
    }

    public void resetCurrentBounds() {
        mCurrentBounds.set(mBounds);
    }

    /**
     * Returns true if {@code top} is equal to the top of this section (if not currently animating)
     * or where the top of this section will be when animation completes.
     */
    public boolean isTargetTop(int top) {
        return (mTopAnimator == null && mCurrentBounds.top == top)
                || (mTopAnimator != null && mEndAnimationRect.top == top);
    }

    /**
     * Returns true if {@code bottom} is equal to the bottom of this section (if not currently
     * animating) or where the bottom of this section will be when animation completes.
     */
    public boolean isTargetBottom(int bottom) {
        return (mBottomAnimator == null && mCurrentBounds.bottom == bottom)
                || (mBottomAnimator != null && mEndAnimationRect.bottom == bottom);
    }

    /**
     * Update the bounds of this section based on it's views
     *
     * @param minTopPosition the minimum position that the top needs to have
     * @param minBottomPosition the minimum position that the bottom needs to have
     * @return the position of the new bottom
     */
    public int updateBounds(int minTopPosition, int minBottomPosition,
            boolean shiftBackgroundWithFirst) {
        int top = minTopPosition;
        int bottom = minTopPosition;
        ExpandableView firstView = getFirstVisibleChild();
        if (firstView != null) {
            // Round Y up to avoid seeing the background during animation
            int finalTranslationY = (int) Math.ceil(ViewState.getFinalTranslationY(firstView));
            // TODO: look into the already animating part
            int newTop;
            if (isTargetTop(finalTranslationY)) {
                // we're ending up at the same location as we are now, let's just skip the
                // animation
                newTop = finalTranslationY;
            } else {
                newTop = (int) Math.ceil(firstView.getTranslationY());
            }
            top = Math.max(newTop, top);
            if (firstView.showingPulsing()) {
                // If we're pulsing, the notification can actually go below!
                bottom = Math.max(bottom, finalTranslationY
                        + ExpandableViewState.getFinalActualHeight(firstView));
                if (shiftBackgroundWithFirst) {
                    mBounds.left += Math.max(firstView.getTranslation(), 0);
                    mBounds.right += Math.min(firstView.getTranslation(), 0);
                }
            }
        }
        top = Math.max(minTopPosition, top);
        ExpandableView lastView = getLastVisibleChild();
        if (lastView != null) {
            float finalTranslationY = ViewState.getFinalTranslationY(lastView);
            int finalHeight = ExpandableViewState.getFinalActualHeight(lastView);
            // Round Y down to avoid seeing the background during animation
            int finalBottom = (int) Math.floor(
                    finalTranslationY + finalHeight - lastView.getClipBottomAmount());
            int newBottom;
            if (isTargetBottom(finalBottom)) {
                // we're ending up at the same location as we are now, lets just skip the animation
                newBottom = finalBottom;
            } else {
                newBottom = (int) (lastView.getTranslationY() + lastView.getActualHeight()
                        - lastView.getClipBottomAmount());
                // The background can never be lower than the end of the last view
                minBottomPosition = (int) Math.min(
                        lastView.getTranslationY() + lastView.getActualHeight(),
                        minBottomPosition);
            }
            bottom = Math.max(bottom, Math.max(newBottom, minBottomPosition));
        }
        bottom = Math.max(top, bottom);
        mBounds.top = top;
        mBounds.bottom = bottom;
        return bottom;
    }

    public boolean needsBackground() {
        return mFirstVisibleChild != null && mBucket != BUCKET_MEDIA_CONTROLS;
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -126,7 +126,7 @@ class NotificationSectionsManager @Inject internal constructor(

    fun createSectionsForBuckets(): Array<NotificationSection> =
            sectionsFeatureManager.getNotificationBuckets()
                    .map { NotificationSection(it) }
                    .map { NotificationSection(parent, it) }
                    .toTypedArray()

    /**
+394 −13

File changed.

Preview size limit exceeded, changes collapsed.

Loading