1 /* 2 * Copyright (C) 2015 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.fingerprint; 18 19 import android.app.admin.DevicePolicyManager; 20 import android.content.ActivityNotFoundException; 21 import android.content.Intent; 22 import android.hardware.fingerprint.FingerprintManager; 23 import android.os.Bundle; 24 import android.os.UserHandle; 25 import android.os.UserManager; 26 import android.util.Log; 27 import android.view.View; 28 import android.widget.Button; 29 import android.widget.TextView; 30 31 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 32 import com.android.settings.R; 33 import com.android.settings.Utils; 34 import com.android.settings.password.ChooseLockGeneric; 35 import com.android.settings.password.ChooseLockSettingsHelper; 36 import com.android.settingslib.HelpUtils; 37 import com.android.settingslib.RestrictedLockUtils; 38 import com.android.setupwizardlib.span.LinkSpan; 39 40 /** 41 * Onboarding activity for fingerprint enrollment. 42 */ 43 public class FingerprintEnrollIntroduction extends FingerprintEnrollBase 44 implements View.OnClickListener, LinkSpan.OnClickListener { 45 46 private static final String TAG = "FingerprintIntro"; 47 48 protected static final int CHOOSE_LOCK_GENERIC_REQUEST = 1; 49 protected static final int FINGERPRINT_FIND_SENSOR_REQUEST = 2; 50 protected static final int LEARN_MORE_REQUEST = 3; 51 52 private UserManager mUserManager; 53 private boolean mHasPassword; 54 private boolean mFingerprintUnlockDisabledByAdmin; 55 private TextView mErrorText; 56 57 @Override 58 protected void onCreate(Bundle savedInstanceState) { 59 super.onCreate(savedInstanceState); 60 mFingerprintUnlockDisabledByAdmin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled( 61 this, DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT, mUserId) != null; 62 63 setContentView(R.layout.fingerprint_enroll_introduction); 64 if (mFingerprintUnlockDisabledByAdmin) { 65 setHeaderText(R.string 66 .security_settings_fingerprint_enroll_introduction_title_unlock_disabled); 67 } else { 68 setHeaderText(R.string.security_settings_fingerprint_enroll_introduction_title); 69 } 70 71 Button cancelButton = (Button) findViewById(R.id.fingerprint_cancel_button); 72 cancelButton.setOnClickListener(this); 73 74 mErrorText = (TextView) findViewById(R.id.error_text); 75 76 mUserManager = UserManager.get(this); 77 updatePasswordQuality(); 78 } 79 80 @Override 81 protected void onResume() { 82 super.onResume(); 83 84 final FingerprintManager fingerprintManager = Utils.getFingerprintManagerOrNull(this); 85 int errorMsg = 0; 86 if (fingerprintManager != null) { 87 final int max = getResources().getInteger( 88 com.android.internal.R.integer.config_fingerprintMaxTemplatesPerUser); 89 final int numEnrolledFingerprints = 90 fingerprintManager.getEnrolledFingerprints(mUserId).size(); 91 if (numEnrolledFingerprints >= max) { 92 errorMsg = R.string.fingerprint_intro_error_max; 93 } 94 } else { 95 errorMsg = R.string.fingerprint_intro_error_unknown; 96 } 97 if (errorMsg == 0) { 98 mErrorText.setText(null); 99 getNextButton().setVisibility(View.VISIBLE); 100 } else { 101 mErrorText.setText(errorMsg); 102 getNextButton().setVisibility(View.GONE); 103 } 104 } 105 106 private void updatePasswordQuality() { 107 final int passwordQuality = new ChooseLockSettingsHelper(this).utils() 108 .getActivePasswordQuality(mUserManager.getCredentialOwnerProfile(mUserId)); 109 mHasPassword = passwordQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; 110 } 111 112 @Override 113 protected Button getNextButton() { 114 return (Button) findViewById(R.id.fingerprint_next_button); 115 } 116 117 @Override 118 protected void onNextButtonClick() { 119 if (!mHasPassword) { 120 // No fingerprints registered, launch into enrollment wizard. 121 launchChooseLock(); 122 } else { 123 // Lock thingy is already set up, launch directly into find sensor step from wizard. 124 launchFindSensor(null); 125 } 126 } 127 128 private void launchChooseLock() { 129 Intent intent = getChooseLockIntent(); 130 long challenge = Utils.getFingerprintManagerOrNull(this).preEnroll(); 131 intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY, 132 DevicePolicyManager.PASSWORD_QUALITY_SOMETHING); 133 intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, true); 134 intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true); 135 intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge); 136 intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, true); 137 if (mUserId != UserHandle.USER_NULL) { 138 intent.putExtra(Intent.EXTRA_USER_ID, mUserId); 139 } 140 startActivityForResult(intent, CHOOSE_LOCK_GENERIC_REQUEST); 141 } 142 143 private void launchFindSensor(byte[] token) { 144 Intent intent = getFindSensorIntent(); 145 if (token != null) { 146 intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token); 147 } 148 if (mUserId != UserHandle.USER_NULL) { 149 intent.putExtra(Intent.EXTRA_USER_ID, mUserId); 150 } 151 startActivityForResult(intent, FINGERPRINT_FIND_SENSOR_REQUEST); 152 } 153 154 protected Intent getChooseLockIntent() { 155 return new Intent(this, ChooseLockGeneric.class); 156 } 157 158 protected Intent getFindSensorIntent() { 159 return new Intent(this, FingerprintEnrollFindSensor.class); 160 } 161 162 @Override 163 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 164 final boolean isResultFinished = resultCode == RESULT_FINISHED; 165 if (requestCode == FINGERPRINT_FIND_SENSOR_REQUEST) { 166 if (isResultFinished || resultCode == RESULT_SKIP) { 167 final int result = isResultFinished ? RESULT_OK : RESULT_SKIP; 168 setResult(result, data); 169 finish(); 170 return; 171 } 172 } else if (requestCode == CHOOSE_LOCK_GENERIC_REQUEST) { 173 if (isResultFinished) { 174 updatePasswordQuality(); 175 byte[] token = data.getByteArrayExtra( 176 ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN); 177 launchFindSensor(token); 178 return; 179 } 180 } else if (requestCode == LEARN_MORE_REQUEST) { 181 overridePendingTransition(R.anim.suw_slide_back_in, R.anim.suw_slide_back_out); 182 } 183 super.onActivityResult(requestCode, resultCode, data); 184 } 185 186 @Override 187 public void onClick(View v) { 188 if (v.getId() == R.id.fingerprint_cancel_button) { 189 onCancelButtonClick(); 190 } else { 191 super.onClick(v); 192 } 193 } 194 195 @Override 196 public int getMetricsCategory() { 197 return MetricsEvent.FINGERPRINT_ENROLL_INTRO; 198 } 199 200 protected void onCancelButtonClick() { 201 finish(); 202 } 203 204 @Override 205 protected void initViews() { 206 super.initViews(); 207 208 TextView description = (TextView) findViewById(R.id.description_text); 209 if (mFingerprintUnlockDisabledByAdmin) { 210 description.setText(R.string 211 .security_settings_fingerprint_enroll_introduction_message_unlock_disabled); 212 } 213 } 214 215 @Override 216 public void onClick(LinkSpan span) { 217 if ("url".equals(span.getId())) { 218 String url = getString(R.string.help_url_fingerprint); 219 Intent intent = HelpUtils.getHelpIntent(this, url, getClass().getName()); 220 if (intent == null) { 221 Log.w(TAG, "Null help intent."); 222 return; 223 } 224 try { 225 // This needs to be startActivityForResult even though we do not care about the 226 // actual result because the help app needs to know about who invoked it. 227 startActivityForResult(intent, LEARN_MORE_REQUEST); 228 } catch (ActivityNotFoundException e) { 229 Log.w(TAG, "Activity was not found for intent, " + e); 230 } 231 } 232 } 233 } 234