From 5d7bab1c2afa2639062b48052c589c7fb1356e01 Mon Sep 17 00:00:00 2001 From: Milton Wu Date: Tue, 10 Jan 2023 15:08:07 +0800 Subject: [PATCH] Refine get props inside FingerprintRepository FingerprintManager::getSensorPropertiesInternal() might return an incorrect value if it's done too soon. Change to use FingerprintManager::addAuthenticatorsRegisteredCallback() in FingerprintRepository. Bug: 264827022 Test: atest FingerprintRepositoryTest FingerprintEnrollIntroViewModelTest FingerprintEnrollmentViewModelTest Change-Id: I68dd3ec1182662cc55aaa8be77a62245ab29cd54 --- .../repository/FingerprintRepository.java | 22 ++- .../repository/FingerprintRepositoryTest.java | 111 ++++------- .../FingerprintEnrollIntroViewModelTest.java | 179 +++++++++++------- .../FingerprintEnrollmentViewModelTest.java | 6 +- .../EnrollmentRequestUtils.java} | 4 +- .../utils/FingerprintRepositoryUtils.java | 82 ++++++++ 6 files changed, 255 insertions(+), 149 deletions(-) rename tests/unit/src/com/android/settings/biometrics2/{util/EnrollmentRequestUtil.java => utils/EnrollmentRequestUtils.java} (97%) create mode 100644 tests/unit/src/com/android/settings/biometrics2/utils/FingerprintRepositoryUtils.java diff --git a/src/com/android/settings/biometrics2/data/repository/FingerprintRepository.java b/src/com/android/settings/biometrics2/data/repository/FingerprintRepository.java index c7229e3eabe..64bf898f97f 100644 --- a/src/com/android/settings/biometrics2/data/repository/FingerprintRepository.java +++ b/src/com/android/settings/biometrics2/data/repository/FingerprintRepository.java @@ -24,6 +24,8 @@ import android.content.res.Resources; import android.hardware.fingerprint.Fingerprint; import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; +import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback; +import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -39,10 +41,21 @@ import java.util.List; */ public class FingerprintRepository { + private static final String TAG = "FingerprintRepository"; @NonNull private final FingerprintManager mFingerprintManager; + private List mSensorPropertiesCache; + public FingerprintRepository(@NonNull FingerprintManager fingerprintManager) { mFingerprintManager = fingerprintManager; + mFingerprintManager.addAuthenticatorsRegisteredCallback( + new IFingerprintAuthenticatorsRegisteredCallback.Stub() { + @Override + public void onAllAuthenticatorsRegistered( + List sensors) { + mSensorPropertiesCache = sensors; + } + }); } /** @@ -86,9 +99,12 @@ public class FingerprintRepository { @Nullable private FingerprintSensorPropertiesInternal getFirstFingerprintSensorPropertiesInternal() { - // TODO(b/264827022) use API addAuthenticatorsRegisteredCallback - final List props = - mFingerprintManager.getSensorPropertiesInternal(); + final List props = mSensorPropertiesCache; + if (props == null) { + // Handle this case if it really happens + Log.e(TAG, "Sensor properties cache is null"); + return null; + } return props.size() > 0 ? props.get(0) : null; } diff --git a/tests/unit/src/com/android/settings/biometrics2/data/repository/FingerprintRepositoryTest.java b/tests/unit/src/com/android/settings/biometrics2/data/repository/FingerprintRepositoryTest.java index 6fb86903316..dec5af86418 100644 --- a/tests/unit/src/com/android/settings/biometrics2/data/repository/FingerprintRepositoryTest.java +++ b/tests/unit/src/com/android/settings/biometrics2/data/repository/FingerprintRepositoryTest.java @@ -23,24 +23,19 @@ import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFP import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_ULTRASONIC; import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UNKNOWN; -import static com.google.common.truth.Truth.assertThat; +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 org.mockito.Mockito.when; +import static com.google.common.truth.Truth.assertThat; 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 androidx.annotation.NonNull; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; -import com.android.settings.testutils.ResourcesUtils; - import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -49,8 +44,6 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; -import java.util.ArrayList; - @RunWith(AndroidJUnit4.class) public class FingerprintRepositoryTest { @@ -60,114 +53,88 @@ public class FingerprintRepositoryTest { @Mock private FingerprintManager mFingerprintManager; private Context mContext; - private FingerprintRepository mFingerprintRepository; @Before public void setUp() { mContext = ApplicationProvider.getApplicationContext(); - mFingerprintRepository = new FingerprintRepository(mFingerprintManager); } @Test public void testCanAssumeSensorType_forUnknownSensor() { - setupFingerprintFirstSensor(mFingerprintManager, TYPE_UNKNOWN, 1); - assertThat(mFingerprintRepository.canAssumeUdfps()).isFalse(); - assertThat(mFingerprintRepository.canAssumeSfps()).isFalse(); + final FingerprintRepository repository = newFingerprintRepository(mFingerprintManager, + TYPE_UNKNOWN, 1); + assertThat(repository.canAssumeUdfps()).isFalse(); + assertThat(repository.canAssumeSfps()).isFalse(); } @Test public void testCanAssumeSensorType_forRearSensor() { - setupFingerprintFirstSensor(mFingerprintManager, TYPE_REAR, 1); - assertThat(mFingerprintRepository.canAssumeUdfps()).isFalse(); - assertThat(mFingerprintRepository.canAssumeSfps()).isFalse(); + final FingerprintRepository repository = newFingerprintRepository(mFingerprintManager, + TYPE_REAR, 1); + assertThat(repository.canAssumeUdfps()).isFalse(); + assertThat(repository.canAssumeSfps()).isFalse(); } @Test public void testCanAssumeSensorType_forUdfpsUltrasonicSensor() { - setupFingerprintFirstSensor(mFingerprintManager, TYPE_UDFPS_ULTRASONIC, 1); - assertThat(mFingerprintRepository.canAssumeUdfps()).isTrue(); - assertThat(mFingerprintRepository.canAssumeSfps()).isFalse(); + final FingerprintRepository repository = newFingerprintRepository(mFingerprintManager, + TYPE_UDFPS_ULTRASONIC, 1); + assertThat(repository.canAssumeUdfps()).isTrue(); + assertThat(repository.canAssumeSfps()).isFalse(); } @Test public void testCanAssumeSensorType_forUdfpsOpticalSensor() { - setupFingerprintFirstSensor(mFingerprintManager, TYPE_UDFPS_OPTICAL, 1); - assertThat(mFingerprintRepository.canAssumeUdfps()).isTrue(); - assertThat(mFingerprintRepository.canAssumeSfps()).isFalse(); + final FingerprintRepository repository = newFingerprintRepository(mFingerprintManager, + TYPE_UDFPS_OPTICAL, 1); + assertThat(repository.canAssumeUdfps()).isTrue(); + assertThat(repository.canAssumeSfps()).isFalse(); } @Test public void testCanAssumeSensorType_forPowerButtonSensor() { - setupFingerprintFirstSensor(mFingerprintManager, TYPE_POWER_BUTTON, 1); - assertThat(mFingerprintRepository.canAssumeUdfps()).isFalse(); - assertThat(mFingerprintRepository.canAssumeSfps()).isTrue(); + final FingerprintRepository repository = newFingerprintRepository(mFingerprintManager, + TYPE_POWER_BUTTON, 1); + assertThat(repository.canAssumeUdfps()).isFalse(); + assertThat(repository.canAssumeSfps()).isTrue(); } @Test public void testCanAssumeSensorType_forHomeButtonSensor() { - setupFingerprintFirstSensor(mFingerprintManager, TYPE_HOME_BUTTON, 1); - assertThat(mFingerprintRepository.canAssumeUdfps()).isFalse(); - assertThat(mFingerprintRepository.canAssumeSfps()).isFalse(); + final FingerprintRepository repository = newFingerprintRepository(mFingerprintManager, + TYPE_HOME_BUTTON, 1); + assertThat(repository.canAssumeUdfps()).isFalse(); + assertThat(repository.canAssumeSfps()).isFalse(); } @Test public void testGetMaxFingerprints() { - setupFingerprintFirstSensor(mFingerprintManager, TYPE_UNKNOWN, 999); - assertThat(mFingerprintRepository.getMaxFingerprints()).isEqualTo(999); + 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(mFingerprintRepository.getNumOfEnrolledFingerprintsSize(10)).isEqualTo(3); - assertThat(mFingerprintRepository.getNumOfEnrolledFingerprintsSize(22)).isEqualTo(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(mFingerprintRepository.getMaxFingerprintsInSuw(mResources)) + assertThat(repository.getMaxFingerprintsInSuw(mResources)) .isEqualTo(333); setupSuwMaxFingerprintsEnrollable(mContext, mResources, 20); - assertThat(mFingerprintRepository.getMaxFingerprintsInSuw(mResources)).isEqualTo(20); + assertThat(repository.getMaxFingerprintsInSuw(mResources)).isEqualTo(20); } - public static void setupSuwMaxFingerprintsEnrollable( - @NonNull Context context, - @NonNull Resources mockedResources, - int numOfFp) { - final int resId = ResourcesUtils.getResourcesId(context, "integer", - "suw_max_fingerprints_enrollable"); - when(mockedResources.getInteger(resId)).thenReturn(numOfFp); - } - - public static void setupFingerprintFirstSensor( - @NonNull FingerprintManager mockedFingerprintManager, - @FingerprintSensorProperties.SensorType int sensorType, - int maxEnrollmentsPerUser) { - - final ArrayList props = new ArrayList<>(); - props.add(new FingerprintSensorPropertiesInternal( - 0 /* sensorId */, - SensorProperties.STRENGTH_STRONG, - maxEnrollmentsPerUser, - new ArrayList<>() /* componentInfo */, - sensorType, - true /* resetLockoutRequiresHardwareAuthToken */)); - when(mockedFingerprintManager.getSensorPropertiesInternal()).thenReturn(props); - } - - public static void setupFingerprintEnrolledFingerprints( - @NonNull FingerprintManager mockedFingerprintManager, - int userId, - int enrolledFingerprints) { - final ArrayList ret = new ArrayList<>(); - for (int i = 0; i < enrolledFingerprints; ++i) { - ret.add(new Fingerprint("name", 0, 0, 0L)); - } - when(mockedFingerprintManager.getEnrolledFingerprints(userId)).thenReturn(ret); - } } diff --git a/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollIntroViewModelTest.java b/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollIntroViewModelTest.java index 192a3050088..9c60b927942 100644 --- a/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollIntroViewModelTest.java +++ b/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollIntroViewModelTest.java @@ -20,20 +20,20 @@ import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_REAR import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_OPTICAL; import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_ULTRASONIC; -import static com.android.settings.biometrics2.data.repository.FingerprintRepositoryTest.setupFingerprintEnrolledFingerprints; -import static com.android.settings.biometrics2.data.repository.FingerprintRepositoryTest.setupFingerprintFirstSensor; -import static com.android.settings.biometrics2.data.repository.FingerprintRepositoryTest.setupSuwMaxFingerprintsEnrollable; import static com.android.settings.biometrics2.ui.model.FingerprintEnrollIntroStatus.FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX; import static com.android.settings.biometrics2.ui.model.FingerprintEnrollIntroStatus.FINGERPRINT_ENROLLABLE_OK; import static com.android.settings.biometrics2.ui.model.FingerprintEnrollIntroStatus.FINGERPRINT_ENROLLABLE_UNKNOWN; import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel.FINGERPRINT_ENROLL_INTRO_ACTION_CONTINUE_ENROLL; import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel.FINGERPRINT_ENROLL_INTRO_ACTION_DONE_AND_FINISH; import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel.FINGERPRINT_ENROLL_INTRO_ACTION_SKIP_OR_CANCEL; -import static com.android.settings.biometrics2.util.EnrollmentRequestUtil.newAllFalseRequest; -import static com.android.settings.biometrics2.util.EnrollmentRequestUtil.newIsSuwDeferredRequest; -import static com.android.settings.biometrics2.util.EnrollmentRequestUtil.newIsSuwPortalRequest; -import static com.android.settings.biometrics2.util.EnrollmentRequestUtil.newIsSuwRequest; -import static com.android.settings.biometrics2.util.EnrollmentRequestUtil.newIsSuwSuggestedActionFlowRequest; +import static com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newAllFalseRequest; +import static com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newIsSuwDeferredRequest; +import static com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newIsSuwPortalRequest; +import static com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newIsSuwRequest; +import static com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newIsSuwSuggestedActionFlowRequest; +import static com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.newFingerprintRepository; +import static com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.setupFingerprintEnrolledFingerprints; +import static com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.setupSuwMaxFingerprintsEnrollable; import static com.google.common.truth.Truth.assertThat; @@ -74,62 +74,83 @@ public class FingerprintEnrollIntroViewModelTest { @Mock private FingerprintManager mFingerprintManager; private Application mApplication; - private FingerprintRepository mFingerprintRepository; - private FingerprintEnrollIntroViewModel mViewModel; + + private FingerprintEnrollIntroViewModel newFingerprintEnrollIntroViewModel( + @NonNull FingerprintRepository fingerprintRepository) { + final FingerprintEnrollIntroViewModel viewModel = + new FingerprintEnrollIntroViewModel(mApplication, fingerprintRepository); + // MediatorLiveData won't update itself unless observed + viewModel.getPageStatusLiveData().observeForever(event -> {}); + return viewModel; + } @Before public void setUp() { mApplication = ApplicationProvider.getApplicationContext(); - mFingerprintRepository = new FingerprintRepository(mFingerprintManager); - mViewModel = new FingerprintEnrollIntroViewModel(mApplication, mFingerprintRepository); - // MediatorLiveData won't update itself unless observed - mViewModel.getPageStatusLiveData().observeForever(event -> {}); } @Test public void testPageStatusLiveDataDefaultValue() { - final FingerprintEnrollIntroStatus status = mViewModel.getPageStatusLiveData().getValue(); + final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel( + newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5)); + final FingerprintEnrollIntroStatus status = viewModel.getPageStatusLiveData().getValue(); assertThat(status.hasScrollToBottom()).isFalse(); assertThat(status.getEnrollableStatus()).isEqualTo(FINGERPRINT_ENROLLABLE_UNKNOWN); } @Test public void testClearActionLiveData() { + final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel( + newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5)); + final MutableLiveData actionLiveData = - (MutableLiveData) mViewModel.getActionLiveData(); + (MutableLiveData) viewModel.getActionLiveData(); actionLiveData.postValue(1); assertThat(actionLiveData.getValue()).isEqualTo(1); - mViewModel.clearActionLiveData(); + viewModel.clearActionLiveData(); assertThat(actionLiveData.getValue()).isNull(); } @Test public void testGetEnrollmentRequest() { + final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel( + newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5)); final EnrollmentRequest request = newAllFalseRequest(mApplication); - mViewModel.setEnrollmentRequest(request); + viewModel.setEnrollmentRequest(request); - assertThat(mViewModel.getEnrollmentRequest()).isEqualTo(request); + assertThat(viewModel.getEnrollmentRequest()).isEqualTo(request); } @Test - public void testOnStartToUpdateEnrollableStatus_isSuw() { + public void testOnStartToUpdateEnrollableStatusOk_isSuw() { + final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel( + newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5)); final int userId = 44; - mViewModel.setUserId(userId); - mViewModel.setEnrollmentRequest(newIsSuwRequest(mApplication)); - + viewModel.setUserId(userId); + viewModel.setEnrollmentRequest(newIsSuwRequest(mApplication)); setupFingerprintEnrolledFingerprints(mFingerprintManager, userId, 0); setupSuwMaxFingerprintsEnrollable(mApplication, mResources, 1); - mViewModel.onStart(mLifecycleOwner); - FingerprintEnrollIntroStatus status = mViewModel.getPageStatusLiveData().getValue(); - assertThat(status.getEnrollableStatus()).isEqualTo(FINGERPRINT_ENROLLABLE_OK); + viewModel.onStart(mLifecycleOwner); + final FingerprintEnrollIntroStatus status = viewModel.getPageStatusLiveData().getValue(); + assertThat(status.getEnrollableStatus()).isEqualTo(FINGERPRINT_ENROLLABLE_OK); + } + + @Test + public void testOnStartToUpdateEnrollableStatusReachMax_isSuw() { + final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel( + newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5)); + final int userId = 44; + viewModel.setUserId(userId); + viewModel.setEnrollmentRequest(newIsSuwRequest(mApplication)); setupFingerprintEnrolledFingerprints(mFingerprintManager, userId, 1); setupSuwMaxFingerprintsEnrollable(mApplication, mResources, 1); - mViewModel.onStart(mLifecycleOwner); - status = mViewModel.getPageStatusLiveData().getValue(); + + viewModel.onStart(mLifecycleOwner); + final FingerprintEnrollIntroStatus status = viewModel.getPageStatusLiveData().getValue(); assertThat(status.getEnrollableStatus()).isEqualTo(FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX); } @@ -176,38 +197,44 @@ public class FingerprintEnrollIntroViewModelTest { private void testOnStartToUpdateEnrollableStatusOk(@NonNull EnrollmentRequest request) { final int userId = 45; - mViewModel.setUserId(userId); - mViewModel.setEnrollmentRequest(request); - + final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel( + newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5)); + viewModel.setUserId(userId); + viewModel.setEnrollmentRequest(request); setupFingerprintEnrolledFingerprints(mFingerprintManager, userId, 0); - setupFingerprintFirstSensor(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5); - mViewModel.onStart(mLifecycleOwner); - FingerprintEnrollIntroStatus status = mViewModel.getPageStatusLiveData().getValue(); + + viewModel.onStart(mLifecycleOwner); + FingerprintEnrollIntroStatus status = viewModel.getPageStatusLiveData().getValue(); assertThat(status.getEnrollableStatus()).isEqualTo(FINGERPRINT_ENROLLABLE_OK); } private void testOnStartToUpdateEnrollableStatusReachMax(@NonNull EnrollmentRequest request) { + final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel( + newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5)); final int userId = 45; - mViewModel.setUserId(userId); - mViewModel.setEnrollmentRequest(request); - + viewModel.setUserId(userId); + viewModel.setEnrollmentRequest(request); setupFingerprintEnrolledFingerprints(mFingerprintManager, userId, 5); - setupFingerprintFirstSensor(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5); - mViewModel.onStart(mLifecycleOwner); - FingerprintEnrollIntroStatus status = mViewModel.getPageStatusLiveData().getValue(); + + viewModel.onStart(mLifecycleOwner); + FingerprintEnrollIntroStatus status = viewModel.getPageStatusLiveData().getValue(); assertThat(status.getEnrollableStatus()).isEqualTo(FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX); } @Test public void textCanAssumeUdfps_forUdfpsUltrasonicSensor() { - setupFingerprintFirstSensor(mFingerprintManager, TYPE_UDFPS_ULTRASONIC, 1); - assertThat(mViewModel.canAssumeUdfps()).isEqualTo(true); + final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel( + newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_ULTRASONIC, 5)); + + assertThat(viewModel.canAssumeUdfps()).isEqualTo(true); } @Test public void textCanAssumeUdfps_forRearSensor() { - setupFingerprintFirstSensor(mFingerprintManager, TYPE_REAR, 1); - assertThat(mViewModel.canAssumeUdfps()).isEqualTo(false); + final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel( + newFingerprintRepository(mFingerprintManager, TYPE_REAR, 5)); + + assertThat(viewModel.canAssumeUdfps()).isEqualTo(false); } @Test @@ -216,13 +243,14 @@ public class FingerprintEnrollIntroViewModelTest { // FingerprintRepository.isParentalConsentRequired() calls static method inside, we can't // mock static method final FingerprintRepository fingerprintRepository = mock(FingerprintRepository.class); - mViewModel = new FingerprintEnrollIntroViewModel(mApplication, fingerprintRepository); + final FingerprintEnrollIntroViewModel viewModel = + new FingerprintEnrollIntroViewModel(mApplication, fingerprintRepository); when(fingerprintRepository.isParentalConsentRequired(mApplication)).thenReturn(true); - assertThat(mViewModel.isParentalConsentRequired()).isEqualTo(true); + assertThat(viewModel.isParentalConsentRequired()).isEqualTo(true); when(fingerprintRepository.isParentalConsentRequired(mApplication)).thenReturn(false); - assertThat(mViewModel.isParentalConsentRequired()).isEqualTo(false); + assertThat(viewModel.isParentalConsentRequired()).isEqualTo(false); } @Test @@ -231,74 +259,87 @@ public class FingerprintEnrollIntroViewModelTest { // FingerprintRepository.isDisabledByAdmin() calls static method inside, we can't mock // static method final FingerprintRepository fingerprintRepository = mock(FingerprintRepository.class); - mViewModel = new FingerprintEnrollIntroViewModel(mApplication, fingerprintRepository); + final FingerprintEnrollIntroViewModel viewModel = + new FingerprintEnrollIntroViewModel(mApplication, fingerprintRepository); final int userId = 33; - mViewModel.setUserId(userId); + viewModel.setUserId(userId); when(fingerprintRepository.isDisabledByAdmin(mApplication, userId)).thenReturn(true); - assertThat(mViewModel.isBiometricUnlockDisabledByAdmin()).isEqualTo(true); + assertThat(viewModel.isBiometricUnlockDisabledByAdmin()).isEqualTo(true); when(fingerprintRepository.isDisabledByAdmin(mApplication, userId)).thenReturn(false); - assertThat(mViewModel.isBiometricUnlockDisabledByAdmin()).isEqualTo(false); + assertThat(viewModel.isBiometricUnlockDisabledByAdmin()).isEqualTo(false); } @Test public void testSetHasScrolledToBottom() { - mViewModel.setHasScrolledToBottom(true); - FingerprintEnrollIntroStatus status = mViewModel.getPageStatusLiveData().getValue(); + final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel( + newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5)); + + viewModel.setHasScrolledToBottom(true); + FingerprintEnrollIntroStatus status = viewModel.getPageStatusLiveData().getValue(); assertThat(status.hasScrollToBottom()).isEqualTo(true); - mViewModel.setHasScrolledToBottom(false); - status = mViewModel.getPageStatusLiveData().getValue(); + viewModel.setHasScrolledToBottom(false); + status = viewModel.getPageStatusLiveData().getValue(); assertThat(status.hasScrollToBottom()).isEqualTo(false); } @Test public void testOnNextButtonClick_enrollNext() { + final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel( + newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5)); final int userId = 46; - mViewModel.setUserId(userId); - mViewModel.setEnrollmentRequest(newIsSuwRequest(mApplication)); + viewModel.setUserId(userId); + viewModel.setEnrollmentRequest(newIsSuwRequest(mApplication)); // Set latest status to FINGERPRINT_ENROLLABLE_OK setupFingerprintEnrolledFingerprints(mFingerprintManager, userId, 0); setupSuwMaxFingerprintsEnrollable(mApplication, mResources, 1); - mViewModel.onStart(mLifecycleOwner); - FingerprintEnrollIntroStatus status = mViewModel.getPageStatusLiveData().getValue(); + + viewModel.onStart(mLifecycleOwner); + FingerprintEnrollIntroStatus status = viewModel.getPageStatusLiveData().getValue(); assertThat(status.getEnrollableStatus()).isEqualTo(FINGERPRINT_ENROLLABLE_OK); // Perform click on `next` - mViewModel.onNextButtonClick(); + viewModel.onNextButtonClick(); - assertThat(mViewModel.getActionLiveData().getValue()) + assertThat(viewModel.getActionLiveData().getValue()) .isEqualTo(FINGERPRINT_ENROLL_INTRO_ACTION_CONTINUE_ENROLL); } @Test public void testOnNextButtonClick_doneAndFinish() { + final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel( + newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5)); final int userId = 46; - mViewModel.setUserId(userId); - mViewModel.setEnrollmentRequest(newIsSuwRequest(mApplication)); + viewModel.setUserId(userId); + viewModel.setEnrollmentRequest(newIsSuwRequest(mApplication)); // Set latest status to FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX setupFingerprintEnrolledFingerprints(mFingerprintManager, userId, 1); setupSuwMaxFingerprintsEnrollable(mApplication, mResources, 1); - mViewModel.onStart(mLifecycleOwner); - FingerprintEnrollIntroStatus status = mViewModel.getPageStatusLiveData().getValue(); + + viewModel.onStart(mLifecycleOwner); + FingerprintEnrollIntroStatus status = viewModel.getPageStatusLiveData().getValue(); assertThat(status.getEnrollableStatus()).isEqualTo(FINGERPRINT_ENROLLABLE_ERROR_REACH_MAX); // Perform click on `next` - mViewModel.onNextButtonClick(); + viewModel.onNextButtonClick(); - assertThat(mViewModel.getActionLiveData().getValue()) + assertThat(viewModel.getActionLiveData().getValue()) .isEqualTo(FINGERPRINT_ENROLL_INTRO_ACTION_DONE_AND_FINISH); } @Test public void testOnSkipOrCancelButtonClick() { - mViewModel.onSkipOrCancelButtonClick(); + final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel( + newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_OPTICAL, 5)); - assertThat(mViewModel.getActionLiveData().getValue()) + viewModel.onSkipOrCancelButtonClick(); + + assertThat(viewModel.getActionLiveData().getValue()) .isEqualTo(FINGERPRINT_ENROLL_INTRO_ACTION_SKIP_OR_CANCEL); } } diff --git a/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollmentViewModelTest.java b/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollmentViewModelTest.java index 736e1ae5b39..a0c1de66e11 100644 --- a/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollmentViewModelTest.java +++ b/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollmentViewModelTest.java @@ -20,10 +20,10 @@ import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_FINISHE import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_SKIP; import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_TIMEOUT; import static com.android.settings.biometrics.fingerprint.SetupFingerprintEnrollIntroduction.EXTRA_FINGERPRINT_ENROLLED_COUNT; -import static com.android.settings.biometrics2.data.repository.FingerprintRepositoryTest.setupFingerprintEnrolledFingerprints; import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollmentViewModel.SAVED_STATE_IS_WAITING_ACTIVITY_RESULT; -import static com.android.settings.biometrics2.util.EnrollmentRequestUtil.newAllFalseRequest; -import static com.android.settings.biometrics2.util.EnrollmentRequestUtil.newIsSuwRequest; +import static com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newAllFalseRequest; +import static com.android.settings.biometrics2.utils.EnrollmentRequestUtils.newIsSuwRequest; +import static com.android.settings.biometrics2.utils.FingerprintRepositoryUtils.setupFingerprintEnrolledFingerprints; import static com.google.common.truth.Truth.assertThat; diff --git a/tests/unit/src/com/android/settings/biometrics2/util/EnrollmentRequestUtil.java b/tests/unit/src/com/android/settings/biometrics2/utils/EnrollmentRequestUtils.java similarity index 97% rename from tests/unit/src/com/android/settings/biometrics2/util/EnrollmentRequestUtil.java rename to tests/unit/src/com/android/settings/biometrics2/utils/EnrollmentRequestUtils.java index 5977c57af2c..ef781b2337a 100644 --- a/tests/unit/src/com/android/settings/biometrics2/util/EnrollmentRequestUtil.java +++ b/tests/unit/src/com/android/settings/biometrics2/utils/EnrollmentRequestUtils.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.settings.biometrics2.util; +package com.android.settings.biometrics2.utils; import static com.android.settings.biometrics.BiometricEnrollBase.EXTRA_FROM_SETTINGS_SUMMARY; @@ -33,7 +33,7 @@ import androidx.annotation.NonNull; import com.android.settings.biometrics2.ui.model.EnrollmentRequest; -public class EnrollmentRequestUtil { +public class EnrollmentRequestUtils { @NonNull public static EnrollmentRequest newAllFalseRequest(@NonNull Context context) { diff --git a/tests/unit/src/com/android/settings/biometrics2/utils/FingerprintRepositoryUtils.java b/tests/unit/src/com/android/settings/biometrics2/utils/FingerprintRepositoryUtils.java new file mode 100644 index 00000000000..011a072a5f4 --- /dev/null +++ b/tests/unit/src/com/android/settings/biometrics2/utils/FingerprintRepositoryUtils.java @@ -0,0 +1,82 @@ +/* + * 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 com.android.settings.testutils.ResourcesUtils; + +import java.util.ArrayList; + +public class FingerprintRepositoryUtils { + + public static void setupSuwMaxFingerprintsEnrollable( + @NonNull Context context, + @NonNull Resources mockedResources, + int numOfFp) { + final int resId = ResourcesUtils.getResourcesId(context, "integer", + "suw_max_fingerprints_enrollable"); + when(mockedResources.getInteger(resId)).thenReturn(numOfFp); + } + + public static FingerprintRepository newFingerprintRepository( + @NonNull FingerprintManager mockedFingerprintManager, + @FingerprintSensorProperties.SensorType int sensorType, + int maxEnrollmentsPerUser) { + + final ArrayList 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 ret = new ArrayList<>(); + for (int i = 0; i < enrolledFingerprints; ++i) { + ret.add(new Fingerprint("name", 0, 0, 0L)); + } + when(mockedFingerprintManager.getEnrolledFingerprints(userId)).thenReturn(ret); + } +}