1 package com.android.systemui.statusbar 2 3 import android.testing.TestableLooper 4 import androidx.test.ext.junit.runners.AndroidJUnit4 5 import androidx.test.filters.SmallTest 6 import com.android.systemui.SysuiTestCase 7 import com.android.systemui.dump.DumpManager 8 import com.android.systemui.plugins.qs.QS 9 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController 10 import com.android.systemui.statusbar.phone.ScrimController 11 import com.android.systemui.statusbar.policy.FakeConfigurationController 12 import com.android.systemui.util.mockito.mock 13 import org.junit.Before 14 import org.junit.Test 15 import org.junit.runner.RunWith 16 import org.mockito.Mock 17 import org.mockito.Mockito.atLeast 18 import org.mockito.Mockito.intThat 19 import org.mockito.Mockito.reset 20 import org.mockito.Mockito.verify 21 import org.mockito.Mockito.verifyNoMoreInteractions 22 import org.mockito.Mockito.verifyZeroInteractions 23 import org.mockito.Mockito.`when` as whenever 24 import org.mockito.MockitoAnnotations 25 26 @RunWith(AndroidJUnit4::class) 27 @SmallTest 28 @TestableLooper.RunWithLooper 29 class SplitShadeLockScreenOverScrollerTest : SysuiTestCase() { 30 31 private val configurationController = FakeConfigurationController() 32 33 @Mock private lateinit var scrimController: ScrimController 34 @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController 35 private var qS: QS? = null 36 @Mock private lateinit var nsslController: NotificationStackScrollLayoutController 37 @Mock private lateinit var dumpManager: DumpManager 38 39 private lateinit var overScroller: SplitShadeLockScreenOverScroller 40 41 @Before setUpnull42 fun setUp() { 43 MockitoAnnotations.initMocks(this) 44 qS = mock() 45 46 whenever(nsslController.height).thenReturn(1800) 47 48 overScroller = 49 SplitShadeLockScreenOverScroller( 50 configurationController, 51 dumpManager, 52 context, 53 scrimController, 54 statusBarStateController, 55 { qS }, 56 { nsslController }) 57 } 58 59 @Test setDragDownAmount_onKeyguard_appliesOverScrollnull60 fun setDragDownAmount_onKeyguard_appliesOverScroll() { 61 whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD) 62 63 setDragAmount(1000f) 64 65 verifyOverScrollPerformed() 66 } 67 68 @Test setDragDownAmount_notOnKeyguard_doesNotApplyOverScrollnull69 fun setDragDownAmount_notOnKeyguard_doesNotApplyOverScroll() { 70 whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE) 71 72 setDragAmount(1000f) 73 74 verifyZeroInteractions(qS) 75 verifyZeroInteractions(scrimController) 76 verifyZeroInteractions(nsslController) 77 } 78 79 @Test setDragAmount_onKeyguard_thenNotOnKeyguard_resetsOverScrollToZeronull80 fun setDragAmount_onKeyguard_thenNotOnKeyguard_resetsOverScrollToZero() { 81 whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD) 82 setDragAmount(1000f) 83 verifyOverScrollPerformed() 84 reset(qS, scrimController, nsslController) 85 86 whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE) 87 setDragAmount(999f) 88 verifyOverScrollResetToZero() 89 } 90 91 @Test setDragAmount_onKeyguard_thenNotOnKeyguard_multipleTimes_resetsOverScrollToZeroOnlyOncenull92 fun setDragAmount_onKeyguard_thenNotOnKeyguard_multipleTimes_resetsOverScrollToZeroOnlyOnce() { 93 whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD) 94 setDragAmount(1000f) 95 whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE) 96 setDragAmount(999f) 97 reset(qS!!, scrimController, nsslController) 98 99 setDragAmount(998f) 100 setDragAmount(997f) 101 setDragAmount(996f) 102 verifyNoMoreOverScrollChanges() 103 } 104 105 @Test qsNull_applyOverscroll_doesNotCrashnull106 fun qsNull_applyOverscroll_doesNotCrash() { 107 qS = null 108 109 setDragAmount(100f) 110 } 111 verifyOverScrollPerformednull112 private fun verifyOverScrollPerformed() { 113 verify(qS!!).setOverScrollAmount(intThat { it > 0 }) 114 verify(scrimController).setNotificationsOverScrollAmount(intThat { it > 0 }) 115 verify(nsslController).setOverScrollAmount(intThat { it > 0 }) 116 } 117 verifyOverScrollResetToZeronull118 private fun verifyOverScrollResetToZero() { 119 // Might be more than once as the animator might have multiple values close to zero that 120 // round down to zero. 121 verify(qS!!, atLeast(1)).setOverScrollAmount(0) 122 verify(scrimController, atLeast(1)).setNotificationsOverScrollAmount(0) 123 verify(nsslController, atLeast(1)).setOverScrollAmount(0) 124 } 125 verifyNoMoreOverScrollChangesnull126 private fun verifyNoMoreOverScrollChanges() { 127 verifyNoMoreInteractions(qS) 128 verifyNoMoreInteractions(scrimController) 129 verifyNoMoreInteractions(nsslController) 130 } 131 setDragAmountnull132 private fun setDragAmount(dragDownAmount: Float) { 133 overScroller.expansionDragDownAmount = dragDownAmount 134 overScroller.finishAnimations() 135 } 136 } 137