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 18 package com.android.systemui.keyguard.domain.interactor 19 20 import android.app.StatusBarManager 21 import androidx.test.ext.junit.runners.AndroidJUnit4 22 import androidx.test.filters.SmallTest 23 import com.android.systemui.RoboPilotTest 24 import com.android.systemui.SysuiTestCase 25 import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository 26 import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository 27 import com.android.systemui.coroutines.collectLastValue 28 import com.android.systemui.flags.FakeFeatureFlags 29 import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR 30 import com.android.systemui.keyguard.data.repository.FakeCommandQueue 31 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository 32 import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel 33 import com.google.common.truth.Truth.assertThat 34 import kotlinx.coroutines.flow.onCompletion 35 import kotlinx.coroutines.test.TestScope 36 import kotlinx.coroutines.test.runCurrent 37 import kotlinx.coroutines.test.runTest 38 import org.junit.Before 39 import org.junit.Test 40 import org.junit.runner.RunWith 41 import org.mockito.MockitoAnnotations 42 43 @SmallTest 44 @RoboPilotTest 45 @RunWith(AndroidJUnit4::class) 46 class KeyguardInteractorTest : SysuiTestCase() { 47 private lateinit var commandQueue: FakeCommandQueue 48 private lateinit var featureFlags: FakeFeatureFlags 49 private lateinit var testScope: TestScope 50 51 private lateinit var underTest: KeyguardInteractor 52 private lateinit var repository: FakeKeyguardRepository 53 private lateinit var bouncerRepository: FakeKeyguardBouncerRepository 54 private lateinit var configurationRepository: FakeConfigurationRepository 55 56 @Before 57 fun setUp() { 58 MockitoAnnotations.initMocks(this) 59 featureFlags = FakeFeatureFlags().apply { set(FACE_AUTH_REFACTOR, true) } 60 commandQueue = FakeCommandQueue() 61 testScope = TestScope() 62 repository = FakeKeyguardRepository() 63 bouncerRepository = FakeKeyguardBouncerRepository() 64 configurationRepository = FakeConfigurationRepository() 65 underTest = 66 KeyguardInteractor( 67 repository, 68 commandQueue, 69 featureFlags, 70 bouncerRepository, 71 configurationRepository, 72 ) 73 } 74 75 @Test 76 fun onCameraLaunchDetected() = 77 testScope.runTest { 78 val flow = underTest.onCameraLaunchDetected 79 var cameraLaunchSource = collectLastValue(flow) 80 runCurrent() 81 82 commandQueue.doForEachCallback { 83 it.onCameraLaunchGestureDetected(StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE) 84 } 85 assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.WIGGLE) 86 87 commandQueue.doForEachCallback { 88 it.onCameraLaunchGestureDetected( 89 StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP 90 ) 91 } 92 assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.POWER_DOUBLE_TAP) 93 94 commandQueue.doForEachCallback { 95 it.onCameraLaunchGestureDetected(StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER) 96 } 97 assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.LIFT_TRIGGER) 98 99 commandQueue.doForEachCallback { 100 it.onCameraLaunchGestureDetected( 101 StatusBarManager.CAMERA_LAUNCH_SOURCE_QUICK_AFFORDANCE 102 ) 103 } 104 assertThat(cameraLaunchSource()).isEqualTo(CameraLaunchSourceModel.QUICK_AFFORDANCE) 105 106 flow.onCompletion { assertThat(commandQueue.callbackCount()).isEqualTo(0) } 107 } 108 109 @Test 110 fun testKeyguardGuardVisibilityStopsSecureCamera() = 111 testScope.runTest { 112 val secureCameraActive = collectLastValue(underTest.isSecureCameraActive) 113 runCurrent() 114 115 commandQueue.doForEachCallback { 116 it.onCameraLaunchGestureDetected( 117 StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP 118 ) 119 } 120 121 assertThat(secureCameraActive()).isTrue() 122 123 // Keyguard is showing but occluded 124 repository.setKeyguardShowing(true) 125 repository.setKeyguardOccluded(true) 126 assertThat(secureCameraActive()).isTrue() 127 128 // Keyguard is showing and not occluded 129 repository.setKeyguardOccluded(false) 130 assertThat(secureCameraActive()).isFalse() 131 } 132 133 @Test 134 fun testBouncerShowingResetsSecureCameraState() = 135 testScope.runTest { 136 val secureCameraActive = collectLastValue(underTest.isSecureCameraActive) 137 runCurrent() 138 139 commandQueue.doForEachCallback { 140 it.onCameraLaunchGestureDetected( 141 StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP 142 ) 143 } 144 assertThat(secureCameraActive()).isTrue() 145 146 // Keyguard is showing and not occluded 147 repository.setKeyguardShowing(true) 148 repository.setKeyguardOccluded(true) 149 assertThat(secureCameraActive()).isTrue() 150 151 bouncerRepository.setPrimaryShow(true) 152 assertThat(secureCameraActive()).isFalse() 153 } 154 155 @Test 156 fun keyguardVisibilityIsDefinedAsKeyguardShowingButNotOccluded() = runTest { 157 var isVisible = collectLastValue(underTest.isKeyguardVisible) 158 repository.setKeyguardShowing(true) 159 repository.setKeyguardOccluded(false) 160 161 assertThat(isVisible()).isTrue() 162 163 repository.setKeyguardOccluded(true) 164 assertThat(isVisible()).isFalse() 165 166 repository.setKeyguardShowing(false) 167 repository.setKeyguardOccluded(true) 168 assertThat(isVisible()).isFalse() 169 } 170 171 @Test 172 fun secureCameraIsNotActiveWhenNoCameraLaunchEventHasBeenFiredYet() = 173 testScope.runTest { 174 val secureCameraActive = collectLastValue(underTest.isSecureCameraActive) 175 runCurrent() 176 177 assertThat(secureCameraActive()).isFalse() 178 } 179 } 180