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.bouncer.domain.interactor 18 19 import androidx.test.ext.junit.runners.AndroidJUnit4 20 import androidx.test.filters.SmallTest 21 import com.android.keyguard.KeyguardUpdateMonitor 22 import com.android.systemui.RoboPilotTest 23 import com.android.systemui.SysuiTestCase 24 import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository 25 import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepositoryImpl 26 import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository 27 import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository 28 import com.android.systemui.log.table.TableLogBuffer 29 import com.android.systemui.plugins.statusbar.StatusBarStateController 30 import com.android.systemui.statusbar.policy.KeyguardStateController 31 import com.android.systemui.util.mockito.whenever 32 import com.android.systemui.util.time.FakeSystemClock 33 import com.android.systemui.util.time.SystemClock 34 import kotlinx.coroutines.ExperimentalCoroutinesApi 35 import kotlinx.coroutines.test.TestCoroutineScope 36 import org.junit.Assert.assertFalse 37 import org.junit.Assert.assertTrue 38 import org.junit.Before 39 import org.junit.Test 40 import org.junit.runner.RunWith 41 import org.mockito.Mock 42 import org.mockito.MockitoAnnotations 43 44 @OptIn(ExperimentalCoroutinesApi::class) 45 @SmallTest 46 @RoboPilotTest 47 @RunWith(AndroidJUnit4::class) 48 class AlternateBouncerInteractorTest : SysuiTestCase() { 49 private lateinit var underTest: AlternateBouncerInteractor 50 private lateinit var bouncerRepository: KeyguardBouncerRepository 51 private lateinit var biometricSettingsRepository: FakeBiometricSettingsRepository 52 private lateinit var deviceEntryFingerprintAuthRepository: 53 FakeDeviceEntryFingerprintAuthRepository 54 @Mock private lateinit var statusBarStateController: StatusBarStateController 55 @Mock private lateinit var keyguardStateController: KeyguardStateController 56 @Mock private lateinit var systemClock: SystemClock 57 @Mock private lateinit var bouncerLogger: TableLogBuffer 58 @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor 59 60 @Before 61 fun setup() { 62 MockitoAnnotations.initMocks(this) 63 bouncerRepository = 64 KeyguardBouncerRepositoryImpl( 65 FakeSystemClock(), 66 TestCoroutineScope(), 67 bouncerLogger, 68 ) 69 biometricSettingsRepository = FakeBiometricSettingsRepository() 70 deviceEntryFingerprintAuthRepository = FakeDeviceEntryFingerprintAuthRepository() 71 underTest = 72 AlternateBouncerInteractor( 73 statusBarStateController, 74 keyguardStateController, 75 bouncerRepository, 76 biometricSettingsRepository, 77 systemClock, 78 keyguardUpdateMonitor, 79 ) 80 } 81 82 @Test 83 fun canShowAlternateBouncerForFingerprint_givenCanShow() { 84 givenCanShowAlternateBouncer() 85 assertTrue(underTest.canShowAlternateBouncerForFingerprint()) 86 } 87 88 @Test 89 fun canShowAlternateBouncerForFingerprint_alternateBouncerUIUnavailable() { 90 givenCanShowAlternateBouncer() 91 bouncerRepository.setAlternateBouncerUIAvailable(false) 92 93 assertFalse(underTest.canShowAlternateBouncerForFingerprint()) 94 } 95 96 @Test 97 fun canShowAlternateBouncerForFingerprint_ifFingerprintIsNotUsuallyAllowed() { 98 givenCanShowAlternateBouncer() 99 biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false) 100 101 assertFalse(underTest.canShowAlternateBouncerForFingerprint()) 102 } 103 104 @Test 105 fun canShowAlternateBouncerForFingerprint_strongBiometricNotAllowed() { 106 givenCanShowAlternateBouncer() 107 biometricSettingsRepository.setIsFingerprintAuthCurrentlyAllowed(false) 108 109 assertFalse(underTest.canShowAlternateBouncerForFingerprint()) 110 } 111 112 @Test 113 fun canShowAlternateBouncerForFingerprint_fingerprintLockedOut() { 114 givenCanShowAlternateBouncer() 115 whenever(keyguardUpdateMonitor.isFingerprintLockedOut).thenReturn(true) 116 117 assertFalse(underTest.canShowAlternateBouncerForFingerprint()) 118 } 119 120 @Test 121 fun show_whenCanShow() { 122 givenCanShowAlternateBouncer() 123 124 assertTrue(underTest.show()) 125 assertTrue(bouncerRepository.alternateBouncerVisible.value) 126 } 127 128 @Test 129 fun canShowAlternateBouncerForFingerprint_butCanDismissLockScreen() { 130 givenCanShowAlternateBouncer() 131 whenever(keyguardStateController.isUnlocked).thenReturn(true) 132 133 assertFalse(underTest.canShowAlternateBouncerForFingerprint()) 134 } 135 136 @Test 137 fun show_whenCannotShow() { 138 givenCannotShowAlternateBouncer() 139 140 assertFalse(underTest.show()) 141 assertFalse(bouncerRepository.alternateBouncerVisible.value) 142 } 143 144 @Test 145 fun hide_wasPreviouslyShowing() { 146 bouncerRepository.setAlternateVisible(true) 147 148 assertTrue(underTest.hide()) 149 assertFalse(bouncerRepository.alternateBouncerVisible.value) 150 } 151 152 @Test 153 fun hide_wasNotPreviouslyShowing() { 154 bouncerRepository.setAlternateVisible(false) 155 156 assertFalse(underTest.hide()) 157 assertFalse(bouncerRepository.alternateBouncerVisible.value) 158 } 159 160 @Test 161 fun alternateBouncerUiAvailable_fromMultipleSources() { 162 assertFalse(bouncerRepository.alternateBouncerUIAvailable.value) 163 164 // GIVEN there are two different sources indicating the alternate bouncer is available 165 underTest.setAlternateBouncerUIAvailable(true, "source1") 166 underTest.setAlternateBouncerUIAvailable(true, "source2") 167 assertTrue(bouncerRepository.alternateBouncerUIAvailable.value) 168 169 // WHEN one of the sources no longer says the UI is available 170 underTest.setAlternateBouncerUIAvailable(false, "source1") 171 172 // THEN alternate bouncer UI is still available (from the other source) 173 assertTrue(bouncerRepository.alternateBouncerUIAvailable.value) 174 175 // WHEN all sources say the UI is not available 176 underTest.setAlternateBouncerUIAvailable(false, "source2") 177 178 // THEN alternate boucer UI is not available 179 assertFalse(bouncerRepository.alternateBouncerUIAvailable.value) 180 } 181 182 private fun givenCanShowAlternateBouncer() { 183 bouncerRepository.setAlternateBouncerUIAvailable(true) 184 biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true) 185 biometricSettingsRepository.setIsFingerprintAuthCurrentlyAllowed(true) 186 whenever(keyguardUpdateMonitor.isFingerprintLockedOut).thenReturn(false) 187 whenever(keyguardStateController.isUnlocked).thenReturn(false) 188 } 189 190 private fun givenCannotShowAlternateBouncer() { 191 biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false) 192 } 193 } 194