FingerprintManager.java revision e0507bbbf95ae6d958c900f32122baf078d47d71
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;
21f501b58de8f467a80fef49c704555781bc61ea6fJim Millerimport android.annotation.RequiresPermission;
2208fa40c5cb5229b7969b2a5146855a337870f45aJim Millerimport android.app.ActivityManagerNative;
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;
29f501b58de8f467a80fef49c704555781bc61ea6fJim Millerimport android.os.Looper;
3008fa40c5cb5229b7969b2a5146855a337870f45aJim Millerimport android.os.RemoteException;
3108fa40c5cb5229b7969b2a5146855a337870f45aJim Millerimport android.os.UserHandle;
32dcdaf87ed0aa99073638bcfe645949f130f0c7adAlex Klyubinimport android.security.keystore.AndroidKeyStoreProvider;
3308fa40c5cb5229b7969b2a5146855a337870f45aJim Millerimport android.util.Log;
34a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport android.util.Slog;
3508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
369f0753f5a378fc80da86305b33244acc6fc53f01Jim Millerimport java.security.Signature;
37ba67aee02cf864793129976cd8a8a46e60c60577Jim Millerimport java.util.List;
38ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller
399f0753f5a378fc80da86305b33244acc6fc53f01Jim Millerimport javax.crypto.Cipher;
40b62dc82b0c7208f106077b46fc7118da6baa6e13Jim Millerimport javax.crypto.Mac;
419f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
42f501b58de8f467a80fef49c704555781bc61ea6fJim Millerimport static android.Manifest.permission.USE_FINGERPRINT;
43f501b58de8f467a80fef49c704555781bc61ea6fJim Millerimport static android.Manifest.permission.MANAGE_FINGERPRINT;
44f501b58de8f467a80fef49c704555781bc61ea6fJim Miller
4508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller/**
4608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * A class that coordinates access to the fingerprint hardware.
47ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller * <p>
48ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller * Use {@link android.content.Context#getSystemService(java.lang.String)}
49ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller * with argument {@link android.content.Context#FINGERPRINT_SERVICE} to get
50ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller * an instance of this class.
5108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller */
5208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
5308fa40c5cb5229b7969b2a5146855a337870f45aJim Millerpublic class FingerprintManager {
5408fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    private static final String TAG = "FingerprintManager";
55d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller    private static final boolean DEBUG = true;
5608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    private static final int MSG_ENROLL_RESULT = 100;
57a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    private static final int MSG_ACQUIRED = 101;
58f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    private static final int MSG_AUTHENTICATION_SUCCEEDED = 102;
59f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    private static final int MSG_AUTHENTICATION_FAILED = 103;
60f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    private static final int MSG_ERROR = 104;
61f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    private static final int MSG_REMOVED = 105;
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.
114f501b58de8f467a80fef49c704555781bc61ea6fJim Miller     * @hide
115ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
1169f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static final int FINGERPRINT_ERROR_VENDOR_BASE = 1000;
11708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
118ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    //
119ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    // Image acquisition messages. Must agree with those in fingerprint.h
120ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    //
121ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
122ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
123ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * The image acquired was good.
124ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
125a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    public static final int FINGERPRINT_ACQUIRED_GOOD = 0;
126ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
127ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
128ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * Only a partial fingerprint image was detected. During enrollment, the user should be
129ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * informed on what needs to happen to resolve this problem, e.g. "press firmly on sensor."
130ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
131a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    public static final int FINGERPRINT_ACQUIRED_PARTIAL = 1;
132ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
133ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
134ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * The fingerprint image was too noisy to process due to a detected condition (i.e. dry skin) or
135ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * a possibly dirty sensor (See {@link #FINGERPRINT_ACQUIRED_IMAGER_DIRTY}).
136ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
137a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    public static final int FINGERPRINT_ACQUIRED_INSUFFICIENT = 2;
138ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
139ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
140ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * The fingerprint image was too noisy due to suspected or detected dirt on the sensor.
141ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * For example, it's reasonable return this after multiple
142ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * {@link #FINGERPRINT_ACQUIRED_INSUFFICIENT} or actual detection of dirt on the sensor
143ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * (stuck pixels, swaths, etc.). The user is expected to take action to clean the sensor
144ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * when this is returned.
145ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
1469f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static final int FINGERPRINT_ACQUIRED_IMAGER_DIRTY = 3;
147ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
148ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
149ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * The fingerprint image was unreadable due to lack of motion. This is most appropriate for
150ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * linear array sensors that require a swipe motion.
151ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
1529f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static final int FINGERPRINT_ACQUIRED_TOO_SLOW = 4;
153ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
154ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
155ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * The fingerprint image was incomplete due to quick motion. While mostly appropriate for
156ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * linear array sensors,  this could also happen if the finger was moved during acquisition.
157ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * The user should be asked to move the finger slower (linear) or leave the finger on the sensor
158ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * longer.
159ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
1609f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static final int FINGERPRINT_ACQUIRED_TOO_FAST = 5;
161ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
162ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
163ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * Hardware vendors may extend this list if there are conditions that do not fall under one of
164ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * the above categories. Vendors are responsible for providing error strings for these errors.
165f501b58de8f467a80fef49c704555781bc61ea6fJim Miller     * @hide
166ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
1679f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static final int FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
168a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
16908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    private IFingerprintService mService;
170d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller    private Context mContext;
171a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    private IBinder mToken = new Binder();
1729f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private AuthenticationCallback mAuthenticationCallback;
1739f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private EnrollmentCallback mEnrollmentCallback;
1749f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private RemovalCallback mRemovalCallback;
1759f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private CryptoObject mCryptoObject;
1769f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private Fingerprint mRemovalFingerprint;
177f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    private Handler mHandler;
178ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
179ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    private class OnEnrollCancelListener implements OnCancelListener {
180ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        @Override
181ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onCancel() {
182fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller            cancelEnrollment();
183ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
184ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    }
185ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
186ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    private class OnAuthenticationCancelListener implements OnCancelListener {
187ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        private CryptoObject mCrypto;
188ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
189ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public OnAuthenticationCancelListener(CryptoObject crypto) {
190ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            mCrypto = crypto;
191ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
192ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
193ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        @Override
194ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onCancel() {
195ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            cancelAuthentication(mCrypto);
196ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
197ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    }
19808fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
1999f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    /**
200ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * A wrapper class for the crypto objects supported by FingerprintManager. Currently the
201b62dc82b0c7208f106077b46fc7118da6baa6e13Jim Miller     * framework supports {@link Signature}, {@link Cipher} and {@link Mac} objects.
2029f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     */
203f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    public static final class CryptoObject {
204ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
205b62dc82b0c7208f106077b46fc7118da6baa6e13Jim Miller        public CryptoObject(@NonNull Signature signature) {
206f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            mCrypto = signature;
207ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
208ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
209b62dc82b0c7208f106077b46fc7118da6baa6e13Jim Miller        public CryptoObject(@NonNull Cipher cipher) {
210f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            mCrypto = cipher;
211b62dc82b0c7208f106077b46fc7118da6baa6e13Jim Miller        }
212b62dc82b0c7208f106077b46fc7118da6baa6e13Jim Miller
213b62dc82b0c7208f106077b46fc7118da6baa6e13Jim Miller        public CryptoObject(@NonNull Mac mac) {
214f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            mCrypto = mac;
215ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
216ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
217ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        /**
218ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * Get {@link Signature} object.
219ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @return {@link Signature} object or null if this doesn't contain one.
220ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         */
221f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        public Signature getSignature() {
222f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            return mCrypto instanceof Signature ? (Signature) mCrypto : null;
223f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        }
224ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
225ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        /**
226ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * Get {@link Cipher} object.
227ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @return {@link Cipher} object or null if this doesn't contain one.
228ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         */
229f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        public Cipher getCipher() {
230f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            return mCrypto instanceof Cipher ? (Cipher) mCrypto : null;
231f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        }
232ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
233ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        /**
234b62dc82b0c7208f106077b46fc7118da6baa6e13Jim Miller         * Get {@link Mac} object.
235b62dc82b0c7208f106077b46fc7118da6baa6e13Jim Miller         * @return {@link Mac} object or null if this doesn't contain one.
236b62dc82b0c7208f106077b46fc7118da6baa6e13Jim Miller         */
237f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        public Mac getMac() {
238f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            return mCrypto instanceof Mac ? (Mac) mCrypto : null;
239f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        }
240b62dc82b0c7208f106077b46fc7118da6baa6e13Jim Miller
241b62dc82b0c7208f106077b46fc7118da6baa6e13Jim Miller        /**
242ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @hide
243ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @return the opId associated with this object or 0 if none
244ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         */
245ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public long getOpId() {
246f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            return mCrypto != null ?
247f501b58de8f467a80fef49c704555781bc61ea6fJim Miller                    AndroidKeyStoreProvider.getKeyStoreOperationHandle(mCrypto) : 0;
248ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
249ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
250f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        private final Object mCrypto;
25108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    };
25208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
2539f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    /**
2549f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Container for callback data from {@link FingerprintManager#authenticate(CryptoObject,
255f501b58de8f467a80fef49c704555781bc61ea6fJim Miller     *     CancellationSignal, int, AuthenticationCallback, Handler)}.
2569f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     */
257748bc36f2eebfdc67520c5025b48fefdfd8d7c01Jim Miller    public static class AuthenticationResult {
2589f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        private Fingerprint mFingerprint;
2599f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        private CryptoObject mCryptoObject;
2609f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
261f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        /**
262f501b58de8f467a80fef49c704555781bc61ea6fJim Miller         * Authentication result
263f501b58de8f467a80fef49c704555781bc61ea6fJim Miller         *
264f501b58de8f467a80fef49c704555781bc61ea6fJim Miller         * @param crypto the crypto object
265f501b58de8f467a80fef49c704555781bc61ea6fJim Miller         * @param fingerprint the recognized fingerprint data, if allowed.
266f501b58de8f467a80fef49c704555781bc61ea6fJim Miller         * @hide
267f501b58de8f467a80fef49c704555781bc61ea6fJim Miller         */
2689f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public AuthenticationResult(CryptoObject crypto, Fingerprint fingerprint) {
2699f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mCryptoObject = crypto;
2709f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mFingerprint = fingerprint;
271ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller        }
2729f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
2739f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
2749f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * Obtain the crypto object associated with this transaction
2759f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * @return crypto object provided to {@link FingerprintManager#authenticate(CryptoObject,
276f501b58de8f467a80fef49c704555781bc61ea6fJim Miller         *     CancellationSignal, int, AuthenticationCallback, Handler)}.
2779f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
2789f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public CryptoObject getCryptoObject() { return mCryptoObject; }
2799f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
2809f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
281ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * Obtain the Fingerprint associated with this operation. Applications are strongly
282ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * discouraged from associating specific fingers with specific applications or operations.
283ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         *
2849f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * @hide
2859f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
2869f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public Fingerprint getFingerprint() { return mFingerprint; }
2879f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    };
288ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller
28906e658f324a937bec1c5ddbe9c3100c3d2fec371Jim Miller    /**
2909f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Callback structure provided to {@link FingerprintManager#authenticate(CryptoObject,
291f501b58de8f467a80fef49c704555781bc61ea6fJim Miller     * CancellationSignal, int, AuthenticationCallback, Handler)}. Users of {@link
292ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * FingerprintManager#authenticate(CryptoObject, CancellationSignal,
293f501b58de8f467a80fef49c704555781bc61ea6fJim Miller     * int, AuthenticationCallback, Handler) } must provide an implementation of this for listening to
294ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * fingerprint events.
29506e658f324a937bec1c5ddbe9c3100c3d2fec371Jim Miller     */
2969f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static abstract class AuthenticationCallback {
2979f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
2989f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * Called when an unrecoverable error has been encountered and the operation is complete.
2999f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * No further callbacks will be made on this object.
300f501b58de8f467a80fef49c704555781bc61ea6fJim Miller         * @param errorCode An integer identifying the error message
301ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param errString A human-readable error string that can be shown in UI
3029f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
303f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        public void onAuthenticationError(int errorCode, CharSequence errString) { }
30408fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
3059f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
306ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * Called when a recoverable error has been encountered during authentication. The help
3079f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * string is provided to give the user guidance for what went wrong, such as
3089f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * "Sensor dirty, please clean it."
309f501b58de8f467a80fef49c704555781bc61ea6fJim Miller         * @param helpCode An integer identifying the error message
310ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param helpString A human-readable string that can be shown in UI
3119f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
312f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        public void onAuthenticationHelp(int helpCode, CharSequence helpString) { }
31308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
3149f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
3159f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * Called when a fingerprint is recognized.
316ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param result An object containing authentication-related data
3179f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
318ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onAuthenticationSucceeded(AuthenticationResult result) { }
319ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
320ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        /**
321ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * Called when a fingerprint is valid but not recognized.
322ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         */
323ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onAuthenticationFailed() { }
3244cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi
3254cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi        /**
3264cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi         * Called when a fingerprint image has been acquired, but wasn't processed yet.
3274cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi         *
3284cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi         * @param acquireInfo one of FINGERPRINT_ACQUIRED_* constants
3294cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi         * @hide
3304cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi         */
3314cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi        public void onAuthenticationAcquired(int acquireInfo) {}
3329f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    };
33308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
3349f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    /**
3359f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Callback structure provided to {@link FingerprintManager#enroll(long, EnrollmentCallback,
3369f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * CancellationSignal, int). Users of {@link #FingerprintManager()}
3379f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * must provide an implementation of this to {@link FingerprintManager#enroll(long,
338f501b58de8f467a80fef49c704555781bc61ea6fJim Miller     * CancellationSignal, int, EnrollmentCallback) for listening to fingerprint events.
339ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *
340ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @hide
3419f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     */
3429f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static abstract class EnrollmentCallback {
3439f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
3449f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * Called when an unrecoverable error has been encountered and the operation is complete.
3459f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * No further callbacks will be made on this object.
346ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param errMsgId An integer identifying the error message
347ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param errString A human-readable error string that can be shown in UI
3489f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
349ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onEnrollmentError(int errMsgId, CharSequence errString) { }
350a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
3519f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
352ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * Called when a recoverable error has been encountered during enrollment. The help
3539f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * string is provided to give the user guidance for what went wrong, such as
3549f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * "Sensor dirty, please clean it" or what they need to do next, such as
3559f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * "Touch sensor again."
356ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param helpMsgId An integer identifying the error message
357ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param helpString A human-readable string that can be shown in UI
3589f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
359ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onEnrollmentHelp(int helpMsgId, CharSequence helpString) { }
36008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
3619f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
3629f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * Called as each enrollment step progresses. Enrollment is considered complete when
363ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * remaining reaches 0. This function will not be called if enrollment fails. See
3649f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * {@link EnrollmentCallback#onEnrollmentError(int, CharSequence)}
365ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param remaining The number of remaining steps
3669f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
367ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onEnrollmentProgress(int remaining) { }
3689f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    };
36908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
3709f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    /**
3719f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Callback structure provided to {@link FingerprintManager#remove(int). Users of
3729f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * {@link #FingerprintManager()} may optionally provide an implementation of this to
3739f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * {@link FingerprintManager#remove(int, int, RemovalCallback)} for listening to
3749f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * fingerprint template removal events.
375ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *
376ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @hide
3779f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     */
3789f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static abstract class RemovalCallback {
3799f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
3809f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * Called when the given fingerprint can't be removed.
381ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param fp The fingerprint that the call attempted to remove
382ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param errMsgId An associated error message id
383ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param errString An error message indicating why the fingerprint id can't be removed
3849f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
385ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onRemovalError(Fingerprint fp, int errMsgId, CharSequence errString) { }
3869f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
3879f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
3889f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * Called when a given fingerprint is successfully removed.
3899f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * @param fingerprint the fingerprint template that was removed.
3909f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
391ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onRemovalSucceeded(Fingerprint fingerprint) { }
39208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    };
39308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
39408fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    /**
395ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * Request authentication of a crypto object. This call warms up the fingerprint hardware
396ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * and starts scanning for a fingerprint. It terminates when
3979f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)} or
3989f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * {@link AuthenticationCallback#onAuthenticationSucceeded(AuthenticationResult) is called, at
3999f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * which point the object is no longer valid. The operation can be canceled by using the
4009f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * provided cancel object.
401d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller     *
4029f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param crypto object associated with the call or null if none required.
4039f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param cancel an object that can be used to cancel authentication
404ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @param flags optional flags; should be 0
405f501b58de8f467a80fef49c704555781bc61ea6fJim Miller     * @param callback an object to receive authentication events
406f501b58de8f467a80fef49c704555781bc61ea6fJim Miller     * @param handler an optional handler to handle callback events
407e4c58e46419bdc1cbe94516bdded71f017534d9cJim Miller     *
408e4c58e46419bdc1cbe94516bdded71f017534d9cJim Miller     * @throws IllegalArgumentException if the crypto operation is not supported or is not backed
409e4c58e46419bdc1cbe94516bdded71f017534d9cJim Miller     *         by <a href="{@docRoot}training/articles/keystore.html">Android Keystore
410e4c58e46419bdc1cbe94516bdded71f017534d9cJim Miller     *         facility</a>.
411e4c58e46419bdc1cbe94516bdded71f017534d9cJim Miller     * @throws IllegalStateException if the crypto primitive is not initialized.
412d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller     */
413f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    @RequiresPermission(USE_FINGERPRINT)
414ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
415f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            int flags, @NonNull AuthenticationCallback callback, @Nullable Handler handler) {
416f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        authenticate(crypto, cancel, flags, callback, handler, UserHandle.myUserId());
417ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi    }
418ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi
419ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi    /**
420f501b58de8f467a80fef49c704555781bc61ea6fJim Miller     * Use the provided handler thread for events.
421f501b58de8f467a80fef49c704555781bc61ea6fJim Miller     * @param handler
422f501b58de8f467a80fef49c704555781bc61ea6fJim Miller     */
423f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    private void useHandler(Handler handler) {
424f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        if (handler != null) {
425f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            mHandler = new MyHandler(handler.getLooper());
426f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        } else if (mHandler.getLooper() != mContext.getMainLooper()){
427f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            mHandler = new MyHandler(mContext.getMainLooper());
428f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        }
429f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    }
430f501b58de8f467a80fef49c704555781bc61ea6fJim Miller
431f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    /**
432f501b58de8f467a80fef49c704555781bc61ea6fJim Miller     * Per-user version
433ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * @hide
434ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     */
435f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    @RequiresPermission(USE_FINGERPRINT)
436ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi    public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
437f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            int flags, @NonNull AuthenticationCallback callback, Handler handler, int userId) {
4389f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        if (callback == null) {
4399f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            throw new IllegalArgumentException("Must supply an authentication callback");
4409f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
4419f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
442ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        if (cancel != null) {
443ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (cancel.isCanceled()) {
444ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                Log.w(TAG, "authentication already canceled");
445ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return;
446ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            } else {
447ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                cancel.setOnCancelListener(new OnAuthenticationCancelListener(crypto));
448ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            }
449ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
4509f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
4519f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        if (mService != null) try {
452f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            useHandler(handler);
4539f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mAuthenticationCallback = callback;
4549f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mCryptoObject = crypto;
455ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            long sessionId = crypto != null ? crypto.getOpId() : 0;
4564af76a51d5082c740609563e07cf35f30bc2224eSvetoslav            mService.authenticate(mToken, sessionId, userId, mServiceReceiver, flags,
4574af76a51d5082c740609563e07cf35f30bc2224eSvetoslav                    mContext.getOpPackageName());
4589f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        } catch (RemoteException e) {
459ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            Log.w(TAG, "Remote exception while authenticating: ", e);
460ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (callback != null) {
461ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                // Though this may not be a hardware issue, it will cause apps to give up or try
462ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                // again later.
463ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                callback.onAuthenticationError(FINGERPRINT_ERROR_HW_UNAVAILABLE,
464ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                        getErrorString(FINGERPRINT_ERROR_HW_UNAVAILABLE));
465ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            }
4669f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
467d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller    }
468d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller
469d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller    /**
4709f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Request fingerprint enrollment. This call warms up the fingerprint hardware
4719f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * and starts scanning for fingerprints. Progress will be indicated by callbacks to the
4729f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * {@link EnrollmentCallback} object. It terminates when
4739f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * {@link EnrollmentCallback#onEnrollmentError(int, CharSequence)} or
4749f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * {@link EnrollmentCallback#onEnrollmentProgress(int) is called with remaining == 0, at
4759f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * which point the object is no longer valid. The operation can be canceled by using the
4769f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * provided cancel object.
477fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller     * @param token a unique token provided by a recent creation or verification of device
478fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller     * credentials (e.g. pin, pattern or password).
4799f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param cancel an object that can be used to cancel enrollment
4809f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param flags optional flags
481f501b58de8f467a80fef49c704555781bc61ea6fJim Miller     * @param callback an object to receive enrollment events
482ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @hide
48308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller     */
484f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    @RequiresPermission(MANAGE_FINGERPRINT)
485f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    public void enroll(byte [] token, CancellationSignal cancel, int flags,
486f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            EnrollmentCallback callback) {
4879f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        if (callback == null) {
4889f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            throw new IllegalArgumentException("Must supply an enrollment callback");
48908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        }
4909f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
491ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        if (cancel != null) {
492ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (cancel.isCanceled()) {
493ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                Log.w(TAG, "enrollment already canceled");
494ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return;
495ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            } else {
496fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller                cancel.setOnCancelListener(new OnEnrollCancelListener());
497ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            }
498ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
4999f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
50008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        if (mService != null) try {
5019f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mEnrollmentCallback = callback;
502fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller            mService.enroll(mToken, token, getCurrentUserId(), mServiceReceiver, flags);
503ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        } catch (RemoteException e) {
504ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            Log.w(TAG, "Remote exception in enroll: ", e);
505ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (callback != null) {
506ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                // Though this may not be a hardware issue, it will cause apps to give up or try
507ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                // again later.
508ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                callback.onEnrollmentError(FINGERPRINT_ERROR_HW_UNAVAILABLE,
509ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                        getErrorString(FINGERPRINT_ERROR_HW_UNAVAILABLE));
510ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            }
511ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
512ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    }
513ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
514ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
515ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * Requests a pre-enrollment auth token to tie enrollment to the confirmation of
516ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * existing device credentials (e.g. pin/pattern/password).
517ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @hide
518ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
519f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    @RequiresPermission(MANAGE_FINGERPRINT)
520ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    public long preEnroll() {
521ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        long result = 0;
522ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        if (mService != null) try {
523ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            result = mService.preEnroll(mToken);
52408fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        } catch (RemoteException e) {
525ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            Log.w(TAG, "Remote exception in enroll: ", e);
52608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        }
527ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        return result;
52808fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    }
52908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
53008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    /**
531e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy     * Finishes enrollment and cancels the current auth token.
532e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy     * @hide
533e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy     */
534e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy    @RequiresPermission(MANAGE_FINGERPRINT)
535e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy    public int postEnroll() {
536e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy        int result = 0;
537e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy        if (mService != null) try {
538e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy            result = mService.postEnroll(mToken);
539e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy        } catch (RemoteException e) {
540e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy            Log.w(TAG, "Remote exception in post enroll: ", e);
541e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy        }
542e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy        return result;
543e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy    }
544e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy
545e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy    /**
5469f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Remove given fingerprint template from fingerprint hardware and/or protected storage.
5479f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param fp the fingerprint item to remove
5489f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param callback an optional callback to verify that fingerprint templates have been
549ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * successfully removed. May be null of no callback is required.
550ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *
5519f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @hide
55208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller     */
553f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    @RequiresPermission(MANAGE_FINGERPRINT)
5549f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public void remove(Fingerprint fp, RemovalCallback callback) {
5559f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        if (mService != null) try {
5569f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mRemovalCallback = callback;
5579f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mRemovalFingerprint = fp;
558ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            mService.remove(mToken, fp.getFingerId(), getCurrentUserId(), mServiceReceiver);
5599f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        } catch (RemoteException e) {
560ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            Log.w(TAG, "Remote exception in remove: ", e);
561ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (callback != null) {
562ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                callback.onRemovalError(fp, FINGERPRINT_ERROR_HW_UNAVAILABLE,
563ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                        getErrorString(FINGERPRINT_ERROR_HW_UNAVAILABLE));
564ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            }
56508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        }
56608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    }
56708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
56808fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    /**
5699f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Renames the given fingerprint template
5709f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param fpId the fingerprint id
5719f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param newName the new name
572ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *
5739f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @hide
57408fa40c5cb5229b7969b2a5146855a337870f45aJim Miller     */
575f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    @RequiresPermission(MANAGE_FINGERPRINT)
5769f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public void rename(int fpId, String newName) {
5779f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        // Renames the given fpId
57808fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        if (mService != null) {
57908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller            try {
5809f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mService.rename(fpId, getCurrentUserId(), newName);
58108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller            } catch (RemoteException e) {
5829f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                Log.v(TAG, "Remote exception in rename(): ", e);
58308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller            }
584a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        } else {
5859f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            Log.w(TAG, "rename(): Service not connected!");
58608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        }
58708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    }
58808fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
5899f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    /**
5909f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Obtain the list of enrolled fingerprints templates.
5919f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @return list of current fingerprint items
592ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *
593ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @hide
5949f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     */
595f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    @RequiresPermission(USE_FINGERPRINT)
5962aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi    public List<Fingerprint> getEnrolledFingerprints(int userId) {
5979f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        if (mService != null) try {
5984af76a51d5082c740609563e07cf35f30bc2224eSvetoslav            return mService.getEnrolledFingerprints(userId, mContext.getOpPackageName());
59908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        } catch (RemoteException e) {
6009f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            Log.v(TAG, "Remote exception in getEnrolledFingerprints: ", e);
60108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        }
6029f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        return null;
60308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    }
60408fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
60508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    /**
6062aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi     * Obtain the list of enrolled fingerprints templates.
6072aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi     * @return list of current fingerprint items
608ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *
6099f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @hide
61008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller     */
611f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    @RequiresPermission(USE_FINGERPRINT)
6122aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi    public List<Fingerprint> getEnrolledFingerprints() {
6132aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi        return getEnrolledFingerprints(UserHandle.myUserId());
6142aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi    }
6152aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi
6162aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi    /**
6172aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi     * Determine if there is at least one fingerprint enrolled.
6182aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi     *
6192aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi     * @return true if at least one fingerprint is enrolled, false otherwise
6202aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi     */
621f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    @RequiresPermission(USE_FINGERPRINT)
6222aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi    public boolean hasEnrolledFingerprints() {
6232aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi        if (mService != null) try {
6244af76a51d5082c740609563e07cf35f30bc2224eSvetoslav            return mService.hasEnrolledFingerprints(UserHandle.myUserId(),
6254af76a51d5082c740609563e07cf35f30bc2224eSvetoslav                    mContext.getOpPackageName());
6262aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi        } catch (RemoteException e) {
6272aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi            Log.v(TAG, "Remote exception in getEnrolledFingerprints: ", e);
6282aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi        }
6292aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi        return false;
6302aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi    }
6312aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi
6322aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi    /**
6332aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi     * Determine if fingerprint hardware is present and functional.
6342aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi     *
6352aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi     * @return true if hardware is present and functional, false otherwise.
6362aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi     */
637f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    @RequiresPermission(USE_FINGERPRINT)
6389f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public boolean isHardwareDetected() {
63908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        if (mService != null) {
64008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller            try {
6419f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                long deviceId = 0; /* TODO: plumb hardware id to FPMS */
6424af76a51d5082c740609563e07cf35f30bc2224eSvetoslav                return mService.isHardwareDetected(deviceId, mContext.getOpPackageName());
64308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller            } catch (RemoteException e) {
6449f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                Log.v(TAG, "Remote exception in isFingerprintHardwareDetected(): ", e);
64508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller            }
64608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        } else {
6479f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            Log.w(TAG, "isFingerprintHardwareDetected(): Service not connected!");
648a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        }
6499f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        return false;
650a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    }
651a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
6524d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales    /**
6534d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales     * Retrieves the authenticator token for binding keys to the lifecycle
6544d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales     * of the current set of fingerprints. Used only by internal clients.
6554d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales     *
6564d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales     * @hide
6574d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales     */
6584d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales    public long getAuthenticatorId() {
6594d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales        if (mService != null) {
6604d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales            try {
6614af76a51d5082c740609563e07cf35f30bc2224eSvetoslav                return mService.getAuthenticatorId(mContext.getOpPackageName());
6624d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales            } catch (RemoteException e) {
6634d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales                Log.v(TAG, "Remote exception in getAuthenticatorId(): ", e);
6644d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales            }
6654d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales        } else {
6664d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales            Log.w(TAG, "getAuthenticatorId(): Service not connected!");
6674d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales        }
6684d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales        return 0;
6694d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales    }
6704d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales
671e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller    /**
672e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller     * Reset the lockout timer when asked to do so by keyguard.
673e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller     *
674e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller     * @param token an opaque token returned by password confirmation.
675e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller     *
676e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller     * @hide
677e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller     */
678e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller    public void resetTimeout(byte[] token) {
679e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller        if (mService != null) {
680e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller            try {
681e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller                mService.resetTimeout(token);
682e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller            } catch (RemoteException e) {
683e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller                Log.v(TAG, "Remote exception in getAuthenticatorId(): ", e);
684e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller            }
685e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller        } else {
686e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller            Log.w(TAG, "getAuthenticatorId(): Service not connected!");
687e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller        }
688e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller    }
689e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller
69024e9e966a85c416a94482fcd10dbdd10ceeb9e6cAlex Klyubin    private class MyHandler extends Handler {
69124e9e966a85c416a94482fcd10dbdd10ceeb9e6cAlex Klyubin        private MyHandler(Context context) {
69224e9e966a85c416a94482fcd10dbdd10ceeb9e6cAlex Klyubin            super(context.getMainLooper());
69324e9e966a85c416a94482fcd10dbdd10ceeb9e6cAlex Klyubin        }
69424e9e966a85c416a94482fcd10dbdd10ceeb9e6cAlex Klyubin
695f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        private MyHandler(Looper looper) {
696f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            super(looper);
697f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        }
698f501b58de8f467a80fef49c704555781bc61ea6fJim Miller
699e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller        @Override
7009f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public void handleMessage(android.os.Message msg) {
7019f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            switch(msg.what) {
7029f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                case MSG_ENROLL_RESULT:
7039f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    sendEnrollResult((Fingerprint) msg.obj, msg.arg1 /* remaining */);
7049f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    break;
7059f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                case MSG_ACQUIRED:
7069f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    sendAcquiredResult((Long) msg.obj /* deviceId */, msg.arg1 /* acquire info */);
7079f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    break;
708f501b58de8f467a80fef49c704555781bc61ea6fJim Miller                case MSG_AUTHENTICATION_SUCCEEDED:
709f501b58de8f467a80fef49c704555781bc61ea6fJim Miller                    sendAuthenticatedSucceeded((Fingerprint) msg.obj);
710f501b58de8f467a80fef49c704555781bc61ea6fJim Miller                    break;
711f501b58de8f467a80fef49c704555781bc61ea6fJim Miller                case MSG_AUTHENTICATION_FAILED:
712f501b58de8f467a80fef49c704555781bc61ea6fJim Miller                    sendAuthenticatedFailed();
7139f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    break;
7149f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                case MSG_ERROR:
7159f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    sendErrorResult((Long) msg.obj /* deviceId */, msg.arg1 /* errMsgId */);
7169f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    break;
7179f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                case MSG_REMOVED:
7189f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    sendRemovedResult((Long) msg.obj /* deviceId */, msg.arg1 /* fingerId */,
7199f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                            msg.arg2 /* groupId */);
7209f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            }
72108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        }
7229f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
7239f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        private void sendRemovedResult(long deviceId, int fingerId, int groupId) {
7249f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            if (mRemovalCallback != null) {
7259f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                int reqFingerId = mRemovalFingerprint.getFingerId();
7269f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                int reqGroupId = mRemovalFingerprint.getGroupId();
7279f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                if (fingerId != reqFingerId) {
7289f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    Log.w(TAG, "Finger id didn't match: " + fingerId + " != " + reqFingerId);
7299f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                }
7309f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                if (fingerId != reqFingerId) {
7319f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    Log.w(TAG, "Group id didn't match: " + groupId + " != " + reqGroupId);
7329f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                }
7339f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mRemovalCallback.onRemovalSucceeded(mRemovalFingerprint);
734a7596147b43940cad3f76c53ed154ef088b9269bJim Miller            }
735a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        }
736a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
7379f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        private void sendErrorResult(long deviceId, int errMsgId) {
7389f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            if (mEnrollmentCallback != null) {
7399f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mEnrollmentCallback.onEnrollmentError(errMsgId, getErrorString(errMsgId));
7409f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            } else if (mAuthenticationCallback != null) {
7419f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mAuthenticationCallback.onAuthenticationError(errMsgId, getErrorString(errMsgId));
7429f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            } else if (mRemovalCallback != null) {
7439f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mRemovalCallback.onRemovalError(mRemovalFingerprint, errMsgId,
7449f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                        getErrorString(errMsgId));
7459f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            }
7469f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
7479f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
7489f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        private void sendEnrollResult(Fingerprint fp, int remaining) {
7499f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            if (mEnrollmentCallback != null) {
7509f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mEnrollmentCallback.onEnrollmentProgress(remaining);
7519f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            }
7529f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
7539f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
754f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        private void sendAuthenticatedSucceeded(Fingerprint fp) {
7559f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            if (mAuthenticationCallback != null) {
756f501b58de8f467a80fef49c704555781bc61ea6fJim Miller                final AuthenticationResult result = new AuthenticationResult(mCryptoObject, fp);
757f501b58de8f467a80fef49c704555781bc61ea6fJim Miller                mAuthenticationCallback.onAuthenticationSucceeded(result);
758f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            }
759f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        }
760f501b58de8f467a80fef49c704555781bc61ea6fJim Miller
761f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        private void sendAuthenticatedFailed() {
762f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            if (mAuthenticationCallback != null) {
763f501b58de8f467a80fef49c704555781bc61ea6fJim Miller               mAuthenticationCallback.onAuthenticationFailed();
7649f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            }
7659f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
7669f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
7679f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        private void sendAcquiredResult(long deviceId, int acquireInfo) {
7684cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi            if (mAuthenticationCallback != null) {
7694cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi                mAuthenticationCallback.onAuthenticationAcquired(acquireInfo);
7704cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi            }
7719f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            final String msg = getAcquiredString(acquireInfo);
7724cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi            if (msg == null) {
7734cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi                return;
7744cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi            }
7759f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            if (mEnrollmentCallback != null) {
7769f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mEnrollmentCallback.onEnrollmentHelp(acquireInfo, msg);
7779f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            } else if (mAuthenticationCallback != null) {
7789f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mAuthenticationCallback.onAuthenticationHelp(acquireInfo, msg);
7799f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            }
7809f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
7819f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    };
782ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller
783ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    /**
784ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller     * @hide
785ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller     */
7869f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public FingerprintManager(Context context, IFingerprintService service) {
7879f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        mContext = context;
7889f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        mService = service;
7899f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        if (mService == null) {
7909f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            Slog.v(TAG, "FingerprintManagerService was null");
7919f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
79224e9e966a85c416a94482fcd10dbdd10ceeb9e6cAlex Klyubin        mHandler = new MyHandler(context);
7939f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    }
7949f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
7959f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private int getCurrentUserId() {
7969f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        try {
7979f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            return ActivityManagerNative.getDefault().getCurrentUser().id;
7989f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        } catch (RemoteException e) {
7999f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            Log.w(TAG, "Failed to get current user id\n");
8009f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            return UserHandle.USER_NULL;
801ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller        }
802ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    }
803ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller
804fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller    private void cancelEnrollment() {
805ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        if (mService != null) try {
806ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            mService.cancelEnrollment(mToken);
807ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        } catch (RemoteException e) {
808ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (DEBUG) Log.w(TAG, "Remote exception while canceling enrollment");
809ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
810ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    }
811ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
812ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    private void cancelAuthentication(CryptoObject cryptoObject) {
813ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        if (mService != null) try {
8144af76a51d5082c740609563e07cf35f30bc2224eSvetoslav            mService.cancelAuthentication(mToken, mContext.getOpPackageName());
815ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        } catch (RemoteException e) {
816ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (DEBUG) Log.w(TAG, "Remote exception while canceling enrollment");
817ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
818ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    }
819ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
820ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    private String getErrorString(int errMsg) {
821ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        switch (errMsg) {
822ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ERROR_UNABLE_TO_PROCESS:
823ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
824ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_error_unable_to_process);
825ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ERROR_HW_UNAVAILABLE:
826ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
827ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_error_hw_not_available);
828ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ERROR_NO_SPACE:
829ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
830ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_error_no_space);
831ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ERROR_TIMEOUT:
832fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller                return mContext.getString(com.android.internal.R.string.fingerprint_error_timeout);
833fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller            case FINGERPRINT_ERROR_CANCELED:
834fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller                return mContext.getString(com.android.internal.R.string.fingerprint_error_canceled);
835fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller            case FINGERPRINT_ERROR_LOCKOUT:
836fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller                return mContext.getString(com.android.internal.R.string.fingerprint_error_lockout);
837ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            default:
838ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                if (errMsg >= FINGERPRINT_ERROR_VENDOR_BASE) {
839ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    int msgNumber = errMsg - FINGERPRINT_ERROR_VENDOR_BASE;
840ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    String[] msgArray = mContext.getResources().getStringArray(
841ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                            com.android.internal.R.array.fingerprint_error_vendor);
842ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    if (msgNumber < msgArray.length) {
843ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                        return msgArray[msgNumber];
844ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    }
8459f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                }
846ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return null;
847ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller        }
848ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    }
84999d6019bead4705b7e126e65b856d538417d4934Jim Miller
850ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    private String getAcquiredString(int acquireInfo) {
851ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        switch (acquireInfo) {
852ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ACQUIRED_GOOD:
853ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return null;
854ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ACQUIRED_PARTIAL:
855ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
856ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_acquired_partial);
857ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ACQUIRED_INSUFFICIENT:
858ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
859ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_acquired_insufficient);
860ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ACQUIRED_IMAGER_DIRTY:
861ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
862ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_acquired_imager_dirty);
863ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ACQUIRED_TOO_SLOW:
864ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
865ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_acquired_too_slow);
866ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ACQUIRED_TOO_FAST:
867ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
868ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_acquired_too_fast);
869ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            default:
870ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                if (acquireInfo >= FINGERPRINT_ACQUIRED_VENDOR_BASE) {
871ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    int msgNumber = acquireInfo - FINGERPRINT_ACQUIRED_VENDOR_BASE;
872ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    String[] msgArray = mContext.getResources().getStringArray(
873ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                            com.android.internal.R.array.fingerprint_acquired_vendor);
874ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    if (msgNumber < msgArray.length) {
875ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                        return msgArray[msgNumber];
876ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    }
8779f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                }
878ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return null;
87999d6019bead4705b7e126e65b856d538417d4934Jim Miller        }
88099d6019bead4705b7e126e65b856d538417d4934Jim Miller    }
8819f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
8829f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private IFingerprintServiceReceiver mServiceReceiver = new IFingerprintServiceReceiver.Stub() {
8839f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
884f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        @Override // binder call
8859f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining) {
8869f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mHandler.obtainMessage(MSG_ENROLL_RESULT, remaining, 0,
8879f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    new Fingerprint(null, groupId, fingerId, deviceId)).sendToTarget();
8889f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
8899f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
890f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        @Override // binder call
8919f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public void onAcquired(long deviceId, int acquireInfo) {
8929f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mHandler.obtainMessage(MSG_ACQUIRED, acquireInfo, 0, deviceId).sendToTarget();
8939f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
8949f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
895f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        @Override // binder call
896f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        public void onAuthenticationSucceeded(long deviceId, Fingerprint fp) {
897f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            mHandler.obtainMessage(MSG_AUTHENTICATION_SUCCEEDED, fp).sendToTarget();
898f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        }
899f501b58de8f467a80fef49c704555781bc61ea6fJim Miller
900f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        @Override // binder call
901f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        public void onAuthenticationFailed(long deviceId) {
902f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            mHandler.obtainMessage(MSG_AUTHENTICATION_FAILED).sendToTarget();;
9039f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
9049f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
905f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        @Override // binder call
9069f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public void onError(long deviceId, int error) {
9079f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mHandler.obtainMessage(MSG_ERROR, error, 0, deviceId).sendToTarget();
9089f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
9099f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
910f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        @Override // binder call
9119f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public void onRemoved(long deviceId, int fingerId, int groupId) {
9129f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mHandler.obtainMessage(MSG_REMOVED, fingerId, groupId, deviceId).sendToTarget();
9139f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
9149f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    };
9159f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
9164d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales}
9174d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales
918