Merge "Move bimetrics v2 tests to unit/"
This commit is contained in:
committed by
Android (Google) Code Review
commit
69b8706b9d
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.biometrics2.repository;
|
||||
|
||||
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_HOME_BUTTON;
|
||||
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_POWER_BUTTON;
|
||||
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_REAR;
|
||||
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_OPTICAL;
|
||||
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_ULTRASONIC;
|
||||
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UNKNOWN;
|
||||
|
||||
import static com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.newFingerprintRepository;
|
||||
import static com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.setupFingerprintEnrolledFingerprints;
|
||||
import static com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.setupSuwMaxFingerprintsEnrollable;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.biometrics2.data.repository.FingerprintRepository;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class FingerprintRepositoryTest {
|
||||
|
||||
@Rule public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
|
||||
@Mock private Resources mResources;
|
||||
@Mock private FingerprintManager mFingerprintManager;
|
||||
|
||||
private Context mContext;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = ApplicationProvider.getApplicationContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCanAssumeSensorType_forUnknownSensor() {
|
||||
final FingerprintRepository repository = newFingerprintRepository(mFingerprintManager,
|
||||
TYPE_UNKNOWN, 1);
|
||||
assertThat(repository.canAssumeUdfps()).isFalse();
|
||||
assertThat(repository.canAssumeSfps()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCanAssumeSensorType_forRearSensor() {
|
||||
final FingerprintRepository repository = newFingerprintRepository(mFingerprintManager,
|
||||
TYPE_REAR, 1);
|
||||
assertThat(repository.canAssumeUdfps()).isFalse();
|
||||
assertThat(repository.canAssumeSfps()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCanAssumeSensorType_forUdfpsUltrasonicSensor() {
|
||||
final FingerprintRepository repository = newFingerprintRepository(mFingerprintManager,
|
||||
TYPE_UDFPS_ULTRASONIC, 1);
|
||||
assertThat(repository.canAssumeUdfps()).isTrue();
|
||||
assertThat(repository.canAssumeSfps()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCanAssumeSensorType_forUdfpsOpticalSensor() {
|
||||
final FingerprintRepository repository = newFingerprintRepository(mFingerprintManager,
|
||||
TYPE_UDFPS_OPTICAL, 1);
|
||||
assertThat(repository.canAssumeUdfps()).isTrue();
|
||||
assertThat(repository.canAssumeSfps()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCanAssumeSensorType_forPowerButtonSensor() {
|
||||
final FingerprintRepository repository = newFingerprintRepository(mFingerprintManager,
|
||||
TYPE_POWER_BUTTON, 1);
|
||||
assertThat(repository.canAssumeUdfps()).isFalse();
|
||||
assertThat(repository.canAssumeSfps()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCanAssumeSensorType_forHomeButtonSensor() {
|
||||
final FingerprintRepository repository = newFingerprintRepository(mFingerprintManager,
|
||||
TYPE_HOME_BUTTON, 1);
|
||||
assertThat(repository.canAssumeUdfps()).isFalse();
|
||||
assertThat(repository.canAssumeSfps()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMaxFingerprints() {
|
||||
final FingerprintRepository repository = newFingerprintRepository(mFingerprintManager,
|
||||
TYPE_UNKNOWN, 999);
|
||||
assertThat(repository.getMaxFingerprints()).isEqualTo(999);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNumOfEnrolledFingerprintsSize() {
|
||||
final FingerprintRepository repository = newFingerprintRepository(mFingerprintManager,
|
||||
TYPE_UNKNOWN, 999);
|
||||
setupFingerprintEnrolledFingerprints(mFingerprintManager, 10, 3);
|
||||
setupFingerprintEnrolledFingerprints(mFingerprintManager, 22, 99);
|
||||
|
||||
assertThat(repository.getNumOfEnrolledFingerprintsSize(10)).isEqualTo(3);
|
||||
assertThat(repository.getNumOfEnrolledFingerprintsSize(22)).isEqualTo(99);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMaxFingerprintsInSuw() {
|
||||
final FingerprintRepository repository = newFingerprintRepository(mFingerprintManager,
|
||||
TYPE_UNKNOWN, 999);
|
||||
setupSuwMaxFingerprintsEnrollable(mContext, mResources, 333);
|
||||
assertThat(repository.getMaxFingerprintsInSuw(mResources))
|
||||
.isEqualTo(333);
|
||||
|
||||
setupSuwMaxFingerprintsEnrollable(mContext, mResources, 20);
|
||||
assertThat(repository.getMaxFingerprintsInSuw(mResources)).isEqualTo(20);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.biometrics2.ui.model;
|
||||
|
||||
import static com.android.settings.biometrics.BiometricEnrollBase.EXTRA_KEY_CHALLENGE;
|
||||
import static com.android.settings.biometrics.BiometricEnrollBase.EXTRA_KEY_SENSOR_ID;
|
||||
import static com.android.settings.biometrics2.ui.model.CredentialModel.INVALID_CHALLENGE;
|
||||
import static com.android.settings.biometrics2.ui.model.CredentialModel.INVALID_GK_PW_HANDLE;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static com.google.common.truth.Truth.assertWithMessage;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.password.ChooseLockSettingsHelper;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.time.Clock;
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class CredentialModelTest {
|
||||
|
||||
private final Clock mClock = SystemClock.elapsedRealtimeClock();
|
||||
|
||||
public static Bundle newCredentialModelIntentExtras(int userId, long challenge, int sensorId,
|
||||
@Nullable byte[] token, long gkPwHandle) {
|
||||
final Bundle bundle = new Bundle();
|
||||
bundle.putInt(Intent.EXTRA_USER_ID, userId);
|
||||
bundle.putInt(EXTRA_KEY_SENSOR_ID, sensorId);
|
||||
bundle.putLong(EXTRA_KEY_CHALLENGE, challenge);
|
||||
bundle.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
|
||||
bundle.putLong(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, gkPwHandle);
|
||||
return bundle;
|
||||
}
|
||||
|
||||
public static Bundle newValidTokenCredentialIntentExtras(int userId) {
|
||||
return newCredentialModelIntentExtras(userId, 1L, 1, new byte[] { 0, 1, 2 },
|
||||
INVALID_GK_PW_HANDLE);
|
||||
}
|
||||
|
||||
public static Bundle newOnlySensorValidCredentialIntentExtras(int userId) {
|
||||
return newCredentialModelIntentExtras(userId, INVALID_CHALLENGE, 1, null,
|
||||
INVALID_GK_PW_HANDLE);
|
||||
}
|
||||
|
||||
public static Bundle newGkPwHandleCredentialIntentExtras(int userId, long gkPwHandle) {
|
||||
return newCredentialModelIntentExtras(userId, INVALID_CHALLENGE, 1, null, gkPwHandle);
|
||||
}
|
||||
|
||||
private static void checkBundleLongValue(@NonNull Bundle bundle1, @NonNull Bundle bundle2,
|
||||
@NonNull String key) {
|
||||
if (!bundle1.containsKey(key)) {
|
||||
return;
|
||||
}
|
||||
final int value1 = bundle1.getInt(key);
|
||||
final int value2 = bundle2.getInt(key);
|
||||
assertWithMessage("bundle not match, key:" + key + ", value1:" + value1 + ", value2:"
|
||||
+ value2).that(value1).isEqualTo(value2);
|
||||
}
|
||||
|
||||
private static void checkBundleIntValue(@NonNull Bundle bundle1, @NonNull Bundle bundle2,
|
||||
@NonNull String key) {
|
||||
if (!bundle1.containsKey(key)) {
|
||||
return;
|
||||
}
|
||||
final long value1 = bundle1.getLong(key);
|
||||
final long value2 = bundle2.getLong(key);
|
||||
assertWithMessage("bundle not match, key:" + key + ", value1:" + value1 + ", value2:"
|
||||
+ value2).that(value1).isEqualTo(value2);
|
||||
}
|
||||
|
||||
private static void checkBundleByteArrayValue(@NonNull Bundle bundle1, @NonNull Bundle bundle2,
|
||||
@NonNull String key) {
|
||||
if (!bundle1.containsKey(key)) {
|
||||
return;
|
||||
}
|
||||
final byte[] value1 = bundle1.getByteArray(key);
|
||||
final byte[] value2 = bundle2.getByteArray(key);
|
||||
final String errMsg = "bundle not match, key:" + key + ", value1:" + Arrays.toString(value1)
|
||||
+ ", value2:" + Arrays.toString(value2);
|
||||
if (value1 == null) {
|
||||
assertWithMessage(errMsg).that(value2).isNull();
|
||||
} else {
|
||||
assertWithMessage(errMsg).that(value1.length).isEqualTo(value2.length);
|
||||
for (int i = 0; i < value1.length; ++i) {
|
||||
assertWithMessage(errMsg).that(value1[i]).isEqualTo(value2[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void verifySameCredentialModels(@NonNull CredentialModel model1,
|
||||
@NonNull CredentialModel model2) {
|
||||
|
||||
assertThat(model1.getUserId()).isEqualTo(model2.getUserId());
|
||||
assertThat(model1.getSensorId()).isEqualTo(model2.getSensorId());
|
||||
assertThat(model1.getChallenge()).isEqualTo(model2.getChallenge());
|
||||
assertThat(model1.getGkPwHandle()).isEqualTo(model2.getGkPwHandle());
|
||||
|
||||
final byte[] token1 = model1.getToken();
|
||||
final byte[] token2 = model2.getToken();
|
||||
if (token1 == null) {
|
||||
assertThat(token2).isNull();
|
||||
} else {
|
||||
assertThat(token2).isNotNull();
|
||||
assertThat(token1.length).isEqualTo(token2.length);
|
||||
for (int i = 0; i < token1.length; ++i) {
|
||||
assertThat(token1[i]).isEqualTo(token2[i]);
|
||||
}
|
||||
}
|
||||
|
||||
final Bundle bundle1 = model1.getBundle();
|
||||
final Bundle bundle2 = model2.getBundle();
|
||||
final Set<String> keySet1 = bundle1.keySet();
|
||||
assertThat(keySet1.equals(bundle2.keySet())).isTrue();
|
||||
checkBundleIntValue(bundle1, bundle2, Intent.EXTRA_USER_ID);
|
||||
checkBundleIntValue(bundle1, bundle2, EXTRA_KEY_SENSOR_ID);
|
||||
checkBundleLongValue(bundle1, bundle2, EXTRA_KEY_CHALLENGE);
|
||||
checkBundleByteArrayValue(bundle1, bundle2, EXTRA_KEY_CHALLENGE);
|
||||
checkBundleLongValue(bundle1, bundle2, EXTRA_KEY_GK_PW_HANDLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sameValueFromBundle() {
|
||||
final Bundle bundle = newCredentialModelIntentExtras(1234, 6677L, 1,
|
||||
new byte[] { 33, 44, 55 }, 987654321);
|
||||
|
||||
final CredentialModel model1 = new CredentialModel(bundle, mClock);
|
||||
final CredentialModel model2 = new CredentialModel(model1.getBundle(), mClock);
|
||||
|
||||
verifySameCredentialModels(model1, model2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sameValueFromBundle_nullToken() {
|
||||
final Bundle bundle = newCredentialModelIntentExtras(22, 33L, 1, null, 21L);
|
||||
|
||||
final CredentialModel model1 = new CredentialModel(bundle, mClock);
|
||||
final CredentialModel model2 = new CredentialModel(model1.getBundle(), mClock);
|
||||
|
||||
verifySameCredentialModels(model1, model2);
|
||||
}
|
||||
}
|
@@ -0,0 +1,626 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.biometrics2.ui.viewmodel;
|
||||
|
||||
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
|
||||
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
|
||||
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
|
||||
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
|
||||
|
||||
import static com.android.settings.biometrics.BiometricEnrollBase.EXTRA_KEY_CHALLENGE;
|
||||
import static com.android.settings.biometrics.BiometricEnrollBase.EXTRA_KEY_SENSOR_ID;
|
||||
import static com.android.settings.biometrics2.ui.model.CredentialModel.INVALID_CHALLENGE;
|
||||
import static com.android.settings.biometrics2.ui.model.CredentialModel.INVALID_GK_PW_HANDLE;
|
||||
import static com.android.settings.biometrics2.ui.model.CredentialModel.INVALID_SENSOR_ID;
|
||||
import static com.android.settings.biometrics2.ui.model.CredentialModelTest.newCredentialModelIntentExtras;
|
||||
import static com.android.settings.biometrics2.ui.model.CredentialModelTest.newGkPwHandleCredentialIntentExtras;
|
||||
import static com.android.settings.biometrics2.ui.model.CredentialModelTest.newOnlySensorValidCredentialIntentExtras;
|
||||
import static com.android.settings.biometrics2.ui.model.CredentialModelTest.newValidTokenCredentialIntentExtras;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_FAIL_NEED_TO_CHOOSE_LOCK;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_FAIL_NEED_TO_CONFIRM_LOCK;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_IS_GENERATING_CHALLENGE;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_VALID;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.ChallengeGenerator;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CredentialAction;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.GenerateChallengeCallback;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.KEY_CREDENTIAL_MODEL;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.KEY_IS_GENERATING_CHALLENGE_DURING_CHECKING_CREDENTIAL;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static com.google.common.truth.Truth.assertWithMessage;
|
||||
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import androidx.activity.result.ActivityResult;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.internal.widget.VerifyCredentialResponse;
|
||||
import com.android.settings.password.ChooseLockPattern;
|
||||
import com.android.settings.testutils.InstantTaskExecutorRule;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class AutoCredentialViewModelTest {
|
||||
|
||||
@Rule public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
@Rule public final InstantTaskExecutorRule mTaskExecutorRule = new InstantTaskExecutorRule();
|
||||
|
||||
@Mock private LockPatternUtils mLockPatternUtils;
|
||||
private TestChallengeGenerator mChallengeGenerator = null;
|
||||
private AutoCredentialViewModel mViewModel;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mChallengeGenerator = new TestChallengeGenerator();
|
||||
mViewModel = new AutoCredentialViewModel(
|
||||
ApplicationProvider.getApplicationContext(),
|
||||
mLockPatternUtils,
|
||||
mChallengeGenerator);
|
||||
}
|
||||
|
||||
private void setupGenerateChallenge(int userId, int newSensorId, long newChallenge) {
|
||||
when(mLockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
PASSWORD_QUALITY_SOMETHING);
|
||||
mChallengeGenerator.mUserId = userId;
|
||||
mChallengeGenerator.mSensorId = newSensorId;
|
||||
mChallengeGenerator.mChallenge = newChallenge;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetCredentialModel_sameResultFromSavedInstanceOrIntent() {
|
||||
final Bundle extras = newCredentialModelIntentExtras(12, 33, 1, new byte[] { 2, 3 }, 3L);
|
||||
|
||||
AutoCredentialViewModel viewModel2 = new AutoCredentialViewModel(
|
||||
ApplicationProvider.getApplicationContext(),
|
||||
mLockPatternUtils,
|
||||
mChallengeGenerator);
|
||||
|
||||
mViewModel.setCredentialModel(null, new Intent().putExtras(extras));
|
||||
final Bundle savedInstance = new Bundle();
|
||||
mViewModel.onSaveInstanceState(savedInstance);
|
||||
viewModel2.setCredentialModel(savedInstance, new Intent());
|
||||
|
||||
final Bundle bundle1 = mViewModel.createCredentialIntentExtra();
|
||||
final Bundle bundle2 = viewModel2.createCredentialIntentExtra();
|
||||
assertThat(bundle1.getLong(EXTRA_KEY_GK_PW_HANDLE))
|
||||
.isEqualTo(bundle2.getLong(EXTRA_KEY_GK_PW_HANDLE));
|
||||
assertThat(bundle1.getLong(Intent.EXTRA_USER_ID))
|
||||
.isEqualTo(bundle2.getLong(Intent.EXTRA_USER_ID));
|
||||
assertThat(bundle1.getLong(EXTRA_KEY_CHALLENGE))
|
||||
.isEqualTo(bundle2.getLong(EXTRA_KEY_CHALLENGE));
|
||||
assertThat(bundle1.getInt(EXTRA_KEY_SENSOR_ID))
|
||||
.isEqualTo(bundle2.getInt(EXTRA_KEY_SENSOR_ID));
|
||||
final byte[] token1 = bundle1.getByteArray(EXTRA_KEY_CHALLENGE_TOKEN);
|
||||
final byte[] token2 = bundle2.getByteArray(EXTRA_KEY_CHALLENGE_TOKEN);
|
||||
assertThat(token1).isNotNull();
|
||||
assertThat(token2).isNotNull();
|
||||
assertThat(token1.length).isEqualTo(token2.length);
|
||||
for (int i = 0; i < token2.length; ++i) {
|
||||
assertThat(token1[i]).isEqualTo(token2[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetCredentialModel_sameResultFromSavedInstanceOrIntent_invalidValues() {
|
||||
final Bundle extras = newCredentialModelIntentExtras(UserHandle.USER_NULL,
|
||||
INVALID_CHALLENGE, INVALID_SENSOR_ID, null, INVALID_GK_PW_HANDLE);
|
||||
|
||||
AutoCredentialViewModel viewModel2 = new AutoCredentialViewModel(
|
||||
ApplicationProvider.getApplicationContext(),
|
||||
mLockPatternUtils,
|
||||
mChallengeGenerator);
|
||||
|
||||
mViewModel.setCredentialModel(null, new Intent().putExtras(extras));
|
||||
final Bundle savedInstance = new Bundle();
|
||||
mViewModel.onSaveInstanceState(savedInstance);
|
||||
viewModel2.setCredentialModel(savedInstance, new Intent());
|
||||
|
||||
final Bundle bundle1 = mViewModel.createCredentialIntentExtra();
|
||||
final Bundle bundle2 = viewModel2.createCredentialIntentExtra();
|
||||
assertThat(bundle1.containsKey(EXTRA_KEY_GK_PW_HANDLE)).isFalse();
|
||||
assertThat(bundle2.containsKey(EXTRA_KEY_GK_PW_HANDLE)).isFalse();
|
||||
assertThat(bundle1.containsKey(EXTRA_KEY_CHALLENGE_TOKEN)).isFalse();
|
||||
assertThat(bundle2.containsKey(EXTRA_KEY_CHALLENGE_TOKEN)).isFalse();
|
||||
assertThat(bundle1.containsKey(EXTRA_KEY_SENSOR_ID)).isTrue();
|
||||
assertThat(bundle2.containsKey(EXTRA_KEY_SENSOR_ID)).isTrue();
|
||||
assertThat(bundle1.containsKey(Intent.EXTRA_USER_ID)).isFalse();
|
||||
assertThat(bundle2.containsKey(Intent.EXTRA_USER_ID)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckCredential_validCredentialCase() {
|
||||
final int userId = 99;
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newValidTokenCredentialIntentExtras(userId)));
|
||||
when(mLockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
PASSWORD_QUALITY_SOMETHING);
|
||||
|
||||
// Run credential check
|
||||
@CredentialAction final int action = mViewModel.checkCredential();
|
||||
|
||||
// Check viewModel behavior
|
||||
assertThat(action).isEqualTo(CREDENTIAL_VALID);
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull();
|
||||
|
||||
// Check createGeneratingChallengeExtras()
|
||||
assertThat(mViewModel.createGeneratingChallengeExtras()).isNull();
|
||||
|
||||
// Check onSaveInstanceState()
|
||||
final Bundle actualBundle = new Bundle();
|
||||
mViewModel.onSaveInstanceState(actualBundle);
|
||||
assertThat(actualBundle.getBoolean(KEY_IS_GENERATING_CHALLENGE_DURING_CHECKING_CREDENTIAL))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckCredential_needToChooseLock() {
|
||||
final int userId = 100;
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newOnlySensorValidCredentialIntentExtras(userId)));
|
||||
when(mLockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
PASSWORD_QUALITY_UNSPECIFIED);
|
||||
|
||||
// Run credential check
|
||||
@CredentialAction final int action = mViewModel.checkCredential();
|
||||
|
||||
// Check viewModel behavior
|
||||
assertThat(action).isEqualTo(CREDENTIAL_FAIL_NEED_TO_CHOOSE_LOCK);
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull();
|
||||
|
||||
// Check createGeneratingChallengeExtras()
|
||||
assertThat(mViewModel.createGeneratingChallengeExtras()).isNull();
|
||||
|
||||
// Check onSaveInstanceState()
|
||||
final Bundle actualBundle = new Bundle();
|
||||
mViewModel.onSaveInstanceState(actualBundle);
|
||||
assertThat(actualBundle.getBoolean(KEY_IS_GENERATING_CHALLENGE_DURING_CHECKING_CREDENTIAL))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckCredential_needToConfirmLockForSomething() {
|
||||
final int userId = 101;
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newOnlySensorValidCredentialIntentExtras(userId)));
|
||||
when(mLockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
PASSWORD_QUALITY_SOMETHING);
|
||||
|
||||
// Run credential check
|
||||
@CredentialAction final int action = mViewModel.checkCredential();
|
||||
|
||||
// Check viewModel behavior
|
||||
assertThat(action).isEqualTo(CREDENTIAL_FAIL_NEED_TO_CONFIRM_LOCK);
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull();
|
||||
|
||||
// Check createGeneratingChallengeExtras()
|
||||
assertThat(mViewModel.createGeneratingChallengeExtras()).isNull();
|
||||
|
||||
// Check onSaveInstanceState()
|
||||
final Bundle actualBundle = new Bundle();
|
||||
mViewModel.onSaveInstanceState(actualBundle);
|
||||
assertThat(actualBundle.getBoolean(KEY_IS_GENERATING_CHALLENGE_DURING_CHECKING_CREDENTIAL))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckCredential_needToConfirmLockForNumeric() {
|
||||
final int userId = 102;
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newOnlySensorValidCredentialIntentExtras(userId)));
|
||||
when(mLockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
PASSWORD_QUALITY_NUMERIC);
|
||||
|
||||
// Run credential check
|
||||
@CredentialAction final int action = mViewModel.checkCredential();
|
||||
|
||||
// Check viewModel behavior
|
||||
assertThat(action).isEqualTo(CREDENTIAL_FAIL_NEED_TO_CONFIRM_LOCK);
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull();
|
||||
|
||||
// Check createGeneratingChallengeExtras()
|
||||
assertThat(mViewModel.createGeneratingChallengeExtras()).isNull();
|
||||
|
||||
// Check onSaveInstanceState()
|
||||
final Bundle actualBundle = new Bundle();
|
||||
mViewModel.onSaveInstanceState(actualBundle);
|
||||
assertThat(actualBundle.getBoolean(KEY_IS_GENERATING_CHALLENGE_DURING_CHECKING_CREDENTIAL))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckCredential_needToConfirmLockForAlphabetic() {
|
||||
final int userId = 103;
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newOnlySensorValidCredentialIntentExtras(userId)));
|
||||
when(mLockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
PASSWORD_QUALITY_ALPHABETIC);
|
||||
|
||||
// Run credential check
|
||||
@CredentialAction final int action = mViewModel.checkCredential();
|
||||
|
||||
// Check viewModel behavior
|
||||
assertThat(action).isEqualTo(CREDENTIAL_FAIL_NEED_TO_CONFIRM_LOCK);
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull();
|
||||
|
||||
// Check createGeneratingChallengeExtras()
|
||||
assertThat(mViewModel.createGeneratingChallengeExtras()).isNull();
|
||||
|
||||
// Check onSaveInstanceState()
|
||||
final Bundle actualBundle = new Bundle();
|
||||
mViewModel.onSaveInstanceState(actualBundle);
|
||||
assertThat(actualBundle.getBoolean(KEY_IS_GENERATING_CHALLENGE_DURING_CHECKING_CREDENTIAL))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckCredential_generateChallenge() {
|
||||
final int userId = 104;
|
||||
final long gkPwHandle = 1111L;
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newGkPwHandleCredentialIntentExtras(userId, gkPwHandle)));
|
||||
when(mLockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
PASSWORD_QUALITY_SOMETHING);
|
||||
|
||||
final int newSensorId = 10;
|
||||
final long newChallenge = 20L;
|
||||
setupGenerateChallenge(userId, newSensorId, newChallenge);
|
||||
when(mLockPatternUtils.verifyGatekeeperPasswordHandle(gkPwHandle, newChallenge, userId))
|
||||
.thenReturn(newGoodCredential(gkPwHandle, new byte[] { 1 }));
|
||||
|
||||
final AtomicBoolean hasCalledRemoveGkPwHandle = new AtomicBoolean();
|
||||
doAnswer(invocation -> {
|
||||
hasCalledRemoveGkPwHandle.set(true);
|
||||
return null;
|
||||
}).when(mLockPatternUtils).removeGatekeeperPasswordHandle(gkPwHandle);
|
||||
|
||||
// Run credential check
|
||||
@CredentialAction final int action = mViewModel.checkCredential();
|
||||
|
||||
// Check viewModel behavior
|
||||
assertThat(action).isEqualTo(CREDENTIAL_IS_GENERATING_CHALLENGE);
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull();
|
||||
|
||||
// Check data inside CredentialModel
|
||||
final Bundle extras = mViewModel.createCredentialIntentExtra();
|
||||
assertThat(extras.getInt(EXTRA_KEY_SENSOR_ID)).isEqualTo(newSensorId);
|
||||
assertThat(extras.getLong(EXTRA_KEY_CHALLENGE)).isEqualTo(newChallenge);
|
||||
assertThat(extras.getByteArray(EXTRA_KEY_CHALLENGE_TOKEN)).isNotNull();
|
||||
assertThat(extras.getLong(EXTRA_KEY_GK_PW_HANDLE)).isEqualTo(INVALID_GK_PW_HANDLE);
|
||||
assertThat(extras.getLong(EXTRA_KEY_CHALLENGE)).isNotEqualTo(INVALID_CHALLENGE);
|
||||
assertThat(mChallengeGenerator.mCallbackRunCount).isEqualTo(1);
|
||||
assertThat(hasCalledRemoveGkPwHandle.get()).isFalse();
|
||||
|
||||
// Check createGeneratingChallengeExtras()
|
||||
final Bundle generatingChallengeExtras = mViewModel.createGeneratingChallengeExtras();
|
||||
assertThat(generatingChallengeExtras).isNotNull();
|
||||
assertThat(generatingChallengeExtras.getLong(EXTRA_KEY_CHALLENGE)).isEqualTo(newChallenge);
|
||||
final byte[] tokens = generatingChallengeExtras.getByteArray(EXTRA_KEY_CHALLENGE_TOKEN);
|
||||
assertThat(tokens).isNotNull();
|
||||
assertThat(tokens.length).isEqualTo(1);
|
||||
assertThat(tokens[0]).isEqualTo(1);
|
||||
|
||||
// Check onSaveInstanceState()
|
||||
final Bundle actualBundle = new Bundle();
|
||||
mViewModel.onSaveInstanceState(actualBundle);
|
||||
assertThat(actualBundle.getBoolean(KEY_IS_GENERATING_CHALLENGE_DURING_CHECKING_CREDENTIAL))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckCredential_generateChallengeFail() {
|
||||
final int userId = 104;
|
||||
final long gkPwHandle = 1111L;
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newGkPwHandleCredentialIntentExtras(userId, gkPwHandle)));
|
||||
when(mLockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
PASSWORD_QUALITY_SOMETHING);
|
||||
|
||||
final int newSensorId = 10;
|
||||
final long newChallenge = 20L;
|
||||
setupGenerateChallenge(userId, newSensorId, newChallenge);
|
||||
when(mLockPatternUtils.verifyGatekeeperPasswordHandle(gkPwHandle, newChallenge, userId))
|
||||
.thenReturn(newBadCredential(0));
|
||||
|
||||
// Run credential check
|
||||
@CredentialAction final int action = mViewModel.checkCredential();
|
||||
|
||||
assertThat(action).isEqualTo(CREDENTIAL_IS_GENERATING_CHALLENGE);
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isTrue();
|
||||
assertThat(mChallengeGenerator.mCallbackRunCount).isEqualTo(1);
|
||||
|
||||
// Check createGeneratingChallengeExtras()
|
||||
assertThat(mViewModel.createGeneratingChallengeExtras()).isNull();
|
||||
|
||||
// Check onSaveInstanceState()
|
||||
final Bundle actualBundle = new Bundle();
|
||||
mViewModel.onSaveInstanceState(actualBundle);
|
||||
assertThat(actualBundle.getBoolean(KEY_IS_GENERATING_CHALLENGE_DURING_CHECKING_CREDENTIAL))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUserId_fromIntent() {
|
||||
final int userId = 106;
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newOnlySensorValidCredentialIntentExtras(userId)));
|
||||
|
||||
// Get userId
|
||||
assertThat(mViewModel.getUserId()).isEqualTo(userId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUserId_fromSavedInstance() {
|
||||
final int userId = 106;
|
||||
final Bundle savedInstance = new Bundle();
|
||||
savedInstance.putBundle(KEY_CREDENTIAL_MODEL,
|
||||
newOnlySensorValidCredentialIntentExtras(userId));
|
||||
mViewModel.setCredentialModel(savedInstance, new Intent());
|
||||
|
||||
// Get userId
|
||||
assertThat(mViewModel.getUserId()).isEqualTo(userId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateGeneratingChallengeExtras_generateChallenge() {
|
||||
final Bundle credentialExtras = newValidTokenCredentialIntentExtras(200);
|
||||
final Bundle savedInstance = new Bundle();
|
||||
savedInstance.putBundle(KEY_CREDENTIAL_MODEL, credentialExtras);
|
||||
savedInstance.putBoolean(KEY_IS_GENERATING_CHALLENGE_DURING_CHECKING_CREDENTIAL, true);
|
||||
mViewModel.setCredentialModel(savedInstance, new Intent());
|
||||
|
||||
// Check createGeneratingChallengeExtras()
|
||||
final Bundle actualExtras = mViewModel.createGeneratingChallengeExtras();
|
||||
assertThat(actualExtras).isNotNull();
|
||||
assertThat(actualExtras.getLong(EXTRA_KEY_CHALLENGE))
|
||||
.isEqualTo(credentialExtras.getLong(EXTRA_KEY_CHALLENGE));
|
||||
final byte[] actualToken = actualExtras.getByteArray(EXTRA_KEY_CHALLENGE_TOKEN);
|
||||
final byte[] expectedToken = credentialExtras.getByteArray(EXTRA_KEY_CHALLENGE_TOKEN);
|
||||
assertThat(actualToken).isNotNull();
|
||||
assertThat(expectedToken).isNotNull();
|
||||
assertThat(actualToken.length).isEqualTo(expectedToken.length);
|
||||
for (int i = 0; i < actualToken.length; ++i) {
|
||||
assertWithMessage("tokens[" + i + "] not match").that(actualToken[i])
|
||||
.isEqualTo(expectedToken[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateGeneratingChallengeExtras_notGenerateChallenge() {
|
||||
final Bundle credentialExtras = newValidTokenCredentialIntentExtras(201);
|
||||
final Bundle savedInstance = new Bundle();
|
||||
savedInstance.putBundle(KEY_CREDENTIAL_MODEL, credentialExtras);
|
||||
savedInstance.putBoolean(KEY_IS_GENERATING_CHALLENGE_DURING_CHECKING_CREDENTIAL, false);
|
||||
mViewModel.setCredentialModel(savedInstance, new Intent());
|
||||
|
||||
// Check createGeneratingChallengeExtras()
|
||||
assertThat(mViewModel.createGeneratingChallengeExtras()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateGeneratingChallengeExtras_invalidToken() {
|
||||
final Bundle credentialExtras = newOnlySensorValidCredentialIntentExtras(202);
|
||||
final Bundle savedInstance = new Bundle();
|
||||
savedInstance.putBundle(KEY_CREDENTIAL_MODEL, credentialExtras);
|
||||
savedInstance.putBoolean(KEY_IS_GENERATING_CHALLENGE_DURING_CHECKING_CREDENTIAL, true);
|
||||
mViewModel.setCredentialModel(savedInstance, new Intent());
|
||||
|
||||
// Check createGeneratingChallengeExtras()
|
||||
assertThat(mViewModel.createGeneratingChallengeExtras()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckNewCredentialFromActivityResult_invalidChooseLock() {
|
||||
final int userId = 107;
|
||||
final long gkPwHandle = 3333L;
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newGkPwHandleCredentialIntentExtras(userId, gkPwHandle)));
|
||||
final Intent intent = new Intent();
|
||||
intent.putExtra(EXTRA_KEY_GK_PW_HANDLE, gkPwHandle);
|
||||
|
||||
// run checkNewCredentialFromActivityResult()
|
||||
final boolean ret = mViewModel.checkNewCredentialFromActivityResult(true,
|
||||
new ActivityResult(ChooseLockPattern.RESULT_FINISHED + 1, intent));
|
||||
|
||||
assertThat(ret).isFalse();
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckNewCredentialFromActivityResult_invalidConfirmLock() {
|
||||
final int userId = 107;
|
||||
final long gkPwHandle = 3333L;
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newGkPwHandleCredentialIntentExtras(userId, gkPwHandle)));
|
||||
final Intent intent = new Intent();
|
||||
intent.putExtra(EXTRA_KEY_GK_PW_HANDLE, gkPwHandle);
|
||||
|
||||
// run checkNewCredentialFromActivityResult()
|
||||
final boolean ret = mViewModel.checkNewCredentialFromActivityResult(false,
|
||||
new ActivityResult(Activity.RESULT_OK + 1, intent));
|
||||
|
||||
assertThat(ret).isFalse();
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckNewCredentialFromActivityResult_nullDataChooseLock() {
|
||||
final int userId = 108;
|
||||
final long gkPwHandle = 4444L;
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newGkPwHandleCredentialIntentExtras(userId, gkPwHandle)));
|
||||
|
||||
// run checkNewCredentialFromActivityResult()
|
||||
final boolean ret = mViewModel.checkNewCredentialFromActivityResult(true,
|
||||
new ActivityResult(ChooseLockPattern.RESULT_FINISHED, null));
|
||||
|
||||
assertThat(ret).isFalse();
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckNewCredentialFromActivityResult_nullDataConfirmLock() {
|
||||
final int userId = 109;
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newOnlySensorValidCredentialIntentExtras(userId)));
|
||||
|
||||
// run checkNewCredentialFromActivityResult()
|
||||
final boolean ret = mViewModel.checkNewCredentialFromActivityResult(false,
|
||||
new ActivityResult(Activity.RESULT_OK, null));
|
||||
|
||||
assertThat(ret).isFalse();
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckNewCredentialFromActivityResult_validChooseLock() {
|
||||
final int userId = 108;
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newOnlySensorValidCredentialIntentExtras(userId)));
|
||||
when(mLockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
PASSWORD_QUALITY_SOMETHING);
|
||||
|
||||
final long gkPwHandle = 6666L;
|
||||
final int newSensorId = 50;
|
||||
final long newChallenge = 60L;
|
||||
setupGenerateChallenge(userId, newSensorId, newChallenge);
|
||||
when(mLockPatternUtils.verifyGatekeeperPasswordHandle(gkPwHandle, newChallenge, userId))
|
||||
.thenReturn(newGoodCredential(gkPwHandle, new byte[] { 1 }));
|
||||
|
||||
final AtomicBoolean hasCalledRemoveGkPwHandle = new AtomicBoolean();
|
||||
doAnswer(invocation -> {
|
||||
hasCalledRemoveGkPwHandle.set(true);
|
||||
return null;
|
||||
}).when(mLockPatternUtils).removeGatekeeperPasswordHandle(gkPwHandle);
|
||||
|
||||
// Run checkNewCredentialFromActivityResult()
|
||||
final Intent intent = new Intent().putExtra(EXTRA_KEY_GK_PW_HANDLE, gkPwHandle);
|
||||
final boolean ret = mViewModel.checkNewCredentialFromActivityResult(true,
|
||||
new ActivityResult(ChooseLockPattern.RESULT_FINISHED, intent));
|
||||
|
||||
assertThat(ret).isTrue();
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull();
|
||||
final Bundle extras = mViewModel.createCredentialIntentExtra();
|
||||
assertThat(extras.getInt(EXTRA_KEY_SENSOR_ID)).isEqualTo(newSensorId);
|
||||
assertThat(extras.getLong(EXTRA_KEY_CHALLENGE)).isEqualTo(newChallenge);
|
||||
assertThat(extras.getByteArray(EXTRA_KEY_CHALLENGE_TOKEN)).isNotNull();
|
||||
assertThat(extras.getLong(EXTRA_KEY_GK_PW_HANDLE)).isEqualTo(INVALID_GK_PW_HANDLE);
|
||||
assertThat(mChallengeGenerator.mCallbackRunCount).isEqualTo(1);
|
||||
assertThat(hasCalledRemoveGkPwHandle.get()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckNewCredentialFromActivityResult_validConfirmLock() {
|
||||
final int userId = 109;
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newOnlySensorValidCredentialIntentExtras(userId)));
|
||||
when(mLockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
PASSWORD_QUALITY_SOMETHING);
|
||||
|
||||
final long gkPwHandle = 5555L;
|
||||
final int newSensorId = 80;
|
||||
final long newChallenge = 90L;
|
||||
setupGenerateChallenge(userId, newSensorId, newChallenge);
|
||||
when(mLockPatternUtils.verifyGatekeeperPasswordHandle(gkPwHandle, newChallenge, userId))
|
||||
.thenReturn(newGoodCredential(gkPwHandle, new byte[] { 1 }));
|
||||
|
||||
final AtomicBoolean hasCalledRemoveGkPwHandle = new AtomicBoolean();
|
||||
doAnswer(invocation -> {
|
||||
hasCalledRemoveGkPwHandle.set(true);
|
||||
return null;
|
||||
}).when(mLockPatternUtils).removeGatekeeperPasswordHandle(gkPwHandle);
|
||||
|
||||
// Run checkNewCredentialFromActivityResult()
|
||||
final Intent intent = new Intent().putExtra(EXTRA_KEY_GK_PW_HANDLE, gkPwHandle);
|
||||
final boolean ret = mViewModel.checkNewCredentialFromActivityResult(false,
|
||||
new ActivityResult(Activity.RESULT_OK, intent));
|
||||
|
||||
assertThat(ret).isTrue();
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull();
|
||||
final Bundle extras = mViewModel.createCredentialIntentExtra();
|
||||
assertThat(extras.getInt(EXTRA_KEY_SENSOR_ID)).isEqualTo(newSensorId);
|
||||
assertThat(extras.getLong(EXTRA_KEY_CHALLENGE)).isEqualTo(newChallenge);
|
||||
assertThat(extras.getByteArray(EXTRA_KEY_CHALLENGE_TOKEN)).isNotNull();
|
||||
assertThat(extras.getLong(EXTRA_KEY_GK_PW_HANDLE)).isEqualTo(INVALID_GK_PW_HANDLE);
|
||||
assertThat(mChallengeGenerator.mCallbackRunCount).isEqualTo(1);
|
||||
assertThat(hasCalledRemoveGkPwHandle.get()).isTrue();
|
||||
}
|
||||
|
||||
public static class TestChallengeGenerator implements ChallengeGenerator {
|
||||
public int mSensorId = INVALID_SENSOR_ID;
|
||||
public int mUserId = UserHandle.myUserId();
|
||||
public long mChallenge = INVALID_CHALLENGE;
|
||||
public int mCallbackRunCount = 0;
|
||||
private GenerateChallengeCallback mCallback;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public GenerateChallengeCallback getCallback() {
|
||||
return mCallback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCallback(@Nullable GenerateChallengeCallback callback) {
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateChallenge(int userId) {
|
||||
final GenerateChallengeCallback callback = mCallback;
|
||||
if (callback == null) {
|
||||
return;
|
||||
}
|
||||
callback.onChallengeGenerated(mSensorId, mUserId, mChallenge);
|
||||
++mCallbackRunCount;
|
||||
}
|
||||
}
|
||||
|
||||
private VerifyCredentialResponse newGoodCredential(long gkPwHandle, @NonNull byte[] hat) {
|
||||
return new VerifyCredentialResponse.Builder()
|
||||
.setGatekeeperPasswordHandle(gkPwHandle)
|
||||
.setGatekeeperHAT(hat)
|
||||
.build();
|
||||
}
|
||||
|
||||
private VerifyCredentialResponse newBadCredential(int timeout) {
|
||||
if (timeout > 0) {
|
||||
return VerifyCredentialResponse.fromTimeout(timeout);
|
||||
} else {
|
||||
return VerifyCredentialResponse.fromError();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.biometrics2.ui.viewmodel;
|
||||
|
||||
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_REAR;
|
||||
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_OPTICAL;
|
||||
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_ULTRASONIC;
|
||||
|
||||
import static com.android.settings.biometrics2.ui.model.FingerprintEnrollIntroStatus.FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX;
|
||||
import static com.android.settings.biometrics2.ui.model.FingerprintEnrollIntroStatus.FINGERPRINT_ENROLLABLE_OK;
|
||||
import static com.android.settings.biometrics2.ui.model.FingerprintEnrollIntroStatus.FINGERPRINT_ENROLLABLE_UNKNOWN;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel.FINGERPRINT_ENROLL_INTRO_ACTION_CONTINUE_ENROLL;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel.FINGERPRINT_ENROLL_INTRO_ACTION_DONE_AND_FINISH;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel.FINGERPRINT_ENROLL_INTRO_ACTION_SKIP_OR_CANCEL;
|
||||
import static com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newAllFalseRequest;
|
||||
import static com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newIsSuwDeferredRequest;
|
||||
import static com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newIsSuwPortalRequest;
|
||||
import static com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newIsSuwRequest;
|
||||
import static com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newIsSuwSuggestedActionFlowRequest;
|
||||
import static com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.newFingerprintRepository;
|
||||
import static com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.setupFingerprintEnrolledFingerprints;
|
||||
import static com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.setupSuwMaxFingerprintsEnrollable;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.res.Resources;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.biometrics2.data.repository.FingerprintRepository;
|
||||
import com.android.settings.biometrics2.ui.model.EnrollmentRequest;
|
||||
import com.android.settings.biometrics2.ui.model.FingerprintEnrollIntroStatus;
|
||||
import com.android.settings.testutils.InstantTaskExecutorRule;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class FingerprintEnrollIntroViewModelTest {
|
||||
|
||||
@Rule public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
@Rule public final InstantTaskExecutorRule mTaskExecutorRule = new InstantTaskExecutorRule();
|
||||
|
||||
@Mock private Resources mResources;
|
||||
@Mock private LifecycleOwner mLifecycleOwner;
|
||||
@Mock private FingerprintManager mFingerprintManager;
|
||||
|
||||
private Application mApplication;
|
||||
|
||||
private FingerprintEnrollIntroViewModel newFingerprintEnrollIntroViewModel(
|
||||
@NonNull FingerprintRepository fingerprintRepository) {
|
||||
final FingerprintEnrollIntroViewModel viewModel =
|
||||
new FingerprintEnrollIntroViewModel(mApplication, fingerprintRepository);
|
||||
// MediatorLiveData won't update itself unless observed
|
||||
viewModel.getPageStatusLiveData().observeForever(event -> {});
|
||||
return viewModel;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mApplication = ApplicationProvider.getApplicationContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPageStatusLiveDataDefaultValue() {
|
||||
final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5));
|
||||
final FingerprintEnrollIntroStatus status = viewModel.getPageStatusLiveData().getValue();
|
||||
assertThat(status.hasScrollToBottom()).isFalse();
|
||||
assertThat(status.getEnrollableStatus()).isEqualTo(FINGERPRINT_ENROLLABLE_UNKNOWN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClearActionLiveData() {
|
||||
final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5));
|
||||
|
||||
final MutableLiveData<Integer> actionLiveData =
|
||||
(MutableLiveData<Integer>) viewModel.getActionLiveData();
|
||||
actionLiveData.postValue(1);
|
||||
assertThat(actionLiveData.getValue()).isEqualTo(1);
|
||||
|
||||
viewModel.clearActionLiveData();
|
||||
|
||||
assertThat(actionLiveData.getValue()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetEnrollmentRequest() {
|
||||
final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5));
|
||||
final EnrollmentRequest request = newAllFalseRequest(mApplication);
|
||||
|
||||
viewModel.setEnrollmentRequest(request);
|
||||
|
||||
assertThat(viewModel.getEnrollmentRequest()).isEqualTo(request);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnStartToUpdateEnrollableStatusOk_isSuw() {
|
||||
final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5));
|
||||
final int userId = 44;
|
||||
viewModel.setUserId(userId);
|
||||
viewModel.setEnrollmentRequest(newIsSuwRequest(mApplication));
|
||||
setupFingerprintEnrolledFingerprints(mFingerprintManager, userId, 0);
|
||||
setupSuwMaxFingerprintsEnrollable(mApplication, mResources, 1);
|
||||
|
||||
viewModel.onStart(mLifecycleOwner);
|
||||
final FingerprintEnrollIntroStatus status = viewModel.getPageStatusLiveData().getValue();
|
||||
assertThat(status.getEnrollableStatus()).isEqualTo(FINGERPRINT_ENROLLABLE_OK);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnStartToUpdateEnrollableStatusReachMax_isSuw() {
|
||||
final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5));
|
||||
final int userId = 44;
|
||||
viewModel.setUserId(userId);
|
||||
viewModel.setEnrollmentRequest(newIsSuwRequest(mApplication));
|
||||
setupFingerprintEnrolledFingerprints(mFingerprintManager, userId, 1);
|
||||
setupSuwMaxFingerprintsEnrollable(mApplication, mResources, 1);
|
||||
|
||||
viewModel.onStart(mLifecycleOwner);
|
||||
final FingerprintEnrollIntroStatus status = viewModel.getPageStatusLiveData().getValue();
|
||||
assertThat(status.getEnrollableStatus()).isEqualTo(FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnStartToUpdateEnrollableStatusOk_isNotSuw() {
|
||||
testOnStartToUpdateEnrollableStatusOk(newAllFalseRequest(mApplication));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnStartToUpdateEnrollableStatusReachMax_isNotSuw() {
|
||||
testOnStartToUpdateEnrollableStatusReachMax(newAllFalseRequest(mApplication));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnStartToUpdateEnrollableStatusOk_isSuwDeferred() {
|
||||
testOnStartToUpdateEnrollableStatusOk(newIsSuwDeferredRequest(mApplication));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnStartToUpdateEnrollableStatusReachMax_isSuwDeferred() {
|
||||
testOnStartToUpdateEnrollableStatusReachMax(newIsSuwDeferredRequest(mApplication));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnStartToUpdateEnrollableStatusOk_isSuwPortal() {
|
||||
testOnStartToUpdateEnrollableStatusOk(newIsSuwPortalRequest(mApplication));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnStartToUpdateEnrollableStatusReachMax_isSuwPortal() {
|
||||
testOnStartToUpdateEnrollableStatusReachMax(newIsSuwPortalRequest(mApplication));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnStartToUpdateEnrollableStatusOk_isSuwSuggestedActionFlow() {
|
||||
testOnStartToUpdateEnrollableStatusOk(newIsSuwSuggestedActionFlowRequest(mApplication));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnStartToUpdateEnrollableStatusReachMax_isSuwSuggestedActionFlow() {
|
||||
testOnStartToUpdateEnrollableStatusReachMax(
|
||||
newIsSuwSuggestedActionFlowRequest(mApplication));
|
||||
}
|
||||
|
||||
private void testOnStartToUpdateEnrollableStatusOk(@NonNull EnrollmentRequest request) {
|
||||
final int userId = 45;
|
||||
final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5));
|
||||
viewModel.setUserId(userId);
|
||||
viewModel.setEnrollmentRequest(request);
|
||||
setupFingerprintEnrolledFingerprints(mFingerprintManager, userId, 0);
|
||||
|
||||
viewModel.onStart(mLifecycleOwner);
|
||||
FingerprintEnrollIntroStatus status = viewModel.getPageStatusLiveData().getValue();
|
||||
assertThat(status.getEnrollableStatus()).isEqualTo(FINGERPRINT_ENROLLABLE_OK);
|
||||
}
|
||||
|
||||
private void testOnStartToUpdateEnrollableStatusReachMax(@NonNull EnrollmentRequest request) {
|
||||
final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5));
|
||||
final int userId = 45;
|
||||
viewModel.setUserId(userId);
|
||||
viewModel.setEnrollmentRequest(request);
|
||||
setupFingerprintEnrolledFingerprints(mFingerprintManager, userId, 5);
|
||||
|
||||
viewModel.onStart(mLifecycleOwner);
|
||||
FingerprintEnrollIntroStatus status = viewModel.getPageStatusLiveData().getValue();
|
||||
assertThat(status.getEnrollableStatus()).isEqualTo(FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void textCanAssumeUdfps_forUdfpsUltrasonicSensor() {
|
||||
final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_ULTRASONIC, 5));
|
||||
|
||||
assertThat(viewModel.canAssumeUdfps()).isEqualTo(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void textCanAssumeUdfps_forRearSensor() {
|
||||
final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_REAR, 5));
|
||||
|
||||
assertThat(viewModel.canAssumeUdfps()).isEqualTo(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsParentalConsentRequired() {
|
||||
// We shall not mock FingerprintRepository, but
|
||||
// FingerprintRepository.isParentalConsentRequired() calls static method inside, we can't
|
||||
// mock static method
|
||||
final FingerprintRepository fingerprintRepository = mock(FingerprintRepository.class);
|
||||
final FingerprintEnrollIntroViewModel viewModel =
|
||||
new FingerprintEnrollIntroViewModel(mApplication, fingerprintRepository);
|
||||
|
||||
when(fingerprintRepository.isParentalConsentRequired(mApplication)).thenReturn(true);
|
||||
assertThat(viewModel.isParentalConsentRequired()).isEqualTo(true);
|
||||
|
||||
when(fingerprintRepository.isParentalConsentRequired(mApplication)).thenReturn(false);
|
||||
assertThat(viewModel.isParentalConsentRequired()).isEqualTo(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsBiometricUnlockDisabledByAdmin() {
|
||||
// We shall not mock FingerprintRepository, but
|
||||
// FingerprintRepository.isDisabledByAdmin() calls static method inside, we can't mock
|
||||
// static method
|
||||
final FingerprintRepository fingerprintRepository = mock(FingerprintRepository.class);
|
||||
final FingerprintEnrollIntroViewModel viewModel =
|
||||
new FingerprintEnrollIntroViewModel(mApplication, fingerprintRepository);
|
||||
|
||||
final int userId = 33;
|
||||
viewModel.setUserId(userId);
|
||||
|
||||
when(fingerprintRepository.isDisabledByAdmin(mApplication, userId)).thenReturn(true);
|
||||
assertThat(viewModel.isBiometricUnlockDisabledByAdmin()).isEqualTo(true);
|
||||
|
||||
when(fingerprintRepository.isDisabledByAdmin(mApplication, userId)).thenReturn(false);
|
||||
assertThat(viewModel.isBiometricUnlockDisabledByAdmin()).isEqualTo(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetHasScrolledToBottom() {
|
||||
final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5));
|
||||
|
||||
viewModel.setHasScrolledToBottom(true);
|
||||
FingerprintEnrollIntroStatus status = viewModel.getPageStatusLiveData().getValue();
|
||||
assertThat(status.hasScrollToBottom()).isEqualTo(true);
|
||||
|
||||
viewModel.setHasScrolledToBottom(false);
|
||||
status = viewModel.getPageStatusLiveData().getValue();
|
||||
assertThat(status.hasScrollToBottom()).isEqualTo(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnNextButtonClick_enrollNext() {
|
||||
final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5));
|
||||
final int userId = 46;
|
||||
viewModel.setUserId(userId);
|
||||
viewModel.setEnrollmentRequest(newIsSuwRequest(mApplication));
|
||||
|
||||
// Set latest status to FINGERPRINT_ENROLLABLE_OK
|
||||
setupFingerprintEnrolledFingerprints(mFingerprintManager, userId, 0);
|
||||
setupSuwMaxFingerprintsEnrollable(mApplication, mResources, 1);
|
||||
|
||||
viewModel.onStart(mLifecycleOwner);
|
||||
FingerprintEnrollIntroStatus status = viewModel.getPageStatusLiveData().getValue();
|
||||
assertThat(status.getEnrollableStatus()).isEqualTo(FINGERPRINT_ENROLLABLE_OK);
|
||||
|
||||
// Perform click on `next`
|
||||
viewModel.onNextButtonClick();
|
||||
|
||||
assertThat(viewModel.getActionLiveData().getValue())
|
||||
.isEqualTo(FINGERPRINT_ENROLL_INTRO_ACTION_CONTINUE_ENROLL);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnNextButtonClick_doneAndFinish() {
|
||||
final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5));
|
||||
final int userId = 46;
|
||||
viewModel.setUserId(userId);
|
||||
viewModel.setEnrollmentRequest(newIsSuwRequest(mApplication));
|
||||
|
||||
// Set latest status to FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX
|
||||
setupFingerprintEnrolledFingerprints(mFingerprintManager, userId, 1);
|
||||
setupSuwMaxFingerprintsEnrollable(mApplication, mResources, 1);
|
||||
|
||||
viewModel.onStart(mLifecycleOwner);
|
||||
FingerprintEnrollIntroStatus status = viewModel.getPageStatusLiveData().getValue();
|
||||
assertThat(status.getEnrollableStatus()).isEqualTo(FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX);
|
||||
|
||||
// Perform click on `next`
|
||||
viewModel.onNextButtonClick();
|
||||
|
||||
assertThat(viewModel.getActionLiveData().getValue())
|
||||
.isEqualTo(FINGERPRINT_ENROLL_INTRO_ACTION_DONE_AND_FINISH);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnSkipOrCancelButtonClick() {
|
||||
final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5));
|
||||
|
||||
viewModel.onSkipOrCancelButtonClick();
|
||||
|
||||
assertThat(viewModel.getActionLiveData().getValue())
|
||||
.isEqualTo(FINGERPRINT_ENROLL_INTRO_ACTION_SKIP_OR_CANCEL);
|
||||
}
|
||||
}
|
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.biometrics2.ui.viewmodel;
|
||||
|
||||
import static android.hardware.fingerprint.FingerprintManager.ENROLL_ENROLL;
|
||||
import static android.hardware.fingerprint.FingerprintManager.ENROLL_FIND_SENSOR;
|
||||
import static android.hardware.fingerprint.FingerprintManager.EnrollReason;
|
||||
import static android.hardware.fingerprint.FingerprintManager.EnrollmentCallback;
|
||||
|
||||
import static com.android.settings.biometrics2.ui.model.EnrollmentProgress.INITIAL_STEPS;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.only;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.res.Resources;
|
||||
import android.os.CancellationSignal;
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.biometrics.fingerprint.FingerprintUpdater;
|
||||
import com.android.settings.biometrics2.ui.model.EnrollmentProgress;
|
||||
import com.android.settings.testutils.InstantTaskExecutorRule;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class FingerprintEnrollProgressViewModelTest {
|
||||
|
||||
@Rule public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
@Rule public final InstantTaskExecutorRule mTaskExecutorRule = new InstantTaskExecutorRule();
|
||||
|
||||
@Mock private Application mApplication;
|
||||
@Mock private Resources mResources;
|
||||
@Mock private FingerprintUpdater mFingerprintUpdater;
|
||||
|
||||
private FingerprintEnrollProgressViewModel mViewModel;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
when(mApplication.getResources()).thenReturn(mResources);
|
||||
when(mResources.getBoolean(R.bool.enrollment_message_display_controller_flag))
|
||||
.thenReturn(false);
|
||||
mViewModel = new FingerprintEnrollProgressViewModel(mApplication, mFingerprintUpdater);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartEnrollment() {
|
||||
@EnrollReason final int enrollReason = ENROLL_FIND_SENSOR;
|
||||
final int userId = 334;
|
||||
final byte[] token = new byte[] { 1, 2, 3 };
|
||||
mViewModel.setToken(token);
|
||||
mViewModel.setUserId(userId);
|
||||
|
||||
// Start enrollment
|
||||
final boolean ret = mViewModel.startEnrollment(enrollReason);
|
||||
|
||||
assertThat(ret).isTrue();
|
||||
verify(mFingerprintUpdater, only()).enroll(eq(token), any(CancellationSignal.class),
|
||||
eq(userId), any(EnrollmentCallback.class), eq(enrollReason));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartEnrollmentFailBecauseOfNoToken() {
|
||||
// Start enrollment
|
||||
final boolean ret = mViewModel.startEnrollment(ENROLL_FIND_SENSOR);
|
||||
|
||||
assertThat(ret).isFalse();
|
||||
verify(mFingerprintUpdater, never()).enroll(any(byte[].class),
|
||||
any(CancellationSignal.class), anyInt(), any(EnrollmentCallback.class), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancelEnrollment() {
|
||||
@EnrollReason final int enrollReason = ENROLL_ENROLL;
|
||||
final int userId = 334;
|
||||
final byte[] token = new byte[] { 1, 2, 3 };
|
||||
mViewModel.setToken(token);
|
||||
mViewModel.setUserId(userId);
|
||||
|
||||
final TestWrapper<CancellationSignal> signalWrapper = new TestWrapper<>();
|
||||
doAnswer(invocation -> {
|
||||
signalWrapper.mValue = invocation.getArgument(1);
|
||||
return null;
|
||||
}).when(mFingerprintUpdater).enroll(any(byte[].class), any(CancellationSignal.class),
|
||||
eq(userId), any(EnrollmentCallback.class), anyInt());
|
||||
|
||||
// Start enrollment
|
||||
final boolean ret = mViewModel.startEnrollment(enrollReason);
|
||||
assertThat(ret).isTrue();
|
||||
assertThat(signalWrapper.mValue).isNotNull();
|
||||
|
||||
// Cancel enrollment
|
||||
mViewModel.cancelEnrollment();
|
||||
|
||||
assertThat(signalWrapper.mValue.isCanceled()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProgressUpdate() {
|
||||
@EnrollReason final int enrollReason = ENROLL_ENROLL;
|
||||
final int userId = 334;
|
||||
final byte[] token = new byte[] { 1, 2, 3 };
|
||||
mViewModel.setToken(token);
|
||||
mViewModel.setUserId(userId);
|
||||
|
||||
final TestWrapper<EnrollmentCallback> callbackWrapper = new TestWrapper<>();
|
||||
doAnswer(invocation -> {
|
||||
callbackWrapper.mValue = invocation.getArgument(3);
|
||||
return null;
|
||||
}).when(mFingerprintUpdater).enroll(any(byte[].class), any(CancellationSignal.class),
|
||||
eq(userId), any(EnrollmentCallback.class), anyInt());
|
||||
|
||||
// Start enrollment
|
||||
final boolean ret = mViewModel.startEnrollment(enrollReason);
|
||||
assertThat(ret).isTrue();
|
||||
assertThat(callbackWrapper.mValue).isNotNull();
|
||||
|
||||
// Update first progress
|
||||
callbackWrapper.mValue.onEnrollmentProgress(25);
|
||||
EnrollmentProgress progress = mViewModel.getProgressLiveData().getValue();
|
||||
assertThat(progress).isNotNull();
|
||||
assertThat(progress.getSteps()).isEqualTo(25);
|
||||
// TODO(b/260957933) verify getRemaining() when it is really used
|
||||
//assertThat(progress.getRemaining()).isEqualTo(25);
|
||||
|
||||
// Update second progress
|
||||
callbackWrapper.mValue.onEnrollmentProgress(20);
|
||||
progress = mViewModel.getProgressLiveData().getValue();
|
||||
assertThat(progress).isNotNull();
|
||||
assertThat(progress.getSteps()).isEqualTo(25);
|
||||
// TODO(b/260957933) verify getRemaining() when it is really used
|
||||
//assertThat(progress.getRemaining()).isEqualTo(20);
|
||||
|
||||
// Clear progress
|
||||
mViewModel.clearProgressLiveData();
|
||||
progress = mViewModel.getProgressLiveData().getValue();
|
||||
assertThat(progress).isNotNull();
|
||||
assertThat(progress.getSteps()).isEqualTo(INITIAL_STEPS);
|
||||
// TODO(b/260957933) verify getRemaining() when it is really used
|
||||
//assertThat(progress.getRemaining()).isEqualTo(INITIAL_REMAINING);
|
||||
}
|
||||
|
||||
// TODO(b/260957933): FingerprintEnrollProgressViewModel::getErrorLiveData() and
|
||||
// FingerprintEnrollProgressViewModel::getHelpLiveData() doesn't built into apk because no one
|
||||
// uses it. We shall test it when new FingerprintEnrollEnrolling has used these 2 methods.
|
||||
|
||||
private static class TestWrapper<T> {
|
||||
T mValue;
|
||||
}
|
||||
}
|
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.biometrics2.ui.viewmodel;
|
||||
|
||||
import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_FINISHED;
|
||||
import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_SKIP;
|
||||
import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_TIMEOUT;
|
||||
import static com.android.settings.biometrics.fingerprint.SetupFingerprintEnrollIntroduction.EXTRA_FINGERPRINT_ENROLLED_COUNT;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollmentViewModel.SAVED_STATE_IS_WAITING_ACTIVITY_RESULT;
|
||||
import static com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newAllFalseRequest;
|
||||
import static com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newIsSuwRequest;
|
||||
import static com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.setupFingerprintEnrolledFingerprints;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Application;
|
||||
import android.app.KeyguardManager;
|
||||
import android.content.Intent;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.activity.result.ActivityResult;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.biometrics2.data.repository.FingerprintRepository;
|
||||
import com.android.settings.biometrics2.ui.model.EnrollmentRequest;
|
||||
import com.android.settings.password.SetupSkipDialog;
|
||||
import com.android.settings.testutils.InstantTaskExecutorRule;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class FingerprintEnrollmentViewModelTest {
|
||||
|
||||
@Rule public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
@Rule public final InstantTaskExecutorRule mTaskExecutorRule = new InstantTaskExecutorRule();
|
||||
|
||||
@Mock private FingerprintManager mFingerprintManager;
|
||||
@Mock private KeyguardManager mKeyguardManager;
|
||||
|
||||
private Application mApplication;
|
||||
private FingerprintRepository mFingerprintRepository;
|
||||
private FingerprintEnrollmentViewModel mViewModel;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mApplication = ApplicationProvider.getApplicationContext();
|
||||
mFingerprintRepository = new FingerprintRepository(mFingerprintManager);
|
||||
mViewModel = new FingerprintEnrollmentViewModel(mApplication, mFingerprintRepository,
|
||||
mKeyguardManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRequest() {
|
||||
when(mKeyguardManager.isKeyguardSecure()).thenReturn(true);
|
||||
assertThat(mViewModel.getRequest()).isNull();
|
||||
|
||||
final EnrollmentRequest request = newAllFalseRequest(mApplication);
|
||||
mViewModel.setRequest(request);
|
||||
assertThat(mViewModel.getRequest()).isEqualTo(request);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNextActivityBaseIntentExtras() {
|
||||
mViewModel.setRequest(newAllFalseRequest(mApplication));
|
||||
assertThat(mViewModel.getNextActivityBaseIntentExtras()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnContinueEnrollActivityResult_shouldRelaySkip1Result() {
|
||||
mViewModel.setRequest(newAllFalseRequest(mApplication));
|
||||
final ActivityResult result = new ActivityResult(RESULT_SKIP, null);
|
||||
|
||||
// Run onContinueEnrollActivityResult
|
||||
mViewModel.onContinueEnrollActivityResult(result, 100);
|
||||
|
||||
assertThat(mViewModel.getSetResultLiveData().getValue()).isEqualTo(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnContinueEnrollActivityResult_shouldRelaySkip2Result() {
|
||||
mViewModel.setRequest(newAllFalseRequest(mApplication));
|
||||
final ActivityResult result = new ActivityResult(SetupSkipDialog.RESULT_SKIP, null);
|
||||
|
||||
// Run onContinueEnrollActivityResult
|
||||
mViewModel.onContinueEnrollActivityResult(result, 100);
|
||||
|
||||
assertThat(mViewModel.getSetResultLiveData().getValue()).isEqualTo(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnContinueEnrollActivityResult_shouldRelayNullDataTimeoutResult() {
|
||||
mViewModel.setRequest(newAllFalseRequest(mApplication));
|
||||
final ActivityResult result = new ActivityResult(RESULT_TIMEOUT, null);
|
||||
|
||||
// Run onContinueEnrollActivityResult
|
||||
mViewModel.onContinueEnrollActivityResult(result, 100);
|
||||
final ActivityResult setResult = mViewModel.getSetResultLiveData().getValue();
|
||||
|
||||
assertThat(setResult).isNotNull();
|
||||
assertThat(setResult.getResultCode()).isEqualTo(result.getResultCode());
|
||||
assertThat(setResult.getData()).isEqualTo(result.getData());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnContinueEnrollActivityResult_shouldRelayWithDataTimeoutResult() {
|
||||
mViewModel.setRequest(newAllFalseRequest(mApplication));
|
||||
final Intent intent = new Intent("testAction");
|
||||
intent.putExtra("testKey", "testValue");
|
||||
final ActivityResult result = new ActivityResult(RESULT_TIMEOUT, intent);
|
||||
|
||||
// Run onContinueEnrollActivityResult
|
||||
mViewModel.onContinueEnrollActivityResult(result, 100);
|
||||
final ActivityResult setResult = mViewModel.getSetResultLiveData().getValue();
|
||||
|
||||
assertThat(setResult).isNotNull();
|
||||
assertThat(setResult.getResultCode()).isEqualTo(result.getResultCode());
|
||||
assertThat(setResult.getData()).isEqualTo(intent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnContinueEnrollActivityResult_shouldRelayNullDataFinishResult() {
|
||||
mViewModel.setRequest(newAllFalseRequest(mApplication));
|
||||
final ActivityResult result = new ActivityResult(RESULT_FINISHED, null);
|
||||
|
||||
// Run onContinueEnrollActivityResult
|
||||
mViewModel.onContinueEnrollActivityResult(result, 100);
|
||||
final ActivityResult setResult = mViewModel.getSetResultLiveData().getValue();
|
||||
|
||||
assertThat(setResult).isNotNull();
|
||||
assertThat(setResult.getResultCode()).isEqualTo(result.getResultCode());
|
||||
assertThat(setResult.getData()).isEqualTo(result.getData());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnContinueEnrollActivityResult_shouldRelayWithDataFinishResult() {
|
||||
mViewModel.setRequest(newAllFalseRequest(mApplication));
|
||||
final Intent intent = new Intent("testAction");
|
||||
intent.putExtra("testKey", "testValue");
|
||||
final ActivityResult result = new ActivityResult(RESULT_FINISHED, intent);
|
||||
|
||||
// Run onContinueEnrollActivityResult
|
||||
mViewModel.onContinueEnrollActivityResult(result, 100);
|
||||
final ActivityResult setResult = mViewModel.getSetResultLiveData().getValue();
|
||||
|
||||
assertThat(setResult).isNotNull();
|
||||
assertThat(setResult.getResultCode()).isEqualTo(result.getResultCode());
|
||||
assertThat(setResult.getData()).isEqualTo(intent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnContinueEnrollActivityResult_shouldRelayNullDataFinishResultAsNewData() {
|
||||
when(mKeyguardManager.isKeyguardSecure()).thenReturn(true);
|
||||
final int userId = 111;
|
||||
final int numOfFp = 4;
|
||||
setupFingerprintEnrolledFingerprints(mFingerprintManager, userId, numOfFp);
|
||||
mViewModel.setRequest(newIsSuwRequest(mApplication));
|
||||
final ActivityResult result = new ActivityResult(RESULT_FINISHED, null);
|
||||
|
||||
// Run onContinueEnrollActivityResult
|
||||
mViewModel.onContinueEnrollActivityResult(result, userId);
|
||||
final ActivityResult setResult = mViewModel.getSetResultLiveData().getValue();
|
||||
|
||||
assertThat(setResult).isNotNull();
|
||||
assertThat(setResult.getResultCode()).isEqualTo(result.getResultCode());
|
||||
assertThat(setResult.getData()).isNotNull();
|
||||
assertThat(setResult.getData().getExtras()).isNotNull();
|
||||
assertThat(setResult.getData().getExtras().getInt(EXTRA_FINGERPRINT_ENROLLED_COUNT, -1))
|
||||
.isEqualTo(numOfFp);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnContinueEnrollActivityResult_shouldRelayWithDataFinishResultAsNewData() {
|
||||
when(mKeyguardManager.isKeyguardSecure()).thenReturn(true);
|
||||
final int userId = 20;
|
||||
final int numOfFp = 9;
|
||||
setupFingerprintEnrolledFingerprints(mFingerprintManager, userId, numOfFp);
|
||||
mViewModel.setRequest(newIsSuwRequest(mApplication));
|
||||
final String action = "testAction";
|
||||
final String key = "testKey";
|
||||
final String value = "testValue";
|
||||
final Intent intent = new Intent(action);
|
||||
intent.putExtra(key, value);
|
||||
final ActivityResult result = new ActivityResult(RESULT_FINISHED, intent);
|
||||
|
||||
// Run onContinueEnrollActivityResult
|
||||
mViewModel.onContinueEnrollActivityResult(result, userId);
|
||||
final ActivityResult setResult = mViewModel.getSetResultLiveData().getValue();
|
||||
|
||||
assertThat(setResult).isNotNull();
|
||||
assertThat(setResult.getResultCode()).isEqualTo(result.getResultCode());
|
||||
assertThat(setResult.getData()).isNotNull();
|
||||
assertThat(setResult.getData().getExtras()).isNotNull();
|
||||
assertThat(setResult.getData().getExtras().getInt(EXTRA_FINGERPRINT_ENROLLED_COUNT, -1))
|
||||
.isEqualTo(numOfFp);
|
||||
assertThat(setResult.getData().getExtras().getString(key)).isEqualTo(value);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetSavedInstanceState() {
|
||||
final Bundle bundle = new Bundle();
|
||||
mViewModel.isWaitingActivityResult().set(true);
|
||||
|
||||
// setSavedInstanceState() as false
|
||||
bundle.putBoolean(SAVED_STATE_IS_WAITING_ACTIVITY_RESULT, false);
|
||||
mViewModel.setSavedInstanceState(bundle);
|
||||
assertThat(mViewModel.isWaitingActivityResult().get()).isFalse();
|
||||
|
||||
// setSavedInstanceState() as false
|
||||
bundle.putBoolean(SAVED_STATE_IS_WAITING_ACTIVITY_RESULT, true);
|
||||
mViewModel.setSavedInstanceState(bundle);
|
||||
assertThat(mViewModel.isWaitingActivityResult().get()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnSaveInstanceState() {
|
||||
final Bundle bundle = new Bundle();
|
||||
|
||||
// setSavedInstanceState() as false
|
||||
mViewModel.isWaitingActivityResult().set(false);
|
||||
mViewModel.onSaveInstanceState(bundle);
|
||||
assertThat(bundle.getBoolean(SAVED_STATE_IS_WAITING_ACTIVITY_RESULT)).isFalse();
|
||||
|
||||
// setSavedInstanceState() as false
|
||||
mViewModel.isWaitingActivityResult().set(true);
|
||||
mViewModel.onSaveInstanceState(bundle);
|
||||
assertThat(bundle.getBoolean(SAVED_STATE_IS_WAITING_ACTIVITY_RESULT)).isTrue();
|
||||
}
|
||||
}
|
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.biometrics2.utils;
|
||||
|
||||
import static com.android.settings.biometrics.BiometricEnrollBase.EXTRA_FROM_SETTINGS_SUMMARY;
|
||||
|
||||
import static com.google.android.setupcompat.util.WizardManagerHelper.EXTRA_IS_DEFERRED_SETUP;
|
||||
import static com.google.android.setupcompat.util.WizardManagerHelper.EXTRA_IS_FIRST_RUN;
|
||||
import static com.google.android.setupcompat.util.WizardManagerHelper.EXTRA_IS_PORTAL_SETUP;
|
||||
import static com.google.android.setupcompat.util.WizardManagerHelper.EXTRA_IS_SETUP_FLOW;
|
||||
import static com.google.android.setupcompat.util.WizardManagerHelper.EXTRA_IS_SUW_SUGGESTED_ACTION_FLOW;
|
||||
import static com.google.android.setupcompat.util.WizardManagerHelper.EXTRA_THEME;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.settings.biometrics2.ui.model.EnrollmentRequest;
|
||||
|
||||
public class EnrollmentRequestUtils {
|
||||
|
||||
@NonNull
|
||||
public static EnrollmentRequest newAllFalseRequest(@NonNull Context context) {
|
||||
return newRequest(context, false, false, false, false, false, false, null);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static EnrollmentRequest newIsSuwRequest(@NonNull Context context) {
|
||||
return newRequest(context, true, false, false, false, false, false, null);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static EnrollmentRequest newIsSuwDeferredRequest(@NonNull Context context) {
|
||||
return newRequest(context, true, true, false, false, false, false, null);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static EnrollmentRequest newIsSuwPortalRequest(@NonNull Context context) {
|
||||
return newRequest(context, true, false, true, false, false, false, null);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static EnrollmentRequest newIsSuwSuggestedActionFlowRequest(
|
||||
@NonNull Context context) {
|
||||
return newRequest(context, true, false, false, true, false, false, null);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static EnrollmentRequest newRequest(@NonNull Context context, boolean isSuw,
|
||||
boolean isSuwDeferred, boolean isSuwPortal, boolean isSuwSuggestedActionFlow,
|
||||
boolean isSuwFirstRun, boolean isFromSettingsSummery, String theme) {
|
||||
Intent i = new Intent();
|
||||
i.putExtra(EXTRA_IS_SETUP_FLOW, isSuw);
|
||||
i.putExtra(EXTRA_IS_DEFERRED_SETUP, isSuwDeferred);
|
||||
i.putExtra(EXTRA_IS_PORTAL_SETUP, isSuwPortal);
|
||||
i.putExtra(EXTRA_IS_SUW_SUGGESTED_ACTION_FLOW, isSuwSuggestedActionFlow);
|
||||
i.putExtra(EXTRA_IS_FIRST_RUN, isSuwFirstRun);
|
||||
i.putExtra(EXTRA_FROM_SETTINGS_SUMMARY, isFromSettingsSummery);
|
||||
if (!TextUtils.isEmpty(theme)) {
|
||||
i.putExtra(EXTRA_THEME, theme);
|
||||
}
|
||||
return new EnrollmentRequest(i, context);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.biometrics2.utils;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.hardware.biometrics.SensorProperties;
|
||||
import android.hardware.fingerprint.Fingerprint;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.hardware.fingerprint.FingerprintSensorProperties;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.settings.biometrics2.data.repository.FingerprintRepository;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class FingerprintRepositoryUtils {
|
||||
|
||||
public static void setupSuwMaxFingerprintsEnrollable(
|
||||
@NonNull Context context,
|
||||
@NonNull Resources mockedResources,
|
||||
int numOfFp) {
|
||||
final int resId = context.getResources().getIdentifier("suw_max_fingerprints_enrollable",
|
||||
"integer", context.getPackageName());
|
||||
when(mockedResources.getInteger(resId)).thenReturn(numOfFp);
|
||||
}
|
||||
|
||||
public static FingerprintRepository newFingerprintRepository(
|
||||
@NonNull FingerprintManager mockedFingerprintManager,
|
||||
@FingerprintSensorProperties.SensorType int sensorType,
|
||||
int maxEnrollmentsPerUser) {
|
||||
|
||||
final ArrayList<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
|
||||
props.add(new FingerprintSensorPropertiesInternal(
|
||||
0 /* sensorId */,
|
||||
SensorProperties.STRENGTH_STRONG,
|
||||
maxEnrollmentsPerUser,
|
||||
new ArrayList<>() /* componentInfo */,
|
||||
sensorType,
|
||||
true /* resetLockoutRequiresHardwareAuthToken */));
|
||||
doAnswer(invocation -> {
|
||||
final IFingerprintAuthenticatorsRegisteredCallback callback =
|
||||
invocation.getArgument(0);
|
||||
callback.onAllAuthenticatorsRegistered(props);
|
||||
return null;
|
||||
}).when(mockedFingerprintManager).addAuthenticatorsRegisteredCallback(any());
|
||||
return new FingerprintRepository(mockedFingerprintManager);
|
||||
}
|
||||
|
||||
public static void setupFingerprintEnrolledFingerprints(
|
||||
@NonNull FingerprintManager mockedFingerprintManager,
|
||||
int userId,
|
||||
int enrolledFingerprints) {
|
||||
final ArrayList<Fingerprint> ret = new ArrayList<>();
|
||||
for (int i = 0; i < enrolledFingerprints; ++i) {
|
||||
ret.add(new Fingerprint("name", 0, 0, 0L));
|
||||
}
|
||||
when(mockedFingerprintManager.getEnrolledFingerprints(userId)).thenReturn(ret);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user