1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.settings.password; 18 19 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD; 20 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN; 21 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN; 22 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS; 23 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE; 24 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT; 25 import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_IS_SUW; 26 27 import android.app.Activity; 28 import android.app.AlertDialog; 29 import android.app.Dialog; 30 import android.app.settings.SettingsEnums; 31 import android.content.DialogInterface; 32 import android.os.Bundle; 33 import android.view.View; 34 import android.view.inputmethod.InputMethodManager; 35 36 import androidx.annotation.NonNull; 37 import androidx.annotation.StringRes; 38 import androidx.fragment.app.FragmentManager; 39 40 import com.android.internal.widget.LockPatternUtils; 41 import com.android.settings.R; 42 import com.android.settings.Utils; 43 import com.android.settings.biometrics.BiometricUtils; 44 import com.android.settings.core.instrumentation.InstrumentedDialogFragment; 45 46 public class SetupSkipDialog extends InstrumentedDialogFragment 47 implements DialogInterface.OnClickListener { 48 49 public static final String EXTRA_FRP_SUPPORTED = ":settings:frp_supported"; 50 51 private static final String ARG_FRP_SUPPORTED = "frp_supported"; 52 // The key indicates type of screen lock credential types(PIN/Pattern/Password) 53 private static final String ARG_LOCK_CREDENTIAL_TYPE = "lock_credential_type"; 54 // The key indicates type of lock screen setup is alphanumeric for password setup. 55 private static final String TAG_SKIP_DIALOG = "skip_dialog"; 56 public static final int RESULT_SKIP = Activity.RESULT_FIRST_USER + 10; 57 newInstance(@ockPatternUtils.CredentialType int credentialType, boolean isFrpSupported, boolean forFingerprint, boolean forFace, boolean forBiometrics, boolean isSuw)58 public static SetupSkipDialog newInstance(@LockPatternUtils.CredentialType int credentialType, 59 boolean isFrpSupported, boolean forFingerprint, boolean forFace, 60 boolean forBiometrics, boolean isSuw) { 61 SetupSkipDialog dialog = new SetupSkipDialog(); 62 Bundle args = new Bundle(); 63 args.putInt(ARG_LOCK_CREDENTIAL_TYPE, credentialType); 64 args.putBoolean(ARG_FRP_SUPPORTED, isFrpSupported); 65 args.putBoolean(EXTRA_KEY_FOR_FINGERPRINT, forFingerprint); 66 args.putBoolean(EXTRA_KEY_FOR_FACE, forFace); 67 args.putBoolean(EXTRA_KEY_FOR_BIOMETRICS, forBiometrics); 68 args.putBoolean(EXTRA_KEY_IS_SUW, isSuw); 69 dialog.setArguments(args); 70 return dialog; 71 } 72 73 @Override getMetricsCategory()74 public int getMetricsCategory() { 75 return SettingsEnums.DIALOG_FINGERPRINT_SKIP_SETUP; 76 } 77 78 @Override onCreateDialog(Bundle savedInstanceState)79 public Dialog onCreateDialog(Bundle savedInstanceState) { 80 return onCreateDialogBuilder().create(); 81 } 82 getBiometricsBuilder( @ockPatternUtils.CredentialType int credentialType, boolean isSuw, boolean hasFace, boolean hasFingerprint)83 private AlertDialog.Builder getBiometricsBuilder( 84 @LockPatternUtils.CredentialType int credentialType, boolean isSuw, boolean hasFace, 85 boolean hasFingerprint) { 86 final boolean isFaceSupported = hasFace && (!isSuw || BiometricUtils.isFaceSupportedInSuw( 87 getContext())); 88 final int msgResId; 89 final int screenLockResId; 90 switch (credentialType) { 91 case CREDENTIAL_TYPE_PATTERN: 92 screenLockResId = R.string.unlock_set_unlock_pattern_title; 93 msgResId = getPatternSkipMessageRes(hasFace && isFaceSupported, hasFingerprint); 94 break; 95 case CREDENTIAL_TYPE_PASSWORD: 96 screenLockResId = R.string.unlock_set_unlock_password_title; 97 msgResId = getPasswordSkipMessageRes(hasFace && isFaceSupported, hasFingerprint); 98 break; 99 case CREDENTIAL_TYPE_PIN: 100 default: 101 screenLockResId = R.string.unlock_set_unlock_pin_title; 102 msgResId = getPinSkipMessageRes(hasFace && isFaceSupported, hasFingerprint); 103 break; 104 } 105 return new AlertDialog.Builder(getContext()) 106 .setPositiveButton(R.string.skip_lock_screen_dialog_button_label, this) 107 .setNegativeButton(R.string.cancel_lock_screen_dialog_button_label, this) 108 .setTitle(getSkipSetupTitle(screenLockResId, hasFingerprint, 109 hasFace && isFaceSupported)) 110 .setMessage(msgResId); 111 } 112 113 @NonNull onCreateDialogBuilder()114 public AlertDialog.Builder onCreateDialogBuilder() { 115 Bundle args = getArguments(); 116 final boolean isSuw = args.getBoolean(EXTRA_KEY_IS_SUW); 117 final boolean forBiometrics = args.getBoolean(EXTRA_KEY_FOR_BIOMETRICS); 118 final boolean forFace = args.getBoolean(EXTRA_KEY_FOR_FACE); 119 final boolean forFingerprint = args.getBoolean(EXTRA_KEY_FOR_FINGERPRINT); 120 @LockPatternUtils.CredentialType 121 final int credentialType = args.getInt(ARG_LOCK_CREDENTIAL_TYPE); 122 123 if (forFace || forFingerprint || forBiometrics) { 124 final boolean hasFace = Utils.hasFaceHardware(getContext()); 125 final boolean hasFingerprint = Utils.hasFingerprintHardware(getContext()); 126 return getBiometricsBuilder(credentialType, isSuw, hasFace, hasFingerprint); 127 } 128 129 return new AlertDialog.Builder(getContext()) 130 .setPositiveButton(R.string.skip_anyway_button_label, this) 131 .setNegativeButton(R.string.go_back_button_label, this) 132 .setTitle(R.string.lock_screen_intro_skip_title) 133 .setMessage(args.getBoolean(ARG_FRP_SUPPORTED) ? 134 R.string.lock_screen_intro_skip_dialog_text_frp : 135 R.string.lock_screen_intro_skip_dialog_text); 136 } 137 138 @StringRes getPatternSkipMessageRes(boolean hasFace, boolean hasFingerprint)139 private int getPatternSkipMessageRes(boolean hasFace, boolean hasFingerprint) { 140 if (hasFace && hasFingerprint) { 141 return R.string.lock_screen_pattern_skip_biometrics_message; 142 } else if (hasFace) { 143 return R.string.lock_screen_pattern_skip_face_message; 144 } else if (hasFingerprint) { 145 return R.string.lock_screen_pattern_skip_fingerprint_message; 146 } else { 147 return R.string.lock_screen_pattern_skip_message; 148 } 149 } 150 151 @StringRes getPasswordSkipMessageRes(boolean hasFace, boolean hasFingerprint)152 private int getPasswordSkipMessageRes(boolean hasFace, boolean hasFingerprint) { 153 if (hasFace && hasFingerprint) { 154 return R.string.lock_screen_password_skip_biometrics_message; 155 } else if (hasFace) { 156 return R.string.lock_screen_password_skip_face_message; 157 } else if (hasFingerprint) { 158 return R.string.lock_screen_password_skip_fingerprint_message; 159 } else { 160 return R.string.lock_screen_password_skip_message; 161 } 162 } 163 164 @StringRes getPinSkipMessageRes(boolean hasFace, boolean hasFingerprint)165 private int getPinSkipMessageRes(boolean hasFace, boolean hasFingerprint) { 166 if (hasFace && hasFingerprint) { 167 return R.string.lock_screen_pin_skip_biometrics_message; 168 } else if (hasFace) { 169 return R.string.lock_screen_pin_skip_face_message; 170 } else if (hasFingerprint) { 171 return R.string.lock_screen_pin_skip_fingerprint_message; 172 } else { 173 return R.string.lock_screen_pin_skip_message; 174 } 175 } 176 getSkipSetupTitle(int screenTypeResId, boolean hasFingerprint, boolean hasFace)177 private String getSkipSetupTitle(int screenTypeResId, boolean hasFingerprint, 178 boolean hasFace) { 179 return getString(R.string.lock_screen_skip_setup_title, 180 BiometricUtils.getCombinedScreenLockOptions(getContext(), 181 getString(screenTypeResId), hasFingerprint, hasFace)); 182 } 183 184 @Override onClick(DialogInterface dialog, int button)185 public void onClick(DialogInterface dialog, int button) { 186 Activity activity = getActivity(); 187 switch (button) { 188 case DialogInterface.BUTTON_POSITIVE: 189 activity.setResult(RESULT_SKIP); 190 activity.finish(); 191 break; 192 case DialogInterface.BUTTON_NEGATIVE: 193 View view = activity.getCurrentFocus(); 194 if(view != null) { 195 view.requestFocus(); 196 InputMethodManager imm = (InputMethodManager) activity 197 .getSystemService(Activity.INPUT_METHOD_SERVICE); 198 imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT); 199 } 200 break; 201 } 202 } 203 show(FragmentManager manager)204 public void show(FragmentManager manager) { 205 show(manager, TAG_SKIP_DIALOG); 206 } 207 }