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