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