From 7dd88b020988fe66288ad68e4e736426a297827e Mon Sep 17 00:00:00 2001 From: Joshua Tsuji Date: Fri, 27 Mar 2020 17:43:09 -0400 Subject: [PATCH] Delete BubbleTouchHandler in favor of more traditional touch handling. This will scale better as we add more views and gestures. Test: manual (fixing test suite now, just getting out for review!) Bug: 152877243 Merged-In: I46001c24f4de58c3d70b7629a22b930fa791b77a Change-Id: I46001c24f4de58c3d70b7629a22b930fa791b77a --- .../systemui/bubbles/BubbleController.java | 20 - .../android/systemui/bubbles/BubbleData.java | 13 + .../systemui/bubbles/BubbleStackView.java | 536 ++++++++++-------- .../systemui/bubbles/BubbleTouchHandler.java | 221 -------- .../ExpandedAnimationController.java | 11 +- .../animation/PhysicsAnimationLayout.java | 5 - .../systemui/util/RelativeTouchListener.kt | 162 ++++++ .../bubbles/BubbleControllerTest.java | 16 +- .../NewNotifPipelineBubbleControllerTest.java | 16 +- 9 files changed, 494 insertions(+), 506 deletions(-) delete mode 100644 packages/SystemUI/src/com/android/systemui/bubbles/BubbleTouchHandler.java create mode 100644 packages/SystemUI/src/com/android/systemui/util/RelativeTouchListener.kt diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index 9d885fd3c207e..99e5eb66a00f1 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -718,13 +718,6 @@ public class BubbleController implements ConfigurationController.ConfigurationLi return mBubbleData.isExpanded(); } - /** - * Tell the stack of bubbles to expand. - */ - public void expandStack() { - mBubbleData.setExpanded(true); - } - /** * Tell the stack of bubbles to collapse. */ @@ -753,12 +746,6 @@ public class BubbleController implements ConfigurationController.ConfigurationLi return (isSummary && isSuppressedSummary) || isBubbleAndSuppressed; } - @VisibleForTesting - void selectBubble(String key) { - Bubble bubble = mBubbleData.getBubbleWithKey(key); - mBubbleData.setSelectedBubble(bubble); - } - void promoteBubbleFromOverflow(Bubble bubble) { bubble.setInflateSynchronously(mInflateSynchronously); mBubbleData.promoteBubbleFromOverflow(bubble, mStackView, mBubbleIconFactory); @@ -777,13 +764,6 @@ public class BubbleController implements ConfigurationController.ConfigurationLi } } - /** - * Tell the stack of bubbles to be dismissed, this will remove all of the bubbles in the stack. - */ - void dismissStack(@DismissReason int reason) { - mBubbleData.dismissAll(reason); - } - /** * Directs a back gesture at the bubble stack. When opened, the current expanded bubble * is forwarded a back key down/up pair. diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java index be9cd5f01c86a..4c149ddd3939a 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java @@ -28,6 +28,7 @@ import android.content.Context; import android.service.notification.NotificationListenerService; import android.util.Log; import android.util.Pair; +import android.view.View; import androidx.annotation.Nullable; @@ -751,6 +752,7 @@ public class BubbleData { } @VisibleForTesting(visibility = PRIVATE) + @Nullable Bubble getBubbleWithKey(String key) { for (int i = 0; i < mBubbles.size(); i++) { Bubble bubble = mBubbles.get(i); @@ -761,6 +763,17 @@ public class BubbleData { return null; } + @Nullable + Bubble getBubbleWithView(View view) { + for (int i = 0; i < mBubbles.size(); i++) { + Bubble bubble = mBubbles.get(i); + if (bubble.getIconView() != null && bubble.getIconView().equals(view)) { + return bubble; + } + } + return null; + } + @VisibleForTesting(visibility = PRIVATE) Bubble getOverflowBubbleWithKey(String key) { for (int i = 0; i < mOverflowBubbles.size(); i++) { diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java index eff6934364511..8d443606e5b11 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java @@ -30,6 +30,7 @@ import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; +import android.annotation.SuppressLint; import android.app.Notification; import android.content.Context; import android.content.res.Configuration; @@ -43,6 +44,7 @@ import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; +import android.graphics.Region; import android.os.Bundle; import android.os.Vibrator; import android.util.Log; @@ -83,6 +85,7 @@ import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.SysUiStatsLog; import com.android.systemui.util.DismissCircleView; import com.android.systemui.util.FloatingContentCoordinator; +import com.android.systemui.util.RelativeTouchListener; import com.android.systemui.util.animation.PhysicsAnimator; import com.android.systemui.util.magnetictarget.MagnetizedObject; @@ -239,7 +242,6 @@ public class BubbleStackView extends FrameLayout { mExpandedAnimationController.dump(fd, pw, args); } - private BubbleTouchHandler mTouchHandler; private BubbleController.BubbleExpandListener mExpandListener; private SysUiState mSysUiState; @@ -296,7 +298,7 @@ public class BubbleStackView extends FrameLayout { @Override public void setValue(Object o, float v) { - onFlyoutDragged(v); + setFlyoutStateForDragLength(v); } }; @@ -336,13 +338,6 @@ public class BubbleStackView extends FrameLayout { */ private MagnetizedObject mMagnetizedObject; - /** - * The action to run when the magnetized object is released in the dismiss target. - * - * This will actually perform the dismissal of either the stack or an individual bubble. - */ - private Runnable mReleasedInDismissTargetAction; - /** * The MagneticTarget instance for our circular dismiss view. This is added to the * MagnetizedObject instances for the stack and any dragged-out bubbles. @@ -377,7 +372,7 @@ public class BubbleStackView extends FrameLayout { public void onReleasedInTarget(@NonNull MagnetizedObject.MagneticTarget target) { mExpandedAnimationController.dismissDraggedOutBubble( mExpandedAnimationController.getDraggedOutBubble(), - mReleasedInDismissTargetAction); + BubbleStackView.this::dismissMagnetizedObject); hideDismissTarget(); } }; @@ -410,7 +405,7 @@ public class BubbleStackView extends FrameLayout { mStackAnimationController.implodeStack( () -> { resetDesaturationAndDarken(); - mReleasedInDismissTargetAction.run(); + dismissMagnetizedObject(); } ); @@ -418,6 +413,197 @@ public class BubbleStackView extends FrameLayout { } }; + /** + * Click listener set on each bubble view. When collapsed, clicking a bubble expands the stack. + * When expanded, clicking a bubble either expands that bubble, or collapses the stack. + */ + private OnClickListener mBubbleClickListener = new OnClickListener() { + @Override + public void onClick(View view) { + final Bubble clickedBubble = mBubbleData.getBubbleWithView(view); + + // If the bubble has since left us, ignore the click. + if (clickedBubble == null) { + return; + } + + final boolean clickedBubbleIsCurrentlyExpandedBubble = + clickedBubble.getKey().equals(mExpandedBubble.getKey()); + + if (isExpanded() && !clickedBubbleIsCurrentlyExpandedBubble) { + if (clickedBubble != mBubbleData.getSelectedBubble()) { + // Select the clicked bubble. + mBubbleData.setSelectedBubble(clickedBubble); + } else { + // If the clicked bubble is the selected bubble (but not the expanded bubble), + // that means overflow was previously expanded. Set the selected bubble + // internally without going through BubbleData (which would ignore it since it's + // already selected). + setSelectedBubble(clickedBubble); + + } + } else { + // Otherwise, we either tapped the stack (which means we're collapsed + // and should expand) or the currently selected bubble (we're expanded + // and should collapse). + if (!maybeShowStackUserEducation()) { + mBubbleData.setExpanded(!mBubbleData.isExpanded()); + } + } + } + }; + + /** + * Touch listener set on each bubble view. This enables dragging and dismissing the stack (when + * collapsed), or individual bubbles (when expanded). + */ + private RelativeTouchListener mBubbleTouchListener = new RelativeTouchListener() { + + @Override + public boolean onDown(@NonNull View v, @NonNull MotionEvent ev) { + // If we're expanding or collapsing, consume but ignore all touch events. + if (mIsExpansionAnimating) { + return true; + } + + if (mBubbleData.isExpanded()) { + maybeShowManageEducation(false /* show */); + + // If we're expanded, tell the animation controller to prepare to drag this bubble, + // dispatching to the individual bubble magnet listener. + mExpandedAnimationController.prepareForBubbleDrag( + v /* bubble */, + mMagneticTarget, + mIndividualBubbleMagnetListener); + + // Save the magnetized individual bubble so we can dispatch touch events to it. + mMagnetizedObject = mExpandedAnimationController.getMagnetizedBubbleDraggingOut(); + } else { + // If we're collapsed, prepare to drag the stack. Cancel active animations, set the + // animation controller, and hide the flyout. + mStackAnimationController.cancelStackPositionAnimations(); + mBubbleContainer.setActiveController(mStackAnimationController); + hideFlyoutImmediate(); + + // Also, save the magnetized stack so we can dispatch touch events to it. + mMagnetizedObject = mStackAnimationController.getMagnetizedStack(mMagneticTarget); + mMagnetizedObject.setMagnetListener(mStackMagnetListener); + } + + passEventToMagnetizedObject(ev); + + // Bubbles are always interested in all touch events! + return true; + } + + @Override + public void onMove(@NonNull View v, @NonNull MotionEvent ev, float viewInitialX, + float viewInitialY, float dx, float dy) { + // If we're expanding or collapsing, ignore all touch events. + if (mIsExpansionAnimating) { + return; + } + + // Show the dismiss target, if we haven't already. + springInDismissTargetMaybe(); + + // First, see if the magnetized object consumes the event - if so, we shouldn't move the + // bubble since it's stuck to the target. + if (!passEventToMagnetizedObject(ev)) { + if (mBubbleData.isExpanded()) { + mExpandedAnimationController.dragBubbleOut( + v, viewInitialX + dx, viewInitialY + dy); + } else { + hideStackUserEducation(false /* fromExpansion */); + mStackAnimationController.moveStackFromTouch( + viewInitialX + dx, viewInitialY + dy); + } + } + } + + @Override + public void onUp(@NonNull View v, @NonNull MotionEvent ev, float viewInitialX, + float viewInitialY, float dx, float dy, float velX, float velY) { + // If we're expanding or collapsing, ignore all touch events. + if (mIsExpansionAnimating) { + return; + } + + // First, see if the magnetized object consumes the event - if so, the bubble was + // released in the target or flung out of it, and we should ignore the event. + if (!passEventToMagnetizedObject(ev)) { + if (mBubbleData.isExpanded()) { + mExpandedAnimationController.snapBubbleBack(v, velX, velY); + } else { + // Fling the stack to the edge, and save whether or not it's going to end up on + // the left side of the screen. + mStackOnLeftOrWillBe = + mStackAnimationController.flingStackThenSpringToEdge( + viewInitialX + dx, velX, velY) <= 0; + + updateBubbleZOrdersAndDotPosition(true /* animate */); + + logBubbleEvent(null /* no bubble associated with bubble stack move */, + SysUiStatsLog.BUBBLE_UICHANGED__ACTION__STACK_MOVED); + } + + hideDismissTarget(); + } + } + }; + + /** Click listener set on the flyout, which expands the stack when the flyout is tapped. */ + private OnClickListener mFlyoutClickListener = new OnClickListener() { + @Override + public void onClick(View view) { + if (maybeShowStackUserEducation()) { + // If we're showing user education, don't open the bubble show the education first + mBubbleToExpandAfterFlyoutCollapse = null; + } else { + mBubbleToExpandAfterFlyoutCollapse = mBubbleData.getSelectedBubble(); + } + + mFlyout.removeCallbacks(mHideFlyout); + mHideFlyout.run(); + } + }; + + /** Touch listener for the flyout. This enables the drag-to-dismiss gesture on the flyout. */ + private RelativeTouchListener mFlyoutTouchListener = new RelativeTouchListener() { + + @Override + public boolean onDown(@NonNull View v, @NonNull MotionEvent ev) { + mFlyout.removeCallbacks(mHideFlyout); + return true; + } + + @Override + public void onMove(@NonNull View v, @NonNull MotionEvent ev, float viewInitialX, + float viewInitialY, float dx, float dy) { + setFlyoutStateForDragLength(dx); + } + + @Override + public void onUp(@NonNull View v, @NonNull MotionEvent ev, float viewInitialX, + float viewInitialY, float dx, float dy, float velX, float velY) { + final boolean onLeft = mStackAnimationController.isStackOnLeftSide(); + final boolean metRequiredVelocity = + onLeft ? velX < -FLYOUT_DISMISS_VELOCITY : velX > FLYOUT_DISMISS_VELOCITY; + final boolean metRequiredDeltaX = + onLeft + ? dx < -mFlyout.getWidth() * FLYOUT_DRAG_PERCENT_DISMISS + : dx > mFlyout.getWidth() * FLYOUT_DRAG_PERCENT_DISMISS; + final boolean isCancelFling = onLeft ? velX > 0 : velX < 0; + final boolean shouldDismiss = metRequiredVelocity + || (metRequiredDeltaX && !isCancelFling); + + mFlyout.removeCallbacks(mHideFlyout); + animateFlyoutCollapsed(shouldDismiss, velX); + + maybeShowStackUserEducation(); + } + }; + private ViewGroup mDismissTargetContainer; private PhysicsAnimator mDismissTargetAnimator; private PhysicsAnimator.SpringConfig mDismissTargetSpring = new PhysicsAnimator.SpringConfig( @@ -436,6 +622,7 @@ public class BubbleStackView extends FrameLayout { private BubbleManageEducationView mManageEducationView; private boolean mAnimatingManageEducationAway; + @SuppressLint("ClickableViewAccessibility") public BubbleStackView(Context context, BubbleData data, @Nullable SurfaceSynchronizer synchronizer, FloatingContentCoordinator floatingContentCoordinator, @@ -444,8 +631,6 @@ public class BubbleStackView extends FrameLayout { mBubbleData = data; mInflater = LayoutInflater.from(context); - mTouchHandler = new BubbleTouchHandler(this, data, context); - setOnTouchListener(mTouchHandler); mSysUiState = sysUiState; @@ -641,6 +826,18 @@ public class BubbleStackView extends FrameLayout { mDesaturateAndDarkenPaint.setColorFilter(new ColorMatrixColorFilter(animatedMatrix)); mDesaturateAndDarkenTargetView.setLayerPaint(mDesaturateAndDarkenPaint); }); + + // If the stack itself is touched, it means none of its touchable views (bubbles, flyouts, + // ActivityViews, etc.) were touched. Collapse the stack if it's expanded. + setOnTouchListener((view, ev) -> { + if (ev.getAction() == MotionEvent.ACTION_DOWN) { + if (mBubbleData.isExpanded()) { + mBubbleData.setExpanded(false); + } + } + + return false; + }); } private void setUpUserEducation() { @@ -690,6 +887,7 @@ public class BubbleStackView extends FrameLayout { } } + @SuppressLint("ClickableViewAccessibility") private void setUpFlyout() { if (mFlyout != null) { removeView(mFlyout); @@ -699,6 +897,8 @@ public class BubbleStackView extends FrameLayout { mFlyout.animate() .setDuration(FLYOUT_ALPHA_ANIMATION_DURATION) .setInterpolator(new AccelerateDecelerateInterpolator()); + mFlyout.setOnClickListener(mFlyoutClickListener); + mFlyout.setOnTouchListener(mFlyoutTouchListener); addView(mFlyout, new FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)); } @@ -718,6 +918,7 @@ public class BubbleStackView extends FrameLayout { mBubbleContainer.addView(mBubbleOverflow.getBtn(), overflowBtnIndex, new FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)); + mBubbleOverflow.getBtn().setOnClickListener(v -> setSelectedBubble(mBubbleOverflow)); } /** * Handle theme changes. @@ -920,6 +1121,7 @@ public class BubbleStackView extends FrameLayout { } // via BubbleData.Listener + @SuppressLint("ClickableViewAccessibility") void addBubble(Bubble bubble) { if (DEBUG_BUBBLE_STACK_VIEW) { Log.d(TAG, "addBubble: " + bubble); @@ -944,6 +1146,9 @@ public class BubbleStackView extends FrameLayout { bubble.getIconView().setDotPositionOnLeft( !mStackOnLeftOrWillBe /* onLeft */, false /* animate */); + bubble.getIconView().setOnClickListener(mBubbleClickListener); + bubble.getIconView().setOnTouchListener(mBubbleTouchListener); + mBubbleContainer.addView(bubble.getIconView(), 0, new FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)); ViewClippingUtil.setClippingDeactivated(bubble.getIconView(), true, mClippingParameters); @@ -1009,10 +1214,6 @@ public class BubbleStackView extends FrameLayout { updatePointerPosition(); } - void showOverflow() { - setSelectedBubble(mBubbleOverflow); - } - /** * Changes the currently selected bubble. If the stack is already expanded, the newly selected * bubble will be shown immediately. This does not change the expanded state or change the @@ -1177,14 +1378,6 @@ public class BubbleStackView extends FrameLayout { } } - /* - * Sets the action to run to dismiss the currently dragging object (either the stack or an - * individual bubble). - */ - public void setReleasedInDismissTargetAction(Runnable action) { - mReleasedInDismissTargetAction = action; - } - /** * Dismiss the stack of bubbles. * @@ -1200,54 +1393,6 @@ public class BubbleStackView extends FrameLayout { SysUiStatsLog.BUBBLE_UICHANGED__ACTION__STACK_DISMISSED); } - /** - * @return the view the touch event is on - */ - @Nullable - public View getTargetView(MotionEvent event) { - float x = event.getRawX(); - float y = event.getRawY(); - if (mIsExpanded) { - if (isIntersecting(mBubbleContainer, x, y)) { - if (BubbleExperimentConfig.allowBubbleOverflow(mContext) - && isIntersecting(mBubbleOverflow.getBtn(), x, y)) { - return mBubbleOverflow.getBtn(); - } - // Could be tapping or dragging a bubble while expanded - for (int i = 0; i < getBubbleCount(); i++) { - BadgedImageView view = (BadgedImageView) mBubbleContainer.getChildAt(i); - if (isIntersecting(view, x, y)) { - return view; - } - } - } - BubbleExpandedView bev = (BubbleExpandedView) mExpandedViewContainer.getChildAt(0); - if (bev.intersectingTouchableContent((int) x, (int) y)) { - return bev; - } - // Outside of the parts we care about. - return null; - } else if (mFlyout.getVisibility() == VISIBLE && isIntersecting(mFlyout, x, y)) { - return mFlyout; - } else if (mUserEducationView != null && mUserEducationView.getVisibility() == VISIBLE) { - View bubbleChild = mBubbleContainer.getChildAt(0); - if (isIntersecting(bubbleChild, x, y)) { - return this; - } else if (isIntersecting(mUserEducationView, x, y)) { - return mUserEducationView; - } else { - return null; - } - } - - // If it wasn't an individual bubble in the expanded state, or the flyout, it's the stack. - return this; - } - - View getFlyoutView() { - return mFlyout; - } - /** * @deprecated use {@link #setExpanded(boolean)} and * {@link BubbleData#setSelectedBubble(Bubble)} @@ -1385,124 +1530,70 @@ public class BubbleStackView extends FrameLayout { } } - /** Called when the collapsed stack is tapped on. */ - void onStackTapped() { - if (!maybeShowStackUserEducation()) { - mBubbleData.setExpanded(true); - } + /** + * This method is called by {@link android.app.ActivityView} because the BubbleStackView has a + * higher Z-index than the ActivityView (so that dragged-out bubbles are visible over the AV). + * ActivityView is asking BubbleStackView to subtract the stack's bounds from the provided + * touchable region, so that the ActivityView doesn't consume events meant for the stack. Due to + * the special nature of ActivityView, it does not respect the standard + * {@link #dispatchTouchEvent} and {@link #onInterceptTouchEvent} methods typically used for + * this purpose. + * + * BubbleStackView is MATCH_PARENT, so that bubbles can be positioned via their translation + * properties for performance reasons. This means that the default implementation of this method + * subtracts the entirety of the screen from the ActivityView's touchable region, resulting in + * it not receiving any touch events. This was previously addressed by returning false in the + * stack's {@link View#canReceivePointerEvents()} method, but this precluded the use of any + * touch handlers in the stack or its child views. + * + * To support touch handlers, we're overriding this method to leave the ActivityView's touchable + * region alone. The only touchable part of the stack that can ever overlap the AV is a + * dragged-out bubble that is animating back into the row of bubbles. It's not worth continually + * updating the touchable region to allow users to grab a bubble while it completes its ~50ms + * animation back to the bubble row. + * + * NOTE: Any future additions to the stack that obscure the ActivityView region will need their + * bounds subtracted here in order to receive touch events. + */ + @Override + public void subtractObscuredTouchableRegion(Region touchableRegion, View view) { + } - /** Called when a drag operation on an individual bubble has started. */ - public void onBubbleDragStart(View bubble) { - if (DEBUG_BUBBLE_STACK_VIEW) { - Log.d(TAG, "onBubbleDragStart: bubble=" + ((BadgedImageView) bubble).getKey()); - } - - if (mBubbleOverflow != null && bubble.equals(mBubbleOverflow.getIconView())) { - return; - } - - mExpandedAnimationController.prepareForBubbleDrag(bubble, mMagneticTarget); - - // We're dragging an individual bubble, so set the magnetized object to the magnetized - // bubble. - mMagnetizedObject = mExpandedAnimationController.getMagnetizedBubbleDraggingOut(); - mMagnetizedObject.setMagnetListener(mIndividualBubbleMagnetListener); - - maybeShowManageEducation(false); + /** + * If you're here because you're not receiving touch events on a view that is a descendant of + * BubbleStackView, and you think BSV is intercepting them - it's not! You need to subtract the + * bounds of the view in question in {@link #subtractObscuredTouchableRegion}. The ActivityView + * consumes all touch events within its bounds, even for views like the BubbleStackView that are + * above it. It ignores typical view touch handling methods like this one and + * dispatchTouchEvent. + */ + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + return super.onInterceptTouchEvent(ev); } - /** Called with the coordinates to which an individual bubble has been dragged. */ - public void onBubbleDragged(View bubble, float x, float y) { - if (!mIsExpanded || mIsExpansionAnimating - || (mBubbleOverflow != null && bubble.equals(mBubbleOverflow.getIconView()))) { - return; + @Override + public boolean dispatchTouchEvent(MotionEvent ev) { + boolean dispatched = super.dispatchTouchEvent(ev); + + // If a new bubble arrives while the collapsed stack is being dragged, it will be positioned + // at the front of the stack (under the touch position). Subsequent ACTION_MOVE events will + // then be passed to the new bubble, which will not consume them since it hasn't received an + // ACTION_DOWN yet. Work around this by passing MotionEvents directly to the touch handler + // until the current gesture ends with an ACTION_UP event. + if (!dispatched && !mIsExpanded && mIsGestureInProgress) { + dispatched = mBubbleTouchListener.onTouch(this /* view */, ev); } - mExpandedAnimationController.dragBubbleOut(bubble, x, y); - springInDismissTarget(); + mIsGestureInProgress = + ev.getAction() != MotionEvent.ACTION_UP + && ev.getAction() != MotionEvent.ACTION_CANCEL; + + return dispatched; } - /** Called when a drag operation on an individual bubble has finished. */ - public void onBubbleDragFinish( - View bubble, float x, float y, float velX, float velY) { - if (DEBUG_BUBBLE_STACK_VIEW) { - Log.d(TAG, "onBubbleDragFinish: bubble=" + bubble); - } - - if (!mIsExpanded || mIsExpansionAnimating - || (mBubbleOverflow != null && bubble.equals(mBubbleOverflow.getIconView()))) { - return; - } - - mExpandedAnimationController.snapBubbleBack(bubble, velX, velY); - hideDismissTarget(); - } - - /** Expands the clicked bubble. */ - public void expandBubble(Bubble bubble) { - if (bubble != null && bubble.equals(mBubbleData.getSelectedBubble())) { - // If the bubble we're supposed to expand is the selected bubble, that means the - // overflow bubble is currently expanded. Don't tell BubbleData to set this bubble as - // selected, since it already is. Just call the stack's setSelectedBubble to expand it. - setSelectedBubble(bubble); - } else { - mBubbleData.setSelectedBubble(bubble); - } - } - - void onDragStart() { - if (DEBUG_BUBBLE_STACK_VIEW) { - Log.d(TAG, "onDragStart()"); - } - if (mIsExpanded || mIsExpansionAnimating) { - if (DEBUG_BUBBLE_STACK_VIEW) { - Log.d(TAG, "mIsExpanded or mIsExpansionAnimating"); - } - return; - } - mStackAnimationController.cancelStackPositionAnimations(); - mBubbleContainer.setActiveController(mStackAnimationController); - hideFlyoutImmediate(); - - // Since we're dragging the stack, set the magnetized object to the magnetized stack. - mMagnetizedObject = mStackAnimationController.getMagnetizedStack(mMagneticTarget); - mMagnetizedObject.setMagnetListener(mStackMagnetListener); - } - - void onDragged(float x, float y) { - if (mIsExpanded || mIsExpansionAnimating) { - return; - } - - hideStackUserEducation(false /* fromExpansion */); - springInDismissTarget(); - mStackAnimationController.moveStackFromTouch(x, y); - } - - void onDragFinish(float x, float y, float velX, float velY) { - if (DEBUG_BUBBLE_STACK_VIEW) { - Log.d(TAG, "onDragFinish"); - } - - if (mIsExpanded || mIsExpansionAnimating) { - return; - } - - final float newStackX = mStackAnimationController.flingStackThenSpringToEdge(x, velX, velY); - logBubbleEvent(null /* no bubble associated with bubble stack move */, - SysUiStatsLog.BUBBLE_UICHANGED__ACTION__STACK_MOVED); - - mStackOnLeftOrWillBe = newStackX <= 0; - updateBubbleZOrdersAndDotPosition(true /* animate */); - hideDismissTarget(); - } - - void onFlyoutDragStart() { - mFlyout.removeCallbacks(mHideFlyout); - } - - void onFlyoutDragged(float deltaX) { + void setFlyoutStateForDragLength(float deltaX) { // This shouldn't happen, but if it does, just wait until the flyout lays out. This method // is continually called. if (mFlyout.getWidth() <= 0) { @@ -1538,61 +1629,29 @@ public class BubbleStackView extends FrameLayout { mFlyout.setTranslationX(mFlyout.getRestingTranslationX() + overscrollTranslation); } - void onFlyoutTapped() { - if (maybeShowStackUserEducation()) { - // If we're showing user education, don't open the bubble show the education first - mBubbleToExpandAfterFlyoutCollapse = null; - } else { - mBubbleToExpandAfterFlyoutCollapse = mBubbleData.getSelectedBubble(); - } - - mFlyout.removeCallbacks(mHideFlyout); - mHideFlyout.run(); - } - - /** - * Called when the flyout drag has finished, and returns true if the gesture successfully - * dismissed the flyout. - */ - void onFlyoutDragFinished(float deltaX, float velX) { - final boolean onLeft = mStackAnimationController.isStackOnLeftSide(); - final boolean metRequiredVelocity = - onLeft ? velX < -FLYOUT_DISMISS_VELOCITY : velX > FLYOUT_DISMISS_VELOCITY; - final boolean metRequiredDeltaX = - onLeft - ? deltaX < -mFlyout.getWidth() * FLYOUT_DRAG_PERCENT_DISMISS - : deltaX > mFlyout.getWidth() * FLYOUT_DRAG_PERCENT_DISMISS; - final boolean isCancelFling = onLeft ? velX > 0 : velX < 0; - final boolean shouldDismiss = metRequiredVelocity || (metRequiredDeltaX && !isCancelFling); - - mFlyout.removeCallbacks(mHideFlyout); - animateFlyoutCollapsed(shouldDismiss, velX); - - maybeShowStackUserEducation(); - } - - /** - * Called when the first touch event of a gesture (stack drag, bubble drag, flyout drag, etc.) - * is received. - */ - void onGestureStart() { - mIsGestureInProgress = true; - } - - /** Called when a gesture is completed or cancelled. */ - void onGestureFinished() { - mIsGestureInProgress = false; - - if (mIsExpanded) { - mExpandedAnimationController.onGestureFinished(); - } - } - /** Passes the MotionEvent to the magnetized object and returns true if it was consumed. */ - boolean passEventToMagnetizedObject(MotionEvent event) { + private boolean passEventToMagnetizedObject(MotionEvent event) { return mMagnetizedObject != null && mMagnetizedObject.maybeConsumeMotionEvent(event); } + /** + * Dismisses the magnetized object - either an individual bubble, if we're expanded, or the + * stack, if we're collapsed. + */ + private void dismissMagnetizedObject() { + if (mIsExpanded) { + final View draggedOutBubbleView = (View) mMagnetizedObject.getUnderlyingObject(); + final Bubble draggedOutBubble = mBubbleData.getBubbleWithView(draggedOutBubbleView); + + if (mBubbleData.hasBubbleWithKey(draggedOutBubble.getKey())) { + mBubbleData.notificationEntryRemoved( + draggedOutBubble.getEntry(), BubbleController.DISMISS_USER_GESTURE); + } + } else { + mBubbleData.dismissAll(BubbleController.DISMISS_USER_GESTURE); + } + } + /** Prepares and starts the desaturate/darken animation on the bubble stack. */ private void animateDesaturateAndDarken(View targetView, boolean desaturateAndDarken) { mDesaturateAndDarkenTargetView = targetView; @@ -1624,7 +1683,7 @@ public class BubbleStackView extends FrameLayout { } /** Animates in the dismiss target. */ - private void springInDismissTarget() { + private void springInDismissTargetMaybe() { if (mShowingDismiss) { return; } @@ -1827,13 +1886,6 @@ public class BubbleStackView extends FrameLayout { return 0; } - private boolean isIntersecting(View view, float x, float y) { - mTempLoc = view.getLocationOnScreen(); - mTempRect.set(mTempLoc[0], mTempLoc[1], mTempLoc[0] + view.getWidth(), - mTempLoc[1] + view.getHeight()); - return mTempRect.contains(x, y); - } - private void requestUpdate() { if (mViewUpdatedRequested || mIsExpansionAnimating) { return; diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTouchHandler.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTouchHandler.java deleted file mode 100644 index 132c45fab3d2f..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTouchHandler.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.bubbles; - -import android.content.Context; -import android.graphics.PointF; -import android.view.MotionEvent; -import android.view.VelocityTracker; -import android.view.View; -import android.view.ViewConfiguration; - -import com.android.systemui.Dependency; - -/** - * Handles interpreting touches on a {@link BubbleStackView}. This includes expanding, collapsing, - * dismissing, and flings. - */ -class BubbleTouchHandler implements View.OnTouchListener { - - private final PointF mTouchDown = new PointF(); - private final PointF mViewPositionOnTouchDown = new PointF(); - private final BubbleStackView mStack; - private final BubbleData mBubbleData; - - private BubbleController mController = Dependency.get(BubbleController.class); - - private boolean mMovedEnough; - private int mTouchSlopSquared; - private VelocityTracker mVelocityTracker; - - /** View that was initially touched, when we received the first ACTION_DOWN event. */ - private View mTouchedView; - - BubbleTouchHandler(BubbleStackView stackView, - BubbleData bubbleData, Context context) { - final int touchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); - mTouchSlopSquared = touchSlop * touchSlop; - mBubbleData = bubbleData; - mStack = stackView; - } - - @Override - public boolean onTouch(View v, MotionEvent event) { - final int action = event.getActionMasked(); - - // If we aren't currently in the process of touching a view, figure out what we're touching. - // It'll be the stack, an individual bubble, or nothing. - if (mTouchedView == null) { - mTouchedView = mStack.getTargetView(event); - } - - // If this is an ACTION_OUTSIDE event, or the stack reported that we aren't touching - // anything, collapse the stack. - if (action == MotionEvent.ACTION_OUTSIDE || mTouchedView == null) { - mBubbleData.setExpanded(false); - mStack.hideStackUserEducation(false /* fromExpansion */); - resetForNextGesture(); - return false; - } - - if (!(mTouchedView instanceof BadgedImageView) - && !(mTouchedView instanceof BubbleStackView) - && !(mTouchedView instanceof BubbleFlyoutView)) { - - // Not touching anything touchable, but we shouldn't collapse (e.g. touching edge - // of expanded view). - mStack.maybeShowManageEducation(false); - resetForNextGesture(); - return false; - } - - final boolean isStack = mStack.equals(mTouchedView); - final boolean isFlyout = mStack.getFlyoutView().equals(mTouchedView); - final float rawX = event.getRawX(); - final float rawY = event.getRawY(); - - // The coordinates of the touch event, in terms of the touched view's position. - final float viewX = mViewPositionOnTouchDown.x + rawX - mTouchDown.x; - final float viewY = mViewPositionOnTouchDown.y + rawY - mTouchDown.y; - switch (action) { - case MotionEvent.ACTION_DOWN: - trackMovement(event); - - mTouchDown.set(rawX, rawY); - mStack.onGestureStart(); - - if (isStack) { - mViewPositionOnTouchDown.set(mStack.getStackPosition()); - - // Dismiss the entire stack if it's released in the dismiss target. - mStack.setReleasedInDismissTargetAction( - () -> mController.dismissStack(BubbleController.DISMISS_USER_GESTURE)); - mStack.onDragStart(); - mStack.passEventToMagnetizedObject(event); - } else if (isFlyout) { - mStack.onFlyoutDragStart(); - } else { - mViewPositionOnTouchDown.set( - mTouchedView.getTranslationX(), mTouchedView.getTranslationY()); - - // Dismiss only the dragged-out bubble if it's released in the target. - final String individualBubbleKey = ((BadgedImageView) mTouchedView).getKey(); - mStack.setReleasedInDismissTargetAction(() -> { - final Bubble bubble = - mBubbleData.getBubbleWithKey(individualBubbleKey); - // bubble can be null if the user is in the middle of - // dismissing the bubble, but the app also sent a cancel - if (bubble != null) { - mController.removeBubble(bubble.getEntry(), - BubbleController.DISMISS_USER_GESTURE); - } - }); - - mStack.onBubbleDragStart(mTouchedView); - mStack.passEventToMagnetizedObject(event); - } - - break; - case MotionEvent.ACTION_MOVE: - trackMovement(event); - final float deltaX = rawX - mTouchDown.x; - final float deltaY = rawY - mTouchDown.y; - - if ((deltaX * deltaX) + (deltaY * deltaY) > mTouchSlopSquared && !mMovedEnough) { - mMovedEnough = true; - } - - if (mMovedEnough) { - if (isFlyout) { - mStack.onFlyoutDragged(deltaX); - } else if (!mStack.passEventToMagnetizedObject(event)) { - // If the magnetic target doesn't consume the event, drag the stack or - // bubble. - if (isStack) { - mStack.onDragged(viewX, viewY); - } else { - mStack.onBubbleDragged(mTouchedView, viewX, viewY); - } - } - } - break; - - case MotionEvent.ACTION_CANCEL: - resetForNextGesture(); - break; - - case MotionEvent.ACTION_UP: - trackMovement(event); - mVelocityTracker.computeCurrentVelocity(/* maxVelocity */ 1000); - final float velX = mVelocityTracker.getXVelocity(); - final float velY = mVelocityTracker.getYVelocity(); - - if (isFlyout && mMovedEnough) { - mStack.onFlyoutDragFinished(rawX - mTouchDown.x /* deltaX */, velX); - } else if (isFlyout) { - if (!mBubbleData.isExpanded() && !mMovedEnough) { - mStack.onFlyoutTapped(); - } - } else if (mMovedEnough) { - if (!mStack.passEventToMagnetizedObject(event)) { - // If the magnetic target didn't consume the event, tell the stack to finish - // the drag. - if (isStack) { - mStack.onDragFinish(viewX, viewY, velX, velY); - } else { - mStack.onBubbleDragFinish(mTouchedView, viewX, viewY, velX, velY); - } - } - } else if (mTouchedView == mStack.getExpandedBubbleView()) { - mBubbleData.setExpanded(false); - } else if (isStack) { - mStack.onStackTapped(); - } else { - final String key = ((BadgedImageView) mTouchedView).getKey(); - if (key == BubbleOverflow.KEY) { - mStack.showOverflow(); - } else { - mStack.expandBubble(mBubbleData.getBubbleWithKey(key)); - } - } - resetForNextGesture(); - break; - } - - return true; - } - - /** Clears all touch-related state. */ - private void resetForNextGesture() { - if (mVelocityTracker != null) { - mVelocityTracker.recycle(); - mVelocityTracker = null; - } - - mTouchedView = null; - mMovedEnough = false; - - mStack.onGestureFinished(); - } - - private void trackMovement(MotionEvent event) { - if (mVelocityTracker == null) { - mVelocityTracker = VelocityTracker.obtain(); - } - mVelocityTracker.addMovement(event); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java index a0b49384d49fa..d974adc34ee03 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java @@ -252,8 +252,14 @@ public class ExpandedAnimationController mSpringToTouchOnNextMotionEvent = true; } - /** Prepares the given bubble to be dragged out. */ - public void prepareForBubbleDrag(View bubble, MagnetizedObject.MagneticTarget target) { + /** + * Prepares the given bubble view to be dragged out, using the provided magnetic target and + * listener. + */ + public void prepareForBubbleDrag( + View bubble, + MagnetizedObject.MagneticTarget target, + MagnetizedObject.MagnetListener listener) { mLayout.cancelAnimationsOnView(bubble); bubble.setTranslationZ(Short.MAX_VALUE); @@ -277,6 +283,7 @@ public class ExpandedAnimationController } }; mMagnetizedBubbleDraggingOut.addTarget(target); + mMagnetizedBubbleDraggingOut.setMagnetListener(listener); mMagnetizedBubbleDraggingOut.setHapticsEnabled(true); mMagnetizedBubbleDraggingOut.setFlingToTargetMinVelocity(FLING_TO_DISMISS_MIN_VELOCITY); } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java index c292769f10660..b1bbafc1ed8fe 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java @@ -1117,9 +1117,4 @@ public class PhysicsAnimationLayout extends FrameLayout { mAssociatedController = controller; } } - - @Override - protected boolean canReceivePointerEvents() { - return false; - } } diff --git a/packages/SystemUI/src/com/android/systemui/util/RelativeTouchListener.kt b/packages/SystemUI/src/com/android/systemui/util/RelativeTouchListener.kt new file mode 100644 index 0000000000000..d65b285adb0cb --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/util/RelativeTouchListener.kt @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.util + +import android.graphics.PointF +import android.os.Handler +import android.view.MotionEvent +import android.view.VelocityTracker +import android.view.View +import android.view.ViewConfiguration +import kotlin.math.hypot + +/** + * Listener which receives [onDown], [onMove], and [onUp] events, with relevant information about + * the coordinates of the touch and the view relative to the initial ACTION_DOWN event and the + * view's initial position. + */ +abstract class RelativeTouchListener : View.OnTouchListener { + + /** + * Called when an ACTION_DOWN event is received for the given view. + * + * @return False if the object is not interested in MotionEvents at this time, or true if we + * should consume this event and subsequent events, and begin calling [onMove]. + */ + abstract fun onDown(v: View, ev: MotionEvent): Boolean + + /** + * Called when an ACTION_MOVE event is received for the given view. This signals that the view + * is being dragged. + * + * @param viewInitialX The view's translationX value when this touch gesture started. + * @param viewInitialY The view's translationY value when this touch gesture started. + * @param dx Horizontal distance covered since the initial ACTION_DOWN event, in pixels. + * @param dy Vertical distance covered since the initial ACTION_DOWN event, in pixels. + */ + abstract fun onMove( + v: View, + ev: MotionEvent, + viewInitialX: Float, + viewInitialY: Float, + dx: Float, + dy: Float + ) + + /** + * Called when an ACTION_UP event is received for the given view. This signals that a drag or + * fling gesture has completed. + * + * @param viewInitialX The view's translationX value when this touch gesture started. + * @param viewInitialY The view's translationY value when this touch gesture started. + * @param dx Horizontal distance covered, in pixels. + * @param dy Vertical distance covered, in pixels. + * @param velX The final horizontal velocity of the gesture, in pixels/second. + * @param velY The final vertical velocity of the gesture, in pixels/second. + */ + abstract fun onUp( + v: View, + ev: MotionEvent, + viewInitialX: Float, + viewInitialY: Float, + dx: Float, + dy: Float, + velX: Float, + velY: Float + ) + + /** The raw coordinates of the last ACTION_DOWN event. */ + private val touchDown = PointF() + + /** The coordinates of the view, at the time of the last ACTION_DOWN event. */ + private val viewPositionOnTouchDown = PointF() + + private val velocityTracker = VelocityTracker.obtain() + + private var touchSlop: Int = -1 + private var movedEnough = false + + private val handler = Handler() + private var performedLongClick = false + + @Suppress("UNCHECKED_CAST") + override fun onTouch(v: View, ev: MotionEvent): Boolean { + addMovement(ev) + + val dx = ev.rawX - touchDown.x + val dy = ev.rawY - touchDown.y + + when (ev.action) { + MotionEvent.ACTION_DOWN -> { + if (!onDown(v, ev)) { + return false + } + + // Grab the touch slop, it might have changed if the config changed since the + // last gesture. + touchSlop = ViewConfiguration.get(v.context).scaledTouchSlop + + touchDown.set(ev.rawX, ev.rawY) + viewPositionOnTouchDown.set(v.translationX, v.translationY) + + performedLongClick = false + handler.postDelayed({ + performedLongClick = v.performLongClick() + }, ViewConfiguration.getLongPressTimeout().toLong()) + } + + MotionEvent.ACTION_MOVE -> { + if (!movedEnough && hypot(dx, dy) > touchSlop && !performedLongClick) { + movedEnough = true + handler.removeCallbacksAndMessages(null) + } + + if (movedEnough) { + onMove(v, ev, viewPositionOnTouchDown.x, viewPositionOnTouchDown.y, dx, dy) + } + } + + MotionEvent.ACTION_UP -> { + if (movedEnough) { + velocityTracker.computeCurrentVelocity(1000 /* units */) + onUp(v, ev, viewPositionOnTouchDown.x, viewPositionOnTouchDown.y, dx, dy, + velocityTracker.xVelocity, velocityTracker.yVelocity) + } else if (!performedLongClick) { + v.performClick() + } else { + handler.removeCallbacksAndMessages(null) + } + + velocityTracker.clear() + movedEnough = false + } + } + + return true + } + + /** + * Adds a movement to the velocity tracker using raw screen coordinates. + */ + private fun addMovement(event: MotionEvent) { + val deltaX = event.rawX - event.x + val deltaY = event.rawY - event.y + event.offsetLocation(deltaX, deltaY) + velocityTracker.addMovement(event) + event.offsetLocation(-deltaX, -deltaY) + } +} \ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java index 037f04ec1d7cd..e472de3494664 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java @@ -374,7 +374,7 @@ public class BubbleControllerTest extends SysuiTestCase { assertNotNull(mBubbleData.getBubbleWithKey(mRow2.getEntry().getKey())); assertTrue(mBubbleController.hasBubbles()); - mBubbleController.dismissStack(BubbleController.DISMISS_USER_GESTURE); + mBubbleData.dismissAll(BubbleController.DISMISS_USER_GESTURE); assertFalse(mNotificationShadeWindowController.getBubblesShowing()); verify(mNotificationEntryManager, times(3)).updateNotifications(any()); assertNull(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey())); @@ -399,7 +399,7 @@ public class BubbleControllerTest extends SysuiTestCase { // Expand the stack BubbleStackView stackView = mBubbleController.getStackView(); - mBubbleController.expandStack(); + mBubbleData.setExpanded(true); assertTrue(mBubbleController.isStackExpanded()); verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey()); assertTrue(mNotificationShadeWindowController.getBubbleExpanded()); @@ -436,7 +436,7 @@ public class BubbleControllerTest extends SysuiTestCase { // Expand BubbleStackView stackView = mBubbleController.getStackView(); - mBubbleController.expandStack(); + mBubbleData.setExpanded(true); assertTrue(mBubbleController.isStackExpanded()); verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow2.getEntry().getKey()); @@ -448,7 +448,7 @@ public class BubbleControllerTest extends SysuiTestCase { mRow2.getEntry())); // Switch which bubble is expanded - mBubbleController.selectBubble(mRow.getEntry().getKey()); + mBubbleData.setSelectedBubble(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey())); mBubbleData.setExpanded(true); assertEquals(mRow.getEntry(), mBubbleData.getBubbleWithKey(stackView.getExpandedBubble().getKey()).getEntry()); @@ -482,7 +482,7 @@ public class BubbleControllerTest extends SysuiTestCase { assertTrue(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey()).showDot()); // Expand - mBubbleController.expandStack(); + mBubbleData.setExpanded(true); assertTrue(mBubbleController.isStackExpanded()); verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey()); @@ -510,7 +510,7 @@ public class BubbleControllerTest extends SysuiTestCase { assertTrue(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey()).showDot()); // Expand - mBubbleController.expandStack(); + mBubbleData.setExpanded(true); assertTrue(mBubbleController.isStackExpanded()); verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey()); @@ -544,7 +544,7 @@ public class BubbleControllerTest extends SysuiTestCase { // Expand BubbleStackView stackView = mBubbleController.getStackView(); - mBubbleController.expandStack(); + mBubbleData.setExpanded(true); assertTrue(mSysUiStateBubblesExpanded); @@ -726,7 +726,7 @@ public class BubbleControllerTest extends SysuiTestCase { public void testDeleteIntent_dismissStack() throws PendingIntent.CanceledException { mBubbleController.updateBubble(mRow.getEntry()); mBubbleController.updateBubble(mRow2.getEntry()); - mBubbleController.dismissStack(BubbleController.DISMISS_USER_GESTURE); + mBubbleData.dismissAll(BubbleController.DISMISS_USER_GESTURE); verify(mDeleteIntent, times(2)).send(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java index 545de210d5b50..5f4f2ef04c1de 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java @@ -321,7 +321,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { assertNotNull(mBubbleData.getBubbleWithKey(mRow2.getEntry().getKey())); assertTrue(mBubbleController.hasBubbles()); - mBubbleController.dismissStack(BubbleController.DISMISS_USER_GESTURE); + mBubbleData.dismissAll(BubbleController.DISMISS_USER_GESTURE); assertFalse(mNotificationShadeWindowController.getBubblesShowing()); verify(mNotifCallback, times(3)).invalidateNotifications(anyString()); assertNull(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey())); @@ -344,7 +344,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { // Expand the stack BubbleStackView stackView = mBubbleController.getStackView(); - mBubbleController.expandStack(); + mBubbleData.setExpanded(true); assertTrue(mBubbleController.isStackExpanded()); verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey()); assertTrue(mNotificationShadeWindowController.getBubbleExpanded()); @@ -376,7 +376,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { // Expand BubbleStackView stackView = mBubbleController.getStackView(); - mBubbleController.expandStack(); + mBubbleData.setExpanded(true); assertTrue(mBubbleController.isStackExpanded()); verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow2.getEntry().getKey()); @@ -385,7 +385,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow2.getEntry())); // Switch which bubble is expanded - mBubbleController.selectBubble(mRow.getEntry().getKey()); + mBubbleData.setSelectedBubble(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey())); mBubbleData.setExpanded(true); assertEquals(mRow.getEntry(), mBubbleData.getBubbleWithKey(stackView.getExpandedBubble().getKey()).getEntry()); @@ -416,7 +416,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { assertTrue(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey()).showDot()); // Expand - mBubbleController.expandStack(); + mBubbleData.setExpanded(true); assertTrue(mBubbleController.isStackExpanded()); verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey()); @@ -442,7 +442,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { assertTrue(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey()).showDot()); // Expand - mBubbleController.expandStack(); + mBubbleData.setExpanded(true); assertTrue(mBubbleController.isStackExpanded()); verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey()); @@ -474,7 +474,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { // Expand BubbleStackView stackView = mBubbleController.getStackView(); - mBubbleController.expandStack(); + mBubbleData.setExpanded(true); assertTrue(mBubbleController.isStackExpanded()); verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow2.getEntry().getKey()); @@ -628,7 +628,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { public void testDeleteIntent_dismissStack() throws PendingIntent.CanceledException { mBubbleController.updateBubble(mRow.getEntry()); mBubbleController.updateBubble(mRow2.getEntry()); - mBubbleController.dismissStack(BubbleController.DISMISS_USER_GESTURE); + mBubbleData.dismissAll(BubbleController.DISMISS_USER_GESTURE); verify(mDeleteIntent, times(2)).send(); }