1 /* 2 * Copyright (C) 2016 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.password; 18 19 import static android.content.pm.PackageManager.FEATURE_FINGERPRINT; 20 21 import static com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment 22 .HIDE_DISABLED_PREFS; 23 import static com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment 24 .MINIMUM_QUALITY_KEY; 25 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE; 26 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT; 27 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE; 28 29 import static com.google.common.truth.Truth.assertThat; 30 31 import static org.junit.Assert.assertEquals; 32 import static org.junit.Assert.assertTrue; 33 import static org.mockito.Matchers.any; 34 import static org.mockito.Matchers.eq; 35 import static org.mockito.Mockito.verify; 36 import static org.mockito.Mockito.when; 37 38 import android.app.admin.DevicePolicyManager; 39 import android.content.ComponentName; 40 import android.content.Intent; 41 import android.content.pm.PackageManager; 42 import android.os.Bundle; 43 44 import com.android.settings.testutils.SettingsRobolectricTestRunner; 45 import com.android.settings.TestConfig; 46 47 import org.junit.Before; 48 import org.junit.Test; 49 import org.junit.runner.RunWith; 50 import org.mockito.ArgumentCaptor; 51 import org.mockito.Mock; 52 import org.mockito.MockitoAnnotations; 53 import org.robolectric.annotation.Config; 54 55 56 /** 57 * Tests for {@link SetNewPasswordController}. 58 */ 59 @RunWith(SettingsRobolectricTestRunner.class) 60 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) 61 public final class SetNewPasswordControllerTest { 62 private static final int CURRENT_USER_ID = 101; 63 private static final long FINGERPRINT_CHALLENGE = -9876512313131L; 64 65 @Mock PackageManager mPackageManager; 66 @Mock IFingerprintManager mFingerprintManager; 67 @Mock DevicePolicyManager mDevicePolicyManager; 68 69 @Mock private SetNewPasswordController.Ui mUi; 70 private SetNewPasswordController mSetNewPasswordController; 71 72 @Before 73 public void setUp() { 74 MockitoAnnotations.initMocks(this); 75 mSetNewPasswordController = new SetNewPasswordController( 76 CURRENT_USER_ID, mPackageManager, mFingerprintManager, mDevicePolicyManager, mUi); 77 78 when(mFingerprintManager.preEnroll()).thenReturn(FINGERPRINT_CHALLENGE); 79 when(mPackageManager.hasSystemFeature(eq(FEATURE_FINGERPRINT))).thenReturn(true); 80 } 81 82 @Test 83 public void launchChooseLockWithFingerprint() { 84 // GIVEN the device supports fingerprint. 85 when(mFingerprintManager.isHardwareDetected()).thenReturn(true); 86 // GIVEN there are no enrolled fingerprints. 87 when(mFingerprintManager.hasEnrolledFingerprints(CURRENT_USER_ID)).thenReturn(false); 88 // GIVEN DPC does not disallow fingerprint for keyguard usage. 89 when(mDevicePolicyManager.getKeyguardDisabledFeatures(any(ComponentName.class))) 90 .thenReturn(0); 91 92 // WHEN the controller dispatches a set new password intent. 93 mSetNewPasswordController.dispatchSetNewPasswordIntent(); 94 95 // THEN the choose lock activity is launched with fingerprint extras. 96 ArgumentCaptor<Bundle> bundleArgumentCaptor = ArgumentCaptor.forClass(Bundle.class); 97 verify(mUi).launchChooseLock(bundleArgumentCaptor.capture()); 98 // THEN the extras have all values for fingerprint setup. 99 compareFingerprintExtras(bundleArgumentCaptor.getValue()); 100 } 101 102 @Test 103 public void launchChooseLockWithoutFingerprint_noFingerprintFeature() { 104 // GIVEN the device does NOT support fingerprint feature. 105 when(mPackageManager.hasSystemFeature(eq(FEATURE_FINGERPRINT))).thenReturn(false); 106 107 // WHEN the controller dispatches a set new password intent. 108 mSetNewPasswordController.dispatchSetNewPasswordIntent(); 109 110 // THEN the choose lock activity is launched without fingerprint extras. 111 ArgumentCaptor<Bundle> bundleArgumentCaptor = ArgumentCaptor.forClass(Bundle.class); 112 verify(mUi).launchChooseLock(bundleArgumentCaptor.capture()); 113 assertBundleContainsUserIdOnly(bundleArgumentCaptor.getValue()); 114 } 115 116 @Test 117 public void launchChooseLockWithoutFingerprint_noFingerprintSensor() { 118 // GIVEN the device does NOT support fingerprint. 119 when(mFingerprintManager.isHardwareDetected()).thenReturn(false); 120 // GIVEN there are no enrolled fingerprints. 121 when(mFingerprintManager.hasEnrolledFingerprints(CURRENT_USER_ID)).thenReturn(false); 122 // GIVEN DPC does not disallow fingerprint for keyguard usage. 123 when(mDevicePolicyManager.getKeyguardDisabledFeatures(any(ComponentName.class))) 124 .thenReturn(0); 125 126 // WHEN the controller dispatches a set new password intent. 127 mSetNewPasswordController.dispatchSetNewPasswordIntent(); 128 129 // THEN the choose lock activity is launched without a bundle contains user id only. 130 ArgumentCaptor<Bundle> bundleArgumentCaptor = ArgumentCaptor.forClass(Bundle.class); 131 verify(mUi).launchChooseLock(bundleArgumentCaptor.capture()); 132 assertBundleContainsUserIdOnly(bundleArgumentCaptor.getValue()); 133 } 134 135 @Test 136 public void launchChooseLockWithoutFingerprint_hasFingerprintEnrolled() { 137 // GIVEN the device supports fingerprint. 138 when(mFingerprintManager.isHardwareDetected()).thenReturn(true); 139 // GIVEN there are no enrolled fingerprints. 140 when(mFingerprintManager.hasEnrolledFingerprints(CURRENT_USER_ID)).thenReturn(true); 141 // GIVEN DPC does not disallow fingerprint for keyguard usage. 142 when(mDevicePolicyManager.getKeyguardDisabledFeatures(any(ComponentName.class))) 143 .thenReturn(0); 144 145 // WHEN the controller dispatches a set new password intent. 146 mSetNewPasswordController.dispatchSetNewPasswordIntent(); 147 148 // THEN the choose lock activity is launched without a bundle contains user id only. 149 ArgumentCaptor<Bundle> bundleArgumentCaptor = ArgumentCaptor.forClass(Bundle.class); 150 verify(mUi).launchChooseLock(bundleArgumentCaptor.capture()); 151 assertBundleContainsUserIdOnly(bundleArgumentCaptor.getValue()); 152 } 153 154 @Test 155 public void launchChooseLockWithoutFingerprint_deviceAdminDisallowFingerprintForKeyguard() { 156 // GIVEN the device supports fingerprint. 157 when(mFingerprintManager.isHardwareDetected()).thenReturn(true); 158 // GIVEN there is an enrolled fingerprint. 159 when(mFingerprintManager.hasEnrolledFingerprints(CURRENT_USER_ID)).thenReturn(true); 160 // GIVEN DPC disallows fingerprint for keyguard usage. 161 when(mDevicePolicyManager.getKeyguardDisabledFeatures(any(ComponentName.class))) 162 .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT); 163 164 // WHEN the controller dispatches a set new password intent. 165 mSetNewPasswordController.dispatchSetNewPasswordIntent(); 166 167 // THEN the choose lock activity is launched without a bundle contains user id only. 168 ArgumentCaptor<Bundle> bundleArgumentCaptor = ArgumentCaptor.forClass(Bundle.class); 169 verify(mUi).launchChooseLock(bundleArgumentCaptor.capture()); 170 assertBundleContainsUserIdOnly(bundleArgumentCaptor.getValue()); 171 } 172 173 private void compareFingerprintExtras(Bundle actualBundle) { 174 assertEquals( 175 "Password quality must be something in order to config fingerprint.", 176 DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, 177 actualBundle.getInt(MINIMUM_QUALITY_KEY)); 178 assertTrue( 179 "All disabled preference should be removed.", 180 actualBundle.getBoolean(HIDE_DISABLED_PREFS)); 181 assertTrue( 182 "There must be a fingerprint challenge.", 183 actualBundle.getBoolean(EXTRA_KEY_HAS_CHALLENGE)); 184 assertEquals( 185 "The fingerprint challenge must come from the FingerprintManager", 186 FINGERPRINT_CHALLENGE, 187 actualBundle.getLong(EXTRA_KEY_CHALLENGE)); 188 assertTrue( 189 "The request must be a fingerprint set up request.", 190 actualBundle.getBoolean(EXTRA_KEY_FOR_FINGERPRINT)); 191 assertEquals( 192 "User id must be equaled to the input one.", 193 CURRENT_USER_ID, 194 actualBundle.getInt(Intent.EXTRA_USER_ID)); 195 } 196 197 private void assertBundleContainsUserIdOnly(Bundle actualBundle) { 198 assertThat(actualBundle.size()).isEqualTo(1); 199 assertThat(actualBundle.getInt(Intent.EXTRA_USER_ID)).isEqualTo(CURRENT_USER_ID); 200 } 201 } 202