Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +13 −12 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package com.android.systemui.statusbar.notification.stack; import static android.os.Trace.TRACE_TAG_APP; import static android.view.MotionEvent.ACTION_CANCEL; import static android.view.MotionEvent.ACTION_UP; import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_SCROLL_FLING; import static com.android.internal.jank.InteractionJankMonitor.CUJ_SHADE_CLEAR_ALL; Loading Loading @@ -3306,7 +3308,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable @Override public boolean dispatchTouchEvent(MotionEvent ev) { if (SceneContainerFlag.isEnabled() && mIsBeingDragged) { if (!mSendingTouchesToSceneFramework) { int action = ev.getActionMasked(); boolean isUpOrCancel = action == ACTION_UP || action == ACTION_CANCEL; if (mSendingTouchesToSceneFramework) { mController.sendTouchToSceneFramework(ev); } else if (!isUpOrCancel) { // if this is the first touch being sent to the scene framework, // convert it into a synthetic DOWN event. mSendingTouchesToSceneFramework = true; Loading @@ -3314,14 +3320,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable downEvent.setAction(MotionEvent.ACTION_DOWN); mController.sendTouchToSceneFramework(downEvent); downEvent.recycle(); } else { mController.sendTouchToSceneFramework(ev); } if ( ev.getActionMasked() == MotionEvent.ACTION_UP || ev.getActionMasked() == MotionEvent.ACTION_CANCEL ) { if (isUpOrCancel) { setIsBeingDragged(false); } return false; Loading Loading @@ -3478,7 +3479,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } } break; case MotionEvent.ACTION_UP: case ACTION_UP: if (mIsBeingDragged) { final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); Loading Loading @@ -3515,7 +3516,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } break; case MotionEvent.ACTION_CANCEL: case ACTION_CANCEL: if (mIsBeingDragged && getChildCount() > 0) { if (mScroller.springBack(mScrollX, mOwnScrollY, 0, 0, 0, getScrollRange())) { Loading Loading @@ -3624,7 +3625,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable mTouchIsClick = false; } break; case MotionEvent.ACTION_UP: case ACTION_UP: if (mStatusBarState != StatusBarState.KEYGUARD && mTouchIsClick && isBelowLastNotification(mInitialTouchX, mInitialTouchY)) { debugShadeLog("handleEmptySpaceClick: touch event propagated further"); Loading Loading @@ -3765,8 +3766,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable break; } case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: case ACTION_CANCEL: case ACTION_UP: /* Release the drag */ setIsBeingDragged(false); mActivePointerId = INVALID_POINTER; Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java +71 −42 Original line number Diff line number Diff line Loading @@ -38,7 +38,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.clearInvocations; Loading Loading @@ -73,11 +72,11 @@ import com.android.keyguard.BouncerPanelExpansionCalculator; import com.android.systemui.ExpandHelper; import com.android.systemui.SysuiTestCase; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.EnableSceneContainer; import com.android.systemui.flags.FakeFeatureFlags; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; import com.android.systemui.res.R; import com.android.systemui.scene.shared.flag.SceneContainerFlag; import com.android.systemui.shade.ShadeController; import com.android.systemui.shade.transition.LargeScreenShadeInterpolator; import com.android.systemui.statusbar.EmptyShadeView; Loading @@ -97,13 +96,11 @@ import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController; import org.junit.Assert; import org.junit.Assume; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; Loading Loading @@ -232,6 +229,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address disabled test public void testUpdateStackHeight_qsExpansionZero() { final float expansionFraction = 0.2f; final float overExpansion = 50f; Loading Loading @@ -730,6 +728,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address lack of QS Header public void testInsideQSHeader_noOffset() { ViewGroup qsHeader = mock(ViewGroup.class); Rect boundsOnScreen = new Rect(0, 0, 1000, 1000); Loading @@ -746,6 +745,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address lack of QS Header public void testInsideQSHeader_Offset() { ViewGroup qsHeader = mock(ViewGroup.class); Rect boundsOnScreen = new Rect(100, 100, 1000, 1000); Loading @@ -765,12 +765,14 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address disabled test public void setFractionToShade_recomputesStackHeight() { mStackScroller.setFractionToShade(1f); verify(mNotificationStackSizeCalculator).computeHeight(any(), anyInt(), anyFloat()); } @Test @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address disabled test public void testSetOwnScrollY_shadeNotClosing_scrollYChanges() { // Given: shade is not closing, scrollY is 0 mAmbientState.setScrollY(0); Loading Loading @@ -869,6 +871,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address disabled test public void testSplitShade_hasTopOverscroll() { mTestableResources .addOverride(R.bool.config_use_split_notification_shade, /* value= */ true); Loading Loading @@ -941,6 +944,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address disabled test public void testSetMaxDisplayedNotifications_notifiesListeners() { ExpandableView.OnHeightChangedListener listener = mock(ExpandableView.OnHeightChangedListener.class); Loading @@ -955,9 +959,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test @DisableFlags(FLAG_SCENE_CONTAINER) public void testDispatchTouchEvent_sceneContainerDisabled() { Assume.assumeFalse(SceneContainerFlag.isEnabled()); MotionEvent event = MotionEvent.obtain( SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), Loading @@ -973,34 +976,60 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test @EnableSceneContainer public void testDispatchTouchEvent_sceneContainerEnabled() { Assume.assumeTrue(SceneContainerFlag.isEnabled()); mStackScroller.setIsBeingDragged(true); MotionEvent moveEvent = MotionEvent.obtain( SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), long downTime = SystemClock.uptimeMillis() - 100; MotionEvent moveEvent1 = MotionEvent.obtain( /* downTime= */ downTime, /* eventTime= */ SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE, 0, 0, 101, 201, 0 ); MotionEvent syntheticDownEvent = moveEvent.copy(); MotionEvent syntheticDownEvent = moveEvent1.copy(); syntheticDownEvent.setAction(MotionEvent.ACTION_DOWN); mStackScroller.dispatchTouchEvent(moveEvent); mStackScroller.dispatchTouchEvent(moveEvent1); assertThatMotionEvent(captureTouchSentToSceneFramework()).matches(syntheticDownEvent); assertTrue(mStackScroller.getIsBeingDragged()); clearInvocations(mStackScrollLayoutController); MotionEvent moveEvent2 = MotionEvent.obtain( /* downTime= */ downTime, /* eventTime= */ SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE, 102, 202, 0 ); mStackScroller.dispatchTouchEvent(moveEvent2); verify(mStackScrollLayoutController).sendTouchToSceneFramework(argThat( new MotionEventMatcher(syntheticDownEvent))); assertThatMotionEvent(captureTouchSentToSceneFramework()).matches(moveEvent2); assertTrue(mStackScroller.getIsBeingDragged()); clearInvocations(mStackScrollLayoutController); MotionEvent upEvent = MotionEvent.obtain( /* downTime= */ downTime, /* eventTime= */ SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 103, 203, 0 ); mStackScroller.dispatchTouchEvent(moveEvent); mStackScroller.dispatchTouchEvent(upEvent); verify(mStackScrollLayoutController).sendTouchToSceneFramework(moveEvent); assertThatMotionEvent(captureTouchSentToSceneFramework()).matches(upEvent); assertFalse(mStackScroller.getIsBeingDragged()); } @Test @EnableFlags(FLAG_SCENE_CONTAINER) public void testDispatchTouchEvent_sceneContainerEnabled_actionUp() { Assume.assumeTrue(SceneContainerFlag.isEnabled()); @EnableSceneContainer public void testDispatchTouchEvent_sceneContainerEnabled_ignoresInitialActionUp() { mStackScroller.setIsBeingDragged(true); MotionEvent upEvent = MotionEvent.obtain( Loading @@ -1011,21 +1040,18 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { 0, 0 ); MotionEvent syntheticDownEvent = upEvent.copy(); syntheticDownEvent.setAction(MotionEvent.ACTION_DOWN); mStackScroller.dispatchTouchEvent(upEvent); verify(mStackScrollLayoutController, atLeastOnce()).sendTouchToSceneFramework(argThat( new MotionEventMatcher(syntheticDownEvent))); mStackScroller.dispatchTouchEvent(upEvent); verify(mStackScrollLayoutController, atLeastOnce()).sendTouchToSceneFramework(argThat( new MotionEventMatcher(upEvent))); verify(mStackScrollLayoutController, never()).sendTouchToSceneFramework(any()); assertFalse(mStackScroller.getIsBeingDragged()); } private MotionEvent captureTouchSentToSceneFramework() { ArgumentCaptor<MotionEvent> captor = ArgumentCaptor.forClass(MotionEvent.class); verify(mStackScrollLayoutController).sendTouchToSceneFramework(captor.capture()); return captor.getValue(); } private void setBarStateForTest(int state) { // Can't inject this through the listener or we end up on the actual implementation // rather than the mock because the spy just coppied the anonymous inner /shruggie. Loading Loading @@ -1073,20 +1099,23 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { ); } private static class MotionEventMatcher implements ArgumentMatcher<MotionEvent> { private final MotionEvent mLeftEvent; private MotionEventSubject assertThatMotionEvent(MotionEvent actual) { return new MotionEventSubject(actual); } private static class MotionEventSubject { private final MotionEvent mActual; MotionEventMatcher(MotionEvent leftEvent) { mLeftEvent = leftEvent; MotionEventSubject(MotionEvent actual) { mActual = actual; } @Override public boolean matches(MotionEvent right) { return mLeftEvent.getActionMasked() == right.getActionMasked() && mLeftEvent.getDownTime() == right.getDownTime() && mLeftEvent.getEventTime() == right.getEventTime() && mLeftEvent.getX() == right.getX() && mLeftEvent.getY() == right.getY(); public void matches(MotionEvent expected) { assertThat(mActual.getActionMasked()).isEqualTo(expected.getActionMasked()); assertThat(mActual.getDownTime()).isEqualTo(expected.getDownTime()); assertThat(mActual.getEventTime()).isEqualTo(expected.getEventTime()); assertThat(mActual.getX()).isEqualTo(expected.getX()); assertThat(mActual.getY()).isEqualTo(expected.getY()); } } } Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +13 −12 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package com.android.systemui.statusbar.notification.stack; import static android.os.Trace.TRACE_TAG_APP; import static android.view.MotionEvent.ACTION_CANCEL; import static android.view.MotionEvent.ACTION_UP; import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_SCROLL_FLING; import static com.android.internal.jank.InteractionJankMonitor.CUJ_SHADE_CLEAR_ALL; Loading Loading @@ -3306,7 +3308,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable @Override public boolean dispatchTouchEvent(MotionEvent ev) { if (SceneContainerFlag.isEnabled() && mIsBeingDragged) { if (!mSendingTouchesToSceneFramework) { int action = ev.getActionMasked(); boolean isUpOrCancel = action == ACTION_UP || action == ACTION_CANCEL; if (mSendingTouchesToSceneFramework) { mController.sendTouchToSceneFramework(ev); } else if (!isUpOrCancel) { // if this is the first touch being sent to the scene framework, // convert it into a synthetic DOWN event. mSendingTouchesToSceneFramework = true; Loading @@ -3314,14 +3320,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable downEvent.setAction(MotionEvent.ACTION_DOWN); mController.sendTouchToSceneFramework(downEvent); downEvent.recycle(); } else { mController.sendTouchToSceneFramework(ev); } if ( ev.getActionMasked() == MotionEvent.ACTION_UP || ev.getActionMasked() == MotionEvent.ACTION_CANCEL ) { if (isUpOrCancel) { setIsBeingDragged(false); } return false; Loading Loading @@ -3478,7 +3479,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } } break; case MotionEvent.ACTION_UP: case ACTION_UP: if (mIsBeingDragged) { final VelocityTracker velocityTracker = mVelocityTracker; velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); Loading Loading @@ -3515,7 +3516,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } break; case MotionEvent.ACTION_CANCEL: case ACTION_CANCEL: if (mIsBeingDragged && getChildCount() > 0) { if (mScroller.springBack(mScrollX, mOwnScrollY, 0, 0, 0, getScrollRange())) { Loading Loading @@ -3624,7 +3625,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable mTouchIsClick = false; } break; case MotionEvent.ACTION_UP: case ACTION_UP: if (mStatusBarState != StatusBarState.KEYGUARD && mTouchIsClick && isBelowLastNotification(mInitialTouchX, mInitialTouchY)) { debugShadeLog("handleEmptySpaceClick: touch event propagated further"); Loading Loading @@ -3765,8 +3766,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable break; } case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: case ACTION_CANCEL: case ACTION_UP: /* Release the drag */ setIsBeingDragged(false); mActivePointerId = INVALID_POINTER; Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java +71 −42 Original line number Diff line number Diff line Loading @@ -38,7 +38,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.clearInvocations; Loading Loading @@ -73,11 +72,11 @@ import com.android.keyguard.BouncerPanelExpansionCalculator; import com.android.systemui.ExpandHelper; import com.android.systemui.SysuiTestCase; import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.EnableSceneContainer; import com.android.systemui.flags.FakeFeatureFlags; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; import com.android.systemui.res.R; import com.android.systemui.scene.shared.flag.SceneContainerFlag; import com.android.systemui.shade.ShadeController; import com.android.systemui.shade.transition.LargeScreenShadeInterpolator; import com.android.systemui.statusbar.EmptyShadeView; Loading @@ -97,13 +96,11 @@ import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController; import org.junit.Assert; import org.junit.Assume; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; Loading Loading @@ -232,6 +229,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address disabled test public void testUpdateStackHeight_qsExpansionZero() { final float expansionFraction = 0.2f; final float overExpansion = 50f; Loading Loading @@ -730,6 +728,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address lack of QS Header public void testInsideQSHeader_noOffset() { ViewGroup qsHeader = mock(ViewGroup.class); Rect boundsOnScreen = new Rect(0, 0, 1000, 1000); Loading @@ -746,6 +745,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address lack of QS Header public void testInsideQSHeader_Offset() { ViewGroup qsHeader = mock(ViewGroup.class); Rect boundsOnScreen = new Rect(100, 100, 1000, 1000); Loading @@ -765,12 +765,14 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address disabled test public void setFractionToShade_recomputesStackHeight() { mStackScroller.setFractionToShade(1f); verify(mNotificationStackSizeCalculator).computeHeight(any(), anyInt(), anyFloat()); } @Test @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address disabled test public void testSetOwnScrollY_shadeNotClosing_scrollYChanges() { // Given: shade is not closing, scrollY is 0 mAmbientState.setScrollY(0); Loading Loading @@ -869,6 +871,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address disabled test public void testSplitShade_hasTopOverscroll() { mTestableResources .addOverride(R.bool.config_use_split_notification_shade, /* value= */ true); Loading Loading @@ -941,6 +944,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test @DisableFlags(FLAG_SCENE_CONTAINER) // TODO(b/312473478): address disabled test public void testSetMaxDisplayedNotifications_notifiesListeners() { ExpandableView.OnHeightChangedListener listener = mock(ExpandableView.OnHeightChangedListener.class); Loading @@ -955,9 +959,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test @DisableFlags(FLAG_SCENE_CONTAINER) public void testDispatchTouchEvent_sceneContainerDisabled() { Assume.assumeFalse(SceneContainerFlag.isEnabled()); MotionEvent event = MotionEvent.obtain( SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), Loading @@ -973,34 +976,60 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test @EnableSceneContainer public void testDispatchTouchEvent_sceneContainerEnabled() { Assume.assumeTrue(SceneContainerFlag.isEnabled()); mStackScroller.setIsBeingDragged(true); MotionEvent moveEvent = MotionEvent.obtain( SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), long downTime = SystemClock.uptimeMillis() - 100; MotionEvent moveEvent1 = MotionEvent.obtain( /* downTime= */ downTime, /* eventTime= */ SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE, 0, 0, 101, 201, 0 ); MotionEvent syntheticDownEvent = moveEvent.copy(); MotionEvent syntheticDownEvent = moveEvent1.copy(); syntheticDownEvent.setAction(MotionEvent.ACTION_DOWN); mStackScroller.dispatchTouchEvent(moveEvent); mStackScroller.dispatchTouchEvent(moveEvent1); assertThatMotionEvent(captureTouchSentToSceneFramework()).matches(syntheticDownEvent); assertTrue(mStackScroller.getIsBeingDragged()); clearInvocations(mStackScrollLayoutController); MotionEvent moveEvent2 = MotionEvent.obtain( /* downTime= */ downTime, /* eventTime= */ SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE, 102, 202, 0 ); mStackScroller.dispatchTouchEvent(moveEvent2); verify(mStackScrollLayoutController).sendTouchToSceneFramework(argThat( new MotionEventMatcher(syntheticDownEvent))); assertThatMotionEvent(captureTouchSentToSceneFramework()).matches(moveEvent2); assertTrue(mStackScroller.getIsBeingDragged()); clearInvocations(mStackScrollLayoutController); MotionEvent upEvent = MotionEvent.obtain( /* downTime= */ downTime, /* eventTime= */ SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 103, 203, 0 ); mStackScroller.dispatchTouchEvent(moveEvent); mStackScroller.dispatchTouchEvent(upEvent); verify(mStackScrollLayoutController).sendTouchToSceneFramework(moveEvent); assertThatMotionEvent(captureTouchSentToSceneFramework()).matches(upEvent); assertFalse(mStackScroller.getIsBeingDragged()); } @Test @EnableFlags(FLAG_SCENE_CONTAINER) public void testDispatchTouchEvent_sceneContainerEnabled_actionUp() { Assume.assumeTrue(SceneContainerFlag.isEnabled()); @EnableSceneContainer public void testDispatchTouchEvent_sceneContainerEnabled_ignoresInitialActionUp() { mStackScroller.setIsBeingDragged(true); MotionEvent upEvent = MotionEvent.obtain( Loading @@ -1011,21 +1040,18 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { 0, 0 ); MotionEvent syntheticDownEvent = upEvent.copy(); syntheticDownEvent.setAction(MotionEvent.ACTION_DOWN); mStackScroller.dispatchTouchEvent(upEvent); verify(mStackScrollLayoutController, atLeastOnce()).sendTouchToSceneFramework(argThat( new MotionEventMatcher(syntheticDownEvent))); mStackScroller.dispatchTouchEvent(upEvent); verify(mStackScrollLayoutController, atLeastOnce()).sendTouchToSceneFramework(argThat( new MotionEventMatcher(upEvent))); verify(mStackScrollLayoutController, never()).sendTouchToSceneFramework(any()); assertFalse(mStackScroller.getIsBeingDragged()); } private MotionEvent captureTouchSentToSceneFramework() { ArgumentCaptor<MotionEvent> captor = ArgumentCaptor.forClass(MotionEvent.class); verify(mStackScrollLayoutController).sendTouchToSceneFramework(captor.capture()); return captor.getValue(); } private void setBarStateForTest(int state) { // Can't inject this through the listener or we end up on the actual implementation // rather than the mock because the spy just coppied the anonymous inner /shruggie. Loading Loading @@ -1073,20 +1099,23 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { ); } private static class MotionEventMatcher implements ArgumentMatcher<MotionEvent> { private final MotionEvent mLeftEvent; private MotionEventSubject assertThatMotionEvent(MotionEvent actual) { return new MotionEventSubject(actual); } private static class MotionEventSubject { private final MotionEvent mActual; MotionEventMatcher(MotionEvent leftEvent) { mLeftEvent = leftEvent; MotionEventSubject(MotionEvent actual) { mActual = actual; } @Override public boolean matches(MotionEvent right) { return mLeftEvent.getActionMasked() == right.getActionMasked() && mLeftEvent.getDownTime() == right.getDownTime() && mLeftEvent.getEventTime() == right.getEventTime() && mLeftEvent.getX() == right.getX() && mLeftEvent.getY() == right.getY(); public void matches(MotionEvent expected) { assertThat(mActual.getActionMasked()).isEqualTo(expected.getActionMasked()); assertThat(mActual.getDownTime()).isEqualTo(expected.getDownTime()); assertThat(mActual.getEventTime()).isEqualTo(expected.getEventTime()); assertThat(mActual.getX()).isEqualTo(expected.getX()); assertThat(mActual.getY()).isEqualTo(expected.getY()); } } }