1a7596147b43940cad3f76c53ed154ef088b9269bJim Miller/** 2a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * Copyright (C) 2014 The Android Open Source Project 3a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * 4a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * Licensed under the Apache License, Version 2.0 (the "License"); 5a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * you may not use this file except in compliance with the License. 6a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * You may obtain a copy of the License at 7a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * 8a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * http://www.apache.org/licenses/LICENSE-2.0 9a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * 10a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * Unless required by applicable law or agreed to in writing, software 11a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * distributed under the License is distributed on an "AS IS" BASIS, 12a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * See the License for the specific language governing permissions and 14a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * limitations under the License. 15a7596147b43940cad3f76c53ed154ef088b9269bJim Miller */ 16a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 17a7596147b43940cad3f76c53ed154ef088b9269bJim Millerpackage com.android.server.fingerprint; 18a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 19a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport android.app.Service; 20a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport android.content.ContentResolver; 21a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport android.content.Context; 22a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport android.content.Intent; 23a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport android.os.Handler; 24a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport android.os.IBinder; 25a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport android.os.PowerManager; 26a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport android.os.RemoteException; 27a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport android.provider.Settings; 28a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport android.service.fingerprint.FingerprintManager; 29a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport android.util.ArrayMap; 30a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport android.util.Slog; 31a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 32a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport com.android.server.SystemService; 33a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 34a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport android.service.fingerprint.FingerprintUtils; 35a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport android.service.fingerprint.IFingerprintService; 36a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport android.service.fingerprint.IFingerprintServiceReceiver; 37a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 38a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport java.io.PrintWriter; 39a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport java.lang.ref.WeakReference; 40a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport java.util.HashMap; 41a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport java.util.Map.Entry; 42a7596147b43940cad3f76c53ed154ef088b9269bJim Millerimport java.util.Set; 43a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 44a7596147b43940cad3f76c53ed154ef088b9269bJim Miller/** 45a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * A service to manage multiple clients that want to access the fingerprint HAL API. 46a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * The service is responsible for maintaining a list of clients and dispatching all 47a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * fingerprint -related events. 48a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * 49a7596147b43940cad3f76c53ed154ef088b9269bJim Miller * @hide 50a7596147b43940cad3f76c53ed154ef088b9269bJim Miller */ 51a7596147b43940cad3f76c53ed154ef088b9269bJim Millerpublic class FingerprintService extends SystemService { 52a7596147b43940cad3f76c53ed154ef088b9269bJim Miller private final String TAG = "FingerprintService"; 53a7596147b43940cad3f76c53ed154ef088b9269bJim Miller private static final boolean DEBUG = true; 54a7596147b43940cad3f76c53ed154ef088b9269bJim Miller private ArrayMap<IBinder, ClientData> mClients = new ArrayMap<IBinder, ClientData>(); 55a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 56a7596147b43940cad3f76c53ed154ef088b9269bJim Miller private static final int MSG_NOTIFY = 10; 57a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 58a7596147b43940cad3f76c53ed154ef088b9269bJim Miller Handler mHandler = new Handler() { 59a7596147b43940cad3f76c53ed154ef088b9269bJim Miller public void handleMessage(android.os.Message msg) { 60a7596147b43940cad3f76c53ed154ef088b9269bJim Miller switch (msg.what) { 61a7596147b43940cad3f76c53ed154ef088b9269bJim Miller case MSG_NOTIFY: 62a7596147b43940cad3f76c53ed154ef088b9269bJim Miller handleNotify(msg.arg1, msg.arg2, (Integer) msg.obj); 63a7596147b43940cad3f76c53ed154ef088b9269bJim Miller break; 64a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 65a7596147b43940cad3f76c53ed154ef088b9269bJim Miller default: 66a7596147b43940cad3f76c53ed154ef088b9269bJim Miller Slog.w(TAG, "Unknown message:" + msg.what); 67a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 68a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 69a7596147b43940cad3f76c53ed154ef088b9269bJim Miller }; 70a7596147b43940cad3f76c53ed154ef088b9269bJim Miller private Context mContext; 71a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 72a7596147b43940cad3f76c53ed154ef088b9269bJim Miller private static final int STATE_IDLE = 0; 73a7596147b43940cad3f76c53ed154ef088b9269bJim Miller private static final int STATE_LISTENING = 1; 74a7596147b43940cad3f76c53ed154ef088b9269bJim Miller private static final int STATE_ENROLLING = 2; 75a7596147b43940cad3f76c53ed154ef088b9269bJim Miller private static final int STATE_REMOVING = 3; 76a7596147b43940cad3f76c53ed154ef088b9269bJim Miller private static final long MS_PER_SEC = 1000; 77a7596147b43940cad3f76c53ed154ef088b9269bJim Miller public static final String USE_FINGERPRINT = "android.permission.USE_FINGERPRINT"; 78a7596147b43940cad3f76c53ed154ef088b9269bJim Miller public static final String ENROLL_FINGERPRINT = "android.permission.ENROLL_FINGERPRINT"; 79a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 80a7596147b43940cad3f76c53ed154ef088b9269bJim Miller private static final class ClientData { 81a7596147b43940cad3f76c53ed154ef088b9269bJim Miller public IFingerprintServiceReceiver receiver; 82a7596147b43940cad3f76c53ed154ef088b9269bJim Miller int state; 83a7596147b43940cad3f76c53ed154ef088b9269bJim Miller int userId; 84a7596147b43940cad3f76c53ed154ef088b9269bJim Miller public TokenWatcher tokenWatcher; 85a7596147b43940cad3f76c53ed154ef088b9269bJim Miller IBinder getToken() { return tokenWatcher.getToken(); } 86a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 87a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 88a7596147b43940cad3f76c53ed154ef088b9269bJim Miller private class TokenWatcher implements IBinder.DeathRecipient { 89a7596147b43940cad3f76c53ed154ef088b9269bJim Miller WeakReference<IBinder> token; 90a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 91a7596147b43940cad3f76c53ed154ef088b9269bJim Miller TokenWatcher(IBinder token) { 92a7596147b43940cad3f76c53ed154ef088b9269bJim Miller this.token = new WeakReference<IBinder>(token); 93a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 94a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 95a7596147b43940cad3f76c53ed154ef088b9269bJim Miller IBinder getToken() { return token.get(); } 96a7596147b43940cad3f76c53ed154ef088b9269bJim Miller public void binderDied() { 97a7596147b43940cad3f76c53ed154ef088b9269bJim Miller mClients.remove(token); 98a7596147b43940cad3f76c53ed154ef088b9269bJim Miller this.token = null; 99a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 100a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 101a7596147b43940cad3f76c53ed154ef088b9269bJim Miller protected void finalize() throws Throwable { 102a7596147b43940cad3f76c53ed154ef088b9269bJim Miller try { 103a7596147b43940cad3f76c53ed154ef088b9269bJim Miller if (token != null) { 104a7596147b43940cad3f76c53ed154ef088b9269bJim Miller if (DEBUG) Slog.w(TAG, "removing leaked reference: " + token); 105a7596147b43940cad3f76c53ed154ef088b9269bJim Miller mClients.remove(token); 106a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 107a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } finally { 108a7596147b43940cad3f76c53ed154ef088b9269bJim Miller super.finalize(); 109a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 110a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 111a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 112a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 113a7596147b43940cad3f76c53ed154ef088b9269bJim Miller public FingerprintService(Context context) { 114a7596147b43940cad3f76c53ed154ef088b9269bJim Miller super(context); 115a7596147b43940cad3f76c53ed154ef088b9269bJim Miller mContext = context; 116a7596147b43940cad3f76c53ed154ef088b9269bJim Miller nativeInit(this); 117a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 118a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 119a7596147b43940cad3f76c53ed154ef088b9269bJim Miller // TODO: Move these into separate process 120a7596147b43940cad3f76c53ed154ef088b9269bJim Miller // JNI methods to communicate from FingerprintManagerService to HAL 121a7596147b43940cad3f76c53ed154ef088b9269bJim Miller native int nativeEnroll(int timeout); 122a7596147b43940cad3f76c53ed154ef088b9269bJim Miller native int nativeEnrollCancel(); 123a7596147b43940cad3f76c53ed154ef088b9269bJim Miller native int nativeRemove(int fingerprintId); 124a7596147b43940cad3f76c53ed154ef088b9269bJim Miller native int nativeOpenHal(); 125a7596147b43940cad3f76c53ed154ef088b9269bJim Miller native int nativeCloseHal(); 126a7596147b43940cad3f76c53ed154ef088b9269bJim Miller native void nativeInit(FingerprintService service); 127a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 128a7596147b43940cad3f76c53ed154ef088b9269bJim Miller // JNI methods for communicating from HAL to clients 129a7596147b43940cad3f76c53ed154ef088b9269bJim Miller void notify(int msg, int arg1, int arg2) { 130a7596147b43940cad3f76c53ed154ef088b9269bJim Miller mHandler.obtainMessage(MSG_NOTIFY, msg, arg1, arg2).sendToTarget(); 131a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 132a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 133a7596147b43940cad3f76c53ed154ef088b9269bJim Miller void handleNotify(int msg, int arg1, int arg2) { 134a7596147b43940cad3f76c53ed154ef088b9269bJim Miller Slog.v(TAG, "handleNotify(msg=" + msg + ", arg1=" + arg1 + ", arg2=" + arg2 + ")"); 135a7596147b43940cad3f76c53ed154ef088b9269bJim Miller for (int i = 0; i < mClients.size(); i++) { 136a7596147b43940cad3f76c53ed154ef088b9269bJim Miller ClientData clientData = mClients.valueAt(i); 137a7596147b43940cad3f76c53ed154ef088b9269bJim Miller if (clientData == null || clientData.receiver == null) { 138a7596147b43940cad3f76c53ed154ef088b9269bJim Miller if (DEBUG) Slog.v(TAG, "clientData at " + i + " is invalid!!"); 139a7596147b43940cad3f76c53ed154ef088b9269bJim Miller continue; 140a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 141a7596147b43940cad3f76c53ed154ef088b9269bJim Miller switch (msg) { 142a7596147b43940cad3f76c53ed154ef088b9269bJim Miller case FingerprintManager.FINGERPRINT_ERROR: { 143a7596147b43940cad3f76c53ed154ef088b9269bJim Miller final int error = arg1; 144a7596147b43940cad3f76c53ed154ef088b9269bJim Miller try { 145a7596147b43940cad3f76c53ed154ef088b9269bJim Miller clientData.receiver.onError(error); 146a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } catch (RemoteException e) { 147a7596147b43940cad3f76c53ed154ef088b9269bJim Miller Slog.e(TAG, "can't send message to client. Did it die?", e); 148a7596147b43940cad3f76c53ed154ef088b9269bJim Miller mClients.remove(mClients.keyAt(i)); 149a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 150a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 151a7596147b43940cad3f76c53ed154ef088b9269bJim Miller break; 152a7596147b43940cad3f76c53ed154ef088b9269bJim Miller case FingerprintManager.FINGERPRINT_ACQUIRED: { 153a7596147b43940cad3f76c53ed154ef088b9269bJim Miller final int acquireInfo = arg1; 154a7596147b43940cad3f76c53ed154ef088b9269bJim Miller try { 155a7596147b43940cad3f76c53ed154ef088b9269bJim Miller clientData.receiver.onAcquired(acquireInfo); 156a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } catch (RemoteException e) { 157a7596147b43940cad3f76c53ed154ef088b9269bJim Miller Slog.e(TAG, "can't send message to client. Did it die?", e); 158a7596147b43940cad3f76c53ed154ef088b9269bJim Miller mClients.remove(mClients.keyAt(i)); 159a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 160a7596147b43940cad3f76c53ed154ef088b9269bJim Miller break; 161a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 162a7596147b43940cad3f76c53ed154ef088b9269bJim Miller case FingerprintManager.FINGERPRINT_PROCESSED: { 163a7596147b43940cad3f76c53ed154ef088b9269bJim Miller final int fingerId = arg1; 164a7596147b43940cad3f76c53ed154ef088b9269bJim Miller try { 165a7596147b43940cad3f76c53ed154ef088b9269bJim Miller clientData.receiver.onProcessed(fingerId); 166a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } catch (RemoteException e) { 167a7596147b43940cad3f76c53ed154ef088b9269bJim Miller Slog.e(TAG, "can't send message to client. Did it die?", e); 168a7596147b43940cad3f76c53ed154ef088b9269bJim Miller mClients.remove(mClients.keyAt(i)); 169a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 170a7596147b43940cad3f76c53ed154ef088b9269bJim Miller break; 171a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 172a7596147b43940cad3f76c53ed154ef088b9269bJim Miller case FingerprintManager.FINGERPRINT_TEMPLATE_ENROLLING: { 173a7596147b43940cad3f76c53ed154ef088b9269bJim Miller final int fingerId = arg1; 174a7596147b43940cad3f76c53ed154ef088b9269bJim Miller final int remaining = arg2; 175a7596147b43940cad3f76c53ed154ef088b9269bJim Miller if (clientData.state == STATE_ENROLLING) { 176a7596147b43940cad3f76c53ed154ef088b9269bJim Miller // Only send enroll updates to clients that are actually enrolling 177a7596147b43940cad3f76c53ed154ef088b9269bJim Miller try { 178a7596147b43940cad3f76c53ed154ef088b9269bJim Miller clientData.receiver.onEnrollResult(fingerId, remaining); 179a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } catch (RemoteException e) { 180a7596147b43940cad3f76c53ed154ef088b9269bJim Miller Slog.e(TAG, "can't send message to client. Did it die?", e); 181a7596147b43940cad3f76c53ed154ef088b9269bJim Miller mClients.remove(mClients.keyAt(i)); 182a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 183a7596147b43940cad3f76c53ed154ef088b9269bJim Miller // Update the database with new finger id. 184a7596147b43940cad3f76c53ed154ef088b9269bJim Miller // TODO: move to client code (Settings) 185a7596147b43940cad3f76c53ed154ef088b9269bJim Miller if (remaining == 0) { 186a7596147b43940cad3f76c53ed154ef088b9269bJim Miller FingerprintUtils.addFingerprintIdForUser(fingerId, 187a7596147b43940cad3f76c53ed154ef088b9269bJim Miller mContext.getContentResolver(), clientData.userId); 188a7596147b43940cad3f76c53ed154ef088b9269bJim Miller clientData.state = STATE_IDLE; // Nothing left to do 189a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 190a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } else { 191a7596147b43940cad3f76c53ed154ef088b9269bJim Miller if (DEBUG) Slog.w(TAG, "Client not enrolling"); 192a7596147b43940cad3f76c53ed154ef088b9269bJim Miller break; 193a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 194a7596147b43940cad3f76c53ed154ef088b9269bJim Miller break; 195a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 196a7596147b43940cad3f76c53ed154ef088b9269bJim Miller case FingerprintManager.FINGERPRINT_TEMPLATE_REMOVED: { 197a7596147b43940cad3f76c53ed154ef088b9269bJim Miller int fingerId = arg1; 198a7596147b43940cad3f76c53ed154ef088b9269bJim Miller if (fingerId == 0) throw new IllegalStateException("Got illegal id from HAL"); 199a7596147b43940cad3f76c53ed154ef088b9269bJim Miller FingerprintUtils.removeFingerprintIdForUser(fingerId, 200a7596147b43940cad3f76c53ed154ef088b9269bJim Miller mContext.getContentResolver(), clientData.userId); 201a7596147b43940cad3f76c53ed154ef088b9269bJim Miller if (clientData.receiver != null) { 202a7596147b43940cad3f76c53ed154ef088b9269bJim Miller try { 203a7596147b43940cad3f76c53ed154ef088b9269bJim Miller clientData.receiver.onRemoved(fingerId); 204a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } catch (RemoteException e) { 205a7596147b43940cad3f76c53ed154ef088b9269bJim Miller Slog.e(TAG, "can't send message to client. Did it die?", e); 206a7596147b43940cad3f76c53ed154ef088b9269bJim Miller mClients.remove(mClients.keyAt(i)); 207a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 208a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 209a7596147b43940cad3f76c53ed154ef088b9269bJim Miller clientData.state = STATE_LISTENING; 210a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 211a7596147b43940cad3f76c53ed154ef088b9269bJim Miller break; 212a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 213a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 214a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 215a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 216a7596147b43940cad3f76c53ed154ef088b9269bJim Miller void startEnroll(IBinder token, long timeout, int userId) { 217a7596147b43940cad3f76c53ed154ef088b9269bJim Miller ClientData clientData = mClients.get(token); 218a7596147b43940cad3f76c53ed154ef088b9269bJim Miller if (clientData != null) { 219a7596147b43940cad3f76c53ed154ef088b9269bJim Miller if (clientData.userId != userId) throw new IllegalStateException("Bad user"); 220a7596147b43940cad3f76c53ed154ef088b9269bJim Miller clientData.state = STATE_ENROLLING; 221a7596147b43940cad3f76c53ed154ef088b9269bJim Miller nativeEnroll((int) (timeout / MS_PER_SEC)); 222a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } else { 223a7596147b43940cad3f76c53ed154ef088b9269bJim Miller Slog.w(TAG, "enroll(): No listener registered"); 224a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 225a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 226a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 227a7596147b43940cad3f76c53ed154ef088b9269bJim Miller void startEnrollCancel(IBinder token, int userId) { 228a7596147b43940cad3f76c53ed154ef088b9269bJim Miller ClientData clientData = mClients.get(token); 229a7596147b43940cad3f76c53ed154ef088b9269bJim Miller if (clientData != null) { 230a7596147b43940cad3f76c53ed154ef088b9269bJim Miller if (clientData.userId != userId) throw new IllegalStateException("Bad user"); 231a7596147b43940cad3f76c53ed154ef088b9269bJim Miller clientData.state = STATE_LISTENING; 232a7596147b43940cad3f76c53ed154ef088b9269bJim Miller nativeEnrollCancel(); 233a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } else { 234a7596147b43940cad3f76c53ed154ef088b9269bJim Miller Slog.w(TAG, "enrollCancel(): No listener registered"); 235a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 236a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 237a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 238a7596147b43940cad3f76c53ed154ef088b9269bJim Miller // Remove all fingerprints for the given user. 239a7596147b43940cad3f76c53ed154ef088b9269bJim Miller void startRemove(IBinder token, int fingerId, int userId) { 240a7596147b43940cad3f76c53ed154ef088b9269bJim Miller ClientData clientData = mClients.get(token); 241a7596147b43940cad3f76c53ed154ef088b9269bJim Miller if (clientData != null) { 242a7596147b43940cad3f76c53ed154ef088b9269bJim Miller if (clientData.userId != userId) throw new IllegalStateException("Bad user"); 243a7596147b43940cad3f76c53ed154ef088b9269bJim Miller clientData.state = STATE_REMOVING; 244a7596147b43940cad3f76c53ed154ef088b9269bJim Miller // The fingerprint id will be removed when we get confirmation from the HAL 245a7596147b43940cad3f76c53ed154ef088b9269bJim Miller int result = nativeRemove(fingerId); 246a7596147b43940cad3f76c53ed154ef088b9269bJim Miller if (result != 0) { 247a7596147b43940cad3f76c53ed154ef088b9269bJim Miller Slog.w(TAG, "Error removing fingerprint with id = " + fingerId); 248a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 249a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } else { 250a7596147b43940cad3f76c53ed154ef088b9269bJim Miller Slog.w(TAG, "remove(" + token + "): No listener registered"); 251a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 252a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 253a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 254a7596147b43940cad3f76c53ed154ef088b9269bJim Miller void addListener(IBinder token, IFingerprintServiceReceiver receiver, int userId) { 255a7596147b43940cad3f76c53ed154ef088b9269bJim Miller if (DEBUG) Slog.v(TAG, "startListening(" + receiver + ")"); 256a7596147b43940cad3f76c53ed154ef088b9269bJim Miller if (mClients.get(token) == null) { 257a7596147b43940cad3f76c53ed154ef088b9269bJim Miller ClientData clientData = new ClientData(); 258a7596147b43940cad3f76c53ed154ef088b9269bJim Miller clientData.state = STATE_LISTENING; 259a7596147b43940cad3f76c53ed154ef088b9269bJim Miller clientData.receiver = receiver; 260a7596147b43940cad3f76c53ed154ef088b9269bJim Miller clientData.userId = userId; 261a7596147b43940cad3f76c53ed154ef088b9269bJim Miller clientData.tokenWatcher = new TokenWatcher(token); 262a7596147b43940cad3f76c53ed154ef088b9269bJim Miller try { 263a7596147b43940cad3f76c53ed154ef088b9269bJim Miller token.linkToDeath(clientData.tokenWatcher, 0); 264a7596147b43940cad3f76c53ed154ef088b9269bJim Miller mClients.put(token, clientData); 265a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } catch (RemoteException e) { 266a7596147b43940cad3f76c53ed154ef088b9269bJim Miller Slog.w(TAG, "caught remote exception in linkToDeath: ", e); 267a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 268a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } else { 269a7596147b43940cad3f76c53ed154ef088b9269bJim Miller if (DEBUG) Slog.v(TAG, "listener already registered for " + token); 270a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 271a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 272a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 273a7596147b43940cad3f76c53ed154ef088b9269bJim Miller void removeListener(IBinder token, int userId) { 274a7596147b43940cad3f76c53ed154ef088b9269bJim Miller if (DEBUG) Slog.v(TAG, "stopListening(" + token + ")"); 275a7596147b43940cad3f76c53ed154ef088b9269bJim Miller ClientData clientData = mClients.get(token); 276a7596147b43940cad3f76c53ed154ef088b9269bJim Miller if (clientData != null) { 277a7596147b43940cad3f76c53ed154ef088b9269bJim Miller token.unlinkToDeath(clientData.tokenWatcher, 0); 278a7596147b43940cad3f76c53ed154ef088b9269bJim Miller mClients.remove(token); 279a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } else { 280a7596147b43940cad3f76c53ed154ef088b9269bJim Miller if (DEBUG) Slog.v(TAG, "listener not registered: " + token); 281a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 282a7596147b43940cad3f76c53ed154ef088b9269bJim Miller mClients.remove(token); 283a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 284a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 285a7596147b43940cad3f76c53ed154ef088b9269bJim Miller void checkPermission(String permisison) { 286a7596147b43940cad3f76c53ed154ef088b9269bJim Miller // TODO 287a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 288a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 289a7596147b43940cad3f76c53ed154ef088b9269bJim Miller private final class FingerprintServiceWrapper extends IFingerprintService.Stub { 290a7596147b43940cad3f76c53ed154ef088b9269bJim Miller @Override // Binder call 291a7596147b43940cad3f76c53ed154ef088b9269bJim Miller public void enroll(IBinder token, long timeout, int userId) { 292a7596147b43940cad3f76c53ed154ef088b9269bJim Miller checkPermission(ENROLL_FINGERPRINT); 293a7596147b43940cad3f76c53ed154ef088b9269bJim Miller startEnroll(token, timeout, userId); 294a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 295a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 296a7596147b43940cad3f76c53ed154ef088b9269bJim Miller @Override // Binder call 297a7596147b43940cad3f76c53ed154ef088b9269bJim Miller public void enrollCancel(IBinder token,int userId) { 298a7596147b43940cad3f76c53ed154ef088b9269bJim Miller checkPermission(ENROLL_FINGERPRINT); 299a7596147b43940cad3f76c53ed154ef088b9269bJim Miller startEnrollCancel(token, userId); 300a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 301a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 302a7596147b43940cad3f76c53ed154ef088b9269bJim Miller @Override // Binder call 303a7596147b43940cad3f76c53ed154ef088b9269bJim Miller public void remove(IBinder token, int fingerprintId, int userId) { 304a7596147b43940cad3f76c53ed154ef088b9269bJim Miller checkPermission(ENROLL_FINGERPRINT); // TODO: Maybe have another permission 305a7596147b43940cad3f76c53ed154ef088b9269bJim Miller startRemove(token, fingerprintId, userId); 306a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 307a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 308a7596147b43940cad3f76c53ed154ef088b9269bJim Miller @Override // Binder call 309a7596147b43940cad3f76c53ed154ef088b9269bJim Miller public void startListening(IBinder token, IFingerprintServiceReceiver receiver, int userId) 310a7596147b43940cad3f76c53ed154ef088b9269bJim Miller { 311a7596147b43940cad3f76c53ed154ef088b9269bJim Miller checkPermission(USE_FINGERPRINT); 312a7596147b43940cad3f76c53ed154ef088b9269bJim Miller addListener(token, receiver, userId); 313a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 314a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 315a7596147b43940cad3f76c53ed154ef088b9269bJim Miller @Override // Binder call 316a7596147b43940cad3f76c53ed154ef088b9269bJim Miller public void stopListening(IBinder token, int userId) { 317a7596147b43940cad3f76c53ed154ef088b9269bJim Miller checkPermission(USE_FINGERPRINT); 318a7596147b43940cad3f76c53ed154ef088b9269bJim Miller removeListener(token, userId); 319a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 320a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 321a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 322a7596147b43940cad3f76c53ed154ef088b9269bJim Miller @Override 323a7596147b43940cad3f76c53ed154ef088b9269bJim Miller public void onStart() { 324a7596147b43940cad3f76c53ed154ef088b9269bJim Miller publishBinderService(Context.FINGERPRINT_SERVICE, new FingerprintServiceWrapper()); 325a7596147b43940cad3f76c53ed154ef088b9269bJim Miller nativeOpenHal(); 326a7596147b43940cad3f76c53ed154ef088b9269bJim Miller } 327a7596147b43940cad3f76c53ed154ef088b9269bJim Miller 328a7596147b43940cad3f76c53ed154ef088b9269bJim Miller} 329