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.data.quickaffordance 19 20 import android.content.Context 21 import androidx.test.ext.junit.runners.AndroidJUnit4 22 import androidx.test.filters.SmallTest 23 import com.android.systemui.R 24 import com.android.systemui.RoboPilotTest 25 import com.android.systemui.common.shared.model.Icon 26 import com.android.systemui.keyguard.shared.quickaffordance.ActivationState 27 import com.android.systemui.statusbar.policy.FlashlightController 28 import com.android.systemui.utils.leaks.FakeFlashlightController 29 import com.android.systemui.utils.leaks.LeakCheckedTest 30 import kotlinx.coroutines.ExperimentalCoroutinesApi 31 import kotlinx.coroutines.flow.toList 32 import kotlinx.coroutines.launch 33 import kotlinx.coroutines.test.UnconfinedTestDispatcher 34 import kotlinx.coroutines.test.runTest 35 import org.junit.Assert.assertEquals 36 import org.junit.Assert.assertTrue 37 import org.junit.Before 38 import org.junit.Test 39 import org.junit.runner.RunWith 40 import org.mockito.Mock 41 import org.mockito.MockitoAnnotations 42 43 @OptIn(ExperimentalCoroutinesApi::class) 44 @SmallTest 45 @RoboPilotTest 46 @RunWith(AndroidJUnit4::class) 47 class FlashlightQuickAffordanceConfigTest : LeakCheckedTest() { 48 49 @Mock private lateinit var context: Context 50 private lateinit var flashlightController: FakeFlashlightController 51 private lateinit var underTest: FlashlightQuickAffordanceConfig 52 53 @Before 54 fun setUp() { 55 injectLeakCheckedDependency(FlashlightController::class.java) 56 MockitoAnnotations.initMocks(this) 57 58 flashlightController = 59 SysuiLeakCheck().getLeakChecker(FlashlightController::class.java) 60 as FakeFlashlightController 61 underTest = FlashlightQuickAffordanceConfig(context, flashlightController) 62 } 63 64 @Test 65 fun flashlightIsOff_triggered_iconIsOnAndActive() = runTest { 66 // given 67 flashlightController.isEnabled = false 68 flashlightController.isAvailable = true 69 val values = mutableListOf<KeyguardQuickAffordanceConfig.LockScreenState>() 70 val job = launch(UnconfinedTestDispatcher()) { underTest.lockScreenState.toList(values) } 71 72 // when 73 underTest.onTriggered(null) 74 val lastValue = values.last() 75 76 // then 77 assertTrue(lastValue is KeyguardQuickAffordanceConfig.LockScreenState.Visible) 78 assertEquals( 79 R.drawable.qs_flashlight_icon_on, 80 ((lastValue as KeyguardQuickAffordanceConfig.LockScreenState.Visible).icon 81 as? Icon.Resource) 82 ?.res 83 ) 84 job.cancel() 85 } 86 87 @Test 88 fun flashlightIsOn_triggered_iconIsOffAndInactive() = runTest { 89 // given 90 flashlightController.isEnabled = true 91 flashlightController.isAvailable = true 92 val values = mutableListOf<KeyguardQuickAffordanceConfig.LockScreenState>() 93 val job = launch(UnconfinedTestDispatcher()) { underTest.lockScreenState.toList(values) } 94 95 // when 96 underTest.onTriggered(null) 97 val lastValue = values.last() 98 99 // then 100 assertTrue(lastValue is KeyguardQuickAffordanceConfig.LockScreenState.Visible) 101 assertEquals( 102 R.drawable.qs_flashlight_icon_off, 103 ((lastValue as KeyguardQuickAffordanceConfig.LockScreenState.Visible).icon 104 as? Icon.Resource) 105 ?.res 106 ) 107 job.cancel() 108 } 109 110 @Test 111 fun flashlightIsOn_receivesError_iconIsOffAndInactive() = runTest { 112 // given 113 flashlightController.isEnabled = true 114 flashlightController.isAvailable = false 115 val values = mutableListOf<KeyguardQuickAffordanceConfig.LockScreenState>() 116 val job = launch(UnconfinedTestDispatcher()) { underTest.lockScreenState.toList(values) } 117 118 // when 119 flashlightController.onFlashlightError() 120 val lastValue = values.last() 121 122 // then 123 assertTrue(lastValue is KeyguardQuickAffordanceConfig.LockScreenState.Visible) 124 assertEquals( 125 R.drawable.qs_flashlight_icon_off, 126 ((lastValue as KeyguardQuickAffordanceConfig.LockScreenState.Visible).icon 127 as? Icon.Resource) 128 ?.res 129 ) 130 job.cancel() 131 } 132 133 @Test 134 fun flashlightAvailabilityNowOff_hidden() = runTest { 135 // given 136 flashlightController.isEnabled = true 137 flashlightController.isAvailable = false 138 val values = mutableListOf<KeyguardQuickAffordanceConfig.LockScreenState>() 139 val job = launch(UnconfinedTestDispatcher()) { underTest.lockScreenState.toList(values) } 140 141 // when 142 flashlightController.onFlashlightAvailabilityChanged(false) 143 val lastValue = values.last() 144 145 // then 146 assertTrue(lastValue is KeyguardQuickAffordanceConfig.LockScreenState.Hidden) 147 job.cancel() 148 } 149 150 @Test 151 fun flashlightAvailabilityNowOn_flashlightOn_inactiveAndIconOff() = runTest { 152 // given 153 flashlightController.isEnabled = true 154 flashlightController.isAvailable = false 155 val values = mutableListOf<KeyguardQuickAffordanceConfig.LockScreenState>() 156 val job = launch(UnconfinedTestDispatcher()) { underTest.lockScreenState.toList(values) } 157 158 // when 159 flashlightController.onFlashlightAvailabilityChanged(true) 160 val lastValue = values.last() 161 162 // then 163 assertTrue(lastValue is KeyguardQuickAffordanceConfig.LockScreenState.Visible) 164 assertTrue( 165 (lastValue as KeyguardQuickAffordanceConfig.LockScreenState.Visible).activationState 166 is ActivationState.Active 167 ) 168 assertEquals(R.drawable.qs_flashlight_icon_on, (lastValue.icon as? Icon.Resource)?.res) 169 job.cancel() 170 } 171 172 @Test 173 fun flashlightAvailabilityNowOn_flashlightOff_inactiveAndIconOff() = runTest { 174 // given 175 flashlightController.isEnabled = false 176 flashlightController.isAvailable = false 177 val values = mutableListOf<KeyguardQuickAffordanceConfig.LockScreenState>() 178 val job = launch(UnconfinedTestDispatcher()) { underTest.lockScreenState.toList(values) } 179 180 // when 181 flashlightController.onFlashlightAvailabilityChanged(true) 182 val lastValue = values.last() 183 184 // then 185 assertTrue(lastValue is KeyguardQuickAffordanceConfig.LockScreenState.Visible) 186 assertTrue( 187 (lastValue as KeyguardQuickAffordanceConfig.LockScreenState.Visible).activationState 188 is ActivationState.Inactive 189 ) 190 assertEquals(R.drawable.qs_flashlight_icon_off, (lastValue.icon as? Icon.Resource)?.res) 191 job.cancel() 192 } 193 194 @Test 195 fun flashlightAvailable_pickerStateDefault() = runTest { 196 // given 197 flashlightController.isAvailable = true 198 199 // when 200 val result = underTest.getPickerScreenState() 201 202 // then 203 assertTrue(result is KeyguardQuickAffordanceConfig.PickerScreenState.Default) 204 } 205 206 @Test 207 fun flashlightNotAvailable_pickerStateUnavailable() = runTest { 208 // given 209 flashlightController.isAvailable = false 210 211 // when 212 val result = underTest.getPickerScreenState() 213 214 // then 215 assertTrue(result is KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice) 216 } 217 } 218