FingerprintManager.java revision ccdfa93f609d3f306a35902df323939e266a7ab3
108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller/**
208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * Copyright (C) 2014 The Android Open Source Project
308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller *
408fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * Licensed under the Apache License, Version 2.0 (the "License");
508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * you may not use this file except in compliance with the License.
608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * You may obtain a copy of the License at
708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller *
808fa40c5cb5229b7969b2a5146855a337870f45aJim Miller *      http://www.apache.org/licenses/LICENSE-2.0
908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller *
1008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * Unless required by applicable law or agreed to in writing, software
1108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * distributed under the License is distributed on an "AS IS" BASIS,
1208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * See the License for the specific language governing permissions and
1408fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * limitations under the License.
1508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller */
1608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
17ebbf205bc6e8292f74d8fc4652c70274a445f907Jim Millerpackage android.hardware.fingerprint;
1808fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
19ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Millerimport android.annotation.NonNull;
20ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Millerimport android.annotation.Nullable;
2108fa40c5cb5229b7969b2a5146855a337870f45aJim Millerimport android.app.ActivityManagerNative;
22d08c2aceb238b02d8348518a2c87693054c6ce37Jim Millerimport android.content.ContentResolver;
2308fa40c5cb5229b7969b2a5146855a337870f45aJim Millerimport android.content.Context;
24a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport android.os.Binder;
259f0753f5a378fc80da86305b33244acc6fc53f01Jim Millerimport android.os.CancellationSignal;
26ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Millerimport android.os.CancellationSignal.OnCancelListener;
2708fa40c5cb5229b7969b2a5146855a337870f45aJim Millerimport android.os.Handler;
2808fa40c5cb5229b7969b2a5146855a337870f45aJim Millerimport android.os.IBinder;
299f0753f5a378fc80da86305b33244acc6fc53f01Jim Millerimport android.os.Parcel;
309f0753f5a378fc80da86305b33244acc6fc53f01Jim Millerimport android.os.Parcelable;
3108fa40c5cb5229b7969b2a5146855a337870f45aJim Millerimport android.os.RemoteException;
3208fa40c5cb5229b7969b2a5146855a337870f45aJim Millerimport android.os.UserHandle;
33d08c2aceb238b02d8348518a2c87693054c6ce37Jim Millerimport android.provider.Settings;
34ebbf205bc6e8292f74d8fc4652c70274a445f907Jim Millerimport android.hardware.fingerprint.FingerprintManager.EnrollmentCallback;
35ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Millerimport android.security.AndroidKeyStoreProvider;
3608fa40c5cb5229b7969b2a5146855a337870f45aJim Millerimport android.util.Log;
37a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport android.util.Slog;
3808fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
399f0753f5a378fc80da86305b33244acc6fc53f01Jim Millerimport java.security.Signature;
40ba67aee02cf864793129976cd8a8a46e60c60577Jim Millerimport java.util.ArrayList;
419f0753f5a378fc80da86305b33244acc6fc53f01Jim Millerimport java.util.HashMap;
42ba67aee02cf864793129976cd8a8a46e60c60577Jim Millerimport java.util.List;
43ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller
449f0753f5a378fc80da86305b33244acc6fc53f01Jim Millerimport javax.crypto.Cipher;
459f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
4608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller/**
4708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller * A class that coordinates access to the fingerprint hardware.
48ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller * <p>
49ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller * Use {@link android.content.Context#getSystemService(java.lang.String)}
50ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller * with argument {@link android.content.Context#FINGERPRINT_SERVICE} to get
51ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller * an instance of this class.
5208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller */
5308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
5408fa40c5cb5229b7969b2a5146855a337870f45aJim Millerpublic class FingerprintManager {
5508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    private static final String TAG = "FingerprintManager";
56d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller    private static final boolean DEBUG = true;
5708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    private static final int MSG_ENROLL_RESULT = 100;
58a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    private static final int MSG_ACQUIRED = 101;
59a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    private static final int MSG_PROCESSED = 102;
60a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    private static final int MSG_ERROR = 103;
61a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    private static final int MSG_REMOVED = 104;
6208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
63ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    //
64ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    // Error messages from fingerprint hardware during initilization, enrollment, authentication or
65ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    // removal. Must agree with the list in fingerprint.h
66ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    //
6708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
68ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
69ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * The hardware is unavailable. Try again later.
70ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
7108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    public static final int FINGERPRINT_ERROR_HW_UNAVAILABLE = 1;
72ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
73ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
74ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * Error state returned when the sensor was unable to process the current image.
75ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
76a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    public static final int FINGERPRINT_ERROR_UNABLE_TO_PROCESS = 2;
77ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
78ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
79ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * Error state returned when the current request has been running too long. This is intended to
80ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * prevent programs from waiting for the fingerprint sensor indefinitely. The timeout is
81ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * platform and sensor-specific, but is generally on the order of 30 seconds.
82ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
8308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    public static final int FINGERPRINT_ERROR_TIMEOUT = 3;
84ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
85ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
86ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * Error state returned for operations like enrollment; the operation cannot be completed
87ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * because there's not enough storage remaining to complete the operation.
88ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
8908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    public static final int FINGERPRINT_ERROR_NO_SPACE = 4;
90ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
91ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
92ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * The operation was canceled because the fingerprint sensor is unavailable. For example,
93ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * this may happen when the user is switched, the device is locked or another pending operation
94ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * prevents or disables it.
95ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
969f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static final int FINGERPRINT_ERROR_CANCELED = 5;
97ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
98ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
99ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * The {@link FingerprintManager#remove(Fingerprint, RemovalCallback)} call failed. Typically
100ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * this will happen when the provided fingerprint id was incorrect.
101ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *
102ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @hide
103ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
104ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    public static final int FINGERPRINT_ERROR_UNABLE_TO_REMOVE = 6;
105ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
106ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
107ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * Hardware vendors may extend this list if there are conditions that do not fall under one of
108ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * the above categories. Vendors are responsible for providing error strings for these errors.
109ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
1109f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static final int FINGERPRINT_ERROR_VENDOR_BASE = 1000;
11108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
112ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    //
113ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    // Image acquisition messages. Must agree with those in fingerprint.h
114ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    //
115ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
116ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
117ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * The image acquired was good.
118ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
119a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    public static final int FINGERPRINT_ACQUIRED_GOOD = 0;
120ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
121ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
122ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * Only a partial fingerprint image was detected. During enrollment, the user should be
123ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * informed on what needs to happen to resolve this problem, e.g. "press firmly on sensor."
124ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
125a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    public static final int FINGERPRINT_ACQUIRED_PARTIAL = 1;
126ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
127ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
128ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * The fingerprint image was too noisy to process due to a detected condition (i.e. dry skin) or
129ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * a possibly dirty sensor (See {@link #FINGERPRINT_ACQUIRED_IMAGER_DIRTY}).
130ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
131a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    public static final int FINGERPRINT_ACQUIRED_INSUFFICIENT = 2;
132ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
133ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
134ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * The fingerprint image was too noisy due to suspected or detected dirt on the sensor.
135ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * For example, it's reasonable return this after multiple
136ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * {@link #FINGERPRINT_ACQUIRED_INSUFFICIENT} or actual detection of dirt on the sensor
137ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * (stuck pixels, swaths, etc.). The user is expected to take action to clean the sensor
138ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * when this is returned.
139ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
1409f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static final int FINGERPRINT_ACQUIRED_IMAGER_DIRTY = 3;
141ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
142ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
143ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * The fingerprint image was unreadable due to lack of motion. This is most appropriate for
144ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * linear array sensors that require a swipe motion.
145ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
1469f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static final int FINGERPRINT_ACQUIRED_TOO_SLOW = 4;
147ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
148ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
149ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * The fingerprint image was incomplete due to quick motion. While mostly appropriate for
150ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * linear array sensors,  this could also happen if the finger was moved during acquisition.
151ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * The user should be asked to move the finger slower (linear) or leave the finger on the sensor
152ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * longer.
153ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
1549f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static final int FINGERPRINT_ACQUIRED_TOO_FAST = 5;
155ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
156ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
157ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * Hardware vendors may extend this list if there are conditions that do not fall under one of
158ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * the above categories. Vendors are responsible for providing error strings for these errors.
159ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
1609f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static final int FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
161a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
16208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    private IFingerprintService mService;
163d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller    private Context mContext;
164a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    private IBinder mToken = new Binder();
1659f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private AuthenticationCallback mAuthenticationCallback;
1669f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private EnrollmentCallback mEnrollmentCallback;
1679f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private RemovalCallback mRemovalCallback;
1689f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private CryptoObject mCryptoObject;
1699f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private Fingerprint mRemovalFingerprint;
170ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
171ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    private class OnEnrollCancelListener implements OnCancelListener {
172ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        private long mChallenge;
173ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
174ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public OnEnrollCancelListener(long challenge) {
175ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            mChallenge = challenge;
176ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
177ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
178ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        @Override
179ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onCancel() {
180ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            cancelEnrollment(mChallenge);
181ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
182ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    }
183ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
184ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    private class OnAuthenticationCancelListener implements OnCancelListener {
185ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        private CryptoObject mCrypto;
186ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
187ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public OnAuthenticationCancelListener(CryptoObject crypto) {
188ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            mCrypto = crypto;
189ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
190ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
191ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        @Override
192ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onCancel() {
193ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            cancelAuthentication(mCrypto);
194ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
195ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    }
19608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
1979f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    /**
198ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * A wrapper class for the crypto objects supported by FingerprintManager. Currently the
199ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * framework supports {@link Signature} and {@link Cipher} objects.
2009f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     */
2019f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static class CryptoObject {
202ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
203ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        CryptoObject(Signature signature) {
204ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            mSignature = signature;
205ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            mCipher = null;
206ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
207ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
208ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        CryptoObject(Cipher cipher) {
209ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            mCipher = cipher;
210ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            mSignature = null;
211ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
212ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
213ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        /**
214ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * Get {@link Signature} object.
215ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @return {@link Signature} object or null if this doesn't contain one.
216ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         */
217ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public Signature getSignature() { return mSignature; }
218ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
219ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        /**
220ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * Get {@link Cipher} object.
221ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @return {@link Cipher} object or null if this doesn't contain one.
222ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         */
223ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public Cipher getCipher() { return mCipher; }
224ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
225ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        /**
226ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @hide
227ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @return the opId associated with this object or 0 if none
228ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         */
229ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public long getOpId() {
230ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (mSignature != null) {
231ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return AndroidKeyStoreProvider.getKeyStoreOperationHandle(mSignature);
232ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            } else if (mCipher != null) {
233ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return AndroidKeyStoreProvider.getKeyStoreOperationHandle(mCipher);
234ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            }
235ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            return 0;
236ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
237ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
238ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        private final Signature mSignature;
239ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        private final Cipher mCipher;
24008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    };
24108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
2429f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    /**
2439f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Container for callback data from {@link FingerprintManager#authenticate(CryptoObject,
244ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *     CancellationSignal, AuthenticationCallback, int)}.
2459f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     */
2469f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static final class AuthenticationResult {
2479f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        private Fingerprint mFingerprint;
2489f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        private CryptoObject mCryptoObject;
2499f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
2509f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public AuthenticationResult(CryptoObject crypto, Fingerprint fingerprint) {
2519f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mCryptoObject = crypto;
2529f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mFingerprint = fingerprint;
253ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller        }
2549f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
2559f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
2569f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * Obtain the crypto object associated with this transaction
2579f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * @return crypto object provided to {@link FingerprintManager#authenticate(CryptoObject,
258ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         *     CancellationSignal, AuthenticationCallback, int)}.
2599f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
2609f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public CryptoObject getCryptoObject() { return mCryptoObject; }
2619f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
2629f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
263ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * Obtain the Fingerprint associated with this operation. Applications are strongly
264ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * discouraged from associating specific fingers with specific applications or operations.
265ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         *
2669f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * @hide
2679f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
2689f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public Fingerprint getFingerprint() { return mFingerprint; }
2699f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    };
270ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller
27106e658f324a937bec1c5ddbe9c3100c3d2fec371Jim Miller    /**
2729f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Callback structure provided to {@link FingerprintManager#authenticate(CryptoObject,
273ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * CancellationSignal, AuthenticationCallback, int)}. Users of {@link
274ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * FingerprintManager#authenticate(CryptoObject, CancellationSignal,
275ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * AuthenticationCallback, int) } must provide an implementation of this for listening to
276ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * fingerprint events.
27706e658f324a937bec1c5ddbe9c3100c3d2fec371Jim Miller     */
2789f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static abstract class AuthenticationCallback {
2799f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
2809f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * Called when an unrecoverable error has been encountered and the operation is complete.
2819f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * No further callbacks will be made on this object.
282ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param errMsgId An integer identifying the error message
283ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param errString A human-readable error string that can be shown in UI
2849f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
285ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onAuthenticationError(int errMsgId, CharSequence errString) { }
28608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
2879f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
288ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * Called when a recoverable error has been encountered during authentication. The help
2899f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * string is provided to give the user guidance for what went wrong, such as
2909f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * "Sensor dirty, please clean it."
291ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param helpMsgId An integer identifying the error message
292ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param helpString A human-readable string that can be shown in UI
2939f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
294ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) { }
29508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
2969f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
2979f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * Called when a fingerprint is recognized.
298ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param result An object containing authentication-related data
2999f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
300ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onAuthenticationSucceeded(AuthenticationResult result) { }
301ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
302ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        /**
303ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * Called when a fingerprint is valid but not recognized.
304ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         */
305ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onAuthenticationFailed() { }
3069f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    };
30708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
3089f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    /**
3099f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Callback structure provided to {@link FingerprintManager#enroll(long, EnrollmentCallback,
3109f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * CancellationSignal, int). Users of {@link #FingerprintManager()}
3119f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * must provide an implementation of this to {@link FingerprintManager#enroll(long,
312ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * CancellationSignal, EnrollmentCallback, int) for listening to fingerprint events.
313ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *
314ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @hide
3159f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     */
3169f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static abstract class EnrollmentCallback {
3179f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
3189f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * Called when an unrecoverable error has been encountered and the operation is complete.
3199f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * No further callbacks will be made on this object.
320ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param errMsgId An integer identifying the error message
321ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param errString A human-readable error string that can be shown in UI
3229f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
323ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onEnrollmentError(int errMsgId, CharSequence errString) { }
324a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
3259f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
326ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * Called when a recoverable error has been encountered during enrollment. The help
3279f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * string is provided to give the user guidance for what went wrong, such as
3289f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * "Sensor dirty, please clean it" or what they need to do next, such as
3299f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * "Touch sensor again."
330ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param helpMsgId An integer identifying the error message
331ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param helpString A human-readable string that can be shown in UI
3329f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
333ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onEnrollmentHelp(int helpMsgId, CharSequence helpString) { }
33408fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
3359f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
3369f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * Called as each enrollment step progresses. Enrollment is considered complete when
337ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * remaining reaches 0. This function will not be called if enrollment fails. See
3389f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * {@link EnrollmentCallback#onEnrollmentError(int, CharSequence)}
339ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param remaining The number of remaining steps
3409f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
341ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onEnrollmentProgress(int remaining) { }
3429f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    };
34308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
3449f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    /**
3459f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Callback structure provided to {@link FingerprintManager#remove(int). Users of
3469f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * {@link #FingerprintManager()} may optionally provide an implementation of this to
3479f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * {@link FingerprintManager#remove(int, int, RemovalCallback)} for listening to
3489f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * fingerprint template removal events.
349ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *
350ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @hide
3519f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     */
3529f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public static abstract class RemovalCallback {
3539f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
3549f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * Called when the given fingerprint can't be removed.
355ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param fp The fingerprint that the call attempted to remove
356ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param errMsgId An associated error message id
357ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller         * @param errString An error message indicating why the fingerprint id can't be removed
3589f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
359ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onRemovalError(Fingerprint fp, int errMsgId, CharSequence errString) { }
3609f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
3619f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        /**
3629f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * Called when a given fingerprint is successfully removed.
3639f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         * @param fingerprint the fingerprint template that was removed.
3649f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller         */
365ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        public void onRemovalSucceeded(Fingerprint fingerprint) { }
36608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    };
36708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
36808fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    /**
369ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * Request authentication of a crypto object. This call warms up the fingerprint hardware
370ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * and starts scanning for a fingerprint. It terminates when
3719f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)} or
3729f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * {@link AuthenticationCallback#onAuthenticationSucceeded(AuthenticationResult) is called, at
3739f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * which point the object is no longer valid. The operation can be canceled by using the
3749f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * provided cancel object.
375d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller     *
3769f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param crypto object associated with the call or null if none required.
3779f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param cancel an object that can be used to cancel authentication
378ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @param callback an object to receive authentication events
379ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @param flags optional flags; should be 0
380d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller     */
381ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
382ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            @NonNull AuthenticationCallback callback, int flags) {
383ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi        authenticate(crypto, cancel, callback, flags, UserHandle.myUserId());
384ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi    }
385ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi
386ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi    /**
387ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * Request authentication of a crypto object. This call warms up the fingerprint hardware
388ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * and starts scanning for a fingerprint. It terminates when
389ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * {@link AuthenticationCallback#onAuthenticationError(int, CharSequence)} or
390ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * {@link AuthenticationCallback#onAuthenticationSucceeded(AuthenticationResult) is called, at
391ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * which point the object is no longer valid. The operation can be canceled by using the
392ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * provided cancel object.
393ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     *
394ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * @param crypto object associated with the call or null if none required.
395ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * @param cancel an object that can be used to cancel authentication
396ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * @param callback an object to receive authentication events
397ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * @param flags optional flags; should be 0
398ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * @param userId the userId the fingerprint belongs to
399ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     * @hide
400ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi     */
401ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi    public void authenticate(@Nullable CryptoObject crypto, @Nullable CancellationSignal cancel,
402ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi            @NonNull AuthenticationCallback callback, int flags, int userId) {
4039f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        if (callback == null) {
4049f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            throw new IllegalArgumentException("Must supply an authentication callback");
4059f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
4069f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
407ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        if (cancel != null) {
408ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (cancel.isCanceled()) {
409ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                Log.w(TAG, "authentication already canceled");
410ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return;
411ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            } else {
412ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                cancel.setOnCancelListener(new OnAuthenticationCancelListener(crypto));
413ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            }
414ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
4159f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
4169f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        if (mService != null) try {
4179f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mAuthenticationCallback = callback;
4189f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mCryptoObject = crypto;
419ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            long sessionId = crypto != null ? crypto.getOpId() : 0;
420ccdfa93f609d3f306a35902df323939e266a7ab3Jorim Jaggi            mService.authenticate(mToken, sessionId, userId, mServiceReceiver, flags);
4219f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        } catch (RemoteException e) {
422ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            Log.w(TAG, "Remote exception while authenticating: ", e);
423ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (callback != null) {
424ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                // Though this may not be a hardware issue, it will cause apps to give up or try
425ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                // again later.
426ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                callback.onAuthenticationError(FINGERPRINT_ERROR_HW_UNAVAILABLE,
427ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                        getErrorString(FINGERPRINT_ERROR_HW_UNAVAILABLE));
428ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            }
4299f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
430d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller    }
431d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller
432d08c2aceb238b02d8348518a2c87693054c6ce37Jim Miller    /**
4339f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Request fingerprint enrollment. This call warms up the fingerprint hardware
4349f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * and starts scanning for fingerprints. Progress will be indicated by callbacks to the
4359f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * {@link EnrollmentCallback} object. It terminates when
4369f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * {@link EnrollmentCallback#onEnrollmentError(int, CharSequence)} or
4379f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * {@link EnrollmentCallback#onEnrollmentProgress(int) is called with remaining == 0, at
4389f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * which point the object is no longer valid. The operation can be canceled by using the
4399f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * provided cancel object.
4409f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param challenge a unique id provided by a recent verification of device credentials
4419f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     *     (e.g. pin, pattern or password).
4429f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param cancel an object that can be used to cancel enrollment
443ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @param callback an object to receive enrollment events
4449f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param flags optional flags
445ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @hide
44608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller     */
447ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    public void enroll(long challenge, CancellationSignal cancel, EnrollmentCallback callback,
448ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            int flags) {
4499f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        if (callback == null) {
4509f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            throw new IllegalArgumentException("Must supply an enrollment callback");
45108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        }
4529f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
453ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        if (cancel != null) {
454ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (cancel.isCanceled()) {
455ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                Log.w(TAG, "enrollment already canceled");
456ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return;
457ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            } else {
458ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                cancel.setOnCancelListener(new OnEnrollCancelListener(challenge));
459ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            }
460ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
4619f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
46208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        if (mService != null) try {
4639f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mEnrollmentCallback = callback;
464ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            mService.enroll(mToken, challenge, getCurrentUserId(), mServiceReceiver, flags);
465ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        } catch (RemoteException e) {
466ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            Log.w(TAG, "Remote exception in enroll: ", e);
467ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (callback != null) {
468ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                // Though this may not be a hardware issue, it will cause apps to give up or try
469ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                // again later.
470ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                callback.onEnrollmentError(FINGERPRINT_ERROR_HW_UNAVAILABLE,
471ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                        getErrorString(FINGERPRINT_ERROR_HW_UNAVAILABLE));
472ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            }
473ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
474ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    }
475ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
476ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    /**
477ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * Requests a pre-enrollment auth token to tie enrollment to the confirmation of
478ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * existing device credentials (e.g. pin/pattern/password).
479ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @hide
480ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     */
481ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    public long preEnroll() {
482ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        long result = 0;
483ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        if (mService != null) try {
484ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            result = mService.preEnroll(mToken);
48508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        } catch (RemoteException e) {
486ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            Log.w(TAG, "Remote exception in enroll: ", e);
48708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        }
488ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        return result;
48908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    }
49008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
49108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    /**
4929f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Remove given fingerprint template from fingerprint hardware and/or protected storage.
4939f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param fp the fingerprint item to remove
4949f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param callback an optional callback to verify that fingerprint templates have been
495ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * successfully removed. May be null of no callback is required.
496ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *
4979f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @hide
49808fa40c5cb5229b7969b2a5146855a337870f45aJim Miller     */
4999f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public void remove(Fingerprint fp, RemovalCallback callback) {
5009f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        if (mService != null) try {
5019f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mRemovalCallback = callback;
5029f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mRemovalFingerprint = fp;
503ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            mService.remove(mToken, fp.getFingerId(), getCurrentUserId(), mServiceReceiver);
5049f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        } catch (RemoteException e) {
505ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            Log.w(TAG, "Remote exception in remove: ", e);
506ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (callback != null) {
507ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                callback.onRemovalError(fp, FINGERPRINT_ERROR_HW_UNAVAILABLE,
508ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                        getErrorString(FINGERPRINT_ERROR_HW_UNAVAILABLE));
509ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            }
51008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        }
51108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    }
51208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
51308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    /**
5149f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Renames the given fingerprint template
5159f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param fpId the fingerprint id
5169f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @param newName the new name
517ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *
5189f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @hide
51908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller     */
5209f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public void rename(int fpId, String newName) {
5219f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        // Renames the given fpId
52208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        if (mService != null) {
52308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller            try {
5249f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mService.rename(fpId, getCurrentUserId(), newName);
52508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller            } catch (RemoteException e) {
5269f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                Log.v(TAG, "Remote exception in rename(): ", e);
52708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller            }
528a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        } else {
5299f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            Log.w(TAG, "rename(): Service not connected!");
53008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        }
53108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    }
53208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
5339f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    /**
5349f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Obtain the list of enrolled fingerprints templates.
5359f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @return list of current fingerprint items
536ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *
537ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     * @hide
5389f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     */
5399f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public List<Fingerprint> getEnrolledFingerprints() {
5409f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        if (mService != null) try {
5419f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            return mService.getEnrolledFingerprints(getCurrentUserId());
54208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        } catch (RemoteException e) {
5439f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            Log.v(TAG, "Remote exception in getEnrolledFingerprints: ", e);
54408fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        }
5459f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        return null;
54608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    }
54708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller
54808fa40c5cb5229b7969b2a5146855a337870f45aJim Miller    /**
5499f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * Determine if fingerprint hardware is present and functional.
5509f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @return true if hardware is present and functional, false otherwise.
551ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller     *
5529f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller     * @hide
55308fa40c5cb5229b7969b2a5146855a337870f45aJim Miller     */
5549f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public boolean isHardwareDetected() {
55508fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        if (mService != null) {
55608fa40c5cb5229b7969b2a5146855a337870f45aJim Miller            try {
5579f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                long deviceId = 0; /* TODO: plumb hardware id to FPMS */
5589f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                return mService.isHardwareDetected(deviceId);
55908fa40c5cb5229b7969b2a5146855a337870f45aJim Miller            } catch (RemoteException e) {
5609f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                Log.v(TAG, "Remote exception in isFingerprintHardwareDetected(): ", e);
56108fa40c5cb5229b7969b2a5146855a337870f45aJim Miller            }
56208fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        } else {
5639f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            Log.w(TAG, "isFingerprintHardwareDetected(): Service not connected!");
564a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        }
5659f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        return false;
566a7596147b43940cad3f76c53ed154ef088b9269bJim Miller    }
567a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
5689f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private Handler mHandler = new Handler() {
5699f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public void handleMessage(android.os.Message msg) {
5709f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            switch(msg.what) {
5719f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                case MSG_ENROLL_RESULT:
5729f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    sendEnrollResult((Fingerprint) msg.obj, msg.arg1 /* remaining */);
5739f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    break;
5749f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                case MSG_ACQUIRED:
5759f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    sendAcquiredResult((Long) msg.obj /* deviceId */, msg.arg1 /* acquire info */);
5769f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    break;
5779f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                case MSG_PROCESSED:
5789f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    sendProcessedResult((Fingerprint) msg.obj);
5799f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    break;
5809f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                case MSG_ERROR:
5819f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    sendErrorResult((Long) msg.obj /* deviceId */, msg.arg1 /* errMsgId */);
5829f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    break;
5839f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                case MSG_REMOVED:
5849f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    sendRemovedResult((Long) msg.obj /* deviceId */, msg.arg1 /* fingerId */,
5859f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                            msg.arg2 /* groupId */);
5869f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            }
58708fa40c5cb5229b7969b2a5146855a337870f45aJim Miller        }
5889f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
5899f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        private void sendRemovedResult(long deviceId, int fingerId, int groupId) {
5909f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            if (mRemovalCallback != null) {
5919f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                int reqFingerId = mRemovalFingerprint.getFingerId();
5929f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                int reqGroupId = mRemovalFingerprint.getGroupId();
5939f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                if (fingerId != reqFingerId) {
5949f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    Log.w(TAG, "Finger id didn't match: " + fingerId + " != " + reqFingerId);
5959f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                }
5969f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                if (fingerId != reqFingerId) {
5979f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    Log.w(TAG, "Group id didn't match: " + groupId + " != " + reqGroupId);
5989f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                }
5999f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mRemovalCallback.onRemovalSucceeded(mRemovalFingerprint);
600a7596147b43940cad3f76c53ed154ef088b9269bJim Miller            }
601a7596147b43940cad3f76c53ed154ef088b9269bJim Miller        }
602a7596147b43940cad3f76c53ed154ef088b9269bJim Miller
6039f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        private void sendErrorResult(long deviceId, int errMsgId) {
6049f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            if (mEnrollmentCallback != null) {
6059f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mEnrollmentCallback.onEnrollmentError(errMsgId, getErrorString(errMsgId));
6069f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            } else if (mAuthenticationCallback != null) {
6079f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mAuthenticationCallback.onAuthenticationError(errMsgId, getErrorString(errMsgId));
6089f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            } else if (mRemovalCallback != null) {
6099f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mRemovalCallback.onRemovalError(mRemovalFingerprint, errMsgId,
6109f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                        getErrorString(errMsgId));
6119f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            }
6129f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
6139f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
6149f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        private void sendEnrollResult(Fingerprint fp, int remaining) {
6159f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            if (mEnrollmentCallback != null) {
6169f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mEnrollmentCallback.onEnrollmentProgress(remaining);
6179f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            }
6189f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
6199f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
6209f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        private void sendProcessedResult(Fingerprint fp) {
6219f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            if (mAuthenticationCallback != null) {
622ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                if (fp.getFingerId() == 0 && fp.getGroupId() == 0) {
623ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    // Fingerprint template valid but doesn't match one in database
624ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    mAuthenticationCallback.onAuthenticationFailed();
625ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                } else {
626ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    final AuthenticationResult result = new AuthenticationResult(mCryptoObject, fp);
627ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    mAuthenticationCallback.onAuthenticationSucceeded(result);
628ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                }
6299f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            }
6309f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
6319f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
6329f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        private void sendAcquiredResult(long deviceId, int acquireInfo) {
6339f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            final String msg = getAcquiredString(acquireInfo);
6349f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            if (msg == null) return;
6359f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
6369f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            if (mEnrollmentCallback != null) {
6379f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mEnrollmentCallback.onEnrollmentHelp(acquireInfo, msg);
6389f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            } else if (mAuthenticationCallback != null) {
6399f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                mAuthenticationCallback.onAuthenticationHelp(acquireInfo, msg);
6409f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            }
6419f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
6429f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    };
643ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller
644ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    /**
645ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller     * @hide
646ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller     */
6479f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    public FingerprintManager(Context context, IFingerprintService service) {
6489f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        mContext = context;
6499f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        mService = service;
6509f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        if (mService == null) {
6519f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            Slog.v(TAG, "FingerprintManagerService was null");
6529f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
6539f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    }
6549f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
6559f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private int getCurrentUserId() {
6569f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        try {
6579f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            return ActivityManagerNative.getDefault().getCurrentUser().id;
6589f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        } catch (RemoteException e) {
6599f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            Log.w(TAG, "Failed to get current user id\n");
6609f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            return UserHandle.USER_NULL;
661ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller        }
662ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    }
663ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller
664ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    private void clearCallbacks() {
665ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        mAuthenticationCallback = null;
666ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        mEnrollmentCallback = null;
667ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        mRemovalCallback = null;
668ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    }
669ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
670ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    private void cancelEnrollment(long challenge) {
671ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        if (mService != null) try {
672ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            mService.cancelEnrollment(mToken);
673ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        } catch (RemoteException e) {
674ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (DEBUG) Log.w(TAG, "Remote exception while canceling enrollment");
675ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
676ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    }
677ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
678ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    private void cancelAuthentication(CryptoObject cryptoObject) {
679ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        if (mService != null) try {
680ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            mService.cancelAuthentication(mToken);
681ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        } catch (RemoteException e) {
682ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            if (DEBUG) Log.w(TAG, "Remote exception while canceling enrollment");
683ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        }
684ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    }
685ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller
686ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    private String getErrorString(int errMsg) {
687ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        switch (errMsg) {
688ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ERROR_UNABLE_TO_PROCESS:
689ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
690ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_error_unable_to_process);
691ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ERROR_HW_UNAVAILABLE:
692ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
693ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_error_hw_not_available);
694ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ERROR_NO_SPACE:
695ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
696ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_error_no_space);
697ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ERROR_TIMEOUT:
698ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
699ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_error_timeout);
700ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            default:
701ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                if (errMsg >= FINGERPRINT_ERROR_VENDOR_BASE) {
702ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    int msgNumber = errMsg - FINGERPRINT_ERROR_VENDOR_BASE;
703ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    String[] msgArray = mContext.getResources().getStringArray(
704ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                            com.android.internal.R.array.fingerprint_error_vendor);
705ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    if (msgNumber < msgArray.length) {
706ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                        return msgArray[msgNumber];
707ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    }
7089f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                }
709ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return null;
710ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller        }
711ba67aee02cf864793129976cd8a8a46e60c60577Jim Miller    }
71299d6019bead4705b7e126e65b856d538417d4934Jim Miller
713ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller    private String getAcquiredString(int acquireInfo) {
714ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller        switch (acquireInfo) {
715ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ACQUIRED_GOOD:
716ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return null;
717ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ACQUIRED_PARTIAL:
718ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
719ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_acquired_partial);
720ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ACQUIRED_INSUFFICIENT:
721ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
722ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_acquired_insufficient);
723ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ACQUIRED_IMAGER_DIRTY:
724ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
725ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_acquired_imager_dirty);
726ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ACQUIRED_TOO_SLOW:
727ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
728ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_acquired_too_slow);
729ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            case FINGERPRINT_ACQUIRED_TOO_FAST:
730ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return mContext.getString(
731ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    com.android.internal.R.string.fingerprint_acquired_too_fast);
732ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller            default:
733ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                if (acquireInfo >= FINGERPRINT_ACQUIRED_VENDOR_BASE) {
734ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    int msgNumber = acquireInfo - FINGERPRINT_ACQUIRED_VENDOR_BASE;
735ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    String[] msgArray = mContext.getResources().getStringArray(
736ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                            com.android.internal.R.array.fingerprint_acquired_vendor);
737ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    if (msgNumber < msgArray.length) {
738ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                        return msgArray[msgNumber];
739ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                    }
7409f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                }
741ce7eb6daf06a88129da365eb2112537ce0bb1b75Jim Miller                return null;
74299d6019bead4705b7e126e65b856d538417d4934Jim Miller        }
74399d6019bead4705b7e126e65b856d538417d4934Jim Miller    }
7449f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
7459f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    private IFingerprintServiceReceiver mServiceReceiver = new IFingerprintServiceReceiver.Stub() {
7469f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
7479f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining) {
7489f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mHandler.obtainMessage(MSG_ENROLL_RESULT, remaining, 0,
7499f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    new Fingerprint(null, groupId, fingerId, deviceId)).sendToTarget();
7509f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
7519f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
7529f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public void onAcquired(long deviceId, int acquireInfo) {
7539f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mHandler.obtainMessage(MSG_ACQUIRED, acquireInfo, 0, deviceId).sendToTarget();
7549f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
7559f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
7569f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public void onProcessed(long deviceId, int fingerId, int groupId) {
7579f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mHandler.obtainMessage(MSG_PROCESSED,
7589f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller                    new Fingerprint(null, groupId, fingerId, deviceId)).sendToTarget();
7599f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
7609f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
7619f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public void onError(long deviceId, int error) {
7629f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mHandler.obtainMessage(MSG_ERROR, error, 0, deviceId).sendToTarget();
7639f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
7649f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
7659f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        public void onRemoved(long deviceId, int fingerId, int groupId) {
7669f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller            mHandler.obtainMessage(MSG_REMOVED, fingerId, groupId, deviceId).sendToTarget();
7679f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller        }
7689f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller    };
7699f0753f5a378fc80da86305b33244acc6fc53f01Jim Miller
77008fa40c5cb5229b7969b2a5146855a337870f45aJim Miller}