FileDocCategorySizeDatePackage
FingerprintService.javaAPI DocAndroid 5.1 API12785Thu Mar 12 22:22:42 GMT 2015com.android.server.fingerprint

FingerprintService

public class FingerprintService extends com.android.server.SystemService
A service to manage multiple clients that want to access the fingerprint HAL API. The service is responsible for maintaining a list of clients and dispatching all fingerprint -related events.
hide

Fields Summary
private final String
TAG
private static final boolean
DEBUG
private android.util.ArrayMap
mClients
private static final int
MSG_NOTIFY
android.os.Handler
mHandler
private android.content.Context
mContext
private static final int
STATE_IDLE
private static final int
STATE_LISTENING
private static final int
STATE_ENROLLING
private static final int
STATE_REMOVING
private static final long
MS_PER_SEC
public static final String
USE_FINGERPRINT
public static final String
ENROLL_FINGERPRINT
Constructors Summary
public FingerprintService(android.content.Context context)

        super(context);
        mContext = context;
        nativeInit(this);
    
Methods Summary
voidaddListener(android.os.IBinder token, android.service.fingerprint.IFingerprintServiceReceiver receiver, int userId)

        if (DEBUG) Slog.v(TAG, "startListening(" + receiver + ")");
        if (mClients.get(token) == null) {
            ClientData clientData = new ClientData();
            clientData.state = STATE_LISTENING;
            clientData.receiver = receiver;
            clientData.userId = userId;
            clientData.tokenWatcher = new TokenWatcher(token);
            try {
                token.linkToDeath(clientData.tokenWatcher, 0);
                mClients.put(token, clientData);
            } catch (RemoteException e) {
                Slog.w(TAG, "caught remote exception in linkToDeath: ", e);
            }
        } else {
            if (DEBUG) Slog.v(TAG, "listener already registered for " + token);
        }
    
voidcheckPermission(java.lang.String permisison)

        // TODO
    
voidhandleNotify(int msg, int arg1, int arg2)

        Slog.v(TAG, "handleNotify(msg=" + msg + ", arg1=" + arg1 + ", arg2=" + arg2 + ")");
        for (int i = 0; i < mClients.size(); i++) {
            ClientData clientData = mClients.valueAt(i);
            if (clientData == null || clientData.receiver == null) {
                if (DEBUG) Slog.v(TAG, "clientData at " + i + " is invalid!!");
                continue;
            }
            switch (msg) {
                case FingerprintManager.FINGERPRINT_ERROR: {
                    final int error = arg1;
                    try {
                        clientData.receiver.onError(error);
                    } catch (RemoteException e) {
                        Slog.e(TAG, "can't send message to client. Did it die?", e);
                        mClients.remove(mClients.keyAt(i));
                    }
                }
                break;
                case FingerprintManager.FINGERPRINT_ACQUIRED: {
                    final int acquireInfo = arg1;
                    try {
                        clientData.receiver.onAcquired(acquireInfo);
                    } catch (RemoteException e) {
                        Slog.e(TAG, "can't send message to client. Did it die?", e);
                        mClients.remove(mClients.keyAt(i));
                    }
                    break;
                }
                case FingerprintManager.FINGERPRINT_PROCESSED: {
                    final int fingerId = arg1;
                    try {
                        clientData.receiver.onProcessed(fingerId);
                    } catch (RemoteException e) {
                        Slog.e(TAG, "can't send message to client. Did it die?", e);
                        mClients.remove(mClients.keyAt(i));
                    }
                    break;
                }
                case FingerprintManager.FINGERPRINT_TEMPLATE_ENROLLING: {
                    final int fingerId = arg1;
                    final int remaining = arg2;
                    if (clientData.state == STATE_ENROLLING) {
                        // Only send enroll updates to clients that are actually enrolling
                        try {
                            clientData.receiver.onEnrollResult(fingerId, remaining);
                        } catch (RemoteException e) {
                            Slog.e(TAG, "can't send message to client. Did it die?", e);
                            mClients.remove(mClients.keyAt(i));
                        }
                        // Update the database with new finger id.
                        // TODO: move to client code (Settings)
                        if (remaining == 0) {
                            FingerprintUtils.addFingerprintIdForUser(fingerId,
                                    mContext.getContentResolver(), clientData.userId);
                            clientData.state = STATE_IDLE; // Nothing left to do
                        }
                    } else {
                        if (DEBUG) Slog.w(TAG, "Client not enrolling");
                        break;
                    }
                    break;
                }
                case FingerprintManager.FINGERPRINT_TEMPLATE_REMOVED: {
                    int fingerId = arg1;
                    if (fingerId == 0) throw new IllegalStateException("Got illegal id from HAL");
                    FingerprintUtils.removeFingerprintIdForUser(fingerId,
                            mContext.getContentResolver(), clientData.userId);
                    if (clientData.receiver != null) {
                        try {
                            clientData.receiver.onRemoved(fingerId);
                        } catch (RemoteException e) {
                            Slog.e(TAG, "can't send message to client. Did it die?", e);
                            mClients.remove(mClients.keyAt(i));
                        }
                    }
                    clientData.state = STATE_LISTENING;
                }
                break;
            }
        }
    
native intnativeCloseHal()

native intnativeEnroll(int timeout)

native intnativeEnrollCancel()

native voidnativeInit(com.android.server.fingerprint.FingerprintService service)

native intnativeOpenHal()

native intnativeRemove(int fingerprintId)

voidnotify(int msg, int arg1, int arg2)

        mHandler.obtainMessage(MSG_NOTIFY, msg, arg1, arg2).sendToTarget();
    
public voidonStart()

       publishBinderService(Context.FINGERPRINT_SERVICE, new FingerprintServiceWrapper());
       nativeOpenHal();
    
voidremoveListener(android.os.IBinder token, int userId)

        if (DEBUG) Slog.v(TAG, "stopListening(" + token + ")");
        ClientData clientData = mClients.get(token);
        if (clientData != null) {
            token.unlinkToDeath(clientData.tokenWatcher, 0);
            mClients.remove(token);
        } else {
            if (DEBUG) Slog.v(TAG, "listener not registered: " + token);
        }
        mClients.remove(token);
    
voidstartEnroll(android.os.IBinder token, long timeout, int userId)

        ClientData clientData = mClients.get(token);
        if (clientData != null) {
            if (clientData.userId != userId) throw new IllegalStateException("Bad user");
            clientData.state = STATE_ENROLLING;
            nativeEnroll((int) (timeout / MS_PER_SEC));
        } else {
            Slog.w(TAG, "enroll(): No listener registered");
        }
    
voidstartEnrollCancel(android.os.IBinder token, int userId)

        ClientData clientData = mClients.get(token);
        if (clientData != null) {
            if (clientData.userId != userId) throw new IllegalStateException("Bad user");
            clientData.state = STATE_LISTENING;
            nativeEnrollCancel();
        } else {
            Slog.w(TAG, "enrollCancel(): No listener registered");
        }
    
voidstartRemove(android.os.IBinder token, int fingerId, int userId)

        ClientData clientData = mClients.get(token);
        if (clientData != null) {
            if (clientData.userId != userId) throw new IllegalStateException("Bad user");
            clientData.state = STATE_REMOVING;
            // The fingerprint id will be removed when we get confirmation from the HAL
            int result = nativeRemove(fingerId);
            if (result != 0) {
                Slog.w(TAG, "Error removing fingerprint with id = " + fingerId);
            }
        } else {
            Slog.w(TAG, "remove(" + token + "): No listener registered");
        }