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