1 /*
2  * Copyright (C) 2023 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.deviceentry.domain.ui.viewmodel
18 
19 import android.platform.test.flag.junit.FlagsParameterization
20 import androidx.test.filters.SmallTest
21 import com.android.systemui.SysuiTestCase
22 import com.android.systemui.accessibility.data.repository.fakeAccessibilityRepository
23 import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
24 import com.android.systemui.coroutines.collectLastValue
25 import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
26 import com.android.systemui.deviceentry.data.ui.viewmodel.deviceEntryUdfpsAccessibilityOverlayViewModel
27 import com.android.systemui.deviceentry.ui.viewmodel.DeviceEntryUdfpsAccessibilityOverlayViewModel
28 import com.android.systemui.flags.Flags.FULL_SCREEN_USER_SWITCHER
29 import com.android.systemui.flags.andSceneContainer
30 import com.android.systemui.flags.fakeFeatureFlagsClassic
31 import com.android.systemui.keyguard.data.repository.deviceEntryFingerprintAuthRepository
32 import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository
33 import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
34 import com.android.systemui.keyguard.shared.model.KeyguardState
35 import com.android.systemui.keyguard.shared.model.TransitionState
36 import com.android.systemui.keyguard.shared.model.TransitionStep
37 import com.android.systemui.keyguard.ui.viewmodel.fakeDeviceEntryIconViewModelTransition
38 import com.android.systemui.kosmos.testScope
39 import com.android.systemui.res.R
40 import com.android.systemui.shade.shadeTestUtil
41 import com.android.systemui.testKosmos
42 import com.google.common.truth.Truth.assertThat
43 import kotlin.test.Test
44 import kotlinx.coroutines.ExperimentalCoroutinesApi
45 import kotlinx.coroutines.test.runCurrent
46 import kotlinx.coroutines.test.runTest
47 import org.junit.After
48 import org.junit.Before
49 import org.junit.runner.RunWith
50 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
51 import platform.test.runner.parameterized.Parameters
52 
53 @ExperimentalCoroutinesApi
54 @SmallTest
55 @RunWith(ParameterizedAndroidJunit4::class)
56 class UdfpsAccessibilityOverlayViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
57     private val kosmos =
<lambda>null58         testKosmos().apply {
59             fakeFeatureFlagsClassic.apply { set(FULL_SCREEN_USER_SWITCHER, false) }
60         }
61     private val deviceEntryIconTransition = kosmos.fakeDeviceEntryIconViewModelTransition
62     private val testScope = kosmos.testScope
63     private val biometricSettingsRepository = kosmos.fakeBiometricSettingsRepository
64     private val accessibilityRepository = kosmos.fakeAccessibilityRepository
65     private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
66     private val fingerprintPropertyRepository = kosmos.fingerprintPropertyRepository
67     private val deviceEntryFingerprintAuthRepository = kosmos.deviceEntryFingerprintAuthRepository
68     private val deviceEntryRepository = kosmos.fakeDeviceEntryRepository
69 
<lambda>null70     private val shadeTestUtil by lazy { kosmos.shadeTestUtil }
71 
72     private lateinit var underTest: DeviceEntryUdfpsAccessibilityOverlayViewModel
73 
74     companion object {
75         @JvmStatic
76         @Parameters(name = "{0}")
getParamsnull77         fun getParams(): List<FlagsParameterization> {
78             return FlagsParameterization.allCombinationsOf().andSceneContainer()
79         }
80     }
81 
82     init {
83         mSetFlagsRule.setFlagsParameterization(flags)
84     }
85 
86     @Before
setupnull87     fun setup() {
88         underTest = kosmos.deviceEntryUdfpsAccessibilityOverlayViewModel
89         overrideResource(R.integer.udfps_padding_debounce_duration, 0)
90     }
91 
92     @After
teardownnull93     fun teardown() {
94         mContext.orCreateTestableResources.removeOverride(R.integer.udfps_padding_debounce_duration)
95     }
96 
97     @Test
visiblenull98     fun visible() =
99         testScope.runTest {
100             val visible by collectLastValue(underTest.visible)
101             setupVisibleStateOnLockscreen()
102             assertThat(visible).isTrue()
103         }
104 
105     @Test
touchExplorationNotEnabled_overlayNotVisiblenull106     fun touchExplorationNotEnabled_overlayNotVisible() =
107         testScope.runTest {
108             val visible by collectLastValue(underTest.visible)
109             setupVisibleStateOnLockscreen()
110             accessibilityRepository.isTouchExplorationEnabled.value = false
111             assertThat(visible).isFalse()
112         }
113 
114     @Test
deviceEntryFgIconViewModelAod_overlayNotVisiblenull115     fun deviceEntryFgIconViewModelAod_overlayNotVisible() =
116         testScope.runTest {
117             val visible by collectLastValue(underTest.visible)
118             setupVisibleStateOnLockscreen()
119 
120             // AOD
121             keyguardTransitionRepository.sendTransitionSteps(
122                 from = KeyguardState.LOCKSCREEN,
123                 to = KeyguardState.AOD,
124                 this,
125             )
126             runCurrent()
127             assertThat(visible).isFalse()
128         }
129 
fpNotRunning_overlayNotVisiblenull130     fun fpNotRunning_overlayNotVisible() =
131         testScope.runTest {
132             val visible by collectLastValue(underTest.visible)
133             setupVisibleStateOnLockscreen()
134             deviceEntryFingerprintAuthRepository.setIsRunning(false)
135             assertThat(visible).isFalse()
136         }
137 
138     @Test
deviceEntryViewAlpha0_overlayNotVisiblenull139     fun deviceEntryViewAlpha0_overlayNotVisible() =
140         testScope.runTest {
141             val visible by collectLastValue(underTest.visible)
142             setupVisibleStateOnLockscreen()
143             deviceEntryIconTransition.setDeviceEntryParentViewAlpha(0f)
144             assertThat(visible).isFalse()
145         }
146 
setupVisibleStateOnLockscreennull147     private suspend fun setupVisibleStateOnLockscreen() {
148         // A11y enabled
149         accessibilityRepository.isTouchExplorationEnabled.value = true
150 
151         // Transition alpha is 1f
152         deviceEntryIconTransition.setDeviceEntryParentViewAlpha(1f)
153 
154         // Listening for UDFPS
155         fingerprintPropertyRepository.supportsUdfps()
156         biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
157         deviceEntryFingerprintAuthRepository.setIsRunning(true)
158 
159         // Lockscreen
160         keyguardTransitionRepository.sendTransitionStep(
161             TransitionStep(
162                 from = KeyguardState.AOD,
163                 to = KeyguardState.LOCKSCREEN,
164                 value = 0f,
165                 transitionState = TransitionState.STARTED,
166             )
167         )
168         keyguardTransitionRepository.sendTransitionStep(
169             TransitionStep(
170                 from = KeyguardState.AOD,
171                 to = KeyguardState.LOCKSCREEN,
172                 value = 1f,
173                 transitionState = TransitionState.FINISHED,
174             )
175         )
176 
177         // Shade not expanded
178         shadeTestUtil.setQsExpansion(0f)
179         shadeTestUtil.setLockscreenShadeExpansion(0f)
180     }
181 }
182