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