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 kotlinx.coroutines.ExperimentalCoroutinesApi 7 import com.android.systemui.SysuiTestCase 8 import com.android.systemui.dump.DumpManager 9 import com.android.systemui.plugins.qs.QS 10 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController 11 import com.android.systemui.statusbar.phone.ScrimController 12 import com.android.systemui.statusbar.policy.FakeConfigurationController 13 import com.android.systemui.util.mockito.mock 14 import org.junit.Before 15 import org.junit.Test 16 import org.junit.runner.RunWith 17 import org.mockito.Mock 18 import org.mockito.Mockito.atLeast 19 import org.mockito.Mockito.intThat 20 import org.mockito.Mockito.reset 21 import org.mockito.Mockito.verify 22 import org.mockito.Mockito.verifyNoMoreInteractions 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 @OptIn(ExperimentalCoroutinesApi::class) 34 @Mock private lateinit var scrimController: ScrimController 35 @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController 36 private var qS: QS? = null 37 @Mock private lateinit var nsslController: NotificationStackScrollLayoutController 38 @Mock private lateinit var dumpManager: DumpManager 39 40 private lateinit var overScroller: SplitShadeLockScreenOverScroller 41 42 @Before setUpnull43 fun setUp() { 44 MockitoAnnotations.initMocks(this) 45 qS = mock() 46 47 whenever(nsslController.height).thenReturn(1800) 48 49 overScroller = 50 SplitShadeLockScreenOverScroller( 51 configurationController, 52 dumpManager, 53 context, 54 scrimController, 55 statusBarStateController, 56 { qS }, 57 { nsslController }) 58 } 59 60 @Test setDragDownAmount_onKeyguard_appliesOverScrollnull61 fun setDragDownAmount_onKeyguard_appliesOverScroll() { 62 whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD) 63 64 setDragAmount(1000f) 65 66 verifyOverScrollPerformed() 67 } 68 69 @Test setDragDownAmount_notOnKeyguard_doesNotApplyOverScrollnull70 fun setDragDownAmount_notOnKeyguard_doesNotApplyOverScroll() { 71 whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE) 72 73 setDragAmount(1000f) 74 75 verifyNoMoreInteractions(qS) 76 verifyNoMoreInteractions(scrimController) 77 verifyNoMoreInteractions(nsslController) 78 } 79 80 @Test setDragAmount_onKeyguard_thenNotOnKeyguard_resetsOverScrollToZeronull81 fun setDragAmount_onKeyguard_thenNotOnKeyguard_resetsOverScrollToZero() { 82 whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD) 83 setDragAmount(1000f) 84 verifyOverScrollPerformed() 85 reset(qS, scrimController, nsslController) 86 87 whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE) 88 setDragAmount(999f) 89 verifyOverScrollResetToZero() 90 } 91 92 @Test setDragAmount_onKeyguard_thenNotOnKeyguard_multipleTimes_resetsOverScrollToZeroOnlyOncenull93 fun setDragAmount_onKeyguard_thenNotOnKeyguard_multipleTimes_resetsOverScrollToZeroOnlyOnce() { 94 whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD) 95 setDragAmount(1000f) 96 whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE) 97 setDragAmount(999f) 98 reset(qS!!, scrimController, nsslController) 99 100 setDragAmount(998f) 101 setDragAmount(997f) 102 setDragAmount(996f) 103 verifyNoMoreOverScrollChanges() 104 } 105 106 @Test qsNull_applyOverscroll_doesNotCrashnull107 fun qsNull_applyOverscroll_doesNotCrash() { 108 qS = null 109 110 setDragAmount(100f) 111 } 112 verifyOverScrollPerformednull113 private fun verifyOverScrollPerformed() { 114 verify(qS!!).setOverScrollAmount(intThat { it > 0 }) 115 verify(scrimController).setNotificationsOverScrollAmount(intThat { it > 0 }) 116 verify(nsslController).setOverScrollAmount(intThat { it > 0 }) 117 } 118 verifyOverScrollResetToZeronull119 private fun verifyOverScrollResetToZero() { 120 // Might be more than once as the animator might have multiple values close to zero that 121 // round down to zero. 122 verify(qS!!, atLeast(1)).setOverScrollAmount(0) 123 verify(scrimController, atLeast(1)).setNotificationsOverScrollAmount(0) 124 verify(nsslController, atLeast(1)).setOverScrollAmount(0) 125 } 126 verifyNoMoreOverScrollChangesnull127 private fun verifyNoMoreOverScrollChanges() { 128 verifyNoMoreInteractions(qS) 129 verifyNoMoreInteractions(scrimController) 130 verifyNoMoreInteractions(nsslController) 131 } 132 setDragAmountnull133 private fun setDragAmount(dragDownAmount: Float) { 134 overScroller.expansionDragDownAmount = dragDownAmount 135 overScroller.finishAnimations() 136 } 137 } 138