1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.statusbar
18 
19 import android.testing.AndroidTestingRunner
20 import androidx.test.filters.SmallTest
21 import com.android.systemui.R
22 import com.android.systemui.SysuiTestCase
23 import com.android.systemui.dump.DumpManager
24 import com.android.systemui.plugins.qs.QS
25 import com.android.systemui.statusbar.policy.FakeConfigurationController
26 import com.google.common.truth.Expect
27 import com.google.common.truth.Truth.assertThat
28 import org.junit.Before
29 import org.junit.Rule
30 import org.junit.Test
31 import org.junit.runner.RunWith
32 import org.mockito.Mock
33 import org.mockito.Mockito.verify
34 import org.mockito.MockitoAnnotations
35 
36 @SmallTest
37 @RunWith(AndroidTestingRunner::class)
38 class LockscreenShadeQsTransitionControllerTest : SysuiTestCase() {
39 
40     private val configurationController = FakeConfigurationController()
41 
42     @get:Rule val expect: Expect = Expect.create()
43 
44     @Mock private lateinit var dumpManager: DumpManager
45     @Mock private lateinit var qS: QS
46 
47     private lateinit var controller: LockscreenShadeQsTransitionController
48 
49     @Before
50     fun setUp() {
51         MockitoAnnotations.initMocks(this)
52         setTransitionDistance(TRANSITION_DISTANCE)
53         setTransitionDelay(TRANSITION_DELAY)
54         setSquishTransitionDistance(SQUISH_TRANSITION_DISTANCE)
55         setSquishStartFraction(SQUISH_START_FRACTION)
56 
57         controller =
58             LockscreenShadeQsTransitionController(
59                 context,
60                 configurationController,
61                 dumpManager,
62                 qsProvider = { qS }
63             )
64     }
65 
66     @Test
67     fun qsTransitionFraction_byDefault_returns0() {
68         assertThat(controller.qsTransitionFraction).isZero()
69     }
70 
71     @Test
72     fun qsTransitionFraction_noStartDelay_returnsBasedOnTransitionDistance() {
73         setTransitionDelay(0)
74         setTransitionDistance(100)
75 
76         controller.dragDownAmount = 25f
77         expect.that(controller.qsTransitionFraction).isEqualTo(0.25f)
78 
79         controller.dragDownAmount = 50f
80         expect.that(controller.qsTransitionFraction).isEqualTo(0.5f)
81 
82         controller.dragDownAmount = 75f
83         expect.that(controller.qsTransitionFraction).isEqualTo(0.75f)
84 
85         controller.dragDownAmount = 100f
86         expect.that(controller.qsTransitionFraction).isEqualTo(1f)
87     }
88 
89     @Test
90     fun qsTransitionFraction_noStartDelay_returnsValuesBetween0and1() {
91         setTransitionDelay(0)
92         setTransitionDistance(100)
93 
94         controller.dragDownAmount = -500f
95         expect.that(controller.qsTransitionFraction).isEqualTo(0f)
96 
97         controller.dragDownAmount = 500f
98         expect.that(controller.qsTransitionFraction).isEqualTo(1f)
99     }
100 
101     @Test
102     fun qsTransitionFraction_withStartDelay_returnsBasedOnTransitionDistanceAndDelay() {
103         setTransitionDelay(10)
104         setTransitionDistance(100)
105 
106         controller.dragDownAmount = 0f
107         expect.that(controller.qsTransitionFraction).isEqualTo(0f)
108 
109         controller.dragDownAmount = 10f
110         expect.that(controller.qsTransitionFraction).isEqualTo(0f)
111 
112         controller.dragDownAmount = 25f
113         expect.that(controller.qsTransitionFraction).isEqualTo(0.15f)
114 
115         controller.dragDownAmount = 100f
116         expect.that(controller.qsTransitionFraction).isEqualTo(0.9f)
117 
118         controller.dragDownAmount = 110f
119         expect.that(controller.qsTransitionFraction).isEqualTo(1f)
120     }
121 
122     @Test
123     fun qsTransitionFraction_withStartDelay_returnsValuesBetween0and1() {
124         setTransitionDelay(10)
125         setTransitionDistance(100)
126 
127         controller.dragDownAmount = -500f
128         expect.that(controller.qsTransitionFraction).isEqualTo(0f)
129 
130         controller.dragDownAmount = 500f
131         expect.that(controller.qsTransitionFraction).isEqualTo(1f)
132     }
133 
134     @Test
135     fun qsSquishTransitionFraction_byDefault_returnsValueSetFromResource() {
136         assertThat(controller.qsSquishTransitionFraction).isEqualTo(SQUISH_START_FRACTION)
137     }
138 
139     @Test
140     fun qsSquishTransitionFraction_noStartDelay_startFraction0_returnsBasedOnTransitionDistance() {
141         setTransitionDelay(0)
142         setSquishStartFraction(0f)
143         setSquishTransitionDistance(1000)
144 
145         controller.dragDownAmount = 250f
146         expect.that(controller.qsSquishTransitionFraction).isEqualTo(0.25f)
147 
148         controller.dragDownAmount = 500f
149         expect.that(controller.qsSquishTransitionFraction).isEqualTo(0.5f)
150 
151         controller.dragDownAmount = 750f
152         expect.that(controller.qsSquishTransitionFraction).isEqualTo(0.75f)
153 
154         controller.dragDownAmount = 1000f
155         expect.that(controller.qsSquishTransitionFraction).isEqualTo(1f)
156     }
157 
158     @Test
159     fun qsSquishTransitionFraction_startDelay_startFraction0_basedOnTransitionDistanceAndDelay() {
160         setTransitionDelay(100)
161         setSquishStartFraction(0f)
162         setSquishTransitionDistance(1000)
163 
164         controller.dragDownAmount = 250f
165         expect.that(controller.qsSquishTransitionFraction).isEqualTo(0.15f)
166 
167         controller.dragDownAmount = 500f
168         expect.that(controller.qsSquishTransitionFraction).isEqualTo(0.4f)
169 
170         controller.dragDownAmount = 750f
171         expect.that(controller.qsSquishTransitionFraction).isEqualTo(0.65f)
172 
173         controller.dragDownAmount = 1000f
174         expect.that(controller.qsSquishTransitionFraction).isEqualTo(0.9f)
175 
176         controller.dragDownAmount = 1100f
177         expect.that(controller.qsSquishTransitionFraction).isEqualTo(1f)
178     }
179 
180     @Test
181     fun qsSquishTransitionFraction_noStartDelay_startFractionSet_returnsBasedOnStartAndDistance() {
182         setTransitionDelay(0)
183         setSquishStartFraction(0.5f)
184         setSquishTransitionDistance(1000)
185 
186         controller.dragDownAmount = 0f
187         expect.that(controller.qsSquishTransitionFraction).isEqualTo(0.5f)
188 
189         controller.dragDownAmount = 500f
190         expect.that(controller.qsSquishTransitionFraction).isEqualTo(0.75f)
191 
192         controller.dragDownAmount = 1000f
193         expect.that(controller.qsSquishTransitionFraction).isEqualTo(1f)
194     }
195 
196     @Test
197     fun qsSquishTransitionFraction_startDelay_startFractionSet_basedOnStartAndDistanceAndDelay() {
198         setTransitionDelay(10)
199         setSquishStartFraction(0.5f)
200         setSquishTransitionDistance(100)
201 
202         controller.dragDownAmount = 0f
203         expect.that(controller.qsSquishTransitionFraction).isEqualTo(0.5f)
204 
205         controller.dragDownAmount = 50f
206         expect.that(controller.qsSquishTransitionFraction).isEqualTo(0.7f)
207 
208         controller.dragDownAmount = 100f
209         expect.that(controller.qsSquishTransitionFraction).isEqualTo(0.95f)
210 
211         controller.dragDownAmount = 110f
212         expect.that(controller.qsSquishTransitionFraction).isEqualTo(1f)
213     }
214 
215     @Test
216     fun onDragDownAmountChanged_setsValuesOnQS() {
217         val rawDragAmount = 200f
218 
219         controller.dragDownAmount = rawDragAmount
220 
221         verify(qS)
222             .setTransitionToFullShadeProgress(
223                 /* isTransitioningToFullShade= */ true,
224                 /* transitionFraction= */ controller.qsTransitionFraction,
225                 /* squishinessFraction= */ controller.qsSquishTransitionFraction
226             )
227     }
228 
229     private fun setTransitionDistance(value: Int) {
230         overrideResource(R.dimen.lockscreen_shade_qs_transition_distance, value)
231         configurationController.notifyConfigurationChanged()
232     }
233 
234     private fun setTransitionDelay(value: Int) {
235         overrideResource(R.dimen.lockscreen_shade_qs_transition_delay, value)
236         configurationController.notifyConfigurationChanged()
237     }
238 
239     private fun setSquishTransitionDistance(value: Int) {
240         overrideResource(R.dimen.lockscreen_shade_qs_squish_transition_distance, value)
241         configurationController.notifyConfigurationChanged()
242     }
243 
244     private fun setSquishStartFraction(value: Float) {
245         overrideResource(R.dimen.lockscreen_shade_qs_squish_start_fraction, value)
246         configurationController.notifyConfigurationChanged()
247     }
248 
249     companion object {
250         private const val TRANSITION_DELAY = 123
251         private const val TRANSITION_DISTANCE = 321
252         private const val SQUISH_START_FRACTION = 0.123f
253         private const val SQUISH_TRANSITION_DISTANCE = 456
254     }
255 }
256