diff options
2 files changed, 47 insertions, 2 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java index 02360434344d..4260bd97759d 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java @@ -105,7 +105,14 @@ public class NotificationShadeWindowViewController { private boolean mTouchActive; private boolean mTouchCancelled; private MotionEvent mDownEvent; + // TODO rename to mLaunchAnimationRunning private boolean mExpandAnimationRunning; + /** + * When mExpandAnimationRunning is true and the touch dispatcher receives a down even after + * uptime exceeds this, the dispatcher will stop blocking touches for the launch animation, + * which has presumabely not completed due to an error. + */ + private long mLaunchAnimationTimeout; private NotificationStackScrollLayout mStackScrollLayout; private PhoneStatusBarViewController mStatusBarViewController; private final CentralSurfaces mService; @@ -266,7 +273,12 @@ public class NotificationShadeWindowViewController { return logDownDispatch(ev, "touch cancelled", false); } if (mExpandAnimationRunning) { - return logDownDispatch(ev, "expand animation running", false); + if (isDown && mClock.uptimeMillis() > mLaunchAnimationTimeout) { + mShadeLogger.d("NSWVC: launch animation timed out"); + setExpandAnimationRunning(false); + } else { + return logDownDispatch(ev, "expand animation running", false); + } } if (mKeyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()) { @@ -548,6 +560,9 @@ public class NotificationShadeWindowViewController { public void setExpandAnimationRunning(boolean running) { if (mExpandAnimationRunning != running) { + if (running) { + mLaunchAnimationTimeout = mClock.uptimeMillis() + 5000; + } mExpandAnimationRunning = running; mNotificationShadeWindowController.setLaunchingActivity(mExpandAnimationRunning); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt index 7a41d7121dfa..8ef8324d07dc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt @@ -110,6 +110,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() { @Mock lateinit var primaryBouncerToGoneTransitionViewModel: PrimaryBouncerToGoneTransitionViewModel + private lateinit var fakeClock: FakeSystemClock private lateinit var interactionEventHandlerCaptor: ArgumentCaptor<InteractionEventHandler> private lateinit var interactionEventHandler: InteractionEventHandler @@ -148,6 +149,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() { ), inputProxy = inputProxy, ) + fakeClock = FakeSystemClock() underTest = NotificationShadeWindowViewController( lockscreenShadeTransitionController, @@ -176,7 +178,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() { primaryBouncerToGoneTransitionViewModel, featureFlags, { multiShadeInteractor }, - FakeSystemClock(), + fakeClock, { MultiShadeMotionEventInteractor( applicationContext = context, @@ -331,6 +333,33 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() { } @Test + fun handleDispatchTouchEvent_launchAnimationRunningTimesOut() = + testScope.runTest { + // GIVEN touch dispatcher in a state that returns true + underTest.setStatusBarViewController(phoneStatusBarViewController) + whenever(keyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()).thenReturn( + true + ) + assertThat(interactionEventHandler.handleDispatchTouchEvent(DOWN_EVENT)).isTrue() + + // WHEN launch animation is running for 2 seconds + fakeClock.setUptimeMillis(10000) + underTest.setExpandAnimationRunning(true) + fakeClock.advanceTime(2000) + + // THEN touch is ignored + assertThat(interactionEventHandler.handleDispatchTouchEvent(DOWN_EVENT)).isFalse() + + // WHEN Launch animation is running for 6 seconds + fakeClock.advanceTime(4000) + + // THEN move is ignored, down is handled, and window is notified + assertThat(interactionEventHandler.handleDispatchTouchEvent(MOVE_EVENT)).isFalse() + assertThat(interactionEventHandler.handleDispatchTouchEvent(DOWN_EVENT)).isTrue() + verify(notificationShadeWindowController).setLaunchingActivity(false) + } + + @Test fun shouldInterceptTouchEvent_statusBarKeyguardViewManagerShouldIntercept() { // down event should be intercepted by keyguardViewManager whenever(statusBarKeyguardViewManager.shouldInterceptTouchEvent(DOWN_EVENT)) @@ -350,6 +379,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() { companion object { private val DOWN_EVENT = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0) + private val MOVE_EVENT = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 0f, 0) private const val VIEW_BOTTOM = 100 } } |