FingerprintManager.java revision fe6439f02db3a541d77a7afb27e3bca1ae7493ed
108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller/**
208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * Copyright (C) 2014 The Android Open Source Project
308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller *
408fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * Licensed under the Apache License, Version 2.0 (the "License");
508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * you may not use this file except in compliance with the License.
608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * You may obtain a copy of the License at
708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller *
808fa40c5cb5229b7969b2a5146855a337870f45aJim Miller *      http://www.apache.org/licenses/LICENSE-2.0
908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller *
1008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * Unless required by applicable law or agreed to in writing, software
1108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * distributed under the License is distributed on an "AS IS" BASIS,
1208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * See the License for the specific language governing permissions and
1408fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * limitations under the License.
1508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller */
1608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
17ebbf205bc6e8292f74d8fc4652c70274a445f907Jim Millerpackage android.hardware.fingerprint;
1808fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
19ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Millerimport android.annotation.NonNull;
20ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Millerimport android.annotation.Nullable;
2108fa40c5cb5229b7969b2a5146855a337870f45aJim Millerimport android.app.ActivityManagerNative;
22d08c2aceb238b02d8348518a2c87693054c6ce37Jim Millerimport android.content.ContentResolver;
2308fa40c5cb5229b7969b2a5146855a337870f45aJim Millerimport android.content.Context;
24a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport android.os.Binder;
259f0753f5a378fc80da86305b33244acc6fc53f01Jim Millerimport android.os.CancellationSignal;
26ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Millerimport android.os.CancellationSignal.OnCancelListener;
2708fa40c5cb5229b7969b2a5146855a337870f45aJim Millerimport android.os.Handler;
2808fa40c5cb5229b7969b2a5146855a337870f45aJim Millerimport android.os.IBinder;
299f0753f5a378fc80da86305b33244acc6fc53f01Jim Millerimport android.os.Parcel;
309f0753f5a378fc80da86305b33244acc6fc53f01Jim Millerimport android.os.Parcelable;
3108fa40c5cb5229b7969b2a5146855a337870f45aJim Millerimport android.os.RemoteException;
3208fa40c5cb5229b7969b2a5146855a337870f45aJim Millerimport android.os.UserHandle;
33d08c2aceb238b02d8348518a2c87693054c6ce37Jim Millerimport android.provider.Settings;
34ebbf205bc6e8292f74d8fc4652c70274a445f907Jim Millerimport android.hardware.fingerprint.FingerprintManager.EnrollmentCallback;
35ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Millerimport android.security.AndroidKeyStoreProvider;
3608fa40c5cb5229b7969b2a5146855a337870f45aJim Millerimport android.util.Log;
37a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport android.util.Slog;
3808fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
399f0753f5a378fc80da86305b33244acc6fc53f01Jim Millerimport java.security.Signature;
40ba67aee02cf864793129976cd8a8a46e60c60577Jim Millerimport java.util.ArrayList;
419f0753f5a378fc80da86305b33244acc6fc53f01Jim Millerimport java.util.HashMap;
42ba67aee02cf864793129976cd8a8a46e60c60577Jim Millerimport java.util.List;
43ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller
449f0753f5a378fc80da86305b33244acc6fc53f01Jim Millerimport javax.crypto.Cipher;
459f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
4608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller/**
4708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * A class that coordinates access to the fingerprint hardware.
48ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller * <p>
49ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller * Use {@link android.content.Context#getSystemService(java.lang.String)}
50ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller * with argument {@link android.content.Context#FINGERPRINT_SERVICE} to get
51ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller * an instance of this class.
5208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller */
5308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
5408fa40c5cb5229b7969b2a5146855a337870f45aJim Millerpublic class FingerprintManager {
5508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    private static final String TAG = "FingerprintManager";
56d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller    private static final boolean DEBUG = true;
5708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    private static final int MSG_ENROLL_RESULT = 100;
58a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    private static final int MSG_ACQUIRED = 101;
59fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller    private static final int MSG_AUTHENTICATED = 102;
60a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    private static final int MSG_ERROR = 103;
61a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    private static final int MSG_REMOVED = 104;
6208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
63ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    //
64ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    // Error messages from fingerprint hardware during initilization, enrollment, authentication or
65ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    // removal. Must agree with the list in fingerprint.h
66ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    //
6708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
68ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
69ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * The hardware is unavailable. Try again later.
70ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
7108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    public static final int FINGERPRINT_ERROR_HW_UNAVAILABLE = 1;
72ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
73ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
74ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * Error state returned when the sensor was unable to process the current image.
75ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
76a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    public static final int FINGERPRINT_ERROR_UNABLE_TO_PROCESS = 2;
77ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
78ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
79ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * Error state returned when the current request has been running too long. This is intended to
80ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * prevent programs from waiting for the fingerprint sensor indefinitely. The timeout is
81ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * platform and sensor-specific, but is generally on the order of 30 seconds.
82ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
8308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    public static final int FINGERPRINT_ERROR_TIMEOUT = 3;
84ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
85ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
86ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * Error state returned for operations like enrollment; the operation cannot be completed
87ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * because there's not enough storage remaining to complete the operation.
88ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
8908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    public static final int FINGERPRINT_ERROR_NO_SPACE = 4;
90ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
91ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
92ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * The operation was canceled because the fingerprint sensor is unavailable. For example,
93ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * this may happen when the user is switched, the device is locked or another pending operation
94ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * prevents or disables it.
95ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
969f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static final int FINGERPRINT_ERROR_CANCELED = 5;
97ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
98ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
99ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * The {@link FingerprintManager#remove(Fingerprint, RemovalCallback)} call failed. Typically
100ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * this will happen when the provided fingerprint id was incorrect.
101ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *
102ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @hide
103ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
104ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    public static final int FINGERPRINT_ERROR_UNABLE_TO_REMOVE = 6;
105ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
106fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller   /**
107fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller     * The operation was canceled because the API is locked out due to too many attempts.
108fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller     */
109fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller    public static final int FINGERPRINT_ERROR_LOCKOUT = 7;
110fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller
111ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
112ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * Hardware vendors may extend this list if there are conditions that do not fall under one of
113ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * the above categories. Vendors are responsible for providing error strings for these errors.
114ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
1159f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static final int FINGERPRINT_ERROR_VENDOR_BASE = 1000;
11608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
117ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    //
118ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    // Image acquisition messages. Must agree with those in fingerprint.h
119ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    //
120ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
121ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
122ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * The image acquired was good.
123ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
124a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    public static final int FINGERPRINT_ACQUIRED_GOOD = 0;
125ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
126ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
127ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * Only a partial fingerprint image was detected. During enrollment, the user should be
128ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * informed on what needs to happen to resolve this problem, e.g. "press firmly on sensor."
129ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
130a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    public static final int FINGERPRINT_ACQUIRED_PARTIAL = 1;
131ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
132ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
133ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * The fingerprint image was too noisy to process due to a detected condition (i.e. dry skin) or
134ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * a possibly dirty sensor (See {@link #FINGERPRINT_ACQUIRED_IMAGER_DIRTY}).
135ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
136a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    public static final int FINGERPRINT_ACQUIRED_INSUFFICIENT = 2;
137ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
138ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
139ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * The fingerprint image was too noisy due to suspected or detected dirt on the sensor.
140ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * For example, it's reasonable return this after multiple
141ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * {@link #FINGERPRINT_ACQUIRED_INSUFFICIENT} or actual detection of dirt on the sensor
142ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * (stuck pixels, swaths, etc.). The user is expected to take action to clean the sensor
143ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * when this is returned.
144ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
1459f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static final int FINGERPRINT_ACQUIRED_IMAGER_DIRTY = 3;
146ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
147ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
148ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * The fingerprint image was unreadable due to lack of motion. This is most appropriate for
149ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * linear array sensors that require a swipe motion.
150ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
1519f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static final int FINGERPRINT_ACQUIRED_TOO_SLOW = 4;
152ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
153ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
154ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * The fingerprint image was incomplete due to quick motion. While mostly appropriate for
155ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * linear array sensors,  this could also happen if the finger was moved during acquisition.
156ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * The user should be asked to move the finger slower (linear) or leave the finger on the sensor
157ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * longer.
158ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
1599f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static final int FINGERPRINT_ACQUIRED_TOO_FAST = 5;
160ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
161ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
162ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * Hardware vendors may extend this list if there are conditions that do not fall under one of
163ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * the above categories. Vendors are responsible for providing error strings for these errors.
164ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
1659f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static final int FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
166a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
16708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    private IFingerprintService mService;
168d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller    private Context mContext;
169a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    private IBinder mToken = new Binder();
1709f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private AuthenticationCallback mAuthenticationCallback;
1719f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private EnrollmentCallback mEnrollmentCallback;
1729f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private RemovalCallback mRemovalCallback;
1739f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private CryptoObject mCryptoObject;
1749f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private Fingerprint mRemovalFingerprint;
175ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
176ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    private class OnEnrollCancelListener implements OnCancelListener {
177ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        @Override
178ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onCancel() {
179fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller            cancelEnrollment();
180ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
181ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    }
182ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
183ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    private class OnAuthenticationCancelListener implements OnCancelListener {
184ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        private CryptoObject mCrypto;
185ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
186ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public OnAuthenticationCancelListener(CryptoObject crypto) {
187ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            mCrypto = crypto;
188ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
189ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
190ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        @Override
191ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onCancel() {
192ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            cancelAuthentication(mCrypto);
193ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
194ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    }
19508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
1969f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    /**
197ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * A wrapper class for the crypto objects supported by FingerprintManager. Currently the
198ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * framework supports {@link Signature} and {@link Cipher} objects.
1999f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     */
2009f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static class CryptoObject {
201ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
202ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        CryptoObject(Signature signature) {
203ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            mSignature = signature;
204ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            mCipher = null;
205ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
206ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
207ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        CryptoObject(Cipher cipher) {
208ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            mCipher = cipher;
209ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            mSignature = null;
210ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
211ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
212ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        /**
213ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * Get {@link Signature} object.
214ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @return {@link Signature} object or null if this doesn't contain one.
215ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         */
216ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public Signature getSignature() { return mSignature; }
217ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
218ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        /**
219ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * Get {@link Cipher} object.
220ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @return {@link Cipher} object or null if this doesn't contain one.
221ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         */
222ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public Cipher getCipher() { return mCipher; }
223ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
224ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        /**
225ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @hide
226ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @return the opId associated with this object or 0 if none
227ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         */
228ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public long getOpId() {
229ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (mSignature != null) {
230ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return AndroidKeyStoreProvider.getKeyStoreOperationHandle(mSignature);
231ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            } else if (mCipher != null) {
232ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return AndroidKeyStoreProvider.getKeyStoreOperationHandle(mCipher);
233ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            }
234ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            return 0;
235ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
236ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
237ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        private final Signature mSignature;
238ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        private final Cipher mCipher;
23908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    };
24008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
2419f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    /**
2429f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Container for callback data from {@link FingerprintManager#authenticate(CryptoObject,
243ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *     CancellationSignal, AuthenticationCallback, int)}.
2449f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     */
2459f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static final class AuthenticationResult {
2469f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        private Fingerprint mFingerprint;
2479f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        private CryptoObject mCryptoObject;
2489f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
2499f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public AuthenticationResult(CryptoObject crypto, Fingerprint fingerprint) {
2509f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mCryptoObject = crypto;
2519f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mFingerprint = fingerprint;
252ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller        }
2539f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
2549f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
2559f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * Obtain the crypto object associated with this transaction
2569f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * @return crypto object provided to {@link FingerprintManager#authenticate(CryptoObject,
257ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         *     CancellationSignal, AuthenticationCallback, int)}.
2589f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
2599f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public CryptoObject getCryptoObject() { return mCryptoObject; }
2609f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
2619f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
262ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * Obtain the Fingerprint associated with this operation. Applications are strongly
263ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * discouraged from associating specific fingers with specific applications or operations.
264ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         *
2659f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * @hide
2669f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
2679f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public Fingerprint getFingerprint() { return mFingerprint; }
2689f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    };
269ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller
27006e658f324a937bec1c5ddbe9c3100c3d2fec371Jim Miller    /**
2719f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Callback structure provided to {@link FingerprintManager#authenticate(CryptoObject,
272ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * CancellationSignal, AuthenticationCallback, int)}. Users of {@link
273ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * FingerprintManager#authenticate(CryptoObject, CancellationSignal,
274ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * AuthenticationCallback, int) } must provide an implementation of this for listening to
275ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * fingerprint events.
27606e658f324a937bec1c5ddbe9c3100c3d2fec371Jim Miller     */
2779f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static abstract class AuthenticationCallback {
2789f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
2799f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * Called when an unrecoverable error has been encountered and the operation is complete.
2809f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * No further callbacks will be made on this object.
281ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param errMsgId An integer identifying the error message
282ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param errString A human-readable error string that can be shown in UI
2839f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
284ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onAuthenticationError(int errMsgId, CharSequence errString) { }
28508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
2869f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
287ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * Called when a recoverable error has been encountered during authentication. The help
2889f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * string is provided to give the user guidance for what went wrong, such as
2899f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * "Sensor dirty, please clean it."
290ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param helpMsgId An integer identifying the error message
291ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param helpString A human-readable string that can be shown in UI
2929f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
293ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) { }
29408fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
2959f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
2969f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * Called when a fingerprint is recognized.
297ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param result An object containing authentication-related data
2989f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
299ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onAuthenticationSucceeded(AuthenticationResult result) { }
300ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
301ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        /**
302ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * Called when a fingerprint is valid but not recognized.
303ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         */
304ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onAuthenticationFailed() { }
3059f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    };
30608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
3079f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    /**
3089f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Callback structure provided to {@link FingerprintManager#enroll(long, EnrollmentCallback,
3099f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * CancellationSignal, int). Users of {@link #FingerprintManager()}
3109f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * must provide an implementation of this to {@link FingerprintManager#enroll(long,
311ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * CancellationSignal, EnrollmentCallback, int) for listening to fingerprint events.
312ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *
313ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @hide
3149f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     */
3159f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static abstract class EnrollmentCallback {
3169f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
3179f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * Called when an unrecoverable error has been encountered and the operation is complete.
3189f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * No further callbacks will be made on this object.
319ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param errMsgId An integer identifying the error message
320ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param errString A human-readable error string that can be shown in UI
3219f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
322ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onEnrollmentError(int errMsgId, CharSequence errString) { }
323a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
3249f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
325ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * Called when a recoverable error has been encountered during enrollment. The help
3269f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * string is provided to give the user guidance for what went wrong, such as
3279f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * "Sensor dirty, please clean it" or what they need to do next, such as
3289f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * "Touch sensor again."
329ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param helpMsgId An integer identifying the error message
330ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param helpString A human-readable string that can be shown in UI
3319f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
332ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onEnrollmentHelp(int helpMsgId, CharSequence helpString) { }
33308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
3349f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
3359f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * Called as each enrollment step progresses. Enrollment is considered complete when
336ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * remaining reaches 0. This function will not be called if enrollment fails. See
3379f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * {@link EnrollmentCallback#onEnrollmentError(int, CharSequence)}
338ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param remaining The number of remaining steps
3399f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
340ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onEnrollmentProgress(int remaining) { }
3419f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    };
34208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
3439f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    /**
3449f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Callback structure provided to {@link FingerprintManager#remove(int). Users of
3459f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * {@link #FingerprintManager()} may optionally provide an implementation of this to
3469f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * {@link FingerprintManager#remove(int, int, RemovalCallback)} for listening to
3479f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * fingerprint template removal events.
348ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *
349ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @hide
3509f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     */
3519f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static abstract class RemovalCallback {
3529f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
3539f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * Called when the given fingerprint can't be removed.
354ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param fp The fingerprint that the call attempted to remove
355ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param errMsgId An associated error message id
356ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param errString An error message indicating why the fingerprint id can't be removed
3579f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
358ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onRemovalError(Fingerprint fp, int errMsgId, CharSequence errString) { }
3599f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
3609f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
3619f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * Called when a given fingerprint is successfully removed.
3629f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * @param fingerprint the fingerprint template that was removed.
3639f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
364ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onRemovalSucceeded(Fingerprint fingerprint) { }
36508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    };
36608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
36708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    /**
368ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * Request authentication of a crypto object. This call warms up the fingerprint hardware
369ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * and starts scanning for a fingerprint. It terminates when
3709f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)} or
3719f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * {@link AuthenticationCallback#onAuthenticationSucceeded(AuthenticationResult) is called, at
3729f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * which point the object is no longer valid. The operation can be canceled by using the
3739f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * provided cancel object.
374d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller     *
3759f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param crypto object associated with the call or null if none required.
3769f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param cancel an object that can be used to cancel authentication
377ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @param callback an object to receive authentication events
378ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @param flags optional flags; should be 0
379d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller     */
380ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
381ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            @NonNull AuthenticationCallback callback, int flags) {
382ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi        authenticate(crypto, cancel, callback, flags, UserHandle.myUserId());
383ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi    }
384ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi
385ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi    /**
386ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * Request authentication of a crypto object. This call warms up the fingerprint hardware
387ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * and starts scanning for a fingerprint. It terminates when
388ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)} or
389ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * {@link AuthenticationCallback#onAuthenticationSucceeded(AuthenticationResult) is called, at
390ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * which point the object is no longer valid. The operation can be canceled by using the
391ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * provided cancel object.
392ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     *
393ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * @param crypto object associated with the call or null if none required.
394ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * @param cancel an object that can be used to cancel authentication
395ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * @param callback an object to receive authentication events
396ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * @param flags optional flags; should be 0
397ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * @param userId the userId the fingerprint belongs to
398ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * @hide
399ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     */
400ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi    public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
401ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi            @NonNull AuthenticationCallback callback, int flags, int userId) {
4029f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        if (callback == null) {
4039f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            throw new IllegalArgumentException("Must supply an authentication callback");
4049f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
4059f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
406ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        if (cancel != null) {
407ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (cancel.isCanceled()) {
408ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                Log.w(TAG, "authentication already canceled");
409ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return;
410ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            } else {
411ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                cancel.setOnCancelListener(new OnAuthenticationCancelListener(crypto));
412ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            }
413ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
4149f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
4159f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        if (mService != null) try {
4169f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mAuthenticationCallback = callback;
4179f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mCryptoObject = crypto;
418ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            long sessionId = crypto != null ? crypto.getOpId() : 0;
419ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi            mService.authenticate(mToken, sessionId, userId, mServiceReceiver, flags);
4209f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        } catch (RemoteException e) {
421ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            Log.w(TAG, "Remote exception while authenticating: ", e);
422ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (callback != null) {
423ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                // Though this may not be a hardware issue, it will cause apps to give up or try
424ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                // again later.
425ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                callback.onAuthenticationError(FINGERPRINT_ERROR_HW_UNAVAILABLE,
426ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                        getErrorString(FINGERPRINT_ERROR_HW_UNAVAILABLE));
427ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            }
4289f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
429d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller    }
430d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller
431d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller    /**
4329f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Request fingerprint enrollment. This call warms up the fingerprint hardware
4339f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * and starts scanning for fingerprints. Progress will be indicated by callbacks to the
4349f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * {@link EnrollmentCallback} object. It terminates when
4359f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * {@link EnrollmentCallback#onEnrollmentError(int, CharSequence)} or
4369f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * {@link EnrollmentCallback#onEnrollmentProgress(int) is called with remaining == 0, at
4379f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * which point the object is no longer valid. The operation can be canceled by using the
4389f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * provided cancel object.
439fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller     * @param token a unique token provided by a recent creation or verification of device
440fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller     * credentials (e.g. pin, pattern or password).
4419f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param cancel an object that can be used to cancel enrollment
442ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @param callback an object to receive enrollment events
4439f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param flags optional flags
444ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @hide
44508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller     */
446fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller    public void enroll(byte [] token, CancellationSignal cancel, EnrollmentCallback callback,
447ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            int flags) {
4489f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        if (callback == null) {
4499f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            throw new IllegalArgumentException("Must supply an enrollment callback");
45008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        }
4519f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
452ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        if (cancel != null) {
453ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (cancel.isCanceled()) {
454ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                Log.w(TAG, "enrollment already canceled");
455ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return;
456ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            } else {
457fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller                cancel.setOnCancelListener(new OnEnrollCancelListener());
458ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            }
459ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
4609f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
46108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        if (mService != null) try {
4629f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mEnrollmentCallback = callback;
463fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller            mService.enroll(mToken, token, getCurrentUserId(), mServiceReceiver, flags);
464ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        } catch (RemoteException e) {
465ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            Log.w(TAG, "Remote exception in enroll: ", e);
466ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (callback != null) {
467ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                // Though this may not be a hardware issue, it will cause apps to give up or try
468ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                // again later.
469ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                callback.onEnrollmentError(FINGERPRINT_ERROR_HW_UNAVAILABLE,
470ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                        getErrorString(FINGERPRINT_ERROR_HW_UNAVAILABLE));
471ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            }
472ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
473ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    }
474ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
475ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
476ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * Requests a pre-enrollment auth token to tie enrollment to the confirmation of
477ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * existing device credentials (e.g. pin/pattern/password).
478ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @hide
479ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
480ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    public long preEnroll() {
481ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        long result = 0;
482ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        if (mService != null) try {
483ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            result = mService.preEnroll(mToken);
48408fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        } catch (RemoteException e) {
485ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            Log.w(TAG, "Remote exception in enroll: ", e);
48608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        }
487ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        return result;
48808fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    }
48908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
49008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    /**
4919f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Remove given fingerprint template from fingerprint hardware and/or protected storage.
4929f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param fp the fingerprint item to remove
4939f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param callback an optional callback to verify that fingerprint templates have been
494ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * successfully removed. May be null of no callback is required.
495ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *
4969f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @hide
49708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller     */
4989f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public void remove(Fingerprint fp, RemovalCallback callback) {
4999f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        if (mService != null) try {
5009f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mRemovalCallback = callback;
5019f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mRemovalFingerprint = fp;
502ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            mService.remove(mToken, fp.getFingerId(), getCurrentUserId(), mServiceReceiver);
5039f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        } catch (RemoteException e) {
504ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            Log.w(TAG, "Remote exception in remove: ", e);
505ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (callback != null) {
506ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                callback.onRemovalError(fp, FINGERPRINT_ERROR_HW_UNAVAILABLE,
507ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                        getErrorString(FINGERPRINT_ERROR_HW_UNAVAILABLE));
508ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            }
50908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        }
51008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    }
51108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
51208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    /**
5139f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Renames the given fingerprint template
5149f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param fpId the fingerprint id
5159f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param newName the new name
516ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *
5179f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @hide
51808fa40c5cb5229b7969b2a5146855a337870f45aJim Miller     */
5199f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public void rename(int fpId, String newName) {
5209f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        // Renames the given fpId
52108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        if (mService != null) {
52208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller            try {
5239f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mService.rename(fpId, getCurrentUserId(), newName);
52408fa40c5cb5229b7969b2a5146855a337870f45aJim Miller            } catch (RemoteException e) {
5259f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                Log.v(TAG, "Remote exception in rename(): ", e);
52608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller            }
527a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        } else {
5289f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            Log.w(TAG, "rename(): Service not connected!");
52908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        }
53008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    }
53108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
5329f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    /**
5339f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Obtain the list of enrolled fingerprints templates.
5349f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @return list of current fingerprint items
535ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *
536ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @hide
5379f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     */
5389f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public List<Fingerprint> getEnrolledFingerprints() {
5399f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        if (mService != null) try {
5409f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            return mService.getEnrolledFingerprints(getCurrentUserId());
54108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        } catch (RemoteException e) {
5429f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            Log.v(TAG, "Remote exception in getEnrolledFingerprints: ", e);
54308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        }
5449f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        return null;
54508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    }
54608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
54708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    /**
5489f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Determine if fingerprint hardware is present and functional.
5499f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @return true if hardware is present and functional, false otherwise.
550ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *
5519f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @hide
55208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller     */
5539f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public boolean isHardwareDetected() {
55408fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        if (mService != null) {
55508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller            try {
5569f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                long deviceId = 0; /* TODO: plumb hardware id to FPMS */
5579f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                return mService.isHardwareDetected(deviceId);
55808fa40c5cb5229b7969b2a5146855a337870f45aJim Miller            } catch (RemoteException e) {
5599f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                Log.v(TAG, "Remote exception in isFingerprintHardwareDetected(): ", e);
56008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller            }
56108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        } else {
5629f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            Log.w(TAG, "isFingerprintHardwareDetected(): Service not connected!");
563a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        }
5649f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        return false;
565a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    }
566a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
5679f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private Handler mHandler = new Handler() {
5689f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public void handleMessage(android.os.Message msg) {
5699f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            switch(msg.what) {
5709f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                case MSG_ENROLL_RESULT:
5719f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    sendEnrollResult((Fingerprint) msg.obj, msg.arg1 /* remaining */);
5729f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    break;
5739f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                case MSG_ACQUIRED:
5749f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    sendAcquiredResult((Long) msg.obj /* deviceId */, msg.arg1 /* acquire info */);
5759f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    break;
576fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller                case MSG_AUTHENTICATED:
577fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller                    sendAuthenticatedResult((Fingerprint) msg.obj);
5789f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    break;
5799f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                case MSG_ERROR:
5809f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    sendErrorResult((Long) msg.obj /* deviceId */, msg.arg1 /* errMsgId */);
5819f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    break;
5829f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                case MSG_REMOVED:
5839f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    sendRemovedResult((Long) msg.obj /* deviceId */, msg.arg1 /* fingerId */,
5849f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                            msg.arg2 /* groupId */);
5859f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            }
58608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        }
5879f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
5889f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        private void sendRemovedResult(long deviceId, int fingerId, int groupId) {
5899f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            if (mRemovalCallback != null) {
5909f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                int reqFingerId = mRemovalFingerprint.getFingerId();
5919f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                int reqGroupId = mRemovalFingerprint.getGroupId();
5929f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                if (fingerId != reqFingerId) {
5939f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    Log.w(TAG, "Finger id didn't match: " + fingerId + " != " + reqFingerId);
5949f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                }
5959f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                if (fingerId != reqFingerId) {
5969f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    Log.w(TAG, "Group id didn't match: " + groupId + " != " + reqGroupId);
5979f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                }
5989f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mRemovalCallback.onRemovalSucceeded(mRemovalFingerprint);
599a7596147b43940cad3f76c53ed154ef088b9269bJim Miller            }
600a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        }
601a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
6029f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        private void sendErrorResult(long deviceId, int errMsgId) {
6039f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            if (mEnrollmentCallback != null) {
6049f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mEnrollmentCallback.onEnrollmentError(errMsgId, getErrorString(errMsgId));
6059f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            } else if (mAuthenticationCallback != null) {
6069f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mAuthenticationCallback.onAuthenticationError(errMsgId, getErrorString(errMsgId));
6079f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            } else if (mRemovalCallback != null) {
6089f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mRemovalCallback.onRemovalError(mRemovalFingerprint, errMsgId,
6099f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                        getErrorString(errMsgId));
6109f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            }
6119f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
6129f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
6139f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        private void sendEnrollResult(Fingerprint fp, int remaining) {
6149f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            if (mEnrollmentCallback != null) {
6159f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mEnrollmentCallback.onEnrollmentProgress(remaining);
6169f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            }
6179f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
6189f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
619fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller        private void sendAuthenticatedResult(Fingerprint fp) {
6209f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            if (mAuthenticationCallback != null) {
621ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                if (fp.getFingerId() == 0 && fp.getGroupId() == 0) {
622ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    // Fingerprint template valid but doesn't match one in database
623ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    mAuthenticationCallback.onAuthenticationFailed();
624ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                } else {
625ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    final AuthenticationResult result = new AuthenticationResult(mCryptoObject, fp);
626ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    mAuthenticationCallback.onAuthenticationSucceeded(result);
627ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                }
6289f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            }
6299f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
6309f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
6319f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        private void sendAcquiredResult(long deviceId, int acquireInfo) {
6329f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            final String msg = getAcquiredString(acquireInfo);
6339f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            if (msg == null) return;
6349f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
6359f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            if (mEnrollmentCallback != null) {
6369f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mEnrollmentCallback.onEnrollmentHelp(acquireInfo, msg);
6379f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            } else if (mAuthenticationCallback != null) {
6389f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mAuthenticationCallback.onAuthenticationHelp(acquireInfo, msg);
6399f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            }
6409f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
6419f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    };
642ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller
643ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    /**
644ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller     * @hide
645ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller     */
6469f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public FingerprintManager(Context context, IFingerprintService service) {
6479f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        mContext = context;
6489f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        mService = service;
6499f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        if (mService == null) {
6509f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            Slog.v(TAG, "FingerprintManagerService was null");
6519f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
6529f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    }
6539f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
6549f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private int getCurrentUserId() {
6559f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        try {
6569f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            return ActivityManagerNative.getDefault().getCurrentUser().id;
6579f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        } catch (RemoteException e) {
6589f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            Log.w(TAG, "Failed to get current user id\n");
6599f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            return UserHandle.USER_NULL;
660ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller        }
661ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    }
662ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller
663ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    private void clearCallbacks() {
664ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        mAuthenticationCallback = null;
665ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        mEnrollmentCallback = null;
666ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        mRemovalCallback = null;
667ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    }
668ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
669fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller    private void cancelEnrollment() {
670ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        if (mService != null) try {
671ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            mService.cancelEnrollment(mToken);
672ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        } catch (RemoteException e) {
673ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (DEBUG) Log.w(TAG, "Remote exception while canceling enrollment");
674ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
675ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    }
676ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
677ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    private void cancelAuthentication(CryptoObject cryptoObject) {
678ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        if (mService != null) try {
679ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            mService.cancelAuthentication(mToken);
680ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        } catch (RemoteException e) {
681ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (DEBUG) Log.w(TAG, "Remote exception while canceling enrollment");
682ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
683ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    }
684ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
685ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    private String getErrorString(int errMsg) {
686ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        switch (errMsg) {
687ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ERROR_UNABLE_TO_PROCESS:
688ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
689ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_error_unable_to_process);
690ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ERROR_HW_UNAVAILABLE:
691ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
692ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_error_hw_not_available);
693ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ERROR_NO_SPACE:
694ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
695ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_error_no_space);
696ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ERROR_TIMEOUT:
697fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller                return mContext.getString(com.android.internal.R.string.fingerprint_error_timeout);
698fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller            case FINGERPRINT_ERROR_CANCELED:
699fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller                return mContext.getString(com.android.internal.R.string.fingerprint_error_canceled);
700fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller            case FINGERPRINT_ERROR_LOCKOUT:
701fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller                return mContext.getString(com.android.internal.R.string.fingerprint_error_lockout);
702ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            default:
703ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                if (errMsg >= FINGERPRINT_ERROR_VENDOR_BASE) {
704ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    int msgNumber = errMsg - FINGERPRINT_ERROR_VENDOR_BASE;
705ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    String[] msgArray = mContext.getResources().getStringArray(
706ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                            com.android.internal.R.array.fingerprint_error_vendor);
707ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    if (msgNumber < msgArray.length) {
708ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                        return msgArray[msgNumber];
709ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    }
7109f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                }
711ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return null;
712ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller        }
713ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    }
71499d6019bead4705b7e126e65b856d538417d4934Jim Miller
715ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    private String getAcquiredString(int acquireInfo) {
716ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        switch (acquireInfo) {
717ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ACQUIRED_GOOD:
718ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return null;
719ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ACQUIRED_PARTIAL:
720ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
721ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_acquired_partial);
722ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ACQUIRED_INSUFFICIENT:
723ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
724ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_acquired_insufficient);
725ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ACQUIRED_IMAGER_DIRTY:
726ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
727ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_acquired_imager_dirty);
728ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ACQUIRED_TOO_SLOW:
729ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
730ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_acquired_too_slow);
731ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ACQUIRED_TOO_FAST:
732ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
733ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_acquired_too_fast);
734ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            default:
735ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                if (acquireInfo >= FINGERPRINT_ACQUIRED_VENDOR_BASE) {
736ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    int msgNumber = acquireInfo - FINGERPRINT_ACQUIRED_VENDOR_BASE;
737ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    String[] msgArray = mContext.getResources().getStringArray(
738ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                            com.android.internal.R.array.fingerprint_acquired_vendor);
739ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    if (msgNumber < msgArray.length) {
740ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                        return msgArray[msgNumber];
741ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    }
7429f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                }
743ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return null;
74499d6019bead4705b7e126e65b856d538417d4934Jim Miller        }
74599d6019bead4705b7e126e65b856d538417d4934Jim Miller    }
7469f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
7479f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private IFingerprintServiceReceiver mServiceReceiver = new IFingerprintServiceReceiver.Stub() {
7489f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
7499f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining) {
7509f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mHandler.obtainMessage(MSG_ENROLL_RESULT, remaining, 0,
7519f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    new Fingerprint(null, groupId, fingerId, deviceId)).sendToTarget();
7529f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
7539f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
7549f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public void onAcquired(long deviceId, int acquireInfo) {
7559f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mHandler.obtainMessage(MSG_ACQUIRED, acquireInfo, 0, deviceId).sendToTarget();
7569f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
7579f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
758fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller        public void onAuthenticated(long deviceId, int fingerId, int groupId) {
759fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller            mHandler.obtainMessage(MSG_AUTHENTICATED,
7609f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    new Fingerprint(null, groupId, fingerId, deviceId)).sendToTarget();
7619f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
7629f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
7639f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public void onError(long deviceId, int error) {
7649f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mHandler.obtainMessage(MSG_ERROR, error, 0, deviceId).sendToTarget();
7659f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
7669f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
7679f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public void onRemoved(long deviceId, int fingerId, int groupId) {
7689f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mHandler.obtainMessage(MSG_REMOVED, fingerId, groupId, deviceId).sendToTarget();
7699f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
7709f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    };
7719f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
77208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller}