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 import com.google.android.material.dialog.MaterialAlertDialogBuilder; 47 public class SetupSkipDialog extends InstrumentedDialogFragment 48 implements DialogInterface.OnClickListener { 49 50 public static final String EXTRA_FRP_SUPPORTED = ":settings:frp_supported"; 51 52 private static final String ARG_FRP_SUPPORTED = "frp_supported"; 53 // The key indicates type of screen lock credential types(PIN/Pattern/Password) 54 private static final String ARG_LOCK_CREDENTIAL_TYPE = "lock_credential_type"; 55 // The key indicates type of lock screen setup is alphanumeric for password setup. 56 private static final String TAG_SKIP_DIALOG = "skip_dialog"; 57 public static final int RESULT_SKIP = Activity.RESULT_FIRST_USER + 10; 58 newInstance(@ockPatternUtils.CredentialType int credentialType, boolean isFrpSupported, boolean forFingerprint, boolean forFace, boolean forBiometrics, boolean isSuw)59 public static SetupSkipDialog newInstance(@LockPatternUtils.CredentialType int credentialType, 60 boolean isFrpSupported, boolean forFingerprint, boolean forFace, 61 boolean forBiometrics, boolean isSuw) { 62 SetupSkipDialog dialog = new SetupSkipDialog(); 63 Bundle args = new Bundle(); 64 args.putInt(ARG_LOCK_CREDENTIAL_TYPE, credentialType); 65 args.putBoolean(ARG_FRP_SUPPORTED, isFrpSupported); 66 args.putBoolean(EXTRA_KEY_FOR_FINGERPRINT, forFingerprint); 67 args.putBoolean(EXTRA_KEY_FOR_FACE, forFace); 68 args.putBoolean(EXTRA_KEY_FOR_BIOMETRICS, forBiometrics); 69 args.putBoolean(EXTRA_KEY_IS_SUW, isSuw); 70 dialog.setArguments(args); 71 return dialog; 72 } 73 74 @Override getMetricsCategory()75 public int getMetricsCategory() { 76 return SettingsEnums.DIALOG_FINGERPRINT_SKIP_SETUP; 77 } 78 79 @Override onCreateDialog(Bundle savedInstanceState)80 public Dialog onCreateDialog(Bundle savedInstanceState) { 81 if (BiometricUtils.isExpressiveStyle(getContext(), false)) { 82 final MaterialAlertDialogBuilder meterialBuilder = 83 (MaterialAlertDialogBuilder) onCreateDialogBuilder(); 84 return meterialBuilder.create(); 85 } else { 86 final AlertDialog.Builder alertDialogBuilder = 87 (AlertDialog.Builder) onCreateDialogBuilder(); 88 return alertDialogBuilder.create(); 89 } 90 } 91 92 @SuppressWarnings("TypeParameterUnusedInFormals") getBiometricsBuilder( @ockPatternUtils.CredentialType int credentialType, boolean isSuw, boolean hasFace, boolean hasFingerprint)93 private <T> T getBiometricsBuilder( 94 @LockPatternUtils.CredentialType int credentialType, boolean isSuw, boolean hasFace, 95 boolean hasFingerprint) { 96 final boolean isFaceSupported = hasFace && (!isSuw 97 || BiometricUtils.isFaceSupportedInSuw(getContext())); 98 final int msgResId; 99 final int screenLockResId; 100 switch (credentialType) { 101 case CREDENTIAL_TYPE_PATTERN: 102 screenLockResId = R.string.unlock_set_unlock_pattern_title; 103 msgResId = getPatternSkipMessageRes(hasFace && isFaceSupported, hasFingerprint); 104 break; 105 case CREDENTIAL_TYPE_PASSWORD: 106 screenLockResId = R.string.unlock_set_unlock_password_title; 107 msgResId = getPasswordSkipMessageRes(hasFace && isFaceSupported, hasFingerprint); 108 break; 109 case CREDENTIAL_TYPE_PIN: 110 default: 111 screenLockResId = R.string.unlock_set_unlock_pin_title; 112 msgResId = getPinSkipMessageRes(hasFace && isFaceSupported, hasFingerprint); 113 break; 114 } 115 116 if (BiometricUtils.isExpressiveStyle(getContext(), false)) { 117 return (T) new MaterialAlertDialogBuilder(getContext()) 118 .setPositiveButton(R.string.skip_lock_screen_dialog_button_label, this) 119 .setNegativeButton(R.string.cancel_lock_screen_dialog_button_label, this) 120 .setTitle(getSkipSetupTitle(screenLockResId, hasFingerprint, 121 hasFace && isFaceSupported)) 122 .setMessage(msgResId); 123 } else { 124 return (T) new AlertDialog.Builder(getContext()) 125 .setPositiveButton(R.string.skip_lock_screen_dialog_button_label, this) 126 .setNegativeButton(R.string.cancel_lock_screen_dialog_button_label, this) 127 .setTitle(getSkipSetupTitle(screenLockResId, hasFingerprint, 128 hasFace && isFaceSupported)) 129 .setMessage(msgResId); 130 } 131 } 132 133 @NonNull 134 @SuppressWarnings("TypeParameterUnusedInFormals") onCreateDialogBuilder()135 public <T> T onCreateDialogBuilder() { 136 Bundle args = getArguments(); 137 final boolean isSuw = args.getBoolean(EXTRA_KEY_IS_SUW); 138 final boolean forBiometrics = args.getBoolean(EXTRA_KEY_FOR_BIOMETRICS); 139 final boolean forFace = args.getBoolean(EXTRA_KEY_FOR_FACE); 140 final boolean forFingerprint = args.getBoolean(EXTRA_KEY_FOR_FINGERPRINT); 141 @LockPatternUtils.CredentialType 142 final int credentialType = args.getInt(ARG_LOCK_CREDENTIAL_TYPE); 143 144 if (forFace || forFingerprint || forBiometrics) { 145 final boolean hasFace = Utils.hasFaceHardware(getContext()); 146 final boolean hasFingerprint = Utils.hasFingerprintHardware(getContext()); 147 return getBiometricsBuilder(credentialType, isSuw, hasFace, hasFingerprint); 148 } 149 150 final int msg = args.getBoolean(ARG_FRP_SUPPORTED) 151 ? R.string.lock_screen_intro_skip_dialog_text_frp 152 : R.string.lock_screen_intro_skip_dialog_text; 153 if (BiometricUtils.isExpressiveStyle(getContext(), false)) { 154 return (T) new MaterialAlertDialogBuilder(getContext()) 155 .setPositiveButton(R.string.skip_anyway_button_label, this) 156 .setNegativeButton(R.string.go_back_button_label, this) 157 .setTitle(R.string.lock_screen_intro_skip_title) 158 .setMessage(msg); 159 160 } else { 161 return (T) new AlertDialog.Builder(getContext()) 162 .setPositiveButton(R.string.skip_anyway_button_label, this) 163 .setNegativeButton(R.string.go_back_button_label, this) 164 .setTitle(R.string.lock_screen_intro_skip_title) 165 .setMessage(msg); 166 } 167 } 168 169 @StringRes getPatternSkipMessageRes(boolean hasFace, boolean hasFingerprint)170 private int getPatternSkipMessageRes(boolean hasFace, boolean hasFingerprint) { 171 if (hasFace && hasFingerprint) { 172 return R.string.lock_screen_pattern_skip_biometrics_message; 173 } else if (hasFace) { 174 return R.string.lock_screen_pattern_skip_face_message; 175 } else if (hasFingerprint) { 176 return R.string.lock_screen_pattern_skip_fingerprint_message; 177 } else { 178 return R.string.lock_screen_pattern_skip_message; 179 } 180 } 181 182 @StringRes getPasswordSkipMessageRes(boolean hasFace, boolean hasFingerprint)183 private int getPasswordSkipMessageRes(boolean hasFace, boolean hasFingerprint) { 184 if (hasFace && hasFingerprint) { 185 return R.string.lock_screen_password_skip_biometrics_message; 186 } else if (hasFace) { 187 return R.string.lock_screen_password_skip_face_message; 188 } else if (hasFingerprint) { 189 return R.string.lock_screen_password_skip_fingerprint_message; 190 } else { 191 return R.string.lock_screen_password_skip_message; 192 } 193 } 194 195 @StringRes getPinSkipMessageRes(boolean hasFace, boolean hasFingerprint)196 private int getPinSkipMessageRes(boolean hasFace, boolean hasFingerprint) { 197 if (hasFace && hasFingerprint) { 198 return R.string.lock_screen_pin_skip_biometrics_message; 199 } else if (hasFace) { 200 return R.string.lock_screen_pin_skip_face_message; 201 } else if (hasFingerprint) { 202 return R.string.lock_screen_pin_skip_fingerprint_message; 203 } else { 204 return R.string.lock_screen_pin_skip_message; 205 } 206 } 207 getSkipSetupTitle(int screenTypeResId, boolean hasFingerprint, boolean hasFace)208 private String getSkipSetupTitle(int screenTypeResId, boolean hasFingerprint, 209 boolean hasFace) { 210 return getString(R.string.lock_screen_skip_setup_title, 211 BiometricUtils.getCombinedScreenLockOptions(getContext(), 212 getString(screenTypeResId), hasFingerprint, hasFace)); 213 } 214 215 @Override onClick(DialogInterface dialog, int button)216 public void onClick(DialogInterface dialog, int button) { 217 Activity activity = getActivity(); 218 switch (button) { 219 case DialogInterface.BUTTON_POSITIVE: 220 activity.setResult(RESULT_SKIP); 221 activity.finish(); 222 break; 223 case DialogInterface.BUTTON_NEGATIVE: 224 View view = activity.getCurrentFocus(); 225 if(view != null) { 226 view.requestFocus(); 227 InputMethodManager imm = (InputMethodManager) activity 228 .getSystemService(Activity.INPUT_METHOD_SERVICE); 229 imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT); 230 } 231 break; 232 } 233 } 234 show(FragmentManager manager)235 public void show(FragmentManager manager) { 236 show(manager, TAG_SKIP_DIALOG); 237 } 238 }