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

Commit d691d0d2 authored by Lyn Han's avatar Lyn Han Committed by Android (Google) Code Review
Browse files

Merge "Fix dot for smart reply and bubble groups"

parents 04d77e17 f1f2c33f
Loading
Loading
Loading
Loading
+75 −80
Original line number Original line Diff line number Diff line
@@ -168,7 +168,7 @@ public class BubbleStackView extends FrameLayout {
     * Callback to run after the flyout hides. Also called if a new flyout is shown before the
     * Callback to run after the flyout hides. Also called if a new flyout is shown before the
     * previous one animates out.
     * previous one animates out.
     */
     */
    private Runnable mAfterFlyoutHides;
    private Runnable mFlyoutOnHide;


    /** Layout change listener that moves the stack to the nearest valid position on rotation. */
    /** Layout change listener that moves the stack to the nearest valid position on rotation. */
    private OnLayoutChangeListener mOrientationChangedListener;
    private OnLayoutChangeListener mOrientationChangedListener;
@@ -1366,73 +1366,48 @@ public class BubbleStackView extends FrameLayout {
    @VisibleForTesting
    @VisibleForTesting
    void animateInFlyoutForBubble(Bubble bubble) {
    void animateInFlyoutForBubble(Bubble bubble) {
        final CharSequence updateMessage = bubble.getUpdateMessage(getContext());
        final CharSequence updateMessage = bubble.getUpdateMessage(getContext());

        if (!bubble.showFlyoutForBubble()) {
        if (!bubble.showFlyoutForBubble()) {
            // In case flyout was suppressed for this update, reset now.
            // In case flyout was suppressed for this update, reset now.
            bubble.setSuppressFlyout(false);
            bubble.setSuppressFlyout(false);
            return;
            return;
        }
        }

        if (updateMessage == null
        if (updateMessage == null
                || isExpanded()
                || isExpanded()
                || mIsExpansionAnimating
                || mIsExpansionAnimating
                || mIsGestureInProgress
                || mIsGestureInProgress
                || mBubbleToExpandAfterFlyoutCollapse != null) {
                || mBubbleToExpandAfterFlyoutCollapse != null
                || bubble.getIconView() == null) {
            // Skip the message if none exists, we're expanded or animating expansion, or we're
            // Skip the message if none exists, we're expanded or animating expansion, or we're
            // about to expand a bubble from the previous tapped flyout.
            // about to expand a bubble from the previous tapped flyout, or if bubble view is null.
            return;
            return;
        }
        }

        if (bubble.getIconView() != null) {
            // Temporarily suppress the dot while the flyout is visible.
            bubble.getIconView().setSuppressDot(
                    true /* suppressDot */, false /* animate */);

            mFlyout.removeCallbacks(mAnimateInFlyout);
        mFlyoutDragDeltaX = 0f;
        mFlyoutDragDeltaX = 0f;

        clearFlyoutOnHide();
            if (mAfterFlyoutHides != null) {
        mFlyoutOnHide = () -> {
                mAfterFlyoutHides.run();
            resetDot(bubble);
            }
            if (mBubbleToExpandAfterFlyoutCollapse == null) {

                return;
            mAfterFlyoutHides = () -> {
                final boolean suppressDot = !bubble.showBubbleDot();
                // If we're going to suppress the dot, make it visible first so it'll
                // visibly animate away.
                if (suppressDot) {
                    bubble.getIconView().setSuppressDot(
                            false /* suppressDot */, false /* animate */);
            }
            }
                // Reset dot suppression. If we're not suppressing due to DND, then
                // stop suppressing it with no animation (since the flyout has
                // transformed into the dot). If we are suppressing due to DND, animate
                // it away.
                bubble.getIconView().setSuppressDot(
                        suppressDot /* suppressDot */,
                        suppressDot /* animate */);

                if (mBubbleToExpandAfterFlyoutCollapse != null) {
            mBubbleData.setSelectedBubble(mBubbleToExpandAfterFlyoutCollapse);
            mBubbleData.setSelectedBubble(mBubbleToExpandAfterFlyoutCollapse);
            mBubbleData.setExpanded(true);
            mBubbleData.setExpanded(true);
            mBubbleToExpandAfterFlyoutCollapse = null;
            mBubbleToExpandAfterFlyoutCollapse = null;
                }
        };
        };

        mFlyout.setVisibility(INVISIBLE);
        mFlyout.setVisibility(INVISIBLE);


            // Post in case layout isn't complete and getWidth returns 0.
        // Temporarily suppress the dot while the flyout is visible.
        bubble.getIconView().setSuppressDot(
                true /* suppressDot */, false /* animate */);

        // Start flyout expansion. Post in case layout isn't complete and getWidth returns 0.
        post(() -> {
        post(() -> {
            // An auto-expanding bubble could have been posted during the time it takes to
            // An auto-expanding bubble could have been posted during the time it takes to
            // layout.
            // layout.
            if (isExpanded()) {
            if (isExpanded()) {
                return;
                return;
            }
            }

            final Runnable expandFlyoutAfterDelay = () -> {
                final Runnable afterShow = () -> {
                mAnimateInFlyout = () -> {
                mAnimateInFlyout = () -> {
                    mFlyout.setVisibility(VISIBLE);
                    mFlyout.setVisibility(VISIBLE);
                        bubble.getIconView().setSuppressDot(
                                true /* suppressDot */, false /* animate */);
                    mFlyoutDragDeltaX =
                    mFlyoutDragDeltaX =
                            mStackAnimationController.isStackOnLeftSide()
                            mStackAnimationController.isStackOnLeftSide()
                                    ? -mFlyout.getWidth()
                                    ? -mFlyout.getWidth()
@@ -1440,37 +1415,57 @@ public class BubbleStackView extends FrameLayout {
                    animateFlyoutCollapsed(false /* collapsed */, 0 /* velX */);
                    animateFlyoutCollapsed(false /* collapsed */, 0 /* velX */);
                    mFlyout.postDelayed(mHideFlyout, FLYOUT_HIDE_AFTER);
                    mFlyout.postDelayed(mHideFlyout, FLYOUT_HIDE_AFTER);
                };
                };

                mFlyout.postDelayed(mAnimateInFlyout, 200);
                mFlyout.postDelayed(mAnimateInFlyout, 200);
            };
            };

            mFlyout.setupFlyoutStartingAsDot(
            mFlyout.setupFlyoutStartingAsDot(
                    updateMessage, mStackAnimationController.getStackPosition(), getWidth(),
                    updateMessage, mStackAnimationController.getStackPosition(), getWidth(),
                    mStackAnimationController.isStackOnLeftSide(),
                    mStackAnimationController.isStackOnLeftSide(),
                        bubble.getIconView().getBadgeColor(),
                    bubble.getIconView().getBadgeColor() /* dotColor */,
                        afterShow,
                    expandFlyoutAfterDelay /* onLayoutComplete */,
                        mAfterFlyoutHides,
                    mFlyoutOnHide,
                    bubble.getIconView().getDotCenter());
                    bubble.getIconView().getDotCenter());
            mFlyout.bringToFront();
            mFlyout.bringToFront();
        });
        });
        }

        mFlyout.removeCallbacks(mHideFlyout);
        mFlyout.removeCallbacks(mHideFlyout);
        mFlyout.postDelayed(mHideFlyout, FLYOUT_HIDE_AFTER);
        mFlyout.postDelayed(mHideFlyout, FLYOUT_HIDE_AFTER);
        logBubbleEvent(bubble, StatsLog.BUBBLE_UICHANGED__ACTION__FLYOUT);
        logBubbleEvent(bubble, StatsLog.BUBBLE_UICHANGED__ACTION__FLYOUT);
    }
    }


    /** Hide the flyout immediately and cancel any pending hide runnables. */
    private void resetDot(Bubble bubble) {
    private void hideFlyoutImmediate() {
        final boolean suppressDot = !bubble.showBubbleDot();
        if (mAfterFlyoutHides != null) {
        // If we're going to suppress the dot, make it visible first so it'll
            mAfterFlyoutHides.run();
        // visibly animate away.

        if (suppressDot) {
            bubble.getIconView().setSuppressDot(
                    false /* suppressDot */, false /* animate */);
        }
        // Reset dot suppression. If we're not suppressing due to DND, then
        // stop suppressing it with no animation (since the flyout has
        // transformed into the dot). If we are suppressing due to DND, animate
        // it away.
        bubble.getIconView().setSuppressDot(
                suppressDot /* suppressDot */,
                suppressDot /* animate */);
    }
    }


    /** Hide the flyout immediately and cancel any pending hide runnables. */
    private void hideFlyoutImmediate() {
        clearFlyoutOnHide();
        mFlyout.removeCallbacks(mAnimateInFlyout);
        mFlyout.removeCallbacks(mAnimateInFlyout);
        mFlyout.removeCallbacks(mHideFlyout);
        mFlyout.removeCallbacks(mHideFlyout);
        mFlyout.hideFlyout();
        mFlyout.hideFlyout();
    }
    }


    private void clearFlyoutOnHide() {
        mFlyout.removeCallbacks(mAnimateInFlyout);
        if (mFlyoutOnHide == null) {
            return;
        }
        mFlyoutOnHide.run();
        mFlyoutOnHide = null;
    }

    @Override
    @Override
    public void getBoundsOnScreen(Rect outRect) {
    public void getBoundsOnScreen(Rect outRect) {
        if (!mIsExpanded) {
        if (!mIsExpanded) {
+28 −26
Original line number Original line Diff line number Diff line
@@ -61,7 +61,7 @@ public class BubbleView extends FrameLayout {
    // mBubbleIconFactory cannot be static because it depends on Context.
    // mBubbleIconFactory cannot be static because it depends on Context.
    private BubbleIconFactory mBubbleIconFactory;
    private BubbleIconFactory mBubbleIconFactory;


    private boolean mSuppressDot = false;
    private boolean mSuppressDot;


    private Bubble mBubble;
    private Bubble mBubble;


@@ -140,6 +140,7 @@ public class BubbleView extends FrameLayout {
    public void setAppIcon(Drawable appIcon) {
    public void setAppIcon(Drawable appIcon) {
        mUserBadgedAppIcon = appIcon;
        mUserBadgedAppIcon = appIcon;
    }
    }

    /**
    /**
     * @return the {@link ExpandableNotificationRow} view to display notification content when the
     * @return the {@link ExpandableNotificationRow} view to display notification content when the
     * bubble is expanded.
     * bubble is expanded.
@@ -154,7 +155,6 @@ public class BubbleView extends FrameLayout {
        updateDotVisibility(animate, null /* after */);
        updateDotVisibility(animate, null /* after */);
    }
    }



    /**
    /**
     * Sets whether or not to hide the dot even if we'd otherwise show it. This is used while the
     * Sets whether or not to hide the dot even if we'd otherwise show it. This is used while the
     * flyout is visible or animating, to hide the dot until the flyout visually transforms into it.
     * flyout is visible or animating, to hide the dot until the flyout visually transforms into it.
@@ -166,7 +166,7 @@ public class BubbleView extends FrameLayout {


    /** Sets the position of the 'new' dot, animating it out and back in if requested. */
    /** Sets the position of the 'new' dot, animating it out and back in if requested. */
    void setDotPosition(boolean onLeft, boolean animate) {
    void setDotPosition(boolean onLeft, boolean animate) {
        if (animate && onLeft != mBadgedImageView.getDotOnLeft() && !mSuppressDot) {
        if (animate && onLeft != mBadgedImageView.getDotOnLeft() && shouldShowDot()) {
            animateDot(false /* showDot */, () -> {
            animateDot(false /* showDot */, () -> {
                mBadgedImageView.setDotOnLeft(onLeft);
                mBadgedImageView.setDotOnLeft(onLeft);
                animateDot(true /* showDot */, null);
                animateDot(true /* showDot */, null);
@@ -190,12 +190,12 @@ public class BubbleView extends FrameLayout {
     * after animation if requested.
     * after animation if requested.
     */
     */
    private void updateDotVisibility(boolean animate, Runnable after) {
    private void updateDotVisibility(boolean animate, Runnable after) {
        boolean showDot = mBubble.showBubbleDot() && !mSuppressDot;
        final boolean showDot = shouldShowDot();

        if (animate) {
        if (animate) {
            animateDot(showDot, after);
            animateDot(showDot, after);
        } else {
        } else {
            mBadgedImageView.setShowDot(showDot);
            mBadgedImageView.setShowDot(showDot);
            mBadgedImageView.setDotScale(showDot ? 1f : 0f);
        }
        }
    }
    }


@@ -203,10 +203,12 @@ public class BubbleView extends FrameLayout {
     * Animates the badge to show or hide.
     * Animates the badge to show or hide.
     */
     */
    private void animateDot(boolean showDot, Runnable after) {
    private void animateDot(boolean showDot, Runnable after) {
        if (mBadgedImageView.isShowingDot() != showDot) {
        if (mBadgedImageView.isShowingDot() == showDot) {
            if (showDot) {
            return;
                mBadgedImageView.setShowDot(true);
        }
        }
        // Do NOT wait until after animation ends to setShowDot
        // to avoid overriding more recent showDot states.
        mBadgedImageView.setShowDot(showDot);
        mBadgedImageView.clearAnimation();
        mBadgedImageView.clearAnimation();
        mBadgedImageView.animate().setDuration(200)
        mBadgedImageView.animate().setDuration(200)
                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
@@ -215,16 +217,12 @@ public class BubbleView extends FrameLayout {
                    fraction = showDot ? fraction : 1f - fraction;
                    fraction = showDot ? fraction : 1f - fraction;
                    mBadgedImageView.setDotScale(fraction);
                    mBadgedImageView.setDotScale(fraction);
                }).withEndAction(() -> {
                }).withEndAction(() -> {
                        if (!showDot) {
            mBadgedImageView.setDotScale(showDot ? 1f : 0f);
                            mBadgedImageView.setShowDot(false);
                        }

            if (after != null) {
            if (after != null) {
                after.run();
                after.run();
            }
            }
        }).start();
        }).start();
    }
    }
    }


    void updateViews() {
    void updateViews() {
        if (mBubble == null || mBubbleIconFactory == null) {
        if (mBubble == null || mBubbleIconFactory == null) {
@@ -273,7 +271,11 @@ public class BubbleView extends FrameLayout {
        iconPath.transform(matrix);
        iconPath.transform(matrix);
        mBadgedImageView.drawDot(iconPath);
        mBadgedImageView.drawDot(iconPath);


        animateDot(mBubble.showBubbleDot() /* showDot */, null /* after */);
        animateDot(shouldShowDot(), null /* after */);
    }

    boolean shouldShowDot() {
        return mBubble.showBubbleDot() && !mSuppressDot;
    }
    }


    int getBadgeColor() {
    int getBadgeColor() {