1 /* 2 * Copyright 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 @file:OptIn(ExperimentalCoroutinesApi::class) 18 19 package com.android.systemui.authentication.data.repository 20 21 import android.app.admin.DevicePolicyManager 22 import android.content.Intent 23 import android.content.pm.UserInfo 24 import androidx.test.filters.SmallTest 25 import com.android.internal.widget.LockPatternUtils 26 import com.android.keyguard.KeyguardSecurityModel 27 import com.android.systemui.SysuiTestCase 28 import com.android.systemui.authentication.data.model.AuthenticationMethodModel 29 import com.android.systemui.coroutines.collectLastValue 30 import com.android.systemui.coroutines.collectValues 31 import com.android.systemui.scene.SceneTestUtils 32 import com.android.systemui.user.data.repository.FakeUserRepository 33 import com.android.systemui.util.mockito.whenever 34 import com.google.common.truth.Truth.assertThat 35 import java.util.function.Function 36 import kotlinx.coroutines.ExperimentalCoroutinesApi 37 import kotlinx.coroutines.runBlocking 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 import org.junit.runners.JUnit4 44 import org.mockito.ArgumentMatchers.anyInt 45 import org.mockito.Mock 46 import org.mockito.MockitoAnnotations 47 48 @SmallTest 49 @RunWith(JUnit4::class) 50 class AuthenticationRepositoryTest : SysuiTestCase() { 51 52 @Mock private lateinit var lockPatternUtils: LockPatternUtils 53 @Mock private lateinit var getSecurityMode: Function<Int, KeyguardSecurityModel.SecurityMode> 54 55 private val testUtils = SceneTestUtils(this) 56 private val testScope = testUtils.testScope 57 private val userRepository = FakeUserRepository() 58 59 private lateinit var underTest: AuthenticationRepository 60 61 private var currentSecurityMode: KeyguardSecurityModel.SecurityMode = 62 KeyguardSecurityModel.SecurityMode.PIN 63 64 @Before 65 fun setUp() { 66 MockitoAnnotations.initMocks(this) 67 userRepository.setUserInfos(USER_INFOS) 68 runBlocking { userRepository.setSelectedUserInfo(USER_INFOS[0]) } 69 whenever(getSecurityMode.apply(anyInt())).thenAnswer { currentSecurityMode } 70 71 underTest = 72 AuthenticationRepositoryImpl( 73 applicationScope = testScope.backgroundScope, 74 getSecurityMode = getSecurityMode, 75 backgroundDispatcher = testUtils.testDispatcher, 76 userRepository = userRepository, 77 keyguardRepository = testUtils.keyguardRepository, 78 lockPatternUtils = lockPatternUtils, 79 broadcastDispatcher = fakeBroadcastDispatcher, 80 ) 81 } 82 83 @Test 84 fun authenticationMethod() = 85 testScope.runTest { 86 val authMethod by collectLastValue(underTest.authenticationMethod) 87 runCurrent() 88 dispatchBroadcast() 89 assertThat(authMethod).isEqualTo(AuthenticationMethodModel.Pin) 90 assertThat(underTest.getAuthenticationMethod()).isEqualTo(AuthenticationMethodModel.Pin) 91 92 setSecurityModeAndDispatchBroadcast(KeyguardSecurityModel.SecurityMode.Pattern) 93 assertThat(authMethod).isEqualTo(AuthenticationMethodModel.Pattern) 94 assertThat(underTest.getAuthenticationMethod()) 95 .isEqualTo(AuthenticationMethodModel.Pattern) 96 97 setSecurityModeAndDispatchBroadcast(KeyguardSecurityModel.SecurityMode.None) 98 assertThat(authMethod).isEqualTo(AuthenticationMethodModel.None) 99 assertThat(underTest.getAuthenticationMethod()) 100 .isEqualTo(AuthenticationMethodModel.None) 101 } 102 103 @Test 104 fun isAutoConfirmEnabled() = 105 testScope.runTest { 106 whenever(lockPatternUtils.isAutoPinConfirmEnabled(USER_INFOS[0].id)).thenReturn(true) 107 whenever(lockPatternUtils.isAutoPinConfirmEnabled(USER_INFOS[1].id)).thenReturn(false) 108 109 val values by collectValues(underTest.isAutoConfirmEnabled) 110 assertThat(values.first()).isFalse() 111 assertThat(values.last()).isTrue() 112 113 userRepository.setSelectedUserInfo(USER_INFOS[1]) 114 assertThat(values.last()).isFalse() 115 } 116 117 @Test 118 fun isPatternVisible() = 119 testScope.runTest { 120 whenever(lockPatternUtils.isVisiblePatternEnabled(USER_INFOS[0].id)).thenReturn(false) 121 whenever(lockPatternUtils.isVisiblePatternEnabled(USER_INFOS[1].id)).thenReturn(true) 122 123 val values by collectValues(underTest.isPatternVisible) 124 assertThat(values.first()).isTrue() 125 assertThat(values.last()).isFalse() 126 127 userRepository.setSelectedUserInfo(USER_INFOS[1]) 128 assertThat(values.last()).isTrue() 129 } 130 131 private fun setSecurityModeAndDispatchBroadcast( 132 securityMode: KeyguardSecurityModel.SecurityMode, 133 ) { 134 currentSecurityMode = securityMode 135 dispatchBroadcast() 136 } 137 138 private fun dispatchBroadcast() { 139 fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly( 140 context, 141 Intent(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED) 142 ) 143 } 144 145 companion object { 146 private val USER_INFOS = 147 listOf( 148 UserInfo( 149 /* id= */ 100, 150 /* name= */ "First user", 151 /* flags= */ 0, 152 ), 153 UserInfo( 154 /* id= */ 101, 155 /* name= */ "Second user", 156 /* flags= */ 0, 157 ), 158 ) 159 } 160 } 161