blob: 6e29989b7744a14f0e026df5b8a8f40415ae44b6 [file] [log] [blame]
Jim Miller08fa40c2014-04-29 18:18:47 -07001/**
2 * Copyright (C) 2014 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
Jim Millerebbf2052015-03-31 17:24:34 -070017package android.hardware.fingerprint;
Jim Miller08fa40c2014-04-29 18:18:47 -070018
Jim Millerce7eb6d2015-04-03 19:29:13 -070019import android.annotation.NonNull;
20import android.annotation.Nullable;
Jim Millerf501b582015-06-03 16:36:31 -070021import android.annotation.RequiresPermission;
Jim Miller08fa40c2014-04-29 18:18:47 -070022import android.app.ActivityManagerNative;
Jim Miller08fa40c2014-04-29 18:18:47 -070023import android.content.Context;
Jim Millera75961472014-06-06 15:00:49 -070024import android.os.Binder;
Jim Miller9f0753f2015-03-23 23:59:22 -070025import android.os.CancellationSignal;
Jim Millerce7eb6d2015-04-03 19:29:13 -070026import android.os.CancellationSignal.OnCancelListener;
Jim Miller08fa40c2014-04-29 18:18:47 -070027import android.os.Handler;
28import android.os.IBinder;
Jim Millerf501b582015-06-03 16:36:31 -070029import android.os.Looper;
Jim Miller08fa40c2014-04-29 18:18:47 -070030import android.os.RemoteException;
31import android.os.UserHandle;
Alex Klyubindcdaf872015-05-13 15:57:09 -070032import android.security.keystore.AndroidKeyStoreProvider;
Jim Miller08fa40c2014-04-29 18:18:47 -070033import android.util.Log;
Jim Millera75961472014-06-06 15:00:49 -070034import android.util.Slog;
Jim Miller08fa40c2014-04-29 18:18:47 -070035
Jim Miller9f0753f2015-03-23 23:59:22 -070036import java.security.Signature;
Jim Millerba67aee2015-02-20 16:21:26 -080037import java.util.List;
38
Jim Miller9f0753f2015-03-23 23:59:22 -070039import javax.crypto.Cipher;
Jim Millerb62dc822015-04-28 20:05:53 -070040import javax.crypto.Mac;
Jim Miller9f0753f2015-03-23 23:59:22 -070041
Jim Millerf501b582015-06-03 16:36:31 -070042import static android.Manifest.permission.USE_FINGERPRINT;
43import static android.Manifest.permission.MANAGE_FINGERPRINT;
44
Jim Miller08fa40c2014-04-29 18:18:47 -070045/**
46 * A class that coordinates access to the fingerprint hardware.
Jim Millerce7eb6d2015-04-03 19:29:13 -070047 * <p>
48 * Use {@link android.content.Context#getSystemService(java.lang.String)}
49 * with argument {@link android.content.Context#FINGERPRINT_SERVICE} to get
50 * an instance of this class.
Jim Miller08fa40c2014-04-29 18:18:47 -070051 */
52
53public class FingerprintManager {
54 private static final String TAG = "FingerprintManager";
Jim Millerd08c2ac2014-05-14 16:30:38 -070055 private static final boolean DEBUG = true;
Jim Miller08fa40c2014-04-29 18:18:47 -070056 private static final int MSG_ENROLL_RESULT = 100;
Jim Millera75961472014-06-06 15:00:49 -070057 private static final int MSG_ACQUIRED = 101;
Jim Millerf501b582015-06-03 16:36:31 -070058 private static final int MSG_AUTHENTICATION_SUCCEEDED = 102;
59 private static final int MSG_AUTHENTICATION_FAILED = 103;
60 private static final int MSG_ERROR = 104;
61 private static final int MSG_REMOVED = 105;
Jim Miller08fa40c2014-04-29 18:18:47 -070062
Jim Millerce7eb6d2015-04-03 19:29:13 -070063 //
64 // Error messages from fingerprint hardware during initilization, enrollment, authentication or
65 // removal. Must agree with the list in fingerprint.h
66 //
Jim Miller08fa40c2014-04-29 18:18:47 -070067
Jim Millerce7eb6d2015-04-03 19:29:13 -070068 /**
69 * The hardware is unavailable. Try again later.
70 */
Jim Miller08fa40c2014-04-29 18:18:47 -070071 public static final int FINGERPRINT_ERROR_HW_UNAVAILABLE = 1;
Jim Millerce7eb6d2015-04-03 19:29:13 -070072
73 /**
74 * Error state returned when the sensor was unable to process the current image.
75 */
Jim Millera75961472014-06-06 15:00:49 -070076 public static final int FINGERPRINT_ERROR_UNABLE_TO_PROCESS = 2;
Jim Millerce7eb6d2015-04-03 19:29:13 -070077
78 /**
79 * Error state returned when the current request has been running too long. This is intended to
80 * prevent programs from waiting for the fingerprint sensor indefinitely. The timeout is
81 * platform and sensor-specific, but is generally on the order of 30 seconds.
82 */
Jim Miller08fa40c2014-04-29 18:18:47 -070083 public static final int FINGERPRINT_ERROR_TIMEOUT = 3;
Jim Millerce7eb6d2015-04-03 19:29:13 -070084
85 /**
86 * Error state returned for operations like enrollment; the operation cannot be completed
87 * because there's not enough storage remaining to complete the operation.
88 */
Jim Miller08fa40c2014-04-29 18:18:47 -070089 public static final int FINGERPRINT_ERROR_NO_SPACE = 4;
Jim Millerce7eb6d2015-04-03 19:29:13 -070090
91 /**
92 * The operation was canceled because the fingerprint sensor is unavailable. For example,
93 * this may happen when the user is switched, the device is locked or another pending operation
94 * prevents or disables it.
95 */
Jim Miller9f0753f2015-03-23 23:59:22 -070096 public static final int FINGERPRINT_ERROR_CANCELED = 5;
Jim Millerce7eb6d2015-04-03 19:29:13 -070097
98 /**
99 * The {@link FingerprintManager#remove(Fingerprint, RemovalCallback)} call failed. Typically
100 * this will happen when the provided fingerprint id was incorrect.
101 *
102 * @hide
103 */
104 public static final int FINGERPRINT_ERROR_UNABLE_TO_REMOVE = 6;
105
Jim Millerfe6439f2015-04-11 18:07:57 -0700106 /**
107 * The operation was canceled because the API is locked out due to too many attempts.
108 */
109 public static final int FINGERPRINT_ERROR_LOCKOUT = 7;
110
Jim Millerce7eb6d2015-04-03 19:29:13 -0700111 /**
112 * Hardware vendors may extend this list if there are conditions that do not fall under one of
113 * the above categories. Vendors are responsible for providing error strings for these errors.
Jim Millerf501b582015-06-03 16:36:31 -0700114 * @hide
Jim Millerce7eb6d2015-04-03 19:29:13 -0700115 */
Jim Miller9f0753f2015-03-23 23:59:22 -0700116 public static final int FINGERPRINT_ERROR_VENDOR_BASE = 1000;
Jim Miller08fa40c2014-04-29 18:18:47 -0700117
Jim Millerce7eb6d2015-04-03 19:29:13 -0700118 //
119 // Image acquisition messages. Must agree with those in fingerprint.h
120 //
121
122 /**
123 * The image acquired was good.
124 */
Jim Millera75961472014-06-06 15:00:49 -0700125 public static final int FINGERPRINT_ACQUIRED_GOOD = 0;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700126
127 /**
128 * Only a partial fingerprint image was detected. During enrollment, the user should be
129 * informed on what needs to happen to resolve this problem, e.g. "press firmly on sensor."
130 */
Jim Millera75961472014-06-06 15:00:49 -0700131 public static final int FINGERPRINT_ACQUIRED_PARTIAL = 1;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700132
133 /**
134 * The fingerprint image was too noisy to process due to a detected condition (i.e. dry skin) or
135 * a possibly dirty sensor (See {@link #FINGERPRINT_ACQUIRED_IMAGER_DIRTY}).
136 */
Jim Millera75961472014-06-06 15:00:49 -0700137 public static final int FINGERPRINT_ACQUIRED_INSUFFICIENT = 2;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700138
139 /**
140 * The fingerprint image was too noisy due to suspected or detected dirt on the sensor.
141 * For example, it's reasonable return this after multiple
142 * {@link #FINGERPRINT_ACQUIRED_INSUFFICIENT} or actual detection of dirt on the sensor
143 * (stuck pixels, swaths, etc.). The user is expected to take action to clean the sensor
144 * when this is returned.
145 */
Jim Miller9f0753f2015-03-23 23:59:22 -0700146 public static final int FINGERPRINT_ACQUIRED_IMAGER_DIRTY = 3;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700147
148 /**
149 * The fingerprint image was unreadable due to lack of motion. This is most appropriate for
150 * linear array sensors that require a swipe motion.
151 */
Jim Miller9f0753f2015-03-23 23:59:22 -0700152 public static final int FINGERPRINT_ACQUIRED_TOO_SLOW = 4;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700153
154 /**
155 * The fingerprint image was incomplete due to quick motion. While mostly appropriate for
156 * linear array sensors, this could also happen if the finger was moved during acquisition.
157 * The user should be asked to move the finger slower (linear) or leave the finger on the sensor
158 * longer.
159 */
Jim Miller9f0753f2015-03-23 23:59:22 -0700160 public static final int FINGERPRINT_ACQUIRED_TOO_FAST = 5;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700161
162 /**
163 * Hardware vendors may extend this list if there are conditions that do not fall under one of
164 * the above categories. Vendors are responsible for providing error strings for these errors.
Jim Millerf501b582015-06-03 16:36:31 -0700165 * @hide
Jim Millerce7eb6d2015-04-03 19:29:13 -0700166 */
Jim Miller9f0753f2015-03-23 23:59:22 -0700167 public static final int FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
Jim Millera75961472014-06-06 15:00:49 -0700168
Jim Miller08fa40c2014-04-29 18:18:47 -0700169 private IFingerprintService mService;
Jim Millerd08c2ac2014-05-14 16:30:38 -0700170 private Context mContext;
Jim Millera75961472014-06-06 15:00:49 -0700171 private IBinder mToken = new Binder();
Jim Miller9f0753f2015-03-23 23:59:22 -0700172 private AuthenticationCallback mAuthenticationCallback;
173 private EnrollmentCallback mEnrollmentCallback;
174 private RemovalCallback mRemovalCallback;
175 private CryptoObject mCryptoObject;
176 private Fingerprint mRemovalFingerprint;
Jim Millerf501b582015-06-03 16:36:31 -0700177 private Handler mHandler;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700178
179 private class OnEnrollCancelListener implements OnCancelListener {
Jim Millerce7eb6d2015-04-03 19:29:13 -0700180 @Override
181 public void onCancel() {
Jim Millerfe6439f2015-04-11 18:07:57 -0700182 cancelEnrollment();
Jim Millerce7eb6d2015-04-03 19:29:13 -0700183 }
184 }
185
186 private class OnAuthenticationCancelListener implements OnCancelListener {
187 private CryptoObject mCrypto;
188
189 public OnAuthenticationCancelListener(CryptoObject crypto) {
190 mCrypto = crypto;
191 }
192
193 @Override
194 public void onCancel() {
195 cancelAuthentication(mCrypto);
196 }
197 }
Jim Miller9f0753f2015-03-23 23:59:22 -0700198
199 /**
Jim Millerce7eb6d2015-04-03 19:29:13 -0700200 * A wrapper class for the crypto objects supported by FingerprintManager. Currently the
Jim Millerb62dc822015-04-28 20:05:53 -0700201 * framework supports {@link Signature}, {@link Cipher} and {@link Mac} objects.
Jim Miller9f0753f2015-03-23 23:59:22 -0700202 */
Jim Millerf501b582015-06-03 16:36:31 -0700203 public static final class CryptoObject {
Jim Millerce7eb6d2015-04-03 19:29:13 -0700204
Jim Millerb62dc822015-04-28 20:05:53 -0700205 public CryptoObject(@NonNull Signature signature) {
Jim Millerf501b582015-06-03 16:36:31 -0700206 mCrypto = signature;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700207 }
208
Jim Millerb62dc822015-04-28 20:05:53 -0700209 public CryptoObject(@NonNull Cipher cipher) {
Jim Millerf501b582015-06-03 16:36:31 -0700210 mCrypto = cipher;
Jim Millerb62dc822015-04-28 20:05:53 -0700211 }
212
213 public CryptoObject(@NonNull Mac mac) {
Jim Millerf501b582015-06-03 16:36:31 -0700214 mCrypto = mac;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700215 }
216
217 /**
218 * Get {@link Signature} object.
219 * @return {@link Signature} object or null if this doesn't contain one.
220 */
Jim Millerf501b582015-06-03 16:36:31 -0700221 public Signature getSignature() {
222 return mCrypto instanceof Signature ? (Signature) mCrypto : null;
223 }
Jim Millerce7eb6d2015-04-03 19:29:13 -0700224
225 /**
226 * Get {@link Cipher} object.
227 * @return {@link Cipher} object or null if this doesn't contain one.
228 */
Jim Millerf501b582015-06-03 16:36:31 -0700229 public Cipher getCipher() {
230 return mCrypto instanceof Cipher ? (Cipher) mCrypto : null;
231 }
Jim Millerce7eb6d2015-04-03 19:29:13 -0700232
233 /**
Jim Millerb62dc822015-04-28 20:05:53 -0700234 * Get {@link Mac} object.
235 * @return {@link Mac} object or null if this doesn't contain one.
236 */
Jim Millerf501b582015-06-03 16:36:31 -0700237 public Mac getMac() {
238 return mCrypto instanceof Mac ? (Mac) mCrypto : null;
239 }
Jim Millerb62dc822015-04-28 20:05:53 -0700240
241 /**
Jim Millerce7eb6d2015-04-03 19:29:13 -0700242 * @hide
243 * @return the opId associated with this object or 0 if none
244 */
245 public long getOpId() {
Jim Millerf501b582015-06-03 16:36:31 -0700246 return mCrypto != null ?
247 AndroidKeyStoreProvider.getKeyStoreOperationHandle(mCrypto) : 0;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700248 }
249
Jim Millerf501b582015-06-03 16:36:31 -0700250 private final Object mCrypto;
Jim Miller9f0753f2015-03-23 23:59:22 -0700251 };
252
253 /**
254 * Container for callback data from {@link FingerprintManager#authenticate(CryptoObject,
Jim Millerf501b582015-06-03 16:36:31 -0700255 * CancellationSignal, int, AuthenticationCallback, Handler)}.
Jim Miller9f0753f2015-03-23 23:59:22 -0700256 */
Jim Miller748bc362015-07-08 19:02:28 -0700257 public static class AuthenticationResult {
Jim Miller9f0753f2015-03-23 23:59:22 -0700258 private Fingerprint mFingerprint;
259 private CryptoObject mCryptoObject;
260
Jim Millerf501b582015-06-03 16:36:31 -0700261 /**
262 * Authentication result
263 *
264 * @param crypto the crypto object
265 * @param fingerprint the recognized fingerprint data, if allowed.
266 * @hide
267 */
Jim Miller9f0753f2015-03-23 23:59:22 -0700268 public AuthenticationResult(CryptoObject crypto, Fingerprint fingerprint) {
269 mCryptoObject = crypto;
270 mFingerprint = fingerprint;
271 }
272
273 /**
274 * Obtain the crypto object associated with this transaction
275 * @return crypto object provided to {@link FingerprintManager#authenticate(CryptoObject,
Jim Millerf501b582015-06-03 16:36:31 -0700276 * CancellationSignal, int, AuthenticationCallback, Handler)}.
Jim Miller9f0753f2015-03-23 23:59:22 -0700277 */
278 public CryptoObject getCryptoObject() { return mCryptoObject; }
279
280 /**
Jim Millerce7eb6d2015-04-03 19:29:13 -0700281 * Obtain the Fingerprint associated with this operation. Applications are strongly
282 * discouraged from associating specific fingers with specific applications or operations.
283 *
Jim Miller9f0753f2015-03-23 23:59:22 -0700284 * @hide
285 */
286 public Fingerprint getFingerprint() { return mFingerprint; }
287 };
288
289 /**
290 * Callback structure provided to {@link FingerprintManager#authenticate(CryptoObject,
Jim Millerf501b582015-06-03 16:36:31 -0700291 * CancellationSignal, int, AuthenticationCallback, Handler)}. Users of {@link
Jim Millerce7eb6d2015-04-03 19:29:13 -0700292 * FingerprintManager#authenticate(CryptoObject, CancellationSignal,
Jim Millerf501b582015-06-03 16:36:31 -0700293 * int, AuthenticationCallback, Handler) } must provide an implementation of this for listening to
Jim Millerce7eb6d2015-04-03 19:29:13 -0700294 * fingerprint events.
Jim Miller9f0753f2015-03-23 23:59:22 -0700295 */
296 public static abstract class AuthenticationCallback {
297 /**
298 * Called when an unrecoverable error has been encountered and the operation is complete.
299 * No further callbacks will be made on this object.
Jim Millerf501b582015-06-03 16:36:31 -0700300 * @param errorCode An integer identifying the error message
Jim Millerce7eb6d2015-04-03 19:29:13 -0700301 * @param errString A human-readable error string that can be shown in UI
Jim Miller9f0753f2015-03-23 23:59:22 -0700302 */
Jim Millerf501b582015-06-03 16:36:31 -0700303 public void onAuthenticationError(int errorCode, CharSequence errString) { }
Jim Miller9f0753f2015-03-23 23:59:22 -0700304
305 /**
Jim Millerce7eb6d2015-04-03 19:29:13 -0700306 * Called when a recoverable error has been encountered during authentication. The help
Jim Miller9f0753f2015-03-23 23:59:22 -0700307 * string is provided to give the user guidance for what went wrong, such as
308 * "Sensor dirty, please clean it."
Jim Millerf501b582015-06-03 16:36:31 -0700309 * @param helpCode An integer identifying the error message
Jim Millerce7eb6d2015-04-03 19:29:13 -0700310 * @param helpString A human-readable string that can be shown in UI
Jim Miller9f0753f2015-03-23 23:59:22 -0700311 */
Jim Millerf501b582015-06-03 16:36:31 -0700312 public void onAuthenticationHelp(int helpCode, CharSequence helpString) { }
Jim Miller9f0753f2015-03-23 23:59:22 -0700313
314 /**
315 * Called when a fingerprint is recognized.
Jim Millerce7eb6d2015-04-03 19:29:13 -0700316 * @param result An object containing authentication-related data
Jim Miller9f0753f2015-03-23 23:59:22 -0700317 */
Jim Millerce7eb6d2015-04-03 19:29:13 -0700318 public void onAuthenticationSucceeded(AuthenticationResult result) { }
319
320 /**
321 * Called when a fingerprint is valid but not recognized.
322 */
323 public void onAuthenticationFailed() { }
Jorim Jaggi740452e2015-07-09 12:13:59 -0700324
325 /**
326 * Called when a fingerprint image has been acquired, but wasn't processed yet.
327 *
328 * @param acquireInfo one of FINGERPRINT_ACQUIRED_* constants
329 * @hide
330 */
331 public void onAuthenticationAcquired(int acquireInfo) {}
Jim Miller9f0753f2015-03-23 23:59:22 -0700332 };
333
334 /**
335 * Callback structure provided to {@link FingerprintManager#enroll(long, EnrollmentCallback,
336 * CancellationSignal, int). Users of {@link #FingerprintManager()}
337 * must provide an implementation of this to {@link FingerprintManager#enroll(long,
Jim Millerf501b582015-06-03 16:36:31 -0700338 * CancellationSignal, int, EnrollmentCallback) for listening to fingerprint events.
Jim Millerce7eb6d2015-04-03 19:29:13 -0700339 *
340 * @hide
Jim Miller9f0753f2015-03-23 23:59:22 -0700341 */
342 public static abstract class EnrollmentCallback {
343 /**
344 * Called when an unrecoverable error has been encountered and the operation is complete.
345 * No further callbacks will be made on this object.
Jim Millerce7eb6d2015-04-03 19:29:13 -0700346 * @param errMsgId An integer identifying the error message
347 * @param errString A human-readable error string that can be shown in UI
Jim Miller9f0753f2015-03-23 23:59:22 -0700348 */
Jim Millerce7eb6d2015-04-03 19:29:13 -0700349 public void onEnrollmentError(int errMsgId, CharSequence errString) { }
Jim Miller9f0753f2015-03-23 23:59:22 -0700350
351 /**
Jim Millerce7eb6d2015-04-03 19:29:13 -0700352 * Called when a recoverable error has been encountered during enrollment. The help
Jim Miller9f0753f2015-03-23 23:59:22 -0700353 * string is provided to give the user guidance for what went wrong, such as
354 * "Sensor dirty, please clean it" or what they need to do next, such as
355 * "Touch sensor again."
Jim Millerce7eb6d2015-04-03 19:29:13 -0700356 * @param helpMsgId An integer identifying the error message
357 * @param helpString A human-readable string that can be shown in UI
Jim Miller9f0753f2015-03-23 23:59:22 -0700358 */
Jim Millerce7eb6d2015-04-03 19:29:13 -0700359 public void onEnrollmentHelp(int helpMsgId, CharSequence helpString) { }
Jim Miller9f0753f2015-03-23 23:59:22 -0700360
361 /**
362 * Called as each enrollment step progresses. Enrollment is considered complete when
Jim Millerce7eb6d2015-04-03 19:29:13 -0700363 * remaining reaches 0. This function will not be called if enrollment fails. See
Jim Miller9f0753f2015-03-23 23:59:22 -0700364 * {@link EnrollmentCallback#onEnrollmentError(int, CharSequence)}
Jim Millerce7eb6d2015-04-03 19:29:13 -0700365 * @param remaining The number of remaining steps
Jim Miller9f0753f2015-03-23 23:59:22 -0700366 */
Jim Millerce7eb6d2015-04-03 19:29:13 -0700367 public void onEnrollmentProgress(int remaining) { }
Jim Miller9f0753f2015-03-23 23:59:22 -0700368 };
369
370 /**
371 * Callback structure provided to {@link FingerprintManager#remove(int). Users of
372 * {@link #FingerprintManager()} may optionally provide an implementation of this to
373 * {@link FingerprintManager#remove(int, int, RemovalCallback)} for listening to
374 * fingerprint template removal events.
Jim Millerce7eb6d2015-04-03 19:29:13 -0700375 *
376 * @hide
Jim Miller9f0753f2015-03-23 23:59:22 -0700377 */
378 public static abstract class RemovalCallback {
379 /**
380 * Called when the given fingerprint can't be removed.
Jim Millerce7eb6d2015-04-03 19:29:13 -0700381 * @param fp The fingerprint that the call attempted to remove
382 * @param errMsgId An associated error message id
383 * @param errString An error message indicating why the fingerprint id can't be removed
Jim Miller9f0753f2015-03-23 23:59:22 -0700384 */
Jim Millerce7eb6d2015-04-03 19:29:13 -0700385 public void onRemovalError(Fingerprint fp, int errMsgId, CharSequence errString) { }
Jim Miller9f0753f2015-03-23 23:59:22 -0700386
387 /**
388 * Called when a given fingerprint is successfully removed.
389 * @param fingerprint the fingerprint template that was removed.
390 */
Jim Millerce7eb6d2015-04-03 19:29:13 -0700391 public void onRemovalSucceeded(Fingerprint fingerprint) { }
Jim Miller9f0753f2015-03-23 23:59:22 -0700392 };
393
394 /**
Jim Millerce7eb6d2015-04-03 19:29:13 -0700395 * Request authentication of a crypto object. This call warms up the fingerprint hardware
396 * and starts scanning for a fingerprint. It terminates when
Jim Miller9f0753f2015-03-23 23:59:22 -0700397 * {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)} or
Jim Miller5f69ca32015-08-19 22:03:43 -0700398 * {@link AuthenticationCallback#onAuthenticationSucceeded(AuthenticationResult)} is called, at
Jim Miller9f0753f2015-03-23 23:59:22 -0700399 * which point the object is no longer valid. The operation can be canceled by using the
400 * provided cancel object.
401 *
402 * @param crypto object associated with the call or null if none required.
Jim Miller9f0753f2015-03-23 23:59:22 -0700403 * @param cancel an object that can be used to cancel authentication
Jim Millerce7eb6d2015-04-03 19:29:13 -0700404 * @param flags optional flags; should be 0
Jim Millerf501b582015-06-03 16:36:31 -0700405 * @param callback an object to receive authentication events
406 * @param handler an optional handler to handle callback events
Jim Millere4c58e42015-06-09 13:48:57 -0700407 *
408 * @throws IllegalArgumentException if the crypto operation is not supported or is not backed
409 * by <a href="{@docRoot}training/articles/keystore.html">Android Keystore
410 * facility</a>.
411 * @throws IllegalStateException if the crypto primitive is not initialized.
Jim Miller9f0753f2015-03-23 23:59:22 -0700412 */
Jim Millerf501b582015-06-03 16:36:31 -0700413 @RequiresPermission(USE_FINGERPRINT)
Jim Millerce7eb6d2015-04-03 19:29:13 -0700414 public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
Jim Millerf501b582015-06-03 16:36:31 -0700415 int flags, @NonNull AuthenticationCallback callback, @Nullable Handler handler) {
416 authenticate(crypto, cancel, flags, callback, handler, UserHandle.myUserId());
Jorim Jaggiccdfa932015-04-13 16:29:48 -0700417 }
418
419 /**
Jim Millerf501b582015-06-03 16:36:31 -0700420 * Use the provided handler thread for events.
421 * @param handler
422 */
423 private void useHandler(Handler handler) {
424 if (handler != null) {
425 mHandler = new MyHandler(handler.getLooper());
426 } else if (mHandler.getLooper() != mContext.getMainLooper()){
427 mHandler = new MyHandler(mContext.getMainLooper());
428 }
429 }
430
431 /**
432 * Per-user version
Jorim Jaggiccdfa932015-04-13 16:29:48 -0700433 * @hide
434 */
Jim Millerf501b582015-06-03 16:36:31 -0700435 @RequiresPermission(USE_FINGERPRINT)
Jorim Jaggiccdfa932015-04-13 16:29:48 -0700436 public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
Jim Millerf501b582015-06-03 16:36:31 -0700437 int flags, @NonNull AuthenticationCallback callback, Handler handler, int userId) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700438 if (callback == null) {
439 throw new IllegalArgumentException("Must supply an authentication callback");
440 }
441
Jim Millerce7eb6d2015-04-03 19:29:13 -0700442 if (cancel != null) {
443 if (cancel.isCanceled()) {
444 Log.w(TAG, "authentication already canceled");
445 return;
446 } else {
447 cancel.setOnCancelListener(new OnAuthenticationCancelListener(crypto));
448 }
449 }
Jim Miller9f0753f2015-03-23 23:59:22 -0700450
451 if (mService != null) try {
Jim Millerf501b582015-06-03 16:36:31 -0700452 useHandler(handler);
Jim Miller9f0753f2015-03-23 23:59:22 -0700453 mAuthenticationCallback = callback;
454 mCryptoObject = crypto;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700455 long sessionId = crypto != null ? crypto.getOpId() : 0;
Svetoslav4af76a52015-04-29 15:29:46 -0700456 mService.authenticate(mToken, sessionId, userId, mServiceReceiver, flags,
457 mContext.getOpPackageName());
Jim Miller9f0753f2015-03-23 23:59:22 -0700458 } catch (RemoteException e) {
Jim Millerce7eb6d2015-04-03 19:29:13 -0700459 Log.w(TAG, "Remote exception while authenticating: ", e);
460 if (callback != null) {
461 // Though this may not be a hardware issue, it will cause apps to give up or try
462 // again later.
463 callback.onAuthenticationError(FINGERPRINT_ERROR_HW_UNAVAILABLE,
464 getErrorString(FINGERPRINT_ERROR_HW_UNAVAILABLE));
465 }
Jim Miller9f0753f2015-03-23 23:59:22 -0700466 }
467 }
468
469 /**
470 * Request fingerprint enrollment. This call warms up the fingerprint hardware
471 * and starts scanning for fingerprints. Progress will be indicated by callbacks to the
472 * {@link EnrollmentCallback} object. It terminates when
473 * {@link EnrollmentCallback#onEnrollmentError(int, CharSequence)} or
474 * {@link EnrollmentCallback#onEnrollmentProgress(int) is called with remaining == 0, at
475 * which point the object is no longer valid. The operation can be canceled by using the
476 * provided cancel object.
Jim Millerfe6439f2015-04-11 18:07:57 -0700477 * @param token a unique token provided by a recent creation or verification of device
478 * credentials (e.g. pin, pattern or password).
Jim Miller9f0753f2015-03-23 23:59:22 -0700479 * @param cancel an object that can be used to cancel enrollment
480 * @param flags optional flags
Jim Millerf501b582015-06-03 16:36:31 -0700481 * @param callback an object to receive enrollment events
Jim Millerce7eb6d2015-04-03 19:29:13 -0700482 * @hide
Jim Miller9f0753f2015-03-23 23:59:22 -0700483 */
Jim Millerf501b582015-06-03 16:36:31 -0700484 @RequiresPermission(MANAGE_FINGERPRINT)
485 public void enroll(byte [] token, CancellationSignal cancel, int flags,
486 EnrollmentCallback callback) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700487 if (callback == null) {
488 throw new IllegalArgumentException("Must supply an enrollment callback");
489 }
490
Jim Millerce7eb6d2015-04-03 19:29:13 -0700491 if (cancel != null) {
492 if (cancel.isCanceled()) {
493 Log.w(TAG, "enrollment already canceled");
494 return;
495 } else {
Jim Millerfe6439f2015-04-11 18:07:57 -0700496 cancel.setOnCancelListener(new OnEnrollCancelListener());
Jim Millerce7eb6d2015-04-03 19:29:13 -0700497 }
498 }
Jim Miller9f0753f2015-03-23 23:59:22 -0700499
500 if (mService != null) try {
501 mEnrollmentCallback = callback;
Jim Millerfe6439f2015-04-11 18:07:57 -0700502 mService.enroll(mToken, token, getCurrentUserId(), mServiceReceiver, flags);
Jim Miller9f0753f2015-03-23 23:59:22 -0700503 } catch (RemoteException e) {
Jim Millerce7eb6d2015-04-03 19:29:13 -0700504 Log.w(TAG, "Remote exception in enroll: ", e);
505 if (callback != null) {
506 // Though this may not be a hardware issue, it will cause apps to give up or try
507 // again later.
508 callback.onEnrollmentError(FINGERPRINT_ERROR_HW_UNAVAILABLE,
509 getErrorString(FINGERPRINT_ERROR_HW_UNAVAILABLE));
510 }
Jim Miller9f0753f2015-03-23 23:59:22 -0700511 }
512 }
513
514 /**
Jim Millerce7eb6d2015-04-03 19:29:13 -0700515 * Requests a pre-enrollment auth token to tie enrollment to the confirmation of
516 * existing device credentials (e.g. pin/pattern/password).
517 * @hide
518 */
Jim Millerf501b582015-06-03 16:36:31 -0700519 @RequiresPermission(MANAGE_FINGERPRINT)
Jim Millerce7eb6d2015-04-03 19:29:13 -0700520 public long preEnroll() {
521 long result = 0;
522 if (mService != null) try {
523 result = mService.preEnroll(mToken);
524 } catch (RemoteException e) {
525 Log.w(TAG, "Remote exception in enroll: ", e);
526 }
527 return result;
528 }
529
530 /**
Sasha Levitskiye0943cf2015-07-08 13:22:20 -0700531 * Finishes enrollment and cancels the current auth token.
532 * @hide
533 */
534 @RequiresPermission(MANAGE_FINGERPRINT)
535 public int postEnroll() {
536 int result = 0;
537 if (mService != null) try {
538 result = mService.postEnroll(mToken);
539 } catch (RemoteException e) {
540 Log.w(TAG, "Remote exception in post enroll: ", e);
541 }
542 return result;
543 }
544
545 /**
Jim Miller9f0753f2015-03-23 23:59:22 -0700546 * Remove given fingerprint template from fingerprint hardware and/or protected storage.
547 * @param fp the fingerprint item to remove
548 * @param callback an optional callback to verify that fingerprint templates have been
Jim Millerce7eb6d2015-04-03 19:29:13 -0700549 * successfully removed. May be null of no callback is required.
550 *
Jim Miller9f0753f2015-03-23 23:59:22 -0700551 * @hide
552 */
Jim Millerf501b582015-06-03 16:36:31 -0700553 @RequiresPermission(MANAGE_FINGERPRINT)
Jim Miller9f0753f2015-03-23 23:59:22 -0700554 public void remove(Fingerprint fp, RemovalCallback callback) {
555 if (mService != null) try {
556 mRemovalCallback = callback;
557 mRemovalFingerprint = fp;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700558 mService.remove(mToken, fp.getFingerId(), getCurrentUserId(), mServiceReceiver);
Jim Miller9f0753f2015-03-23 23:59:22 -0700559 } catch (RemoteException e) {
Jim Millerce7eb6d2015-04-03 19:29:13 -0700560 Log.w(TAG, "Remote exception in remove: ", e);
561 if (callback != null) {
562 callback.onRemovalError(fp, FINGERPRINT_ERROR_HW_UNAVAILABLE,
563 getErrorString(FINGERPRINT_ERROR_HW_UNAVAILABLE));
564 }
Jim Miller9f0753f2015-03-23 23:59:22 -0700565 }
566 }
567
568 /**
569 * Renames the given fingerprint template
570 * @param fpId the fingerprint id
571 * @param newName the new name
Jim Millerce7eb6d2015-04-03 19:29:13 -0700572 *
Jim Miller9f0753f2015-03-23 23:59:22 -0700573 * @hide
574 */
Jim Millerf501b582015-06-03 16:36:31 -0700575 @RequiresPermission(MANAGE_FINGERPRINT)
Jim Miller9f0753f2015-03-23 23:59:22 -0700576 public void rename(int fpId, String newName) {
577 // Renames the given fpId
578 if (mService != null) {
579 try {
580 mService.rename(fpId, getCurrentUserId(), newName);
581 } catch (RemoteException e) {
582 Log.v(TAG, "Remote exception in rename(): ", e);
583 }
584 } else {
585 Log.w(TAG, "rename(): Service not connected!");
586 }
587 }
588
589 /**
590 * Obtain the list of enrolled fingerprints templates.
591 * @return list of current fingerprint items
Jim Millerce7eb6d2015-04-03 19:29:13 -0700592 *
593 * @hide
Jim Miller9f0753f2015-03-23 23:59:22 -0700594 */
Jim Millerf501b582015-06-03 16:36:31 -0700595 @RequiresPermission(USE_FINGERPRINT)
Jorim Jaggi2aad7ee2015-04-14 15:25:06 -0700596 public List<Fingerprint> getEnrolledFingerprints(int userId) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700597 if (mService != null) try {
Svetoslav4af76a52015-04-29 15:29:46 -0700598 return mService.getEnrolledFingerprints(userId, mContext.getOpPackageName());
Jim Miller9f0753f2015-03-23 23:59:22 -0700599 } catch (RemoteException e) {
600 Log.v(TAG, "Remote exception in getEnrolledFingerprints: ", e);
601 }
602 return null;
603 }
604
605 /**
Jorim Jaggi2aad7ee2015-04-14 15:25:06 -0700606 * Obtain the list of enrolled fingerprints templates.
607 * @return list of current fingerprint items
Jim Millerce7eb6d2015-04-03 19:29:13 -0700608 *
Jim Miller9f0753f2015-03-23 23:59:22 -0700609 * @hide
610 */
Jim Millerf501b582015-06-03 16:36:31 -0700611 @RequiresPermission(USE_FINGERPRINT)
Jorim Jaggi2aad7ee2015-04-14 15:25:06 -0700612 public List<Fingerprint> getEnrolledFingerprints() {
613 return getEnrolledFingerprints(UserHandle.myUserId());
614 }
615
616 /**
617 * Determine if there is at least one fingerprint enrolled.
618 *
619 * @return true if at least one fingerprint is enrolled, false otherwise
620 */
Jim Millerf501b582015-06-03 16:36:31 -0700621 @RequiresPermission(USE_FINGERPRINT)
Jorim Jaggi2aad7ee2015-04-14 15:25:06 -0700622 public boolean hasEnrolledFingerprints() {
623 if (mService != null) try {
Svetoslav4af76a52015-04-29 15:29:46 -0700624 return mService.hasEnrolledFingerprints(UserHandle.myUserId(),
625 mContext.getOpPackageName());
Jorim Jaggi2aad7ee2015-04-14 15:25:06 -0700626 } catch (RemoteException e) {
627 Log.v(TAG, "Remote exception in getEnrolledFingerprints: ", e);
628 }
629 return false;
630 }
631
632 /**
633 * Determine if fingerprint hardware is present and functional.
634 *
635 * @return true if hardware is present and functional, false otherwise.
636 */
Jim Millerf501b582015-06-03 16:36:31 -0700637 @RequiresPermission(USE_FINGERPRINT)
Jim Miller9f0753f2015-03-23 23:59:22 -0700638 public boolean isHardwareDetected() {
639 if (mService != null) {
640 try {
641 long deviceId = 0; /* TODO: plumb hardware id to FPMS */
Svetoslav4af76a52015-04-29 15:29:46 -0700642 return mService.isHardwareDetected(deviceId, mContext.getOpPackageName());
Jim Miller9f0753f2015-03-23 23:59:22 -0700643 } catch (RemoteException e) {
644 Log.v(TAG, "Remote exception in isFingerprintHardwareDetected(): ", e);
645 }
646 } else {
647 Log.w(TAG, "isFingerprintHardwareDetected(): Service not connected!");
648 }
649 return false;
650 }
Jim Miller08fa40c2014-04-29 18:18:47 -0700651
Andres Morales4d41a202015-04-16 14:12:38 -0700652 /**
653 * Retrieves the authenticator token for binding keys to the lifecycle
654 * of the current set of fingerprints. Used only by internal clients.
655 *
656 * @hide
657 */
658 public long getAuthenticatorId() {
659 if (mService != null) {
660 try {
Svetoslav4af76a52015-04-29 15:29:46 -0700661 return mService.getAuthenticatorId(mContext.getOpPackageName());
Andres Morales4d41a202015-04-16 14:12:38 -0700662 } catch (RemoteException e) {
663 Log.v(TAG, "Remote exception in getAuthenticatorId(): ", e);
664 }
665 } else {
666 Log.w(TAG, "getAuthenticatorId(): Service not connected!");
667 }
668 return 0;
669 }
670
Alex Klyubin24e9e962015-04-30 13:30:48 -0700671 private class MyHandler extends Handler {
672 private MyHandler(Context context) {
673 super(context.getMainLooper());
674 }
675
Jim Millerf501b582015-06-03 16:36:31 -0700676 private MyHandler(Looper looper) {
677 super(looper);
678 }
679
Jim Miller08fa40c2014-04-29 18:18:47 -0700680 public void handleMessage(android.os.Message msg) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700681 switch(msg.what) {
682 case MSG_ENROLL_RESULT:
683 sendEnrollResult((Fingerprint) msg.obj, msg.arg1 /* remaining */);
684 break;
685 case MSG_ACQUIRED:
686 sendAcquiredResult((Long) msg.obj /* deviceId */, msg.arg1 /* acquire info */);
687 break;
Jim Millerf501b582015-06-03 16:36:31 -0700688 case MSG_AUTHENTICATION_SUCCEEDED:
689 sendAuthenticatedSucceeded((Fingerprint) msg.obj);
690 break;
691 case MSG_AUTHENTICATION_FAILED:
692 sendAuthenticatedFailed();
Jim Miller9f0753f2015-03-23 23:59:22 -0700693 break;
694 case MSG_ERROR:
695 sendErrorResult((Long) msg.obj /* deviceId */, msg.arg1 /* errMsgId */);
696 break;
697 case MSG_REMOVED:
698 sendRemovedResult((Long) msg.obj /* deviceId */, msg.arg1 /* fingerId */,
699 msg.arg2 /* groupId */);
700 }
701 }
702
703 private void sendRemovedResult(long deviceId, int fingerId, int groupId) {
704 if (mRemovalCallback != null) {
705 int reqFingerId = mRemovalFingerprint.getFingerId();
706 int reqGroupId = mRemovalFingerprint.getGroupId();
707 if (fingerId != reqFingerId) {
708 Log.w(TAG, "Finger id didn't match: " + fingerId + " != " + reqFingerId);
Jim Miller08fa40c2014-04-29 18:18:47 -0700709 }
Jim Miller9f0753f2015-03-23 23:59:22 -0700710 if (fingerId != reqFingerId) {
711 Log.w(TAG, "Group id didn't match: " + groupId + " != " + reqGroupId);
712 }
713 mRemovalCallback.onRemovalSucceeded(mRemovalFingerprint);
714 }
715 }
716
717 private void sendErrorResult(long deviceId, int errMsgId) {
718 if (mEnrollmentCallback != null) {
719 mEnrollmentCallback.onEnrollmentError(errMsgId, getErrorString(errMsgId));
720 } else if (mAuthenticationCallback != null) {
721 mAuthenticationCallback.onAuthenticationError(errMsgId, getErrorString(errMsgId));
722 } else if (mRemovalCallback != null) {
723 mRemovalCallback.onRemovalError(mRemovalFingerprint, errMsgId,
724 getErrorString(errMsgId));
725 }
726 }
727
728 private void sendEnrollResult(Fingerprint fp, int remaining) {
729 if (mEnrollmentCallback != null) {
730 mEnrollmentCallback.onEnrollmentProgress(remaining);
731 }
732 }
733
Jim Millerf501b582015-06-03 16:36:31 -0700734 private void sendAuthenticatedSucceeded(Fingerprint fp) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700735 if (mAuthenticationCallback != null) {
Jim Millerf501b582015-06-03 16:36:31 -0700736 final AuthenticationResult result = new AuthenticationResult(mCryptoObject, fp);
737 mAuthenticationCallback.onAuthenticationSucceeded(result);
738 }
739 }
740
741 private void sendAuthenticatedFailed() {
742 if (mAuthenticationCallback != null) {
743 mAuthenticationCallback.onAuthenticationFailed();
Jim Miller9f0753f2015-03-23 23:59:22 -0700744 }
745 }
746
747 private void sendAcquiredResult(long deviceId, int acquireInfo) {
Jorim Jaggi740452e2015-07-09 12:13:59 -0700748 if (mAuthenticationCallback != null) {
749 mAuthenticationCallback.onAuthenticationAcquired(acquireInfo);
750 }
Jim Miller9f0753f2015-03-23 23:59:22 -0700751 final String msg = getAcquiredString(acquireInfo);
Jorim Jaggi740452e2015-07-09 12:13:59 -0700752 if (msg == null) {
753 return;
754 }
Jim Miller9f0753f2015-03-23 23:59:22 -0700755 if (mEnrollmentCallback != null) {
756 mEnrollmentCallback.onEnrollmentHelp(acquireInfo, msg);
757 } else if (mAuthenticationCallback != null) {
758 mAuthenticationCallback.onAuthenticationHelp(acquireInfo, msg);
759 }
760 }
Jim Miller08fa40c2014-04-29 18:18:47 -0700761 };
762
Jim Miller06e658f2014-06-17 15:59:40 -0700763 /**
764 * @hide
765 */
Jim Millera75961472014-06-06 15:00:49 -0700766 public FingerprintManager(Context context, IFingerprintService service) {
Jim Millerd08c2ac2014-05-14 16:30:38 -0700767 mContext = context;
Jim Millera75961472014-06-06 15:00:49 -0700768 mService = service;
769 if (mService == null) {
770 Slog.v(TAG, "FingerprintManagerService was null");
Jim Miller08fa40c2014-04-29 18:18:47 -0700771 }
Alex Klyubin24e9e962015-04-30 13:30:48 -0700772 mHandler = new MyHandler(context);
Jim Miller08fa40c2014-04-29 18:18:47 -0700773 }
774
Jim Miller08fa40c2014-04-29 18:18:47 -0700775 private int getCurrentUserId() {
776 try {
777 return ActivityManagerNative.getDefault().getCurrentUser().id;
778 } catch (RemoteException e) {
779 Log.w(TAG, "Failed to get current user id\n");
780 return UserHandle.USER_NULL;
781 }
782 }
783
Jim Millerfe6439f2015-04-11 18:07:57 -0700784 private void cancelEnrollment() {
Jim Millerce7eb6d2015-04-03 19:29:13 -0700785 if (mService != null) try {
786 mService.cancelEnrollment(mToken);
787 } catch (RemoteException e) {
788 if (DEBUG) Log.w(TAG, "Remote exception while canceling enrollment");
Jim Miller08fa40c2014-04-29 18:18:47 -0700789 }
790 }
Jim Millera75961472014-06-06 15:00:49 -0700791
Jim Millerce7eb6d2015-04-03 19:29:13 -0700792 private void cancelAuthentication(CryptoObject cryptoObject) {
793 if (mService != null) try {
Svetoslav4af76a52015-04-29 15:29:46 -0700794 mService.cancelAuthentication(mToken, mContext.getOpPackageName());
Jim Millerce7eb6d2015-04-03 19:29:13 -0700795 } catch (RemoteException e) {
796 if (DEBUG) Log.w(TAG, "Remote exception while canceling enrollment");
797 }
798 }
799
800 private String getErrorString(int errMsg) {
801 switch (errMsg) {
802 case FINGERPRINT_ERROR_UNABLE_TO_PROCESS:
803 return mContext.getString(
804 com.android.internal.R.string.fingerprint_error_unable_to_process);
805 case FINGERPRINT_ERROR_HW_UNAVAILABLE:
806 return mContext.getString(
807 com.android.internal.R.string.fingerprint_error_hw_not_available);
808 case FINGERPRINT_ERROR_NO_SPACE:
809 return mContext.getString(
810 com.android.internal.R.string.fingerprint_error_no_space);
811 case FINGERPRINT_ERROR_TIMEOUT:
Jim Millerfe6439f2015-04-11 18:07:57 -0700812 return mContext.getString(com.android.internal.R.string.fingerprint_error_timeout);
813 case FINGERPRINT_ERROR_CANCELED:
814 return mContext.getString(com.android.internal.R.string.fingerprint_error_canceled);
815 case FINGERPRINT_ERROR_LOCKOUT:
816 return mContext.getString(com.android.internal.R.string.fingerprint_error_lockout);
Jim Millerce7eb6d2015-04-03 19:29:13 -0700817 default:
818 if (errMsg >= FINGERPRINT_ERROR_VENDOR_BASE) {
819 int msgNumber = errMsg - FINGERPRINT_ERROR_VENDOR_BASE;
820 String[] msgArray = mContext.getResources().getStringArray(
821 com.android.internal.R.array.fingerprint_error_vendor);
822 if (msgNumber < msgArray.length) {
823 return msgArray[msgNumber];
824 }
Jim Miller9f0753f2015-03-23 23:59:22 -0700825 }
Jim Millerce7eb6d2015-04-03 19:29:13 -0700826 return null;
827 }
828 }
829
830 private String getAcquiredString(int acquireInfo) {
831 switch (acquireInfo) {
832 case FINGERPRINT_ACQUIRED_GOOD:
833 return null;
834 case FINGERPRINT_ACQUIRED_PARTIAL:
835 return mContext.getString(
836 com.android.internal.R.string.fingerprint_acquired_partial);
837 case FINGERPRINT_ACQUIRED_INSUFFICIENT:
838 return mContext.getString(
839 com.android.internal.R.string.fingerprint_acquired_insufficient);
840 case FINGERPRINT_ACQUIRED_IMAGER_DIRTY:
841 return mContext.getString(
842 com.android.internal.R.string.fingerprint_acquired_imager_dirty);
843 case FINGERPRINT_ACQUIRED_TOO_SLOW:
844 return mContext.getString(
845 com.android.internal.R.string.fingerprint_acquired_too_slow);
846 case FINGERPRINT_ACQUIRED_TOO_FAST:
847 return mContext.getString(
848 com.android.internal.R.string.fingerprint_acquired_too_fast);
849 default:
850 if (acquireInfo >= FINGERPRINT_ACQUIRED_VENDOR_BASE) {
851 int msgNumber = acquireInfo - FINGERPRINT_ACQUIRED_VENDOR_BASE;
852 String[] msgArray = mContext.getResources().getStringArray(
853 com.android.internal.R.array.fingerprint_acquired_vendor);
854 if (msgNumber < msgArray.length) {
855 return msgArray[msgNumber];
856 }
857 }
858 return null;
Jim Millerba67aee2015-02-20 16:21:26 -0800859 }
Jim Millerba67aee2015-02-20 16:21:26 -0800860 }
Jim Miller99d60192015-03-11 17:41:58 -0700861
Jim Miller9f0753f2015-03-23 23:59:22 -0700862 private IFingerprintServiceReceiver mServiceReceiver = new IFingerprintServiceReceiver.Stub() {
863
Jim Millerf501b582015-06-03 16:36:31 -0700864 @Override // binder call
Jim Miller9f0753f2015-03-23 23:59:22 -0700865 public void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining) {
866 mHandler.obtainMessage(MSG_ENROLL_RESULT, remaining, 0,
867 new Fingerprint(null, groupId, fingerId, deviceId)).sendToTarget();
Jim Miller99d60192015-03-11 17:41:58 -0700868 }
Jim Miller9f0753f2015-03-23 23:59:22 -0700869
Jim Millerf501b582015-06-03 16:36:31 -0700870 @Override // binder call
Jim Miller9f0753f2015-03-23 23:59:22 -0700871 public void onAcquired(long deviceId, int acquireInfo) {
872 mHandler.obtainMessage(MSG_ACQUIRED, acquireInfo, 0, deviceId).sendToTarget();
873 }
874
Jim Millerf501b582015-06-03 16:36:31 -0700875 @Override // binder call
876 public void onAuthenticationSucceeded(long deviceId, Fingerprint fp) {
877 mHandler.obtainMessage(MSG_AUTHENTICATION_SUCCEEDED, fp).sendToTarget();
Jim Miller9f0753f2015-03-23 23:59:22 -0700878 }
879
Jim Millerf501b582015-06-03 16:36:31 -0700880 @Override // binder call
881 public void onAuthenticationFailed(long deviceId) {
882 mHandler.obtainMessage(MSG_AUTHENTICATION_FAILED).sendToTarget();;
883 }
884
885 @Override // binder call
Jim Miller9f0753f2015-03-23 23:59:22 -0700886 public void onError(long deviceId, int error) {
887 mHandler.obtainMessage(MSG_ERROR, error, 0, deviceId).sendToTarget();
888 }
889
Jim Millerf501b582015-06-03 16:36:31 -0700890 @Override // binder call
Jim Miller9f0753f2015-03-23 23:59:22 -0700891 public void onRemoved(long deviceId, int fingerId, int groupId) {
892 mHandler.obtainMessage(MSG_REMOVED, fingerId, groupId, deviceId).sendToTarget();
893 }
894 };
895
Andres Morales4d41a202015-04-16 14:12:38 -0700896}
897