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
This commit is contained in:
Milton Wu
2023-03-03 17:12:00 +08:00
parent 6113725b61
commit 7b817dd0a0
19 changed files with 377 additions and 379 deletions

View File

@@ -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.
*
* <strong>Note:</strong> 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();
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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);

View File

@@ -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 + "}"
+ " }";
}
}

View File

@@ -418,7 +418,7 @@ public class FingerprintEnrollEnrollingRfpsFragment extends Fragment {
private void showIconTouchDialog() {
mIconTouchCount = 0;
mEnrollingViewModel.onIconTouchDialogShow();
mEnrollingViewModel.showIconTouchDialog();
}
private final Runnable mShowDialogRunnable = () -> showIconTouchDialog();

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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
*/

View File

@@ -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<Integer> mActionLiveData = new MutableLiveData<>();
private final MutableLiveData<Integer> mIconTouchDialogLiveData = new MutableLiveData<>();
private final MutableLiveData<ErrorDialogData> mErrorDialogLiveData = new MutableLiveData<>();
private final MutableLiveData<Integer> 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);
}

View File

@@ -179,10 +179,6 @@ public class FingerprintEnrollmentViewModel extends AndroidViewModel {
return mFingerprintRepository.canAssumeSfps();
}
public boolean isNewFingerprintAdded() {
return mIsNewFingerprintAdded;
}
/**
* Sets mIsNewFingerprintAdded to true
*/

View File

@@ -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<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
final FingerprintSensorPropertiesInternal prop = new FingerprintSensorPropertiesInternal(
0 /* sensorId */,
SensorProperties.STRENGTH_STRONG,
5,
new ArrayList<>() /* componentInfo */,
TYPE_UDFPS_OPTICAL,
true /* resetLockoutRequiresHardwareAuthToken */);
props.add(prop);
doAnswer(invocation -> {
final IFingerprintAuthenticatorsRegisteredCallback callback =
invocation.getArgument(0);
callback.onAllAuthenticatorsRegistered(props);
return null;
}).when(mFingerprintManager).addAuthenticatorsRegisteredCallback(any());
final FingerprintRepository repository = new FingerprintRepository(mFingerprintManager);
assertThat(repository.getFirstFingerprintSensorPropertiesInternal()).isEqualTo(prop);
}
@Test
public void testGetEnrollStageCount() {
final FingerprintRepository repository = newFingerprintRepository(mFingerprintManager,
TYPE_UNKNOWN, 999);
final int expectedValue = 24;
doReturn(expectedValue).when(mFingerprintManager).getEnrollStageCount();
assertThat(repository.getEnrollStageCount()).isEqualTo(expectedValue);
}
@Test
public void testGetEnrollStageThreshold() {
final FingerprintRepository repository = newFingerprintRepository(mFingerprintManager,
TYPE_UNKNOWN, 999);
final float expectedValue0 = 0.42f;
final float expectedValue1 = 0.24f;
final float expectedValue2 = 0.33f;
final float expectedValue3 = 0.90f;
doReturn(expectedValue0).when(mFingerprintManager).getEnrollStageThreshold(0);
doReturn(expectedValue1).when(mFingerprintManager).getEnrollStageThreshold(1);
doReturn(expectedValue2).when(mFingerprintManager).getEnrollStageThreshold(2);
doReturn(expectedValue3).when(mFingerprintManager).getEnrollStageThreshold(3);
assertThat(repository.getEnrollStageThreshold(2)).isEqualTo(expectedValue2);
assertThat(repository.getEnrollStageThreshold(1)).isEqualTo(expectedValue1);
assertThat(repository.getEnrollStageThreshold(3)).isEqualTo(expectedValue3);
assertThat(repository.getEnrollStageThreshold(0)).isEqualTo(expectedValue0);
}
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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<Integer> 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<Integer> actionLiveData = mViewModel.getActionLiveData();
assertThat(actionLiveData.getValue()).isEqualTo(null);
assertThat(mViewModel.getOnBackPressed()).isEqualTo(false);
mViewModel.setOnBackPressed();
assertThat(mViewModel.getOnBackPressed()).isEqualTo(true);
mViewModel.onCancelledDueToOnBackPressed();
assertThat(mViewModel.getOnBackPressed()).isEqualTo(false);
assertThat(actionLiveData.getValue()).isEqualTo(
FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_BACK_PRESSED);
}
@Test
public void testSkipPressedScenario() {
final LiveData<Integer> actionLiveData = mViewModel.getActionLiveData();
assertThat(actionLiveData.getValue()).isEqualTo(null);
assertThat(mViewModel.getOnSkipPressed()).isEqualTo(false);
mViewModel.setOnSkipPressed();
assertThat(mViewModel.getOnSkipPressed()).isEqualTo(true);
mViewModel.onCancelledDueToOnSkipPressed();
assertThat(mViewModel.getOnSkipPressed()).isEqualTo(false);
assertThat(actionLiveData.getValue()).isEqualTo(
FINGERPRINT_ENROLL_ENROLLING_CANCELED_BECAUSE_USER_SKIP);
}
@Test
public void 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<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
final FingerprintSensorPropertiesInternal prop = new FingerprintSensorPropertiesInternal(
0 /* sensorId */,
SensorProperties.STRENGTH_STRONG,
5,
new ArrayList<>() /* componentInfo */,
TYPE_UDFPS_OPTICAL,
true /* resetLockoutRequiresHardwareAuthToken */);
props.add(prop);
doAnswer(invocation -> {
final IFingerprintAuthenticatorsRegisteredCallback callback =
invocation.getArgument(0);
callback.onAllAuthenticatorsRegistered(props);
return null;
}).when(mFingerprintManager).addAuthenticatorsRegisteredCallback(any());
mViewModel = new FingerprintEnrollEnrollingViewModel(
mApplication,
TEST_USER_ID,
new FingerprintRepository(mFingerprintManager)
);
assertThat(mViewModel.getFirstFingerprintSensorPropertiesInternal()).isEqualTo(prop);
}
@Test
public void testGetEnrollStageCount() {
final int expectedValue = 24;
doReturn(expectedValue).when(mFingerprintManager).getEnrollStageCount();
assertThat(mViewModel.getEnrollStageCount()).isEqualTo(expectedValue);
}
@Test
public void testGetEnrollStageThreshold() {
final float expectedValue0 = 0.42f;
final float expectedValue1 = 0.24f;
final float expectedValue2 = 0.33f;
final float expectedValue3 = 0.90f;
doReturn(expectedValue0).when(mFingerprintManager).getEnrollStageThreshold(0);
doReturn(expectedValue1).when(mFingerprintManager).getEnrollStageThreshold(1);
doReturn(expectedValue2).when(mFingerprintManager).getEnrollStageThreshold(2);
doReturn(expectedValue3).when(mFingerprintManager).getEnrollStageThreshold(3);
assertThat(mViewModel.getEnrollStageThreshold(2)).isEqualTo(expectedValue2);
assertThat(mViewModel.getEnrollStageThreshold(1)).isEqualTo(expectedValue1);
assertThat(mViewModel.getEnrollStageThreshold(3)).isEqualTo(expectedValue3);
assertThat(mViewModel.getEnrollStageThreshold(0)).isEqualTo(expectedValue0);
}
}

View File

@@ -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();
}
}

View File

@@ -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));

View File

@@ -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