diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java index b96cee6506639..1b62ec4772f35 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java @@ -82,6 +82,8 @@ public class BouncerSwipeTouchHandler implements DreamTouchHandler { private Boolean mCapture; + private boolean mBouncerInitiallyShowing; + private TouchSession mTouchSession; private ValueAnimatorCreator mValueAnimatorCreator; @@ -97,6 +99,7 @@ public class BouncerSwipeTouchHandler implements DreamTouchHandler { // If the user scrolling favors a vertical direction, begin capturing // scrolls. mCapture = Math.abs(distanceY) > Math.abs(distanceX); + mBouncerInitiallyShowing = mCentralSurfaces.isBouncerShowing(); if (mCapture) { // Since the user is dragging the bouncer up, set scrimmed to false. @@ -115,7 +118,7 @@ public class BouncerSwipeTouchHandler implements DreamTouchHandler { // (0). final float screenTravelPercentage = Math.abs((e1.getY() - e2.getY()) / mCentralSurfaces.getDisplayHeight()); - setPanelExpansion(mCentralSurfaces.isBouncerShowing() + setPanelExpansion(mBouncerInitiallyShowing ? screenTravelPercentage : 1 - screenTravelPercentage); return true; } @@ -174,18 +177,18 @@ public class BouncerSwipeTouchHandler implements DreamTouchHandler { mTouchSession = session; mVelocityTracker.clear(); mNotificationShadeWindowController.setForcePluginOpen(true, this); + + session.registerCallback(() -> { + mVelocityTracker.recycle(); + mCapture = null; + mNotificationShadeWindowController.setForcePluginOpen(false, this); + }); + session.registerGestureListener(mOnGestureListener); session.registerInputListener(ev -> onMotionEvent(ev)); } - @Override - public void onSessionEnd(TouchSession session) { - mVelocityTracker.recycle(); - mCapture = null; - mNotificationShadeWindowController.setForcePluginOpen(false, this); - } - private void onMotionEvent(InputEvent event) { if (!(event instanceof MotionEvent)) { Log.e(TAG, "non MotionEvent received:" + event); diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamTouchHandler.java index 20008d5b02c85..8288fcfb54811 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamTouchHandler.java @@ -96,11 +96,4 @@ public interface DreamTouchHandler { * @param session */ void onSessionStart(TouchSession session); - - /** - * Invoked when a session has ended. This will be invoked for every session completion, even - * those that are removed through {@link TouchSession#pop()}. - * @param session - */ - default void onSessionEnd(TouchSession session) { } } diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/HideComplicationTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/HideComplicationTouchHandler.java index d4ba2d82f38a7..4965c9dfd00b0 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/touch/HideComplicationTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/HideComplicationTouchHandler.java @@ -127,11 +127,4 @@ public class HideComplicationTouchHandler implements DreamTouchHandler { } }); } - - @Override - public void onSessionEnd(TouchSession session) { - if (DEBUG) { - Log.d(TAG, "onSessionEnd"); - } - } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java index ce92d5e304559..b08dd57f1c98b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java @@ -31,6 +31,7 @@ import android.graphics.Region; import android.testing.AndroidTestingRunner; import android.util.DisplayMetrics; import android.view.GestureDetector; +import android.view.GestureDetector.OnGestureListener; import android.view.MotionEvent; import android.view.VelocityTracker; @@ -111,6 +112,7 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase { mFlingAnimationUtilsClosing, TOUCH_REGION); + when(mCentralSurfaces.isBouncerShowing()).thenReturn(false); when(mCentralSurfaces.getDisplayHeight()).thenReturn((float) SCREEN_HEIGHT_PX); when(mCentralSurfaces.isBouncerShowing()).thenReturn(false); when(mValueAnimatorCreator.create(anyFloat(), anyFloat())).thenReturn(mValueAnimator); @@ -162,24 +164,58 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase { ArgumentCaptor.forClass(GestureDetector.OnGestureListener.class); verify(mTouchSession).registerGestureListener(gestureListenerCaptor.capture()); - final float scrollAmount = .3f; - final float distanceY = SCREEN_HEIGHT_PX * scrollAmount; + final OnGestureListener gestureListener = gestureListenerCaptor.getValue(); + when(mCentralSurfaces.isBouncerShowing()).thenReturn(false); + verifyScroll(.3f, Direction.UP, true, gestureListener); + + // Ensure that subsequent gestures are treated as expanding even if the bouncer state + // changes. + when(mCentralSurfaces.isBouncerShowing()).thenReturn(true); + verifyScroll(.7f, Direction.UP, true, gestureListener); + } + + /** + * Makes sure collapse amount is proportional to scroll. + */ + @Test + public void testCollapseAmount() { + mTouchHandler.onSessionStart(mTouchSession); + ArgumentCaptor gestureListenerCaptor = + ArgumentCaptor.forClass(GestureDetector.OnGestureListener.class); + verify(mTouchSession).registerGestureListener(gestureListenerCaptor.capture()); + + final OnGestureListener gestureListener = gestureListenerCaptor.getValue(); + when(mCentralSurfaces.isBouncerShowing()).thenReturn(true); + verifyScroll(.3f, Direction.DOWN, false, gestureListener); + + // Ensure that subsequent gestures are treated as collapsing even if the bouncer state + // changes. + when(mCentralSurfaces.isBouncerShowing()).thenReturn(false); + verifyScroll(.7f, Direction.DOWN, false, gestureListener); + } + + private enum Direction { + DOWN, + UP, + } + + private void verifyScroll(float percent, Direction direction, boolean expanding, + android.view.GestureDetector.OnGestureListener gestureListener) { + + final float distanceY = SCREEN_HEIGHT_PX * percent; final MotionEvent event1 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, - 0, SCREEN_HEIGHT_PX, 0); + 0, direction == Direction.UP ? SCREEN_HEIGHT_PX : 0, 0); final MotionEvent event2 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, - 0, SCREEN_HEIGHT_PX - distanceY, 0); + 0, direction == Direction.UP ? SCREEN_HEIGHT_PX - distanceY : distanceY, 0); - assertThat(gestureListenerCaptor.getValue().onScroll(event1, event2, 0, distanceY)) + assertThat(gestureListener.onScroll(event1, event2, 0, distanceY)) .isTrue(); - // Ensure only called once - verify(mStatusBarKeyguardViewManager) - .onPanelExpansionChanged(anyFloat(), anyBoolean(), anyBoolean()); - // Ensure correct expansion passed in. verify(mStatusBarKeyguardViewManager) - .onPanelExpansionChanged(eq(1 - scrollAmount), eq(false), eq(true)); + .onPanelExpansionChanged( + eq(expanding ? 1 - percent : percent), eq(false), eq(true)); } /** diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitorTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitorTest.java index 29f56e0d8bf04..a807407f170d1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitorTest.java @@ -344,6 +344,26 @@ public class DreamOverlayTouchMonitorTest extends SysuiTestCase { verify(frontEventListener, never()).onInputEvent(any()); } + @Test + public void testPop() { + final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class); + final DreamTouchHandler.TouchSession.Callback callback = + Mockito.mock(DreamTouchHandler.TouchSession.Callback.class); + + final Environment environment = new Environment(Stream.of(touchHandler) + .collect(Collectors.toCollection(HashSet::new))); + + final InputEvent initialEvent = Mockito.mock(InputEvent.class); + environment.publishInputEvent(initialEvent); + + final DreamTouchHandler.TouchSession session = captureSession(touchHandler); + session.registerCallback(callback); + session.pop(); + environment.executeAll(); + + verify(callback).onRemoved(); + } + @Test public void testPause() { final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class);