• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.biometrics
18 
19 import android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE
20 import android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT
21 import android.hardware.biometrics.BiometricConstants
22 import android.hardware.face.FaceManager
23 import android.testing.TestableLooper
24 import android.testing.TestableLooper.RunWithLooper
25 import android.view.View
26 import androidx.test.ext.junit.runners.AndroidJUnit4
27 import androidx.test.filters.SmallTest
28 import com.android.systemui.R
29 import com.android.systemui.RoboPilotTest
30 import com.android.systemui.SysuiTestCase
31 import com.google.common.truth.Truth.assertThat
32 import org.junit.After
33 import org.junit.Before
34 import org.junit.Rule
35 import org.junit.Test
36 import org.junit.runner.RunWith
37 import org.mockito.Mock
38 import org.mockito.Mockito.never
39 import org.mockito.Mockito.verify
40 import org.mockito.Mockito.times
41 import org.mockito.junit.MockitoJUnit
42 
43 
44 @RunWith(AndroidJUnit4::class)
45 @RunWithLooper(setAsMainLooper = true)
46 @SmallTest
47 @RoboPilotTest
48 class AuthBiometricFingerprintAndFaceViewTest : SysuiTestCase() {
49 
50     @JvmField
51     @Rule
52     var mockitoRule = MockitoJUnit.rule()
53 
54     @Mock
55     private lateinit var callback: AuthBiometricView.Callback
56 
57     @Mock
58     private lateinit var panelController: AuthPanelController
59 
60     private lateinit var biometricView: AuthBiometricFingerprintAndFaceView
61 
62     @Before
setupnull63     fun setup() {
64         biometricView = R.layout.auth_biometric_fingerprint_and_face_view
65                 .asTestAuthBiometricView(mContext, callback, panelController)
66         waitForIdleSync()
67     }
68 
69     @After
tearDownnull70     fun tearDown() {
71         biometricView.destroyDialog()
72     }
73 
74     @Test
fingerprintSuccessDoesNotRequireExplicitConfirmationnull75     fun fingerprintSuccessDoesNotRequireExplicitConfirmation() {
76         biometricView.onDialogAnimatedIn(fingerprintWasStarted = true)
77         biometricView.onAuthenticationSucceeded(TYPE_FINGERPRINT)
78         TestableLooper.get(this).moveTimeForward(1000)
79         waitForIdleSync()
80 
81         assertThat(biometricView.isAuthenticated).isTrue()
82         verify(callback).onAction(AuthBiometricView.Callback.ACTION_AUTHENTICATED)
83     }
84 
85     @Test
faceSuccessRequiresExplicitConfirmationnull86     fun faceSuccessRequiresExplicitConfirmation() {
87         biometricView.onDialogAnimatedIn(fingerprintWasStarted = true)
88         biometricView.onAuthenticationSucceeded(TYPE_FACE)
89         waitForIdleSync()
90 
91         assertThat(biometricView.isAuthenticated).isFalse()
92         assertThat(biometricView.isAuthenticating).isFalse()
93         assertThat(biometricView.mConfirmButton.visibility).isEqualTo(View.GONE)
94         verify(callback, never()).onAction(AuthBiometricView.Callback.ACTION_AUTHENTICATED)
95 
96         // icon acts as confirm button
97         biometricView.mIconView.performClick()
98         TestableLooper.get(this).moveTimeForward(1000)
99         waitForIdleSync()
100 
101         assertThat(biometricView.isAuthenticated).isTrue()
102         verify(callback).onAction(AuthBiometricView.Callback.ACTION_AUTHENTICATED_AND_CONFIRMED)
103     }
104 
105     @Test
ignoresFaceErrors_faceIsNotClass3_notLockoutErrornull106     fun ignoresFaceErrors_faceIsNotClass3_notLockoutError() {
107         biometricView.onDialogAnimatedIn(fingerprintWasStarted = true)
108         biometricView.onError(TYPE_FACE, "not a face")
109         waitForIdleSync()
110 
111         assertThat(biometricView.isAuthenticating).isTrue()
112         verify(callback, never()).onAction(AuthBiometricView.Callback.ACTION_ERROR)
113 
114         biometricView.onError(TYPE_FINGERPRINT, "that's a nope")
115         TestableLooper.get(this).moveTimeForward(1000)
116         waitForIdleSync()
117 
118         verify(callback).onAction(AuthBiometricView.Callback.ACTION_ERROR)
119     }
120 
121     @Test
doNotIgnoresFaceErrors_faceIsClass3_notLockoutErrornull122     fun doNotIgnoresFaceErrors_faceIsClass3_notLockoutError() {
123         biometricView.isFaceClass3 = true
124         biometricView.onDialogAnimatedIn(fingerprintWasStarted = true)
125         biometricView.onError(TYPE_FACE, "not a face")
126         waitForIdleSync()
127 
128         assertThat(biometricView.isAuthenticating).isTrue()
129         verify(callback, never()).onAction(AuthBiometricView.Callback.ACTION_ERROR)
130 
131         biometricView.onError(TYPE_FINGERPRINT, "that's a nope")
132         TestableLooper.get(this).moveTimeForward(1000)
133         waitForIdleSync()
134 
135         verify(callback).onAction(AuthBiometricView.Callback.ACTION_ERROR)
136     }
137 
138     @Test
doNotIgnoresFaceErrors_faceIsClass3_lockoutErrornull139     fun doNotIgnoresFaceErrors_faceIsClass3_lockoutError() {
140         biometricView.isFaceClass3 = true
141         biometricView.onDialogAnimatedIn(fingerprintWasStarted = true)
142         biometricView.onError(
143             TYPE_FACE,
144             FaceManager.getErrorString(
145                 biometricView.context,
146                 BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT,
147                 0 /*vendorCode */
148             )
149         )
150         waitForIdleSync()
151 
152         assertThat(biometricView.isAuthenticating).isTrue()
153         verify(callback).onAction(AuthBiometricView.Callback.ACTION_ERROR)
154 
155         biometricView.onError(TYPE_FINGERPRINT, "that's a nope")
156         TestableLooper.get(this).moveTimeForward(1000)
157         waitForIdleSync()
158 
159         verify(callback, times(2)).onAction(AuthBiometricView.Callback.ACTION_ERROR)
160     }
161 
162 
waitForIdleSyncnull163     override fun waitForIdleSync() = TestableLooper.get(this).processAllMessages()
164 }
165