FingerprintManager.java revision 3a464785088e7fd206666f640912729533948ce8
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    /**
3953a464785088e7fd206666f640912729533948ce8Jorim Jaggi     * @hide
3963a464785088e7fd206666f640912729533948ce8Jorim Jaggi     */
3973a464785088e7fd206666f640912729533948ce8Jorim Jaggi    public static abstract class LockoutResetCallback {
3983a464785088e7fd206666f640912729533948ce8Jorim Jaggi
3993a464785088e7fd206666f640912729533948ce8Jorim Jaggi        /**
4003a464785088e7fd206666f640912729533948ce8Jorim Jaggi         * Called when lockout period expired and clients are allowed to listen for fingerprint
4013a464785088e7fd206666f640912729533948ce8Jorim Jaggi         * again.
4023a464785088e7fd206666f640912729533948ce8Jorim Jaggi         */
4033a464785088e7fd206666f640912729533948ce8Jorim Jaggi        public void onLockoutReset() { }
4043a464785088e7fd206666f640912729533948ce8Jorim Jaggi    };
4053a464785088e7fd206666f640912729533948ce8Jorim Jaggi
4063a464785088e7fd206666f640912729533948ce8Jorim Jaggi    /**
407ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * Request authentication of a crypto object. This call warms up the fingerprint hardware
408ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * and starts scanning for a fingerprint. It terminates when
4099f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)} or
4105f69ca3be3005fd127c82f503d0692f807729688Jim Miller     * {@link AuthenticationCallback#onAuthenticationSucceeded(AuthenticationResult)} is called, at
4119f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * which point the object is no longer valid. The operation can be canceled by using the
4129f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * provided cancel object.
413d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller     *
4149f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param crypto object associated with the call or null if none required.
4159f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param cancel an object that can be used to cancel authentication
416ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @param flags optional flags; should be 0
417f501b58de8f467a80fef49c704555781bc61ea6fJim Miller     * @param callback an object to receive authentication events
418f501b58de8f467a80fef49c704555781bc61ea6fJim Miller     * @param handler an optional handler to handle callback events
419e4c58e46419bdc1cbe94516bdded71f017534d9cJim Miller     *
420e4c58e46419bdc1cbe94516bdded71f017534d9cJim Miller     * @throws IllegalArgumentException if the crypto operation is not supported or is not backed
421e4c58e46419bdc1cbe94516bdded71f017534d9cJim Miller     *         by <a href="{@docRoot}training/articles/keystore.html">Android Keystore
422e4c58e46419bdc1cbe94516bdded71f017534d9cJim Miller     *         facility</a>.
423e4c58e46419bdc1cbe94516bdded71f017534d9cJim Miller     * @throws IllegalStateException if the crypto primitive is not initialized.
424d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller     */
425f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    @RequiresPermission(USE_FINGERPRINT)
426ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
427f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            int flags, @NonNull AuthenticationCallback callback, @Nullable Handler handler) {
428f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        authenticate(crypto, cancel, flags, callback, handler, UserHandle.myUserId());
429ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi    }
430ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi
431ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi    /**
432f501b58de8f467a80fef49c704555781bc61ea6fJim Miller     * Use the provided handler thread for events.
433f501b58de8f467a80fef49c704555781bc61ea6fJim Miller     * @param handler
434f501b58de8f467a80fef49c704555781bc61ea6fJim Miller     */
435f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    private void useHandler(Handler handler) {
436f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        if (handler != null) {
437f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            mHandler = new MyHandler(handler.getLooper());
438f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        } else if (mHandler.getLooper() != mContext.getMainLooper()){
439f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            mHandler = new MyHandler(mContext.getMainLooper());
440f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        }
441f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    }
442f501b58de8f467a80fef49c704555781bc61ea6fJim Miller
443f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    /**
444f501b58de8f467a80fef49c704555781bc61ea6fJim Miller     * Per-user version
445ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * @hide
446ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     */
447f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    @RequiresPermission(USE_FINGERPRINT)
448ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi    public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
449f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            int flags, @NonNull AuthenticationCallback callback, Handler handler, int userId) {
4509f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        if (callback == null) {
4519f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            throw new IllegalArgumentException("Must supply an authentication callback");
4529f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
4539f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
454ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        if (cancel != null) {
455ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (cancel.isCanceled()) {
456ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                Log.w(TAG, "authentication already canceled");
457ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return;
458ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            } else {
459ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                cancel.setOnCancelListener(new OnAuthenticationCancelListener(crypto));
460ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            }
461ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
4629f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
4639f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        if (mService != null) try {
464f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            useHandler(handler);
4659f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mAuthenticationCallback = callback;
4669f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mCryptoObject = crypto;
467ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            long sessionId = crypto != null ? crypto.getOpId() : 0;
4684af76a51d5082c740609563e07cf35f30bc2224eSvetoslav            mService.authenticate(mToken, sessionId, userId, mServiceReceiver, flags,
4694af76a51d5082c740609563e07cf35f30bc2224eSvetoslav                    mContext.getOpPackageName());
4709f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        } catch (RemoteException e) {
471ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            Log.w(TAG, "Remote exception while authenticating: ", e);
472ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (callback != null) {
473ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                // Though this may not be a hardware issue, it will cause apps to give up or try
474ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                // again later.
475ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                callback.onAuthenticationError(FINGERPRINT_ERROR_HW_UNAVAILABLE,
476ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                        getErrorString(FINGERPRINT_ERROR_HW_UNAVAILABLE));
477ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            }
4789f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
479d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller    }
480d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller
481d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller    /**
4829f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Request fingerprint enrollment. This call warms up the fingerprint hardware
4839f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * and starts scanning for fingerprints. Progress will be indicated by callbacks to the
4849f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * {@link EnrollmentCallback} object. It terminates when
4859f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * {@link EnrollmentCallback#onEnrollmentError(int, CharSequence)} or
4869f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * {@link EnrollmentCallback#onEnrollmentProgress(int) is called with remaining == 0, at
4879f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * which point the object is no longer valid. The operation can be canceled by using the
4889f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * provided cancel object.
489fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller     * @param token a unique token provided by a recent creation or verification of device
490fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller     * credentials (e.g. pin, pattern or password).
4919f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param cancel an object that can be used to cancel enrollment
4929f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param flags optional flags
493f501b58de8f467a80fef49c704555781bc61ea6fJim Miller     * @param callback an object to receive enrollment events
494ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @hide
49508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller     */
496f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    @RequiresPermission(MANAGE_FINGERPRINT)
497f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    public void enroll(byte [] token, CancellationSignal cancel, int flags,
498f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            EnrollmentCallback callback) {
4999f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        if (callback == null) {
5009f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            throw new IllegalArgumentException("Must supply an enrollment callback");
50108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        }
5029f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
503ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        if (cancel != null) {
504ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (cancel.isCanceled()) {
505ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                Log.w(TAG, "enrollment already canceled");
506ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return;
507ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            } else {
508fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller                cancel.setOnCancelListener(new OnEnrollCancelListener());
509ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            }
510ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
5119f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
51208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        if (mService != null) try {
5139f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mEnrollmentCallback = callback;
514fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller            mService.enroll(mToken, token, getCurrentUserId(), mServiceReceiver, flags);
515ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        } catch (RemoteException e) {
516ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            Log.w(TAG, "Remote exception in enroll: ", e);
517ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (callback != null) {
518ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                // Though this may not be a hardware issue, it will cause apps to give up or try
519ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                // again later.
520ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                callback.onEnrollmentError(FINGERPRINT_ERROR_HW_UNAVAILABLE,
521ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                        getErrorString(FINGERPRINT_ERROR_HW_UNAVAILABLE));
522ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            }
523ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
524ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    }
525ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
526ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
527ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * Requests a pre-enrollment auth token to tie enrollment to the confirmation of
528ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * existing device credentials (e.g. pin/pattern/password).
529ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @hide
530ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
531f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    @RequiresPermission(MANAGE_FINGERPRINT)
532ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    public long preEnroll() {
533ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        long result = 0;
534ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        if (mService != null) try {
535ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            result = mService.preEnroll(mToken);
53608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        } catch (RemoteException e) {
537ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            Log.w(TAG, "Remote exception in enroll: ", e);
53808fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        }
539ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        return result;
54008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    }
54108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
54208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    /**
543e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy     * Finishes enrollment and cancels the current auth token.
544e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy     * @hide
545e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy     */
546e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy    @RequiresPermission(MANAGE_FINGERPRINT)
547e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy    public int postEnroll() {
548e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy        int result = 0;
549e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy        if (mService != null) try {
550e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy            result = mService.postEnroll(mToken);
551e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy        } catch (RemoteException e) {
552e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy            Log.w(TAG, "Remote exception in post enroll: ", e);
553e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy        }
554e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy        return result;
555e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy    }
556e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy
557e0943cf5665b3d7b0870debda771032f77db094cSasha Levitskiy    /**
5589f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Remove given fingerprint template from fingerprint hardware and/or protected storage.
5599f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param fp the fingerprint item to remove
5609f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param callback an optional callback to verify that fingerprint templates have been
561ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * successfully removed. May be null of no callback is required.
562ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *
5639f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @hide
56408fa40c5cb5229b7969b2a5146855a337870f45aJim Miller     */
565f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    @RequiresPermission(MANAGE_FINGERPRINT)
5669f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public void remove(Fingerprint fp, RemovalCallback callback) {
5679f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        if (mService != null) try {
5689f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mRemovalCallback = callback;
5699f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mRemovalFingerprint = fp;
570ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            mService.remove(mToken, fp.getFingerId(), getCurrentUserId(), mServiceReceiver);
5719f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        } catch (RemoteException e) {
572ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            Log.w(TAG, "Remote exception in remove: ", e);
573ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (callback != null) {
574ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                callback.onRemovalError(fp, FINGERPRINT_ERROR_HW_UNAVAILABLE,
575ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                        getErrorString(FINGERPRINT_ERROR_HW_UNAVAILABLE));
576ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            }
57708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        }
57808fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    }
57908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
58008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    /**
5819f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Renames the given fingerprint template
5829f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param fpId the fingerprint id
5839f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param newName the new name
584ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *
5859f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @hide
58608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller     */
587f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    @RequiresPermission(MANAGE_FINGERPRINT)
5889f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public void rename(int fpId, String newName) {
5899f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        // Renames the given fpId
59008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        if (mService != null) {
59108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller            try {
5929f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mService.rename(fpId, getCurrentUserId(), newName);
59308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller            } catch (RemoteException e) {
5949f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                Log.v(TAG, "Remote exception in rename(): ", e);
59508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller            }
596a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        } else {
5979f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            Log.w(TAG, "rename(): Service not connected!");
59808fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        }
59908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    }
60008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
6019f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    /**
6029f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Obtain the list of enrolled fingerprints templates.
6039f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @return list of current fingerprint items
604ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *
605ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @hide
6069f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     */
607f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    @RequiresPermission(USE_FINGERPRINT)
6082aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi    public List<Fingerprint> getEnrolledFingerprints(int userId) {
6099f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        if (mService != null) try {
6104af76a51d5082c740609563e07cf35f30bc2224eSvetoslav            return mService.getEnrolledFingerprints(userId, mContext.getOpPackageName());
61108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        } catch (RemoteException e) {
6129f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            Log.v(TAG, "Remote exception in getEnrolledFingerprints: ", e);
61308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        }
6149f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        return null;
61508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    }
61608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
61708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    /**
6182aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi     * Obtain the list of enrolled fingerprints templates.
6192aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi     * @return list of current fingerprint items
620ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *
6219f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @hide
62208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller     */
623f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    @RequiresPermission(USE_FINGERPRINT)
6242aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi    public List<Fingerprint> getEnrolledFingerprints() {
6252aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi        return getEnrolledFingerprints(UserHandle.myUserId());
6262aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi    }
6272aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi
6282aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi    /**
6292aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi     * Determine if there is at least one fingerprint enrolled.
6302aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi     *
6312aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi     * @return true if at least one fingerprint is enrolled, false otherwise
6322aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi     */
633f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    @RequiresPermission(USE_FINGERPRINT)
6342aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi    public boolean hasEnrolledFingerprints() {
6352aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi        if (mService != null) try {
6364af76a51d5082c740609563e07cf35f30bc2224eSvetoslav            return mService.hasEnrolledFingerprints(UserHandle.myUserId(),
6374af76a51d5082c740609563e07cf35f30bc2224eSvetoslav                    mContext.getOpPackageName());
6382aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi        } catch (RemoteException e) {
6392aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi            Log.v(TAG, "Remote exception in getEnrolledFingerprints: ", e);
6402aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi        }
6412aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi        return false;
6422aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi    }
6432aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi
6442aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi    /**
6452aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi     * Determine if fingerprint hardware is present and functional.
6462aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi     *
6472aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi     * @return true if hardware is present and functional, false otherwise.
6482aad7ee245857a46aae305fefc4e3c1bcdd4a586Jorim Jaggi     */
649f501b58de8f467a80fef49c704555781bc61ea6fJim Miller    @RequiresPermission(USE_FINGERPRINT)
6509f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public boolean isHardwareDetected() {
65108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        if (mService != null) {
65208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller            try {
6539f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                long deviceId = 0; /* TODO: plumb hardware id to FPMS */
6544af76a51d5082c740609563e07cf35f30bc2224eSvetoslav                return mService.isHardwareDetected(deviceId, mContext.getOpPackageName());
65508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller            } catch (RemoteException e) {
6569f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                Log.v(TAG, "Remote exception in isFingerprintHardwareDetected(): ", e);
65708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller            }
65808fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        } else {
6599f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            Log.w(TAG, "isFingerprintHardwareDetected(): Service not connected!");
660a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        }
6619f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        return false;
662a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    }
663a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
6644d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales    /**
6654d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales     * Retrieves the authenticator token for binding keys to the lifecycle
6664d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales     * of the current set of fingerprints. Used only by internal clients.
6674d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales     *
6684d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales     * @hide
6694d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales     */
6704d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales    public long getAuthenticatorId() {
6714d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales        if (mService != null) {
6724d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales            try {
6734af76a51d5082c740609563e07cf35f30bc2224eSvetoslav                return mService.getAuthenticatorId(mContext.getOpPackageName());
6744d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales            } catch (RemoteException e) {
6754d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales                Log.v(TAG, "Remote exception in getAuthenticatorId(): ", e);
6764d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales            }
6774d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales        } else {
6784d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales            Log.w(TAG, "getAuthenticatorId(): Service not connected!");
6794d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales        }
6804d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales        return 0;
6814d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales    }
6824d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales
683e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller    /**
684e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller     * Reset the lockout timer when asked to do so by keyguard.
685e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller     *
686e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller     * @param token an opaque token returned by password confirmation.
687e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller     *
688e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller     * @hide
689e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller     */
690e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller    public void resetTimeout(byte[] token) {
691e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller        if (mService != null) {
692e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller            try {
693e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller                mService.resetTimeout(token);
694e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller            } catch (RemoteException e) {
6953a464785088e7fd206666f640912729533948ce8Jorim Jaggi                Log.v(TAG, "Remote exception in resetTimeout(): ", e);
696e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller            }
697e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller        } else {
6983a464785088e7fd206666f640912729533948ce8Jorim Jaggi            Log.w(TAG, "resetTimeout(): Service not connected!");
6993a464785088e7fd206666f640912729533948ce8Jorim Jaggi        }
7003a464785088e7fd206666f640912729533948ce8Jorim Jaggi    }
7013a464785088e7fd206666f640912729533948ce8Jorim Jaggi
7023a464785088e7fd206666f640912729533948ce8Jorim Jaggi    /**
7033a464785088e7fd206666f640912729533948ce8Jorim Jaggi     * @hide
7043a464785088e7fd206666f640912729533948ce8Jorim Jaggi     */
7053a464785088e7fd206666f640912729533948ce8Jorim Jaggi    public void addLockoutResetCallback(final LockoutResetCallback callback) {
7063a464785088e7fd206666f640912729533948ce8Jorim Jaggi        if (mService != null) {
7073a464785088e7fd206666f640912729533948ce8Jorim Jaggi            try {
7083a464785088e7fd206666f640912729533948ce8Jorim Jaggi                mService.addLockoutResetCallback(
7093a464785088e7fd206666f640912729533948ce8Jorim Jaggi                        new IFingerprintServiceLockoutResetCallback.Stub() {
7103a464785088e7fd206666f640912729533948ce8Jorim Jaggi
7113a464785088e7fd206666f640912729533948ce8Jorim Jaggi                    @Override
7123a464785088e7fd206666f640912729533948ce8Jorim Jaggi                    public void onLockoutReset(long deviceId) throws RemoteException {
7133a464785088e7fd206666f640912729533948ce8Jorim Jaggi                        mHandler.post(new Runnable() {
7143a464785088e7fd206666f640912729533948ce8Jorim Jaggi                            @Override
7153a464785088e7fd206666f640912729533948ce8Jorim Jaggi                            public void run() {
7163a464785088e7fd206666f640912729533948ce8Jorim Jaggi                                callback.onLockoutReset();
7173a464785088e7fd206666f640912729533948ce8Jorim Jaggi                            }
7183a464785088e7fd206666f640912729533948ce8Jorim Jaggi                        });
7193a464785088e7fd206666f640912729533948ce8Jorim Jaggi                    }
7203a464785088e7fd206666f640912729533948ce8Jorim Jaggi                });
7213a464785088e7fd206666f640912729533948ce8Jorim Jaggi            } catch (RemoteException e) {
7223a464785088e7fd206666f640912729533948ce8Jorim Jaggi                Log.v(TAG, "Remote exception in addLockoutResetCallback(): ", e);
7233a464785088e7fd206666f640912729533948ce8Jorim Jaggi            }
7243a464785088e7fd206666f640912729533948ce8Jorim Jaggi        } else {
7253a464785088e7fd206666f640912729533948ce8Jorim Jaggi            Log.w(TAG, "addLockoutResetCallback(): Service not connected!");
726e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller        }
727e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller    }
728e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller
72924e9e966a85c416a94482fcd10dbdd10ceeb9e6cAlex Klyubin    private class MyHandler extends Handler {
73024e9e966a85c416a94482fcd10dbdd10ceeb9e6cAlex Klyubin        private MyHandler(Context context) {
73124e9e966a85c416a94482fcd10dbdd10ceeb9e6cAlex Klyubin            super(context.getMainLooper());
73224e9e966a85c416a94482fcd10dbdd10ceeb9e6cAlex Klyubin        }
73324e9e966a85c416a94482fcd10dbdd10ceeb9e6cAlex Klyubin
734f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        private MyHandler(Looper looper) {
735f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            super(looper);
736f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        }
737f501b58de8f467a80fef49c704555781bc61ea6fJim Miller
738e0507bbbf95ae6d958c900f32122baf078d47d71Jim Miller        @Override
7399f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public void handleMessage(android.os.Message msg) {
7409f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            switch(msg.what) {
7419f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                case MSG_ENROLL_RESULT:
7429f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    sendEnrollResult((Fingerprint) msg.obj, msg.arg1 /* remaining */);
7439f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    break;
7449f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                case MSG_ACQUIRED:
7459f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    sendAcquiredResult((Long) msg.obj /* deviceId */, msg.arg1 /* acquire info */);
7469f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    break;
747f501b58de8f467a80fef49c704555781bc61ea6fJim Miller                case MSG_AUTHENTICATION_SUCCEEDED:
748f501b58de8f467a80fef49c704555781bc61ea6fJim Miller                    sendAuthenticatedSucceeded((Fingerprint) msg.obj);
749f501b58de8f467a80fef49c704555781bc61ea6fJim Miller                    break;
750f501b58de8f467a80fef49c704555781bc61ea6fJim Miller                case MSG_AUTHENTICATION_FAILED:
751f501b58de8f467a80fef49c704555781bc61ea6fJim Miller                    sendAuthenticatedFailed();
7529f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    break;
7539f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                case MSG_ERROR:
7549f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    sendErrorResult((Long) msg.obj /* deviceId */, msg.arg1 /* errMsgId */);
7559f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    break;
7569f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                case MSG_REMOVED:
7579f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    sendRemovedResult((Long) msg.obj /* deviceId */, msg.arg1 /* fingerId */,
7589f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                            msg.arg2 /* groupId */);
7599f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            }
76008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        }
7619f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
7629f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        private void sendRemovedResult(long deviceId, int fingerId, int groupId) {
7639f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            if (mRemovalCallback != null) {
7649f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                int reqFingerId = mRemovalFingerprint.getFingerId();
7659f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                int reqGroupId = mRemovalFingerprint.getGroupId();
7669f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                if (fingerId != reqFingerId) {
7679f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    Log.w(TAG, "Finger id didn't match: " + fingerId + " != " + reqFingerId);
7689f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                }
7699f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                if (fingerId != reqFingerId) {
7709f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    Log.w(TAG, "Group id didn't match: " + groupId + " != " + reqGroupId);
7719f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                }
7729f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mRemovalCallback.onRemovalSucceeded(mRemovalFingerprint);
773a7596147b43940cad3f76c53ed154ef088b9269bJim Miller            }
774a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        }
775a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
7769f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        private void sendErrorResult(long deviceId, int errMsgId) {
7779f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            if (mEnrollmentCallback != null) {
7789f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mEnrollmentCallback.onEnrollmentError(errMsgId, getErrorString(errMsgId));
7799f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            } else if (mAuthenticationCallback != null) {
7809f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mAuthenticationCallback.onAuthenticationError(errMsgId, getErrorString(errMsgId));
7819f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            } else if (mRemovalCallback != null) {
7829f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mRemovalCallback.onRemovalError(mRemovalFingerprint, errMsgId,
7839f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                        getErrorString(errMsgId));
7849f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            }
7859f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
7869f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
7879f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        private void sendEnrollResult(Fingerprint fp, int remaining) {
7889f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            if (mEnrollmentCallback != null) {
7899f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mEnrollmentCallback.onEnrollmentProgress(remaining);
7909f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            }
7919f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
7929f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
793f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        private void sendAuthenticatedSucceeded(Fingerprint fp) {
7949f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            if (mAuthenticationCallback != null) {
795f501b58de8f467a80fef49c704555781bc61ea6fJim Miller                final AuthenticationResult result = new AuthenticationResult(mCryptoObject, fp);
796f501b58de8f467a80fef49c704555781bc61ea6fJim Miller                mAuthenticationCallback.onAuthenticationSucceeded(result);
797f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            }
798f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        }
799f501b58de8f467a80fef49c704555781bc61ea6fJim Miller
800f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        private void sendAuthenticatedFailed() {
801f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            if (mAuthenticationCallback != null) {
802f501b58de8f467a80fef49c704555781bc61ea6fJim Miller               mAuthenticationCallback.onAuthenticationFailed();
8039f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            }
8049f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
8059f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
8069f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        private void sendAcquiredResult(long deviceId, int acquireInfo) {
8074cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi            if (mAuthenticationCallback != null) {
8084cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi                mAuthenticationCallback.onAuthenticationAcquired(acquireInfo);
8094cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi            }
8109f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            final String msg = getAcquiredString(acquireInfo);
8114cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi            if (msg == null) {
8124cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi                return;
8134cfdcf5b0551e5656ea379c428e78b812c2e5cbeJorim Jaggi            }
8149f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            if (mEnrollmentCallback != null) {
8159f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mEnrollmentCallback.onEnrollmentHelp(acquireInfo, msg);
8169f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            } else if (mAuthenticationCallback != null) {
8179f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mAuthenticationCallback.onAuthenticationHelp(acquireInfo, msg);
8189f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            }
8199f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
8209f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    };
821ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller
822ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    /**
823ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller     * @hide
824ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller     */
8259f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public FingerprintManager(Context context, IFingerprintService service) {
8269f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        mContext = context;
8279f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        mService = service;
8289f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        if (mService == null) {
8299f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            Slog.v(TAG, "FingerprintManagerService was null");
8309f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
83124e9e966a85c416a94482fcd10dbdd10ceeb9e6cAlex Klyubin        mHandler = new MyHandler(context);
8329f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    }
8339f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
8349f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private int getCurrentUserId() {
8359f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        try {
8369f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            return ActivityManagerNative.getDefault().getCurrentUser().id;
8379f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        } catch (RemoteException e) {
8389f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            Log.w(TAG, "Failed to get current user id\n");
8399f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            return UserHandle.USER_NULL;
840ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller        }
841ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    }
842ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller
843fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller    private void cancelEnrollment() {
844ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        if (mService != null) try {
845ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            mService.cancelEnrollment(mToken);
846ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        } catch (RemoteException e) {
847ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (DEBUG) Log.w(TAG, "Remote exception while canceling enrollment");
848ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
849ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    }
850ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
851ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    private void cancelAuthentication(CryptoObject cryptoObject) {
852ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        if (mService != null) try {
8534af76a51d5082c740609563e07cf35f30bc2224eSvetoslav            mService.cancelAuthentication(mToken, mContext.getOpPackageName());
854ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        } catch (RemoteException e) {
855ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (DEBUG) Log.w(TAG, "Remote exception while canceling enrollment");
856ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
857ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    }
858ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
859ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    private String getErrorString(int errMsg) {
860ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        switch (errMsg) {
861ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ERROR_UNABLE_TO_PROCESS:
862ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
863ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_error_unable_to_process);
864ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ERROR_HW_UNAVAILABLE:
865ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
866ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_error_hw_not_available);
867ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ERROR_NO_SPACE:
868ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
869ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_error_no_space);
870ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ERROR_TIMEOUT:
871fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller                return mContext.getString(com.android.internal.R.string.fingerprint_error_timeout);
872fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller            case FINGERPRINT_ERROR_CANCELED:
873fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller                return mContext.getString(com.android.internal.R.string.fingerprint_error_canceled);
874fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller            case FINGERPRINT_ERROR_LOCKOUT:
875fe6439f02db3a541d77a7afb27e3bca1ae7493edJim Miller                return mContext.getString(com.android.internal.R.string.fingerprint_error_lockout);
876ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            default:
877ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                if (errMsg >= FINGERPRINT_ERROR_VENDOR_BASE) {
878ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    int msgNumber = errMsg - FINGERPRINT_ERROR_VENDOR_BASE;
879ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    String[] msgArray = mContext.getResources().getStringArray(
880ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                            com.android.internal.R.array.fingerprint_error_vendor);
881ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    if (msgNumber < msgArray.length) {
882ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                        return msgArray[msgNumber];
883ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    }
8849f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                }
885ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return null;
886ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller        }
887ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    }
88899d6019bead4705b7e126e65b856d538417d4934Jim Miller
889ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    private String getAcquiredString(int acquireInfo) {
890ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        switch (acquireInfo) {
891ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ACQUIRED_GOOD:
892ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return null;
893ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ACQUIRED_PARTIAL:
894ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
895ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_acquired_partial);
896ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ACQUIRED_INSUFFICIENT:
897ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
898ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_acquired_insufficient);
899ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ACQUIRED_IMAGER_DIRTY:
900ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
901ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_acquired_imager_dirty);
902ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ACQUIRED_TOO_SLOW:
903ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
904ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_acquired_too_slow);
905ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ACQUIRED_TOO_FAST:
906ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
907ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_acquired_too_fast);
908ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            default:
909ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                if (acquireInfo >= FINGERPRINT_ACQUIRED_VENDOR_BASE) {
910ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    int msgNumber = acquireInfo - FINGERPRINT_ACQUIRED_VENDOR_BASE;
911ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    String[] msgArray = mContext.getResources().getStringArray(
912ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                            com.android.internal.R.array.fingerprint_acquired_vendor);
913ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    if (msgNumber < msgArray.length) {
914ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                        return msgArray[msgNumber];
915ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    }
9169f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                }
917ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return null;
91899d6019bead4705b7e126e65b856d538417d4934Jim Miller        }
91999d6019bead4705b7e126e65b856d538417d4934Jim Miller    }
9209f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
9219f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private IFingerprintServiceReceiver mServiceReceiver = new IFingerprintServiceReceiver.Stub() {
9229f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
923f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        @Override // binder call
9249f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining) {
9259f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mHandler.obtainMessage(MSG_ENROLL_RESULT, remaining, 0,
9269f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    new Fingerprint(null, groupId, fingerId, deviceId)).sendToTarget();
9279f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
9289f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
929f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        @Override // binder call
9309f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public void onAcquired(long deviceId, int acquireInfo) {
9319f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mHandler.obtainMessage(MSG_ACQUIRED, acquireInfo, 0, deviceId).sendToTarget();
9329f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
9339f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
934f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        @Override // binder call
935f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        public void onAuthenticationSucceeded(long deviceId, Fingerprint fp) {
936f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            mHandler.obtainMessage(MSG_AUTHENTICATION_SUCCEEDED, fp).sendToTarget();
937f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        }
938f501b58de8f467a80fef49c704555781bc61ea6fJim Miller
939f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        @Override // binder call
940f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        public void onAuthenticationFailed(long deviceId) {
941f501b58de8f467a80fef49c704555781bc61ea6fJim Miller            mHandler.obtainMessage(MSG_AUTHENTICATION_FAILED).sendToTarget();;
9429f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
9439f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
944f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        @Override // binder call
9459f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public void onError(long deviceId, int error) {
9469f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mHandler.obtainMessage(MSG_ERROR, error, 0, deviceId).sendToTarget();
9479f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
9489f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
949f501b58de8f467a80fef49c704555781bc61ea6fJim Miller        @Override // binder call
9509f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public void onRemoved(long deviceId, int fingerId, int groupId) {
9519f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mHandler.obtainMessage(MSG_REMOVED, fingerId, groupId, deviceId).sendToTarget();
9529f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
9539f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    };
9549f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
9554d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales}
9564d41a203a08c55b3f3190519535ccee6557ea4feAndres Morales
957