Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a7596147 authored by Jim Miller's avatar Jim Miller
Browse files

First pass at FingerprintService integration with HAL.

Move FingerprintService to framework services directory
Fix merge conflicts.

Tested: scanning, enrolling, removing.

Change-Id: I58b2b902cb671dc82cdaa54a195ba5f1a154622c
parent afc00e1c
Loading
Loading
Loading
Loading
+37 −5
Original line number Diff line number Diff line
@@ -26011,29 +26011,61 @@ package android.service.dreams {
package android.service.fingerprint {
  public class FingerprintManager {
    ctor public FingerprintManager(android.content.Context);
    ctor public FingerprintManager(android.content.Context, android.service.fingerprint.IFingerprintService);
    method public void enroll(long);
    method public void enrollCancel();
    method public boolean enrolledAndEnabled();
    method public void remove(int);
    method public void startListening(android.service.fingerprint.FingerprintManagerReceiver);
    method public void stopListening();
    field public static final int FINGERPRINT_ACQUIRED = 1; // 0x1
    field public static final int FINGERPRINT_ACQUIRED_GOOD = 0; // 0x0
    field public static final int FINGERPRINT_ACQUIRED_IMAGER_DIRTY = 4; // 0x4
    field public static final int FINGERPRINT_ACQUIRED_INSUFFICIENT = 2; // 0x2
    field public static final int FINGERPRINT_ACQUIRED_PARTIAL = 1; // 0x1
    field public static final int FINGERPRINT_ACQUIRED_TOO_FAST = 16; // 0x10
    field public static final int FINGERPRINT_ACQUIRED_TOO_SLOW = 8; // 0x8
    field public static final int FINGERPRINT_ERROR = -1; // 0xffffffff
    field public static final int FINGERPRINT_ERROR_BAD_CAPTURE = 2; // 0x2
    field public static final int FINGERPRINT_ERROR_HW_UNAVAILABLE = 1; // 0x1
    field public static final int FINGERPRINT_ERROR_NO_RECEIVER = -10; // 0xfffffff6
    field public static final int FINGERPRINT_ERROR_NO_SPACE = 4; // 0x4
    field public static final int FINGERPRINT_ERROR_TIMEOUT = 3; // 0x3
    field public static final int FINGERPRINT_SCANNED = 1; // 0x1
    field public static final int FINGERPRINT_TEMPLATE_ENROLLING = 2; // 0x2
    field public static final int FINGERPRINT_ERROR_UNABLE_TO_PROCESS = 2; // 0x2
    field public static final int FINGERPRINT_PROCESSED = 2; // 0x2
    field public static final int FINGERPRINT_TEMPLATE_ENROLLING = 3; // 0x3
    field public static final int FINGERPRINT_TEMPLATE_REMOVED = 4; // 0x4
  }
  public class FingerprintManagerReceiver {
    ctor public FingerprintManagerReceiver();
    method public void onAcquired(int);
    method public void onEnrollResult(int, int);
    method public void onError(int);
    method public void onProcessed(int);
    method public void onRemoved(int);
    method public void onScanned(int, int);
  }
  public class FingerprintUtils {
    ctor public FingerprintUtils();
    method public static void addFingerprintIdForUser(int, android.content.ContentResolver, int);
    method public static int[] getFingerprintIdsForUser(android.content.ContentResolver, int);
    method public static boolean removeFingerprintIdForUser(int, android.content.ContentResolver, int);
  }
  public abstract interface IFingerprintService implements android.os.IInterface {
    method public abstract void enroll(android.os.IBinder, long, int) throws android.os.RemoteException;
    method public abstract void enrollCancel(android.os.IBinder, int) throws android.os.RemoteException;
    method public abstract void remove(android.os.IBinder, int, int) throws android.os.RemoteException;
    method public abstract void startListening(android.os.IBinder, android.service.fingerprint.IFingerprintServiceReceiver, int) throws android.os.RemoteException;
    method public abstract void stopListening(android.os.IBinder, int) throws android.os.RemoteException;
  }
  public abstract interface IFingerprintServiceReceiver implements android.os.IInterface {
    method public abstract void onAcquired(int) throws android.os.RemoteException;
    method public abstract void onEnrollResult(int, int) throws android.os.RemoteException;
    method public abstract void onError(int) throws android.os.RemoteException;
    method public abstract void onProcessed(int) throws android.os.RemoteException;
    method public abstract void onRemoved(int) throws android.os.RemoteException;
  }
}
+10 −7
Original line number Diff line number Diff line
@@ -115,9 +115,8 @@ import android.os.storage.IMountService;
import android.os.storage.StorageManager;
import android.print.IPrintManager;
import android.print.PrintManager;
import android.service.fingerprint.IFingerprintService;
import android.service.fingerprint.FingerprintManager;
import android.service.fingerprint.FingerprintManagerReceiver;
import android.service.fingerprint.FingerprintService;
import android.telecomm.TelecommManager;
import android.telephony.TelephonyManager;
import android.content.ClipboardManager;
@@ -466,11 +465,6 @@ class ContextImpl extends Context {
                    return new KeyguardManager();
                }});

        registerService(FINGERPRINT_SERVICE, new ServiceFetcher() {
            public Object createService(ContextImpl ctx) {
                return new FingerprintManager(ctx);
            }});

        registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {
                public Object createService(ContextImpl ctx) {
                    return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
@@ -690,6 +684,7 @@ class ContextImpl extends Context {
                return new MediaSessionManager(ctx);
            }
        });

        registerService(TRUST_SERVICE, new ServiceFetcher() {
            public Object createService(ContextImpl ctx) {
                IBinder b = ServiceManager.getService(TRUST_SERVICE);
@@ -697,6 +692,14 @@ class ContextImpl extends Context {
            }
        });

        registerService(FINGERPRINT_SERVICE, new ServiceFetcher() {
            public Object createService(ContextImpl ctx) {
                IBinder b = ServiceManager.getService(FINGERPRINT_SERVICE);
                IFingerprintService service = IFingerprintService.Stub.asInterface(b);
                return new FingerprintManager(ctx.getOuterContext(), service);
            }
        });

        registerService(TV_INPUT_SERVICE, new ServiceFetcher() {
            public Object createService(ContextImpl ctx) {
                IBinder iBinder = ServiceManager.getService(TV_INPUT_SERVICE);
+84 −52
Original line number Diff line number Diff line
@@ -22,12 +22,14 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
import android.util.Slog;

/**
 * A class that coordinates access to the fingerprint hardware.
@@ -36,31 +38,40 @@ import android.util.Log;
public class FingerprintManager {
    private static final String TAG = "FingerprintManager";
    private static final boolean DEBUG = true;
    private static final String FINGERPRINT_SERVICE_PACKAGE = "com.android.service.fingerprint";
    private static final String FINGERPRINT_SERVICE_CLASS =
            "com.android.service.fingerprint.FingerprintService";
    private static final int MSG_ENROLL_RESULT = 100;
    private static final int MSG_SCANNED = 101;
    private static final int MSG_ERROR = 102;
    private static final int MSG_REMOVED = 103;
    private static final int MSG_ACQUIRED = 101;
    private static final int MSG_PROCESSED = 102;
    private static final int MSG_ERROR = 103;
    private static final int MSG_REMOVED = 104;

    // Errors generated by layers above HAL
    public static final int FINGERPRINT_ERROR_NO_RECEIVER = -10;
    public static final int FINGERPRINT_ERROR = -1; // One of the error messages below.

    // Progress messages.
    public static final int FINGERPRINT_SCANNED = 1;
    public static final int FINGERPRINT_TEMPLATE_ENROLLING = 2;
    // Message types.  Must agree with HAL (fingerprint.h)
    public static final int FINGERPRINT_ERROR = -1;
    public static final int FINGERPRINT_ACQUIRED = 1;
    public static final int FINGERPRINT_PROCESSED = 2;
    public static final int FINGERPRINT_TEMPLATE_ENROLLING = 3;
    public static final int FINGERPRINT_TEMPLATE_REMOVED = 4;

    // Error messages. Must agree with fingerprint HAL definitions.
    // Error messages. Must agree with HAL (fingerprint.h)
    public static final int FINGERPRINT_ERROR_HW_UNAVAILABLE = 1;
    public static final int FINGERPRINT_ERROR_BAD_CAPTURE = 2;
    public static final int FINGERPRINT_ERROR_UNABLE_TO_PROCESS = 2;
    public static final int FINGERPRINT_ERROR_TIMEOUT = 3;
    public static final int FINGERPRINT_ERROR_NO_SPACE = 4;

    // FINGERPRINT_ACQUIRED messages.  Must agree with HAL (fingerprint.h)
    public static final int FINGERPRINT_ACQUIRED_GOOD = 0;
    public static final int FINGERPRINT_ACQUIRED_PARTIAL = 1;
    public static final int FINGERPRINT_ACQUIRED_INSUFFICIENT = 2;
    public static final int FINGERPRINT_ACQUIRED_IMAGER_DIRTY = 4;
    public static final int FINGERPRINT_ACQUIRED_TOO_SLOW = 8;
    public static final int FINGERPRINT_ACQUIRED_TOO_FAST = 16;

    private IFingerprintService mService;
    private FingerprintManagerReceiver mClientReceiver;
    private Context mContext;
    private IBinder mToken = new Binder();

    private Handler mHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
@@ -69,8 +80,11 @@ public class FingerprintManager {
                    case MSG_ENROLL_RESULT:
                        mClientReceiver.onEnrollResult(msg.arg1, msg.arg2);
                        break;
                    case MSG_SCANNED:
                        mClientReceiver.onScanned(msg.arg1, msg.arg2);
                    case MSG_ACQUIRED:
                        mClientReceiver.onAcquired(msg.arg1);
                        break;
                    case MSG_PROCESSED:
                        mClientReceiver.onProcessed(msg.arg1);
                        break;
                    case MSG_ERROR:
                        mClientReceiver.onError(msg.arg1);
@@ -82,35 +96,13 @@ public class FingerprintManager {
        }
    };

    public FingerprintManager(Context context) {
    public FingerprintManager(Context context, IFingerprintService service) {
        mContext = context;
        // Connect to service...
        Intent intent = new Intent();
        intent.setClassName(FINGERPRINT_SERVICE_PACKAGE, FINGERPRINT_SERVICE_CLASS);
        if (!context.bindServiceAsUser(intent, mFingerprintConnection,
                Context.BIND_AUTO_CREATE, UserHandle.CURRENT_OR_SELF)) {
            if (DEBUG) Log.v(TAG, "Can't bind to " + FINGERPRINT_SERVICE_CLASS);
        }
        mService = service;
        if (mService == null) {
            Slog.v(TAG, "FingerprintManagerService was null");
        }

    private final ServiceConnection mFingerprintConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            if (DEBUG) Log.v(TAG, "Connected to FingerprintService");
            mService = IFingerprintService.Stub.asInterface(service);
            try {
                mService.startListening(mServiceReceiver, getCurrentUserId());
            } catch (RemoteException e) {
                if (DEBUG) Log.v(TAG, "Failed to set callback", e);
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            if (DEBUG) Log.v(TAG, "Disconnected from FingerprintService");
            mService = null;
    }
    };

    private IFingerprintServiceReceiver mServiceReceiver = new IFingerprintServiceReceiver.Stub() {

@@ -118,9 +110,12 @@ public class FingerprintManager {
            mHandler.obtainMessage(MSG_ENROLL_RESULT, fingerprintId, remaining).sendToTarget();
        }

        public void onScanned(int fingerprintId, int confidence) {
            mHandler.obtainMessage(MSG_SCANNED, fingerprintId, confidence)
                    .sendToTarget();;
        public void onAcquired(int acquireInfo) {
            mHandler.obtainMessage(MSG_ACQUIRED, acquireInfo, 0).sendToTarget();
        }

        public void onProcessed(int fingerprintId) {
            mHandler.obtainMessage(MSG_PROCESSED, fingerprintId, 0).sendToTarget();
        }

        public void onError(int error) {
@@ -151,12 +146,14 @@ public class FingerprintManager {
     */
    public void enroll(long timeout) {
        if (mServiceReceiver == null) {
            throw new IllegalStateException("enroll: Call registerCallback() first");
            sendError(FINGERPRINT_ERROR_NO_RECEIVER, 0, 0);
            return;
        }
        if (mService != null) try {
            mService.enroll(timeout, getCurrentUserId());
            mService.enroll(mToken, timeout, getCurrentUserId());
        } catch (RemoteException e) {
            Log.v(TAG, "Remote exception while enrolling: ", e);
            sendError(FINGERPRINT_ERROR_HW_UNAVAILABLE, 0, 0);
        }
    }

@@ -166,11 +163,20 @@ public class FingerprintManager {
     * @param fingerprintId
     */
    public void remove(int fingerprintId) {
        if (mService != null) try {
            mService.remove(fingerprintId, getCurrentUserId());
        if (mServiceReceiver == null) {
            sendError(FINGERPRINT_ERROR_NO_RECEIVER, 0, 0);
            return;
        }
        if (mService != null) {
            try {
                mService.remove(mToken, fingerprintId, getCurrentUserId());
            } catch (RemoteException e) {
                Log.v(TAG, "Remote exception during remove of fingerprintId: " + fingerprintId, e);
            }
        } else {
            Log.w(TAG, "remove(): Service not connected!");
            sendError(FINGERPRINT_ERROR_HW_UNAVAILABLE, 0, 0);
        }
    }

    /**
@@ -181,10 +187,13 @@ public class FingerprintManager {
        mClientReceiver = receiver;
        if (mService != null) {
            try {
                mService.startListening(mServiceReceiver, getCurrentUserId());
                mService.startListening(mToken, mServiceReceiver, getCurrentUserId());
            } catch (RemoteException e) {
                Log.v(TAG, "Remote exception in startListening(): ", e);
            }
        } else {
            Log.w(TAG, "startListening(): Service not connected!");
            sendError(FINGERPRINT_ERROR_HW_UNAVAILABLE, 0, 0);
        }
    }

@@ -201,15 +210,38 @@ public class FingerprintManager {
     * Stops the client from listening to fingerprint events.
     */
    public void stopListening() {
        mClientReceiver = null;
        if (mService != null) {
            try {
                mService.stopListening(getCurrentUserId());
                mService.stopListening(mToken, getCurrentUserId());
                mClientReceiver = null;
            } catch (RemoteException e) {
                Log.v(TAG, "Remote exception in stopListening(): ", e);
            }
        } else {
            Log.w(TAG, "stopListening(): Service not connected!");
            sendError(FINGERPRINT_ERROR_HW_UNAVAILABLE, 0, 0);
        }
    }

    public void enrollCancel() {
        if (mServiceReceiver == null) {
            sendError(FINGERPRINT_ERROR_NO_RECEIVER, 0, 0);
            return;
        }
        if (mService != null) {
            try {
                mService.enrollCancel(mToken, getCurrentUserId());
                mClientReceiver = null;
            } catch (RemoteException e) {
                Log.v(TAG, "Remote exception in enrollCancel(): ", e);
                sendError(FINGERPRINT_ERROR_HW_UNAVAILABLE, 0, 0);
            }
        } else {
            Log.w(TAG, "enrollCancel(): Service not connected!");
        }
    }

    private void sendError(int msg, int arg1, int arg2) {
        mHandler.obtainMessage(msg, arg1, arg2);
    }
}
 No newline at end of file
+20 −6
Original line number Diff line number Diff line
@@ -30,18 +30,32 @@ public class FingerprintManagerReceiver {
    public void onEnrollResult(int fingerprintId,  int remaining) { }

    /**
     * Fingerprint scan detected. Most clients will use this function to detect a fingerprint
     * Fingerprint touch detected, but not processed yet. Clients will use this message to
     * determine a good or bad scan before the fingerprint is processed.  This is meant for the
     * client to provide feedback about the scan or alert the user that recognition is to follow.
     *
     * @param fingerprintId is the finger the hardware has detected.
     * @param confidence from 0 (no confidence) to 65535 (high confidence). Fingerprint 0 has
     * special meaning - the finger wasn't recognized.
     * @param acquiredInfo one of:
     * {@link FingerprintManager#FINGERPRINT_ACQUIRED_GOOD},
     * {@link FingerprintManager#FINGERPRINT_ACQUIRED_PARTIAL},
     * {@link FingerprintManager#FINGERPRINT_ACQUIRED_INSUFFICIENT},
     * {@link FingerprintManager#FINGERPRINT_ACQUIRED_IMAGER_DIRTY},
     * {@link FingerprintManager#FINGERPRINT_ACQUIRED_TOO_SLOW},
     * {@link FingerprintManager#FINGERPRINT_ACQUIRED_TOO_FAST}
     */
    public void onScanned(int fingerprintId, int confidence) { }
    public void onAcquired(int acquiredInfo) { }

    /**
     * Fingerprint has been detected and processed.  A non-zero return indicates a valid
     * fingerprint was detected.
     *
     * @param fingerprintId the finger id, or 0 if not recognized.
     */
    public void onProcessed(int fingerprintId) { }

    /**
     * An error was detected during scan or enrollment.  One of
     * {@link FingerprintManager#FINGERPRINT_ERROR_HW_UNAVAILABLE},
     * {@link FingerprintManager#FINGERPRINT_ERROR_BAD_CAPTURE} or
     * {@link FingerprintManager#FINGERPRINT_ERROR_UNABLE_TO_PROCESS} or
     * {@link FingerprintManager#FINGERPRINT_ERROR_TIMEOUT}
     * {@link FingerprintManager#FINGERPRINT_ERROR_NO_SPACE}
     *
+12 −7
Original line number Diff line number Diff line
@@ -18,10 +18,12 @@ package android.service.fingerprint;

import android.content.ContentResolver;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;

import java.util.Arrays;

public
class FingerprintUtils {
    private static final boolean DEBUG = true;
    private static final String TAG = "FingerprintUtils";
@@ -30,8 +32,10 @@ class FingerprintUtils {
        String fingerIdsRaw = Settings.Secure.getStringForUser(res,
                Settings.Secure.USER_FINGERPRINT_IDS, userId);

        int result[] = {};
        if (!TextUtils.isEmpty(fingerIdsRaw)) {
            String[] fingerStringIds = fingerIdsRaw.replace("[","").replace("]","").split(", ");
        int result[] = new int[fingerStringIds.length];
            result = new int[fingerStringIds.length];
            for (int i = 0; i < result.length; i++) {
                try {
                    result[i] = Integer.decode(fingerStringIds[i]);
@@ -39,6 +43,7 @@ class FingerprintUtils {
                    if (DEBUG) Log.d(TAG, "Error when parsing finger id " + fingerStringIds[i]);
                }
            }
        }
        return result;
    }

Loading