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.settings.safetycenter;
18 
19 import static android.provider.Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS;
20 import static android.safetycenter.SafetyEvent.SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED;
21 
22 import static com.google.common.truth.Truth.assertThat;
23 
24 import static org.mockito.ArgumentMatchers.any;
25 import static org.mockito.ArgumentMatchers.anyInt;
26 import static org.mockito.ArgumentMatchers.eq;
27 import static org.mockito.Mockito.doReturn;
28 import static org.mockito.Mockito.never;
29 import static org.mockito.Mockito.spy;
30 import static org.mockito.Mockito.verify;
31 import static org.mockito.Mockito.when;
32 
33 import android.app.admin.DevicePolicyManager;
34 import android.content.ComponentName;
35 import android.content.Context;
36 import android.content.Intent;
37 import android.content.pm.PackageManager;
38 import android.hardware.face.FaceManager;
39 import android.hardware.fingerprint.Fingerprint;
40 import android.hardware.fingerprint.FingerprintManager;
41 import android.os.UserHandle;
42 import android.safetycenter.SafetyEvent;
43 import android.safetycenter.SafetySourceData;
44 import android.safetycenter.SafetySourceStatus;
45 
46 import androidx.test.core.app.ApplicationProvider;
47 import androidx.test.ext.junit.runners.AndroidJUnit4;
48 
49 import com.android.internal.widget.LockPatternUtils;
50 import com.android.settings.Settings;
51 import com.android.settings.biometrics.face.FaceEnrollIntroductionInternal;
52 import com.android.settings.biometrics.fingerprint.FingerprintSettings;
53 import com.android.settings.testutils.ActiveUnlockTestUtils;
54 import com.android.settings.testutils.FakeFeatureFactory;
55 import com.android.settings.testutils.ResourcesUtils;
56 import com.android.settingslib.utils.StringUtil;
57 
58 import org.junit.After;
59 import org.junit.Before;
60 import org.junit.Test;
61 import org.junit.runner.RunWith;
62 import org.mockito.ArgumentCaptor;
63 import org.mockito.Mock;
64 import org.mockito.MockitoAnnotations;
65 
66 import java.util.ArrayList;
67 import java.util.Collections;
68 import java.util.List;
69 
70 @RunWith(AndroidJUnit4.class)
71 public class BiometricsSafetySourceTest {
72 
73     private static final ComponentName COMPONENT_NAME = new ComponentName("package", "class");
74     private static final UserHandle USER_HANDLE = new UserHandle(UserHandle.myUserId());
75     private static final SafetyEvent EVENT_SOURCE_STATE_CHANGED =
76             new SafetyEvent.Builder(SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED).build();
77 
78     private Context mApplicationContext;
79 
80     @Mock private PackageManager mPackageManager;
81     @Mock private DevicePolicyManager mDevicePolicyManager;
82     @Mock private FingerprintManager mFingerprintManager;
83     @Mock private FaceManager mFaceManager;
84     @Mock private LockPatternUtils mLockPatternUtils;
85     @Mock private SafetyCenterManagerWrapper mSafetyCenterManagerWrapper;
86 
87     @Before
setUp()88     public void setUp() {
89         MockitoAnnotations.initMocks(this);
90         mApplicationContext = spy(ApplicationProvider.getApplicationContext());
91         when(mApplicationContext.getPackageManager()).thenReturn(mPackageManager);
92         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)).thenReturn(true);
93         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true);
94         when(mDevicePolicyManager.getProfileOwnerOrDeviceOwnerSupervisionComponent(USER_HANDLE))
95                 .thenReturn(COMPONENT_NAME);
96         when(mApplicationContext.getSystemService(Context.FINGERPRINT_SERVICE))
97                 .thenReturn(mFingerprintManager);
98         when(mApplicationContext.getSystemService(Context.DEVICE_POLICY_SERVICE))
99                 .thenReturn(mDevicePolicyManager);
100         when(mApplicationContext.getSystemService(Context.FACE_SERVICE)).thenReturn(mFaceManager);
101         FakeFeatureFactory featureFactory = FakeFeatureFactory.setupForTest();
102         when(featureFactory.securityFeatureProvider.getLockPatternUtils(mApplicationContext))
103                 .thenReturn(mLockPatternUtils);
104         doReturn(true).when(mLockPatternUtils).isSecure(anyInt());
105         SafetyCenterManagerWrapper.sInstance = mSafetyCenterManagerWrapper;
106     }
107 
108     @After
tearDown()109     public void tearDown() {
110         SafetyCenterManagerWrapper.sInstance = null;
111     }
112 
113     @Test
setSafetyData_whenSafetyCenterIsDisabled_doesNotSetData()114     public void setSafetyData_whenSafetyCenterIsDisabled_doesNotSetData() {
115         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(false);
116 
117         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
118 
119         verify(mSafetyCenterManagerWrapper, never())
120                 .setSafetySourceData(any(), any(), any(), any());
121     }
122 
123     @Test
setSafetySourceData_whenSafetyCenterIsEnabled_withoutBiometrics_setsNullData()124     public void setSafetySourceData_whenSafetyCenterIsEnabled_withoutBiometrics_setsNullData() {
125         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
126         when(mFingerprintManager.isHardwareDetected()).thenReturn(false);
127         when(mFaceManager.isHardwareDetected()).thenReturn(false);
128 
129         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
130 
131         verify(mSafetyCenterManagerWrapper)
132                 .setSafetySourceData(
133                         any(), eq(BiometricsSafetySource.SAFETY_SOURCE_ID), eq(null), any());
134     }
135 
136     @Test
setSafetySourceData_setsDataForBiometricSource()137     public void setSafetySourceData_setsDataForBiometricSource() {
138         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
139         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
140         when(mFaceManager.isHardwareDetected()).thenReturn(false);
141         when(mFingerprintManager.hasEnrolledFingerprints(anyInt())).thenReturn(false);
142         when(mDevicePolicyManager.getKeyguardDisabledFeatures(COMPONENT_NAME)).thenReturn(0);
143 
144         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
145 
146         verify(mSafetyCenterManagerWrapper)
147                 .setSafetySourceData(
148                         any(), eq(BiometricsSafetySource.SAFETY_SOURCE_ID), any(), any());
149     }
150 
151     @Test
setSafetySourceData_setsDataWithCorrectSafetyEvent()152     public void setSafetySourceData_setsDataWithCorrectSafetyEvent() {
153         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
154         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
155         when(mFaceManager.isHardwareDetected()).thenReturn(false);
156         when(mFingerprintManager.hasEnrolledFingerprints(anyInt())).thenReturn(false);
157         when(mDevicePolicyManager.getKeyguardDisabledFeatures(COMPONENT_NAME)).thenReturn(0);
158 
159         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
160 
161         verify(mSafetyCenterManagerWrapper)
162                 .setSafetySourceData(any(), any(), any(), eq(EVENT_SOURCE_STATE_CHANGED));
163     }
164 
165     @Test
setSafetySourceData_withFingerprintNotEnrolled_whenDisabledByAdmin_setsData()166     public void setSafetySourceData_withFingerprintNotEnrolled_whenDisabledByAdmin_setsData() {
167         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
168         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
169         when(mFaceManager.isHardwareDetected()).thenReturn(false);
170         when(mFingerprintManager.hasEnrolledFingerprints(anyInt())).thenReturn(false);
171         when(mDevicePolicyManager.getKeyguardDisabledFeatures(COMPONENT_NAME))
172                 .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT);
173 
174         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
175 
176         assertSafetySourceDisabledDataSetWithSingularSummary(
177                 "security_settings_fingerprint_preference_title",
178                 "security_settings_fingerprint_preference_summary_none");
179     }
180 
181     @Test
setSafetySourceData_withFingerprintNotEnrolled_whenNotDisabledByAdmin_setsData()182     public void setSafetySourceData_withFingerprintNotEnrolled_whenNotDisabledByAdmin_setsData() {
183         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
184         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
185         when(mFaceManager.isHardwareDetected()).thenReturn(false);
186         when(mFingerprintManager.hasEnrolledFingerprints(anyInt())).thenReturn(false);
187         when(mDevicePolicyManager.getKeyguardDisabledFeatures(COMPONENT_NAME)).thenReturn(0);
188 
189         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
190 
191         assertSafetySourceEnabledDataSetWithSingularSummary(
192                 "security_settings_fingerprint_preference_title",
193                 "security_settings_fingerprint_preference_summary_none",
194                 FingerprintSettings.class.getName());
195     }
196 
197     @Test
setSafetySourceData_withFingerprintsEnrolled_whenDisabledByAdmin_setsData()198     public void setSafetySourceData_withFingerprintsEnrolled_whenDisabledByAdmin_setsData() {
199         final int enrolledFingerprintsCount = 2;
200         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
201         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
202         when(mFaceManager.isHardwareDetected()).thenReturn(false);
203         when(mFingerprintManager.hasEnrolledFingerprints(anyInt())).thenReturn(true);
204         when(mFingerprintManager.getEnrolledFingerprints(anyInt()))
205                 .thenReturn(createFingerprintList(enrolledFingerprintsCount));
206         when(mDevicePolicyManager.getKeyguardDisabledFeatures(COMPONENT_NAME))
207                 .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT);
208 
209         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
210 
211         assertSafetySourceDisabledDataSetWithPluralSummary(
212                 "security_settings_fingerprint_preference_title",
213                 "security_settings_fingerprint_preference_summary",
214                 enrolledFingerprintsCount);
215     }
216 
217     @Test
setSafetySourceData_withFingerprintsEnrolled_whenNotDisabledByAdmin_setsData()218     public void setSafetySourceData_withFingerprintsEnrolled_whenNotDisabledByAdmin_setsData() {
219         final int enrolledFingerprintsCount = 2;
220         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
221         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
222         when(mFaceManager.isHardwareDetected()).thenReturn(false);
223         when(mFingerprintManager.hasEnrolledFingerprints(anyInt())).thenReturn(true);
224         when(mFingerprintManager.getEnrolledFingerprints(anyInt()))
225                 .thenReturn(createFingerprintList(enrolledFingerprintsCount));
226         when(mDevicePolicyManager.getKeyguardDisabledFeatures(COMPONENT_NAME)).thenReturn(0);
227 
228         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
229 
230         assertSafetySourceEnabledDataSetWithPluralSummary(
231                 "security_settings_fingerprint_preference_title",
232                 "security_settings_fingerprint_preference_summary",
233                 enrolledFingerprintsCount,
234                 FingerprintSettings.class.getName());
235     }
236 
237     @Test
setSafetySourceData_withFaceNotEnrolled_whenDisabledByAdmin_setsData()238     public void setSafetySourceData_withFaceNotEnrolled_whenDisabledByAdmin_setsData() {
239         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
240         when(mFingerprintManager.isHardwareDetected()).thenReturn(false);
241         when(mFaceManager.isHardwareDetected()).thenReturn(true);
242         when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(false);
243         when(mDevicePolicyManager.getKeyguardDisabledFeatures(COMPONENT_NAME))
244                 .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FACE);
245 
246         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
247 
248         assertSafetySourceDisabledDataSetWithSingularSummary(
249                 "security_settings_face_preference_title",
250                 "security_settings_face_preference_summary_none");
251     }
252 
253     @Test
setSafetySourceData_withFaceNotEnrolled_whenNotDisabledByAdmin_setsData()254     public void setSafetySourceData_withFaceNotEnrolled_whenNotDisabledByAdmin_setsData() {
255         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
256         when(mFingerprintManager.isHardwareDetected()).thenReturn(false);
257         when(mFaceManager.isHardwareDetected()).thenReturn(true);
258         when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(false);
259         when(mDevicePolicyManager.getKeyguardDisabledFeatures(COMPONENT_NAME)).thenReturn(0);
260 
261         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
262 
263         assertSafetySourceEnabledDataSetWithSingularSummary(
264                 "security_settings_face_preference_title",
265                 "security_settings_face_preference_summary_none",
266                 FaceEnrollIntroductionInternal.class.getName());
267     }
268 
269     @Test
setSafetySourceData_withFaceEnrolled_whenDisabledByAdmin_setsData()270     public void setSafetySourceData_withFaceEnrolled_whenDisabledByAdmin_setsData() {
271         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
272         when(mFingerprintManager.isHardwareDetected()).thenReturn(false);
273         when(mFaceManager.isHardwareDetected()).thenReturn(true);
274         when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(true);
275         when(mDevicePolicyManager.getKeyguardDisabledFeatures(COMPONENT_NAME))
276                 .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FACE);
277 
278         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
279 
280         assertSafetySourceDisabledDataSetWithSingularSummary(
281                 "security_settings_face_preference_title",
282                 "security_settings_face_preference_summary");
283     }
284 
285     @Test
setSafetySourceData_withFaceEnrolled_whenNotDisabledByAdmin_setsData()286     public void setSafetySourceData_withFaceEnrolled_whenNotDisabledByAdmin_setsData() {
287         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
288         when(mFingerprintManager.isHardwareDetected()).thenReturn(false);
289         when(mFaceManager.isHardwareDetected()).thenReturn(true);
290         when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(true);
291         when(mDevicePolicyManager.getKeyguardDisabledFeatures(COMPONENT_NAME)).thenReturn(0);
292 
293         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
294 
295         assertSafetySourceEnabledDataSetWithSingularSummary(
296                 "security_settings_face_preference_title",
297                 "security_settings_face_preference_summary",
298                 Settings.FaceSettingsInternalActivity.class.getName());
299     }
300 
301     @Test
setSafetySourceData_withFaceAndFingerprint_whenBothNotDisabledByAdmin_setsData()302     public void setSafetySourceData_withFaceAndFingerprint_whenBothNotDisabledByAdmin_setsData() {
303         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
304         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
305         when(mFaceManager.isHardwareDetected()).thenReturn(true);
306         when(mDevicePolicyManager.getKeyguardDisabledFeatures(COMPONENT_NAME)).thenReturn(0);
307 
308         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
309 
310         assertSafetySourceEnabledDataSetWithSingularSummary(
311                 "security_settings_biometric_preference_title",
312                 "security_settings_biometric_preference_summary_none_enrolled",
313                 Settings.CombinedBiometricSettingsActivity.class.getName());
314     }
315 
316     @Test
setSafetySourceData_withFaceAndFingerprint_whenFaceDisabledByAdmin_setsData()317     public void setSafetySourceData_withFaceAndFingerprint_whenFaceDisabledByAdmin_setsData() {
318         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
319         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
320         when(mFaceManager.isHardwareDetected()).thenReturn(true);
321         when(mDevicePolicyManager.getKeyguardDisabledFeatures(COMPONENT_NAME))
322                 .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FACE);
323 
324         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
325 
326         assertSafetySourceEnabledDataSetWithSingularSummary(
327                 "security_settings_biometric_preference_title",
328                 "security_settings_biometric_preference_summary_none_enrolled",
329                 Settings.CombinedBiometricSettingsActivity.class.getName());
330     }
331 
332     @Test
setSafetySourceData_faceAndFingerprint_whenFingerprintDisabledByAdmin_setsData()333     public void setSafetySourceData_faceAndFingerprint_whenFingerprintDisabledByAdmin_setsData() {
334         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
335         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
336         when(mFaceManager.isHardwareDetected()).thenReturn(true);
337         when(mDevicePolicyManager.getKeyguardDisabledFeatures(COMPONENT_NAME))
338                 .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT);
339 
340         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
341 
342         assertSafetySourceEnabledDataSetWithSingularSummary(
343                 "security_settings_biometric_preference_title",
344                 "security_settings_biometric_preference_summary_none_enrolled",
345                 Settings.CombinedBiometricSettingsActivity.class.getName());
346     }
347 
348     @Test
setSafetySourceData_faceAndFingerprint_whenBothDisabledByAdmin_setsData()349     public void setSafetySourceData_faceAndFingerprint_whenBothDisabledByAdmin_setsData() {
350         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
351         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
352         when(mFaceManager.isHardwareDetected()).thenReturn(true);
353         when(mDevicePolicyManager.getKeyguardDisabledFeatures(COMPONENT_NAME))
354                 .thenReturn(
355                         DevicePolicyManager.KEYGUARD_DISABLE_FACE
356                                 | DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT);
357 
358         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
359 
360         assertSafetySourceDisabledDataSetWithSingularSummary(
361                 "security_settings_biometric_preference_title",
362                 "security_settings_biometric_preference_summary_none_enrolled");
363     }
364 
365     @Test
setSafetySourceData_faceAndFingerprint_whenFaceEnrolled_withMpFingers_setsData()366     public void setSafetySourceData_faceAndFingerprint_whenFaceEnrolled_withMpFingers_setsData() {
367         final int enrolledFingerprintsCount = 2;
368         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
369         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
370         when(mFaceManager.isHardwareDetected()).thenReturn(true);
371         when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(true);
372         when(mFingerprintManager.getEnrolledFingerprints(anyInt()))
373                 .thenReturn(createFingerprintList(enrolledFingerprintsCount));
374 
375         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
376 
377         assertSafetySourceEnabledDataSetWithSingularSummary(
378                 "security_settings_biometric_preference_title",
379                 "security_settings_biometric_preference_summary_both_fp_multiple",
380                 Settings.CombinedBiometricSettingsActivity.class.getName());
381     }
382 
383     @Test
setSafetySourceData_faceAndFingerprint_whenFaceEnrolled_withOneFinger_setsData()384     public void setSafetySourceData_faceAndFingerprint_whenFaceEnrolled_withOneFinger_setsData() {
385         final int enrolledFingerprintsCount = 1;
386         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
387         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
388         when(mFaceManager.isHardwareDetected()).thenReturn(true);
389         when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(true);
390         when(mFingerprintManager.getEnrolledFingerprints(anyInt()))
391                 .thenReturn(createFingerprintList(enrolledFingerprintsCount));
392 
393         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
394 
395         assertSafetySourceEnabledDataSetWithSingularSummary(
396                 "security_settings_biometric_preference_title",
397                 "security_settings_biometric_preference_summary_both_fp_single",
398                 Settings.CombinedBiometricSettingsActivity.class.getName());
399     }
400 
401     @Test
setSafetySourceData_faceAndFingerprint_whenFaceEnrolled_withNoFingers_setsData()402     public void setSafetySourceData_faceAndFingerprint_whenFaceEnrolled_withNoFingers_setsData() {
403         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
404         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
405         when(mFaceManager.isHardwareDetected()).thenReturn(true);
406         when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(true);
407         when(mFingerprintManager.getEnrolledFingerprints(anyInt()))
408                 .thenReturn(Collections.emptyList());
409 
410         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
411 
412         assertSafetySourceEnabledDataSetWithSingularSummary(
413                 "security_settings_biometric_preference_title",
414                 "security_settings_face_preference_summary",
415                 Settings.CombinedBiometricSettingsActivity.class.getName());
416     }
417 
418     @Test
setSafetySourceData_activeUnlockEnabled_withFingerprintOnly_setsData()419     public void setSafetySourceData_activeUnlockEnabled_withFingerprintOnly_setsData() {
420         final int enrolledFingerprintsCount = 1;
421         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
422         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
423         when(mFaceManager.isHardwareDetected()).thenReturn(false);
424         when(mFingerprintManager.getEnrolledFingerprints(anyInt()))
425                 .thenReturn(createFingerprintList(enrolledFingerprintsCount));
426 
427         ActiveUnlockTestUtils.enable(mApplicationContext);
428 
429         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
430 
431         assertSafetySourceEnabledDataSetWithPluralSummary(
432                 "security_settings_fingerprint_preference_title",
433                 "security_settings_fingerprint_preference_summary",
434                 enrolledFingerprintsCount,
435                 Settings.CombinedBiometricSettingsActivity.class.getName());
436     }
437 
438     @Test
setSafetySourceData_activeUnlockEnabled_withFaceOnly_setsData()439     public void setSafetySourceData_activeUnlockEnabled_withFaceOnly_setsData() {
440         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
441         when(mFingerprintManager.isHardwareDetected()).thenReturn(false);
442         when(mFaceManager.isHardwareDetected()).thenReturn(true);
443         when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(true);
444         ActiveUnlockTestUtils.enable(mApplicationContext);
445 
446         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
447 
448         assertSafetySourceEnabledDataSetWithSingularSummary(
449                 "security_settings_face_preference_title",
450                 "security_settings_face_preference_summary",
451                 Settings.CombinedBiometricSettingsActivity.class.getName());
452     }
453 
454     @Test
setSafetySourceData_activeUnlockEnabled_withFaceAndFingerprint_setsData()455     public void setSafetySourceData_activeUnlockEnabled_withFaceAndFingerprint_setsData() {
456         final int enrolledFingerprintsCount = 1;
457         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
458         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
459         when(mFaceManager.isHardwareDetected()).thenReturn(true);
460         when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(true);
461         when(mFingerprintManager.getEnrolledFingerprints(anyInt()))
462                 .thenReturn(createFingerprintList(enrolledFingerprintsCount));
463         ActiveUnlockTestUtils.enable(mApplicationContext);
464 
465         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
466 
467         assertSafetySourceEnabledDataSetWithSingularSummary(
468                 "security_settings_biometric_preference_title",
469                 "security_settings_biometric_preference_summary_both_fp_single",
470                 Settings.CombinedBiometricSettingsActivity.class.getName());
471     }
472 
473     @Test
setSafetySourceData_faceAndFingerprint_whenNoFaceEnrolled_withFingers_setsData()474     public void setSafetySourceData_faceAndFingerprint_whenNoFaceEnrolled_withFingers_setsData() {
475         final int enrolledFingerprintsCount = 1;
476         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
477         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
478         when(mFaceManager.isHardwareDetected()).thenReturn(true);
479         when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(false);
480         when(mFingerprintManager.getEnrolledFingerprints(anyInt()))
481                 .thenReturn(createFingerprintList(enrolledFingerprintsCount));
482 
483         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
484 
485         assertSafetySourceEnabledDataSetWithPluralSummary(
486                 "security_settings_biometric_preference_title",
487                 "security_settings_fingerprint_preference_summary",
488                 enrolledFingerprintsCount,
489                 Settings.CombinedBiometricSettingsActivity.class.getName());
490     }
491 
492     @Test
setSafetySourceData_faceAndFingerprint_whenFaceEnrolled_setsInfoSeverity()493     public void setSafetySourceData_faceAndFingerprint_whenFaceEnrolled_setsInfoSeverity() {
494         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
495         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
496         when(mFaceManager.isHardwareDetected()).thenReturn(true);
497         when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(true);
498         when(mFingerprintManager.hasEnrolledFingerprints(anyInt())).thenReturn(false);
499 
500         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
501 
502         ArgumentCaptor<SafetySourceData> captor = ArgumentCaptor.forClass(SafetySourceData.class);
503         verify(mSafetyCenterManagerWrapper)
504                 .setSafetySourceData(
505                         any(),
506                         eq(BiometricsSafetySource.SAFETY_SOURCE_ID),
507                         captor.capture(),
508                         any());
509         SafetySourceStatus safetySourceStatus = captor.getValue().getStatus();
510         assertThat(safetySourceStatus.getSeverityLevel())
511                 .isEqualTo(SafetySourceData.SEVERITY_LEVEL_INFORMATION);
512     }
513 
514     @Test
setSafetySourceData_faceAndFingerprint_whenFingerprintEnrolled_setsInfoSeverity()515     public void setSafetySourceData_faceAndFingerprint_whenFingerprintEnrolled_setsInfoSeverity() {
516         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
517         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
518         when(mFaceManager.isHardwareDetected()).thenReturn(true);
519         when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(false);
520         when(mFingerprintManager.hasEnrolledFingerprints(anyInt())).thenReturn(true);
521 
522         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
523 
524         ArgumentCaptor<SafetySourceData> captor = ArgumentCaptor.forClass(SafetySourceData.class);
525         verify(mSafetyCenterManagerWrapper)
526                 .setSafetySourceData(
527                         any(),
528                         eq(BiometricsSafetySource.SAFETY_SOURCE_ID),
529                         captor.capture(),
530                         any());
531         SafetySourceStatus safetySourceStatus = captor.getValue().getStatus();
532         assertThat(safetySourceStatus.getSeverityLevel())
533                 .isEqualTo(SafetySourceData.SEVERITY_LEVEL_INFORMATION);
534     }
535 
536     @Test
setSafetySourceData_faceAndFingerprint_whenNotEnrolled_setsUnspSeverity()537     public void setSafetySourceData_faceAndFingerprint_whenNotEnrolled_setsUnspSeverity() {
538         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
539         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
540         when(mFaceManager.isHardwareDetected()).thenReturn(true);
541         when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(false);
542         when(mFingerprintManager.hasEnrolledFingerprints(anyInt())).thenReturn(false);
543 
544         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
545 
546         ArgumentCaptor<SafetySourceData> captor = ArgumentCaptor.forClass(SafetySourceData.class);
547         verify(mSafetyCenterManagerWrapper)
548                 .setSafetySourceData(
549                         any(),
550                         eq(BiometricsSafetySource.SAFETY_SOURCE_ID),
551                         captor.capture(),
552                         any());
553         SafetySourceStatus safetySourceStatus = captor.getValue().getStatus();
554         assertThat(safetySourceStatus.getSeverityLevel())
555                 .isEqualTo(SafetySourceData.SEVERITY_LEVEL_UNSPECIFIED);
556     }
557 
558     @Test
setSafetySourceData_fingerprint_whenEnrolled_setsInfoSeverity()559     public void setSafetySourceData_fingerprint_whenEnrolled_setsInfoSeverity() {
560         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
561         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
562         when(mFaceManager.isHardwareDetected()).thenReturn(false);
563         when(mFingerprintManager.hasEnrolledFingerprints(anyInt())).thenReturn(true);
564 
565         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
566 
567         ArgumentCaptor<SafetySourceData> captor = ArgumentCaptor.forClass(SafetySourceData.class);
568         verify(mSafetyCenterManagerWrapper)
569                 .setSafetySourceData(
570                         any(),
571                         eq(BiometricsSafetySource.SAFETY_SOURCE_ID),
572                         captor.capture(),
573                         any());
574         SafetySourceStatus safetySourceStatus = captor.getValue().getStatus();
575         assertThat(safetySourceStatus.getSeverityLevel())
576                 .isEqualTo(SafetySourceData.SEVERITY_LEVEL_INFORMATION);
577     }
578 
579     @Test
setSafetySourceData_fingerprint_whenNotEnrolled_setsUnspSeverity()580     public void setSafetySourceData_fingerprint_whenNotEnrolled_setsUnspSeverity() {
581         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
582         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
583         when(mFaceManager.isHardwareDetected()).thenReturn(false);
584         when(mFingerprintManager.hasEnrolledFingerprints(anyInt())).thenReturn(false);
585 
586         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
587 
588         ArgumentCaptor<SafetySourceData> captor = ArgumentCaptor.forClass(SafetySourceData.class);
589         verify(mSafetyCenterManagerWrapper)
590                 .setSafetySourceData(
591                         any(),
592                         eq(BiometricsSafetySource.SAFETY_SOURCE_ID),
593                         captor.capture(),
594                         any());
595         SafetySourceStatus safetySourceStatus = captor.getValue().getStatus();
596         assertThat(safetySourceStatus.getSeverityLevel())
597                 .isEqualTo(SafetySourceData.SEVERITY_LEVEL_UNSPECIFIED);
598     }
599 
600     @Test
setSafetySourceData_face_whenEnrolled_setsInfoSeverity()601     public void setSafetySourceData_face_whenEnrolled_setsInfoSeverity() {
602         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
603         when(mFingerprintManager.isHardwareDetected()).thenReturn(false);
604         when(mFaceManager.isHardwareDetected()).thenReturn(true);
605         when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(true);
606 
607         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
608 
609         ArgumentCaptor<SafetySourceData> captor = ArgumentCaptor.forClass(SafetySourceData.class);
610         verify(mSafetyCenterManagerWrapper)
611                 .setSafetySourceData(
612                         any(),
613                         eq(BiometricsSafetySource.SAFETY_SOURCE_ID),
614                         captor.capture(),
615                         any());
616         SafetySourceStatus safetySourceStatus = captor.getValue().getStatus();
617         assertThat(safetySourceStatus.getSeverityLevel())
618                 .isEqualTo(SafetySourceData.SEVERITY_LEVEL_INFORMATION);
619     }
620 
621     @Test
setSafetySourceData_face_whenNotEnrolled_setsUnspSeverity()622     public void setSafetySourceData_face_whenNotEnrolled_setsUnspSeverity() {
623         when(mSafetyCenterManagerWrapper.isEnabled(mApplicationContext)).thenReturn(true);
624         when(mFingerprintManager.isHardwareDetected()).thenReturn(false);
625         when(mFaceManager.isHardwareDetected()).thenReturn(true);
626         when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(false);
627 
628         BiometricsSafetySource.setSafetySourceData(mApplicationContext, EVENT_SOURCE_STATE_CHANGED);
629 
630         ArgumentCaptor<SafetySourceData> captor = ArgumentCaptor.forClass(SafetySourceData.class);
631         verify(mSafetyCenterManagerWrapper)
632                 .setSafetySourceData(
633                         any(),
634                         eq(BiometricsSafetySource.SAFETY_SOURCE_ID),
635                         captor.capture(),
636                         any());
637         SafetySourceStatus safetySourceStatus = captor.getValue().getStatus();
638         assertThat(safetySourceStatus.getSeverityLevel())
639                 .isEqualTo(SafetySourceData.SEVERITY_LEVEL_UNSPECIFIED);
640     }
641 
assertSafetySourceDisabledDataSetWithSingularSummary( String expectedTitleResName, String expectedSummaryResName)642     private void assertSafetySourceDisabledDataSetWithSingularSummary(
643             String expectedTitleResName, String expectedSummaryResName) {
644         assertSafetySourceDisabledDataSet(
645                 ResourcesUtils.getResourcesString(mApplicationContext, expectedTitleResName),
646                 ResourcesUtils.getResourcesString(mApplicationContext, expectedSummaryResName));
647     }
648 
assertSafetySourceEnabledDataSetWithSingularSummary( String expectedTitleResName, String expectedSummaryResName, String expectedSettingsClassName)649     private void assertSafetySourceEnabledDataSetWithSingularSummary(
650             String expectedTitleResName,
651             String expectedSummaryResName,
652             String expectedSettingsClassName) {
653         assertSafetySourceEnabledDataSet(
654                 ResourcesUtils.getResourcesString(mApplicationContext, expectedTitleResName),
655                 ResourcesUtils.getResourcesString(mApplicationContext, expectedSummaryResName),
656                 expectedSettingsClassName);
657     }
658 
assertSafetySourceDisabledDataSetWithPluralSummary( String expectedTitleResName, String expectedSummaryResName, int expectedSummaryQuantity)659     private void assertSafetySourceDisabledDataSetWithPluralSummary(
660             String expectedTitleResName,
661             String expectedSummaryResName,
662             int expectedSummaryQuantity) {
663         final int stringResId =
664                 ResourcesUtils.getResourcesId(
665                         ApplicationProvider.getApplicationContext(),
666                         "string",
667                         expectedSummaryResName);
668         assertSafetySourceDisabledDataSet(
669                 ResourcesUtils.getResourcesString(mApplicationContext, expectedTitleResName),
670                 StringUtil.getIcuPluralsString(
671                         mApplicationContext, expectedSummaryQuantity, stringResId));
672     }
673 
assertSafetySourceEnabledDataSetWithPluralSummary( String expectedTitleResName, String expectedSummaryResName, int expectedSummaryQuantity, String expectedSettingsClassName)674     private void assertSafetySourceEnabledDataSetWithPluralSummary(
675             String expectedTitleResName,
676             String expectedSummaryResName,
677             int expectedSummaryQuantity,
678             String expectedSettingsClassName) {
679         final int stringResId =
680                 ResourcesUtils.getResourcesId(
681                         ApplicationProvider.getApplicationContext(),
682                         "string",
683                         expectedSummaryResName);
684         assertSafetySourceEnabledDataSet(
685                 ResourcesUtils.getResourcesString(mApplicationContext, expectedTitleResName),
686                 StringUtil.getIcuPluralsString(
687                         mApplicationContext, expectedSummaryQuantity, stringResId),
688                 expectedSettingsClassName);
689     }
690 
assertSafetySourceDisabledDataSet(String expectedTitle, String expectedSummary)691     private void assertSafetySourceDisabledDataSet(String expectedTitle, String expectedSummary) {
692         ArgumentCaptor<SafetySourceData> captor = ArgumentCaptor.forClass(SafetySourceData.class);
693         verify(mSafetyCenterManagerWrapper)
694                 .setSafetySourceData(
695                         any(),
696                         eq(BiometricsSafetySource.SAFETY_SOURCE_ID),
697                         captor.capture(),
698                         any());
699         SafetySourceData safetySourceData = captor.getValue();
700         SafetySourceStatus safetySourceStatus = safetySourceData.getStatus();
701 
702         assertThat(safetySourceStatus.getTitle().toString()).isEqualTo(expectedTitle);
703         assertThat(safetySourceStatus.getSummary().toString()).isEqualTo(expectedSummary);
704         assertThat(safetySourceStatus.isEnabled()).isFalse();
705         assertThat(safetySourceStatus.getSeverityLevel())
706                 .isEqualTo(SafetySourceData.SEVERITY_LEVEL_UNSPECIFIED);
707 
708         final Intent clickIntent = safetySourceStatus.getPendingIntent().getIntent();
709         assertThat(clickIntent).isNotNull();
710         assertThat(clickIntent.getAction()).isEqualTo(ACTION_SHOW_ADMIN_SUPPORT_DETAILS);
711     }
712 
assertSafetySourceEnabledDataSet( String expectedTitle, String expectedSummary, String expectedSettingsClassName)713     private void assertSafetySourceEnabledDataSet(
714             String expectedTitle, String expectedSummary, String expectedSettingsClassName) {
715         ArgumentCaptor<SafetySourceData> captor = ArgumentCaptor.forClass(SafetySourceData.class);
716         verify(mSafetyCenterManagerWrapper)
717                 .setSafetySourceData(
718                         any(),
719                         eq(BiometricsSafetySource.SAFETY_SOURCE_ID),
720                         captor.capture(),
721                         any());
722         SafetySourceData safetySourceData = captor.getValue();
723         SafetySourceStatus safetySourceStatus = safetySourceData.getStatus();
724 
725         assertThat(safetySourceStatus.getTitle().toString()).isEqualTo(expectedTitle);
726         assertThat(safetySourceStatus.getSummary().toString()).isEqualTo(expectedSummary);
727         assertThat(safetySourceStatus.isEnabled()).isTrue();
728         final Intent clickIntent = safetySourceStatus.getPendingIntent().getIntent();
729         assertThat(clickIntent).isNotNull();
730         assertThat(clickIntent.getComponent().getPackageName()).isEqualTo("com.android.settings");
731         assertThat(clickIntent.getComponent().getClassName()).isEqualTo(expectedSettingsClassName);
732     }
733 
createFingerprintList(int size)734     private List<Fingerprint> createFingerprintList(int size) {
735         final List<Fingerprint> fingerprintList = new ArrayList<>(size);
736         for (int i = 0; i < size; i++) {
737             fingerprintList.add(new Fingerprint("fingerprint" + i, 0, 0));
738         }
739         return fingerprintList;
740     }
741 }
742