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

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

Add fingerprint settings support to the framework

- cleanup thread issue and simplify native FingerprintService methods
- add new permissions and enforce them
- add fingerprint hardware detection API

Change-Id: I87c2243ea2412061f1e85b044138480d0161bcdf
parent 07a65f44
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -141,6 +141,7 @@ package android {
    field public static final java.lang.String UNINSTALL_SHORTCUT = "com.android.launcher.permission.UNINSTALL_SHORTCUT";
    field public static final java.lang.String UPDATE_DEVICE_STATS = "android.permission.UPDATE_DEVICE_STATS";
    field public static final java.lang.String USE_CREDENTIALS = "android.permission.USE_CREDENTIALS";
    field public static final java.lang.String USE_FINGERPRINT = "android.permission.USE_FINGERPRINT";
    field public static final java.lang.String USE_SIP = "android.permission.USE_SIP";
    field public static final java.lang.String VIBRATE = "android.permission.VIBRATE";
    field public static final java.lang.String WAKE_LOCK = "android.permission.WAKE_LOCK";
+1 −0
Original line number Diff line number Diff line
@@ -210,6 +210,7 @@ package android {
    field public static final java.lang.String UPDATE_LOCK = "android.permission.UPDATE_LOCK";
    field public static final java.lang.String USER_ACTIVITY = "android.permission.USER_ACTIVITY";
    field public static final java.lang.String USE_CREDENTIALS = "android.permission.USE_CREDENTIALS";
    field public static final java.lang.String USE_FINGERPRINT = "android.permission.USE_FINGERPRINT";
    field public static final java.lang.String USE_SIP = "android.permission.USE_SIP";
    field public static final java.lang.String VIBRATE = "android.permission.VIBRATE";
    field public static final java.lang.String WAKE_LOCK = "android.permission.WAKE_LOCK";
+47 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.BaseBundle;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
@@ -31,6 +32,9 @@ import android.provider.Settings;
import android.util.Log;
import android.util.Slog;

import java.util.ArrayList;
import java.util.List;

/**
 * A class that coordinates access to the fingerprint hardware.
 * @hide
@@ -97,6 +101,15 @@ public class FingerprintManager {
        }
    };

    public static final class FingerprintItem {
        CharSequence name;
        int id;
        FingerprintItem(CharSequence name, int id) {
            this.name = name;
            this.id = id;
        }
    }

    /**
     * @hide
     */
@@ -248,4 +261,38 @@ public class FingerprintManager {
    private void sendError(int msg, int arg1, int arg2) {
        mHandler.obtainMessage(msg, arg1, arg2);
    }

    /**
     * @return list of current fingerprint items
     * @hide
     */
    public List<FingerprintItem> getEnrolledFingerprints() {
        int[] ids = FingerprintUtils.getFingerprintIdsForUser(mContext.getContentResolver(),
                getCurrentUserId());
        List<FingerprintItem> result = new ArrayList<FingerprintItem>();
        for (int i = 0; i < ids.length; i++) {
            // TODO: persist names in Settings
            FingerprintItem item = new FingerprintItem("Finger" + ids[i], ids[i]);
            result.add(item);
        }
        return result;
    }

    /**
     * Determine if fingerprint hardware is present and functional.
     * @return true if hardware is present and functional, false otherwise.
     * @hide
     */
    public boolean isHardwareDetected() {
        if (mService != null) {
            try {
                return mService.isHardwareDetected();
            } catch (RemoteException e) {
                Log.v(TAG, "Remote exception in isFingerprintHardwareDetected(): ", e);
            }
        } else {
            Log.w(TAG, "isFingerprintHardwareDetected(): Service not connected!");
        }
        return false;
    }
}
 No newline at end of file
+37 −23
Original line number Diff line number Diff line
@@ -21,7 +21,11 @@ import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;

import com.android.internal.util.ArrayUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Utility class for dealing with fingerprints and fingerprint settings.
@@ -32,34 +36,50 @@ class FingerprintUtils {
    private static final boolean DEBUG = true;
    private static final String TAG = "FingerprintUtils";

    private static int[] toIntArray(List<Integer> list) {
        if (list == null) {
            return null;
        }
        int[] arr = new int[list.size()];
        int i = 0;
        for (int elem : list) {
            arr[i] = elem;
            i++;
        }
        return arr;
    }

    public static int[] getFingerprintIdsForUser(ContentResolver res, int userId) {
        String fingerIdsRaw = Settings.Secure.getStringForUser(res,
                Settings.Secure.USER_FINGERPRINT_IDS, userId);

        int result[] = {};
        ArrayList<Integer> tmp = new ArrayList<Integer>();
        if (!TextUtils.isEmpty(fingerIdsRaw)) {
            String[] fingerStringIds = fingerIdsRaw.replace("[","").replace("]","").split(", ");
            result = new int[fingerStringIds.length];
            for (int i = 0; i < result.length; i++) {
            int length = fingerStringIds.length;
            for (int i = 0; i < length; i++) {
                try {
                    result[i] = Integer.decode(fingerStringIds[i]);
                    tmp.add(Integer.decode(fingerStringIds[i]));
                } catch (NumberFormatException e) {
                    if (DEBUG) Log.d(TAG, "Error when parsing finger id " + fingerStringIds[i]);
                    if (DEBUG) Log.w(TAG, "Error parsing finger id: '" + fingerStringIds[i] + "'");
                }
            }
        }
        return result;
        return toIntArray(tmp);
    }

    public static void addFingerprintIdForUser(int fingerId, ContentResolver res, int userId) {
        int[] fingerIds = getFingerprintIdsForUser(res, userId);

        // FingerId 0 has special meaning.
        if (fingerId == 0) return;
        if (fingerId == 0) {
            Log.w(TAG, "Tried to add fingerId 0");
            return;
        }

        int[] fingerIds = getFingerprintIdsForUser(res, userId);

        // Don't allow dups
        for (int i = 0; i < fingerIds.length; i++) {
            if (fingerIds[i] == fingerId) return;
        if (ArrayUtils.contains(fingerIds, fingerId)) {
            Log.w(TAG, "finger already added " + fingerId);
            return;
        }
        int[] newList = Arrays.copyOf(fingerIds, fingerIds.length + 1);
        newList[fingerIds.length] = fingerId;
@@ -72,19 +92,13 @@ class FingerprintUtils {
        // FingerId 0 has special meaning. The HAL layer is supposed to remove each finger one
        // at a time and invoke notify() for each fingerId.  If we get called with 0 here, it means
        // something bad has happened.
        if (fingerId == 0) throw new IllegalStateException("Bad fingerId");
        if (fingerId == 0) throw new IllegalArgumentException("fingerId can't be 0");

        int[] fingerIds = getFingerprintIdsForUser(res, userId);
        int[] resultIds = Arrays.copyOf(fingerIds, fingerIds.length);
        int resultCount = 0;
        for (int i = 0; i < fingerIds.length; i++) {
            if (fingerId != fingerIds[i]) {
                resultIds[resultCount++] = fingerIds[i];
            }
        }
        if (resultCount > 0) {
        final int[] fingerIds = getFingerprintIdsForUser(res, userId);
        if (ArrayUtils.contains(fingerIds, fingerId)) {
            final int[] result = ArrayUtils.removeInt(fingerIds, fingerId);
            Settings.Secure.putStringForUser(res, Settings.Secure.USER_FINGERPRINT_IDS,
                    Arrays.toString(Arrays.copyOf(resultIds, resultCount)), userId);
                    Arrays.toString(result), userId);
            return true;
        }
        return false;
+5 −2
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ import android.service.fingerprint.IFingerprintServiceReceiver;
 * Communication channel from client to the fingerprint service.
 * @hide
 */
oneway interface IFingerprintService {
interface IFingerprintService {
    // Any errors resulting from this call will be returned to the listener
    void enroll(IBinder token, long timeout, int userId);

@@ -38,4 +38,7 @@ oneway interface IFingerprintService {

    // Stops listening for fingerprints
    void stopListening(IBinder token, int userId);

    // Determine if HAL is loaded and ready
    boolean isHardwareDetected();
}
Loading