Snap for 9010110 from bbcdc91967 to tm-qpr1-release

Change-Id: I9c314c19dc1e92d4f4a2e63f125879fc3188fff5
This commit is contained in:
Android Build Coastguard Worker
2022-08-30 23:26:04 +00:00
18 changed files with 750 additions and 94 deletions

View File

@@ -199,6 +199,8 @@
android:layout_width="16dp"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/footer_learn_more"
android:linksClickable="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/BiometricEnrollIntroMessage"

View File

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

View File

@@ -31,11 +31,13 @@ import com.android.settings.R;
import com.android.settings.biometrics.BiometricEnrollBase;
import com.android.settings.biometrics.BiometricEnrollSidecar;
import com.android.settings.biometrics.BiometricErrorDialog;
import com.android.settings.biometrics.BiometricUtils;
import com.android.settings.biometrics.BiometricsEnrollEnrolling;
import com.android.settings.slices.CustomSliceRegistry;
import com.google.android.setupcompat.template.FooterBarMixin;
import com.google.android.setupcompat.template.FooterButton;
import com.google.android.setupcompat.util.WizardManagerHelper;
import java.util.ArrayList;
@@ -112,6 +114,25 @@ public class FaceEnrollEnrolling extends BiometricsEnrollEnrolling {
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
public void startEnrollment() {
super.startEnrollment();

View File

@@ -26,6 +26,8 @@ import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.face.FaceManager;
import android.hardware.face.FaceSensorPropertiesInternal;
import android.os.Bundle;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
@@ -120,7 +122,9 @@ public class FaceEnrollIntroduction extends BiometricEnrollIntroduction {
infoMessageLooking.setText(getInfoMessageLooking());
inControlTitle.setText(getInControlTitle());
howMessage.setText(getHowMessage());
inControlMessage.setText(getInControlMessage());
inControlMessage.setText(Html.fromHtml(getString(getInControlMessage()),
Html.FROM_HTML_MODE_LEGACY));
inControlMessage.setMovementMethod(LinkMovementMethod.getInstance());
lessSecure.setText(getLessSecureMessage());
// Set up and show the "less secure" info section if necessary.

View File

@@ -16,6 +16,8 @@
package com.android.settings.biometrics.fingerprint;
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ERROR_USER_CANCELED;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.annotation.IntDef;
@@ -51,6 +53,7 @@ import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.IdRes;
import androidx.appcompat.app.AlertDialog;
import com.android.internal.annotations.VisibleForTesting;
@@ -80,6 +83,7 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
private static final String TAG = "FingerprintEnrollEnrolling";
static final String TAG_SIDECAR = "sidecar";
static final String KEY_STATE_CANCELED = "is_canceled";
static final String KEY_STATE_PREVIOUS_ROTATION = "previous_rotation";
private static final int PROGRESS_BAR_MAX = 10000;
@@ -134,6 +138,7 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
private boolean mRestoring;
private Vibrator mVibrator;
private boolean mIsSetupWizard;
private boolean mIsOrientationChanged;
private boolean mIsCanceled;
private AccessibilityManager mAccessibilityManager;
private boolean mIsAccessibilityEnabled;
@@ -155,6 +160,23 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
return defaultDensity == currentDensity;
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
if (hasFocus) {
return;
}
// By UX design, we should ensure seamless enrollment CUJ even though user rotate device.
// Do NOT cancel enrollment progress after rotating, adding mIsOrientationChanged
// to judge if the focus changed was triggered by rotation, current WMS has triple callbacks
// (true > false > true), we need to reset mIsOrientationChanged when !hasFocus callback.
if (!mIsOrientationChanged) {
onCancelEnrollment(FINGERPRINT_ERROR_USER_CANCELED);
} else {
mIsOrientationChanged = false;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -295,11 +317,15 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(KEY_STATE_CANCELED, mIsCanceled);
outState.putInt(KEY_STATE_PREVIOUS_ROTATION, mPreviousRotation);
}
private void restoreSavedState(Bundle savedInstanceState) {
mRestoring = true;
mIsCanceled = savedInstanceState.getBoolean(KEY_STATE_CANCELED, false);
mPreviousRotation = savedInstanceState.getInt(KEY_STATE_PREVIOUS_ROTATION,
getDisplay().getRotation());
mIsOrientationChanged = mPreviousRotation != getDisplay().getRotation();
}
@Override
@@ -337,10 +363,38 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
}
}
@VisibleForTesting
void onCancelEnrollment(@IdRes int errorMsgId) {
FingerprintErrorDialog.showErrorDialog(this, errorMsgId);
mIsCanceled = true;
mIsOrientationChanged = false;
cancelEnrollment();
stopIconAnimation();
stopListenOrientationEvent();
if (!mCanAssumeUdfps) {
mErrorText.removeCallbacks(mTouchAgainRunnable);
}
}
@Override
protected void onStop() {
super.onStop();
if (!isChangingConfigurations()) {
if (!WizardManagerHelper.isAnySetupWizard(getIntent())
&& !BiometricUtils.isAnyMultiBiometricFlow(this)
&& !mFromSettingsSummary) {
setResult(RESULT_TIMEOUT);
}
finish();
}
stopIconAnimation();
super.onStop();
}
@Override
protected boolean shouldFinishWhenBackgrounded() {
// Prevent super.onStop() from finishing, since we handle this in our onStop().
return false;
}
@Override
@@ -541,14 +595,7 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
@Override
public void onEnrollmentError(int errMsgId, CharSequence errString) {
FingerprintErrorDialog.showErrorDialog(this, errMsgId);
mIsCanceled = true;
cancelEnrollment();
stopIconAnimation();
stopListenOrientationEvent();
if (!mCanAssumeUdfps) {
mErrorText.removeCallbacks(mTouchAgainRunnable);
}
onCancelEnrollment(errMsgId);
}
@Override

View File

@@ -49,8 +49,8 @@ import java.util.List;
public class FingerprintEnrollFindSensor extends BiometricEnrollBase implements
BiometricEnrollSidecar.Listener {
private static final String TAG = "FingerprintEnrollFindSensor";
private static final String SAVED_STATE_IS_NEXT_CLICKED = "is_next_clicked";
@Nullable
private FingerprintFindSensorAnimation mAnimation;
@@ -67,7 +67,7 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase implements
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final FingerprintManager fingerprintManager = getSystemService(FingerprintManager.class);
final FingerprintManager fingerprintManager = Utils.getFingerprintManagerOrNull(this);
final List<FingerprintSensorPropertiesInternal> props =
fingerprintManager.getSensorPropertiesInternal();
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);
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
if (mToken == null && BiometricUtils.containsGatekeeperPasswordHandle(getIntent())) {
final FingerprintManager fpm = getSystemService(FingerprintManager.class);
fpm.generateChallenge(mUserId, (sensorId, userId, challenge) -> {
fingerprintManager.generateChallenge(mUserId, (sensorId, userId, challenge) -> {
mChallenge = challenge;
mSensorId = sensorId;
mToken = BiometricUtils.requestGatekeeperHat(this, getIntent(), mUserId, challenge);
@@ -149,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...");
@@ -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
public void onBackPressed() {
stopLookingForFingerprint();
@@ -240,7 +256,6 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase implements
@Override
public void onEnrollmentError(int errMsgId, CharSequence errString) {
if (mNextClicked && errMsgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED) {
mNextClicked = false;
proceedToEnrolling(false /* cancelEnrollment */);
} else {
FingerprintErrorDialog.showErrorDialog(this, errMsgId);
@@ -270,6 +285,7 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase implements
}
private void onStartButtonClick(View view) {
mNextClicked = true;
startActivityForResult(getFingerprintEnrollingIntent(), ENROLL_REQUEST);
}
@@ -289,6 +305,7 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase implements
return;
}
}
mSidecar.setListener(null);
getSupportFragmentManager().beginTransaction().remove(mSidecar).
commitAllowingStateLoss();
mSidecar = null;
@@ -341,6 +358,7 @@ public class FingerprintEnrollFindSensor extends BiometricEnrollBase implements
finish();
} else {
// We came back from enrolling but it wasn't completed, start again.
mNextClicked = false;
startLookingForFingerprint();
}
break;

View File

@@ -32,7 +32,6 @@ import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.biometrics.BiometricEnrollBase;
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.FooterButton;
@@ -51,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);
@@ -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
protected void onNextButtonClick(View view) {
updateFingerprintSuggestionEnableState();
finishAndToNext();
}
private void finishAndToNext() {
mIsAddAnotherOrFinish = true;
setResult(RESULT_FINISHED);
if (WizardManagerHelper.isAnySetupWizard(getIntent())) {
postEnroll();
} else if (mFromSettingsSummary) {
// Only launch fingerprint settings if enrollment was triggered through settings summary
launchFingerprintSettings();
}
finish();
}
@@ -148,27 +160,22 @@ public class FingerprintEnrollFinish extends BiometricEnrollBase {
}
}
private void launchFingerprintSettings() {
final Intent intent = new Intent(ACTION_FINGERPRINT_SETTINGS);
intent.setPackage(Utils.SETTINGS_PACKAGE_NAME);
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) {
mIsAddAnotherOrFinish = true;
startActivityForResult(getFingerprintEnrollingIntent(), BiometricUtils.REQUEST_ADD_ANOTHER);
}
private void onAddAnotherButtonClick(View view) {
startActivityForResult(getFingerprintEnrollingIntent(), BiometricUtils.REQUEST_ADD_ANOTHER);
@Override
protected boolean 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

@@ -26,6 +26,8 @@ import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.os.Bundle;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
@@ -104,6 +106,11 @@ public class FingerprintEnrollIntroduction extends BiometricEnrollIntroduction {
footerMessage5.setText(getFooterMessage5());
footerMessage6.setText(getFooterMessage6());
final TextView footerLink = findViewById(R.id.footer_learn_more);
footerLink.setMovementMethod(LinkMovementMethod.getInstance());
footerLink.setText(Html.fromHtml(getString(getFooterLearnMore()),
Html.FROM_HTML_MODE_LEGACY));
if (mCanAssumeUdfps) {
footerMessage6.setVisibility(View.VISIBLE);
iconShield.setVisibility(View.VISIBLE);
@@ -187,6 +194,11 @@ public class FingerprintEnrollIntroduction extends BiometricEnrollIntroduction {
return R.string.security_settings_fingerprint_v2_enroll_introduction_footer_message_6;
}
@StringRes
protected int getFooterLearnMore() {
return R.string.security_settings_fingerprint_v2_enroll_introduction_message_learn_more;
}
@Override
protected boolean isDisabledByAdmin() {
return RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(

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 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.Dialog;
@@ -62,6 +63,7 @@ import com.android.settings.SubSettings;
import com.android.settings.Utils;
import com.android.settings.biometrics.BiometricEnrollBase;
import com.android.settings.biometrics.BiometricUtils;
import com.android.settings.core.SettingsBaseActivity;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settings.password.ChooseLockGeneric;
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.EnforcedAdmin;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.transition.SettingsTransitionHelper;
import com.android.settingslib.widget.FooterPreference;
import com.android.settingslib.widget.TwoTargetPreference;
@@ -129,6 +132,8 @@ public class FingerprintSettings extends SubSettings {
private static final String KEY_FINGERPRINT_ENABLE_KEYGUARD_TOGGLE =
"fingerprint_enable_keyguard_toggle";
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_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 ADD_FINGERPRINT_REQUEST = 10;
private static final int AUTO_ADD_FIRST_FINGERPRINT_REQUEST = 11;
protected static final boolean DEBUG = false;
@@ -149,10 +155,11 @@ public class FingerprintSettings extends SubSettings {
private boolean mInFingerprintLockout;
private byte[] mToken;
private boolean mLaunchedConfirm;
private boolean mHasFirstEnrolled = true;
private Drawable mHighlightDrawable;
private int mUserId;
private final List<FooterColumn> mFooterColumns = new ArrayList<>();
private boolean mEnrollClicked;
private boolean mIsEnrolling;
private long mChallenge;
@@ -341,6 +348,9 @@ public class FingerprintSettings extends SubSettings {
}
mFingerprintsRenaming = new HashMap<Integer, String>();
mUserId = getActivity().getIntent().getIntExtra(
Intent.EXTRA_USER_ID, UserHandle.myUserId());
mHasFirstEnrolled = mFingerprintManager.hasEnrolledFingerprints(mUserId);
if (savedInstanceState != null) {
mFingerprintsRenaming = (HashMap<Integer, String>)
@@ -349,14 +359,21 @@ public class FingerprintSettings extends SubSettings {
ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN);
mLaunchedConfirm = savedInstanceState.getBoolean(
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());
// Need to authenticate a session token if none
if (mToken == null && mLaunchedConfirm == false) {
mLaunchedConfirm = true;
launchChooseOrConfirmLock();
// (mLaunchedConfirm or mIsEnrolling) means that we are waiting an activity result.
if (!mLaunchedConfirm && !mIsEnrolling) {
// Need to authenticate a session token if none
if (mToken == null) {
mLaunchedConfirm = true;
launchChooseOrConfirmLock();
} else if (!mHasFirstEnrolled) {
mIsEnrolling = true;
addFirstFingerprint();
}
}
updateFooterColumns(activity);
}
@@ -546,7 +563,7 @@ public class FingerprintSettings extends SubSettings {
@Override
public void onStop() {
super.onStop();
if (!getActivity().isChangingConfigurations() && !mLaunchedConfirm && !mEnrollClicked) {
if (!getActivity().isChangingConfigurations() && !mLaunchedConfirm && !mIsEnrolling) {
getActivity().finish();
}
}
@@ -557,13 +574,15 @@ public class FingerprintSettings extends SubSettings {
mToken);
outState.putBoolean(KEY_LAUNCHED_CONFIRM, mLaunchedConfirm);
outState.putSerializable("mFingerprintsRenaming", mFingerprintsRenaming);
outState.putBoolean(KEY_IS_ENROLLING, mIsEnrolling);
outState.putBoolean(KEY_HAS_FIRST_ENROLLED, mHasFirstEnrolled);
}
@Override
public boolean onPreferenceTreeClick(Preference pref) {
final String key = pref.getKey();
if (KEY_FINGERPRINT_ADD.equals(key)) {
mEnrollClicked = true;
mIsEnrolling = true;
Intent intent = new Intent();
intent.setClassName(SETTINGS_PACKAGE_NAME,
FingerprintEnrollEnrolling.class.getName());
@@ -659,6 +678,10 @@ public class FingerprintSettings extends SubSettings {
BiometricUtils.removeGatekeeperPasswordHandle(getActivity(),
data);
updateAddPreference();
if (!mHasFirstEnrolled && !mIsEnrolling) {
mIsEnrolling = true;
addFirstFingerprint();
}
});
} else {
Log.d(TAG, "Data null or GK PW missing");
@@ -669,12 +692,19 @@ public class FingerprintSettings extends SubSettings {
finish();
}
} else if (requestCode == ADD_FINGERPRINT_REQUEST) {
mEnrollClicked = false;
mIsEnrolling = false;
if (resultCode == RESULT_TIMEOUT) {
Activity activity = getActivity();
activity.setResult(resultCode);
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
void deleteFingerPrint(Fingerprint fingerPrint) {
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.
*/
public String getSettingsClassName() {
return hasEnrolled() ? FingerprintSettings.class.getName()
: FingerprintEnrollIntroductionInternal.class.getName();
return FingerprintSettings.class.getName();
}
/**

View File

@@ -369,10 +369,6 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
addFooterPreferenceIfNeeded(false);
return false;
}
if (mBatteryUsageMap == null) {
// Battery usage data is not ready, wait for data ready to refresh UI.
return false;
}
if (isBatteryLevelDataInOneDay()) {
// Only 1 day data, hide the daily chart view.
@@ -394,6 +390,10 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
mHourlyChartView.setViewModel(hourlyViewModel);
}
if (mBatteryUsageMap == null) {
// Battery usage data is not ready, wait for data ready to refresh UI.
return false;
}
mHandler.post(() -> {
final long start = System.currentTimeMillis();
removeAndCacheAllPrefs();

View File

@@ -515,7 +515,7 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
private boolean hasOverlap(
final Rect[] displayAreas, final int leftIndex, final int rightIndex) {
return displayAreas[leftIndex].right + mTextPadding * 2f > displayAreas[rightIndex].left;
return displayAreas[leftIndex].right + mTextPadding * 2.3f > displayAreas[rightIndex].left;
}
private void drawAxisLabelText(

View File

@@ -20,6 +20,7 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;
import android.util.FeatureFlagUtils;
public class PanelFeatureProviderImpl implements PanelFeatureProvider {
@@ -49,9 +50,19 @@ public class PanelFeatureProviderImpl implements PanelFeatureProvider {
case Settings.Panel.ACTION_WIFI:
return WifiPanel.create(context);
case Settings.Panel.ACTION_VOLUME:
return VolumePanel.create(context);
if (FeatureFlagUtils.isEnabled(context,
FeatureFlagUtils.SETTINGS_VOLUME_PANEL_IN_SYSTEMUI)) {
// Redirect to the volume panel in SystemUI.
Intent volumeIntent = new Intent(Settings.Panel.ACTION_VOLUME);
volumeIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND).setPackage(
SYSTEMUI_PACKAGE_NAME);
context.sendBroadcast(volumeIntent);
return null;
} else {
return VolumePanel.create(context);
}
}
throw new IllegalStateException("No matching panel for: " + panelType);
throw new IllegalStateException("No matching panel for: " + panelType);
}
}

View File

@@ -16,6 +16,8 @@
package com.android.settings.biometrics.fingerprint;
import static com.android.settings.biometrics.fingerprint.FingerprintEnrollEnrolling.KEY_STATE_PREVIOUS_ROTATION;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
@@ -28,14 +30,18 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.hardware.biometrics.ComponentInfoInternal;
import android.hardware.biometrics.SensorProperties;
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.os.Vibrator;
import android.view.Display;
import android.view.Surface;
import android.widget.TextView;
import com.android.settings.R;
@@ -49,6 +55,7 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.android.controller.ActivityController;
import java.util.ArrayList;
@@ -61,7 +68,10 @@ public class FingerprintEnrollEnrollingTest {
@Mock private Vibrator mVibrator;
@Mock private Display mMockDisplay;
private FingerprintEnrollEnrolling mActivity;
private Context mContext;
@Before
public void setUp() {
@@ -100,6 +110,26 @@ public class FingerprintEnrollEnrollingTest {
verify(mVibrator, never()).vibrate(anyInt(), anyString(), any(), anyString(), any());
}
@Test
public void fingerprintUdfpsOverlayEnrollment_gainFocus_shouldNotCancel() {
initializeActivityFor(FingerprintSensorProperties.TYPE_UDFPS_OPTICAL);
mActivity.onEnrollmentProgressChange(1, 1);
mActivity.onWindowFocusChanged(true);
verify(mActivity, never()).onCancelEnrollment(anyInt());
}
@Test
public void fingerprintUdfpsOverlayEnrollment_loseFocus_shouldCancel() {
initializeActivityFor(FingerprintSensorProperties.TYPE_UDFPS_OPTICAL);
mActivity.onEnrollmentProgressChange(1, 1);
mActivity.onWindowFocusChanged(false);
verify(mActivity, never()).onCancelEnrollment(anyInt());
}
private void initializeActivityFor(int sensorType) {
final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
final FingerprintSensorPropertiesInternal prop =
@@ -111,15 +141,21 @@ public class FingerprintEnrollEnrollingTest {
sensorType,
true /* resetLockoutRequiresHardwareAuthToken */);
final ArrayList<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
final Bundle savedInstanceState = new Bundle();
savedInstanceState.putInt(KEY_STATE_PREVIOUS_ROTATION, Surface.ROTATION_90);
props.add(prop);
when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(props);
mContext = spy(RuntimeEnvironment.application);
mActivity = spy(FingerprintEnrollEnrolling.class);
when(mFingerprintManager.getSensorPropertiesInternal()).thenReturn(props);
when(mContext.getDisplay()).thenReturn(mMockDisplay);
when(mMockDisplay.getRotation()).thenReturn(Surface.ROTATION_0);
doReturn(true).when(mActivity).shouldShowLottie();
doReturn(mFingerprintManager).when(mActivity).getSystemService(FingerprintManager.class);
doReturn(mVibrator).when(mActivity).getSystemService(Vibrator.class);
ActivityController.of(mActivity).create();
ActivityController.of(mActivity).create(savedInstanceState);
}
private EnrollmentCallback verifyAndCaptureEnrollmentCallback() {

View File

@@ -16,21 +16,39 @@
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;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.doReturn;
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;
import android.hardware.biometrics.ComponentInfoInternal;
import android.hardware.biometrics.SensorProperties;
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;
@@ -40,6 +58,8 @@ import com.android.settings.testutils.shadow.ShadowUtils;
import com.google.android.setupcompat.PartnerCustomizationLayout;
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.Before;
@@ -51,31 +71,69 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.Shadows;
import org.robolectric.android.controller.ActivityController;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowActivity;
import org.robolectric.shadows.ShadowActivity.IntentForResult;
import java.util.ArrayList;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowUtils.class)
public class FingerprintEnrollFindSensorTest {
private static final int DEFAULT_ACTIVITY_RESULT = Activity.RESULT_CANCELED;
@Mock
private FingerprintManager mFingerprintManager;
private ActivityController<FingerprintEnrollFindSensor> mActivityController;
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
public void setUp() {
MockitoAnnotations.initMocks(this);
ShadowUtils.setFingerprintManager(mFingerprintManager);
FakeFeatureFactory.setupForTest();
buildActivity();
}
mActivity = 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]))
.setup().get();
private void setupActivity_onRearDevice() {
final ArrayList<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
props.add(newFingerprintSensorPropertiesInternal(TYPE_REAR));
doReturn(props).when(mFingerprintManager).getSensorPropertiesInternal();
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
@@ -83,13 +141,7 @@ public class FingerprintEnrollFindSensorTest {
ShadowUtils.reset();
}
@Test
public void enrollFingerprint_shouldProceed() {
EnrollmentCallback enrollmentCallback = verifyAndCaptureEnrollmentCallback();
enrollmentCallback.onEnrollmentProgress(123);
enrollmentCallback.onEnrollmentError(FingerprintManager.FINGERPRINT_ERROR_CANCELED, "test");
private void verifyStartEnrollingActivity() {
ShadowActivity shadowActivity = Shadows.shadowOf(mActivity);
IntentForResult startedActivity =
shadowActivity.getNextStartedActivityForResult();
@@ -100,6 +152,7 @@ public class FingerprintEnrollFindSensorTest {
@Test
public void enrollFingerprintTwice_shouldStartOneEnrolling() {
setupActivity_onRearDevice();
EnrollmentCallback enrollmentCallback = verifyAndCaptureEnrollmentCallback();
enrollmentCallback.onEnrollmentProgress(123);
@@ -123,6 +176,8 @@ public class FingerprintEnrollFindSensorTest {
@Config(qualifiers = "mcc999")
@Test
public void layoutWithoutAnimation_shouldNotCrash() {
setupActivity_onRearDevice();
EnrollmentCallback enrollmentCallback = verifyAndCaptureEnrollmentCallback();
enrollmentCallback.onEnrollmentProgress(123);
enrollmentCallback.onEnrollmentError(FingerprintManager.FINGERPRINT_ERROR_CANCELED, "test");
@@ -137,12 +192,14 @@ public class FingerprintEnrollFindSensorTest {
@Test
public void clickSkip_shouldReturnResultSkip() {
setupActivity_onRearDevice();
PartnerCustomizationLayout layout = mActivity.findViewById(R.id.setup_wizard_layout);
layout.getMixin(FooterBarMixin.class).getSecondaryButtonView().performClick();
ShadowActivity shadowActivity = Shadows.shadowOf(mActivity);
assertWithMessage("result code").that(shadowActivity.getResultCode())
.isEqualTo(BiometricEnrollBase.RESULT_SKIP);
.isEqualTo(RESULT_SKIP);
}
private EnrollmentCallback verifyAndCaptureEnrollmentCallback() {
@@ -160,9 +217,404 @@ public class FingerprintEnrollFindSensorTest {
@Test
public void onActivityResult_withNullIntentShouldNotCrash() {
setupActivity_onRearDevice();
// this should not crash
mActivity.onActivityResult(BiometricEnrollBase.CONFIRM_REQUEST, Activity.RESULT_OK,
null);
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
public void getSettingsClassName_whenNotEnrolled_returnsFingerprintEnrollInduction() {
public void getSettingsClassName_whenNotEnrolled_returnsFingerprintSettings() {
when(mFingerprintManager.hasEnrolledFingerprints(anyInt())).thenReturn(false);
assertThat(mFingerprintStatusUtils.getSettingsClassName())
.isEqualTo(FingerprintEnrollIntroductionInternal.class.getName());
.isEqualTo(FingerprintSettings.class.getName());
}
@Test

View File

@@ -28,6 +28,7 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;
import android.util.FeatureFlagUtils;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -35,6 +36,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@RunWith(AndroidJUnit4.class)
public class PanelFeatureProviderImplTest {
@@ -66,11 +68,27 @@ public class PanelFeatureProviderImplTest {
}
@Test
public void getPanel_volume_returnsCorrectPanel() {
public void getPanel_volumePanel_returnsCorrectPanel() {
FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_VOLUME_PANEL_IN_SYSTEMUI,
false);
mBundle.putString(KEY_PANEL_TYPE_ARGUMENT, Settings.Panel.ACTION_VOLUME);
final PanelContent panel = mProvider.getPanel(mContext, mBundle);
assertThat(panel).isInstanceOf(VolumePanel.class);
}
@Test
public void getPanel_volumePanelFlagEnabled_sendRedirectIntent() {
FeatureFlagUtils.setEnabled(mContext, FeatureFlagUtils.SETTINGS_VOLUME_PANEL_IN_SYSTEMUI,
true);
mBundle.putString(KEY_PANEL_TYPE_ARGUMENT, Settings.Panel.ACTION_VOLUME);
final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
mProvider.getPanel(mContext, mBundle);
verify(mContext).sendBroadcast(intentCaptor.capture());
assertThat(intentCaptor.getValue().getAction()).isEqualTo(Settings.Panel.ACTION_VOLUME);
assertThat(intentCaptor.getValue().getPackage()).isEqualTo(SYSTEMUI_PACKAGE_NAME);
}
}

View File

@@ -47,7 +47,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.Settings;
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.testutils.ResourcesUtils;
@@ -186,7 +185,7 @@ public class BiometricsSafetySourceTest {
assertSafetySourceEnabledDataSetWithSingularSummary(
"security_settings_fingerprint_preference_title",
"security_settings_fingerprint_preference_summary_none",
FingerprintEnrollIntroductionInternal.class.getName());
FingerprintSettings.class.getName());
}
@Test