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 
18 package com.android.systemui.keyguard.domain.interactor
19 
20 import androidx.test.ext.junit.runners.AndroidJUnit4
21 import androidx.test.filters.SmallTest
22 import com.android.systemui.RoboPilotTest
23 import com.android.systemui.SysuiTestCase
24 import com.android.systemui.coroutines.collectValues
25 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
26 import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
27 import com.android.systemui.keyguard.shared.model.KeyguardState.DOZING
28 import com.android.systemui.keyguard.shared.model.KeyguardState.GONE
29 import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
30 import com.android.systemui.keyguard.shared.model.KeyguardState.OFF
31 import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
32 import com.android.systemui.keyguard.shared.model.TransitionState.FINISHED
33 import com.android.systemui.keyguard.shared.model.TransitionState.RUNNING
34 import com.android.systemui.keyguard.shared.model.TransitionState.STARTED
35 import com.android.systemui.keyguard.shared.model.TransitionStep
36 import com.google.common.truth.Truth.assertThat
37 import kotlinx.coroutines.test.TestScope
38 import kotlinx.coroutines.test.runCurrent
39 import kotlinx.coroutines.test.runTest
40 import org.junit.Before
41 import org.junit.Test
42 import org.junit.runner.RunWith
43 
44 @SmallTest
45 @RoboPilotTest
46 @RunWith(AndroidJUnit4::class)
47 @kotlinx.coroutines.ExperimentalCoroutinesApi
48 class KeyguardTransitionInteractorTest : SysuiTestCase() {
49 
50     private lateinit var underTest: KeyguardTransitionInteractor
51     private lateinit var repository: FakeKeyguardTransitionRepository
52     private val testScope = TestScope()
53 
54     @Before
55     fun setUp() {
56         repository = FakeKeyguardTransitionRepository()
57         underTest = KeyguardTransitionInteractorFactory.create(
58                 scope = testScope.backgroundScope,
59                 repository = repository,
60         ).keyguardTransitionInteractor
61     }
62 
63     @Test
64     fun transitionCollectorsReceivesOnlyAppropriateEvents() = runTest {
65         val lockscreenToAodSteps by collectValues(underTest.lockscreenToAodTransition)
66         val aodToLockscreenSteps by collectValues(underTest.aodToLockscreenTransition)
67 
68         val steps = mutableListOf<TransitionStep>()
69         steps.add(TransitionStep(AOD, GONE, 0f, STARTED))
70         steps.add(TransitionStep(AOD, GONE, 1f, FINISHED))
71         steps.add(TransitionStep(AOD, LOCKSCREEN, 0f, STARTED))
72         steps.add(TransitionStep(AOD, LOCKSCREEN, 0.5f, RUNNING))
73         steps.add(TransitionStep(AOD, LOCKSCREEN, 1f, FINISHED))
74         steps.add(TransitionStep(LOCKSCREEN, AOD, 0f, STARTED))
75         steps.add(TransitionStep(LOCKSCREEN, AOD, 0.1f, RUNNING))
76         steps.add(TransitionStep(LOCKSCREEN, AOD, 0.2f, RUNNING))
77 
78         steps.forEach {
79             repository.sendTransitionStep(it)
80             runCurrent()
81         }
82 
83         assertThat(aodToLockscreenSteps).isEqualTo(steps.subList(2, 5))
84         assertThat(lockscreenToAodSteps).isEqualTo(steps.subList(5, 8))
85     }
86 
87     @Test
88     fun dozeAmountTransitionTest() = runTest {
89         val dozeAmountSteps by collectValues(underTest.dozeAmountTransition)
90 
91         val steps = mutableListOf<TransitionStep>()
92 
93         steps.add(TransitionStep(AOD, LOCKSCREEN, 0f, STARTED))
94         steps.add(TransitionStep(AOD, LOCKSCREEN, 0.5f, RUNNING))
95         steps.add(TransitionStep(AOD, LOCKSCREEN, 1f, FINISHED))
96         steps.add(TransitionStep(LOCKSCREEN, AOD, 0f, STARTED))
97         steps.add(TransitionStep(LOCKSCREEN, AOD, 0.8f, RUNNING))
98         steps.add(TransitionStep(LOCKSCREEN, AOD, 0.9f, RUNNING))
99         steps.add(TransitionStep(LOCKSCREEN, AOD, 1f, FINISHED))
100 
101         steps.forEach {
102             repository.sendTransitionStep(it)
103             runCurrent()
104         }
105 
106         assertThat(dozeAmountSteps.subList(0, 3))
107             .isEqualTo(
108                 listOf(
109                     steps[0].copy(value = 1f - steps[0].value),
110                     steps[1].copy(value = 1f - steps[1].value),
111                     steps[2].copy(value = 1f - steps[2].value),
112                 )
113             )
114         assertThat(dozeAmountSteps.subList(3, 7)).isEqualTo(steps.subList(3, 7))
115     }
116 
117     @Test
118     fun finishedKeyguardStateTests() = testScope.runTest {
119         val finishedSteps by collectValues(underTest.finishedKeyguardState)
120         runCurrent()
121         val steps = mutableListOf<TransitionStep>()
122 
123         steps.add(TransitionStep(AOD, PRIMARY_BOUNCER, 0f, STARTED))
124         steps.add(TransitionStep(AOD, PRIMARY_BOUNCER, 0.5f, RUNNING))
125         steps.add(TransitionStep(AOD, PRIMARY_BOUNCER, 1f, FINISHED))
126         steps.add(TransitionStep(PRIMARY_BOUNCER, AOD, 0f, STARTED))
127         steps.add(TransitionStep(PRIMARY_BOUNCER, AOD, 0.9f, RUNNING))
128         steps.add(TransitionStep(PRIMARY_BOUNCER, AOD, 1f, FINISHED))
129         steps.add(TransitionStep(AOD, GONE, 1f, STARTED))
130 
131         steps.forEach {
132             repository.sendTransitionStep(it)
133             runCurrent()
134         }
135 
136         assertThat(finishedSteps).isEqualTo(listOf(LOCKSCREEN, PRIMARY_BOUNCER, AOD))
137     }
138 
139     @Test
140     fun startedKeyguardStateTests() = testScope.runTest {
141         val finishedSteps by collectValues(underTest.startedKeyguardState)
142         runCurrent()
143         val steps = mutableListOf<TransitionStep>()
144 
145         steps.add(TransitionStep(AOD, PRIMARY_BOUNCER, 0f, STARTED))
146         steps.add(TransitionStep(AOD, PRIMARY_BOUNCER, 0.5f, RUNNING))
147         steps.add(TransitionStep(AOD, PRIMARY_BOUNCER, 1f, FINISHED))
148         steps.add(TransitionStep(PRIMARY_BOUNCER, AOD, 0f, STARTED))
149         steps.add(TransitionStep(PRIMARY_BOUNCER, AOD, 0.9f, RUNNING))
150         steps.add(TransitionStep(PRIMARY_BOUNCER, AOD, 1f, FINISHED))
151         steps.add(TransitionStep(AOD, GONE, 1f, STARTED))
152 
153         steps.forEach {
154             repository.sendTransitionStep(it)
155             runCurrent()
156         }
157 
158         assertThat(finishedSteps).isEqualTo(listOf(OFF, PRIMARY_BOUNCER, AOD, GONE))
159     }
160 
161     @Test
162     fun finishedKeyguardTransitionStepTests() = runTest {
163         val finishedSteps by collectValues(underTest.finishedKeyguardTransitionStep)
164 
165         val steps = mutableListOf<TransitionStep>()
166 
167         steps.add(TransitionStep(AOD, LOCKSCREEN, 0f, STARTED))
168         steps.add(TransitionStep(AOD, LOCKSCREEN, 0.5f, RUNNING))
169         steps.add(TransitionStep(AOD, LOCKSCREEN, 1f, FINISHED))
170         steps.add(TransitionStep(LOCKSCREEN, AOD, 0f, STARTED))
171         steps.add(TransitionStep(LOCKSCREEN, AOD, 0.9f, RUNNING))
172         steps.add(TransitionStep(LOCKSCREEN, AOD, 1f, FINISHED))
173         steps.add(TransitionStep(AOD, GONE, 1f, STARTED))
174 
175         steps.forEach {
176             repository.sendTransitionStep(it)
177             runCurrent()
178         }
179 
180         assertThat(finishedSteps).isEqualTo(listOf(steps[2], steps[5]))
181     }
182 
183     @Test
184     fun startedKeyguardTransitionStepTests() = runTest {
185         val startedSteps by collectValues(underTest.startedKeyguardTransitionStep)
186 
187         val steps = mutableListOf<TransitionStep>()
188 
189         steps.add(TransitionStep(AOD, LOCKSCREEN, 0f, STARTED))
190         steps.add(TransitionStep(AOD, LOCKSCREEN, 0.5f, RUNNING))
191         steps.add(TransitionStep(AOD, LOCKSCREEN, 1f, FINISHED))
192         steps.add(TransitionStep(LOCKSCREEN, AOD, 0f, STARTED))
193         steps.add(TransitionStep(LOCKSCREEN, AOD, 0.9f, RUNNING))
194         steps.add(TransitionStep(LOCKSCREEN, AOD, 1f, FINISHED))
195         steps.add(TransitionStep(AOD, GONE, 1f, STARTED))
196 
197         steps.forEach {
198             repository.sendTransitionStep(it)
199             runCurrent()
200         }
201 
202         assertThat(startedSteps).isEqualTo(listOf(steps[0], steps[3], steps[6]))
203     }
204 
205     @Test
206     fun transitionValue() = runTest {
207         val startedSteps by collectValues(underTest.transitionValue(state = DOZING))
208 
209         val toSteps =
210             listOf(
211                 TransitionStep(AOD, DOZING, 0f, STARTED),
212                 TransitionStep(AOD, DOZING, 0.5f, RUNNING),
213                 TransitionStep(AOD, DOZING, 1f, FINISHED),
214             )
215         toSteps.forEach {
216             repository.sendTransitionStep(it)
217             runCurrent()
218         }
219 
220         val fromSteps =
221             listOf(
222                 TransitionStep(DOZING, LOCKSCREEN, 0f, STARTED),
223                 TransitionStep(DOZING, LOCKSCREEN, 0.5f, RUNNING),
224                 TransitionStep(DOZING, LOCKSCREEN, 1f, FINISHED),
225             )
226         fromSteps.forEach {
227             repository.sendTransitionStep(it)
228             runCurrent()
229         }
230 
231         assertThat(startedSteps).isEqualTo(listOf(0f, 0.5f, 1f, 1f, 0.5f, 0f))
232     }
233 }
234