From 7b817dd0a0094477b746fc34e422a990000f4552 Mon Sep 17 00:00:00 2001 From: Milton Wu Date: Fri, 3 Mar 2023 17:12:00 +0800 Subject: [PATCH] Fix icon touch dialog in Enrolling page 1. Fix icon touch dialog not shown in Enrolling page for SFPS and RFPS devices 2. Remove AccessibilityRepository and VibratorRepository because they only bypass info w/o actual effect. 3. Add/Refine missing test cases for FingerprintRepositoryTest, CredentailModelTest, AutoCredentialViewModelTest, FingerprintEnrollEnrollingViewModelTest, FingerprintEnrollFindSensorViewModelTest, FingerprintEnrollIntroViewModelTest Bug: 271535048 Bug: 271220339 Test: atest FingerprintEnrollmentActivityTest CredentialModelTest FingerprintRepositoryTest AutoCredentialViewModelTest FingerprintEnrollEnrollingViewModelTest FingerprintEnrollFindSensorViewModelTest FingerprintEnrollIntroViewModelTest Test: Manually test enrollment Change-Id: I7d1ed935e156bbd41d5da63902683e430fd3fc1f --- .../repository/AccessibilityRepository.java | 77 ------ .../data/repository/VibratorRepository.java | 43 ---- .../factory/BiometricsRepositoryProvider.java | 14 -- .../BiometricsRepositoryProviderImpl.java | 51 ---- .../factory/BiometricsViewModelFactory.java | 11 +- .../biometrics2/ui/model/CredentialModel.java | 36 +-- ...ingerprintEnrollEnrollingRfpsFragment.java | 2 +- ...ingerprintEnrollEnrollingSfpsFragment.java | 3 +- .../view/FingerprintEnrollmentActivity.java | 4 +- .../ui/viewmodel/AutoCredentialViewModel.java | 23 -- .../FingerprintEnrollEnrollingViewModel.java | 56 ++--- .../FingerprintEnrollmentViewModel.java | 4 - .../repository/FingerprintRepositoryTest.java | 61 +++++ .../ui/model/CredentialModelTest.java | 14 +- .../AutoCredentialViewModelTest.java | 56 +---- ...ngerprintEnrollEnrollingViewModelTest.java | 231 ++++++++++++++++++ ...gerprintEnrollFindSensorViewModelTest.java | 49 ++-- .../FingerprintEnrollIntroViewModelTest.java | 4 +- .../FingerprintEnrollmentViewModelTest.java | 17 +- 19 files changed, 377 insertions(+), 379 deletions(-) delete mode 100644 src/com/android/settings/biometrics2/data/repository/AccessibilityRepository.java delete mode 100644 src/com/android/settings/biometrics2/data/repository/VibratorRepository.java create mode 100644 tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollEnrollingViewModelTest.java diff --git a/src/com/android/settings/biometrics2/data/repository/AccessibilityRepository.java b/src/com/android/settings/biometrics2/data/repository/AccessibilityRepository.java deleted file mode 100644 index 20d7f1fc70f..00000000000 --- a/src/com/android/settings/biometrics2/data/repository/AccessibilityRepository.java +++ /dev/null @@ -1,77 +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.data.repository; - -import android.view.View; -import android.view.accessibility.AccessibilityEvent; -import android.view.accessibility.AccessibilityManager; - -import androidx.annotation.NonNull; - -/** - * This repository is used to call all APIs in {@link AccessibilityManager} - */ -public class AccessibilityRepository { - - private final AccessibilityManager mAccessibilityManager; - - public AccessibilityRepository(AccessibilityManager accessibilityManager) { - mAccessibilityManager = accessibilityManager; - } - - /** - * Requests interruption of the accessibility feedback from all accessibility services. - */ - public void interrupt() { - mAccessibilityManager.interrupt(); - } - - /** - * Returns if the {@link AccessibilityManager} is enabled. - * - * @return True if this {@link AccessibilityManager} is enabled, false otherwise. - */ - public boolean isEnabled() { - return mAccessibilityManager.isEnabled(); - } - - /** - * Sends an {@link AccessibilityEvent}. - * - * @param event The event to send. - * - * @throws IllegalStateException if accessibility is not enabled. - * - * Note: The preferred mechanism for sending custom accessibility - * events is through calling - * {@link android.view.ViewParent#requestSendAccessibilityEvent(View, AccessibilityEvent)} - * instead of this method to allow predecessors to augment/filter events sent by - * their descendants. - */ - public void sendAccessibilityEvent(@NonNull AccessibilityEvent event) { - mAccessibilityManager.sendAccessibilityEvent(event); - } - - /** - * Returns if the touch exploration in the system is enabled. - * - * @return True if touch exploration is enabled, false otherwise. - */ - public boolean isTouchExplorationEnabled() { - return mAccessibilityManager.isTouchExplorationEnabled(); - } -} diff --git a/src/com/android/settings/biometrics2/data/repository/VibratorRepository.java b/src/com/android/settings/biometrics2/data/repository/VibratorRepository.java deleted file mode 100644 index cccafffe28f..00000000000 --- a/src/com/android/settings/biometrics2/data/repository/VibratorRepository.java +++ /dev/null @@ -1,43 +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.data.repository; - -import android.annotation.NonNull; -import android.os.VibrationAttributes; -import android.os.VibrationEffect; -import android.os.Vibrator; - -/** - * This repository is used to call all APIs in {@link Vibrator} - */ -public class VibratorRepository { - - private final Vibrator mVibrator; - - public VibratorRepository(Vibrator vibrator) { - mVibrator = vibrator; - } - - /** - * Like {@link #vibrate(VibrationEffect, VibrationAttributes)}, but allows the - * caller to specify the vibration is owned by someone else and set a reason for vibration. - */ - public void vibrate(int uid, String opPkg, @NonNull VibrationEffect vibe, - String reason, @NonNull VibrationAttributes attributes) { - mVibrator.vibrate(uid, opPkg, vibe, reason, attributes); - } -} diff --git a/src/com/android/settings/biometrics2/factory/BiometricsRepositoryProvider.java b/src/com/android/settings/biometrics2/factory/BiometricsRepositoryProvider.java index 8e17ba45d97..fdc5745e926 100644 --- a/src/com/android/settings/biometrics2/factory/BiometricsRepositoryProvider.java +++ b/src/com/android/settings/biometrics2/factory/BiometricsRepositoryProvider.java @@ -21,9 +21,7 @@ import android.app.Application; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.android.settings.biometrics2.data.repository.AccessibilityRepository; import com.android.settings.biometrics2.data.repository.FingerprintRepository; -import com.android.settings.biometrics2.data.repository.VibratorRepository; /** * Interface for BiometricsRepositoryProvider @@ -35,16 +33,4 @@ public interface BiometricsRepositoryProvider { */ @Nullable FingerprintRepository getFingerprintRepository(@NonNull Application application); - - /** - * Get VibtatorRepository - */ - @Nullable - VibratorRepository getVibratorRepository(@NonNull Application application); - - /** - * Get AccessibilityRepository - */ - @Nullable - AccessibilityRepository getAccessibilityRepository(@NonNull Application application); } diff --git a/src/com/android/settings/biometrics2/factory/BiometricsRepositoryProviderImpl.java b/src/com/android/settings/biometrics2/factory/BiometricsRepositoryProviderImpl.java index 7b1fe162a8e..22409c849d7 100644 --- a/src/com/android/settings/biometrics2/factory/BiometricsRepositoryProviderImpl.java +++ b/src/com/android/settings/biometrics2/factory/BiometricsRepositoryProviderImpl.java @@ -18,16 +18,12 @@ package com.android.settings.biometrics2.factory; import android.app.Application; import android.hardware.fingerprint.FingerprintManager; -import android.os.Vibrator; -import android.view.accessibility.AccessibilityManager; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.settings.Utils; -import com.android.settings.biometrics2.data.repository.AccessibilityRepository; import com.android.settings.biometrics2.data.repository.FingerprintRepository; -import com.android.settings.biometrics2.data.repository.VibratorRepository; /** * Implementation for BiometricsRepositoryProvider @@ -35,8 +31,6 @@ import com.android.settings.biometrics2.data.repository.VibratorRepository; public class BiometricsRepositoryProviderImpl implements BiometricsRepositoryProvider { private static volatile FingerprintRepository sFingerprintRepository; - private static volatile VibratorRepository sVibratorRepository; - private static volatile AccessibilityRepository sAccessibilityRepository; /** * Get FingerprintRepository @@ -58,49 +52,4 @@ public class BiometricsRepositoryProviderImpl implements BiometricsRepositoryPro } return sFingerprintRepository; } - - /** - * Get VibratorRepository - */ - @Nullable - @Override - public VibratorRepository getVibratorRepository(@NonNull Application application) { - - final Vibrator vibrator = application.getSystemService(Vibrator.class); - if (vibrator == null) { - return null; - } - - if (sVibratorRepository == null) { - synchronized (VibratorRepository.class) { - if (sVibratorRepository == null) { - sVibratorRepository = new VibratorRepository(vibrator); - } - } - } - return sVibratorRepository; - } - - /** - * Get AccessibilityRepository - */ - @Nullable - @Override - public AccessibilityRepository getAccessibilityRepository(@NonNull Application application) { - - final AccessibilityManager accessibilityManager = application.getSystemService( - AccessibilityManager.class); - if (accessibilityManager == null) { - return null; - } - - if (sAccessibilityRepository == null) { - synchronized (AccessibilityRepository.class) { - if (sAccessibilityRepository == null) { - sAccessibilityRepository = new AccessibilityRepository(accessibilityManager); - } - } - } - return sAccessibilityRepository; - } } diff --git a/src/com/android/settings/biometrics2/factory/BiometricsViewModelFactory.java b/src/com/android/settings/biometrics2/factory/BiometricsViewModelFactory.java index 970ed0279a2..dd5b6738ab0 100644 --- a/src/com/android/settings/biometrics2/factory/BiometricsViewModelFactory.java +++ b/src/com/android/settings/biometrics2/factory/BiometricsViewModelFactory.java @@ -27,9 +27,7 @@ import androidx.lifecycle.viewmodel.CreationExtras; import com.android.internal.widget.LockPatternUtils; import com.android.settings.biometrics.fingerprint.FingerprintUpdater; -import com.android.settings.biometrics2.data.repository.AccessibilityRepository; import com.android.settings.biometrics2.data.repository.FingerprintRepository; -import com.android.settings.biometrics2.data.repository.VibratorRepository; import com.android.settings.biometrics2.ui.model.EnrollmentRequest; import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel; import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.ChallengeGenerator; @@ -115,12 +113,9 @@ public class BiometricsViewModelFactory implements ViewModelProvider.Factory { final Integer userId = extras.get(USER_ID_KEY); final FingerprintRepository fingerprint = provider.getFingerprintRepository( application); - final AccessibilityRepository accessibility = provider.getAccessibilityRepository( - application); - final VibratorRepository vibrator = provider.getVibratorRepository(application); - if (fingerprint != null && accessibility != null && vibrator != null) { - return (T) new FingerprintEnrollEnrollingViewModel(application, userId, fingerprint, - accessibility, vibrator); + if (fingerprint != null) { + return (T) new FingerprintEnrollEnrollingViewModel(application, userId, + fingerprint); } } else if (modelClass.isAssignableFrom(FingerprintEnrollFinishViewModel.class)) { final Integer userId = extras.get(USER_ID_KEY); diff --git a/src/com/android/settings/biometrics2/ui/model/CredentialModel.java b/src/com/android/settings/biometrics2/ui/model/CredentialModel.java index a6e8b6e7173..caff80a8e2a 100644 --- a/src/com/android/settings/biometrics2/ui/model/CredentialModel.java +++ b/src/com/android/settings/biometrics2/ui/model/CredentialModel.java @@ -17,7 +17,6 @@ package com.android.settings.biometrics2.ui.model; import static com.android.settings.biometrics.BiometricEnrollBase.EXTRA_KEY_CHALLENGE; -import static com.android.settings.biometrics.BiometricEnrollBase.EXTRA_KEY_SENSOR_ID; import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN; import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE; @@ -34,10 +33,9 @@ import java.time.Clock; /** * Secret credential data including * 1. userId - * 2. sensorId - * 3. challenge - * 4. token - * 5. gkPwHandle + * 2. challenge + * 3. token + * 4. gkPwHandle */ public final class CredentialModel { @@ -53,22 +51,12 @@ public final class CredentialModel { @VisibleForTesting public static final long INVALID_GK_PW_HANDLE = 0L; - /** - * Default value for a invalid sensor id - */ - @VisibleForTesting - public static final int INVALID_SENSOR_ID = -1; - private final Clock mClock; private final long mInitMillis; private final int mUserId; - private int mSensorId; - @Nullable - private Long mUpdateSensorIdMillis = null; - private long mChallenge; @Nullable private Long mUpdateChallengeMillis = null; @@ -87,7 +75,6 @@ public final class CredentialModel { bundle = new Bundle(); } mUserId = bundle.getInt(Intent.EXTRA_USER_ID, UserHandle.myUserId()); - mSensorId = bundle.getInt(EXTRA_KEY_SENSOR_ID, INVALID_SENSOR_ID); mChallenge = bundle.getLong(EXTRA_KEY_CHALLENGE, INVALID_CHALLENGE); mToken = bundle.getByteArray(EXTRA_KEY_CHALLENGE_TOKEN); mGkPwHandle = bundle.getLong(EXTRA_KEY_GK_PW_HANDLE, INVALID_GK_PW_HANDLE); @@ -102,7 +89,6 @@ public final class CredentialModel { public Bundle getBundle() { final Bundle bundle = new Bundle(); bundle.putInt(Intent.EXTRA_USER_ID, mUserId); - bundle.putInt(EXTRA_KEY_SENSOR_ID, mSensorId); bundle.putLong(EXTRA_KEY_CHALLENGE, mChallenge); bundle.putByteArray(EXTRA_KEY_CHALLENGE_TOKEN, mToken); bundle.putLong(EXTRA_KEY_GK_PW_HANDLE, mGkPwHandle); @@ -190,21 +176,6 @@ public final class CredentialModel { return mGkPwHandle != INVALID_GK_PW_HANDLE; } - /** - * Get sensor id - */ - public int getSensorId() { - return mSensorId; - } - - /** - * Set sensor id - */ - public void setSensorId(int value) { - mUpdateSensorIdMillis = mClock.millis(); - mSensorId = value; - } - /** * Returns a string representation of the object */ @@ -221,7 +192,6 @@ public final class CredentialModel { + ", updateMillis:" + mUpdateTokenMillis + "}" + ", gkPwHandle:{len:" + gkPwHandleLen + ", isValid:" + isValidGkPwHandle() + ", clearMillis:" + mClearGkPwHandleMillis + "}" - + ", mSensorId:{id:" + mSensorId + ", updateMillis:" + mUpdateSensorIdMillis + "}" + " }"; } } diff --git a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingRfpsFragment.java b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingRfpsFragment.java index 8e022e0c091..8a4ed633222 100644 --- a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingRfpsFragment.java +++ b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingRfpsFragment.java @@ -418,7 +418,7 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment { private void showIconTouchDialog() { mIconTouchCount = 0; - mEnrollingViewModel.onIconTouchDialogShow(); + mEnrollingViewModel.showIconTouchDialog(); } private final Runnable mShowDialogRunnable = () -> showIconTouchDialog(); diff --git a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingSfpsFragment.java b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingSfpsFragment.java index ab772e3771b..720857c32b0 100644 --- a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingSfpsFragment.java +++ b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollEnrollingSfpsFragment.java @@ -540,8 +540,7 @@ public class FingerprintEnrollEnrollingSfpsFragment extends Fragment { private void showIconTouchDialog() { mIconTouchCount = 0; - //TODO EnrollingActivity should observe live data and add dialog fragment - mEnrollingViewModel.onIconTouchDialogShow(); + mEnrollingViewModel.showIconTouchDialog(); } private final Runnable mShowDialogRunnable = () -> showIconTouchDialog(); diff --git a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivity.java b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivity.java index ff43e8bea30..7f69b91d9e8 100644 --- a/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivity.java +++ b/src/com/android/settings/biometrics2/ui/view/FingerprintEnrollmentActivity.java @@ -30,8 +30,8 @@ import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnr import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_ACTION_DISMISS_ICON_TOUCH_DIALOG; import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_ACTION_DONE; 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_ACTION_SKIP; 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.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH; import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_TIMEOUT; import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FingerprintEnrollEnrollingAction; @@ -503,7 +503,7 @@ public class FingerprintEnrollmentActivity extends FragmentActivity { startFinishFragment(); break; } - case FINGERPRINT_ENROLL_ENROLLING_ACTION_SKIP: { + case FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_USER_SKIP: { onSetActivityResult(new ActivityResult(BiometricEnrollBase.RESULT_SKIP, null)); break; } diff --git a/src/com/android/settings/biometrics2/ui/viewmodel/AutoCredentialViewModel.java b/src/com/android/settings/biometrics2/ui/viewmodel/AutoCredentialViewModel.java index 2b7b3b79d6f..7e48f82136d 100644 --- a/src/com/android/settings/biometrics2/ui/viewmodel/AutoCredentialViewModel.java +++ b/src/com/android/settings/biometrics2/ui/viewmodel/AutoCredentialViewModel.java @@ -19,9 +19,7 @@ package com.android.settings.biometrics2.ui.viewmodel; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; import static com.android.settings.biometrics.BiometricEnrollBase.EXTRA_KEY_CHALLENGE; -import static com.android.settings.biometrics.BiometricEnrollBase.EXTRA_KEY_SENSOR_ID; import static com.android.settings.biometrics2.ui.model.CredentialModel.INVALID_GK_PW_HANDLE; -import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN; import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE; import android.annotation.IntDef; @@ -268,7 +266,6 @@ public class AutoCredentialViewModel extends AndroidViewModel { mChallengeGenerator.setCallback((sensorId, userId, challenge) -> { try { final byte[] newToken = requestGatekeeperHat(gkPwHandle, challenge, userId); - mCredentialModel.setSensorId(sensorId); mCredentialModel.setChallenge(challenge); mCredentialModel.setToken(newToken); } catch (IllegalStateException e) { @@ -354,26 +351,6 @@ public class AutoCredentialViewModel extends AndroidViewModel { return response.getGatekeeperHAT(); } - /** - * Get Credential intent extra which will be used to launch next activity. - */ - @NonNull - public Bundle createCredentialIntentExtra() { - final Bundle retBundle = new Bundle(); - if (mCredentialModel.isValidGkPwHandle()) { - retBundle.putLong(EXTRA_KEY_GK_PW_HANDLE, mCredentialModel.getGkPwHandle()); - } - if (mCredentialModel.isValidToken()) { - retBundle.putByteArray(EXTRA_KEY_CHALLENGE_TOKEN, mCredentialModel.getToken()); - } - if (mCredentialModel.isValidUserId()) { - retBundle.putInt(Intent.EXTRA_USER_ID, mCredentialModel.getUserId()); - } - retBundle.putLong(EXTRA_KEY_CHALLENGE, mCredentialModel.getChallenge()); - retBundle.putInt(EXTRA_KEY_SENSOR_ID, mCredentialModel.getSensorId()); - return retBundle; - } - /** * Create Intent for choosing lock */ diff --git a/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollEnrollingViewModel.java b/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollEnrollingViewModel.java index 194bc1e2ed9..025c58bca95 100644 --- a/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollEnrollingViewModel.java +++ b/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollEnrollingViewModel.java @@ -21,6 +21,7 @@ import android.app.Application; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.os.VibrationAttributes; import android.os.VibrationEffect; +import android.os.Vibrator; import android.util.Log; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; @@ -31,9 +32,7 @@ import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; -import com.android.settings.biometrics2.data.repository.AccessibilityRepository; import com.android.settings.biometrics2.data.repository.FingerprintRepository; -import com.android.settings.biometrics2.data.repository.VibratorRepository; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -51,25 +50,25 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel { private static final VibrationAttributes FINGERPRINT_ENROLLING_SONFICATION_ATTRIBUTES = VibrationAttributes.createForUsage(VibrationAttributes.USAGE_ACCESSIBILITY); - /** - * Enrolling skipped - */ - public static final int FINGERPRINT_ENROLL_ENROLLING_ACTION_SKIP = 0; - /** * Enrolling finished */ - public static final int FINGERPRINT_ENROLL_ENROLLING_ACTION_DONE = 1; + public static final int FINGERPRINT_ENROLL_ENROLLING_ACTION_DONE = 0; /** * Icon touch dialog show */ - public static final int FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG = 2; + public static final int FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG = 1; /** * Icon touch dialog dismiss */ - public static final int FINGERPRINT_ENROLL_ENROLLING_ACTION_DISMISS_ICON_TOUCH_DIALOG = 3; + public static final int FINGERPRINT_ENROLL_ENROLLING_ACTION_DISMISS_ICON_TOUCH_DIALOG = 2; + + /** + * Has got latest cancelled event due to user skip + */ + public static final int FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_USER_SKIP = 3; /** * Has got latest cancelled event due to back key @@ -77,10 +76,10 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel { public static final int FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED = 4; @IntDef(prefix = { "FINGERPRINT_ENROLL_ENROLLING_ACTION_" }, value = { - FINGERPRINT_ENROLL_ENROLLING_ACTION_SKIP, FINGERPRINT_ENROLL_ENROLLING_ACTION_DONE, FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG, FINGERPRINT_ENROLL_ENROLLING_ACTION_DISMISS_ICON_TOUCH_DIALOG, + FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_USER_SKIP, FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED }) @Retention(RetentionPolicy.SOURCE) @@ -112,25 +111,22 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel { private final int mUserId; private boolean mOnBackPressed; private boolean mOnSkipPressed; - private final FingerprintRepository mFingerprintRepository; - private final AccessibilityRepository mAccessibilityRepository; - private final VibratorRepository mVibratorRepository; + @NonNull private final FingerprintRepository mFingerprintRepository; + private final AccessibilityManager mAccessibilityManager; + private final Vibrator mVibrator; private final MutableLiveData mActionLiveData = new MutableLiveData<>(); private final MutableLiveData mIconTouchDialogLiveData = new MutableLiveData<>(); private final MutableLiveData mErrorDialogLiveData = new MutableLiveData<>(); private final MutableLiveData mErrorDialogActionLiveData = new MutableLiveData<>(); - public FingerprintEnrollEnrollingViewModel(Application application, - int userId, - FingerprintRepository fingerprintRepository, - AccessibilityRepository accessibilityRepository, - VibratorRepository vibratorRepository) { + public FingerprintEnrollEnrollingViewModel(@NonNull Application application, + int userId, @NonNull FingerprintRepository fingerprintRepository) { super(application); mUserId = userId; mFingerprintRepository = fingerprintRepository; - mAccessibilityRepository = accessibilityRepository; - mVibratorRepository = vibratorRepository; + mAccessibilityManager = application.getSystemService(AccessibilityManager.class); + mVibrator = application.getSystemService(Vibrator.class); } /** @@ -184,7 +180,7 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel { * Enrolling is cacelled because user clicks skip */ public void onCancelledDueToOnSkipPressed() { - final int action = FINGERPRINT_ENROLL_ENROLLING_ACTION_SKIP; + final int action = FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_USER_SKIP; if (DEBUG) { Log.d(TAG, "onSkipButtonClick, post action " + action); } @@ -229,12 +225,12 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel { /** * Icon touch dialog show */ - public void onIconTouchDialogShow() { + public void showIconTouchDialog() { final int action = FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG; if (DEBUG) { Log.d(TAG, "onIconTouchDialogShow, post action " + action); } - mIconTouchDialogLiveData.postValue(action); + mActionLiveData.postValue(action); } /** @@ -245,7 +241,7 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel { if (DEBUG) { Log.d(TAG, "onIconTouchDialogDismiss, post action " + action); } - mIconTouchDialogLiveData.postValue(action); + mActionLiveData.postValue(action); } /** @@ -266,7 +262,7 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel { * Requests interruption of the accessibility feedback from all accessibility services. */ public void clearTalkback() { - mAccessibilityRepository.interrupt(); + mAccessibilityManager.interrupt(); } /** @@ -275,7 +271,7 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel { * @return True if this {@link AccessibilityManager} is enabled, false otherwise. */ public boolean isAccessibilityEnabled() { - return mAccessibilityRepository.isEnabled(); + return mAccessibilityManager.isEnabled(); } /** @@ -287,7 +283,7 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel { e.setClassName(getClass().getName()); e.setPackageName(getApplication().getPackageName()); e.getText().add(announcement); - mAccessibilityRepository.sendAccessibilityEvent(e); + mAccessibilityManager.sendAccessibilityEvent(e); } /** @@ -296,7 +292,7 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel { * @return True if touch exploration is enabled, false otherwise. */ public boolean isTouchExplorationEnabled() { - return mAccessibilityRepository.isTouchExplorationEnabled(); + return mAccessibilityManager.isTouchExplorationEnabled(); } /** @@ -304,7 +300,7 @@ public class FingerprintEnrollEnrollingViewModel extends AndroidViewModel { * caller to specify the vibration is owned by someone else and set a reason for vibration. */ public void vibrateError(String reason) { - mVibratorRepository.vibrate(mUserId, getApplication().getOpPackageName(), + mVibrator.vibrate(mUserId, getApplication().getOpPackageName(), VIBRATE_EFFECT_ERROR, reason, FINGERPRINT_ENROLLING_SONFICATION_ATTRIBUTES); } diff --git a/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollmentViewModel.java b/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollmentViewModel.java index 4f07ae6bacd..3c779c95104 100644 --- a/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollmentViewModel.java +++ b/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollmentViewModel.java @@ -179,10 +179,6 @@ public class FingerprintEnrollmentViewModel extends AndroidViewModel { return mFingerprintRepository.canAssumeSfps(); } - public boolean isNewFingerprintAdded() { - return mIsNewFingerprintAdded; - } - /** * Sets mIsNewFingerprintAdded to true */ diff --git a/tests/unit/src/com/android/settings/biometrics2/repository/FingerprintRepositoryTest.java b/tests/unit/src/com/android/settings/biometrics2/repository/FingerprintRepositoryTest.java index 727559b55eb..89895955f58 100644 --- a/tests/unit/src/com/android/settings/biometrics2/repository/FingerprintRepositoryTest.java +++ b/tests/unit/src/com/android/settings/biometrics2/repository/FingerprintRepositoryTest.java @@ -29,9 +29,16 @@ import static com.android.settings.biometrics2.utils.FingerprintRepositoryUtils. 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; @@ -46,6 +53,8 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; +import java.util.ArrayList; + @RunWith(AndroidJUnit4.class) public class FingerprintRepositoryTest { @@ -139,4 +148,56 @@ public class FingerprintRepositoryTest { assertThat(repository.getMaxFingerprintsInSuw(mResources)).isEqualTo(20); } + @Test + public void testGetFirstFingerprintSensorPropertiesInternal() { + final ArrayList 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); + } } diff --git a/tests/unit/src/com/android/settings/biometrics2/ui/model/CredentialModelTest.java b/tests/unit/src/com/android/settings/biometrics2/ui/model/CredentialModelTest.java index 57b74205c5a..8dfca016093 100644 --- a/tests/unit/src/com/android/settings/biometrics2/ui/model/CredentialModelTest.java +++ b/tests/unit/src/com/android/settings/biometrics2/ui/model/CredentialModelTest.java @@ -48,11 +48,10 @@ public class CredentialModelTest { private final Clock mClock = SystemClock.elapsedRealtimeClock(); - public static Bundle newCredentialModelIntentExtras(int userId, long challenge, int sensorId, + public static Bundle newCredentialModelIntentExtras(int userId, long challenge, @Nullable byte[] token, long gkPwHandle) { final Bundle bundle = new Bundle(); bundle.putInt(Intent.EXTRA_USER_ID, userId); - bundle.putInt(EXTRA_KEY_SENSOR_ID, sensorId); bundle.putLong(EXTRA_KEY_CHALLENGE, challenge); bundle.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token); bundle.putLong(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, gkPwHandle); @@ -60,17 +59,17 @@ public class CredentialModelTest { } public static Bundle newValidTokenCredentialIntentExtras(int userId) { - return newCredentialModelIntentExtras(userId, 1L, 1, new byte[] { 0, 1, 2 }, + return newCredentialModelIntentExtras(userId, 1L, new byte[] { 0, 1, 2 }, INVALID_GK_PW_HANDLE); } public static Bundle newOnlySensorValidCredentialIntentExtras(int userId) { - return newCredentialModelIntentExtras(userId, INVALID_CHALLENGE, 1, null, + return newCredentialModelIntentExtras(userId, INVALID_CHALLENGE, null, INVALID_GK_PW_HANDLE); } public static Bundle newGkPwHandleCredentialIntentExtras(int userId, long gkPwHandle) { - return newCredentialModelIntentExtras(userId, INVALID_CHALLENGE, 1, null, gkPwHandle); + return newCredentialModelIntentExtras(userId, INVALID_CHALLENGE, null, gkPwHandle); } private static void checkBundleLongValue(@NonNull Bundle bundle1, @NonNull Bundle bundle2, @@ -118,7 +117,6 @@ public class CredentialModelTest { @NonNull CredentialModel model2) { assertThat(model1.getUserId()).isEqualTo(model2.getUserId()); - assertThat(model1.getSensorId()).isEqualTo(model2.getSensorId()); assertThat(model1.getChallenge()).isEqualTo(model2.getChallenge()); assertThat(model1.getGkPwHandle()).isEqualTo(model2.getGkPwHandle()); @@ -154,7 +152,7 @@ public class CredentialModelTest { @Test public void testSameValueFromBundle() { - final Bundle bundle = newCredentialModelIntentExtras(1234, 6677L, 1, + final Bundle bundle = newCredentialModelIntentExtras(1234, 6677L, new byte[] { 33, 44, 55 }, 987654321); final CredentialModel model1 = new CredentialModel(bundle, mClock); @@ -165,7 +163,7 @@ public class CredentialModelTest { @Test public void testSameValueFromBundle_nullToken() { - final Bundle bundle = newCredentialModelIntentExtras(22, 33L, 1, null, 21L); + final Bundle bundle = newCredentialModelIntentExtras(22, 33L, null, 21L); final CredentialModel model1 = new CredentialModel(bundle, mClock); final CredentialModel model2 = new CredentialModel(model1.getBundle(), mClock); diff --git a/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/AutoCredentialViewModelTest.java b/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/AutoCredentialViewModelTest.java index c12be68e54d..05a7239e95d 100644 --- a/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/AutoCredentialViewModelTest.java +++ b/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/AutoCredentialViewModelTest.java @@ -22,10 +22,8 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; import static com.android.settings.biometrics.BiometricEnrollBase.EXTRA_KEY_CHALLENGE; -import static com.android.settings.biometrics.BiometricEnrollBase.EXTRA_KEY_SENSOR_ID; import static com.android.settings.biometrics2.ui.model.CredentialModel.INVALID_CHALLENGE; import static com.android.settings.biometrics2.ui.model.CredentialModel.INVALID_GK_PW_HANDLE; -import static com.android.settings.biometrics2.ui.model.CredentialModel.INVALID_SENSOR_ID; import static com.android.settings.biometrics2.ui.model.CredentialModelTest.newCredentialModelIntentExtras; import static com.android.settings.biometrics2.ui.model.CredentialModelTest.newGkPwHandleCredentialIntentExtras; import static com.android.settings.biometrics2.ui.model.CredentialModelTest.newOnlySensorValidCredentialIntentExtras; @@ -103,7 +101,7 @@ public class AutoCredentialViewModelTest { @Test public void testSetCredentialModel_sameResultFromSavedInstanceOrIntent() { - final Bundle extras = newCredentialModelIntentExtras(12, 33, 1, new byte[] { 2, 3 }, 3L); + final Bundle extras = newCredentialModelIntentExtras(12, 33, new byte[] { 2, 3 }, 3L); AutoCredentialViewModel viewModel2 = new AutoCredentialViewModel( ApplicationProvider.getApplicationContext(), @@ -115,18 +113,9 @@ public class AutoCredentialViewModelTest { mViewModel.onSaveInstanceState(savedInstance); viewModel2.setCredentialModel(savedInstance, new Intent()); - final Bundle bundle1 = mViewModel.createCredentialIntentExtra(); - final Bundle bundle2 = viewModel2.createCredentialIntentExtra(); - assertThat(bundle1.getLong(EXTRA_KEY_GK_PW_HANDLE)) - .isEqualTo(bundle2.getLong(EXTRA_KEY_GK_PW_HANDLE)); - assertThat(bundle1.getLong(Intent.EXTRA_USER_ID)) - .isEqualTo(bundle2.getLong(Intent.EXTRA_USER_ID)); - assertThat(bundle1.getLong(EXTRA_KEY_CHALLENGE)) - .isEqualTo(bundle2.getLong(EXTRA_KEY_CHALLENGE)); - assertThat(bundle1.getInt(EXTRA_KEY_SENSOR_ID)) - .isEqualTo(bundle2.getInt(EXTRA_KEY_SENSOR_ID)); - final byte[] token1 = bundle1.getByteArray(EXTRA_KEY_CHALLENGE_TOKEN); - final byte[] token2 = bundle2.getByteArray(EXTRA_KEY_CHALLENGE_TOKEN); + assertThat(mViewModel.getUserId()).isEqualTo(viewModel2.getUserId()); + final byte[] token1 = mViewModel.getToken(); + final byte[] token2 = viewModel2.getToken(); assertThat(token1).isNotNull(); assertThat(token2).isNotNull(); assertThat(token1.length).isEqualTo(token2.length); @@ -138,7 +127,7 @@ public class AutoCredentialViewModelTest { @Test public void testSetCredentialModel_sameResultFromSavedInstanceOrIntent_invalidValues() { final Bundle extras = newCredentialModelIntentExtras(UserHandle.USER_NULL, - INVALID_CHALLENGE, INVALID_SENSOR_ID, null, INVALID_GK_PW_HANDLE); + INVALID_CHALLENGE, null, INVALID_GK_PW_HANDLE); AutoCredentialViewModel viewModel2 = new AutoCredentialViewModel( ApplicationProvider.getApplicationContext(), @@ -150,16 +139,10 @@ public class AutoCredentialViewModelTest { mViewModel.onSaveInstanceState(savedInstance); viewModel2.setCredentialModel(savedInstance, new Intent()); - final Bundle bundle1 = mViewModel.createCredentialIntentExtra(); - final Bundle bundle2 = viewModel2.createCredentialIntentExtra(); - assertThat(bundle1.containsKey(EXTRA_KEY_GK_PW_HANDLE)).isFalse(); - assertThat(bundle2.containsKey(EXTRA_KEY_GK_PW_HANDLE)).isFalse(); - assertThat(bundle1.containsKey(EXTRA_KEY_CHALLENGE_TOKEN)).isFalse(); - assertThat(bundle2.containsKey(EXTRA_KEY_CHALLENGE_TOKEN)).isFalse(); - assertThat(bundle1.containsKey(EXTRA_KEY_SENSOR_ID)).isTrue(); - assertThat(bundle2.containsKey(EXTRA_KEY_SENSOR_ID)).isTrue(); - assertThat(bundle1.containsKey(Intent.EXTRA_USER_ID)).isFalse(); - assertThat(bundle2.containsKey(Intent.EXTRA_USER_ID)).isFalse(); + assertThat(mViewModel.getUserId()).isEqualTo(UserHandle.USER_NULL); + assertThat(viewModel2.getUserId()).isEqualTo(UserHandle.USER_NULL); + assertThat(mViewModel.getToken()).isNull(); + assertThat(viewModel2.getToken()).isNull(); } @Test @@ -316,12 +299,7 @@ public class AutoCredentialViewModelTest { assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull(); // Check data inside CredentialModel - final Bundle extras = mViewModel.createCredentialIntentExtra(); - assertThat(extras.getInt(EXTRA_KEY_SENSOR_ID)).isEqualTo(newSensorId); - assertThat(extras.getLong(EXTRA_KEY_CHALLENGE)).isEqualTo(newChallenge); - assertThat(extras.getByteArray(EXTRA_KEY_CHALLENGE_TOKEN)).isNotNull(); - assertThat(extras.getLong(EXTRA_KEY_GK_PW_HANDLE)).isEqualTo(INVALID_GK_PW_HANDLE); - assertThat(extras.getLong(EXTRA_KEY_CHALLENGE)).isNotEqualTo(INVALID_CHALLENGE); + assertThat(mViewModel.getToken()).isNotNull(); assertThat(mChallengeGenerator.mCallbackRunCount).isEqualTo(1); assertThat(hasCalledRemoveGkPwHandle.get()).isFalse(); @@ -534,11 +512,7 @@ public class AutoCredentialViewModelTest { assertThat(ret).isTrue(); assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull(); - final Bundle extras = mViewModel.createCredentialIntentExtra(); - assertThat(extras.getInt(EXTRA_KEY_SENSOR_ID)).isEqualTo(newSensorId); - assertThat(extras.getLong(EXTRA_KEY_CHALLENGE)).isEqualTo(newChallenge); - assertThat(extras.getByteArray(EXTRA_KEY_CHALLENGE_TOKEN)).isNotNull(); - assertThat(extras.getLong(EXTRA_KEY_GK_PW_HANDLE)).isEqualTo(INVALID_GK_PW_HANDLE); + assertThat(mViewModel.getToken()).isNotNull(); assertThat(mChallengeGenerator.mCallbackRunCount).isEqualTo(1); assertThat(hasCalledRemoveGkPwHandle.get()).isTrue(); } @@ -571,17 +545,13 @@ public class AutoCredentialViewModelTest { assertThat(ret).isTrue(); assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull(); - final Bundle extras = mViewModel.createCredentialIntentExtra(); - assertThat(extras.getInt(EXTRA_KEY_SENSOR_ID)).isEqualTo(newSensorId); - assertThat(extras.getLong(EXTRA_KEY_CHALLENGE)).isEqualTo(newChallenge); - assertThat(extras.getByteArray(EXTRA_KEY_CHALLENGE_TOKEN)).isNotNull(); - assertThat(extras.getLong(EXTRA_KEY_GK_PW_HANDLE)).isEqualTo(INVALID_GK_PW_HANDLE); + assertThat(mViewModel.getToken()).isNotNull(); assertThat(mChallengeGenerator.mCallbackRunCount).isEqualTo(1); assertThat(hasCalledRemoveGkPwHandle.get()).isTrue(); } public static class TestChallengeGenerator implements ChallengeGenerator { - public int mSensorId = INVALID_SENSOR_ID; + public int mSensorId = -1; public int mUserId = UserHandle.myUserId(); public long mChallenge = INVALID_CHALLENGE; public int mCallbackRunCount = 0; diff --git a/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollEnrollingViewModelTest.java b/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollEnrollingViewModelTest.java new file mode 100644 index 00000000000..4de1057436a --- /dev/null +++ b/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollEnrollingViewModelTest.java @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.biometrics2.ui.viewmodel; + +import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_REAR; +import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_OPTICAL; +import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_ULTRASONIC; + +import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.ErrorDialogData; +import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ENROLL_ENROLLING_ACTION_DISMISS_ICON_TOUCH_DIALOG; +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.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ERROR_DIALOG_ACTION_RESTART; +import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH; +import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_TIMEOUT; +import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollEnrollingViewModel.FingerprintErrorDialogAction; +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 testShowErrorDialogLiveData() { + assertThat(mViewModel.getErrorDialogLiveData().getValue()).isEqualTo(null); + + final ErrorDialogData data = new ErrorDialogData("errMsg", "errTitle", 0); + mViewModel.showErrorDialog(data); + assertThat(mViewModel.getErrorDialogLiveData().getValue()).isEqualTo(data); + } + + @Test + public void testIconTouchDialog() { + final LiveData actionLiveData = mViewModel.getActionLiveData(); + assertThat(actionLiveData.getValue()).isEqualTo(null); + + mViewModel.showIconTouchDialog(); + assertThat(actionLiveData.getValue()).isEqualTo( + FINGERPRINT_ENROLL_ENROLLING_ACTION_SHOW_ICON_TOUCH_DIALOG); + + mViewModel.onIconTouchDialogDismiss(); + assertThat(actionLiveData.getValue()).isEqualTo( + FINGERPRINT_ENROLL_ENROLLING_ACTION_DISMISS_ICON_TOUCH_DIALOG); + } + + @Test + public void testErrorDialogActionLiveData() { + assertThat(mViewModel.getErrorDialogActionLiveData().getValue()).isEqualTo(null); + + @FingerprintErrorDialogAction int action = FINGERPRINT_ERROR_DIALOG_ACTION_RESTART; + mViewModel.onErrorDialogAction(action); + assertThat(mViewModel.getErrorDialogActionLiveData().getValue()).isEqualTo(action); + + action = FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_TIMEOUT; + mViewModel.onErrorDialogAction(action); + assertThat(mViewModel.getErrorDialogActionLiveData().getValue()).isEqualTo(action); + + action = FINGERPRINT_ERROR_DIALOG_ACTION_SET_RESULT_FINISH; + mViewModel.onErrorDialogAction(action); + assertThat(mViewModel.getErrorDialogActionLiveData().getValue()).isEqualTo(action); + } + + @Test + public void tesBackPressedScenario() { + final LiveData 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 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 testCanAssumeUdfps_forUdfpsUltrasonicSensor() { + mViewModel = new FingerprintEnrollEnrollingViewModel( + mApplication, + TEST_USER_ID, + newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_ULTRASONIC, 5) + ); + assertThat(mViewModel.canAssumeUdfps()).isEqualTo(true); + } + + @Test + public void testCanAssumeUdfps_forRearSensor() { + mViewModel = new FingerprintEnrollEnrollingViewModel( + mApplication, + TEST_USER_ID, + newFingerprintRepository(mFingerprintManager, TYPE_REAR, 5) + ); + assertThat(mViewModel.canAssumeUdfps()).isEqualTo(false); + } + + @Test + public void testGetFirstFingerprintSensorPropertiesInternal() { + final ArrayList 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); + } +} diff --git a/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollFindSensorViewModelTest.java b/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollFindSensorViewModelTest.java index 43df08dcfaa..a72175d56e4 100644 --- a/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollFindSensorViewModelTest.java +++ b/tests/unit/src/com/android/settings/biometrics2/ui/viewmodel/FingerprintEnrollFindSensorViewModelTest.java @@ -18,7 +18,6 @@ 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; @@ -40,61 +39,45 @@ 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 testClickStartButton() { - final FingerprintEnrollFindSensorViewModel viewModel = - new FingerprintEnrollFindSensorViewModel(mApplication, false); - - viewModel.onStartButtonClick(); - assertThat(viewModel.getActionLiveData().getValue()).isEqualTo( - FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_START); - } - - @Test - public void testClickSkipButton() { - final FingerprintEnrollFindSensorViewModel viewModel = - new FingerprintEnrollFindSensorViewModel(mApplication, false); - - viewModel.onSkipButtonClick(); - assertThat(viewModel.getActionLiveData().getValue()).isEqualTo( + 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() { - final FingerprintEnrollFindSensorViewModel viewModel = - new FingerprintEnrollFindSensorViewModel(mApplication, true); - - viewModel.onSkipButtonClick(); - assertThat(viewModel.getActionLiveData().getValue()).isEqualTo( + mViewModel = new FingerprintEnrollFindSensorViewModel(mApplication, true); + mViewModel.onSkipButtonClick(); + assertThat(mViewModel.getActionLiveData().getValue()).isEqualTo( FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_DIALOG); } @Test public void testClickSkipDialogButton() { - final FingerprintEnrollFindSensorViewModel viewModel = - new FingerprintEnrollFindSensorViewModel(mApplication, true); - - viewModel.onSkipDialogButtonClick(); - assertThat(viewModel.getActionLiveData().getValue()).isEqualTo( + mViewModel.onSkipDialogButtonClick(); + assertThat(mViewModel.getActionLiveData().getValue()).isEqualTo( FINGERPRINT_ENROLL_FIND_SENSOR_ACTION_SKIP); } @Test public void testClearActionLiveData() { - final FingerprintEnrollFindSensorViewModel viewModel = - new FingerprintEnrollFindSensorViewModel(mApplication, false); + assertThat(mViewModel.getActionLiveData().getValue()).isNull(); - viewModel.onStartButtonClick(); - assertThat(viewModel.getActionLiveData().getValue()).isNotNull(); + mViewModel.onStartButtonClick(); + assertThat(mViewModel.getActionLiveData().getValue()).isNotNull(); - viewModel.clearActionLiveData(); - assertThat(viewModel.getActionLiveData().getValue()).isNull(); + mViewModel.clearActionLiveData(); + assertThat(mViewModel.getActionLiveData().getValue()).isNull(); } } 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 fbcbb16c62c..41d82267e7e 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 @@ -211,7 +211,7 @@ public class FingerprintEnrollIntroViewModelTest { } @Test - public void textCanAssumeUdfps_forUdfpsUltrasonicSensor() { + public void testCanAssumeUdfps_forUdfpsUltrasonicSensor() { final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel( newFingerprintRepository(mFingerprintManager, TYPE_UDFPS_ULTRASONIC, 5), newAllFalseRequest(mApplication)); @@ -220,7 +220,7 @@ public class FingerprintEnrollIntroViewModelTest { } @Test - public void textCanAssumeUdfps_forRearSensor() { + public void testCanAssumeUdfps_forRearSensor() { final FingerprintEnrollIntroViewModel viewModel = newFingerprintEnrollIntroViewModel( newFingerprintRepository(mFingerprintManager, TYPE_REAR, 5), newAllFalseRequest(mApplication)); 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 2c3fbf03b11..945ce8acbbc 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 @@ -69,27 +69,34 @@ public class FingerprintEnrollmentViewModelTest { public void testSetSavedInstanceState() { // setSavedInstanceState() as false final Bundle bundle = new Bundle(); + final Bundle outBundle = new Bundle(); + + // Set SAVED_STATE_IS_WAITING_ACTIVITY_RESULT to true bundle.putBoolean(SAVED_STATE_IS_WAITING_ACTIVITY_RESULT, false); mViewModel.setSavedInstanceState(bundle); assertThat(mViewModel.isWaitingActivityResult().get()).isFalse(); - // setSavedInstanceState() as false + // Set SAVED_STATE_IS_WAITING_ACTIVITY_RESULT to true bundle.clear(); bundle.putBoolean(SAVED_STATE_IS_WAITING_ACTIVITY_RESULT, true); mViewModel.setSavedInstanceState(bundle); assertThat(mViewModel.isWaitingActivityResult().get()).isTrue(); - // setSavedInstanceState() as false + // Set SAVED_STATE_IS_NEW_FINGERPRINT_ADDED to false bundle.clear(); bundle.putBoolean(SAVED_STATE_IS_NEW_FINGERPRINT_ADDED, false); mViewModel.setSavedInstanceState(bundle); - assertThat(mViewModel.isNewFingerprintAdded()).isFalse(); + outBundle.clear(); + mViewModel.onSaveInstanceState(outBundle); + assertThat(outBundle.getBoolean(SAVED_STATE_IS_NEW_FINGERPRINT_ADDED)).isFalse(); - // setSavedInstanceState() as false + // Set SAVED_STATE_IS_NEW_FINGERPRINT_ADDED to true bundle.clear(); bundle.putBoolean(SAVED_STATE_IS_NEW_FINGERPRINT_ADDED, true); mViewModel.setSavedInstanceState(bundle); - assertThat(mViewModel.isNewFingerprintAdded()).isTrue(); + outBundle.clear(); + mViewModel.onSaveInstanceState(outBundle); + assertThat(outBundle.getBoolean(SAVED_STATE_IS_NEW_FINGERPRINT_ADDED)).isTrue(); } @Test