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

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/19764093

Change-Id: I3b0053910613af42ecc91b8a416b131c662c1837
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
TreeHugger Robot
2022-08-30 00:53:37 +00:00
committed by Automerger Merge Worker
3 changed files with 326 additions and 52 deletions

View File

@@ -134,6 +134,9 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase implements
setHeaderText(R.string.security_settings_fingerprint_enroll_find_sensor_title);
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.
// adb shell am start -a android.app.action.SET_NEW_PASSWORD
@@ -148,11 +151,19 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase implements
// it passed in.
getIntent().putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken);
startLookingForFingerprint();
// 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();
}
});
} else if (mToken != null) {
// HAT passed in from somewhere else, such as FingerprintEnrollIntroduction
startLookingForFingerprint();
// 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
startLookingForFingerprint();
}
} else {
// There's something wrong with the enrollment flow, this should never happen.
throw new IllegalStateException("HAT and GkPwHandle both missing...");
@@ -173,9 +184,6 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase implements
mAnimation = (FingerprintFindSensorAnimation) animationView;
}
}
if (savedInstanceState != null) {
mNextClicked = savedInstanceState.getBoolean(SAVED_STATE_IS_NEXT_CLICKED, mNextClicked);
}
}
@Override
@@ -297,6 +305,7 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase implements
return;
}
}
mSidecar.setListener(null);
getSupportFragmentManager().beginTransaction().remove(mSidecar).
commitAllowingStateLoss();
mSidecar = null;

View File

@@ -50,6 +50,8 @@ public class FingerprintEnrollFinish extends BiometricEnrollBase {
static final String FINGERPRINT_SUGGESTION_ACTIVITY =
"com.android.settings.SetupFingerprintSuggestionActivity";
private boolean mIsAddAnotherOrFinish;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -107,9 +109,23 @@ 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
protected void onNextButtonClick(View view) {
updateFingerprintSuggestionEnableState();
finishAndToNext();
}
private void finishAndToNext() {
mIsAddAnotherOrFinish = true;
setResult(RESULT_FINISHED);
if (WizardManagerHelper.isAnySetupWizard(getIntent())) {
postEnroll();
@@ -145,20 +161,21 @@ public class FingerprintEnrollFinish extends BiometricEnrollBase {
}
private void onAddAnotherButtonClick(View view) {
mIsAddAnotherOrFinish = true;
startActivityForResult(getFingerprintEnrollingIntent(), BiometricUtils.REQUEST_ADD_ANOTHER);
}
@Override
protected boolean shouldFinishWhenBackgrounded() {
return !isFinishing() && super.shouldFinishWhenBackgrounded();
return !mIsAddAnotherOrFinish && super.shouldFinishWhenBackgrounded();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
updateFingerprintSuggestionEnableState();
if (requestCode == BiometricUtils.REQUEST_ADD_ANOTHER && resultCode != RESULT_CANCELED) {
setResult(resultCode, data);
finish();
// If user cancel during "Add another", just use similar flow on "Next" button
finishAndToNext();
} else {
super.onActivityResult(requestCode, resultCode, data);
}

View File

@@ -19,6 +19,11 @@ 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.assertWithMessage;
@@ -29,6 +34,7 @@ import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.verify;
import static org.robolectric.RuntimeEnvironment.application;
import android.annotation.NonNull;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
@@ -38,9 +44,12 @@ import android.hardware.fingerprint.FingerprintManager;
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.view.View;
import androidx.fragment.app.Fragment;
import com.android.settings.R;
import com.android.settings.biometrics.BiometricEnrollBase;
import com.android.settings.password.ChooseLockSettingsHelper;
@@ -82,12 +91,7 @@ public class FingerprintEnrollFindSensorTest {
private FingerprintEnrollFindSensor mActivity;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowUtils.setFingerprintManager(mFingerprintManager);
FakeFeatureFactory.setupForTest();
private void buildActivity() {
mActivityController = Robolectric.buildActivity(
FingerprintEnrollFindSensor.class,
new Intent()
@@ -97,6 +101,14 @@ public class FingerprintEnrollFindSensorTest {
mActivity = mActivityController.get();
}
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowUtils.setFingerprintManager(mFingerprintManager);
FakeFeatureFactory.setupForTest();
buildActivity();
}
private void setupActivity_onRearDevice() {
final ArrayList<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
props.add(newFingerprintSensorPropertiesInternal(TYPE_REAR));
@@ -187,7 +199,7 @@ public class FingerprintEnrollFindSensorTest {
ShadowActivity shadowActivity = Shadows.shadowOf(mActivity);
assertWithMessage("result code").that(shadowActivity.getResultCode())
.isEqualTo(BiometricEnrollBase.RESULT_SKIP);
.isEqualTo(RESULT_SKIP);
}
private EnrollmentCallback verifyAndCaptureEnrollmentCallback() {
@@ -214,123 +226,320 @@ public class FingerprintEnrollFindSensorTest {
}
@Test
public void enrollingFinishResultShallSentBack_onRearDevice() {
public void resultFinishShallForward_onRearDevice() {
setupActivity_onRearDevice();
triggerEnrollProgressAndError_onRearDevice();
verifyStartEnrollingActivity();
// onStop shall not change 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_verifyResultSentBack(BiometricEnrollBase.RESULT_FINISHED);
gotEnrollingResult_resumeActivityAndVerifyResultThenForward(RESULT_FINISHED);
}
@Test
public void enrollingSkipResultShallSentBack_onRearDevice() {
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
mActivityController.pause().stop();
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
gotEnrollingResult_verifyResultSentBack(BiometricEnrollBase.RESULT_SKIP);
gotEnrollingResult_recreateActivityAndVerifyResultThenForward(RESULT_FINISHED, bundle);
}
@Test
public void enrollingTimeoutResultShallSentBack_onRearDevice() {
public void resultSkipShallForward_onRearDevice() {
setupActivity_onRearDevice();
verifySidecar_onRearOrSfpsDevice();
triggerEnrollProgressAndError_onRearDevice();
verifyStartEnrollingActivity();
// onStop shall not change 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_verifyResultSentBack(BiometricEnrollBase.RESULT_TIMEOUT);
gotEnrollingResult_resumeActivityAndVerifyResultThenForward(RESULT_SKIP);
}
@Test
public void enrollingFinishResultShallSentBack_onUdfpsDevice_triggeredByLottieClick() {
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);
// onStop shall not change 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_verifyResultSentBack(BiometricEnrollBase.RESULT_FINISHED);
gotEnrollingResult_resumeActivityAndVerifyResultThenForward(RESULT_FINISHED);
}
@Test
public void enrollingSkipResultShallSentBack_onUdfpsDevice_triggeredByLottieClick() {
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
mActivityController.pause().stop();
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
gotEnrollingResult_verifyResultSentBack(BiometricEnrollBase.RESULT_SKIP);
gotEnrollingResult_recreateActivityAndVerifyResultThenForward(RESULT_FINISHED, bundle);
}
@Test
public void enrollingTimeoutResultShallSentBack_onUdfpsDevice_triggeredByLottieClick() {
public void clickLottieResultSkipShallForward_onUdfpsDevice() {
setupActivity_onUdfpsDevice();
verifyNoSidecar();
clickLottieView_onUdfpsDevice();
verifyStartEnrollingActivity();
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
// onStop shall not change 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_verifyResultSentBack(BiometricEnrollBase.RESULT_TIMEOUT);
gotEnrollingResult_resumeActivityAndVerifyResultThenForward(RESULT_SKIP);
}
@Test
public void enrollingFinishResultShallSentBack_onUdfpsDevice_triggeredByPrimaryButtonClick() {
public void clickLottieResultSkipShallForward_onUdfpsDevice_ifActivityRecycled() {
setupActivity_onUdfpsDevice();
clickPrimaryButton_onUdfpsDevice();
verifyStartEnrollingActivity();
verifyNoSidecar();
// onStop shall not change default activity result
mActivityController.pause().stop();
clickLottieView_onUdfpsDevice();
verifyStartEnrollingActivity();
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
gotEnrollingResult_verifyResultSentBack(BiometricEnrollBase.RESULT_FINISHED);
// 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 enrollingSkipResultShallSentBack_onUdfpsDevice_triggeredByPrimaryButtonClick() {
public void clickLottieResultTimeoutShallForward_onUdfpsDevice() {
setupActivity_onUdfpsDevice();
clickPrimaryButton_onUdfpsDevice();
verifyStartEnrollingActivity();
verifyNoSidecar();
// onStop shall not change default activity result
mActivityController.pause().stop();
clickLottieView_onUdfpsDevice();
verifyStartEnrollingActivity();
assertThat(Shadows.shadowOf(mActivity).getResultCode()).isEqualTo(DEFAULT_ACTIVITY_RESULT);
gotEnrollingResult_verifyResultSentBack(BiometricEnrollBase.RESULT_SKIP);
// 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 enrollingTimeoutResultShallSentBack_onUdfpsDevice_triggeredByPrimaryButtonClick() {
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();
// onStop shall not change 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_verifyResultSentBack(BiometricEnrollBase.RESULT_TIMEOUT);
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() {
@@ -355,9 +564,13 @@ public class FingerprintEnrollFindSensorTest {
lottieView.performClick();
}
private void gotEnrollingResult_verifyResultSentBack(int testActivityResult) {
// onActivityResult from Enrolling activity shall be sent back
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,
@@ -366,7 +579,42 @@ public class FingerprintEnrollFindSensorTest {
assertThat(mActivity.isFinishing()).isEqualTo(true);
// onStop shall not change last activity result
mActivityController.pause().stop();
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();
}
}
}