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.annotation.Nullable; 20 import android.app.Activity; 21 import android.content.Intent; 22 import android.hardware.fingerprint.FingerprintManager; 23 import android.os.Bundle; 24 import android.os.CancellationSignal; 25 import android.os.Handler; 26 import android.os.UserHandle; 27 28 import com.android.internal.logging.MetricsProto.MetricsEvent; 29 import com.android.settings.ChooseLockSettingsHelper; 30 import com.android.settings.InstrumentedFragment; 31 32 /** 33 * Sidecar fragment to handle the state around fingerprint enrollment. 34 */ 35 public class FingerprintEnrollSidecar extends InstrumentedFragment { 36 37 private int mEnrollmentSteps = -1; 38 private int mEnrollmentRemaining = 0; 39 private Listener mListener; 40 private boolean mEnrolling; 41 private CancellationSignal mEnrollmentCancel; 42 private Handler mHandler = new Handler(); 43 private byte[] mToken; 44 private boolean mDone; 45 private int mUserId; 46 private FingerprintManager mFingerprintManager; 47 48 @Override 49 public void onCreate(@Nullable Bundle savedInstanceState) { 50 super.onCreate(savedInstanceState); 51 setRetainInstance(true); 52 } 53 54 @Override 55 public void onAttach(Activity activity) { 56 super.onAttach(activity); 57 mFingerprintManager = activity.getSystemService(FingerprintManager.class); 58 mToken = activity.getIntent().getByteArrayExtra( 59 ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN); 60 mUserId = activity.getIntent().getIntExtra(Intent.EXTRA_USER_ID, UserHandle.USER_NULL); 61 } 62 63 @Override 64 public void onStart() { 65 super.onStart(); 66 if (!mEnrolling) { 67 startEnrollment(); 68 } 69 } 70 71 @Override 72 public void onStop() { 73 super.onStop(); 74 if (!getActivity().isChangingConfigurations()) { 75 cancelEnrollment(); 76 } 77 } 78 79 private void startEnrollment() { 80 mHandler.removeCallbacks(mTimeoutRunnable); 81 mEnrollmentSteps = -1; 82 mEnrollmentCancel = new CancellationSignal(); 83 if (mUserId != UserHandle.USER_NULL) { 84 mFingerprintManager.setActiveUser(mUserId); 85 } 86 mFingerprintManager.enroll(mToken, mEnrollmentCancel, 87 0 /* flags */, mUserId, mEnrollmentCallback); 88 mEnrolling = true; 89 } 90 91 boolean cancelEnrollment() { 92 mHandler.removeCallbacks(mTimeoutRunnable); 93 if (mEnrolling) { 94 mEnrollmentCancel.cancel(); 95 mEnrolling = false; 96 mEnrollmentSteps = -1; 97 return true; 98 } 99 return false; 100 } 101 102 public void setListener(Listener listener) { 103 mListener = listener; 104 } 105 106 public int getEnrollmentSteps() { 107 return mEnrollmentSteps; 108 } 109 110 public int getEnrollmentRemaining() { 111 return mEnrollmentRemaining; 112 } 113 114 public boolean isDone() { 115 return mDone; 116 } 117 118 private FingerprintManager.EnrollmentCallback mEnrollmentCallback 119 = new FingerprintManager.EnrollmentCallback() { 120 121 @Override 122 public void onEnrollmentProgress(int remaining) { 123 if (mEnrollmentSteps == -1) { 124 mEnrollmentSteps = remaining; 125 } 126 mEnrollmentRemaining = remaining; 127 mDone = remaining == 0; 128 if (mListener != null) { 129 mListener.onEnrollmentProgressChange(mEnrollmentSteps, remaining); 130 } 131 } 132 133 @Override 134 public void onEnrollmentHelp(int helpMsgId, CharSequence helpString) { 135 if (mListener != null) { 136 mListener.onEnrollmentHelp(helpString); 137 } 138 } 139 140 @Override 141 public void onEnrollmentError(int errMsgId, CharSequence errString) { 142 if (mListener != null) { 143 mListener.onEnrollmentError(errMsgId, errString); 144 } 145 mEnrolling = false; 146 } 147 }; 148 149 private final Runnable mTimeoutRunnable = new Runnable() { 150 @Override 151 public void run() { 152 cancelEnrollment(); 153 } 154 }; 155 156 @Override 157 protected int getMetricsCategory() { 158 return MetricsEvent.FINGERPRINT_ENROLL_SIDECAR; 159 } 160 161 public interface Listener { 162 void onEnrollmentHelp(CharSequence helpString); 163 void onEnrollmentError(int errMsgId, CharSequence errString); 164 void onEnrollmentProgressChange(int steps, int remaining); 165 } 166 167 public boolean isEnrolling() { 168 return mEnrolling; 169 } 170 } 171