• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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;
18 
19 import static android.hardware.biometrics.SensorProperties.STRENGTH_CONVENIENCE;
20 import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG;
21 import static android.hardware.biometrics.SensorProperties.STRENGTH_WEAK;
22 
23 import static com.android.settings.Utils.SETTINGS_PACKAGE_NAME;
24 import static com.android.settings.password.ConfirmDeviceCredentialActivity.BIOMETRIC_PROMPT_AUTHENTICATORS;
25 import static com.android.settings.password.ConfirmDeviceCredentialActivity.BIOMETRIC_PROMPT_HIDE_BACKGROUND;
26 import static com.android.settings.password.ConfirmDeviceCredentialActivity.BIOMETRIC_PROMPT_NEGATIVE_BUTTON_TEXT;
27 
28 import static com.google.common.truth.Truth.assertThat;
29 
30 import static org.junit.Assert.assertNull;
31 import static org.junit.Assert.assertThrows;
32 import static org.mockito.ArgumentMatchers.anyInt;
33 import static org.mockito.ArgumentMatchers.anyString;
34 import static org.mockito.ArgumentMatchers.eq;
35 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
36 import static org.mockito.Mockito.doReturn;
37 import static org.mockito.Mockito.mock;
38 import static org.mockito.Mockito.spy;
39 import static org.mockito.Mockito.verify;
40 import static org.mockito.Mockito.when;
41 
42 import android.app.ActionBar;
43 import android.app.KeyguardManager;
44 import android.app.admin.DevicePolicyManager;
45 import android.app.admin.DevicePolicyResourcesManager;
46 import android.content.ComponentName;
47 import android.content.Context;
48 import android.content.Intent;
49 import android.content.pm.ApplicationInfo;
50 import android.content.pm.PackageManager;
51 import android.content.pm.UserInfo;
52 import android.graphics.Bitmap;
53 import android.graphics.Color;
54 import android.graphics.drawable.BitmapDrawable;
55 import android.graphics.drawable.ColorDrawable;
56 import android.graphics.drawable.VectorDrawable;
57 import android.hardware.biometrics.BiometricManager;
58 import android.hardware.biometrics.Flags;
59 import android.hardware.face.FaceManager;
60 import android.hardware.face.FaceSensorProperties;
61 import android.hardware.face.FaceSensorPropertiesInternal;
62 import android.net.ConnectivityManager;
63 import android.net.LinkAddress;
64 import android.net.LinkProperties;
65 import android.net.Network;
66 import android.net.wifi.WifiManager;
67 import android.os.Bundle;
68 import android.os.UserHandle;
69 import android.os.UserManager;
70 import android.os.storage.DiskInfo;
71 import android.os.storage.StorageManager;
72 import android.os.storage.VolumeInfo;
73 import android.platform.test.annotations.EnableFlags;
74 import android.platform.test.flag.junit.SetFlagsRule;
75 import android.util.IconDrawableFactory;
76 import android.widget.EditText;
77 import android.widget.ScrollView;
78 import android.widget.TextView;
79 
80 import androidx.core.graphics.drawable.IconCompat;
81 import androidx.fragment.app.Fragment;
82 import androidx.fragment.app.FragmentActivity;
83 
84 import com.android.internal.widget.LockPatternUtils;
85 import com.android.settings.password.ChooseLockSettingsHelper;
86 import com.android.settings.password.ConfirmDeviceCredentialActivity;
87 import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
88 
89 import org.junit.After;
90 import org.junit.Before;
91 import org.junit.Rule;
92 import org.junit.Test;
93 import org.junit.runner.RunWith;
94 import org.mockito.ArgumentCaptor;
95 import org.mockito.Mock;
96 import org.mockito.MockitoAnnotations;
97 import org.robolectric.Robolectric;
98 import org.robolectric.RobolectricTestRunner;
99 import org.robolectric.RuntimeEnvironment;
100 import org.robolectric.annotation.Config;
101 import org.robolectric.shadows.ShadowBinder;
102 
103 import java.net.InetAddress;
104 import java.util.ArrayList;
105 import java.util.List;
106 
107 @RunWith(RobolectricTestRunner.class)
108 @Config(shadows = ShadowLockPatternUtils.class)
109 public class UtilsTest {
110 
111     @Rule
112     public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
113 
114     private static final String PACKAGE_NAME = "com.android.app";
115     private static final int USER_ID = 1;
116 
117     @Mock
118     private WifiManager wifiManager;
119     @Mock
120     private Network network;
121     @Mock
122     private ConnectivityManager connectivityManager;
123     @Mock
124     private DevicePolicyManager mDevicePolicyManager;
125     @Mock
126     private DevicePolicyResourcesManager mDevicePolicyResourcesManager;
127     @Mock
128     private UserManager mMockUserManager;
129     @Mock
130     private PackageManager mPackageManager;
131     @Mock
132     private IconDrawableFactory mIconDrawableFactory;
133     @Mock
134     private ApplicationInfo mApplicationInfo;
135     @Mock
136     private BiometricManager mBiometricManager;
137     @Mock
138     private Fragment mFragment;
139 
140     private Context mContext;
141     private UserManager mUserManager;
142     private static final int FLAG_SYSTEM = 0x00000000;
143     private static final int FLAG_MAIN = 0x00004000;
144 
145     @Before
setUp()146     public void setUp() {
147         MockitoAnnotations.initMocks(this);
148 
149         mContext = spy(RuntimeEnvironment.application);
150         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
151         when(mContext.getSystemService(WifiManager.class)).thenReturn(wifiManager);
152         when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE))
153                 .thenReturn(connectivityManager);
154         when(mContext.getPackageManager()).thenReturn(mPackageManager);
155         when(mContext.getSystemService(BiometricManager.class)).thenReturn(mBiometricManager);
156     }
157 
158     @After
tearDown()159     public void tearDown() {
160         ShadowLockPatternUtils.reset();
161     }
162 
163     @Test
getWifiIpAddresses_succeeds()164     public void getWifiIpAddresses_succeeds() throws Exception {
165         when(wifiManager.getCurrentNetwork()).thenReturn(network);
166         LinkAddress address = new LinkAddress(InetAddress.getByName("127.0.0.1"), 0);
167         LinkProperties lp = new LinkProperties();
168         lp.addLinkAddress(address);
169         when(connectivityManager.getLinkProperties(network)).thenReturn(lp);
170 
171         assertThat(Utils.getWifiIpAddresses(mContext)).isEqualTo("127.0.0.1");
172     }
173 
174     @Test
getWifiIpAddresses_nullLinkProperties()175     public void getWifiIpAddresses_nullLinkProperties() {
176         when(wifiManager.getCurrentNetwork()).thenReturn(network);
177         // Explicitly set the return value to null for readability sake.
178         when(connectivityManager.getLinkProperties(network)).thenReturn(null);
179 
180         assertThat(Utils.getWifiIpAddresses(mContext)).isNull();
181     }
182 
183     @Test
getWifiIpAddresses_nullNetwork()184     public void getWifiIpAddresses_nullNetwork() {
185         // Explicitly set the return value to null for readability sake.
186         when(wifiManager.getCurrentNetwork()).thenReturn(null);
187 
188         assertThat(Utils.getWifiIpAddresses(mContext)).isNull();
189     }
190 
191     @Test
initializeVolumeDoesntBreakOnNullVolume()192     public void initializeVolumeDoesntBreakOnNullVolume() {
193         VolumeInfo info = new VolumeInfo("id", 0, new DiskInfo("id", 0), "");
194         StorageManager storageManager = mock(StorageManager.class, RETURNS_DEEP_STUBS);
195         when(storageManager.findVolumeById(anyString())).thenReturn(info);
196 
197         Utils.maybeInitializeVolume(storageManager, new Bundle());
198     }
199 
200     @Test
isProfileOrDeviceOwner_deviceOwnerApp_returnTrue()201     public void isProfileOrDeviceOwner_deviceOwnerApp_returnTrue() {
202         when(mDevicePolicyManager.isDeviceOwnerAppOnAnyUser(PACKAGE_NAME)).thenReturn(true);
203 
204         assertThat(
205             Utils.isProfileOrDeviceOwner(mMockUserManager, mDevicePolicyManager, PACKAGE_NAME))
206                 .isTrue();
207     }
208 
209     @Test
isProfileOrDeviceOwner_profileOwnerApp_returnTrue()210     public void isProfileOrDeviceOwner_profileOwnerApp_returnTrue() {
211         final List<UserInfo> userInfos = new ArrayList<>();
212         userInfos.add(new UserInfo());
213 
214         when(mMockUserManager.getUsers()).thenReturn(userInfos);
215         when(mDevicePolicyManager.getProfileOwnerAsUser(userInfos.get(0).id))
216             .thenReturn(new ComponentName(PACKAGE_NAME, ""));
217 
218         assertThat(
219             Utils.isProfileOrDeviceOwner(mMockUserManager, mDevicePolicyManager, PACKAGE_NAME))
220                 .isTrue();
221     }
222 
223     @Test
setEditTextCursorPosition_shouldGetExpectedEditTextLenght()224     public void setEditTextCursorPosition_shouldGetExpectedEditTextLenght() {
225         final EditText editText = new EditText(mContext);
226         final CharSequence text = "test";
227         editText.setText(text, TextView.BufferType.EDITABLE);
228         final int length = editText.getText().length();
229         Utils.setEditTextCursorPosition(editText);
230 
231         assertThat(editText.getSelectionEnd()).isEqualTo(length);
232     }
233 
234     @Test
createIconWithDrawable_BitmapDrawable()235     public void createIconWithDrawable_BitmapDrawable() {
236         final Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
237         final BitmapDrawable drawable = new BitmapDrawable(mContext.getResources(), bitmap);
238 
239         final IconCompat icon = Utils.createIconWithDrawable(drawable);
240 
241         assertThat(icon.getBitmap()).isNotNull();
242     }
243 
244     @Test
createIconWithDrawable_ColorDrawable()245     public void createIconWithDrawable_ColorDrawable() {
246         final ColorDrawable drawable = new ColorDrawable(Color.BLACK);
247 
248         final IconCompat icon = Utils.createIconWithDrawable(drawable);
249 
250         assertThat(icon.getBitmap()).isNotNull();
251     }
252 
253     @Test
createIconWithDrawable_VectorDrawable()254     public void createIconWithDrawable_VectorDrawable() {
255         final VectorDrawable drawable = VectorDrawable.create(mContext.getResources(),
256                 R.drawable.ic_settings_accent);
257 
258         final IconCompat icon = Utils.createIconWithDrawable(drawable);
259 
260         assertThat(icon.getBitmap()).isNotNull();
261     }
262 
263     @Test
getBadgedIcon_usePackageNameAndUserId()264     public void getBadgedIcon_usePackageNameAndUserId()
265         throws PackageManager.NameNotFoundException {
266         doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfoAsUser(
267                 PACKAGE_NAME, PackageManager.GET_META_DATA, USER_ID);
268 
269         Utils.getBadgedIcon(mIconDrawableFactory, mPackageManager, PACKAGE_NAME, USER_ID);
270 
271         // Verify that it uses the correct user id
272         verify(mPackageManager).getApplicationInfoAsUser(eq(PACKAGE_NAME), anyInt(), eq(USER_ID));
273         verify(mIconDrawableFactory).getBadgedIcon(mApplicationInfo, USER_ID);
274     }
275 
276     @Test
isPackageEnabled_appEnabled_returnTrue()277     public void isPackageEnabled_appEnabled_returnTrue()
278             throws PackageManager.NameNotFoundException{
279         mApplicationInfo.enabled = true;
280         when(mPackageManager.getApplicationInfo(PACKAGE_NAME, 0)).thenReturn(mApplicationInfo);
281 
282         assertThat(Utils.isPackageEnabled(mContext, PACKAGE_NAME)).isTrue();
283     }
284 
285     @Test
isPackageEnabled_appDisabled_returnTrue()286     public void isPackageEnabled_appDisabled_returnTrue()
287             throws PackageManager.NameNotFoundException{
288         mApplicationInfo.enabled = false;
289         when(mPackageManager.getApplicationInfo(PACKAGE_NAME, 0)).thenReturn(mApplicationInfo);
290 
291         assertThat(Utils.isPackageEnabled(mContext, PACKAGE_NAME)).isFalse();
292     }
293 
294     @Test
isPackageEnabled_noApp_returnFalse()295     public void isPackageEnabled_noApp_returnFalse() {
296         assertThat(Utils.isPackageEnabled(mContext, PACKAGE_NAME)).isFalse();
297     }
298 
299     @Test
setActionBarShadowAnimation_nullParameters_shouldNotCrash()300     public void setActionBarShadowAnimation_nullParameters_shouldNotCrash() {
301         // no crash here
302         Utils.setActionBarShadowAnimation(null, null, null);
303     }
304 
305     @Test
setActionBarShadowAnimation_shouldSetElevationToZero()306     public void setActionBarShadowAnimation_shouldSetElevationToZero() {
307         final FragmentActivity activity = Robolectric.setupActivity(FragmentActivity.class);
308         final ActionBar actionBar = activity.getActionBar();
309 
310         Utils.setActionBarShadowAnimation(activity, activity.getLifecycle(),
311                 new ScrollView(mContext));
312 
313         assertThat(actionBar.getElevation()).isEqualTo(0.f);
314     }
315 
316     @Test
isSettingsIntelligence_IsSI_returnTrue()317     public void isSettingsIntelligence_IsSI_returnTrue() {
318         final String siPackageName = mContext.getString(
319                 R.string.config_settingsintelligence_package_name);
320         ShadowBinder.setCallingUid(USER_ID);
321         when(mPackageManager.getPackagesForUid(USER_ID)).thenReturn(new String[]{siPackageName});
322 
323         assertThat(Utils.isSettingsIntelligence(mContext)).isTrue();
324     }
325 
326     @Test
isSettingsIntelligence_IsNotSI_returnFalse()327     public void isSettingsIntelligence_IsNotSI_returnFalse() {
328         ShadowBinder.setCallingUid(USER_ID);
329         when(mPackageManager.getPackagesForUid(USER_ID)).thenReturn(new String[]{PACKAGE_NAME});
330 
331         assertThat(Utils.isSettingsIntelligence(mContext)).isFalse();
332     }
333 
334     @Test
canCurrentUserDream_isMainUser_returnTrue()335     public void canCurrentUserDream_isMainUser_returnTrue() {
336         Context mockContext = mock(Context.class);
337         UserManager mockUserManager = mock(UserManager.class);
338 
339         when(mockContext.getSystemService(UserManager.class)).thenReturn(mockUserManager);
340 
341         // mock MainUser
342         UserHandle mainUser = new UserHandle(10);
343         when(mockUserManager.getMainUser()).thenReturn(mainUser);
344         when(mockUserManager.isUserForeground()).thenReturn(true);
345 
346         when(mockContext.createContextAsUser(mainUser, 0)).thenReturn(mockContext);
347 
348         assertThat(Utils.canCurrentUserDream(mockContext)).isTrue();
349     }
350 
351     @Test
canCurrentUserDream_nullMainUser_returnFalse()352     public void canCurrentUserDream_nullMainUser_returnFalse() {
353         Context mockContext = mock(Context.class);
354         UserManager mockUserManager = mock(UserManager.class);
355 
356         when(mockContext.getSystemService(UserManager.class)).thenReturn(mockUserManager);
357         when(mockUserManager.getMainUser()).thenReturn(null);
358 
359         assertThat(Utils.canCurrentUserDream(mockContext)).isFalse();
360     }
361 
362     @Test
canCurrentUserDream_notMainUser_returnFalse()363     public void canCurrentUserDream_notMainUser_returnFalse() {
364         Context mockContext = mock(Context.class);
365         UserManager mockUserManager = mock(UserManager.class);
366 
367         when(mockContext.getSystemService(UserManager.class)).thenReturn(mockUserManager);
368         when(mockUserManager.isUserForeground()).thenReturn(false);
369 
370         assertThat(Utils.canCurrentUserDream(mockContext)).isFalse();
371     }
372 
373     @Test
checkUserOwnsFrpCredential_userOwnsFrpCredential_returnUserId()374     public void checkUserOwnsFrpCredential_userOwnsFrpCredential_returnUserId() {
375         ShadowLockPatternUtils.setUserOwnsFrpCredential(true);
376 
377         assertThat(Utils.checkUserOwnsFrpCredential(mContext, 123)).isEqualTo(123);
378     }
379 
380     @Test
checkUserOwnsFrpCredential_userNotOwnsFrpCredential_returnUserId()381     public void checkUserOwnsFrpCredential_userNotOwnsFrpCredential_returnUserId() {
382         ShadowLockPatternUtils.setUserOwnsFrpCredential(false);
383 
384         assertThrows(
385                 SecurityException.class,
386                 () -> Utils.checkUserOwnsFrpCredential(mContext, 123));
387     }
388 
389     @Test
getConfirmCredentialStringForUser_Pin_shouldReturnCorrectString()390     public void getConfirmCredentialStringForUser_Pin_shouldReturnCorrectString() {
391         setUpForConfirmCredentialString(false /* isEffectiveUserManagedProfile */);
392 
393         when(mContext.getString(R.string.lockpassword_confirm_your_pin_generic))
394                 .thenReturn("PIN");
395 
396         String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext,
397                 USER_ID, LockPatternUtils.CREDENTIAL_TYPE_PIN);
398 
399         assertThat(confirmCredentialString).isEqualTo("PIN");
400     }
401 
402     @Test
getConfirmCredentialStringForUser_Pattern_shouldReturnCorrectString()403     public void getConfirmCredentialStringForUser_Pattern_shouldReturnCorrectString() {
404         setUpForConfirmCredentialString(false /* isEffectiveUserManagedProfile */);
405 
406         when(mContext.getString(R.string.lockpassword_confirm_your_pattern_generic))
407                 .thenReturn("PATTERN");
408 
409         String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext,
410                 USER_ID, LockPatternUtils.CREDENTIAL_TYPE_PATTERN);
411 
412         assertThat(confirmCredentialString).isEqualTo("PATTERN");
413     }
414 
415     @Test
getConfirmCredentialStringForUser_Password_shouldReturnCorrectString()416     public void getConfirmCredentialStringForUser_Password_shouldReturnCorrectString() {
417         setUpForConfirmCredentialString(false /* isEffectiveUserManagedProfile */);
418 
419         when(mContext.getString(R.string.lockpassword_confirm_your_password_generic))
420                 .thenReturn("PASSWORD");
421 
422         String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext,
423                 USER_ID, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD);
424 
425         assertThat(confirmCredentialString).isEqualTo("PASSWORD");
426     }
427 
428     @Test
getConfirmCredentialStringForUser_workPin_shouldReturnNull()429     public void getConfirmCredentialStringForUser_workPin_shouldReturnNull() {
430         setUpForConfirmCredentialString(true /* isEffectiveUserManagedProfile */);
431 
432         String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext,
433                 USER_ID, LockPatternUtils.CREDENTIAL_TYPE_PIN);
434 
435         assertNull(confirmCredentialString);
436     }
437 
438     @Test
getConfirmCredentialStringForUser_workPattern_shouldReturnNull()439     public void getConfirmCredentialStringForUser_workPattern_shouldReturnNull() {
440         setUpForConfirmCredentialString(true /* isEffectiveUserManagedProfile */);
441 
442         String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext,
443                 USER_ID, LockPatternUtils.CREDENTIAL_TYPE_PATTERN);
444 
445         assertNull(confirmCredentialString);
446     }
447 
448     @Test
getConfirmCredentialStringForUser_workPassword_shouldReturnNull()449     public void getConfirmCredentialStringForUser_workPassword_shouldReturnNull() {
450         setUpForConfirmCredentialString(true /* isEffectiveUserManagedProfile */);
451 
452         String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext,
453                 USER_ID, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD);
454 
455         assertNull(confirmCredentialString);
456     }
457 
458     @Test
getConfirmCredentialStringForUser_credentialTypeNone_shouldReturnNull()459     public void getConfirmCredentialStringForUser_credentialTypeNone_shouldReturnNull() {
460         setUpForConfirmCredentialString(false /* isEffectiveUserManagedProfile */);
461 
462         String confirmCredentialString = Utils.getConfirmCredentialStringForUser(mContext,
463                 USER_ID, LockPatternUtils.CREDENTIAL_TYPE_NONE);
464 
465         assertNull(confirmCredentialString);
466     }
467 
468     @Test
isFaceNotConvenienceBiometric_faceStrengthStrong_shouldReturnTrue()469     public void isFaceNotConvenienceBiometric_faceStrengthStrong_shouldReturnTrue() {
470         FaceManager mockFaceManager = mock(FaceManager.class);
471         when(mContext.getSystemService(Context.FACE_SERVICE)).thenReturn(mockFaceManager);
472         doReturn(true).when(mPackageManager).hasSystemFeature(anyString());
473         List<FaceSensorPropertiesInternal> props = List.of(new FaceSensorPropertiesInternal(
474                 0 /* id */,
475                 STRENGTH_STRONG,
476                 1 /* maxTemplatesAllowed */,
477                 new ArrayList<>() /* componentInfo */,
478                 FaceSensorProperties.TYPE_UNKNOWN,
479                 true /* supportsFaceDetection */,
480                 true /* supportsSelfIllumination */,
481                 false /* resetLockoutRequiresChallenge */));
482         doReturn(props).when(mockFaceManager).getSensorPropertiesInternal();
483 
484         assertThat(Utils.isFaceNotConvenienceBiometric(mContext)).isTrue();
485     }
486 
487     @Test
isFaceNotConvenienceBiometric_faceStrengthWeak_shouldReturnTrue()488     public void isFaceNotConvenienceBiometric_faceStrengthWeak_shouldReturnTrue() {
489         FaceManager mockFaceManager = mock(FaceManager.class);
490         when(mContext.getSystemService(Context.FACE_SERVICE)).thenReturn(mockFaceManager);
491         doReturn(true).when(mPackageManager).hasSystemFeature(anyString());
492         List<FaceSensorPropertiesInternal> props = List.of(new FaceSensorPropertiesInternal(
493                 0 /* id */,
494                 STRENGTH_WEAK,
495                 1 /* maxTemplatesAllowed */,
496                 new ArrayList<>() /* componentInfo */,
497                 FaceSensorProperties.TYPE_UNKNOWN,
498                 true /* supportsFaceDetection */,
499                 true /* supportsSelfIllumination */,
500                 false /* resetLockoutRequiresChallenge */));
501         doReturn(props).when(mockFaceManager).getSensorPropertiesInternal();
502 
503         assertThat(Utils.isFaceNotConvenienceBiometric(mContext)).isTrue();
504     }
505 
506     @Test
isFaceNotConvenienceBiometric_faceStrengthConvenience_shouldReturnFalse()507     public void isFaceNotConvenienceBiometric_faceStrengthConvenience_shouldReturnFalse() {
508         FaceManager mockFaceManager = mock(FaceManager.class);
509         when(mContext.getSystemService(Context.FACE_SERVICE)).thenReturn(mockFaceManager);
510         doReturn(true).when(mPackageManager).hasSystemFeature(anyString());
511         List<FaceSensorPropertiesInternal> props = List.of(new FaceSensorPropertiesInternal(
512                 0 /* id */,
513                 STRENGTH_CONVENIENCE,
514                 1 /* maxTemplatesAllowed */,
515                 new ArrayList<>() /* componentInfo */,
516                 FaceSensorProperties.TYPE_UNKNOWN,
517                 true /* supportsFaceDetection */,
518                 true /* supportsSelfIllumination */,
519                 false /* resetLockoutRequiresChallenge */));
520         doReturn(props).when(mockFaceManager).getSensorPropertiesInternal();
521 
522         assertThat(Utils.isFaceNotConvenienceBiometric(mContext)).isFalse();
523     }
524 
525     @Test
isFaceNotConvenienceBiometric_faceManagerNull_shouldReturnFalse()526     public void isFaceNotConvenienceBiometric_faceManagerNull_shouldReturnFalse() {
527         when(mContext.getSystemService(Context.FACE_SERVICE)).thenReturn(null);
528         assertThat(Utils.isFaceNotConvenienceBiometric(mContext)).isFalse();
529     }
530 
531     @Test
532     @EnableFlags(Flags.FLAG_MANDATORY_BIOMETRICS)
testRequestBiometricAuthentication_biometricManagerNull_shouldReturnNotActive()533     public void testRequestBiometricAuthentication_biometricManagerNull_shouldReturnNotActive() {
534         when(mContext.getSystemService(BiometricManager.class)).thenReturn(null);
535         assertThat(Utils.requestBiometricAuthenticationForMandatoryBiometrics(mContext,
536                 false /* biometricsAuthenticationRequested */, USER_ID)).isEqualTo(
537                         Utils.BiometricStatus.NOT_ACTIVE);
538     }
539 
540     @Test
541     @EnableFlags(Flags.FLAG_MANDATORY_BIOMETRICS)
testRequestBiometricAuthentication_biometricManagerReturnsSuccess_shouldReturnOk()542     public void testRequestBiometricAuthentication_biometricManagerReturnsSuccess_shouldReturnOk() {
543         when(mBiometricManager.canAuthenticate(USER_ID,
544                 BiometricManager.Authenticators.IDENTITY_CHECK))
545                 .thenReturn(BiometricManager.BIOMETRIC_SUCCESS);
546         final Utils.BiometricStatus requestBiometricAuthenticationForMandatoryBiometrics =
547                 Utils.requestBiometricAuthenticationForMandatoryBiometrics(mContext,
548                         false /* biometricsAuthenticationRequested */, USER_ID);
549         assertThat(requestBiometricAuthenticationForMandatoryBiometrics).isEqualTo(
550                 Utils.BiometricStatus.OK);
551     }
552 
553     @Test
554     @EnableFlags(Flags.FLAG_MANDATORY_BIOMETRICS)
testRequestBiometricAuthentication_biometricManagerReturnsError_shouldReturnError()555     public void testRequestBiometricAuthentication_biometricManagerReturnsError_shouldReturnError() {
556         when(mBiometricManager.canAuthenticate(anyInt(),
557                 eq(BiometricManager.Authenticators.IDENTITY_CHECK)))
558                 .thenReturn(BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE);
559         assertThat(Utils.requestBiometricAuthenticationForMandatoryBiometrics(mContext,
560                 false /* biometricsAuthenticationRequested */, USER_ID)).isEqualTo(
561                         Utils.BiometricStatus.ERROR);
562     }
563 
564     @Test
565     @EnableFlags(Flags.FLAG_MANDATORY_BIOMETRICS)
testRequestBiometricAuthentication_biometricManagerReturnsSuccessForDifferentUser_shouldReturnError()566     public void testRequestBiometricAuthentication_biometricManagerReturnsSuccessForDifferentUser_shouldReturnError() {
567         when(mContext.getSystemService(UserManager.class)).thenReturn(mMockUserManager);
568         when(mMockUserManager.getCredentialOwnerProfile(USER_ID)).thenReturn(USER_ID);
569         when(mBiometricManager.canAuthenticate(anyInt(),
570                 eq(BiometricManager.Authenticators.IDENTITY_CHECK)))
571                 .thenReturn(BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE);
572         when(mBiometricManager.canAuthenticate(0 /* userId */,
573                 BiometricManager.Authenticators.IDENTITY_CHECK))
574                 .thenReturn(BiometricManager.BIOMETRIC_SUCCESS);
575         assertThat(Utils.requestBiometricAuthenticationForMandatoryBiometrics(mContext,
576                 false /* biometricsAuthenticationRequested */, USER_ID)).isEqualTo(
577                         Utils.BiometricStatus.ERROR);
578     }
579 
580     @Test
581     @EnableFlags(Flags.FLAG_MANDATORY_BIOMETRICS)
testLaunchBiometricPrompt_checkIntentValues()582     public void testLaunchBiometricPrompt_checkIntentValues() {
583         when(mFragment.getContext()).thenReturn(mContext);
584         when(mContext.getSystemService(UserManager.class)).thenReturn(mMockUserManager);
585         when(mMockUserManager.getCredentialOwnerProfile(USER_ID)).thenReturn(USER_ID);
586 
587         final int requestCode = 1;
588         final ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
589         Utils.launchBiometricPromptForMandatoryBiometrics(mFragment, requestCode, USER_ID,
590                 false /* hideBackground */);
591 
592         verify(mFragment).startActivityForResult(intentArgumentCaptor.capture(), eq(requestCode));
593 
594         final Intent intent = intentArgumentCaptor.getValue();
595 
596         assertThat(intent.getExtra(BIOMETRIC_PROMPT_AUTHENTICATORS)).isEqualTo(
597                 BiometricManager.Authenticators.IDENTITY_CHECK);
598         assertThat(intent.getExtra(BIOMETRIC_PROMPT_NEGATIVE_BUTTON_TEXT)).isNotNull();
599         assertThat(intent.getExtra(KeyguardManager.EXTRA_DESCRIPTION)).isNotNull();
600         assertThat(intent.getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_ALLOW_ANY_USER, false))
601                 .isTrue();
602         assertThat(intent.getBooleanExtra(BIOMETRIC_PROMPT_HIDE_BACKGROUND, true))
603                 .isFalse();
604         assertThat(intent.getIntExtra(Intent.EXTRA_USER_ID, 0)).isEqualTo(USER_ID);
605         assertThat(intent.getComponent().getPackageName()).isEqualTo(SETTINGS_PACKAGE_NAME);
606         assertThat(intent.getComponent().getClassName()).isEqualTo(
607                 ConfirmDeviceCredentialActivity.InternalActivity.class.getName());
608     }
609 
setUpForConfirmCredentialString(boolean isEffectiveUserManagedProfile)610     private void setUpForConfirmCredentialString(boolean isEffectiveUserManagedProfile) {
611         when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mMockUserManager);
612         when(mMockUserManager.getCredentialOwnerProfile(USER_ID)).thenReturn(USER_ID);
613         when(mMockUserManager.isManagedProfile(USER_ID)).thenReturn(isEffectiveUserManagedProfile);
614     }
615 }
616