Merge changes from topic "qpr.biometric.2panels" into tm-qpr-dev

* changes:
  Bypass cancel error code during "Add another"
  Fix udfps fingerprint setting flow
  Use setting as base activity for fingerprint
  Use Mockito 4.6.1 FingerprintEnrollFindSensorTest
This commit is contained in:
TreeHugger Robot
2022-08-30 00:22:53 +00:00
committed by Android (Google) Code Review
10 changed files with 615 additions and 74 deletions

View File

@@ -24,8 +24,6 @@ import android.view.View;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.password.ChooseLockSettingsHelper; import com.android.settings.password.ChooseLockSettingsHelper;
import com.google.android.setupcompat.util.WizardManagerHelper;
/** /**
* Abstract base activity which handles the actual enrolling for biometrics. * Abstract base activity which handles the actual enrolling for biometrics.
*/ */
@@ -62,30 +60,18 @@ public abstract class BiometricsEnrollEnrolling extends BiometricEnrollBase
@Override @Override
protected void onStop() { protected void onStop() {
super.onStop();
if (mSidecar != null) { if (mSidecar != null) {
mSidecar.setListener(null); mSidecar.setListener(null);
} }
if (!isChangingConfigurations()) { if (!isChangingConfigurations()) {
if (mSidecar != null) { if (mSidecar != null) {
mSidecar.cancelEnrollment(); mSidecar.cancelEnrollment();
getSupportFragmentManager() getSupportFragmentManager()
.beginTransaction().remove(mSidecar).commitAllowingStateLoss(); .beginTransaction().remove(mSidecar).commitAllowingStateLoss();
} }
if (!WizardManagerHelper.isAnySetupWizard(getIntent())
&& !BiometricUtils.isAnyMultiBiometricFlow(this)) {
setResult(RESULT_TIMEOUT);
}
finish();
}
} }
@Override super.onStop();
protected boolean shouldFinishWhenBackgrounded() {
// Prevent super.onStop() from finishing, since we handle this in our onStop().
return false;
} }
@Override @Override

View File

@@ -31,11 +31,13 @@ import com.android.settings.R;
import com.android.settings.biometrics.BiometricEnrollBase; import com.android.settings.biometrics.BiometricEnrollBase;
import com.android.settings.biometrics.BiometricEnrollSidecar; import com.android.settings.biometrics.BiometricEnrollSidecar;
import com.android.settings.biometrics.BiometricErrorDialog; import com.android.settings.biometrics.BiometricErrorDialog;
import com.android.settings.biometrics.BiometricUtils;
import com.android.settings.biometrics.BiometricsEnrollEnrolling; import com.android.settings.biometrics.BiometricsEnrollEnrolling;
import com.android.settings.slices.CustomSliceRegistry; import com.android.settings.slices.CustomSliceRegistry;
import com.google.android.setupcompat.template.FooterBarMixin; import com.google.android.setupcompat.template.FooterBarMixin;
import com.google.android.setupcompat.template.FooterButton; import com.google.android.setupcompat.template.FooterButton;
import com.google.android.setupcompat.util.WizardManagerHelper;
import java.util.ArrayList; import java.util.ArrayList;
@@ -112,6 +114,25 @@ public class FaceEnrollEnrolling extends BiometricsEnrollEnrolling {
startEnrollment(); startEnrollment();
} }
@Override
protected void onStop() {
if (!isChangingConfigurations()) {
if (!WizardManagerHelper.isAnySetupWizard(getIntent())
&& !BiometricUtils.isAnyMultiBiometricFlow(this)) {
setResult(RESULT_TIMEOUT);
}
finish();
}
super.onStop();
}
@Override
protected boolean shouldFinishWhenBackgrounded() {
// Prevent super.onStop() from finishing, since we handle this in our onStop().
return false;
}
@Override @Override
public void startEnrollment() { public void startEnrollment() {
super.startEnrollment(); super.startEnrollment();

View File

@@ -339,8 +339,23 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
@Override @Override
protected void onStop() { protected void onStop() {
super.onStop(); if (!isChangingConfigurations()) {
if (!WizardManagerHelper.isAnySetupWizard(getIntent())
&& !BiometricUtils.isAnyMultiBiometricFlow(this)
&& !mFromSettingsSummary) {
setResult(RESULT_TIMEOUT);
}
finish();
}
stopIconAnimation(); stopIconAnimation();
super.onStop();
}
@Override
protected boolean shouldFinishWhenBackgrounded() {
// Prevent super.onStop() from finishing, since we handle this in our onStop().
return false;
} }
@Override @Override

View File

@@ -49,8 +49,8 @@ import java.util.List;
public class FingerprintEnrollFindSensor extends BiometricEnrollBase implements public class FingerprintEnrollFindSensor extends BiometricEnrollBase implements
BiometricEnrollSidecar.Listener { BiometricEnrollSidecar.Listener {
private static final String TAG = "FingerprintEnrollFindSensor"; private static final String TAG = "FingerprintEnrollFindSensor";
private static final String SAVED_STATE_IS_NEXT_CLICKED = "is_next_clicked";
@Nullable @Nullable
private FingerprintFindSensorAnimation mAnimation; private FingerprintFindSensorAnimation mAnimation;
@@ -67,7 +67,7 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase implements
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
final FingerprintManager fingerprintManager = getSystemService(FingerprintManager.class); final FingerprintManager fingerprintManager = Utils.getFingerprintManagerOrNull(this);
final List<FingerprintSensorPropertiesInternal> props = final List<FingerprintSensorPropertiesInternal> props =
fingerprintManager.getSensorPropertiesInternal(); fingerprintManager.getSensorPropertiesInternal();
mCanAssumeUdfps = props != null && props.size() == 1 && props.get(0).isAnyUdfpsType(); mCanAssumeUdfps = props != null && props.size() == 1 && props.get(0).isAnyUdfpsType();
@@ -134,12 +134,14 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase implements
setHeaderText(R.string.security_settings_fingerprint_enroll_find_sensor_title); setHeaderText(R.string.security_settings_fingerprint_enroll_find_sensor_title);
setDescriptionText(R.string.security_settings_fingerprint_enroll_find_sensor_message); setDescriptionText(R.string.security_settings_fingerprint_enroll_find_sensor_message);
} }
if (savedInstanceState != null) {
mNextClicked = savedInstanceState.getBoolean(SAVED_STATE_IS_NEXT_CLICKED, mNextClicked);
}
// This is an entry point for SetNewPasswordController, e.g. // This is an entry point for SetNewPasswordController, e.g.
// adb shell am start -a android.app.action.SET_NEW_PASSWORD // adb shell am start -a android.app.action.SET_NEW_PASSWORD
if (mToken == null && BiometricUtils.containsGatekeeperPasswordHandle(getIntent())) { if (mToken == null && BiometricUtils.containsGatekeeperPasswordHandle(getIntent())) {
final FingerprintManager fpm = getSystemService(FingerprintManager.class); fingerprintManager.generateChallenge(mUserId, (sensorId, userId, challenge) -> {
fpm.generateChallenge(mUserId, (sensorId, userId, challenge) -> {
mChallenge = challenge; mChallenge = challenge;
mSensorId = sensorId; mSensorId = sensorId;
mToken = BiometricUtils.requestGatekeeperHat(this, getIntent(), mUserId, challenge); mToken = BiometricUtils.requestGatekeeperHat(this, getIntent(), mUserId, challenge);
@@ -149,11 +151,19 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase implements
// it passed in. // it passed in.
getIntent().putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken); getIntent().putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken);
// Do not start looking for fingerprint if this activity is re-created because it is
// waiting for activity result from enrolling activity.
if (!mNextClicked) {
startLookingForFingerprint(); startLookingForFingerprint();
}
}); });
} else if (mToken != null) { } else if (mToken != null) {
// Do not start looking for fingerprint if this activity is re-created because it is
// waiting for activity result from enrolling activity.
if (!mNextClicked) {
// HAT passed in from somewhere else, such as FingerprintEnrollIntroduction // HAT passed in from somewhere else, such as FingerprintEnrollIntroduction
startLookingForFingerprint(); startLookingForFingerprint();
}
} else { } else {
// There's something wrong with the enrollment flow, this should never happen. // There's something wrong with the enrollment flow, this should never happen.
throw new IllegalStateException("HAT and GkPwHandle both missing..."); throw new IllegalStateException("HAT and GkPwHandle both missing...");
@@ -176,6 +186,12 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase implements
} }
} }
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(SAVED_STATE_IS_NEXT_CLICKED, mNextClicked);
}
@Override @Override
public void onBackPressed() { public void onBackPressed() {
stopLookingForFingerprint(); stopLookingForFingerprint();
@@ -240,7 +256,6 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase implements
@Override @Override
public void onEnrollmentError(int errMsgId, CharSequence errString) { public void onEnrollmentError(int errMsgId, CharSequence errString) {
if (mNextClicked && errMsgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED) { if (mNextClicked && errMsgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
mNextClicked = false;
proceedToEnrolling(false /* cancelEnrollment */); proceedToEnrolling(false /* cancelEnrollment */);
} else { } else {
FingerprintErrorDialog.showErrorDialog(this, errMsgId); FingerprintErrorDialog.showErrorDialog(this, errMsgId);
@@ -270,6 +285,7 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase implements
} }
private void onStartButtonClick(View view) { private void onStartButtonClick(View view) {
mNextClicked = true;
startActivityForResult(getFingerprintEnrollingIntent(), ENROLL_REQUEST); startActivityForResult(getFingerprintEnrollingIntent(), ENROLL_REQUEST);
} }
@@ -289,6 +305,7 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase implements
return; return;
} }
} }
mSidecar.setListener(null);
getSupportFragmentManager().beginTransaction().remove(mSidecar). getSupportFragmentManager().beginTransaction().remove(mSidecar).
commitAllowingStateLoss(); commitAllowingStateLoss();
mSidecar = null; mSidecar = null;
@@ -341,6 +358,7 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase implements
finish(); finish();
} else { } else {
// We came back from enrolling but it wasn't completed, start again. // We came back from enrolling but it wasn't completed, start again.
mNextClicked = false;
startLookingForFingerprint(); startLookingForFingerprint();
} }
break; break;

View File

@@ -32,7 +32,6 @@ import com.android.settings.R;
import com.android.settings.Utils; import com.android.settings.Utils;
import com.android.settings.biometrics.BiometricEnrollBase; import com.android.settings.biometrics.BiometricEnrollBase;
import com.android.settings.biometrics.BiometricUtils; import com.android.settings.biometrics.BiometricUtils;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.google.android.setupcompat.template.FooterBarMixin; import com.google.android.setupcompat.template.FooterBarMixin;
import com.google.android.setupcompat.template.FooterButton; import com.google.android.setupcompat.template.FooterButton;
@@ -51,6 +50,8 @@ public class FingerprintEnrollFinish extends BiometricEnrollBase {
static final String FINGERPRINT_SUGGESTION_ACTIVITY = static final String FINGERPRINT_SUGGESTION_ACTIVITY =
"com.android.settings.SetupFingerprintSuggestionActivity"; "com.android.settings.SetupFingerprintSuggestionActivity";
private boolean mIsAddAnotherOrFinish;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@@ -108,15 +109,26 @@ public class FingerprintEnrollFinish extends BiometricEnrollBase {
} }
} }
@Override
protected void onStart() {
super.onStart();
// Reset it to false every time activity back to fg because this flag is stateless between
// different life cycle.
mIsAddAnotherOrFinish = false;
}
@Override @Override
protected void onNextButtonClick(View view) { protected void onNextButtonClick(View view) {
updateFingerprintSuggestionEnableState(); updateFingerprintSuggestionEnableState();
finishAndToNext();
}
private void finishAndToNext() {
mIsAddAnotherOrFinish = true;
setResult(RESULT_FINISHED); setResult(RESULT_FINISHED);
if (WizardManagerHelper.isAnySetupWizard(getIntent())) { if (WizardManagerHelper.isAnySetupWizard(getIntent())) {
postEnroll(); postEnroll();
} else if (mFromSettingsSummary) {
// Only launch fingerprint settings if enrollment was triggered through settings summary
launchFingerprintSettings();
} }
finish(); finish();
} }
@@ -148,27 +160,22 @@ public class FingerprintEnrollFinish extends BiometricEnrollBase {
} }
} }
private void launchFingerprintSettings() { private void onAddAnotherButtonClick(View view) {
final Intent intent = new Intent(ACTION_FINGERPRINT_SETTINGS); mIsAddAnotherOrFinish = true;
intent.setPackage(Utils.SETTINGS_PACKAGE_NAME); startActivityForResult(getFingerprintEnrollingIntent(), BiometricUtils.REQUEST_ADD_ANOTHER);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
intent.putExtra(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, mChallenge);
startActivity(intent);
overridePendingTransition(R.anim.sud_slide_back_in, R.anim.sud_slide_back_out);
} }
private void onAddAnotherButtonClick(View view) { @Override
startActivityForResult(getFingerprintEnrollingIntent(), BiometricUtils.REQUEST_ADD_ANOTHER); protected boolean shouldFinishWhenBackgrounded() {
return !mIsAddAnotherOrFinish && super.shouldFinishWhenBackgrounded();
} }
@Override @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { protected void onActivityResult(int requestCode, int resultCode, Intent data) {
updateFingerprintSuggestionEnableState(); updateFingerprintSuggestionEnableState();
if (requestCode == BiometricUtils.REQUEST_ADD_ANOTHER && resultCode != RESULT_CANCELED) { if (requestCode == BiometricUtils.REQUEST_ADD_ANOTHER && resultCode != RESULT_CANCELED) {
setResult(resultCode, data); // If user cancel during "Add another", just use similar flow on "Next" button
finish(); finishAndToNext();
} else { } else {
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);
} }

View File

@@ -22,6 +22,7 @@ import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROF
import static android.app.admin.DevicePolicyResources.UNDEFINED; import static android.app.admin.DevicePolicyResources.UNDEFINED;
import static com.android.settings.Utils.SETTINGS_PACKAGE_NAME; import static com.android.settings.Utils.SETTINGS_PACKAGE_NAME;
import static com.android.settings.biometrics.BiometricEnrollBase.EXTRA_FROM_SETTINGS_SUMMARY;
import android.app.Activity; import android.app.Activity;
import android.app.Dialog; import android.app.Dialog;
@@ -62,6 +63,7 @@ import com.android.settings.SubSettings;
import com.android.settings.Utils; import com.android.settings.Utils;
import com.android.settings.biometrics.BiometricEnrollBase; import com.android.settings.biometrics.BiometricEnrollBase;
import com.android.settings.biometrics.BiometricUtils; import com.android.settings.biometrics.BiometricUtils;
import com.android.settings.core.SettingsBaseActivity;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.password.ChooseLockGeneric; import com.android.settings.password.ChooseLockGeneric;
import com.android.settings.password.ChooseLockSettingsHelper; import com.android.settings.password.ChooseLockSettingsHelper;
@@ -69,6 +71,7 @@ import com.android.settingslib.HelpUtils;
import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.RestrictedLockUtilsInternal; import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.transition.SettingsTransitionHelper;
import com.android.settingslib.widget.FooterPreference; import com.android.settingslib.widget.FooterPreference;
import com.android.settingslib.widget.TwoTargetPreference; import com.android.settingslib.widget.TwoTargetPreference;
@@ -129,6 +132,8 @@ public class FingerprintSettings extends SubSettings {
private static final String KEY_FINGERPRINT_ENABLE_KEYGUARD_TOGGLE = private static final String KEY_FINGERPRINT_ENABLE_KEYGUARD_TOGGLE =
"fingerprint_enable_keyguard_toggle"; "fingerprint_enable_keyguard_toggle";
private static final String KEY_LAUNCHED_CONFIRM = "launched_confirm"; private static final String KEY_LAUNCHED_CONFIRM = "launched_confirm";
private static final String KEY_HAS_FIRST_ENROLLED = "has_first_enrolled";
private static final String KEY_IS_ENROLLING = "is_enrolled";
private static final int MSG_REFRESH_FINGERPRINT_TEMPLATES = 1000; private static final int MSG_REFRESH_FINGERPRINT_TEMPLATES = 1000;
private static final int MSG_FINGER_AUTH_SUCCESS = 1001; private static final int MSG_FINGER_AUTH_SUCCESS = 1001;
@@ -140,6 +145,7 @@ public class FingerprintSettings extends SubSettings {
private static final int CHOOSE_LOCK_GENERIC_REQUEST = 102; private static final int CHOOSE_LOCK_GENERIC_REQUEST = 102;
private static final int ADD_FINGERPRINT_REQUEST = 10; private static final int ADD_FINGERPRINT_REQUEST = 10;
private static final int AUTO_ADD_FIRST_FINGERPRINT_REQUEST = 11;
protected static final boolean DEBUG = false; protected static final boolean DEBUG = false;
@@ -149,10 +155,11 @@ public class FingerprintSettings extends SubSettings {
private boolean mInFingerprintLockout; private boolean mInFingerprintLockout;
private byte[] mToken; private byte[] mToken;
private boolean mLaunchedConfirm; private boolean mLaunchedConfirm;
private boolean mHasFirstEnrolled = true;
private Drawable mHighlightDrawable; private Drawable mHighlightDrawable;
private int mUserId; private int mUserId;
private final List<FooterColumn> mFooterColumns = new ArrayList<>(); private final List<FooterColumn> mFooterColumns = new ArrayList<>();
private boolean mEnrollClicked; private boolean mIsEnrolling;
private long mChallenge; private long mChallenge;
@@ -341,6 +348,9 @@ public class FingerprintSettings extends SubSettings {
} }
mFingerprintsRenaming = new HashMap<Integer, String>(); mFingerprintsRenaming = new HashMap<Integer, String>();
mUserId = getActivity().getIntent().getIntExtra(
Intent.EXTRA_USER_ID, UserHandle.myUserId());
mHasFirstEnrolled = mFingerprintManager.hasEnrolledFingerprints(mUserId);
if (savedInstanceState != null) { if (savedInstanceState != null) {
mFingerprintsRenaming = (HashMap<Integer, String>) mFingerprintsRenaming = (HashMap<Integer, String>)
@@ -349,14 +359,21 @@ public class FingerprintSettings extends SubSettings {
ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN); ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
mLaunchedConfirm = savedInstanceState.getBoolean( mLaunchedConfirm = savedInstanceState.getBoolean(
KEY_LAUNCHED_CONFIRM, false); KEY_LAUNCHED_CONFIRM, false);
mIsEnrolling = savedInstanceState.getBoolean(KEY_IS_ENROLLING, mIsEnrolling);
mHasFirstEnrolled = savedInstanceState.getBoolean(KEY_HAS_FIRST_ENROLLED,
mHasFirstEnrolled);
} }
mUserId = getActivity().getIntent().getIntExtra(
Intent.EXTRA_USER_ID, UserHandle.myUserId());
// (mLaunchedConfirm or mIsEnrolling) means that we are waiting an activity result.
if (!mLaunchedConfirm && !mIsEnrolling) {
// Need to authenticate a session token if none // Need to authenticate a session token if none
if (mToken == null && mLaunchedConfirm == false) { if (mToken == null) {
mLaunchedConfirm = true; mLaunchedConfirm = true;
launchChooseOrConfirmLock(); launchChooseOrConfirmLock();
} else if (!mHasFirstEnrolled) {
mIsEnrolling = true;
addFirstFingerprint();
}
} }
updateFooterColumns(activity); updateFooterColumns(activity);
} }
@@ -546,7 +563,7 @@ public class FingerprintSettings extends SubSettings {
@Override @Override
public void onStop() { public void onStop() {
super.onStop(); super.onStop();
if (!getActivity().isChangingConfigurations() && !mLaunchedConfirm && !mEnrollClicked) { if (!getActivity().isChangingConfigurations() && !mLaunchedConfirm && !mIsEnrolling) {
getActivity().finish(); getActivity().finish();
} }
} }
@@ -557,13 +574,15 @@ public class FingerprintSettings extends SubSettings {
mToken); mToken);
outState.putBoolean(KEY_LAUNCHED_CONFIRM, mLaunchedConfirm); outState.putBoolean(KEY_LAUNCHED_CONFIRM, mLaunchedConfirm);
outState.putSerializable("mFingerprintsRenaming", mFingerprintsRenaming); outState.putSerializable("mFingerprintsRenaming", mFingerprintsRenaming);
outState.putBoolean(KEY_IS_ENROLLING, mIsEnrolling);
outState.putBoolean(KEY_HAS_FIRST_ENROLLED, mHasFirstEnrolled);
} }
@Override @Override
public boolean onPreferenceTreeClick(Preference pref) { public boolean onPreferenceTreeClick(Preference pref) {
final String key = pref.getKey(); final String key = pref.getKey();
if (KEY_FINGERPRINT_ADD.equals(key)) { if (KEY_FINGERPRINT_ADD.equals(key)) {
mEnrollClicked = true; mIsEnrolling = true;
Intent intent = new Intent(); Intent intent = new Intent();
intent.setClassName(SETTINGS_PACKAGE_NAME, intent.setClassName(SETTINGS_PACKAGE_NAME,
FingerprintEnrollEnrolling.class.getName()); FingerprintEnrollEnrolling.class.getName());
@@ -659,6 +678,10 @@ public class FingerprintSettings extends SubSettings {
BiometricUtils.removeGatekeeperPasswordHandle(getActivity(), BiometricUtils.removeGatekeeperPasswordHandle(getActivity(),
data); data);
updateAddPreference(); updateAddPreference();
if (!mHasFirstEnrolled && !mIsEnrolling) {
mIsEnrolling = true;
addFirstFingerprint();
}
}); });
} else { } else {
Log.d(TAG, "Data null or GK PW missing"); Log.d(TAG, "Data null or GK PW missing");
@@ -669,12 +692,19 @@ public class FingerprintSettings extends SubSettings {
finish(); finish();
} }
} else if (requestCode == ADD_FINGERPRINT_REQUEST) { } else if (requestCode == ADD_FINGERPRINT_REQUEST) {
mEnrollClicked = false; mIsEnrolling = false;
if (resultCode == RESULT_TIMEOUT) { if (resultCode == RESULT_TIMEOUT) {
Activity activity = getActivity(); Activity activity = getActivity();
activity.setResult(resultCode); activity.setResult(resultCode);
activity.finish(); activity.finish();
} }
} else if (requestCode == AUTO_ADD_FIRST_FINGERPRINT_REQUEST) {
mIsEnrolling = false;
mHasFirstEnrolled = true;
if (resultCode != RESULT_FINISHED) {
Log.d(TAG, "Add first fingerprint fail, result:" + resultCode);
finish();
}
} }
} }
@@ -746,6 +776,20 @@ public class FingerprintSettings extends SubSettings {
} }
} }
private void addFirstFingerprint() {
Intent intent = new Intent();
intent.setClassName(SETTINGS_PACKAGE_NAME,
FingerprintEnrollIntroductionInternal.class.getName());
intent.putExtra(EXTRA_FROM_SETTINGS_SUMMARY, true);
intent.putExtra(SettingsBaseActivity.EXTRA_PAGE_TRANSITION_TYPE,
SettingsTransitionHelper.TransitionType.TRANSITION_SLIDE);
intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken);
startActivityForResult(intent, AUTO_ADD_FIRST_FINGERPRINT_REQUEST);
}
@VisibleForTesting @VisibleForTesting
void deleteFingerPrint(Fingerprint fingerPrint) { void deleteFingerPrint(Fingerprint fingerPrint) {
mRemovalSidecar.startRemove(fingerPrint, mUserId); mRemovalSidecar.startRemove(fingerPrint, mUserId);

View File

@@ -78,8 +78,7 @@ public class FingerprintStatusUtils {
* Returns the class name of the Settings page corresponding to fingerprint settings. * Returns the class name of the Settings page corresponding to fingerprint settings.
*/ */
public String getSettingsClassName() { public String getSettingsClassName() {
return hasEnrolled() ? FingerprintSettings.class.getName() return FingerprintSettings.class.getName();
: FingerprintEnrollIntroductionInternal.class.getName();
} }
/** /**

View File

@@ -16,21 +16,39 @@
package com.android.settings.biometrics.fingerprint; package com.android.settings.biometrics.fingerprint;
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_REAR;
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_OPTICAL;
import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_FINISHED;
import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_SKIP;
import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_TIMEOUT;
import static com.android.settings.biometrics.fingerprint.FingerprintEnrollEnrolling.TAG_SIDECAR;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage; import static com.google.common.truth.Truth.assertWithMessage;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.any;
import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.anyInt;
import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.robolectric.RuntimeEnvironment.application; import static org.robolectric.RuntimeEnvironment.application;
import android.annotation.NonNull;
import android.app.Activity; import android.app.Activity;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Intent; import android.content.Intent;
import android.hardware.biometrics.ComponentInfoInternal;
import android.hardware.biometrics.SensorProperties;
import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintManager.EnrollmentCallback; import android.hardware.fingerprint.FingerprintManager.EnrollmentCallback;
import android.hardware.fingerprint.FingerprintSensorProperties;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.os.Bundle;
import android.os.CancellationSignal; import android.os.CancellationSignal;
import android.view.View;
import androidx.fragment.app.Fragment;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.biometrics.BiometricEnrollBase; import com.android.settings.biometrics.BiometricEnrollBase;
@@ -40,6 +58,8 @@ import com.android.settings.testutils.shadow.ShadowUtils;
import com.google.android.setupcompat.PartnerCustomizationLayout; import com.google.android.setupcompat.PartnerCustomizationLayout;
import com.google.android.setupcompat.template.FooterBarMixin; import com.google.android.setupcompat.template.FooterBarMixin;
import com.google.android.setupcompat.template.FooterButton;
import com.google.android.setupdesign.GlifLayout;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
@@ -51,31 +71,69 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric; import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.robolectric.Shadows; import org.robolectric.Shadows;
import org.robolectric.android.controller.ActivityController;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowActivity; import org.robolectric.shadows.ShadowActivity;
import org.robolectric.shadows.ShadowActivity.IntentForResult; import org.robolectric.shadows.ShadowActivity.IntentForResult;
import java.util.ArrayList;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowUtils.class) @Config(shadows = ShadowUtils.class)
public class FingerprintEnrollFindSensorTest { public class FingerprintEnrollFindSensorTest {
private static final int DEFAULT_ACTIVITY_RESULT = Activity.RESULT_CANCELED;
@Mock @Mock
private FingerprintManager mFingerprintManager; private FingerprintManager mFingerprintManager;
private ActivityController<FingerprintEnrollFindSensor> mActivityController;
private FingerprintEnrollFindSensor mActivity; private FingerprintEnrollFindSensor mActivity;
private void buildActivity() {
mActivityController = Robolectric.buildActivity(
FingerprintEnrollFindSensor.class,
new Intent()
// Set the challenge token so the confirm screen will not be shown
.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, new byte[0])
);
mActivity = mActivityController.get();
}
@Before @Before
public void setUp() { public void setUp() {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
ShadowUtils.setFingerprintManager(mFingerprintManager); ShadowUtils.setFingerprintManager(mFingerprintManager);
FakeFeatureFactory.setupForTest(); FakeFeatureFactory.setupForTest();
buildActivity();
}
mActivity = Robolectric.buildActivity( private void setupActivity_onRearDevice() {
FingerprintEnrollFindSensor.class, final ArrayList<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
new Intent() props.add(newFingerprintSensorPropertiesInternal(TYPE_REAR));
// Set the challenge token so the confirm screen will not be shown doReturn(props).when(mFingerprintManager).getSensorPropertiesInternal();
.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, new byte[0]))
.setup().get(); mActivityController.setup();
}
private void setupActivity_onUdfpsDevice() {
final ArrayList<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
props.add(newFingerprintSensorPropertiesInternal(TYPE_UDFPS_OPTICAL));
doReturn(props).when(mFingerprintManager).getSensorPropertiesInternal();
mActivityController.setup();
}
private FingerprintSensorPropertiesInternal newFingerprintSensorPropertiesInternal(
@FingerprintSensorProperties.SensorType int sensorType) {
return new FingerprintSensorPropertiesInternal(
0 /* sensorId */,
SensorProperties.STRENGTH_STRONG,
1 /* maxEnrollmentsPerUser */,
new ArrayList<ComponentInfoInternal>(),
sensorType,
true /* resetLockoutRequiresHardwareAuthToken */);
} }
@After @After
@@ -83,13 +141,7 @@ public class FingerprintEnrollFindSensorTest {
ShadowUtils.reset(); ShadowUtils.reset();
} }
@Test private void verifyStartEnrollingActivity() {
public void enrollFingerprint_shouldProceed() {
EnrollmentCallback enrollmentCallback = verifyAndCaptureEnrollmentCallback();
enrollmentCallback.onEnrollmentProgress(123);
enrollmentCallback.onEnrollmentError(FingerprintManager.FINGERPRINT_ERROR_CANCELED, "test");
ShadowActivity shadowActivity = Shadows.shadowOf(mActivity); ShadowActivity shadowActivity = Shadows.shadowOf(mActivity);
IntentForResult startedActivity = IntentForResult startedActivity =
shadowActivity.getNextStartedActivityForResult(); shadowActivity.getNextStartedActivityForResult();
@@ -100,6 +152,7 @@ public class FingerprintEnrollFindSensorTest {
@Test @Test
public void enrollFingerprintTwice_shouldStartOneEnrolling() { public void enrollFingerprintTwice_shouldStartOneEnrolling() {
setupActivity_onRearDevice();
EnrollmentCallback enrollmentCallback = verifyAndCaptureEnrollmentCallback(); EnrollmentCallback enrollmentCallback = verifyAndCaptureEnrollmentCallback();
enrollmentCallback.onEnrollmentProgress(123); enrollmentCallback.onEnrollmentProgress(123);
@@ -123,6 +176,8 @@ public class FingerprintEnrollFindSensorTest {
@Config(qualifiers = "mcc999") @Config(qualifiers = "mcc999")
@Test @Test
public void layoutWithoutAnimation_shouldNotCrash() { public void layoutWithoutAnimation_shouldNotCrash() {
setupActivity_onRearDevice();
EnrollmentCallback enrollmentCallback = verifyAndCaptureEnrollmentCallback(); EnrollmentCallback enrollmentCallback = verifyAndCaptureEnrollmentCallback();
enrollmentCallback.onEnrollmentProgress(123); enrollmentCallback.onEnrollmentProgress(123);
enrollmentCallback.onEnrollmentError(FingerprintManager.FINGERPRINT_ERROR_CANCELED, "test"); enrollmentCallback.onEnrollmentError(FingerprintManager.FINGERPRINT_ERROR_CANCELED, "test");
@@ -137,12 +192,14 @@ public class FingerprintEnrollFindSensorTest {
@Test @Test
public void clickSkip_shouldReturnResultSkip() { public void clickSkip_shouldReturnResultSkip() {
setupActivity_onRearDevice();
PartnerCustomizationLayout layout = mActivity.findViewById(R.id.setup_wizard_layout); PartnerCustomizationLayout layout = mActivity.findViewById(R.id.setup_wizard_layout);
layout.getMixin(FooterBarMixin.class).getSecondaryButtonView().performClick(); layout.getMixin(FooterBarMixin.class).getSecondaryButtonView().performClick();
ShadowActivity shadowActivity = Shadows.shadowOf(mActivity); ShadowActivity shadowActivity = Shadows.shadowOf(mActivity);
assertWithMessage("result code").that(shadowActivity.getResultCode()) assertWithMessage("result code").that(shadowActivity.getResultCode())
.isEqualTo(BiometricEnrollBase.RESULT_SKIP); .isEqualTo(RESULT_SKIP);
} }
private EnrollmentCallback verifyAndCaptureEnrollmentCallback() { private EnrollmentCallback verifyAndCaptureEnrollmentCallback() {
@@ -160,9 +217,404 @@ public class FingerprintEnrollFindSensorTest {
@Test @Test
public void onActivityResult_withNullIntentShouldNotCrash() { public void onActivityResult_withNullIntentShouldNotCrash() {
setupActivity_onRearDevice();
// this should not crash // this should not crash
mActivity.onActivityResult(BiometricEnrollBase.CONFIRM_REQUEST, Activity.RESULT_OK, mActivity.onActivityResult(BiometricEnrollBase.CONFIRM_REQUEST, Activity.RESULT_OK,
null); null);
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(Activity.RESULT_CANCELED); assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(Activity.RESULT_CANCELED);
} }
@Test
public void resultFinishShallForward_onRearDevice() {
setupActivity_onRearDevice();
triggerEnrollProgressAndError_onRearDevice();
verifyStartEnrollingActivity();
// pause activity
mActivityController.pause().stop();
// onStop shall not change default activity result
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
gotEnrollingResult_resumeActivityAndVerifyResultThenForward(RESULT_FINISHED);
}
@Test
public void resultFinishShallForward_onRearDevice_recreate() {
setupActivity_onRearDevice();
triggerEnrollProgressAndError_onRearDevice();
verifyStartEnrollingActivity();
// recycle activity
final Bundle bundle = new Bundle();
mActivityController.pause().stop().saveInstanceState(bundle).destroy();
// onStop shall not change default activity result
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
gotEnrollingResult_recreateActivityAndVerifyResultThenForward(RESULT_FINISHED, bundle);
}
@Test
public void resultSkipShallForward_onRearDevice() {
setupActivity_onRearDevice();
verifySidecar_onRearOrSfpsDevice();
triggerEnrollProgressAndError_onRearDevice();
verifyStartEnrollingActivity();
// pause activity
mActivityController.pause().stop();
// onStop shall not change default activity result
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
gotEnrollingResult_resumeActivityAndVerifyResultThenForward(RESULT_SKIP);
}
@Test
public void resultSkipShallForward_onRearDevice_recreate() {
setupActivity_onRearDevice();
verifySidecar_onRearOrSfpsDevice();
triggerEnrollProgressAndError_onRearDevice();
verifyStartEnrollingActivity();
// recycle activity
final Bundle bundle = new Bundle();
mActivityController.pause().stop().saveInstanceState(bundle).destroy();
// onStop shall not change default activity result
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
gotEnrollingResult_recreateActivityAndVerifyResultThenForward(RESULT_SKIP, bundle);
}
@Test
public void resultTimeoutShallForward_onRearDevice() {
setupActivity_onRearDevice();
verifySidecar_onRearOrSfpsDevice();
triggerEnrollProgressAndError_onRearDevice();
verifyStartEnrollingActivity();
// pause activity
mActivityController.pause().stop();
// onStop shall not change default activity result
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
gotEnrollingResult_resumeActivityAndVerifyResultThenForward(RESULT_TIMEOUT);
}
@Test
public void resultTimeoutShallForward_onRearDevice_recreate() {
setupActivity_onRearDevice();
verifySidecar_onRearOrSfpsDevice();
triggerEnrollProgressAndError_onRearDevice();
verifyStartEnrollingActivity();
// recycle activity
final Bundle bundle = new Bundle();
mActivityController.pause().stop().saveInstanceState(bundle).destroy();
// onStop shall not change default activity result
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
gotEnrollingResult_recreateActivityAndVerifyResultThenForward(RESULT_TIMEOUT, bundle);
}
@Test
public void clickLottieResultFinishShallForward_onUdfpsDevice() {
setupActivity_onUdfpsDevice();
verifyNoSidecar();
clickLottieView_onUdfpsDevice();
verifyStartEnrollingActivity();
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
// pause activity
mActivityController.pause().stop();
// onStop shall not change default activity result
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
gotEnrollingResult_resumeActivityAndVerifyResultThenForward(RESULT_FINISHED);
}
@Test
public void clickLottieResultFinishShallForward_onUdfpsDevice_ifActivityRecycled() {
setupActivity_onUdfpsDevice();
verifyNoSidecar();
clickLottieView_onUdfpsDevice();
verifyStartEnrollingActivity();
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
// recycle activity
final Bundle bundle = new Bundle();
mActivityController.pause().stop().saveInstanceState(bundle).destroy();
// onStop shall not change default activity result
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
gotEnrollingResult_recreateActivityAndVerifyResultThenForward(RESULT_FINISHED, bundle);
}
@Test
public void clickLottieResultSkipShallForward_onUdfpsDevice() {
setupActivity_onUdfpsDevice();
verifyNoSidecar();
clickLottieView_onUdfpsDevice();
verifyStartEnrollingActivity();
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
// pause activity
mActivityController.pause().stop();
// onStop shall not change default activity result
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
gotEnrollingResult_resumeActivityAndVerifyResultThenForward(RESULT_SKIP);
}
@Test
public void clickLottieResultSkipShallForward_onUdfpsDevice_ifActivityRecycled() {
setupActivity_onUdfpsDevice();
verifyNoSidecar();
clickLottieView_onUdfpsDevice();
verifyStartEnrollingActivity();
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
// recycle activity
final Bundle bundle = new Bundle();
mActivityController.pause().stop().saveInstanceState(bundle).destroy();
// onStop shall not change default activity result
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
gotEnrollingResult_recreateActivityAndVerifyResultThenForward(RESULT_SKIP, bundle);
}
@Test
public void clickLottieResultTimeoutShallForward_onUdfpsDevice() {
setupActivity_onUdfpsDevice();
verifyNoSidecar();
clickLottieView_onUdfpsDevice();
verifyStartEnrollingActivity();
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
// pause activity
mActivityController.pause().stop();
// onStop shall not change default activity result
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
gotEnrollingResult_resumeActivityAndVerifyResultThenForward(RESULT_TIMEOUT);
}
@Test
public void clickLottieResultTimeoutShallForward_onUdfpsDevice_ifActivityRecycled() {
setupActivity_onUdfpsDevice();
verifyNoSidecar();
clickLottieView_onUdfpsDevice();
verifyStartEnrollingActivity();
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
// recycle activity
final Bundle bundle = new Bundle();
mActivityController.pause().stop().saveInstanceState(bundle).destroy();
// onStop shall not change default activity result
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
gotEnrollingResult_recreateActivityAndVerifyResultThenForward(RESULT_TIMEOUT, bundle);
}
@Test
public void clickPrimiaryButtonResultFinishShallForward_onUdfpsDevice() {
setupActivity_onUdfpsDevice();
verifyNoSidecar();
clickPrimaryButton_onUdfpsDevice();
verifyStartEnrollingActivity();
// pause activity
mActivityController.pause().stop();
// onStop shall not change default activity result
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
gotEnrollingResult_resumeActivityAndVerifyResultThenForward(RESULT_FINISHED);
}
@Test
public void clickPrimiaryButtonResultFinishShallForward_onUdfpsDevice_ifActivityRecycled() {
setupActivity_onUdfpsDevice();
verifyNoSidecar();
clickPrimaryButton_onUdfpsDevice();
verifyStartEnrollingActivity();
// recycle activity
final Bundle bundle = new Bundle();
mActivityController.pause().stop().saveInstanceState(bundle).destroy();
// onStop shall not change default activity result
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
gotEnrollingResult_recreateActivityAndVerifyResultThenForward(RESULT_FINISHED, bundle);
}
@Test
public void clickPrimiaryButtonResultSkipShallForward_onUdfpsDevice() {
setupActivity_onUdfpsDevice();
verifyNoSidecar();
clickPrimaryButton_onUdfpsDevice();
verifyStartEnrollingActivity();
// pause activity
mActivityController.pause().stop();
// onStop shall not change default activity result
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
gotEnrollingResult_resumeActivityAndVerifyResultThenForward(RESULT_SKIP);
}
@Test
public void clickPrimaryButtonResultSkipShallForward_onUdfpsDevice_ifActivityRecycled() {
setupActivity_onUdfpsDevice();
verifyNoSidecar();
clickPrimaryButton_onUdfpsDevice();
verifyStartEnrollingActivity();
// recycle activity
final Bundle bundle = new Bundle();
mActivityController.pause().stop().saveInstanceState(bundle).destroy();
// onStop shall not change default activity result
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
gotEnrollingResult_recreateActivityAndVerifyResultThenForward(RESULT_SKIP, bundle);
}
@Test
public void clickPrimaryButtonResultTimeoutShallForward_onUdfpsDevice() {
setupActivity_onUdfpsDevice();
verifyNoSidecar();
clickPrimaryButton_onUdfpsDevice();
verifyStartEnrollingActivity();
// pause activity
mActivityController.pause().stop();
// onStop shall not change default activity result
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
gotEnrollingResult_resumeActivityAndVerifyResultThenForward(RESULT_TIMEOUT);
}
@Test
public void clickPrimaryButtonResultTimeoutShallForward_onUdfpsDevice_ifActivityRecycled() {
setupActivity_onUdfpsDevice();
verifyNoSidecar();
clickPrimaryButton_onUdfpsDevice();
verifyStartEnrollingActivity();
// recycle activity
final Bundle bundle = new Bundle();
mActivityController.pause().stop().saveInstanceState(bundle).destroy();
// onStop shall not change default activity result
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
gotEnrollingResult_recreateActivityAndVerifyResultThenForward(RESULT_TIMEOUT, bundle);
}
private void triggerEnrollProgressAndError_onRearDevice() {
EnrollmentCallback enrollmentCallback = verifyAndCaptureEnrollmentCallback();
enrollmentCallback.onEnrollmentProgress(123);
enrollmentCallback.onEnrollmentError(FingerprintManager.FINGERPRINT_ERROR_CANCELED, "test");
}
private void clickPrimaryButton_onUdfpsDevice() {
final FooterBarMixin footerBarMixin =
((GlifLayout) mActivity.findViewById(R.id.setup_wizard_layout))
.getMixin(FooterBarMixin.class);
final FooterButton primaryButton = footerBarMixin.getPrimaryButton();
assertThat(primaryButton).isNotNull();
assertThat(primaryButton.getVisibility()).isEqualTo(View.VISIBLE);
primaryButton.onClick(null);
}
private void clickLottieView_onUdfpsDevice() {
final View lottieView = mActivity.findViewById(R.id.illustration_lottie);
assertThat(lottieView).isNotNull();
lottieView.performClick();
}
private void gotEnrollingResult_resumeActivityAndVerifyResultThenForward(
int testActivityResult) {
// resume activity
mActivityController.start().resume().visible();
verifyNoSidecar();
// onActivityResult from Enrolling activity shall be forward back
Shadows.shadowOf(mActivity).receiveResult(
new Intent(mActivity, FingerprintEnrollEnrolling.class),
testActivityResult,
null);
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(testActivityResult);
assertThat(mActivity.isFinishing()).isEqualTo(true);
// onStop shall not change last activity result
mActivityController.pause().stop().destroy();
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(testActivityResult);
}
private void gotEnrollingResult_recreateActivityAndVerifyResultThenForward(
int testActivityResult, @NonNull Bundle savedInstance) {
// Rebuild activity and use savedInstance to restore.
buildActivity();
mActivityController.setup(savedInstance);
verifyNoSidecar();
// onActivityResult from Enrolling activity shall be forward back
Shadows.shadowOf(mActivity).receiveResult(
new Intent(mActivity, FingerprintEnrollEnrolling.class),
testActivityResult,
null);
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(testActivityResult);
assertThat(mActivity.isFinishing()).isEqualTo(true);
// onStop shall not change last activity result
mActivityController.pause().stop().destroy();
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(testActivityResult);
}
private void verifySidecar_onRearOrSfpsDevice() {
final Fragment sidecar = mActivity.getSupportFragmentManager().findFragmentByTag(
TAG_SIDECAR);
assertThat(sidecar).isNotNull();
assertThat(sidecar.isAdded()).isTrue();
}
private void verifyNoSidecar() {
final Fragment sidecar = mActivity.getSupportFragmentManager().findFragmentByTag(
TAG_SIDECAR);
if (sidecar != null) {
assertThat(sidecar.isAdded()).isFalse();
}
}
} }

View File

@@ -179,11 +179,11 @@ public class FingerprintStatusUtilsTest {
} }
@Test @Test
public void getSettingsClassName_whenNotEnrolled_returnsFingerprintEnrollInduction() { public void getSettingsClassName_whenNotEnrolled_returnsFingerprintSettings() {
when(mFingerprintManager.hasEnrolledFingerprints(anyInt())).thenReturn(false); when(mFingerprintManager.hasEnrolledFingerprints(anyInt())).thenReturn(false);
assertThat(mFingerprintStatusUtils.getSettingsClassName()) assertThat(mFingerprintStatusUtils.getSettingsClassName())
.isEqualTo(FingerprintEnrollIntroductionInternal.class.getName()); .isEqualTo(FingerprintSettings.class.getName());
} }
@Test @Test

View File

@@ -47,7 +47,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.Settings; import com.android.settings.Settings;
import com.android.settings.biometrics.face.FaceEnrollIntroductionInternal; import com.android.settings.biometrics.face.FaceEnrollIntroductionInternal;
import com.android.settings.biometrics.fingerprint.FingerprintEnrollIntroductionInternal;
import com.android.settings.biometrics.fingerprint.FingerprintSettings; import com.android.settings.biometrics.fingerprint.FingerprintSettings;
import com.android.settings.testutils.ResourcesUtils; import com.android.settings.testutils.ResourcesUtils;
@@ -186,7 +185,7 @@ public class BiometricsSafetySourceTest {
assertSafetySourceEnabledDataSetWithSingularSummary( assertSafetySourceEnabledDataSetWithSingularSummary(
"security_settings_fingerprint_preference_title", "security_settings_fingerprint_preference_title",
"security_settings_fingerprint_preference_summary_none", "security_settings_fingerprint_preference_summary_none",
FingerprintEnrollIntroductionInternal.class.getName()); FingerprintSettings.class.getName());
} }
@Test @Test