From 67d6dff7cc6a04f0136cd7ebb9be8c523116cadf Mon Sep 17 00:00:00 2001 From: lbill Date: Fri, 21 Apr 2023 10:21:07 +0000 Subject: [PATCH] Refine SkipDialog title and desc by device configs 1. Wrap isFaceSupportedInSUW() in Settings Utils 2. Wrap getCombinedScreenLockOptions in Settings Utils 3. Add EXTRA_KEY_FOR_SUW to judge if in SUW flow 4. Refactor SetupSkipDialog by hasFace, hasFingerprint, isSuw, isFaceSupported conditions 5. Clean up the mapping logic of SetupSkipDialog 6. Replace bools with @LockPatternUtils.CredentialType 7. Refine the logic for isFaceSupported --------------------------------------- Config |SuwSupportFace|!SuwSupportFace| isSuw | true | false | !isSuw | hasFace | hasFace | Bug: 263070591 Bug: 279389803 Bug: 279195215 Test: adb shell am start -a android.settings.BIOMETRIC_ENROLL Test: SUW(workprofile), post-SUW Test: m RunSettingsRoboTests ROBOTEST_FILTER=com.android.settings.password Test: m RunSettingsRoboTests ROBOTEST_FILTER=SetupSkipDialogTest Change-Id: Ie7af4299695dc3983b4190929b4dd659c301c082 --- res/values/strings.xml | 2 + .../settings/biometrics/BiometricUtils.java | 48 ++++++ .../settings/password/ChooseLockGeneric.java | 37 ++-- .../password/ChooseLockSettingsHelper.java | 2 + .../password/SetupChooseLockGeneric.java | 12 +- .../password/SetupChooseLockPassword.java | 11 +- .../password/SetupChooseLockPattern.java | 11 +- .../settings/password/SetupSkipDialog.java | 159 +++++++++--------- .../password/ChooseLockGenericTest.java | 32 +++- .../password/SetupChooseLockGenericTest.java | 77 ++++----- .../password/SetupChooseLockPasswordTest.java | 4 +- .../password/SetupChooseLockPatternTest.java | 6 +- .../password/SetupSkipDialogTest.java | 159 +++++++++++++++--- 13 files changed, 359 insertions(+), 201 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index b12f390de71..dd9746610ae 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -991,6 +991,8 @@ Skip fingerprint setup? You\u2019ve chosen to use your fingerprint as one way to unlock your phone. If you skip now, you\u2019ll need to set this up later. Setup takes only a minute or so. + + Skip setup for %s? Skip PIN setup? diff --git a/src/com/android/settings/biometrics/BiometricUtils.java b/src/com/android/settings/biometrics/BiometricUtils.java index 772aec33bfd..3356dfa9322 100644 --- a/src/com/android/settings/biometrics/BiometricUtils.java +++ b/src/com/android/settings/biometrics/BiometricUtils.java @@ -28,6 +28,8 @@ import android.hardware.face.FaceManager; import android.hardware.face.FaceSensorPropertiesInternal; import android.os.Bundle; import android.os.storage.StorageManager; +import android.text.BidiFormatter; +import android.text.SpannableStringBuilder; import android.util.FeatureFlagUtils; import android.util.Log; import android.view.Surface; @@ -38,6 +40,7 @@ import androidx.fragment.app.FragmentActivity; import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.VerifyCredentialResponse; +import com.android.settings.R; import com.android.settings.SetupWizardUtils; import com.android.settings.biometrics.face.FaceEnrollIntroduction; import com.android.settings.biometrics.fingerprint.FingerprintEnrollFindSensor; @@ -45,6 +48,7 @@ import com.android.settings.biometrics.fingerprint.FingerprintEnrollIntroduction import com.android.settings.biometrics.fingerprint.SetupFingerprintEnrollFindSensor; import com.android.settings.biometrics.fingerprint.SetupFingerprintEnrollIntroduction; import com.android.settings.biometrics2.ui.view.FingerprintEnrollmentActivity; +import com.android.settings.overlay.FeatureFactory; import com.android.settings.password.ChooseLockGeneric; import com.android.settings.password.ChooseLockSettingsHelper; import com.android.settings.password.SetupChooseLockGeneric; @@ -60,6 +64,9 @@ import java.lang.annotation.RetentionPolicy; public class BiometricUtils { private static final String TAG = "BiometricUtils"; + /** The character ' • ' to separate the setup choose options */ + public static final String SEPARATOR = " \u2022 "; + // Note: Theis IntDef must align SystemUI DevicePostureInt @IntDef(prefix = {"DEVICE_POSTURE_"}, value = { DEVICE_POSTURE_UNKNOWN, @@ -496,4 +503,45 @@ public class BiometricUtils { public static boolean isLandscape(@NonNull Context context) { return context.getDisplay().getRotation() == Surface.ROTATION_90; } + + /** + * Returns true if the device supports Face enrollment in SUW flow + */ + public static boolean isFaceSupportedInSuw(Context context) { + return FeatureFactory.getFactory(context).getFaceFeatureProvider().isSetupWizardSupported( + context); + } + + /** + * Returns the combined screen lock options by device biometrics config + * @param context the application context + * @param screenLock the type of screen lock(PIN, Pattern, Password) in string + * @param hasFingerprint device support fingerprint or not + * @param isFaceSupported device support face or not + * @return the options combined with screen lock, face, and fingerprint in String format. + */ + public static String getCombinedScreenLockOptions(Context context, + CharSequence screenLock, boolean hasFingerprint, boolean isFaceSupported) { + final SpannableStringBuilder ssb = new SpannableStringBuilder(); + final BidiFormatter bidi = BidiFormatter.getInstance(); + // Assume the flow is "Screen Lock" + "Face" + "Fingerprint" + ssb.append(bidi.unicodeWrap(screenLock)); + + if (isFaceSupported) { + ssb.append(bidi.unicodeWrap(SEPARATOR)); + ssb.append(bidi.unicodeWrap( + capitalize(context.getString(R.string.keywords_face_settings)))); + } + + if (hasFingerprint) { + ssb.append(bidi.unicodeWrap(SEPARATOR)); + ssb.append(bidi.unicodeWrap( + capitalize(context.getString(R.string.security_settings_fingerprint)))); + } + return ssb.toString(); + } + + private static String capitalize(final String input) { + return Character.toUpperCase(input.charAt(0)) + input.substring(1); + } } diff --git a/src/com/android/settings/password/ChooseLockGeneric.java b/src/com/android/settings/password/ChooseLockGeneric.java index 0bf13b15c0c..4c4795cbd84 100644 --- a/src/com/android/settings/password/ChooseLockGeneric.java +++ b/src/com/android/settings/password/ChooseLockGeneric.java @@ -48,8 +48,6 @@ import android.os.UserHandle; import android.os.UserManager; import android.os.storage.StorageManager; import android.service.persistentdata.PersistentDataBlockManager; -import android.text.BidiFormatter; -import android.text.SpannableStringBuilder; import android.text.TextUtils; import android.util.EventLog; import android.util.Log; @@ -77,9 +75,9 @@ import com.android.settings.SetupWizardUtils; import com.android.settings.Utils; import com.android.settings.biometrics.BiometricEnrollActivity; import com.android.settings.biometrics.BiometricEnrollBase; +import com.android.settings.biometrics.BiometricUtils; import com.android.settings.core.SubSettingLauncher; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; -import com.android.settings.overlay.FeatureFactory; import com.android.settings.safetycenter.LockScreenSafetySource; import com.android.settings.search.SearchFeatureProvider; import com.android.settingslib.RestrictedPreference; @@ -143,9 +141,6 @@ public class ChooseLockGeneric extends SettingsActivity { */ public static final String EXTRA_CHOOSE_LOCK_GENERIC_EXTRAS = "choose_lock_generic_extras"; - /** The character ' • ' to separate the setup choose options */ - public static final String SEPARATOR = " \u2022 "; - @VisibleForTesting static final int CONFIRM_EXISTING_REQUEST = 100; @VisibleForTesting @@ -662,32 +657,20 @@ public class ChooseLockGeneric extends SettingsActivity { @VisibleForTesting String getBiometricsPreferenceTitle(@NonNull ScreenLockType secureType) { - SpannableStringBuilder ssb = new SpannableStringBuilder(); - BidiFormatter bidi = BidiFormatter.getInstance(); + final boolean hasFingerprint = Utils.hasFingerprintHardware(getContext()); + final boolean hasFace = Utils.hasFaceHardware(getContext()); + final boolean isSuw = WizardManagerHelper.isAnySetupWizard(getIntent()); + final boolean isFaceSupported = + hasFace && (!isSuw || BiometricUtils.isFaceSupportedInSuw(getContext())); + // Assume the flow is "Screen Lock" + "Face" + "Fingerprint" if (mController != null) { - ssb.append(bidi.unicodeWrap(mController.getTitle(secureType))); + return BiometricUtils.getCombinedScreenLockOptions(getContext(), + mController.getTitle(secureType), hasFingerprint, isFaceSupported); } else { Log.e(TAG, "ChooseLockGenericController is null!"); + return getResources().getString(R.string.error_title); } - - if (mFaceManager != null && mFaceManager.isHardwareDetected() && isFaceSupported()) { - ssb.append(bidi.unicodeWrap(SEPARATOR)); - ssb.append(bidi.unicodeWrap( - getResources().getString(R.string.keywords_face_settings))); - } - if (mFingerprintManager != null && mFingerprintManager.isHardwareDetected()) { - ssb.append(bidi.unicodeWrap(SEPARATOR)); - ssb.append(bidi.unicodeWrap( - getResources().getString(R.string.security_settings_fingerprint))); - } - return ssb.toString(); - } - - private boolean isFaceSupported() { - return FeatureFactory.getFactory(getContext().getApplicationContext()) - .getFaceFeatureProvider() - .isSetupWizardSupported(getContext().getApplicationContext()); } private void setPreferenceTitle(ScreenLockType lock, @StringRes int title) { diff --git a/src/com/android/settings/password/ChooseLockSettingsHelper.java b/src/com/android/settings/password/ChooseLockSettingsHelper.java index 9657175c2e5..216f7db1ac1 100644 --- a/src/com/android/settings/password/ChooseLockSettingsHelper.java +++ b/src/com/android/settings/password/ChooseLockSettingsHelper.java @@ -64,6 +64,8 @@ public final class ChooseLockSettingsHelper { public static final String EXTRA_KEY_FOR_FACE = "for_face"; // For the paths where multiple biometric sensors exist public static final String EXTRA_KEY_FOR_BIOMETRICS = "for_biometrics"; + // For the paths where setup biometrics in suw flow + public static final String EXTRA_KEY_IS_SUW = "is_suw"; public static final String EXTRA_KEY_FOREGROUND_ONLY = "foreground_only"; public static final String EXTRA_KEY_REQUEST_GK_PW_HANDLE = "request_gk_pw_handle"; // Gatekeeper password handle, which can subsequently be used to generate Gatekeeper diff --git a/src/com/android/settings/password/SetupChooseLockGeneric.java b/src/com/android/settings/password/SetupChooseLockGeneric.java index 17d83b30b88..bc6c5129968 100644 --- a/src/com/android/settings/password/SetupChooseLockGeneric.java +++ b/src/com/android/settings/password/SetupChooseLockGeneric.java @@ -19,6 +19,7 @@ package com.android.settings.password; import static android.Manifest.permission.REQUEST_PASSWORD_COMPLEXITY; import static android.app.admin.DevicePolicyManager.EXTRA_PASSWORD_COMPLEXITY; +import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE; import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY; import android.app.RemoteServiceException.MissingRequestPasswordComplexityPermissionException; @@ -43,6 +44,7 @@ import com.android.settings.R; import com.android.settings.SetupWizardUtils; import com.android.settings.utils.SettingsDividerItemDecoration; +import com.google.android.setupcompat.util.WizardManagerHelper; import com.google.android.setupdesign.GlifPreferenceLayout; import com.google.android.setupdesign.util.ThemeHelper; @@ -187,14 +189,14 @@ public class SetupChooseLockGeneric extends ChooseLockGeneric { final String key = preference.getKey(); if (KEY_UNLOCK_SET_DO_LATER.equals(key)) { // show warning. + final Intent intent = getActivity().getIntent(); SetupSkipDialog dialog = SetupSkipDialog.newInstance( - getActivity().getIntent() - .getBooleanExtra(SetupSkipDialog.EXTRA_FRP_SUPPORTED, false), - /* isPatternMode= */ false, - /* isAlphaMode= */ false, + CREDENTIAL_TYPE_NONE, + intent.getBooleanExtra(SetupSkipDialog.EXTRA_FRP_SUPPORTED, false), /* forFingerprint= */ false, /* forFace= */ false, - /* forBiometrics= */ false + /* forBiometrics= */ false, + WizardManagerHelper.isAnySetupWizard(intent) ); dialog.show(getFragmentManager()); return true; diff --git a/src/com/android/settings/password/SetupChooseLockPassword.java b/src/com/android/settings/password/SetupChooseLockPassword.java index 74cb2718b00..0101aa5c29f 100644 --- a/src/com/android/settings/password/SetupChooseLockPassword.java +++ b/src/com/android/settings/password/SetupChooseLockPassword.java @@ -16,6 +16,9 @@ package com.android.settings.password; +import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD; +import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN; + import android.app.Activity; import android.content.Context; import android.content.Intent; @@ -31,6 +34,8 @@ import com.android.settings.R; import com.android.settings.SetupRedactionInterstitial; import com.android.settings.password.ChooseLockTypeDialogFragment.OnLockTypeSelectedListener; +import com.google.android.setupcompat.util.WizardManagerHelper; + /** * Setup Wizard's version of ChooseLockPassword screen. It inherits the logic and basic structure * from ChooseLockPassword class, and should remain similar to that behaviorally. This class should @@ -113,12 +118,12 @@ public class SetupChooseLockPassword extends ChooseLockPassword { final boolean forBiometrics = intent .getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, false); final SetupSkipDialog dialog = SetupSkipDialog.newInstance( + mIsAlphaMode ? CREDENTIAL_TYPE_PASSWORD : CREDENTIAL_TYPE_PIN, frpSupported, - /* isPatternMode= */ false, - mIsAlphaMode, forFingerprint, forFace, - forBiometrics); + forBiometrics, + WizardManagerHelper.isAnySetupWizard(intent)); ConfirmDeviceCredentialUtils.hideImeImmediately( getActivity().getWindow().getDecorView()); diff --git a/src/com/android/settings/password/SetupChooseLockPattern.java b/src/com/android/settings/password/SetupChooseLockPattern.java index 09ecda48ee5..2cad1813568 100644 --- a/src/com/android/settings/password/SetupChooseLockPattern.java +++ b/src/com/android/settings/password/SetupChooseLockPattern.java @@ -18,6 +18,8 @@ package com.android.settings.password; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; +import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN; + import android.content.Context; import android.content.Intent; import android.os.Bundle; @@ -32,6 +34,8 @@ import androidx.fragment.app.Fragment; import com.android.settings.R; import com.android.settings.SetupRedactionInterstitial; +import com.google.android.setupcompat.util.WizardManagerHelper; + /** * Setup Wizard's version of ChooseLockPattern screen. It inherits the logic and basic structure * from ChooseLockPattern class, and should remain similar to that behaviorally. This class should @@ -101,14 +105,13 @@ public class SetupChooseLockPattern extends ChooseLockPattern { .getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, false); final boolean forBiometrics = intent .getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, false); - final SetupSkipDialog dialog = SetupSkipDialog.newInstance( + CREDENTIAL_TYPE_PATTERN, frpSupported, - /* isPatternMode= */ true, - /* isAlphaMode= */ false, forFingerprint, forFace, - forBiometrics); + forBiometrics, + WizardManagerHelper.isAnySetupWizard(intent)); dialog.show(getFragmentManager()); return; } diff --git a/src/com/android/settings/password/SetupSkipDialog.java b/src/com/android/settings/password/SetupSkipDialog.java index 2dac3d655dd..9049da7348e 100644 --- a/src/com/android/settings/password/SetupSkipDialog.java +++ b/src/com/android/settings/password/SetupSkipDialog.java @@ -16,6 +16,14 @@ package com.android.settings.password; +import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD; +import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN; +import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN; +import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS; +import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE; +import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT; +import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_IS_SUW; + import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; @@ -29,7 +37,10 @@ import androidx.annotation.NonNull; import androidx.annotation.StringRes; import androidx.fragment.app.FragmentManager; +import com.android.internal.widget.LockPatternUtils; import com.android.settings.R; +import com.android.settings.Utils; +import com.android.settings.biometrics.BiometricUtils; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; public class SetupSkipDialog extends InstrumentedDialogFragment @@ -38,24 +49,23 @@ public class SetupSkipDialog extends InstrumentedDialogFragment public static final String EXTRA_FRP_SUPPORTED = ":settings:frp_supported"; private static final String ARG_FRP_SUPPORTED = "frp_supported"; - // The key indicates type of lock screen is pattern setup. - private static final String ARG_LOCK_TYPE_PATTERN = "lock_type_pattern"; + // The key indicates type of screen lock credential types(PIN/Pattern/Password) + private static final String ARG_LOCK_CREDENTIAL_TYPE = "lock_credential_type"; // The key indicates type of lock screen setup is alphanumeric for password setup. - private static final String ARG_LOCK_TYPE_ALPHANUMERIC = "lock_type_alphanumeric"; private static final String TAG_SKIP_DIALOG = "skip_dialog"; public static final int RESULT_SKIP = Activity.RESULT_FIRST_USER + 10; - public static SetupSkipDialog newInstance(boolean isFrpSupported, boolean isPatternMode, - boolean isAlphanumericMode, boolean forFingerprint, boolean forFace, - boolean forBiometrics) { + public static SetupSkipDialog newInstance(@LockPatternUtils.CredentialType int credentialType, + boolean isFrpSupported, boolean forFingerprint, boolean forFace, + boolean forBiometrics, boolean isSuw) { SetupSkipDialog dialog = new SetupSkipDialog(); Bundle args = new Bundle(); + args.putInt(ARG_LOCK_CREDENTIAL_TYPE, credentialType); args.putBoolean(ARG_FRP_SUPPORTED, isFrpSupported); - args.putBoolean(ARG_LOCK_TYPE_PATTERN, isPatternMode); - args.putBoolean(ARG_LOCK_TYPE_ALPHANUMERIC, isAlphanumericMode); - args.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, forFingerprint); - args.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, forFace); - args.putBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, forBiometrics); + args.putBoolean(EXTRA_KEY_FOR_FINGERPRINT, forFingerprint); + args.putBoolean(EXTRA_KEY_FOR_FACE, forFace); + args.putBoolean(EXTRA_KEY_FOR_BIOMETRICS, forBiometrics); + args.putBoolean(EXTRA_KEY_IS_SUW, isSuw); dialog.setArguments(args); return dialog; } @@ -70,59 +80,59 @@ public class SetupSkipDialog extends InstrumentedDialogFragment return onCreateDialogBuilder().create(); } + private AlertDialog.Builder getBiometricsBuilder( + @LockPatternUtils.CredentialType int credentialType, boolean isSuw, boolean hasFace, + boolean hasFingerprint) { + final boolean isFaceSupported = hasFace && (!isSuw || BiometricUtils.isFaceSupportedInSuw( + getContext())); + final int msgResId; + final int screenLockResId; + switch (credentialType) { + case CREDENTIAL_TYPE_PATTERN: + screenLockResId = R.string.unlock_set_unlock_pattern_title; + msgResId = getPatternSkipMessageRes(hasFace && isFaceSupported, hasFingerprint); + break; + case CREDENTIAL_TYPE_PASSWORD: + screenLockResId = R.string.unlock_set_unlock_password_title; + msgResId = getPasswordSkipMessageRes(hasFace && isFaceSupported, hasFingerprint); + break; + case CREDENTIAL_TYPE_PIN: + default: + screenLockResId = R.string.unlock_set_unlock_pin_title; + msgResId = getPinSkipMessageRes(hasFace && isFaceSupported, hasFingerprint); + break; + } + return new AlertDialog.Builder(getContext()) + .setPositiveButton(R.string.skip_lock_screen_dialog_button_label, this) + .setNegativeButton(R.string.cancel_lock_screen_dialog_button_label, this) + .setTitle(getSkipSetupTitle(screenLockResId, hasFingerprint, + hasFace && isFaceSupported)) + .setMessage(msgResId); + } + @NonNull public AlertDialog.Builder onCreateDialogBuilder() { Bundle args = getArguments(); - final boolean forFace = - args.getBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE); - final boolean forFingerprint = - args.getBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT); - final boolean forBiometrics = - args.getBoolean(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS); + final boolean isSuw = args.getBoolean(EXTRA_KEY_IS_SUW); + final boolean forBiometrics = args.getBoolean(EXTRA_KEY_FOR_BIOMETRICS); + final boolean forFace = args.getBoolean(EXTRA_KEY_FOR_FACE); + final boolean forFingerprint = args.getBoolean(EXTRA_KEY_FOR_FINGERPRINT); + @LockPatternUtils.CredentialType + final int credentialType = args.getInt(ARG_LOCK_CREDENTIAL_TYPE); + if (forFace || forFingerprint || forBiometrics) { - final boolean hasFace = forFace || forBiometrics; - final boolean hasFingerprint = forFingerprint || forBiometrics; - - final int titleId; - final int msgResId; - if (args.getBoolean(ARG_LOCK_TYPE_PATTERN)) { - titleId = getPatternSkipTitleRes(hasFace, hasFingerprint); - msgResId = getPatternSkipMessageRes(hasFace, hasFingerprint); - } else if (args.getBoolean(ARG_LOCK_TYPE_ALPHANUMERIC)) { - titleId = getPasswordSkipTitleRes(hasFace, hasFingerprint); - msgResId = getPasswordSkipMessageRes(hasFace, hasFingerprint); - } else { - titleId = getPinSkipTitleRes(hasFace, hasFingerprint); - msgResId = getPinSkipMessageRes(hasFace, hasFingerprint); - } - - return new AlertDialog.Builder(getContext()) - .setPositiveButton(R.string.skip_lock_screen_dialog_button_label, this) - .setNegativeButton(R.string.cancel_lock_screen_dialog_button_label, this) - .setTitle(titleId) - .setMessage(msgResId); - } else { - return new AlertDialog.Builder(getContext()) - .setPositiveButton(R.string.skip_anyway_button_label, this) - .setNegativeButton(R.string.go_back_button_label, this) - .setTitle(R.string.lock_screen_intro_skip_title) - .setMessage(args.getBoolean(ARG_FRP_SUPPORTED) ? - R.string.lock_screen_intro_skip_dialog_text_frp : - R.string.lock_screen_intro_skip_dialog_text); + final boolean hasFace = Utils.hasFaceHardware(getContext()); + final boolean hasFingerprint = Utils.hasFingerprintHardware(getContext()); + return getBiometricsBuilder(credentialType, isSuw, hasFace, hasFingerprint); } - } - @StringRes - private int getPatternSkipTitleRes(boolean hasFace, boolean hasFingerprint) { - if (hasFace && hasFingerprint) { - return R.string.lock_screen_pattern_skip_biometrics_title; - } else if (hasFace) { - return R.string.lock_screen_pattern_skip_face_title; - } else if (hasFingerprint) { - return R.string.lock_screen_pattern_skip_fingerprint_title; - } else { - return R.string.lock_screen_pattern_skip_title; - } + return new AlertDialog.Builder(getContext()) + .setPositiveButton(R.string.skip_anyway_button_label, this) + .setNegativeButton(R.string.go_back_button_label, this) + .setTitle(R.string.lock_screen_intro_skip_title) + .setMessage(args.getBoolean(ARG_FRP_SUPPORTED) ? + R.string.lock_screen_intro_skip_dialog_text_frp : + R.string.lock_screen_intro_skip_dialog_text); } @StringRes @@ -138,19 +148,6 @@ public class SetupSkipDialog extends InstrumentedDialogFragment } } - @StringRes - private int getPasswordSkipTitleRes(boolean hasFace, boolean hasFingerprint) { - if (hasFace && hasFingerprint) { - return R.string.lock_screen_password_skip_biometrics_title; - } else if (hasFace) { - return R.string.lock_screen_password_skip_face_title; - } else if (hasFingerprint) { - return R.string.lock_screen_password_skip_fingerprint_title; - } else { - return R.string.lock_screen_password_skip_title; - } - } - @StringRes private int getPasswordSkipMessageRes(boolean hasFace, boolean hasFingerprint) { if (hasFace && hasFingerprint) { @@ -164,19 +161,6 @@ public class SetupSkipDialog extends InstrumentedDialogFragment } } - @StringRes - private int getPinSkipTitleRes(boolean hasFace, boolean hasFingerprint) { - if (hasFace && hasFingerprint) { - return R.string.lock_screen_pin_skip_biometrics_title; - } else if (hasFace) { - return R.string.lock_screen_pin_skip_face_title; - } else if (hasFingerprint) { - return R.string.lock_screen_pin_skip_fingerprint_title; - } else { - return R.string.lock_screen_pin_skip_title; - } - } - @StringRes private int getPinSkipMessageRes(boolean hasFace, boolean hasFingerprint) { if (hasFace && hasFingerprint) { @@ -190,6 +174,13 @@ public class SetupSkipDialog extends InstrumentedDialogFragment } } + private String getSkipSetupTitle(int screenTypeResId, boolean hasFingerprint, + boolean hasFace) { + return getString(R.string.lock_screen_skip_setup_title, + BiometricUtils.getCombinedScreenLockOptions(getContext(), + getString(screenTypeResId), hasFingerprint, hasFace)); + } + @Override public void onClick(DialogInterface dialog, int button) { Activity activity = getActivity(); diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java index f2894cc20e2..dbc60dce731 100644 --- a/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java +++ b/tests/robotests/src/com/android/settings/password/ChooseLockGenericTest.java @@ -79,6 +79,7 @@ import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; +import org.robolectric.android.controller.ActivityController; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowApplication; import org.robolectric.shadows.ShadowPersistentDataBlockManager; @@ -98,6 +99,8 @@ public class ChooseLockGenericTest { @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + + private ActivityController mActivityController; private FakeFeatureFactory mFakeFeatureFactory; private ChooseLockGenericFragment mFragment; private ChooseLockGeneric mActivity; @@ -109,7 +112,8 @@ public class ChooseLockGenericTest { @Before public void setUp() { mFakeFeatureFactory = FakeFeatureFactory.setupForTest(); - mActivity = Robolectric.buildActivity(ChooseLockGeneric.class) + mActivityController = Robolectric.buildActivity(ChooseLockGeneric.class); + mActivity = mActivityController .create() .start() .postCreate(null) @@ -314,6 +318,20 @@ public class ChooseLockGenericTest { assertThat(mActivity.isFinishing()).isTrue(); } + @Test + public void securedScreenLock_notChangingConfig_notWaitForConfirmation_onStopFinishSelf() { + Intent intent = new Intent().putExtra( + LockPatternUtils.PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_NUMERIC); + intent.putExtra("waiting_for_confirmation", true); + initActivity(intent); + + mFragment.updatePreferencesOrFinish(false /* isRecreatingActivity */); + mActivityController.configurationChange(); + mActivityController.stop(); + + assertThat(mActivity.isFinishing()).isTrue(); + } + @Test public void onPreferenceTreeClick_fingerprintPassesMinComplexityInfoOntoNextActivity() { Intent intent = new Intent(ACTION_SET_NEW_PASSWORD) @@ -534,10 +552,10 @@ public class ChooseLockGenericTest { assertThat(passwordIntent.getIntExtra(ChooseLockPassword.EXTRA_KEY_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_NONE)).isEqualTo(PASSWORD_COMPLEXITY_LOW); - final String supportFingerprint = mActivity.getResources().getString( - R.string.security_settings_fingerprint); - final String supportFace = mActivity.getResources().getString( - R.string.keywords_face_settings); + final String supportFingerprint = capitalize(mActivity.getResources().getString( + R.string.security_settings_fingerprint)); + final String supportFace = capitalize(mActivity.getResources().getString( + R.string.keywords_face_settings)); assertThat(mFragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).contains( supportFingerprint); @@ -563,4 +581,8 @@ public class ChooseLockGenericTest { .create().start().postCreate(null).resume().get(); mActivity.getSupportFragmentManager().beginTransaction().add(mFragment, null).commitNow(); } + + private static String capitalize(final String input) { + return Character.toUpperCase(input.charAt(0)) + input.substring(1); + } } diff --git a/tests/robotests/src/com/android/settings/password/SetupChooseLockGenericTest.java b/tests/robotests/src/com/android/settings/password/SetupChooseLockGenericTest.java index 8db3fd75154..b04a71821c0 100644 --- a/tests/robotests/src/com/android/settings/password/SetupChooseLockGenericTest.java +++ b/tests/robotests/src/com/android/settings/password/SetupChooseLockGenericTest.java @@ -21,6 +21,7 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_HIGH; import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY; +import static com.google.android.setupcompat.util.WizardManagerHelper.EXTRA_IS_SETUP_FLOW; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -43,6 +44,7 @@ import com.android.settings.testutils.shadow.ShadowLockPatternUtils; import com.android.settings.testutils.shadow.ShadowPasswordUtils; import com.android.settings.testutils.shadow.ShadowUserManager; import com.android.settings.testutils.shadow.ShadowUtils; +import com.android.settings.utils.ActivityControllerWrapper; import com.google.android.setupdesign.GlifPreferenceLayout; @@ -100,6 +102,7 @@ public class SetupChooseLockGenericTest { @Test public void setupChooseLockGenericPasswordComplexityExtraWithoutPermission() { Intent intent = new Intent("com.android.settings.SETUP_LOCK_SCREEN"); + intent.putExtra(EXTRA_IS_SETUP_FLOW, true); intent.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_HIGH); SetupChooseLockGeneric activity = Robolectric.buildActivity(SetupChooseLockGeneric.class, intent).create().get(); @@ -114,6 +117,7 @@ public class SetupChooseLockGenericTest { ShadowPasswordUtils.addGrantedPermission(REQUEST_PASSWORD_COMPLEXITY); Intent intent = new Intent("com.android.settings.SETUP_LOCK_SCREEN"); + intent.putExtra(EXTRA_IS_SETUP_FLOW, true); intent.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_HIGH); SetupChooseLockGeneric activity = Robolectric.buildActivity(SetupChooseLockGeneric.class, intent).create().get(); @@ -124,7 +128,8 @@ public class SetupChooseLockGenericTest { @Test public void setupChooseLockGenericUsingDescriptionTextOfGlifLayout() { - SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(false); + SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(true, true, + false); GlifPreferenceLayout view = getViewOfSetupChooseLockGenericFragment(fragment); assertThat(TextUtils.isEmpty(view.getDescriptionText())).isFalse(); assertThat(view.getDescriptionText().toString()).isEqualTo(fragment.loadDescriptionText()); @@ -132,47 +137,24 @@ public class SetupChooseLockGenericTest { @Test public void setupChooseLockGenericUsingDescriptionTextOfGlifLayoutForBiometric() { - SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(true); + SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(true, true, + true); GlifPreferenceLayout view = getViewOfSetupChooseLockGenericFragment(fragment); assertThat(TextUtils.isEmpty(view.getDescriptionText())).isFalse(); assertThat(view.getDescriptionText().toString()).isEqualTo(fragment.loadDescriptionText()); } - @Test - public void updatePreferenceTextShowScreenLockAndFingerprint() { - when(mFakeFeatureFactory.mFaceFeatureProvider.isSetupWizardSupported(any())).thenReturn( - false); - SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(true); - - final String supportFingerprint = fragment.getResources().getString( - R.string.security_settings_fingerprint); - final String supportFace = fragment.getResources().getString( - R.string.keywords_face_settings); - - assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).contains( - supportFingerprint); - assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).doesNotContain( - supportFace); - assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PATTERN)).contains( - supportFingerprint); - assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PATTERN)).doesNotContain( - supportFace); - assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PASSWORD)).contains( - supportFingerprint); - assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PASSWORD)).doesNotContain( - supportFace); - } - @Test public void updatePreferenceTextShowScreenLockAndShowFaceAndShowFingerprint() { when(mFakeFeatureFactory.mFaceFeatureProvider.isSetupWizardSupported(any())).thenReturn( true); - SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(true); + SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(true, true, + true); - final String supportFingerprint = fragment.getResources().getString( - R.string.security_settings_fingerprint); - final String supportFace = fragment.getResources().getString( - R.string.keywords_face_settings); + final String supportFingerprint = capitalize(fragment.getResources().getString( + R.string.security_settings_fingerprint)); + final String supportFace = capitalize(fragment.getResources().getString( + R.string.keywords_face_settings)); assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).contains( supportFingerprint); @@ -192,12 +174,13 @@ public class SetupChooseLockGenericTest { public void updatePreferenceTextShowScreenLockAndShowFingerprint() { when(mFakeFeatureFactory.mFaceFeatureProvider.isSetupWizardSupported(any())).thenReturn( false); - SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(true); + SetupChooseLockGenericFragment fragment = getFragmentOfSetupChooseLockGeneric(false, false, + true); - final String supportFingerprint = fragment.getResources().getString( - R.string.security_settings_fingerprint); - final String supportFace = fragment.getResources().getString( - R.string.keywords_face_settings); + final String supportFingerprint = capitalize(fragment.getResources().getString( + R.string.security_settings_fingerprint)); + final String supportFace = capitalize(fragment.getResources().getString( + R.string.keywords_face_settings)); assertThat(fragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).contains( supportFingerprint); @@ -213,16 +196,18 @@ public class SetupChooseLockGenericTest { supportFace); } - private SetupChooseLockGenericFragment getFragmentOfSetupChooseLockGeneric(boolean biometric) { + private SetupChooseLockGenericFragment getFragmentOfSetupChooseLockGeneric( + boolean forFingerprint, boolean forFace, boolean forBiometric) { ShadowPasswordUtils.addGrantedPermission(REQUEST_PASSWORD_COMPLEXITY); Intent intent = new Intent("com.android.settings.SETUP_LOCK_SCREEN"); intent.putExtra(EXTRA_KEY_REQUESTED_MIN_COMPLEXITY, PASSWORD_COMPLEXITY_HIGH); - intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, biometric); - intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, biometric); - // TODO(b/275023433) This presents the activity from being made 'visible` is workaround - SetupChooseLockGeneric activity = - Robolectric.buildActivity(SetupChooseLockGeneric.class, - intent).create().start().postCreate(null).resume().get(); + intent.putExtra(EXTRA_IS_SETUP_FLOW, true); + intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, forFingerprint); + intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE, forFace); + intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS, forBiometric); + + SetupChooseLockGeneric activity = (SetupChooseLockGeneric) ActivityControllerWrapper.setup( + Robolectric.buildActivity(SetupChooseLockGeneric.class, intent)).get(); List fragments = activity.getSupportFragmentManager().getFragments(); assertThat(fragments).isNotNull(); @@ -238,4 +223,8 @@ public class SetupChooseLockGenericTest { return (GlifPreferenceLayout) fragment.getView(); } + + private static String capitalize(final String input) { + return Character.toUpperCase(input.charAt(0)) + input.substring(1); + } } diff --git a/tests/robotests/src/com/android/settings/password/SetupChooseLockPasswordTest.java b/tests/robotests/src/com/android/settings/password/SetupChooseLockPasswordTest.java index abc7400b466..a3e2ed49591 100644 --- a/tests/robotests/src/com/android/settings/password/SetupChooseLockPasswordTest.java +++ b/tests/robotests/src/com/android/settings/password/SetupChooseLockPasswordTest.java @@ -30,7 +30,6 @@ import android.widget.Button; import androidx.appcompat.app.AlertDialog; import com.android.settings.R; -import com.android.settings.utils.ActivityControllerWrapper; import com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment; import com.android.settings.password.ChooseLockPassword.ChooseLockPasswordFragment.Stage; import com.android.settings.password.ChooseLockPassword.IntentBuilder; @@ -40,6 +39,7 @@ import com.android.settings.testutils.shadow.ShadowAlertDialogCompat; import com.android.settings.testutils.shadow.ShadowDevicePolicyManager; import com.android.settings.testutils.shadow.ShadowLockPatternUtils; import com.android.settings.testutils.shadow.ShadowUtils; +import com.android.settings.utils.ActivityControllerWrapper; import com.android.settings.widget.ScrollToParentEditText; import com.google.android.setupcompat.PartnerCustomizationLayout; @@ -93,7 +93,6 @@ public class SetupChooseLockPasswordTest { application, new IntentBuilder(application).build()); - //ActivityController.of(new SetupChooseLockPassword(), intent).setup().get(); ActivityControllerWrapper.setup( Robolectric.buildActivity(SetupChooseLockPassword.class, intent)).get(); } @@ -204,7 +203,6 @@ public class SetupChooseLockPasswordTest { intent.putExtra(ChooseLockGenericFragment.EXTRA_SHOW_OPTIONS_BUTTON, true); return (SetupChooseLockPassword) ActivityControllerWrapper.setup( Robolectric.buildActivity(SetupChooseLockPassword.class, intent)).get(); - //return ActivityController.of(new SetupChooseLockPassword(), intent).setup().get(); } @Implements(ChooseLockGenericController.class) diff --git a/tests/robotests/src/com/android/settings/password/SetupChooseLockPatternTest.java b/tests/robotests/src/com/android/settings/password/SetupChooseLockPatternTest.java index 1512ee564b3..c5e08137863 100644 --- a/tests/robotests/src/com/android/settings/password/SetupChooseLockPatternTest.java +++ b/tests/robotests/src/com/android/settings/password/SetupChooseLockPatternTest.java @@ -38,10 +38,10 @@ import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternView; import com.android.internal.widget.LockPatternView.Cell; import com.android.internal.widget.LockPatternView.DisplayMode; -import com.android.settings.password.ChooseLockPattern.ChooseLockPatternFragment; -import com.android.settings.password.ChooseLockPattern.IntentBuilder; import com.android.settings.R; import com.android.settings.SetupRedactionInterstitial; +import com.android.settings.password.ChooseLockPattern.ChooseLockPatternFragment; +import com.android.settings.password.ChooseLockPattern.IntentBuilder; import com.android.settings.testutils.shadow.ShadowAlertDialogCompat; import com.android.settings.testutils.shadow.ShadowLockPatternUtils; import com.android.settings.testutils.shadow.ShadowUtils; @@ -84,7 +84,7 @@ public class SetupChooseLockPatternTest { new IntentBuilder(application) .setUserId(UserHandle.myUserId()) .build()); - //mActivity = ActivityController.of(new SetupChooseLockPattern(), intent).setup().get(); + mActivity = (SetupChooseLockPattern) ActivityControllerWrapper.setup( Robolectric.buildActivity(SetupChooseLockPattern.class, intent)).get(); } diff --git a/tests/robotests/src/com/android/settings/password/SetupSkipDialogTest.java b/tests/robotests/src/com/android/settings/password/SetupSkipDialogTest.java index ae360e528f6..813efe9f1b5 100644 --- a/tests/robotests/src/com/android/settings/password/SetupSkipDialogTest.java +++ b/tests/robotests/src/com/android/settings/password/SetupSkipDialogTest.java @@ -16,18 +16,34 @@ package com.android.settings.password; +import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD; +import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN; +import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN; + import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +import android.hardware.face.FaceManager; +import android.hardware.fingerprint.FingerprintManager; + import androidx.fragment.app.FragmentActivity; import androidx.test.core.app.ApplicationProvider; import com.android.settings.R; +import com.android.settings.biometrics.BiometricUtils; +import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.shadow.ShadowUtils; import com.android.settings.utils.ActivityControllerWrapper; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; @@ -39,12 +55,25 @@ import org.robolectric.shadows.ShadowApplication; @Config(shadows = {ShadowUtils.class, ShadowAlertDialog.class}) public class SetupSkipDialogTest { + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Mock + private FingerprintManager mFingerprintManager; + @Mock + private FaceManager mFaceManager; private FragmentActivity mActivity; + private FakeFeatureFactory mFakeFeatureFactory; @Before public void setUp() { + ShadowUtils.setFingerprintManager(mFingerprintManager); + ShadowUtils.setFaceManager(mFaceManager); + mFakeFeatureFactory = FakeFeatureFactory.setupForTest(); mActivity = (FragmentActivity) ActivityControllerWrapper.setup( Robolectric.buildActivity(FragmentActivity.class)).get(); + + when(mFakeFeatureFactory.mFaceFeatureProvider.isSetupWizardSupported(any())).thenReturn( + true); } private ShadowAlertDialog getShadowAlertDialog() { @@ -55,10 +84,33 @@ public class SetupSkipDialogTest { return shadowAlertDialog; } + private String getSkipSetupTitle(int credentialType, boolean hasFingerprint, + boolean hasFace) { + final int screenLockResId; + switch (credentialType) { + case CREDENTIAL_TYPE_PATTERN: + screenLockResId = R.string.unlock_set_unlock_pattern_title; + break; + case CREDENTIAL_TYPE_PASSWORD: + screenLockResId = R.string.unlock_set_unlock_password_title; + break; + case CREDENTIAL_TYPE_PIN: + default: + screenLockResId = R.string.unlock_set_unlock_pin_title; + break; + } + return mActivity.getString(R.string.lock_screen_skip_setup_title, + BiometricUtils.getCombinedScreenLockOptions(mActivity, + mActivity.getString(screenLockResId), hasFingerprint, hasFace)); + } + @Test public void frpMessages_areShownCorrectly_whenNotSupported() { + when(mFaceManager.isHardwareDetected()).thenReturn(false); + when(mFingerprintManager.isHardwareDetected()).thenReturn(false); + SetupSkipDialog setupSkipDialog = - SetupSkipDialog.newInstance(false, false, false, false, false, false); + SetupSkipDialog.newInstance(CREDENTIAL_TYPE_PIN, false, false, false, false, true); setupSkipDialog.show(mActivity.getSupportFragmentManager()); ShadowAlertDialog shadowAlertDialog = getShadowAlertDialog(); @@ -70,8 +122,11 @@ public class SetupSkipDialogTest { @Test public void frpMessages_areShownCorrectly_whenSupported() { + when(mFaceManager.isHardwareDetected()).thenReturn(false); + when(mFingerprintManager.isHardwareDetected()).thenReturn(false); + SetupSkipDialog setupSkipDialog = - SetupSkipDialog.newInstance(true, false, false, false, false, false); + SetupSkipDialog.newInstance(CREDENTIAL_TYPE_PIN, true, false, false, false, true); setupSkipDialog.show(mActivity.getSupportFragmentManager()); ShadowAlertDialog shadowAlertDialog = getShadowAlertDialog(); @@ -83,117 +138,175 @@ public class SetupSkipDialogTest { @Test public void dialogMessage_whenSkipPinSetupForFace_shouldShownCorrectly() { - SetupSkipDialog setupSkipDialog = - SetupSkipDialog.newInstance(true, false, false, false, true, false); + final boolean hasFace = true; + final boolean hasFingerprint = false; + + when(mFaceManager.isHardwareDetected()).thenReturn(hasFace); + when(mFingerprintManager.isHardwareDetected()).thenReturn(hasFingerprint); + + SetupSkipDialog setupSkipDialog = SetupSkipDialog.newInstance(CREDENTIAL_TYPE_PIN, false, + false, true, false, true); setupSkipDialog.show(mActivity.getSupportFragmentManager()); ShadowAlertDialog shadowAlertDialog = getShadowAlertDialog(); assertThat(shadowAlertDialog.getTitle().toString()).isEqualTo( - mActivity.getString(R.string.lock_screen_pin_skip_face_title)); + getSkipSetupTitle(CREDENTIAL_TYPE_PIN, hasFingerprint, hasFace)); assertThat(shadowAlertDialog.getMessage().toString()).isEqualTo( mActivity.getString(R.string.lock_screen_pin_skip_face_message)); } @Test public void dialogMessage_whenSkipPasswordSetupForFace_shouldShownCorrectly() { - SetupSkipDialog setupSkipDialog = - SetupSkipDialog.newInstance(true, false, true, false, true, false); + final boolean hasFace = true; + final boolean hasFingerprint = false; + + when(mFaceManager.isHardwareDetected()).thenReturn(hasFace); + when(mFingerprintManager.isHardwareDetected()).thenReturn(hasFingerprint); + + SetupSkipDialog setupSkipDialog = SetupSkipDialog.newInstance(CREDENTIAL_TYPE_PASSWORD, + false, hasFingerprint, hasFace, false, true); setupSkipDialog.show(mActivity.getSupportFragmentManager()); ShadowAlertDialog shadowAlertDialog = getShadowAlertDialog(); assertThat(shadowAlertDialog.getTitle().toString()).isEqualTo( - mActivity.getString(R.string.lock_screen_password_skip_face_title)); + getSkipSetupTitle(CREDENTIAL_TYPE_PASSWORD, hasFingerprint, hasFace)); assertThat(shadowAlertDialog.getMessage().toString()).isEqualTo( mActivity.getString(R.string.lock_screen_password_skip_face_message)); } @Test public void dialogMessage_whenSkipPatternSetupForFace_shouldShownCorrectly() { + final boolean hasFace = true; + final boolean hasFingerprint = false; + + when(mFaceManager.isHardwareDetected()).thenReturn(hasFace); + when(mFingerprintManager.isHardwareDetected()).thenReturn(hasFingerprint); + SetupSkipDialog setupSkipDialog = - SetupSkipDialog.newInstance(true, true, false, false, true, false); + SetupSkipDialog.newInstance(CREDENTIAL_TYPE_PATTERN, true, false, true, false, + true); setupSkipDialog.show(mActivity.getSupportFragmentManager()); ShadowAlertDialog shadowAlertDialog = getShadowAlertDialog(); assertThat(shadowAlertDialog.getTitle().toString()).isEqualTo( - mActivity.getString(R.string.lock_screen_pattern_skip_face_title)); + getSkipSetupTitle(CREDENTIAL_TYPE_PATTERN, hasFingerprint, hasFace)); assertThat(shadowAlertDialog.getMessage().toString()).isEqualTo( mActivity.getString(R.string.lock_screen_pattern_skip_face_message)); } @Test public void dialogMessage_whenSkipPinSetupForFingerprint_shouldShownCorrectly() { + final boolean hasFace = false; + final boolean hasFingerprint = true; + + when(mFaceManager.isHardwareDetected()).thenReturn(hasFace); + when(mFingerprintManager.isHardwareDetected()).thenReturn(hasFingerprint); + SetupSkipDialog setupSkipDialog = - SetupSkipDialog.newInstance(true, false, false, true, false, false); + SetupSkipDialog.newInstance(CREDENTIAL_TYPE_PIN, true, true, false, false, true); setupSkipDialog.show(mActivity.getSupportFragmentManager()); ShadowAlertDialog shadowAlertDialog = getShadowAlertDialog(); assertThat(shadowAlertDialog.getTitle().toString()).isEqualTo( - mActivity.getString(R.string.lock_screen_pin_skip_fingerprint_title)); + getSkipSetupTitle(CREDENTIAL_TYPE_PIN, hasFingerprint, hasFace)); assertThat(shadowAlertDialog.getMessage().toString()).isEqualTo( mActivity.getString(R.string.lock_screen_pin_skip_fingerprint_message)); } @Test public void dialogMessage_whenSkipPasswordSetupForFingerprint_shouldShownCorrectly() { + final boolean hasFace = false; + final boolean hasFingerprint = true; + + when(mFaceManager.isHardwareDetected()).thenReturn(hasFace); + when(mFingerprintManager.isHardwareDetected()).thenReturn(hasFingerprint); + SetupSkipDialog setupSkipDialog = - SetupSkipDialog.newInstance(true, false, true, true, false, false); + SetupSkipDialog.newInstance(CREDENTIAL_TYPE_PASSWORD, true, true, false, false, + true); setupSkipDialog.show(mActivity.getSupportFragmentManager()); ShadowAlertDialog shadowAlertDialog = getShadowAlertDialog(); assertThat(shadowAlertDialog.getTitle().toString()).isEqualTo( - mActivity.getString(R.string.lock_screen_password_skip_fingerprint_title)); + getSkipSetupTitle(CREDENTIAL_TYPE_PASSWORD, hasFingerprint, hasFace)); assertThat(shadowAlertDialog.getMessage().toString()).isEqualTo( mActivity.getString(R.string.lock_screen_password_skip_fingerprint_message)); } @Test public void dialogMessage_whenSkipPatternSetupForFingerprint_shouldShownCorrectly() { - SetupSkipDialog setupSkipDialog = - SetupSkipDialog.newInstance(true, true, false, true, false, false); + final boolean hasFace = false; + final boolean hasFingerprint = true; + + when(mFaceManager.isHardwareDetected()).thenReturn(hasFace); + when(mFingerprintManager.isHardwareDetected()).thenReturn(hasFingerprint); + + SetupSkipDialog setupSkipDialog = SetupSkipDialog.newInstance(CREDENTIAL_TYPE_PATTERN, true, + true, false, false, true); setupSkipDialog.show(mActivity.getSupportFragmentManager()); ShadowAlertDialog shadowAlertDialog = getShadowAlertDialog(); assertThat(shadowAlertDialog.getTitle().toString()).isEqualTo( - mActivity.getString(R.string.lock_screen_pattern_skip_fingerprint_title)); + getSkipSetupTitle(CREDENTIAL_TYPE_PATTERN, hasFingerprint, hasFace)); assertThat(shadowAlertDialog.getMessage().toString()).isEqualTo( mActivity.getString(R.string.lock_screen_pattern_skip_fingerprint_message)); } @Test public void dialogMessage_whenSkipPinSetupForBiometrics_shouldShownCorrectly() { + final boolean hasFace = true; + final boolean hasFingerprint = true; + + when(mFaceManager.isHardwareDetected()).thenReturn(hasFace); + when(mFingerprintManager.isHardwareDetected()).thenReturn(hasFingerprint); + SetupSkipDialog setupSkipDialog = - SetupSkipDialog.newInstance(true, false, false, false, false, true); + SetupSkipDialog.newInstance(CREDENTIAL_TYPE_PIN, true, false, false, true, true); setupSkipDialog.show(mActivity.getSupportFragmentManager()); ShadowAlertDialog shadowAlertDialog = getShadowAlertDialog(); assertThat(shadowAlertDialog.getTitle().toString()).isEqualTo( - mActivity.getString(R.string.lock_screen_pin_skip_biometrics_title)); + getSkipSetupTitle(CREDENTIAL_TYPE_PIN, hasFingerprint, hasFace)); assertThat(shadowAlertDialog.getMessage().toString()).isEqualTo( mActivity.getString(R.string.lock_screen_pin_skip_biometrics_message)); } @Test public void dialogMessage_whenSkipPasswordSetupForBiometrics_shouldShownCorrectly() { + final boolean hasFace = true; + final boolean hasFingerprint = true; + + when(mFaceManager.isHardwareDetected()).thenReturn(hasFace); + when(mFingerprintManager.isHardwareDetected()).thenReturn(hasFingerprint); + SetupSkipDialog setupSkipDialog = - SetupSkipDialog.newInstance(true, false, true, false, false, true); + SetupSkipDialog.newInstance(CREDENTIAL_TYPE_PASSWORD, true, false, false, true, + true); setupSkipDialog.show(mActivity.getSupportFragmentManager()); ShadowAlertDialog shadowAlertDialog = getShadowAlertDialog(); assertThat(shadowAlertDialog.getTitle().toString()).isEqualTo( - mActivity.getString(R.string.lock_screen_password_skip_biometrics_title)); + getSkipSetupTitle(CREDENTIAL_TYPE_PASSWORD, hasFingerprint, hasFace)); assertThat(shadowAlertDialog.getMessage().toString()).isEqualTo( mActivity.getString(R.string.lock_screen_password_skip_biometrics_message)); } @Test public void dialogMessage_whenSkipPatternSetupForBiometrics_shouldShownCorrectly() { + final boolean hasFace = true; + final boolean hasFingerprint = true; + + when(mFaceManager.isHardwareDetected()).thenReturn(hasFace); + when(mFingerprintManager.isHardwareDetected()).thenReturn(hasFingerprint); + SetupSkipDialog setupSkipDialog = - SetupSkipDialog.newInstance(true, true, false, false, false, true); + SetupSkipDialog.newInstance(CREDENTIAL_TYPE_PATTERN, true, false, false, true, + true); setupSkipDialog.show(mActivity.getSupportFragmentManager()); ShadowAlertDialog shadowAlertDialog = getShadowAlertDialog(); assertThat(shadowAlertDialog.getTitle().toString()).isEqualTo( - mActivity.getString(R.string.lock_screen_pattern_skip_biometrics_title)); + getSkipSetupTitle(CREDENTIAL_TYPE_PATTERN, hasFingerprint, hasFace)); assertThat(shadowAlertDialog.getMessage().toString()).isEqualTo( mActivity.getString(R.string.lock_screen_pattern_skip_biometrics_message)); }