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.biometrics; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.ArgumentMatchers.any; 22 import static org.mockito.Mockito.doNothing; 23 import static org.mockito.Mockito.never; 24 import static org.mockito.Mockito.spy; 25 import static org.mockito.Mockito.verify; 26 import static org.mockito.Mockito.when; 27 28 import android.app.admin.DevicePolicyManager; 29 import android.content.ComponentName; 30 import android.content.Context; 31 import android.content.Intent; 32 import android.os.Bundle; 33 import android.os.UserHandle; 34 import android.os.UserManager; 35 import android.provider.Settings; 36 37 import androidx.activity.result.ActivityResultLauncher; 38 import androidx.test.core.app.ApplicationProvider; 39 import androidx.test.ext.junit.runners.AndroidJUnit4; 40 41 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; 42 43 import org.junit.Before; 44 import org.junit.Test; 45 import org.junit.runner.RunWith; 46 import org.mockito.ArgumentCaptor; 47 import org.mockito.Mock; 48 import org.mockito.MockitoAnnotations; 49 50 @RunWith(AndroidJUnit4.class) 51 public class BiometricNavigationUtilsTest { 52 53 private static final String SETTINGS_CLASS_NAME = "SettingsClassName"; 54 private static final String EXTRA_KEY = "EXTRA_KEY"; 55 private static final ComponentName COMPONENT_NAME = new ComponentName("package", "class"); 56 private static final int ADMIN_USER_ID = 2; 57 58 @Mock 59 private UserManager mUserManager; 60 @Mock 61 private ActivityResultLauncher<Intent> mLauncher; 62 private Context mContext; 63 private BiometricNavigationUtils mBiometricNavigationUtils; 64 65 @Before setUp()66 public void setUp() { 67 MockitoAnnotations.initMocks(this); 68 mContext = spy(ApplicationProvider.getApplicationContext()); 69 when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager); 70 doNothing().when(mContext).startActivity(any()); 71 mBiometricNavigationUtils = new BiometricNavigationUtils(UserHandle.myUserId()); 72 } 73 74 @Test launchBiometricSettings_quietMode_launchesQuiteModeDialog()75 public void launchBiometricSettings_quietMode_launchesQuiteModeDialog() { 76 when(mUserManager.isQuietModeEnabled(any())).thenReturn(true); 77 78 mBiometricNavigationUtils.launchBiometricSettings(mContext, SETTINGS_CLASS_NAME, 79 Bundle.EMPTY, null); 80 81 assertQuietModeDialogLaunchRequested(); 82 } 83 84 @Test launchBiometricSettings_quietMode_returnsFalse()85 public void launchBiometricSettings_quietMode_returnsFalse() { 86 when(mUserManager.isQuietModeEnabled(any())).thenReturn(true); 87 88 assertThat(mBiometricNavigationUtils.launchBiometricSettings( 89 mContext, SETTINGS_CLASS_NAME, Bundle.EMPTY, null)).isFalse(); 90 } 91 92 @Test launchBiometricSettings_quietMode_withLauncher_notThroughLauncher()93 public void launchBiometricSettings_quietMode_withLauncher_notThroughLauncher() { 94 when(mUserManager.isQuietModeEnabled(any())).thenReturn(true); 95 96 mBiometricNavigationUtils.launchBiometricSettings(mContext, SETTINGS_CLASS_NAME, 97 Bundle.EMPTY, mLauncher); 98 99 verify(mLauncher, never()).launch(any(Intent.class)); 100 } 101 102 @Test launchBiometricSettings_noQuietMode_emptyExtras_launchesFragmentWithoutExtras()103 public void launchBiometricSettings_noQuietMode_emptyExtras_launchesFragmentWithoutExtras() { 104 when(mUserManager.isQuietModeEnabled(any())).thenReturn(false); 105 106 mBiometricNavigationUtils.launchBiometricSettings( 107 mContext, SETTINGS_CLASS_NAME, Bundle.EMPTY, null); 108 109 assertSettingsPageLaunchRequested(false /* shouldContainExtras */); 110 } 111 112 @Test launchBiometricSettings_noQuietMode_emptyExtras_returnsTrue()113 public void launchBiometricSettings_noQuietMode_emptyExtras_returnsTrue() { 114 when(mUserManager.isQuietModeEnabled(any())).thenReturn(false); 115 116 assertThat(mBiometricNavigationUtils.launchBiometricSettings( 117 mContext, SETTINGS_CLASS_NAME, Bundle.EMPTY, null)).isTrue(); 118 } 119 120 @Test launchBiometricSettings_noQuietMode_withExtras_launchesFragmentWithExtras()121 public void launchBiometricSettings_noQuietMode_withExtras_launchesFragmentWithExtras() { 122 when(mUserManager.isQuietModeEnabled(any())).thenReturn(false); 123 124 final Bundle extras = createNotEmptyExtras(); 125 mBiometricNavigationUtils.launchBiometricSettings( 126 mContext, SETTINGS_CLASS_NAME, extras, null); 127 128 assertSettingsPageLaunchRequested(true /* shouldContainExtras */); 129 } 130 131 @Test launchBiometricSettings_noQuietMode_withLauncher_launchesThroughLauncher()132 public void launchBiometricSettings_noQuietMode_withLauncher_launchesThroughLauncher() { 133 when(mUserManager.isQuietModeEnabled(any())).thenReturn(false); 134 135 final Bundle extras = createNotEmptyExtras(); 136 mBiometricNavigationUtils.launchBiometricSettings( 137 mContext, SETTINGS_CLASS_NAME, extras, mLauncher); 138 139 verify(mLauncher).launch(any(Intent.class)); 140 } 141 142 @Test launchBiometricSettings_noQuietMode_withExtras_returnsTrue()143 public void launchBiometricSettings_noQuietMode_withExtras_returnsTrue() { 144 when(mUserManager.isQuietModeEnabled(any())).thenReturn(false); 145 146 assertThat(mBiometricNavigationUtils.launchBiometricSettings( 147 mContext, SETTINGS_CLASS_NAME, createNotEmptyExtras(), null)).isTrue(); 148 } 149 150 @Test getBiometricSettingsIntent_quietMode_returnsQuiteModeDialogIntent()151 public void getBiometricSettingsIntent_quietMode_returnsQuiteModeDialogIntent() { 152 when(mUserManager.isQuietModeEnabled(any())).thenReturn(true); 153 154 final Intent intent = mBiometricNavigationUtils.getBiometricSettingsIntent( 155 mContext, SETTINGS_CLASS_NAME, null /* enforcedAdmin */, Bundle.EMPTY); 156 157 assertQuietModeDialogIntent(intent); 158 } 159 160 @Test getBiometricSettingsIntent_noQuietMode_emptyExtras_returnsSettingsIntent()161 public void getBiometricSettingsIntent_noQuietMode_emptyExtras_returnsSettingsIntent() { 162 when(mUserManager.isQuietModeEnabled(any())).thenReturn(false); 163 164 final Intent intent = mBiometricNavigationUtils.getBiometricSettingsIntent( 165 mContext, SETTINGS_CLASS_NAME, null /* enforcedAdmin */, Bundle.EMPTY); 166 167 assertSettingsPageIntent(intent, false /* shouldContainExtras */); 168 } 169 170 @Test getBiometricSettingsIntent_noQuietMode_withExtras_returnsSettingsIntent()171 public void getBiometricSettingsIntent_noQuietMode_withExtras_returnsSettingsIntent() { 172 when(mUserManager.isQuietModeEnabled(any())).thenReturn(false); 173 174 final Intent intent = mBiometricNavigationUtils.getBiometricSettingsIntent( 175 mContext, SETTINGS_CLASS_NAME, null /* enforcedAdmin */, createNotEmptyExtras()); 176 177 assertSettingsPageIntent(intent, true /* shouldContainExtras */); 178 } 179 180 @Test getBiometricSettingsIntent_whenDisabledByAdmin_quietMode_returnsBlockedIntent()181 public void getBiometricSettingsIntent_whenDisabledByAdmin_quietMode_returnsBlockedIntent() { 182 when(mUserManager.isQuietModeEnabled(any())).thenReturn(true); 183 final EnforcedAdmin enforcedAdmin = new EnforcedAdmin( 184 COMPONENT_NAME, UserHandle.of(ADMIN_USER_ID)); 185 186 final Intent intent = mBiometricNavigationUtils.getBiometricSettingsIntent( 187 mContext, SETTINGS_CLASS_NAME, enforcedAdmin, Bundle.EMPTY); 188 189 assertBlockedByAdminDialogIntent(intent); 190 } 191 192 @Test getBiometricSettingsIntent_whenDisabledByAdmin_emptyExtras_returnsBlockedIntent()193 public void getBiometricSettingsIntent_whenDisabledByAdmin_emptyExtras_returnsBlockedIntent() { 194 when(mUserManager.isQuietModeEnabled(any())).thenReturn(false); 195 final EnforcedAdmin enforcedAdmin = new EnforcedAdmin( 196 COMPONENT_NAME, UserHandle.of(ADMIN_USER_ID)); 197 198 final Intent intent = mBiometricNavigationUtils.getBiometricSettingsIntent( 199 mContext, SETTINGS_CLASS_NAME, enforcedAdmin, Bundle.EMPTY); 200 201 assertBlockedByAdminDialogIntent(intent); 202 } 203 204 @Test getBiometricSettingsIntent_whenDisabledByAdmin_withExtras_returnsBlockedIntent()205 public void getBiometricSettingsIntent_whenDisabledByAdmin_withExtras_returnsBlockedIntent() { 206 when(mUserManager.isQuietModeEnabled(any())).thenReturn(false); 207 final EnforcedAdmin enforcedAdmin = new EnforcedAdmin( 208 COMPONENT_NAME, UserHandle.of(ADMIN_USER_ID)); 209 210 final Intent intent = mBiometricNavigationUtils.getBiometricSettingsIntent( 211 mContext, SETTINGS_CLASS_NAME, enforcedAdmin, Bundle.EMPTY); 212 213 assertBlockedByAdminDialogIntent(intent); 214 } 215 createNotEmptyExtras()216 private Bundle createNotEmptyExtras() { 217 final Bundle bundle = new Bundle(); 218 bundle.putInt(EXTRA_KEY, 0); 219 return bundle; 220 } 221 assertQuietModeDialogLaunchRequested()222 private void assertQuietModeDialogLaunchRequested() { 223 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 224 verify(mContext).startActivity(intentCaptor.capture()); 225 226 Intent intent = intentCaptor.getValue(); 227 assertQuietModeDialogIntent(intent); 228 } 229 assertQuietModeDialogIntent(Intent intent)230 private void assertQuietModeDialogIntent(Intent intent) { 231 assertThat(intent.getComponent().getPackageName()) 232 .isEqualTo("android"); 233 assertThat(intent.getComponent().getClassName()) 234 .isEqualTo("com.android.internal.app.UnlaunchableAppActivity"); 235 } 236 assertBlockedByAdminDialogIntent(Intent intent)237 private void assertBlockedByAdminDialogIntent(Intent intent) { 238 assertThat(intent.getAction()).isEqualTo(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS); 239 assertThat( 240 (ComponentName) intent.getParcelableExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN)) 241 .isEqualTo(COMPONENT_NAME); 242 } 243 assertSettingsPageLaunchRequested(boolean shouldContainExtras)244 private void assertSettingsPageLaunchRequested(boolean shouldContainExtras) { 245 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 246 verify(mContext).startActivity(intentCaptor.capture()); 247 248 Intent intent = intentCaptor.getValue(); 249 assertSettingsPageIntent(intent, shouldContainExtras); 250 } 251 assertSettingsPageIntent(Intent intent, boolean shouldContainExtras)252 private void assertSettingsPageIntent(Intent intent, boolean shouldContainExtras) { 253 assertThat(intent.getComponent().getPackageName()) 254 .isEqualTo("com.android.settings"); 255 assertThat(intent.getComponent().getClassName()) 256 .isEqualTo(SETTINGS_CLASS_NAME); 257 assertThat(intent.getExtras().containsKey(EXTRA_KEY)).isEqualTo(shouldContainExtras); 258 } 259 260 } 261