Remove package biometric2 from AOSP settings
Flag: EXEMPT Remove legacy code from AOSP Bug: 351977012 Test: Build pass Change-Id: I2285ab8cc2776071c329d7432849aeffc28ed8ee
This commit is contained in:
@@ -1 +0,0 @@
|
||||
include /src/com/android/settings/biometrics/OWNERS
|
@@ -1,203 +0,0 @@
|
||||
/*
|
||||
* 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 static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.hardware.biometrics.SensorProperties;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
|
||||
|
||||
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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetFirstFingerprintSensorPropertiesInternal() {
|
||||
final ArrayList<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
|
||||
final FingerprintSensorPropertiesInternal prop = new FingerprintSensorPropertiesInternal(
|
||||
0 /* sensorId */,
|
||||
SensorProperties.STRENGTH_STRONG,
|
||||
5,
|
||||
new ArrayList<>() /* componentInfo */,
|
||||
TYPE_UDFPS_OPTICAL,
|
||||
true /* resetLockoutRequiresHardwareAuthToken */);
|
||||
props.add(prop);
|
||||
doAnswer(invocation -> {
|
||||
final IFingerprintAuthenticatorsRegisteredCallback callback =
|
||||
invocation.getArgument(0);
|
||||
callback.onAllAuthenticatorsRegistered(props);
|
||||
return null;
|
||||
}).when(mFingerprintManager).addAuthenticatorsRegisteredCallback(any());
|
||||
|
||||
final FingerprintRepository repository = new FingerprintRepository(mFingerprintManager);
|
||||
assertThat(repository.getFirstFingerprintSensorPropertiesInternal()).isEqualTo(prop);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetEnrollStageCount() {
|
||||
final FingerprintRepository repository = newFingerprintRepository(mFingerprintManager,
|
||||
TYPE_UNKNOWN, 999);
|
||||
|
||||
final int expectedValue = 24;
|
||||
doReturn(expectedValue).when(mFingerprintManager).getEnrollStageCount();
|
||||
|
||||
assertThat(repository.getEnrollStageCount()).isEqualTo(expectedValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetEnrollStageThreshold() {
|
||||
final FingerprintRepository repository = newFingerprintRepository(mFingerprintManager,
|
||||
TYPE_UNKNOWN, 999);
|
||||
|
||||
final float expectedValue0 = 0.42f;
|
||||
final float expectedValue1 = 0.24f;
|
||||
final float expectedValue2 = 0.33f;
|
||||
final float expectedValue3 = 0.90f;
|
||||
doReturn(expectedValue0).when(mFingerprintManager).getEnrollStageThreshold(0);
|
||||
doReturn(expectedValue1).when(mFingerprintManager).getEnrollStageThreshold(1);
|
||||
doReturn(expectedValue2).when(mFingerprintManager).getEnrollStageThreshold(2);
|
||||
doReturn(expectedValue3).when(mFingerprintManager).getEnrollStageThreshold(3);
|
||||
|
||||
assertThat(repository.getEnrollStageThreshold(2)).isEqualTo(expectedValue2);
|
||||
assertThat(repository.getEnrollStageThreshold(1)).isEqualTo(expectedValue1);
|
||||
assertThat(repository.getEnrollStageThreshold(3)).isEqualTo(expectedValue3);
|
||||
assertThat(repository.getEnrollStageThreshold(0)).isEqualTo(expectedValue0);
|
||||
}
|
||||
}
|
@@ -1,136 +0,0 @@
|
||||
/*
|
||||
* 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 android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.os.SystemClock
|
||||
import android.os.UserHandle
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.settings.biometrics.BiometricEnrollBase
|
||||
import com.android.settings.password.ChooseLockSettingsHelper
|
||||
import com.google.common.truth.Truth
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import java.util.Arrays
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class CredentialModelTest {
|
||||
|
||||
private val clock = SystemClock.elapsedRealtimeClock()
|
||||
|
||||
@Test
|
||||
fun testNullBundle() {
|
||||
val credentialModel = CredentialModel(null, clock)
|
||||
Truth.assertThat(credentialModel.userId).isEqualTo(UserHandle.myUserId())
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun newCredentialModelIntentExtras(
|
||||
userId: Int, challenge: Long,
|
||||
token: ByteArray?, gkPwHandle: Long
|
||||
): Bundle {
|
||||
val bundle = Bundle()
|
||||
bundle.putInt(Intent.EXTRA_USER_ID, userId)
|
||||
bundle.putLong(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, challenge)
|
||||
bundle.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token)
|
||||
bundle.putLong(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, gkPwHandle)
|
||||
return bundle
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun newValidTokenCredentialIntentExtras(userId: Int): Bundle {
|
||||
return newCredentialModelIntentExtras(
|
||||
userId, 1L, byteArrayOf(0, 1, 2),
|
||||
CredentialModel.INVALID_GK_PW_HANDLE
|
||||
)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun newOnlySensorValidCredentialIntentExtras(userId: Int): Bundle {
|
||||
return newCredentialModelIntentExtras(
|
||||
userId, CredentialModel.INVALID_CHALLENGE, null,
|
||||
CredentialModel.INVALID_GK_PW_HANDLE
|
||||
)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun newGkPwHandleCredentialIntentExtras(userId: Int, gkPwHandle: Long): Bundle {
|
||||
return newCredentialModelIntentExtras(
|
||||
userId,
|
||||
CredentialModel.INVALID_CHALLENGE,
|
||||
null,
|
||||
gkPwHandle
|
||||
)
|
||||
}
|
||||
|
||||
private fun checkBundleLongValue(
|
||||
bundle1: Bundle, bundle2: Bundle,
|
||||
key: String
|
||||
) {
|
||||
if (!bundle1.containsKey(key)) {
|
||||
return
|
||||
}
|
||||
val value1 = bundle1.getInt(key)
|
||||
val value2 = bundle2.getInt(key)
|
||||
Truth.assertWithMessage(
|
||||
"bundle not match, key:" + key + ", value1:" + value1 + ", value2:"
|
||||
+ value2
|
||||
).that(value1).isEqualTo(value2)
|
||||
}
|
||||
|
||||
private fun checkBundleIntValue(
|
||||
bundle1: Bundle, bundle2: Bundle,
|
||||
key: String
|
||||
) {
|
||||
if (!bundle1.containsKey(key)) {
|
||||
return
|
||||
}
|
||||
val value1 = bundle1.getLong(key)
|
||||
val value2 = bundle2.getLong(key)
|
||||
Truth.assertWithMessage(
|
||||
"bundle not match, key:" + key + ", value1:" + value1 + ", value2:"
|
||||
+ value2
|
||||
).that(value1).isEqualTo(value2)
|
||||
}
|
||||
|
||||
private fun checkBundleByteArrayValue(
|
||||
bundle1: Bundle, bundle2: Bundle,
|
||||
key: String
|
||||
) {
|
||||
if (!bundle1.containsKey(key)) {
|
||||
return
|
||||
}
|
||||
val value1 = bundle1.getByteArray(key)
|
||||
val value2 = bundle2.getByteArray(key)
|
||||
val errMsg = ("bundle not match, key:" + key + ", value1:" + Arrays.toString(value1)
|
||||
+ ", value2:" + Arrays.toString(value2))
|
||||
if (value1 == null) {
|
||||
Truth.assertWithMessage(errMsg).that(value2).isNull()
|
||||
} else {
|
||||
Truth.assertWithMessage(errMsg).that(value1.size).isEqualTo(
|
||||
value2!!.size
|
||||
)
|
||||
for (i in value1.indices) {
|
||||
Truth.assertWithMessage(errMsg).that(value1[i]).isEqualTo(
|
||||
value2[i]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,175 +0,0 @@
|
||||
/*
|
||||
* 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 android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.settings.biometrics.BiometricEnrollActivity
|
||||
import com.google.android.setupcompat.util.WizardManagerHelper
|
||||
import com.google.common.truth.Truth
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class EnrollmentRequestTest {
|
||||
|
||||
private val context = ApplicationProvider.getApplicationContext<Context>()
|
||||
|
||||
@Test
|
||||
fun testIsSuw() {
|
||||
// Default false
|
||||
Truth.assertThat(EnrollmentRequest(Intent(), context, true).isSuw).isFalse()
|
||||
Truth.assertThat(EnrollmentRequest(Intent(), context, false).isSuw).isFalse()
|
||||
val trueIntent = Intent()
|
||||
trueIntent.putExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, true)
|
||||
Truth.assertThat(EnrollmentRequest(trueIntent, context, true).isSuw).isTrue()
|
||||
Truth.assertThat(EnrollmentRequest(trueIntent, context, false).isSuw).isFalse()
|
||||
val falseIntent = Intent()
|
||||
trueIntent.putExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, false)
|
||||
Truth.assertThat(EnrollmentRequest(falseIntent, context, true).isSuw).isFalse()
|
||||
Truth.assertThat(EnrollmentRequest(falseIntent, context, false).isSuw).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIsAfterSuwOrSuwSuggestedAction() {
|
||||
// Default false
|
||||
Truth.assertThat(
|
||||
EnrollmentRequest(Intent(), context, true)
|
||||
.isAfterSuwOrSuwSuggestedAction
|
||||
).isFalse()
|
||||
Truth.assertThat(
|
||||
EnrollmentRequest(Intent(), context, false)
|
||||
.isAfterSuwOrSuwSuggestedAction
|
||||
).isFalse()
|
||||
val deferredTrueIntent = Intent()
|
||||
deferredTrueIntent.putExtra(WizardManagerHelper.EXTRA_IS_DEFERRED_SETUP, true)
|
||||
Truth.assertThat(
|
||||
EnrollmentRequest(deferredTrueIntent, context, true)
|
||||
.isAfterSuwOrSuwSuggestedAction
|
||||
).isTrue()
|
||||
Truth.assertThat(
|
||||
EnrollmentRequest(deferredTrueIntent, context, false)
|
||||
.isAfterSuwOrSuwSuggestedAction
|
||||
).isFalse()
|
||||
val deferredFalseIntent = Intent()
|
||||
deferredFalseIntent.putExtra(WizardManagerHelper.EXTRA_IS_DEFERRED_SETUP, false)
|
||||
Truth.assertThat(
|
||||
EnrollmentRequest(deferredFalseIntent, context, false)
|
||||
.isAfterSuwOrSuwSuggestedAction
|
||||
).isFalse()
|
||||
Truth.assertThat(
|
||||
EnrollmentRequest(deferredFalseIntent, context, false)
|
||||
.isAfterSuwOrSuwSuggestedAction
|
||||
).isFalse()
|
||||
val portalTrueIntent = Intent()
|
||||
portalTrueIntent.putExtra(WizardManagerHelper.EXTRA_IS_PORTAL_SETUP, true)
|
||||
Truth.assertThat(
|
||||
EnrollmentRequest(portalTrueIntent, context, true)
|
||||
.isAfterSuwOrSuwSuggestedAction
|
||||
).isTrue()
|
||||
Truth.assertThat(
|
||||
EnrollmentRequest(portalTrueIntent, context, false)
|
||||
.isAfterSuwOrSuwSuggestedAction
|
||||
).isFalse()
|
||||
val portalFalseIntent = Intent()
|
||||
portalFalseIntent.putExtra(WizardManagerHelper.EXTRA_IS_PORTAL_SETUP, false)
|
||||
Truth.assertThat(
|
||||
EnrollmentRequest(portalFalseIntent, context, false)
|
||||
.isAfterSuwOrSuwSuggestedAction
|
||||
).isFalse()
|
||||
Truth.assertThat(
|
||||
EnrollmentRequest(portalFalseIntent, context, false)
|
||||
.isAfterSuwOrSuwSuggestedAction
|
||||
).isFalse()
|
||||
val suggestedTrueIntent = Intent()
|
||||
suggestedTrueIntent.putExtra(WizardManagerHelper.EXTRA_IS_SUW_SUGGESTED_ACTION_FLOW, true)
|
||||
Truth.assertThat(
|
||||
EnrollmentRequest(suggestedTrueIntent, context, true)
|
||||
.isAfterSuwOrSuwSuggestedAction
|
||||
).isTrue()
|
||||
Truth.assertThat(
|
||||
EnrollmentRequest(suggestedTrueIntent, context, false)
|
||||
.isAfterSuwOrSuwSuggestedAction
|
||||
).isFalse()
|
||||
val suggestedFalseIntent = Intent()
|
||||
suggestedFalseIntent.putExtra(WizardManagerHelper.EXTRA_IS_SUW_SUGGESTED_ACTION_FLOW, false)
|
||||
Truth.assertThat(
|
||||
EnrollmentRequest(suggestedFalseIntent, context, false)
|
||||
.isAfterSuwOrSuwSuggestedAction
|
||||
).isFalse()
|
||||
Truth.assertThat(
|
||||
EnrollmentRequest(suggestedFalseIntent, context, false)
|
||||
.isAfterSuwOrSuwSuggestedAction
|
||||
).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetSuwExtras_inSuw() {
|
||||
val suwIntent = Intent()
|
||||
suwIntent.putExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, true)
|
||||
val setupRequest = EnrollmentRequest(suwIntent, context, true)
|
||||
val bundle = setupRequest.suwExtras
|
||||
Truth.assertThat(bundle).isNotNull()
|
||||
Truth.assertThat(bundle.size()).isAtLeast(1)
|
||||
Truth.assertThat(bundle.getBoolean(WizardManagerHelper.EXTRA_IS_SETUP_FLOW)).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetSuwExtras_notInSuw() {
|
||||
val suwIntent = Intent()
|
||||
suwIntent.putExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, true)
|
||||
val setupRequest = EnrollmentRequest(suwIntent, context, false)
|
||||
val bundle = setupRequest.suwExtras
|
||||
Truth.assertThat(bundle).isNotNull()
|
||||
Truth.assertThat(bundle.size()).isEqualTo(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIsSkipIntro() {
|
||||
// Default false
|
||||
Truth.assertThat(EnrollmentRequest(Intent(), context, true).isSkipIntro).isFalse()
|
||||
Truth.assertThat(EnrollmentRequest(Intent(), context, false).isSkipIntro).isFalse()
|
||||
val trueIntent = Intent()
|
||||
trueIntent.putExtra(BiometricEnrollActivity.EXTRA_SKIP_INTRO, true)
|
||||
Truth.assertThat(EnrollmentRequest(trueIntent, context, true).isSkipIntro).isTrue()
|
||||
Truth.assertThat(EnrollmentRequest(trueIntent, context, false).isSkipIntro).isTrue()
|
||||
val falseIntent = Intent()
|
||||
falseIntent.putExtra(BiometricEnrollActivity.EXTRA_SKIP_INTRO, false)
|
||||
Truth.assertThat(EnrollmentRequest(falseIntent, context, false).isSkipIntro).isFalse()
|
||||
Truth.assertThat(EnrollmentRequest(falseIntent, context, false).isSkipIntro).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIsSkipFindSensor() {
|
||||
// Default false
|
||||
Truth.assertThat(EnrollmentRequest(Intent(), context, true).isSkipFindSensor)
|
||||
.isFalse()
|
||||
Truth.assertThat(EnrollmentRequest(Intent(), context, false).isSkipFindSensor)
|
||||
.isFalse()
|
||||
val trueIntent = Intent()
|
||||
trueIntent.putExtra(EnrollmentRequest.EXTRA_SKIP_FIND_SENSOR, true)
|
||||
Truth.assertThat(EnrollmentRequest(trueIntent, context, true).isSkipFindSensor).isTrue()
|
||||
Truth.assertThat(EnrollmentRequest(trueIntent, context, false).isSkipFindSensor).isTrue()
|
||||
val falseIntent = Intent()
|
||||
falseIntent.putExtra(EnrollmentRequest.EXTRA_SKIP_FIND_SENSOR, false)
|
||||
Truth.assertThat(EnrollmentRequest(falseIntent, context, false).isSkipFindSensor)
|
||||
.isFalse()
|
||||
Truth.assertThat(EnrollmentRequest(falseIntent, context, false).isSkipFindSensor)
|
||||
.isFalse()
|
||||
}
|
||||
}
|
@@ -1,519 +0,0 @@
|
||||
/*
|
||||
* 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 android.app.Activity
|
||||
import android.app.admin.DevicePolicyManager
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.os.SystemClock
|
||||
import android.os.UserHandle
|
||||
import androidx.activity.result.ActivityResult
|
||||
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.biometrics.BiometricEnrollBase
|
||||
import com.android.settings.biometrics2.ui.model.CredentialModel
|
||||
import com.android.settings.biometrics2.ui.model.CredentialModelTest.Companion.newGkPwHandleCredentialIntentExtras
|
||||
import com.android.settings.biometrics2.ui.model.CredentialModelTest.Companion.newOnlySensorValidCredentialIntentExtras
|
||||
import com.android.settings.biometrics2.ui.model.CredentialModelTest.Companion.newValidTokenCredentialIntentExtras
|
||||
import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.ChallengeGenerator
|
||||
import com.android.settings.password.ChooseLockPattern
|
||||
import com.android.settings.password.ChooseLockSettingsHelper
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import kotlinx.coroutines.flow.toList
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.UnconfinedTestDispatcher
|
||||
import kotlinx.coroutines.test.runCurrent
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito
|
||||
import org.mockito.junit.MockitoJUnit
|
||||
import org.mockito.junit.MockitoRule
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class AutoCredentialViewModelTest {
|
||||
|
||||
@get:Rule val mockito: MockitoRule = MockitoJUnit.rule()
|
||||
|
||||
@Mock private lateinit var lockPatternUtils: LockPatternUtils
|
||||
|
||||
private var challengeGenerator: TestChallengeGenerator = TestChallengeGenerator()
|
||||
|
||||
private lateinit var viewModel: AutoCredentialViewModel
|
||||
private fun newAutoCredentialViewModel(bundle: Bundle?): AutoCredentialViewModel {
|
||||
return AutoCredentialViewModel(
|
||||
ApplicationProvider.getApplicationContext(),
|
||||
lockPatternUtils,
|
||||
challengeGenerator,
|
||||
CredentialModel(bundle, SystemClock.elapsedRealtimeClock())
|
||||
)
|
||||
}
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
challengeGenerator = TestChallengeGenerator()
|
||||
}
|
||||
|
||||
private fun setupGenerateChallenge(userId: Int, newSensorId: Int, newChallenge: Long) {
|
||||
whenever(lockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
|
||||
)
|
||||
challengeGenerator.userId = userId
|
||||
challengeGenerator.sensorId = newSensorId
|
||||
challengeGenerator.challenge = newChallenge
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCheckCredential_validCredentialCase() = runTest {
|
||||
val userId = 99
|
||||
viewModel = newAutoCredentialViewModel(newValidTokenCredentialIntentExtras(userId))
|
||||
whenever(lockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
|
||||
)
|
||||
|
||||
val generateFails = listOfGenerateChallengeFailedFlow()
|
||||
|
||||
// Run credential check
|
||||
val action = viewModel.checkCredential(backgroundScope)
|
||||
runCurrent()
|
||||
|
||||
// Check viewModel behavior
|
||||
assertThat(action).isEqualTo(CredentialAction.CREDENTIAL_VALID)
|
||||
assertThat(generateFails.size).isEqualTo(0)
|
||||
|
||||
// Check createGeneratingChallengeExtras()
|
||||
assertThat(viewModel.createGeneratingChallengeExtras()).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCheckCredential_needToChooseLock() = runTest {
|
||||
val userId = 100
|
||||
viewModel = newAutoCredentialViewModel(newOnlySensorValidCredentialIntentExtras(userId))
|
||||
whenever(lockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED
|
||||
)
|
||||
|
||||
val generateFails = listOfGenerateChallengeFailedFlow()
|
||||
|
||||
// Run credential check
|
||||
val action = viewModel.checkCredential(backgroundScope)
|
||||
runCurrent()
|
||||
|
||||
// Check viewModel behavior
|
||||
assertThat(action).isEqualTo(CredentialAction.FAIL_NEED_TO_CHOOSE_LOCK)
|
||||
assertThat(generateFails.size).isEqualTo(0)
|
||||
|
||||
// Check createGeneratingChallengeExtras()
|
||||
assertThat(viewModel.createGeneratingChallengeExtras()).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCheckCredential_needToConfirmLockForSomething() = runTest {
|
||||
val userId = 101
|
||||
viewModel =
|
||||
newAutoCredentialViewModel(newOnlySensorValidCredentialIntentExtras(userId))
|
||||
whenever(lockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
|
||||
)
|
||||
|
||||
val generateFails = listOfGenerateChallengeFailedFlow()
|
||||
|
||||
// Run credential check
|
||||
val action = viewModel.checkCredential(backgroundScope)
|
||||
runCurrent()
|
||||
|
||||
// Check viewModel behavior
|
||||
assertThat(action).isEqualTo(CredentialAction.FAIL_NEED_TO_CONFIRM_LOCK)
|
||||
assertThat(generateFails.size).isEqualTo(0)
|
||||
|
||||
// Check createGeneratingChallengeExtras()
|
||||
assertThat(viewModel.createGeneratingChallengeExtras()).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCheckCredential_needToConfirmLockForNumeric() = runTest {
|
||||
val userId = 102
|
||||
viewModel =
|
||||
newAutoCredentialViewModel(newOnlySensorValidCredentialIntentExtras(userId))
|
||||
whenever(lockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
|
||||
)
|
||||
|
||||
val generateFails = listOfGenerateChallengeFailedFlow()
|
||||
|
||||
// Run credential check
|
||||
val action = viewModel.checkCredential(backgroundScope)
|
||||
runCurrent()
|
||||
|
||||
// Check viewModel behavior
|
||||
assertThat(action).isEqualTo(CredentialAction.FAIL_NEED_TO_CONFIRM_LOCK)
|
||||
assertThat(generateFails.size).isEqualTo(0)
|
||||
|
||||
// Check createGeneratingChallengeExtras()
|
||||
assertThat(viewModel.createGeneratingChallengeExtras()).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCheckCredential_needToConfirmLockForAlphabetic() = runTest {
|
||||
val userId = 103
|
||||
viewModel =
|
||||
newAutoCredentialViewModel(newOnlySensorValidCredentialIntentExtras(userId))
|
||||
whenever(lockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC
|
||||
)
|
||||
|
||||
val generateFails = listOfGenerateChallengeFailedFlow()
|
||||
|
||||
// Run credential check
|
||||
val action = viewModel.checkCredential(this)
|
||||
runCurrent()
|
||||
|
||||
// Check viewModel behavior
|
||||
assertThat(action).isEqualTo(CredentialAction.FAIL_NEED_TO_CONFIRM_LOCK)
|
||||
assertThat(generateFails.size).isEqualTo(0)
|
||||
|
||||
// Check createGeneratingChallengeExtras()
|
||||
assertThat(viewModel.createGeneratingChallengeExtras()).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCheckCredential_generateChallenge() = runTest {
|
||||
val userId = 104
|
||||
val gkPwHandle = 1111L
|
||||
viewModel =
|
||||
newAutoCredentialViewModel(newGkPwHandleCredentialIntentExtras(userId, gkPwHandle))
|
||||
whenever(lockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
|
||||
)
|
||||
val newSensorId = 10
|
||||
val newChallenge = 20L
|
||||
setupGenerateChallenge(userId, newSensorId, newChallenge)
|
||||
whenever(
|
||||
lockPatternUtils.verifyGatekeeperPasswordHandle(
|
||||
gkPwHandle,
|
||||
newChallenge,
|
||||
userId
|
||||
)
|
||||
)
|
||||
.thenReturn(newGoodCredential(gkPwHandle, byteArrayOf(1)))
|
||||
val hasCalledRemoveGkPwHandle = AtomicBoolean()
|
||||
Mockito.doAnswer {
|
||||
hasCalledRemoveGkPwHandle.set(true)
|
||||
null
|
||||
}.`when`(lockPatternUtils).removeGatekeeperPasswordHandle(gkPwHandle)
|
||||
|
||||
val generateFails = listOfGenerateChallengeFailedFlow()
|
||||
|
||||
// Run credential check
|
||||
val action = viewModel.checkCredential(backgroundScope)
|
||||
runCurrent()
|
||||
|
||||
// Check viewModel behavior
|
||||
assertThat(action).isEqualTo(CredentialAction.IS_GENERATING_CHALLENGE)
|
||||
assertThat(generateFails.size).isEqualTo(0)
|
||||
|
||||
// Check data inside CredentialModel
|
||||
assertThat(viewModel.token).isNotNull()
|
||||
assertThat(challengeGenerator.callbackRunCount).isEqualTo(1)
|
||||
assertThat(hasCalledRemoveGkPwHandle.get()).isFalse()
|
||||
|
||||
// Check createGeneratingChallengeExtras()
|
||||
val generatingChallengeExtras = viewModel.createGeneratingChallengeExtras()
|
||||
assertThat(generatingChallengeExtras).isNotNull()
|
||||
assertThat(generatingChallengeExtras!!.getLong(BiometricEnrollBase.EXTRA_KEY_CHALLENGE))
|
||||
.isEqualTo(newChallenge)
|
||||
val tokens =
|
||||
generatingChallengeExtras.getByteArray(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN)
|
||||
assertThat(tokens).isNotNull()
|
||||
assertThat(tokens!!.size).isEqualTo(1)
|
||||
assertThat(tokens[0]).isEqualTo(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCheckCredential_generateChallengeFail() = runTest {
|
||||
backgroundScope.launch {
|
||||
val userId = 104
|
||||
val gkPwHandle = 1111L
|
||||
viewModel =
|
||||
newAutoCredentialViewModel(newGkPwHandleCredentialIntentExtras(userId, gkPwHandle))
|
||||
whenever(lockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
|
||||
)
|
||||
val newSensorId = 10
|
||||
val newChallenge = 20L
|
||||
setupGenerateChallenge(userId, newSensorId, newChallenge)
|
||||
whenever(
|
||||
lockPatternUtils.verifyGatekeeperPasswordHandle(
|
||||
gkPwHandle,
|
||||
newChallenge,
|
||||
userId
|
||||
)
|
||||
)
|
||||
.thenReturn(newBadCredential(0))
|
||||
|
||||
val generateFails = listOfGenerateChallengeFailedFlow()
|
||||
|
||||
// Run credential check
|
||||
val action = viewModel.checkCredential(this)
|
||||
runCurrent()
|
||||
|
||||
assertThat(action).isEqualTo(CredentialAction.IS_GENERATING_CHALLENGE)
|
||||
assertThat(generateFails.size).isEqualTo(1)
|
||||
assertThat(generateFails[0]).isEqualTo(true)
|
||||
assertThat(challengeGenerator.callbackRunCount).isEqualTo(1)
|
||||
|
||||
// Check createGeneratingChallengeExtras()
|
||||
assertThat(viewModel.createGeneratingChallengeExtras()).isNull()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetUserId_fromIntent() {
|
||||
val userId = 106
|
||||
viewModel = newAutoCredentialViewModel(newOnlySensorValidCredentialIntentExtras(userId))
|
||||
|
||||
// Get userId
|
||||
assertThat(viewModel.userId).isEqualTo(userId)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGenerateChallengeAsCredentialActivityResult_invalidChooseLock() = runTest {
|
||||
backgroundScope.launch {
|
||||
val userId = 107
|
||||
val gkPwHandle = 3333L
|
||||
viewModel =
|
||||
newAutoCredentialViewModel(newGkPwHandleCredentialIntentExtras(userId, gkPwHandle))
|
||||
val intent = Intent()
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, gkPwHandle)
|
||||
|
||||
val generateFails = listOfGenerateChallengeFailedFlow()
|
||||
|
||||
// Run generateChallengeAsCredentialActivityResult()
|
||||
val ret = viewModel.generateChallengeAsCredentialActivityResult(
|
||||
true,
|
||||
ActivityResult(ChooseLockPattern.RESULT_FINISHED + 1, intent),
|
||||
backgroundScope
|
||||
)
|
||||
runCurrent()
|
||||
|
||||
assertThat(ret).isFalse()
|
||||
assertThat(generateFails.size).isEqualTo(0)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGenerateChallengeAsCredentialActivityResult_invalidConfirmLock() = runTest {
|
||||
backgroundScope.launch {
|
||||
val userId = 107
|
||||
val gkPwHandle = 3333L
|
||||
viewModel =
|
||||
newAutoCredentialViewModel(newGkPwHandleCredentialIntentExtras(userId, gkPwHandle))
|
||||
val intent = Intent()
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, gkPwHandle)
|
||||
|
||||
val generateFails = listOfGenerateChallengeFailedFlow()
|
||||
|
||||
// Run generateChallengeAsCredentialActivityResult()
|
||||
val ret = viewModel.generateChallengeAsCredentialActivityResult(
|
||||
false,
|
||||
ActivityResult(Activity.RESULT_OK + 1, intent),
|
||||
backgroundScope
|
||||
)
|
||||
runCurrent()
|
||||
|
||||
assertThat(ret).isFalse()
|
||||
assertThat(generateFails.size).isEqualTo(0)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGenerateChallengeAsCredentialActivityResult_nullDataChooseLock() = runTest {
|
||||
val userId = 108
|
||||
val gkPwHandle = 4444L
|
||||
viewModel =
|
||||
newAutoCredentialViewModel(newGkPwHandleCredentialIntentExtras(userId, gkPwHandle))
|
||||
|
||||
val generateFails = listOfGenerateChallengeFailedFlow()
|
||||
|
||||
// Run generateChallengeAsCredentialActivityResult()
|
||||
val ret = viewModel.generateChallengeAsCredentialActivityResult(
|
||||
true,
|
||||
ActivityResult(ChooseLockPattern.RESULT_FINISHED, null),
|
||||
backgroundScope
|
||||
)
|
||||
runCurrent()
|
||||
|
||||
assertThat(ret).isFalse()
|
||||
assertThat(generateFails.size).isEqualTo(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGenerateChallengeAsCredentialActivityResult_nullDataConfirmLock() = runTest {
|
||||
val userId = 109
|
||||
viewModel =
|
||||
newAutoCredentialViewModel(newOnlySensorValidCredentialIntentExtras(userId))
|
||||
|
||||
val generateFails = listOfGenerateChallengeFailedFlow()
|
||||
|
||||
// Run generateChallengeAsCredentialActivityResult()
|
||||
val ret = viewModel.generateChallengeAsCredentialActivityResult(
|
||||
false,
|
||||
ActivityResult(Activity.RESULT_OK, null),
|
||||
backgroundScope
|
||||
)
|
||||
runCurrent()
|
||||
|
||||
assertThat(ret).isFalse()
|
||||
assertThat(generateFails.size).isEqualTo(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGenerateChallengeAsCredentialActivityResult_validChooseLock() = runTest {
|
||||
val userId = 108
|
||||
viewModel =
|
||||
newAutoCredentialViewModel(newOnlySensorValidCredentialIntentExtras(userId))
|
||||
whenever(lockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
|
||||
)
|
||||
val gkPwHandle = 6666L
|
||||
val newSensorId = 50
|
||||
val newChallenge = 60L
|
||||
setupGenerateChallenge(userId, newSensorId, newChallenge)
|
||||
whenever(
|
||||
lockPatternUtils.verifyGatekeeperPasswordHandle(
|
||||
gkPwHandle,
|
||||
newChallenge,
|
||||
userId
|
||||
)
|
||||
)
|
||||
.thenReturn(newGoodCredential(gkPwHandle, byteArrayOf(1)))
|
||||
val hasCalledRemoveGkPwHandle = AtomicBoolean()
|
||||
Mockito.doAnswer {
|
||||
hasCalledRemoveGkPwHandle.set(true)
|
||||
null
|
||||
}.`when`(lockPatternUtils).removeGatekeeperPasswordHandle(gkPwHandle)
|
||||
|
||||
val generateFails = listOfGenerateChallengeFailedFlow()
|
||||
|
||||
// Run generateChallengeAsCredentialActivityResult()
|
||||
val intent =
|
||||
Intent().putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, gkPwHandle)
|
||||
val ret = viewModel.generateChallengeAsCredentialActivityResult(
|
||||
true,
|
||||
ActivityResult(ChooseLockPattern.RESULT_FINISHED, intent),
|
||||
backgroundScope
|
||||
)
|
||||
runCurrent()
|
||||
|
||||
assertThat(ret).isTrue()
|
||||
assertThat(generateFails.size).isEqualTo(0)
|
||||
assertThat(viewModel.token).isNotNull()
|
||||
assertThat(challengeGenerator.callbackRunCount).isEqualTo(1)
|
||||
assertThat(hasCalledRemoveGkPwHandle.get()).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGenerateChallengeAsCredentialActivityResult_validConfirmLock() = runTest {
|
||||
val userId = 109
|
||||
viewModel =
|
||||
newAutoCredentialViewModel(newOnlySensorValidCredentialIntentExtras(userId))
|
||||
whenever(lockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
|
||||
)
|
||||
val gkPwHandle = 5555L
|
||||
val newSensorId = 80
|
||||
val newChallenge = 90L
|
||||
setupGenerateChallenge(userId, newSensorId, newChallenge)
|
||||
whenever(
|
||||
lockPatternUtils.verifyGatekeeperPasswordHandle(
|
||||
gkPwHandle,
|
||||
newChallenge,
|
||||
userId
|
||||
)
|
||||
)
|
||||
.thenReturn(newGoodCredential(gkPwHandle, byteArrayOf(1)))
|
||||
val hasCalledRemoveGkPwHandle = AtomicBoolean()
|
||||
Mockito.doAnswer {
|
||||
hasCalledRemoveGkPwHandle.set(true)
|
||||
null
|
||||
}.`when`(lockPatternUtils).removeGatekeeperPasswordHandle(gkPwHandle)
|
||||
|
||||
val generateFails = listOfGenerateChallengeFailedFlow()
|
||||
|
||||
// Run generateChallengeAsCredentialActivityResult()
|
||||
val intent =
|
||||
Intent().putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, gkPwHandle)
|
||||
val ret = viewModel.generateChallengeAsCredentialActivityResult(
|
||||
false,
|
||||
ActivityResult(Activity.RESULT_OK, intent),
|
||||
backgroundScope
|
||||
)
|
||||
runCurrent()
|
||||
|
||||
assertThat(ret).isTrue()
|
||||
assertThat(generateFails.size).isEqualTo(0)
|
||||
assertThat(viewModel.token).isNotNull()
|
||||
assertThat(challengeGenerator.callbackRunCount).isEqualTo(1)
|
||||
assertThat(hasCalledRemoveGkPwHandle.get()).isTrue()
|
||||
}
|
||||
|
||||
private fun TestScope.listOfGenerateChallengeFailedFlow(): List<Boolean> =
|
||||
mutableListOf<Boolean>().also {
|
||||
backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) {
|
||||
viewModel.generateChallengeFailedFlow.toList(it)
|
||||
}
|
||||
}
|
||||
|
||||
class TestChallengeGenerator : ChallengeGenerator {
|
||||
var sensorId = -1
|
||||
var userId = UserHandle.myUserId()
|
||||
var challenge = CredentialModel.INVALID_CHALLENGE
|
||||
var callbackRunCount = 0
|
||||
|
||||
override var callback: AutoCredentialViewModel.GenerateChallengeCallback? = null
|
||||
|
||||
override fun generateChallenge(userId: Int) {
|
||||
callback?.let {
|
||||
it.onChallengeGenerated(sensorId, this.userId, challenge)
|
||||
++callbackRunCount
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun newGoodCredential(gkPwHandle: Long, hat: ByteArray): VerifyCredentialResponse {
|
||||
return VerifyCredentialResponse.Builder()
|
||||
.setGatekeeperPasswordHandle(gkPwHandle)
|
||||
.setGatekeeperHAT(hat)
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun newBadCredential(timeout: Int): VerifyCredentialResponse {
|
||||
return if (timeout > 0) {
|
||||
VerifyCredentialResponse.fromTimeout(timeout)
|
||||
} else {
|
||||
VerifyCredentialResponse.fromError()
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.res.Configuration;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.testutils.InstantTaskExecutorRule;
|
||||
import com.android.systemui.unfold.compat.ScreenSizeFoldProvider;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class DeviceFoldedViewModelTest {
|
||||
|
||||
@Rule public final InstantTaskExecutorRule mTaskExecutorRule = new InstantTaskExecutorRule();
|
||||
|
||||
private DeviceFoldedViewModel mViewModel;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
final Application application = ApplicationProvider.getApplicationContext();
|
||||
mViewModel = new DeviceFoldedViewModel(new ScreenSizeFoldProvider(application),
|
||||
application.getMainExecutor());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLiveData() {
|
||||
final Configuration config1 = new Configuration();
|
||||
config1.smallestScreenWidthDp = 601;
|
||||
mViewModel.onConfigurationChanged(config1);
|
||||
assertThat(mViewModel.getLiveData().getValue()).isFalse();
|
||||
|
||||
final Configuration config2 = new Configuration();
|
||||
config2.smallestScreenWidthDp = 599;
|
||||
mViewModel.onConfigurationChanged(config2);
|
||||
assertThat(mViewModel.getLiveData().getValue()).isTrue();
|
||||
}
|
||||
}
|
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.app.Application;
|
||||
import android.view.Surface;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
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.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class DeviceRotationViewModelTest {
|
||||
|
||||
@Rule public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
@Rule public final InstantTaskExecutorRule mTaskExecutorRule = new InstantTaskExecutorRule();
|
||||
|
||||
private TestDeviceRotationViewModel mViewModel;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
TestDeviceRotationViewModel.sTestRotation = 3;
|
||||
mViewModel = new TestDeviceRotationViewModel(ApplicationProvider.getApplicationContext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultLiveDataNotNull() {
|
||||
assertThat(mViewModel.getLiveData().getValue()).isEqualTo(mViewModel.sTestRotation);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnDisplayChange() {
|
||||
mViewModel.sTestRotation = 3;
|
||||
mViewModel.triggerOnDisplayChanged();
|
||||
assertThat(mViewModel.getLiveData().getValue()).isEqualTo(mViewModel.sTestRotation);
|
||||
}
|
||||
|
||||
public static class TestDeviceRotationViewModel extends DeviceRotationViewModel {
|
||||
|
||||
@Surface.Rotation static int sTestRotation = 0;
|
||||
|
||||
public TestDeviceRotationViewModel(@NonNull Application application) {
|
||||
super(application);
|
||||
}
|
||||
|
||||
void triggerOnDisplayChanged() {
|
||||
mDisplayListener.onDisplayChanged(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getRotation() {
|
||||
return sTestRotation;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,173 +0,0 @@
|
||||
/*
|
||||
* 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_UDFPS_OPTICAL;
|
||||
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_USER_SKIP;
|
||||
import static com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.newFingerprintRepository;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
|
||||
import android.app.Application;
|
||||
import android.hardware.biometrics.SensorProperties;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
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.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.ArrayList;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class FingerprintEnrollEnrollingViewModelTest {
|
||||
|
||||
private static final int TEST_USER_ID = 33;
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
@Rule
|
||||
public final InstantTaskExecutorRule mTaskExecutorRule = new InstantTaskExecutorRule();
|
||||
|
||||
@Mock
|
||||
private FingerprintManager mFingerprintManager;
|
||||
|
||||
private Application mApplication;
|
||||
private FingerprintEnrollEnrollingViewModel mViewModel;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mApplication = ApplicationProvider.getApplicationContext();
|
||||
mViewModel = new FingerprintEnrollEnrollingViewModel(
|
||||
mApplication,
|
||||
TEST_USER_ID,
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIconTouchDialog() {
|
||||
final LiveData<Integer> actionLiveData = mViewModel.getActionLiveData();
|
||||
assertThat(actionLiveData.getValue()).isEqualTo(null);
|
||||
|
||||
mViewModel.showIconTouchDialog();
|
||||
assertThat(actionLiveData.getValue()).isEqualTo(
|
||||
FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tesBackPressedScenario() {
|
||||
final LiveData<Integer> actionLiveData = mViewModel.getActionLiveData();
|
||||
assertThat(actionLiveData.getValue()).isEqualTo(null);
|
||||
assertThat(mViewModel.getOnBackPressed()).isEqualTo(false);
|
||||
|
||||
mViewModel.setOnBackPressed();
|
||||
assertThat(mViewModel.getOnBackPressed()).isEqualTo(true);
|
||||
|
||||
mViewModel.onCancelledDueToOnBackPressed();
|
||||
assertThat(mViewModel.getOnBackPressed()).isEqualTo(false);
|
||||
assertThat(actionLiveData.getValue()).isEqualTo(
|
||||
FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipPressedScenario() {
|
||||
final LiveData<Integer> actionLiveData = mViewModel.getActionLiveData();
|
||||
assertThat(actionLiveData.getValue()).isEqualTo(null);
|
||||
assertThat(mViewModel.getOnSkipPressed()).isEqualTo(false);
|
||||
|
||||
mViewModel.setOnSkipPressed();
|
||||
assertThat(mViewModel.getOnSkipPressed()).isEqualTo(true);
|
||||
|
||||
mViewModel.onCancelledDueToOnSkipPressed();
|
||||
assertThat(mViewModel.getOnSkipPressed()).isEqualTo(false);
|
||||
assertThat(actionLiveData.getValue()).isEqualTo(
|
||||
FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_USER_SKIP);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetFirstFingerprintSensorPropertiesInternal() {
|
||||
final ArrayList<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
|
||||
final FingerprintSensorPropertiesInternal prop = new FingerprintSensorPropertiesInternal(
|
||||
0 /* sensorId */,
|
||||
SensorProperties.STRENGTH_STRONG,
|
||||
5,
|
||||
new ArrayList<>() /* componentInfo */,
|
||||
TYPE_UDFPS_OPTICAL,
|
||||
true /* resetLockoutRequiresHardwareAuthToken */);
|
||||
props.add(prop);
|
||||
doAnswer(invocation -> {
|
||||
final IFingerprintAuthenticatorsRegisteredCallback callback =
|
||||
invocation.getArgument(0);
|
||||
callback.onAllAuthenticatorsRegistered(props);
|
||||
return null;
|
||||
}).when(mFingerprintManager).addAuthenticatorsRegisteredCallback(any());
|
||||
|
||||
mViewModel = new FingerprintEnrollEnrollingViewModel(
|
||||
mApplication,
|
||||
TEST_USER_ID,
|
||||
new FingerprintRepository(mFingerprintManager)
|
||||
);
|
||||
|
||||
assertThat(mViewModel.getFirstFingerprintSensorPropertiesInternal()).isEqualTo(prop);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetEnrollStageCount() {
|
||||
final int expectedValue = 24;
|
||||
doReturn(expectedValue).when(mFingerprintManager).getEnrollStageCount();
|
||||
|
||||
assertThat(mViewModel.getEnrollStageCount()).isEqualTo(expectedValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetEnrollStageThreshold() {
|
||||
final float expectedValue0 = 0.42f;
|
||||
final float expectedValue1 = 0.24f;
|
||||
final float expectedValue2 = 0.33f;
|
||||
final float expectedValue3 = 0.90f;
|
||||
|
||||
doReturn(expectedValue0).when(mFingerprintManager).getEnrollStageThreshold(0);
|
||||
doReturn(expectedValue1).when(mFingerprintManager).getEnrollStageThreshold(1);
|
||||
doReturn(expectedValue2).when(mFingerprintManager).getEnrollStageThreshold(2);
|
||||
doReturn(expectedValue3).when(mFingerprintManager).getEnrollStageThreshold(3);
|
||||
|
||||
assertThat(mViewModel.getEnrollStageThreshold(2)).isEqualTo(expectedValue2);
|
||||
assertThat(mViewModel.getEnrollStageThreshold(1)).isEqualTo(expectedValue1);
|
||||
assertThat(mViewModel.getEnrollStageThreshold(3)).isEqualTo(expectedValue3);
|
||||
assertThat(mViewModel.getEnrollStageThreshold(0)).isEqualTo(expectedValue0);
|
||||
}
|
||||
}
|
@@ -1,121 +0,0 @@
|
||||
/*
|
||||
* 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 android.app.Application
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintErrorDialogSetResultAction.FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.flow.toList
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.test.UnconfinedTestDispatcher
|
||||
import kotlinx.coroutines.test.runCurrent
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class FingerprintEnrollErrorDialogViewModelTest {
|
||||
|
||||
private val application = ApplicationProvider.getApplicationContext<Application>()
|
||||
private var viewModel: FingerprintEnrollErrorDialogViewModel =
|
||||
FingerprintEnrollErrorDialogViewModel(application, false)
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
// Make sure viewModel is new for each test
|
||||
viewModel = FingerprintEnrollErrorDialogViewModel(application, false)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIsDialogNotShownDefaultFalse() {
|
||||
assertThat(viewModel.isDialogShown).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIsSuw() {
|
||||
assertThat(FingerprintEnrollErrorDialogViewModel(application, false).isSuw).isFalse()
|
||||
assertThat(FingerprintEnrollErrorDialogViewModel(application, true).isSuw).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNewDialog() = runTest {
|
||||
val newDialogs: List<Int> = mutableListOf<Int>().also {
|
||||
backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) {
|
||||
viewModel.newDialogFlow.toList(it)
|
||||
}
|
||||
}
|
||||
|
||||
runCurrent()
|
||||
|
||||
// Default values
|
||||
assertThat(viewModel.isDialogShown).isFalse()
|
||||
assertThat(newDialogs.size).isEqualTo(0)
|
||||
|
||||
val testErrorMsgId = 3456
|
||||
viewModel.newDialog(testErrorMsgId)
|
||||
runCurrent()
|
||||
|
||||
// verify after emit
|
||||
assertThat(viewModel.isDialogShown).isTrue()
|
||||
assertThat(newDialogs.size).isEqualTo(1)
|
||||
assertThat(newDialogs[0]).isEqualTo(testErrorMsgId)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTriggerRetry() = runTest {
|
||||
val triggerRetries: List<Any> = mutableListOf<Any>().also {
|
||||
backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) {
|
||||
viewModel.triggerRetryFlow.toList(it)
|
||||
}
|
||||
}
|
||||
|
||||
runCurrent()
|
||||
|
||||
// Default values
|
||||
assertThat(triggerRetries.size).isEqualTo(0)
|
||||
|
||||
viewModel.triggerRetry()
|
||||
runCurrent()
|
||||
|
||||
// verify after emit
|
||||
assertThat(triggerRetries.size).isEqualTo(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSetResultFinish() = runTest {
|
||||
val setResults: List<FingerprintErrorDialogSetResultAction> =
|
||||
mutableListOf<FingerprintErrorDialogSetResultAction>().also {
|
||||
backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) {
|
||||
viewModel.setResultFlow.toList(it)
|
||||
}
|
||||
}
|
||||
|
||||
runCurrent()
|
||||
|
||||
// Default values
|
||||
assertThat(setResults.size).isEqualTo(0)
|
||||
|
||||
viewModel.setResultAndFinish(FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH)
|
||||
runCurrent()
|
||||
|
||||
// verify after emit
|
||||
assertThat(setResults.size).isEqualTo(1)
|
||||
assertThat(setResults[0]).isEqualTo(FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH)
|
||||
}
|
||||
}
|
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* 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.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel.FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_DIALOG;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel.FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_SKIP;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFindSensorViewModel.FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_START;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.app.Application;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.testutils.InstantTaskExecutorRule;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class FingerprintEnrollFindSensorViewModelTest {
|
||||
|
||||
@Rule public final InstantTaskExecutorRule mTaskExecutorRule = new InstantTaskExecutorRule();
|
||||
|
||||
private Application mApplication;
|
||||
private FingerprintEnrollFindSensorViewModel mViewModel;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mApplication = ApplicationProvider.getApplicationContext();
|
||||
mViewModel = new FingerprintEnrollFindSensorViewModel(mApplication, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClickSkipButtonNotInSuw() {
|
||||
mViewModel = new FingerprintEnrollFindSensorViewModel(mApplication, false);
|
||||
mViewModel.onSkipButtonClick();
|
||||
assertThat(mViewModel.getActionLiveData().getValue()).isEqualTo(
|
||||
FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_SKIP);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClickSkipButtonInSuw() {
|
||||
mViewModel = new FingerprintEnrollFindSensorViewModel(mApplication, true);
|
||||
mViewModel.onSkipButtonClick();
|
||||
assertThat(mViewModel.getActionLiveData().getValue()).isEqualTo(
|
||||
FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_DIALOG);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClickSkipDialogButton() {
|
||||
mViewModel.onSkipDialogButtonClick();
|
||||
assertThat(mViewModel.getActionLiveData().getValue()).isEqualTo(
|
||||
FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_SKIP);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClickStartDialogButton() {
|
||||
mViewModel.onStartButtonClick();
|
||||
assertThat(mViewModel.getActionLiveData().getValue()).isEqualTo(
|
||||
FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_START);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClearActionLiveData() {
|
||||
assertThat(mViewModel.getActionLiveData().getValue()).isNull();
|
||||
|
||||
mViewModel.onStartButtonClick();
|
||||
assertThat(mViewModel.getActionLiveData().getValue()).isNotNull();
|
||||
|
||||
mViewModel.clearActionLiveData();
|
||||
assertThat(mViewModel.getActionLiveData().getValue()).isNull();
|
||||
}
|
||||
}
|
@@ -1,134 +0,0 @@
|
||||
/*
|
||||
* 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_POWER_BUTTON;
|
||||
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_REAR;
|
||||
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_OPTICAL;
|
||||
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFinishViewModel.FINGERPRINT_ENROLL_FINISH_ACTION_ADD_BUTTON_CLICK;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollFinishViewModel.FINGERPRINT_ENROLL_FINISH_ACTION_NEXT_BUTTON_CLICK;
|
||||
import static com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.newFingerprintRepository;
|
||||
import static com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.setupFingerprintEnrolledFingerprints;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Intent;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.biometrics2.ui.model.EnrollmentRequest;
|
||||
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 FingerprintEnrollFinishViewModelTest {
|
||||
|
||||
private static final int USER_ID = 334;
|
||||
private static final int MAX_ENROLLABLE = 5;
|
||||
|
||||
@Rule public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
@Rule public final InstantTaskExecutorRule mTaskExecutorRule = new InstantTaskExecutorRule();
|
||||
|
||||
@Mock private FingerprintManager mFingerprintManager;
|
||||
|
||||
private Application mApplication;
|
||||
private EnrollmentRequest mRequest;
|
||||
private FingerprintEnrollFinishViewModel mViewModel;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mApplication = ApplicationProvider.getApplicationContext();
|
||||
mRequest = new EnrollmentRequest(new Intent(), mApplication, true);
|
||||
mViewModel = new FingerprintEnrollFinishViewModel(mApplication, USER_ID, mRequest,
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, MAX_ENROLLABLE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCanAssumeSfps() {
|
||||
mViewModel = new FingerprintEnrollFinishViewModel(mApplication, USER_ID, mRequest,
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, MAX_ENROLLABLE));
|
||||
assertThat(mViewModel.canAssumeSfps()).isFalse();
|
||||
|
||||
mViewModel = new FingerprintEnrollFinishViewModel(mApplication, USER_ID, mRequest,
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_REAR, MAX_ENROLLABLE));
|
||||
assertThat(mViewModel.canAssumeSfps()).isFalse();
|
||||
|
||||
mViewModel = new FingerprintEnrollFinishViewModel(mApplication, USER_ID, mRequest,
|
||||
newFingerprintRepository(mFingerprintManager, TYPE_POWER_BUTTON, MAX_ENROLLABLE));
|
||||
assertThat(mViewModel.canAssumeSfps()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAnotherFingerprintEnrollable() {
|
||||
setupFingerprintEnrolledFingerprints(mFingerprintManager, USER_ID, MAX_ENROLLABLE);
|
||||
assertThat(mViewModel.isAnotherFingerprintEnrollable()).isFalse();
|
||||
|
||||
setupFingerprintEnrolledFingerprints(mFingerprintManager, USER_ID, MAX_ENROLLABLE - 1);
|
||||
assertThat(mViewModel.isAnotherFingerprintEnrollable()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRequest() {
|
||||
assertThat(mViewModel.getRequest()).isEqualTo(mRequest);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnAddButtonClick() {
|
||||
final LiveData<Integer> actionLiveData = mViewModel.getActionLiveData();
|
||||
|
||||
// Test init value
|
||||
assertThat(actionLiveData.getValue()).isNull();
|
||||
|
||||
// Test onAddButtonClick()
|
||||
mViewModel.onAddButtonClick();
|
||||
assertThat(actionLiveData.getValue()).isEqualTo(
|
||||
FINGERPRINT_ENROLL_FINISH_ACTION_ADD_BUTTON_CLICK);
|
||||
|
||||
// Clear
|
||||
mViewModel.clearActionLiveData();
|
||||
assertThat(actionLiveData.getValue()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnNextButtonClick() {
|
||||
final LiveData<Integer> actionLiveData = mViewModel.getActionLiveData();
|
||||
|
||||
// Test init value
|
||||
assertThat(actionLiveData.getValue()).isNull();
|
||||
|
||||
// Test onNextButtonClick()
|
||||
mViewModel.onNextButtonClick();
|
||||
assertThat(actionLiveData.getValue()).isEqualTo(
|
||||
FINGERPRINT_ENROLL_FINISH_ACTION_NEXT_BUTTON_CLICK);
|
||||
|
||||
// Clear
|
||||
mViewModel.clearActionLiveData();
|
||||
assertThat(actionLiveData.getValue()).isNull();
|
||||
}
|
||||
}
|
@@ -1,357 +0,0 @@
|
||||
/*
|
||||
* 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 android.app.Application
|
||||
import android.content.res.Resources
|
||||
import android.hardware.fingerprint.FingerprintManager
|
||||
import android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_OPTICAL
|
||||
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.biometrics2.ui.model.FingerprintEnrollable.FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX
|
||||
import com.android.settings.biometrics2.ui.model.FingerprintEnrollable.FINGERPRINT_ENROLLABLE_OK
|
||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroAction.CONTINUE_ENROLL
|
||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroAction.DONE_AND_FINISH
|
||||
import com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroAction.SKIP_OR_CANCEL
|
||||
import com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newAllFalseRequest
|
||||
import com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newIsSuwDeferredRequest
|
||||
import com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newIsSuwPortalRequest
|
||||
import com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newIsSuwRequest
|
||||
import com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newIsSuwSuggestedActionFlowRequest
|
||||
import com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.newFingerprintRepository
|
||||
import com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.setupFingerprintEnrolledFingerprints
|
||||
import com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.setupSuwMaxFingerprintsEnrollable
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.flow.toList
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.UnconfinedTestDispatcher
|
||||
import kotlinx.coroutines.test.runCurrent
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito
|
||||
import org.mockito.junit.MockitoJUnit
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class FingerprintEnrollIntroViewModelTest {
|
||||
|
||||
@get:Rule val mockito = MockitoJUnit.rule()
|
||||
|
||||
@Mock private lateinit var resources: Resources
|
||||
@Mock private lateinit var fingerprintManager: FingerprintManager
|
||||
|
||||
private var application: Application = ApplicationProvider.getApplicationContext()
|
||||
|
||||
private fun newFingerprintEnrollIntroViewModel(
|
||||
fingerprintRepository: FingerprintRepository,
|
||||
enrollmentRequest: EnrollmentRequest
|
||||
) = FingerprintEnrollIntroViewModel(
|
||||
application,
|
||||
fingerprintRepository,
|
||||
enrollmentRequest,
|
||||
TEST_USER_ID
|
||||
)
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
application = ApplicationProvider.getApplicationContext()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPageStatusFlowDefaultAndUpdate() = runTest {
|
||||
val viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(fingerprintManager, TYPE_UDFPS_OPTICAL, 1),
|
||||
newAllFalseRequest(application)
|
||||
)
|
||||
|
||||
val statusList = listOfPageStatusFlow(viewModel)
|
||||
|
||||
runCurrent()
|
||||
|
||||
// assert default values
|
||||
assertThat(statusList.size).isEqualTo(1)
|
||||
assertThat(statusList[0].hasScrollToBottom()).isFalse()
|
||||
assertThat(statusList[0].enrollableStatus).isEqualTo(FINGERPRINT_ENROLLABLE_OK)
|
||||
|
||||
setupFingerprintEnrolledFingerprints(fingerprintManager, TEST_USER_ID, 1)
|
||||
viewModel.updateEnrollableStatus(backgroundScope)
|
||||
runCurrent()
|
||||
|
||||
// assert new updated value
|
||||
assertThat(statusList.size).isEqualTo(2)
|
||||
assertThat(statusList[1].hasScrollToBottom()).isFalse()
|
||||
assertThat(statusList[1].enrollableStatus).isEqualTo(FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX)
|
||||
}
|
||||
|
||||
fun testOnStartToUpdateEnrollableStatusOk_isSuw() = runTest {
|
||||
setupFingerprintEnrolledFingerprints(fingerprintManager, TEST_USER_ID, 0)
|
||||
setupSuwMaxFingerprintsEnrollable(application, resources, 1)
|
||||
val viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(fingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
newIsSuwRequest(application)
|
||||
)
|
||||
|
||||
val statusList = listOfPageStatusFlow(viewModel)
|
||||
|
||||
runCurrent()
|
||||
|
||||
assertThat(statusList.size).isEqualTo(1)
|
||||
assertThat(statusList[0].enrollableStatus).isEqualTo(FINGERPRINT_ENROLLABLE_OK)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnStartToUpdateEnrollableStatusReachMax_isSuw() = runTest {
|
||||
setupFingerprintEnrolledFingerprints(fingerprintManager, TEST_USER_ID, 1)
|
||||
setupSuwMaxFingerprintsEnrollable(application, resources, 1)
|
||||
val viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(fingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
newIsSuwRequest(application)
|
||||
)
|
||||
|
||||
val statusList = listOfPageStatusFlow(viewModel)
|
||||
|
||||
runCurrent()
|
||||
|
||||
assertThat(statusList.size).isEqualTo(1)
|
||||
assertThat(statusList[0].enrollableStatus).isEqualTo(FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnStartToUpdateEnrollableStatusOk_isNotSuw() = runTest {
|
||||
testOnStartToUpdateEnrollableStatusOk(newAllFalseRequest(application))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnStartToUpdateEnrollableStatusReachMax_isNotSuw() = runTest {
|
||||
testOnStartToUpdateEnrollableStatusReachMax(newAllFalseRequest(application))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnStartToUpdateEnrollableStatusOk_isSuwDeferred() = runTest {
|
||||
testOnStartToUpdateEnrollableStatusOk(newIsSuwDeferredRequest(application))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnStartToUpdateEnrollableStatusReachMax_isSuwDeferred() = runTest {
|
||||
testOnStartToUpdateEnrollableStatusReachMax(newIsSuwDeferredRequest(application))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnStartToUpdateEnrollableStatusOk_isSuwPortal() = runTest {
|
||||
testOnStartToUpdateEnrollableStatusOk(newIsSuwPortalRequest(application))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnStartToUpdateEnrollableStatusReachMax_isSuwPortal() = runTest {
|
||||
testOnStartToUpdateEnrollableStatusReachMax(newIsSuwPortalRequest(application))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnStartToUpdateEnrollableStatusOk_isSuwSuggestedActionFlow() = runTest {
|
||||
testOnStartToUpdateEnrollableStatusOk(newIsSuwSuggestedActionFlowRequest(application))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnStartToUpdateEnrollableStatusReachMax_isSuwSuggestedActionFlow() = runTest {
|
||||
testOnStartToUpdateEnrollableStatusReachMax(
|
||||
newIsSuwSuggestedActionFlowRequest(application)
|
||||
)
|
||||
}
|
||||
|
||||
private fun TestScope.testOnStartToUpdateEnrollableStatusOk(request: EnrollmentRequest) {
|
||||
setupFingerprintEnrolledFingerprints(fingerprintManager, TEST_USER_ID, 0)
|
||||
val viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(fingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
request
|
||||
)
|
||||
|
||||
val statusList = listOfPageStatusFlow(viewModel)
|
||||
|
||||
runCurrent()
|
||||
|
||||
assertThat(statusList.size).isEqualTo(1)
|
||||
assertThat(statusList[0].enrollableStatus).isEqualTo(FINGERPRINT_ENROLLABLE_OK)
|
||||
}
|
||||
|
||||
private fun TestScope.testOnStartToUpdateEnrollableStatusReachMax(request: EnrollmentRequest) {
|
||||
setupFingerprintEnrolledFingerprints(fingerprintManager, TEST_USER_ID, 5)
|
||||
val viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(fingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
request
|
||||
)
|
||||
|
||||
val statusList = listOfPageStatusFlow(viewModel)
|
||||
|
||||
runCurrent()
|
||||
|
||||
assertThat(statusList.size).isEqualTo(1)
|
||||
assertThat(statusList[0].enrollableStatus).isEqualTo(FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIsParentalConsentRequired() {
|
||||
// We shall not mock FingerprintRepository, but
|
||||
// FingerprintRepository.isParentalConsentRequired() calls static method inside, we can't
|
||||
// mock static method
|
||||
val fingerprintRepository = Mockito.mock(
|
||||
FingerprintRepository::class.java
|
||||
)
|
||||
val viewModel = FingerprintEnrollIntroViewModel(
|
||||
application,
|
||||
fingerprintRepository,
|
||||
newAllFalseRequest(application),
|
||||
TEST_USER_ID
|
||||
)
|
||||
Mockito.`when`(
|
||||
fingerprintRepository.isParentalConsentRequired(application)
|
||||
).thenReturn(true)
|
||||
assertThat(viewModel.isParentalConsentRequired).isEqualTo(true)
|
||||
Mockito.`when`(
|
||||
fingerprintRepository.isParentalConsentRequired(application)
|
||||
).thenReturn(false)
|
||||
assertThat(viewModel.isParentalConsentRequired).isEqualTo(false)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIsBiometricUnlockDisabledByAdmin() {
|
||||
// We shall not mock FingerprintRepository, but
|
||||
// FingerprintRepository.isDisabledByAdmin() calls static method inside, we can't mock
|
||||
// static method
|
||||
val fingerprintRepository = Mockito.mock(FingerprintRepository::class.java)
|
||||
val viewModel = FingerprintEnrollIntroViewModel(
|
||||
application,
|
||||
fingerprintRepository,
|
||||
newAllFalseRequest(application),
|
||||
TEST_USER_ID
|
||||
)
|
||||
Mockito.`when`(
|
||||
fingerprintRepository.isDisabledByAdmin(application, TEST_USER_ID)
|
||||
).thenReturn(true)
|
||||
assertThat(viewModel.isBiometricUnlockDisabledByAdmin).isEqualTo(true)
|
||||
Mockito.`when`(
|
||||
fingerprintRepository.isDisabledByAdmin(application, TEST_USER_ID)
|
||||
).thenReturn(false)
|
||||
assertThat(viewModel.isBiometricUnlockDisabledByAdmin).isEqualTo(false)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSetHasScrolledToBottom() = runTest {
|
||||
val viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(fingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
newAllFalseRequest(application)
|
||||
)
|
||||
|
||||
val pageStatusList = listOfPageStatusFlow(viewModel)
|
||||
|
||||
viewModel.setHasScrolledToBottom(true, backgroundScope)
|
||||
runCurrent()
|
||||
|
||||
assertThat(pageStatusList[pageStatusList.size-1].hasScrollToBottom()).isEqualTo(true)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnNextButtonClick_enrollNext() = runTest {
|
||||
// Set latest status to FINGERPRINT_ENROLLABLE_OK
|
||||
setupFingerprintEnrolledFingerprints(fingerprintManager, TEST_USER_ID, 0)
|
||||
setupSuwMaxFingerprintsEnrollable(application, resources, 1)
|
||||
val viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(fingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
newIsSuwRequest(application)
|
||||
)
|
||||
|
||||
val actions = listOfActionFlow(viewModel)
|
||||
|
||||
// Perform click on `next`
|
||||
viewModel.onNextButtonClick(backgroundScope)
|
||||
runCurrent()
|
||||
|
||||
assertThat(actions.size).isEqualTo(1)
|
||||
assertThat(actions[0]).isEqualTo(CONTINUE_ENROLL)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnNextButtonClick_doneAndFinish() = runTest {
|
||||
// Set latest status to FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX
|
||||
setupFingerprintEnrolledFingerprints(fingerprintManager, TEST_USER_ID, 1)
|
||||
setupSuwMaxFingerprintsEnrollable(application, resources, 1)
|
||||
val viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(fingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
newIsSuwRequest(application)
|
||||
)
|
||||
|
||||
val statusList = listOfPageStatusFlow(viewModel)
|
||||
val actionList = listOfActionFlow(viewModel)
|
||||
|
||||
runCurrent()
|
||||
|
||||
assertThat(statusList.size).isEqualTo(1)
|
||||
assertThat(statusList[0].enrollableStatus).isEqualTo(FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX)
|
||||
|
||||
val actions = listOfActionFlow(viewModel)
|
||||
|
||||
// Perform click on `next`
|
||||
viewModel.onNextButtonClick(backgroundScope)
|
||||
runCurrent()
|
||||
|
||||
assertThat(actionList.size).isEqualTo(1)
|
||||
assertThat(actionList[0]).isEqualTo(DONE_AND_FINISH)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnSkipOrCancelButtonClick() = runTest {
|
||||
val viewModel = newFingerprintEnrollIntroViewModel(
|
||||
newFingerprintRepository(fingerprintManager, TYPE_UDFPS_OPTICAL, 5),
|
||||
newAllFalseRequest(application)
|
||||
)
|
||||
|
||||
val actions = listOfActionFlow(viewModel)
|
||||
|
||||
viewModel.onSkipOrCancelButtonClick(backgroundScope)
|
||||
runCurrent()
|
||||
|
||||
assertThat(actions.size).isEqualTo(1)
|
||||
assertThat(actions[0]).isEqualTo(SKIP_OR_CANCEL)
|
||||
}
|
||||
|
||||
private fun TestScope.listOfActionFlow(
|
||||
viewModel: FingerprintEnrollIntroViewModel
|
||||
): List<FingerprintEnrollIntroAction> =
|
||||
mutableListOf<FingerprintEnrollIntroAction>().also {
|
||||
backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) {
|
||||
viewModel.actionFlow.toList(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun TestScope.listOfPageStatusFlow(
|
||||
viewModel: FingerprintEnrollIntroViewModel
|
||||
): List<FingerprintEnrollIntroStatus> =
|
||||
mutableListOf<FingerprintEnrollIntroStatus>().also {
|
||||
backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) {
|
||||
viewModel.pageStatusFlow.toList(it)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TEST_USER_ID = 33
|
||||
}
|
||||
}
|
@@ -1,421 +0,0 @@
|
||||
/*
|
||||
* 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.Utils.SETTINGS_PACKAGE_NAME;
|
||||
|
||||
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.times;
|
||||
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 android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.biometrics.fingerprint.FingerprintUpdater;
|
||||
import com.android.settings.biometrics.fingerprint.MessageDisplayController;
|
||||
import com.android.settings.biometrics2.ui.model.EnrollmentProgress;
|
||||
import com.android.settings.biometrics2.ui.model.EnrollmentStatusMessage;
|
||||
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 {
|
||||
|
||||
private static final int TEST_USER_ID = 334;
|
||||
|
||||
@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;
|
||||
private final TestWrapper<CancellationSignal> mCancellationSignalWrapper = new TestWrapper<>();
|
||||
private final TestWrapper<EnrollmentCallback> mCallbackWrapper = new TestWrapper<>();
|
||||
private int mEnrollmentMessageDisplayControllerFlagResId;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mEnrollmentMessageDisplayControllerFlagResId = ApplicationProvider.getApplicationContext()
|
||||
.getResources().getIdentifier("enrollment_message_display_controller_flag", "bool",
|
||||
SETTINGS_PACKAGE_NAME);
|
||||
|
||||
when(mApplication.getResources()).thenReturn(mResources);
|
||||
|
||||
// Not use MessageDisplayController by default
|
||||
when(mResources.getBoolean(mEnrollmentMessageDisplayControllerFlagResId)).thenReturn(false);
|
||||
mViewModel = new FingerprintEnrollProgressViewModel(mApplication, mFingerprintUpdater,
|
||||
TEST_USER_ID);
|
||||
|
||||
mCancellationSignalWrapper.mValue = null;
|
||||
mCallbackWrapper.mValue = null;
|
||||
doAnswer(invocation -> {
|
||||
mCancellationSignalWrapper.mValue = invocation.getArgument(1);
|
||||
mCallbackWrapper.mValue = invocation.getArgument(3);
|
||||
return null;
|
||||
}).when(mFingerprintUpdater).enroll(any(byte[].class), any(CancellationSignal.class),
|
||||
eq(TEST_USER_ID), any(EnrollmentCallback.class), anyInt(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartFindSensor() {
|
||||
@EnrollReason final int enrollReason = ENROLL_FIND_SENSOR;
|
||||
final byte[] token = new byte[] { 1, 2, 3 };
|
||||
mViewModel.setToken(token);
|
||||
|
||||
// Start enrollment
|
||||
final Object ret = mViewModel.startEnrollment(enrollReason);
|
||||
|
||||
assertThat(ret).isNotNull();
|
||||
verify(mFingerprintUpdater, only()).enroll(eq(token), any(CancellationSignal.class),
|
||||
eq(TEST_USER_ID), any(EnrollmentCallback.class), eq(enrollReason), any());
|
||||
assertThat(mCallbackWrapper.mValue instanceof MessageDisplayController).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartEnrolling() {
|
||||
@EnrollReason final int enrollReason = ENROLL_ENROLL;
|
||||
final byte[] token = new byte[] { 1, 2, 3 };
|
||||
mViewModel.setToken(token);
|
||||
|
||||
// Start enrollment
|
||||
final Object ret = mViewModel.startEnrollment(enrollReason);
|
||||
|
||||
assertThat(ret).isNotNull();
|
||||
verify(mFingerprintUpdater, only()).enroll(eq(token), any(CancellationSignal.class),
|
||||
eq(TEST_USER_ID), any(EnrollmentCallback.class), eq(enrollReason), any());
|
||||
assertThat(mCallbackWrapper.mValue instanceof MessageDisplayController).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartEnrollingWithMessageDisplayController() {
|
||||
// Enable MessageDisplayController and mock handler for it
|
||||
when(mResources.getBoolean(mEnrollmentMessageDisplayControllerFlagResId)).thenReturn(true);
|
||||
when(mApplication.getMainThreadHandler()).thenReturn(new TestHandler());
|
||||
|
||||
@EnrollReason final int enrollReason = ENROLL_ENROLL;
|
||||
final byte[] token = new byte[] { 1, 2, 3 };
|
||||
mViewModel.setToken(token);
|
||||
|
||||
// Start enrollment
|
||||
final Object ret = mViewModel.startEnrollment(enrollReason);
|
||||
|
||||
assertThat(ret).isNotNull();
|
||||
verify(mFingerprintUpdater, only()).enroll(eq(token), any(CancellationSignal.class),
|
||||
eq(TEST_USER_ID), any(MessageDisplayController.class), eq(enrollReason), any());
|
||||
assertThat(mCallbackWrapper.mValue).isNotNull();
|
||||
|
||||
assertThat(mCallbackWrapper.mValue instanceof MessageDisplayController).isTrue();
|
||||
final EnrollmentCallback callback1 = mCallbackWrapper.mValue;
|
||||
|
||||
// Cancel and start again
|
||||
mViewModel.cancelEnrollment();
|
||||
mViewModel.startEnrollment(enrollReason);
|
||||
|
||||
// Shall not use the same MessageDisplayController
|
||||
verify(mFingerprintUpdater, times(2)).enroll(eq(token), any(CancellationSignal.class),
|
||||
eq(TEST_USER_ID), any(MessageDisplayController.class), eq(enrollReason), any());
|
||||
assertThat(mCallbackWrapper.mValue).isNotNull();
|
||||
assertThat(callback1).isNotEqualTo(mCallbackWrapper.mValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartEnrollmentFailBecauseOfNoToken() {
|
||||
// Start enrollment
|
||||
final Object ret = mViewModel.startEnrollment(ENROLL_FIND_SENSOR);
|
||||
|
||||
assertThat(ret).isNull();
|
||||
verify(mFingerprintUpdater, never()).enroll(any(byte[].class),
|
||||
any(CancellationSignal.class), anyInt(), any(EnrollmentCallback.class), anyInt(),
|
||||
any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancelEnrollment() {
|
||||
// Start enrollment
|
||||
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
||||
final Object ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
||||
assertThat(ret).isNotNull();
|
||||
assertThat(mCancellationSignalWrapper.mValue).isNotNull();
|
||||
|
||||
// Cancel enrollment
|
||||
mViewModel.cancelEnrollment();
|
||||
|
||||
assertThat(mCancellationSignalWrapper.mValue.isCanceled()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProgressUpdate() {
|
||||
// Start enrollment
|
||||
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
||||
final Object ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
||||
assertThat(ret).isNotNull();
|
||||
assertThat(mCallbackWrapper.mValue).isNotNull();
|
||||
|
||||
// Test default value
|
||||
final LiveData<EnrollmentProgress> progressLiveData = mViewModel.getProgressLiveData();
|
||||
EnrollmentProgress progress = progressLiveData.getValue();
|
||||
assertThat(progress).isNotNull();
|
||||
assertThat(progress.getSteps()).isEqualTo(-1);
|
||||
assertThat(progress.getRemaining()).isEqualTo(0);
|
||||
|
||||
// Update first progress
|
||||
mCallbackWrapper.mValue.onEnrollmentProgress(25);
|
||||
progress = progressLiveData.getValue();
|
||||
assertThat(progress).isNotNull();
|
||||
assertThat(progress.getSteps()).isEqualTo(25);
|
||||
assertThat(progress.getRemaining()).isEqualTo(25);
|
||||
|
||||
// Update second progress
|
||||
mCallbackWrapper.mValue.onEnrollmentProgress(20);
|
||||
progress = progressLiveData.getValue();
|
||||
assertThat(progress).isNotNull();
|
||||
assertThat(progress.getSteps()).isEqualTo(25);
|
||||
assertThat(progress.getRemaining()).isEqualTo(20);
|
||||
|
||||
// Update latest progress
|
||||
mCallbackWrapper.mValue.onEnrollmentProgress(0);
|
||||
progress = progressLiveData.getValue();
|
||||
assertThat(progress).isNotNull();
|
||||
assertThat(progress.getSteps()).isEqualTo(25);
|
||||
assertThat(progress.getRemaining()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProgressUpdateClearHelpMessage() {
|
||||
// Start enrollment
|
||||
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
||||
final Object ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
||||
assertThat(ret).isNotNull();
|
||||
assertThat(mCallbackWrapper.mValue).isNotNull();
|
||||
final LiveData<EnrollmentProgress> progressLiveData = mViewModel.getProgressLiveData();
|
||||
final LiveData<EnrollmentStatusMessage> helpMsgLiveData =
|
||||
mViewModel.getHelpMessageLiveData();
|
||||
|
||||
// Update first progress
|
||||
mCallbackWrapper.mValue.onEnrollmentProgress(25);
|
||||
EnrollmentProgress progress = progressLiveData.getValue();
|
||||
assertThat(progress).isNotNull();
|
||||
assertThat(progress.getSteps()).isEqualTo(25);
|
||||
assertThat(progress.getRemaining()).isEqualTo(25);
|
||||
|
||||
// Update help message
|
||||
final int testHelpMsgId = 3;
|
||||
final String testHelpString = "Test Help String";
|
||||
mCallbackWrapper.mValue.onEnrollmentHelp(testHelpMsgId, testHelpString);
|
||||
final EnrollmentStatusMessage helpMsg = helpMsgLiveData.getValue();
|
||||
assertThat(helpMsg).isNotNull();
|
||||
assertThat(helpMsg.getMsgId()).isEqualTo(testHelpMsgId);
|
||||
assertThat(helpMsg.getStr().toString()).isEqualTo(testHelpString);
|
||||
|
||||
// Update second progress
|
||||
mCallbackWrapper.mValue.onEnrollmentProgress(20);
|
||||
progress = progressLiveData.getValue();
|
||||
assertThat(progress).isNotNull();
|
||||
assertThat(progress.getSteps()).isEqualTo(25);
|
||||
assertThat(progress.getRemaining()).isEqualTo(20);
|
||||
|
||||
// Help message shall be set to null
|
||||
assertThat(helpMsgLiveData.getValue()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProgressUpdateWithMessageDisplayController() {
|
||||
// Enable MessageDisplayController and mock handler for it
|
||||
when(mResources.getBoolean(mEnrollmentMessageDisplayControllerFlagResId)).thenReturn(true);
|
||||
when(mApplication.getMainThreadHandler()).thenReturn(new TestHandler());
|
||||
|
||||
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
||||
|
||||
// Start enrollment
|
||||
final Object ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
||||
assertThat(ret).isNotNull();
|
||||
assertThat(mCallbackWrapper.mValue).isNotNull();
|
||||
|
||||
// Test default value
|
||||
final LiveData<EnrollmentProgress> progressLiveData = mViewModel.getProgressLiveData();
|
||||
EnrollmentProgress progress = progressLiveData.getValue();
|
||||
assertThat(progress).isNotNull();
|
||||
assertThat(progress.getSteps()).isEqualTo(-1);
|
||||
assertThat(progress.getRemaining()).isEqualTo(0);
|
||||
|
||||
// Update first progress
|
||||
mCallbackWrapper.mValue.onEnrollmentProgress(25);
|
||||
progress = progressLiveData.getValue();
|
||||
assertThat(progress).isNotNull();
|
||||
assertThat(progress.getSteps()).isEqualTo(25);
|
||||
assertThat(progress.getRemaining()).isEqualTo(25);
|
||||
|
||||
// Update second progress
|
||||
mCallbackWrapper.mValue.onEnrollmentProgress(20);
|
||||
progress = progressLiveData.getValue();
|
||||
assertThat(progress).isNotNull();
|
||||
assertThat(progress.getSteps()).isEqualTo(25);
|
||||
assertThat(progress.getRemaining()).isEqualTo(20);
|
||||
|
||||
// Update latest progress
|
||||
mCallbackWrapper.mValue.onEnrollmentProgress(0);
|
||||
progress = progressLiveData.getValue();
|
||||
assertThat(progress).isNotNull();
|
||||
assertThat(progress.getSteps()).isEqualTo(25);
|
||||
assertThat(progress.getRemaining()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetErrorMessageLiveData() {
|
||||
// Start enrollment
|
||||
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
||||
final Object ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
||||
assertThat(ret).isNotNull();
|
||||
assertThat(mCallbackWrapper.mValue).isNotNull();
|
||||
|
||||
// Check default value
|
||||
final LiveData<EnrollmentStatusMessage> liveData = mViewModel.getErrorMessageLiveData();
|
||||
assertThat(liveData.getValue()).isNull();
|
||||
|
||||
// Notify error message
|
||||
final int errMsgId = 3;
|
||||
final String errMsg = "test error message";
|
||||
mCallbackWrapper.mValue.onEnrollmentError(errMsgId, errMsg);
|
||||
final EnrollmentStatusMessage value = liveData.getValue();
|
||||
assertThat(value).isNotNull();
|
||||
assertThat(value.getMsgId()).isEqualTo(errMsgId);
|
||||
assertThat(value.getStr().toString()).isEqualTo(errMsg);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetHelpMessageLiveData() {
|
||||
// Start enrollment
|
||||
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
||||
final Object ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
||||
assertThat(ret).isNotNull();
|
||||
assertThat(mCallbackWrapper.mValue).isNotNull();
|
||||
|
||||
// Check default value
|
||||
final LiveData<EnrollmentStatusMessage> liveData = mViewModel.getHelpMessageLiveData();
|
||||
assertThat(liveData.getValue()).isNull();
|
||||
|
||||
// Notify help message
|
||||
final int errMsgId = 3;
|
||||
final String errMsg = "test error message";
|
||||
mCallbackWrapper.mValue.onEnrollmentHelp(errMsgId, errMsg);
|
||||
final EnrollmentStatusMessage value = liveData.getValue();
|
||||
assertThat(value).isNotNull();
|
||||
assertThat(value.getMsgId()).isEqualTo(errMsgId);
|
||||
assertThat(value.getStr().toString()).isEqualTo(errMsg);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAcquireLiveData() {
|
||||
// Start enrollment
|
||||
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
||||
final Object ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
||||
assertThat(ret).isNotNull();
|
||||
assertThat(mCallbackWrapper.mValue).isNotNull();
|
||||
|
||||
// Check default value
|
||||
final LiveData<Boolean> liveData = mViewModel.getAcquireLiveData();
|
||||
assertThat(liveData.getValue()).isNull();
|
||||
|
||||
// Notify acquire message
|
||||
mCallbackWrapper.mValue.onAcquired(true);
|
||||
assertThat(liveData.getValue()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPointerDownLiveData() {
|
||||
// Start enrollment
|
||||
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
||||
final Object ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
||||
assertThat(ret).isNotNull();
|
||||
assertThat(mCallbackWrapper.mValue).isNotNull();
|
||||
|
||||
// Check default value
|
||||
final LiveData<Integer> liveData = mViewModel.getPointerDownLiveData();
|
||||
assertThat(liveData.getValue()).isNull();
|
||||
|
||||
// Notify acquire message
|
||||
final int value = 33;
|
||||
mCallbackWrapper.mValue.onUdfpsPointerDown(value);
|
||||
assertThat(liveData.getValue()).isEqualTo(value);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPointerUpLiveData() {
|
||||
// Start enrollment
|
||||
mViewModel.setToken(new byte[] { 1, 2, 3 });
|
||||
final Object ret = mViewModel.startEnrollment(ENROLL_ENROLL);
|
||||
assertThat(ret).isNotNull();
|
||||
assertThat(mCallbackWrapper.mValue).isNotNull();
|
||||
|
||||
// Check default value
|
||||
final LiveData<Integer> liveData = mViewModel.getPointerUpLiveData();
|
||||
assertThat(liveData.getValue()).isNull();
|
||||
|
||||
// Notify acquire message
|
||||
final int value = 44;
|
||||
mCallbackWrapper.mValue.onUdfpsPointerUp(value);
|
||||
assertThat(liveData.getValue()).isEqualTo(value);
|
||||
}
|
||||
|
||||
private static class TestWrapper<T> {
|
||||
T mValue;
|
||||
}
|
||||
|
||||
private static class TestHandler extends Handler {
|
||||
|
||||
TestHandler() {
|
||||
super(Looper.getMainLooper());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
|
||||
msg.getCallback().run();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,322 +0,0 @@
|
||||
/*
|
||||
* 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 android.app.Application
|
||||
import android.content.Intent
|
||||
import android.hardware.fingerprint.FingerprintManager
|
||||
import android.hardware.fingerprint.FingerprintSensorProperties
|
||||
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.biometrics.BiometricEnrollBase
|
||||
import com.android.settings.biometrics2.data.repository.FingerprintRepository
|
||||
import com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newAllFalseRequest
|
||||
import com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newIsSuwRequest
|
||||
import com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.newFingerprintRepository
|
||||
import com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.setupFingerprintEnrolledFingerprints
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.flow.toList
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.UnconfinedTestDispatcher
|
||||
import kotlinx.coroutines.test.runCurrent
|
||||
import kotlinx.coroutines.test.runTest
|
||||
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)
|
||||
class FingerprintEnrollmentViewModelTest {
|
||||
|
||||
@get:Rule val mockito: MockitoRule = MockitoJUnit.rule()
|
||||
|
||||
private val application: Application
|
||||
get() = ApplicationProvider.getApplicationContext()
|
||||
|
||||
@Mock
|
||||
private lateinit var fingerprintManager: FingerprintManager
|
||||
|
||||
private lateinit var fingerprintRepository: FingerprintRepository
|
||||
private lateinit var viewModel: FingerprintEnrollmentViewModel
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
fingerprintRepository = newFingerprintRepository(
|
||||
fingerprintManager,
|
||||
FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
|
||||
5
|
||||
)
|
||||
viewModel = FingerprintEnrollmentViewModel(
|
||||
application,
|
||||
fingerprintRepository,
|
||||
newAllFalseRequest(application)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetRequest() {
|
||||
assertThat(viewModel.request).isNotNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIsWaitingActivityResultDefaultFalse() {
|
||||
assertThat(viewModel.isWaitingActivityResult.value).isFalse()
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun testOverrideActivityResult_shallKeepNullIntent_woChallengeExtra() {
|
||||
val retResult = viewModel.getOverrideActivityResult(
|
||||
ActivityResult(22, null), null
|
||||
)
|
||||
assertThat(retResult).isNotNull()
|
||||
assertThat(retResult.data).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOverrideActivityResult_shallKeepNullIntent_noIntent_woChallengeExtra() {
|
||||
val intent = Intent()
|
||||
val retResult = viewModel.getOverrideActivityResult(
|
||||
ActivityResult(33, intent), null
|
||||
)
|
||||
assertThat(retResult).isNotNull()
|
||||
assertThat(retResult.data).isEqualTo(intent)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOverrideActivityResult_shallKeepNull_woAdded_woIntent_withChallenge() {
|
||||
val extra = Bundle()
|
||||
extra.putString("test1", "test123")
|
||||
|
||||
val retResult = viewModel.getOverrideActivityResult(
|
||||
ActivityResult(33, null), extra
|
||||
)
|
||||
|
||||
assertThat(retResult).isNotNull()
|
||||
assertThat(retResult.data).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOverrideActivityResult_shallCreateNew_woIntent_withChallenge() {
|
||||
val key1 = "test1"
|
||||
val key2 = "test2"
|
||||
val extra = Bundle().apply {
|
||||
putString(key1, "test123")
|
||||
putInt(key2, 9999)
|
||||
}
|
||||
|
||||
viewModel.isNewFingerprintAdded = true
|
||||
|
||||
val retResult = viewModel.getOverrideActivityResult(
|
||||
ActivityResult(33, null), extra
|
||||
)
|
||||
assertThat(retResult).isNotNull()
|
||||
|
||||
val retIntent = retResult.data
|
||||
assertThat(retIntent).isNotNull()
|
||||
|
||||
val retExtra = retIntent!!.extras
|
||||
assertThat(retExtra).isNotNull()
|
||||
assertThat(retExtra!!.size).isEqualTo(extra.size)
|
||||
assertThat(retExtra.getString(key1)).isEqualTo(extra.getString(key1))
|
||||
assertThat(retExtra.getInt(key2)).isEqualTo(extra.getInt(key2))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOverrideActivityResult_shallNotMerge_nonAdded_woIntent_withChallenge() {
|
||||
val extra = Bundle().apply {
|
||||
putString("test2", "test123")
|
||||
}
|
||||
|
||||
val key2 = "test2"
|
||||
val intent = Intent().apply {
|
||||
putExtra(key2, 3456L)
|
||||
}
|
||||
|
||||
val retResult = viewModel.getOverrideActivityResult(ActivityResult(33, intent), extra)
|
||||
|
||||
assertThat(retResult).isNotNull()
|
||||
|
||||
val retIntent = retResult.data
|
||||
assertThat(retIntent).isNotNull()
|
||||
|
||||
val retExtra = retIntent!!.extras
|
||||
assertThat(retExtra).isNotNull()
|
||||
assertThat(retExtra!!.size).isEqualTo(intent.extras!!.size)
|
||||
assertThat(retExtra.getString(key2)).isEqualTo(intent.extras!!.getString(key2))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOverrideActivityResult_shallMerge_added_woIntent_withChallenge() {
|
||||
val key1 = "test1"
|
||||
val key2 = "test2"
|
||||
val extra = Bundle().apply {
|
||||
putString(key1, "test123")
|
||||
putInt(key2, 9999)
|
||||
}
|
||||
|
||||
val key3 = "test3"
|
||||
val intent = Intent().apply {
|
||||
putExtra(key3, 3456L)
|
||||
}
|
||||
|
||||
viewModel.isNewFingerprintAdded = true
|
||||
|
||||
val retResult = viewModel.getOverrideActivityResult(ActivityResult(33, intent), extra)
|
||||
assertThat(retResult).isNotNull()
|
||||
|
||||
val retIntent = retResult.data
|
||||
assertThat(retIntent).isNotNull()
|
||||
|
||||
val retExtra = retIntent!!.extras
|
||||
assertThat(retExtra).isNotNull()
|
||||
assertThat(retExtra!!.size).isEqualTo(extra.size + intent.extras!!.size)
|
||||
assertThat(retExtra.getString(key1)).isEqualTo(extra.getString(key1))
|
||||
assertThat(retExtra.getInt(key2)).isEqualTo(extra.getInt(key2))
|
||||
assertThat(retExtra.getLong(key3)).isEqualTo(intent.extras!!.getLong(key3))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIsMaxEnrolledReached() {
|
||||
val uid = 100
|
||||
fingerprintRepository = newFingerprintRepository(
|
||||
fingerprintManager,
|
||||
FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
|
||||
3
|
||||
)
|
||||
viewModel = FingerprintEnrollmentViewModel(
|
||||
application,
|
||||
fingerprintRepository,
|
||||
newAllFalseRequest(application)
|
||||
)
|
||||
|
||||
setupFingerprintEnrolledFingerprints(fingerprintManager, uid, 0)
|
||||
assertThat(viewModel.isMaxEnrolledReached(uid)).isFalse()
|
||||
|
||||
setupFingerprintEnrolledFingerprints(fingerprintManager, uid, 1)
|
||||
assertThat(viewModel.isMaxEnrolledReached(uid)).isFalse()
|
||||
|
||||
setupFingerprintEnrolledFingerprints(fingerprintManager, uid, 2)
|
||||
assertThat(viewModel.isMaxEnrolledReached(uid)).isFalse()
|
||||
|
||||
setupFingerprintEnrolledFingerprints(fingerprintManager, uid, 3)
|
||||
assertThat(viewModel.isMaxEnrolledReached(uid)).isTrue()
|
||||
|
||||
setupFingerprintEnrolledFingerprints(fingerprintManager, uid, 4)
|
||||
assertThat(viewModel.isMaxEnrolledReached(uid)).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSetResultFlow_defaultEmpty() = runTest {
|
||||
val activityResults = listOfSetResultFlow()
|
||||
|
||||
runCurrent()
|
||||
|
||||
assertThat(activityResults.size).isEqualTo(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCheckFinishActivityDuringOnPause_doNothingIfIsSuw() = runTest {
|
||||
viewModel = FingerprintEnrollmentViewModel(
|
||||
application,
|
||||
fingerprintRepository,
|
||||
newIsSuwRequest(application)
|
||||
)
|
||||
|
||||
val activityResults = listOfSetResultFlow()
|
||||
|
||||
viewModel.checkFinishActivityDuringOnPause(
|
||||
isActivityFinishing = false,
|
||||
isChangingConfigurations = false,
|
||||
scope = this
|
||||
)
|
||||
runCurrent()
|
||||
|
||||
assertThat(activityResults.size).isEqualTo(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCheckFinishActivityDuringOnPause_doNothingIfIsWaitingActivity() = runTest {
|
||||
val activityResults = listOfSetResultFlow()
|
||||
|
||||
viewModel.isWaitingActivityResult.value = true
|
||||
viewModel.checkFinishActivityDuringOnPause(
|
||||
isActivityFinishing = false,
|
||||
isChangingConfigurations = false,
|
||||
scope = this
|
||||
)
|
||||
runCurrent()
|
||||
|
||||
assertThat(activityResults.size).isEqualTo(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCheckFinishActivityDuringOnPause_doNothingIfIsActivityFinishing() = runTest {
|
||||
val activityResults = listOfSetResultFlow()
|
||||
|
||||
viewModel.checkFinishActivityDuringOnPause(
|
||||
isActivityFinishing = true,
|
||||
isChangingConfigurations = false,
|
||||
scope = this
|
||||
)
|
||||
runCurrent()
|
||||
|
||||
assertThat(activityResults.size).isEqualTo(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCheckFinishActivityDuringOnPause_doNothingIfIsChangingConfigurations() = runTest {
|
||||
val activityResults = listOfSetResultFlow()
|
||||
|
||||
viewModel.checkFinishActivityDuringOnPause(
|
||||
isActivityFinishing = false,
|
||||
isChangingConfigurations = true,
|
||||
scope = this
|
||||
)
|
||||
runCurrent()
|
||||
|
||||
assertThat(activityResults.size).isEqualTo(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCheckFinishActivityDuringOnPause_defaultFinishSelf() = runTest {
|
||||
val activityResults = listOfSetResultFlow()
|
||||
|
||||
viewModel.checkFinishActivityDuringOnPause(
|
||||
isActivityFinishing = false,
|
||||
isChangingConfigurations = false,
|
||||
scope = backgroundScope
|
||||
)
|
||||
runCurrent()
|
||||
|
||||
assertThat(activityResults.size).isEqualTo(1)
|
||||
assertThat(activityResults[0].resultCode).isEqualTo(BiometricEnrollBase.RESULT_TIMEOUT)
|
||||
assertThat(activityResults[0].data).isEqualTo(null)
|
||||
}
|
||||
|
||||
private fun TestScope.listOfSetResultFlow(): List<ActivityResult> =
|
||||
mutableListOf<ActivityResult>().also {
|
||||
backgroundScope.launch(UnconfinedTestDispatcher(testScheduler)) {
|
||||
viewModel.setResultFlow.toList(it)
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
* 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 android.content.Context
|
||||
import android.content.Intent
|
||||
import android.text.TextUtils
|
||||
import com.android.settings.biometrics.BiometricEnrollBase
|
||||
import com.android.settings.biometrics2.ui.model.EnrollmentRequest
|
||||
import com.google.android.setupcompat.util.WizardManagerHelper
|
||||
|
||||
object EnrollmentRequestUtils {
|
||||
@JvmStatic
|
||||
fun newAllFalseRequest(context: Context): EnrollmentRequest {
|
||||
return newRequest(
|
||||
context = context,
|
||||
isSuw = false,
|
||||
isSuwDeferred = false,
|
||||
isSuwPortal = false,
|
||||
isSuwSuggestedActionFlow = false,
|
||||
isSuwFirstRun = false,
|
||||
isFromSettingsSummery = false)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun newIsSuwRequest(context: Context): EnrollmentRequest {
|
||||
return newRequest(
|
||||
context = context,
|
||||
isSuw = true,
|
||||
isSuwDeferred = false,
|
||||
isSuwPortal = false,
|
||||
isSuwSuggestedActionFlow = false,
|
||||
isSuwFirstRun = false,
|
||||
isFromSettingsSummery = false)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun newIsSuwDeferredRequest(context: Context): EnrollmentRequest {
|
||||
return newRequest(
|
||||
context = context,
|
||||
isSuw = true,
|
||||
isSuwDeferred = true,
|
||||
isSuwPortal = false,
|
||||
isSuwSuggestedActionFlow = false,
|
||||
isSuwFirstRun = false,
|
||||
isFromSettingsSummery = false, null)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun newIsSuwPortalRequest(context: Context): EnrollmentRequest {
|
||||
return newRequest(
|
||||
context = context,
|
||||
isSuw = true,
|
||||
isSuwDeferred = false,
|
||||
isSuwPortal = true,
|
||||
isSuwSuggestedActionFlow = false,
|
||||
isSuwFirstRun = false,
|
||||
isFromSettingsSummery = false)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun newIsSuwSuggestedActionFlowRequest(
|
||||
context: Context
|
||||
): EnrollmentRequest {
|
||||
return newRequest(
|
||||
context = context,
|
||||
isSuw = true,
|
||||
isSuwDeferred = false,
|
||||
isSuwPortal = false,
|
||||
isSuwSuggestedActionFlow = true,
|
||||
isSuwFirstRun = false,
|
||||
isFromSettingsSummery = false)
|
||||
}
|
||||
|
||||
fun newRequest(
|
||||
context: Context,
|
||||
isSuw: Boolean,
|
||||
isSuwDeferred: Boolean,
|
||||
isSuwPortal: Boolean,
|
||||
isSuwSuggestedActionFlow: Boolean,
|
||||
isSuwFirstRun: Boolean,
|
||||
isFromSettingsSummery: Boolean,
|
||||
theme: String? = null
|
||||
): EnrollmentRequest {
|
||||
val i = Intent()
|
||||
i.putExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, isSuw)
|
||||
i.putExtra(WizardManagerHelper.EXTRA_IS_DEFERRED_SETUP, isSuwDeferred)
|
||||
i.putExtra(WizardManagerHelper.EXTRA_IS_PORTAL_SETUP, isSuwPortal)
|
||||
i.putExtra(WizardManagerHelper.EXTRA_IS_SUW_SUGGESTED_ACTION_FLOW, isSuwSuggestedActionFlow)
|
||||
i.putExtra(WizardManagerHelper.EXTRA_IS_FIRST_RUN, isSuwFirstRun)
|
||||
i.putExtra(BiometricEnrollBase.EXTRA_FROM_SETTINGS_SUMMARY, isFromSettingsSummery)
|
||||
if (!TextUtils.isEmpty(theme)) {
|
||||
i.putExtra(WizardManagerHelper.EXTRA_THEME, theme)
|
||||
}
|
||||
return EnrollmentRequest(i, context, true)
|
||||
}
|
||||
}
|
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
@@ -25,7 +25,6 @@ import com.android.settings.accounts.AccountFeatureProvider;
|
||||
import com.android.settings.applications.ApplicationFeatureProvider;
|
||||
import com.android.settings.biometrics.face.FaceFeatureProvider;
|
||||
import com.android.settings.biometrics.fingerprint.FingerprintFeatureProvider;
|
||||
import com.android.settings.biometrics2.factory.BiometricsRepositoryProvider;
|
||||
import com.android.settings.bluetooth.BluetoothFeatureProvider;
|
||||
import com.android.settings.connecteddevice.fastpair.FastPairFeatureProvider;
|
||||
import com.android.settings.connecteddevice.stylus.StylusFeatureProvider;
|
||||
@@ -82,7 +81,6 @@ public class FakeFeatureFactory extends FeatureFactory {
|
||||
public final BluetoothFeatureProvider mBluetoothFeatureProvider;
|
||||
public final FaceFeatureProvider mFaceFeatureProvider;
|
||||
public final FingerprintFeatureProvider mFingerprintFeatureProvider;
|
||||
public final BiometricsRepositoryProvider mBiometricsRepositoryProvider;
|
||||
|
||||
public PanelFeatureProvider panelFeatureProvider;
|
||||
public SlicesFeatureProvider slicesFeatureProvider;
|
||||
@@ -140,7 +138,6 @@ public class FakeFeatureFactory extends FeatureFactory {
|
||||
mBluetoothFeatureProvider = mock(BluetoothFeatureProvider.class);
|
||||
mFaceFeatureProvider = mock(FaceFeatureProvider.class);
|
||||
mFingerprintFeatureProvider = mock(FingerprintFeatureProvider.class);
|
||||
mBiometricsRepositoryProvider = mock(BiometricsRepositoryProvider.class);
|
||||
wifiTrackerLibProvider = mock(WifiTrackerLibProvider.class);
|
||||
securitySettingsFeatureProvider = mock(SecuritySettingsFeatureProvider.class);
|
||||
mAccessibilitySearchFeatureProvider = mock(AccessibilitySearchFeatureProvider.class);
|
||||
@@ -272,11 +269,6 @@ public class FakeFeatureFactory extends FeatureFactory {
|
||||
return mFingerprintFeatureProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiometricsRepositoryProvider getBiometricsRepositoryProvider() {
|
||||
return mBiometricsRepositoryProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WifiTrackerLibProvider getWifiTrackerLibProvider() {
|
||||
return wifiTrackerLibProvider;
|
||||
|
Reference in New Issue
Block a user