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 package com.android.server.biometrics;
18 
19 import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE;
20 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
21 
22 import static com.android.server.biometrics.sensors.LockoutTracker.LOCKOUT_NONE;
23 
24 import static com.google.common.truth.Truth.assertThat;
25 
26 import static org.mockito.ArgumentMatchers.any;
27 import static org.mockito.ArgumentMatchers.anyInt;
28 import static org.mockito.Mockito.when;
29 
30 import android.app.admin.DevicePolicyManager;
31 import android.app.trust.ITrustManager;
32 import android.content.Context;
33 import android.hardware.biometrics.BiometricManager;
34 import android.hardware.biometrics.IBiometricAuthenticator;
35 import android.hardware.biometrics.PromptInfo;
36 import android.os.RemoteException;
37 import android.platform.test.annotations.Presubmit;
38 
39 import androidx.test.filters.SmallTest;
40 
41 import org.junit.Before;
42 import org.junit.Rule;
43 import org.junit.Test;
44 import org.mockito.Mock;
45 import org.mockito.junit.MockitoJUnit;
46 import org.mockito.junit.MockitoRule;
47 
48 import java.util.List;
49 
50 @Presubmit
51 @SmallTest
52 public class PreAuthInfoTest {
53     @Rule
54     public final MockitoRule mMockitoRule = MockitoJUnit.rule();
55 
56     private static final int SENSOR_ID_FACE = 1;
57     private static final String TEST_PACKAGE_NAME = "PreAuthInfoTestPackage";
58 
59     @Mock
60     IBiometricAuthenticator mFaceAuthenticator;
61     @Mock
62     Context mContext;
63     @Mock
64     ITrustManager mTrustManager;
65     @Mock
66     DevicePolicyManager mDevicePolicyManager;
67     @Mock
68     BiometricService.SettingObserver mSettingObserver;
69     @Mock
70     BiometricCameraManager mBiometricCameraManager;
71 
72     @Before
setup()73     public void setup() throws RemoteException {
74         when(mTrustManager.isDeviceSecure(anyInt(), anyInt())).thenReturn(true);
75         when(mDevicePolicyManager.getKeyguardDisabledFeatures(any(), anyInt()))
76                 .thenReturn(KEYGUARD_DISABLE_FEATURES_NONE);
77         when(mSettingObserver.getEnabledForApps(anyInt())).thenReturn(true);
78         when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
79         when(mFaceAuthenticator.isHardwareDetected(any())).thenReturn(true);
80         when(mFaceAuthenticator.getLockoutModeForUser(anyInt()))
81                 .thenReturn(LOCKOUT_NONE);
82         when(mBiometricCameraManager.isCameraPrivacyEnabled()).thenReturn(false);
83         when(mBiometricCameraManager.isAnyCameraUnavailable()).thenReturn(false);
84     }
85 
86     @Test
testFaceAuthentication_whenCameraPrivacyIsEnabled()87     public void testFaceAuthentication_whenCameraPrivacyIsEnabled() throws Exception {
88         when(mBiometricCameraManager.isCameraPrivacyEnabled()).thenReturn(true);
89 
90         BiometricSensor sensor = new BiometricSensor(mContext, SENSOR_ID_FACE, TYPE_FACE,
91                 BiometricManager.Authenticators.BIOMETRIC_STRONG, mFaceAuthenticator) {
92             @Override
93             boolean confirmationAlwaysRequired(int userId) {
94                 return false;
95             }
96 
97             @Override
98             boolean confirmationSupported() {
99                 return false;
100             }
101         };
102         PromptInfo promptInfo = new PromptInfo();
103         promptInfo.setConfirmationRequested(false /* requireConfirmation */);
104         promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG);
105         promptInfo.setDisallowBiometricsIfPolicyExists(false /* checkDevicePolicy */);
106         PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager,
107                 mSettingObserver, List.of(sensor),
108                 0 /* userId */, promptInfo, TEST_PACKAGE_NAME,
109                 false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager);
110 
111         assertThat(preAuthInfo.eligibleSensors).isEmpty();
112     }
113 
114     @Test
testFaceAuthentication_whenCameraPrivacyIsDisabledAndCameraIsAvailable()115     public void testFaceAuthentication_whenCameraPrivacyIsDisabledAndCameraIsAvailable()
116             throws Exception {
117         BiometricSensor sensor = new BiometricSensor(mContext, SENSOR_ID_FACE, TYPE_FACE,
118                 BiometricManager.Authenticators.BIOMETRIC_STRONG, mFaceAuthenticator) {
119             @Override
120             boolean confirmationAlwaysRequired(int userId) {
121                 return false;
122             }
123 
124             @Override
125             boolean confirmationSupported() {
126                 return false;
127             }
128         };
129         PromptInfo promptInfo = new PromptInfo();
130         promptInfo.setConfirmationRequested(false /* requireConfirmation */);
131         promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG);
132         promptInfo.setDisallowBiometricsIfPolicyExists(false /* checkDevicePolicy */);
133         PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager,
134                 mSettingObserver, List.of(sensor),
135                 0 /* userId */, promptInfo, TEST_PACKAGE_NAME,
136                 false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager);
137 
138         assertThat(preAuthInfo.eligibleSensors).hasSize(1);
139     }
140 
141     @Test
testFaceAuthentication_whenCameraIsUnavailable()142     public void testFaceAuthentication_whenCameraIsUnavailable() throws RemoteException {
143         when(mBiometricCameraManager.isAnyCameraUnavailable()).thenReturn(true);
144         BiometricSensor sensor = new BiometricSensor(mContext, SENSOR_ID_FACE, TYPE_FACE,
145                 BiometricManager.Authenticators.BIOMETRIC_STRONG, mFaceAuthenticator) {
146             @Override
147             boolean confirmationAlwaysRequired(int userId) {
148                 return false;
149             }
150 
151             @Override
152             boolean confirmationSupported() {
153                 return false;
154             }
155         };
156         PromptInfo promptInfo = new PromptInfo();
157         promptInfo.setConfirmationRequested(false /* requireConfirmation */);
158         promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG);
159         promptInfo.setDisallowBiometricsIfPolicyExists(false /* checkDevicePolicy */);
160         PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager,
161                 mSettingObserver, List.of(sensor),
162                 0 /* userId */, promptInfo, TEST_PACKAGE_NAME,
163                 false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager);
164 
165         assertThat(preAuthInfo.eligibleSensors).hasSize(0);
166     }
167 }
168