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 17package com.android.settings.fingerprint; 18 19import android.content.Intent; 20import android.hardware.fingerprint.FingerprintManager; 21import android.os.Bundle; 22import android.os.UserHandle; 23 24import com.android.internal.logging.MetricsProto.MetricsEvent; 25import com.android.settings.ChooseLockSettingsHelper; 26import com.android.settings.R; 27import com.android.settings.fingerprint.FingerprintEnrollSidecar.Listener; 28 29/** 30 * Activity explaining the fingerprint sensor location for fingerprint enrollment. 31 */ 32public class FingerprintEnrollFindSensor extends FingerprintEnrollBase { 33 34 private static final int CONFIRM_REQUEST = 1; 35 private static final int ENROLLING = 2; 36 public static final String EXTRA_KEY_LAUNCHED_CONFIRM = "launched_confirm_lock"; 37 38 private FingerprintFindSensorAnimation mAnimation; 39 private boolean mLaunchedConfirmLock; 40 private FingerprintEnrollSidecar mSidecar; 41 private boolean mNextClicked; 42 43 @Override 44 protected void onCreate(Bundle savedInstanceState) { 45 super.onCreate(savedInstanceState); 46 setContentView(getContentView()); 47 setHeaderText(R.string.security_settings_fingerprint_enroll_find_sensor_title); 48 if (savedInstanceState != null) { 49 mLaunchedConfirmLock = savedInstanceState.getBoolean(EXTRA_KEY_LAUNCHED_CONFIRM); 50 mToken = savedInstanceState.getByteArray( 51 ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN); 52 } 53 if (mToken == null && !mLaunchedConfirmLock) { 54 launchConfirmLock(); 55 } else if (mToken != null) { 56 startLookingForFingerprint(); // already confirmed, so start looking for fingerprint 57 } 58 mAnimation = (FingerprintFindSensorAnimation) findViewById( 59 R.id.fingerprint_sensor_location_animation); 60 } 61 62 protected int getContentView() { 63 return R.layout.fingerprint_enroll_find_sensor; 64 } 65 66 @Override 67 protected void onStart() { 68 super.onStart(); 69 mAnimation.startAnimation(); 70 } 71 72 private void startLookingForFingerprint() { 73 mSidecar = (FingerprintEnrollSidecar) getFragmentManager().findFragmentByTag( 74 FingerprintEnrollEnrolling.TAG_SIDECAR); 75 if (mSidecar == null) { 76 mSidecar = new FingerprintEnrollSidecar(); 77 getFragmentManager().beginTransaction() 78 .add(mSidecar, FingerprintEnrollEnrolling.TAG_SIDECAR).commit(); 79 } 80 mSidecar.setListener(new Listener() { 81 @Override 82 public void onEnrollmentProgressChange(int steps, int remaining) { 83 mNextClicked = true; 84 if (!mSidecar.cancelEnrollment()) { 85 proceedToEnrolling(); 86 } 87 } 88 89 @Override 90 public void onEnrollmentHelp(CharSequence helpString) { 91 } 92 93 @Override 94 public void onEnrollmentError(int errMsgId, CharSequence errString) { 95 if (mNextClicked && errMsgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED) { 96 mNextClicked = false; 97 proceedToEnrolling(); 98 } 99 } 100 }); 101 } 102 103 @Override 104 protected void onStop() { 105 super.onStop(); 106 mAnimation.pauseAnimation(); 107 } 108 109 @Override 110 protected void onDestroy() { 111 super.onDestroy(); 112 mAnimation.stopAnimation(); 113 } 114 115 @Override 116 public void onSaveInstanceState(Bundle outState) { 117 super.onSaveInstanceState(outState); 118 outState.putBoolean(EXTRA_KEY_LAUNCHED_CONFIRM, mLaunchedConfirmLock); 119 outState.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken); 120 } 121 122 @Override 123 protected void onNextButtonClick() { 124 mNextClicked = true; 125 if (mSidecar == null || (mSidecar != null && !mSidecar.cancelEnrollment())) { 126 proceedToEnrolling(); 127 } 128 } 129 130 private void proceedToEnrolling() { 131 getFragmentManager().beginTransaction().remove(mSidecar).commit(); 132 mSidecar = null; 133 startActivityForResult(getEnrollingIntent(), ENROLLING); 134 } 135 136 @Override 137 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 138 if (requestCode == CONFIRM_REQUEST) { 139 if (resultCode == RESULT_OK) { 140 mToken = data.getByteArrayExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN); 141 overridePendingTransition(R.anim.suw_slide_next_in, R.anim.suw_slide_next_out); 142 getIntent().putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken); 143 startLookingForFingerprint(); 144 } else { 145 finish(); 146 } 147 } else if (requestCode == ENROLLING) { 148 if (resultCode == RESULT_FINISHED) { 149 setResult(RESULT_FINISHED); 150 finish(); 151 } else if (resultCode == RESULT_SKIP) { 152 setResult(RESULT_SKIP); 153 finish(); 154 } else if (resultCode == RESULT_TIMEOUT) { 155 setResult(RESULT_TIMEOUT); 156 finish(); 157 } else { 158 FingerprintManager fpm = getSystemService(FingerprintManager.class); 159 int enrolled = fpm.getEnrolledFingerprints().size(); 160 int max = getResources().getInteger( 161 com.android.internal.R.integer.config_fingerprintMaxTemplatesPerUser); 162 if (enrolled >= max) { 163 finish(); 164 } else { 165 // We came back from enrolling but it wasn't completed, start again. 166 startLookingForFingerprint(); 167 } 168 } 169 } else { 170 super.onActivityResult(requestCode, resultCode, data); 171 } 172 } 173 174 private void launchConfirmLock() { 175 long challenge = getSystemService(FingerprintManager.class).preEnroll(); 176 ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper(this); 177 boolean launchedConfirmationActivity = false; 178 if (mUserId == UserHandle.USER_NULL) { 179 launchedConfirmationActivity = helper.launchConfirmationActivity(CONFIRM_REQUEST, 180 getString(R.string.security_settings_fingerprint_preference_title), 181 null, null, challenge); 182 } else { 183 launchedConfirmationActivity = helper.launchConfirmationActivity(CONFIRM_REQUEST, 184 getString(R.string.security_settings_fingerprint_preference_title), 185 null, null, challenge, mUserId); 186 } 187 if (!launchedConfirmationActivity) { 188 // This shouldn't happen, as we should only end up at this step if a lock thingy is 189 // already set. 190 finish(); 191 } else { 192 mLaunchedConfirmLock = true; 193 } 194 } 195 196 @Override 197 protected int getMetricsCategory() { 198 return MetricsEvent.FINGERPRINT_FIND_SENSOR; 199 } 200} 201