From 40e4645e6e564b962bb73c85c5325ec54ad34cc1 Mon Sep 17 00:00:00 2001 From: Jim Miller Date: Fri, 16 Dec 2016 18:38:53 -0800 Subject: [PATCH] Rewrite FingerprintService to use HIDL 2.1 Bug: 33199080 Test: Fingerprint enroll, remove, unlock, fingerprint arbitration. Change-Id: I8b98236ba81f053527ee74c8a189af1adfd17d55 --- Android.mk | 2 - .../fingerprint/FingerprintManager.java | 148 ++++++++++---- .../fingerprint/IFingerprintDaemon.aidl | 40 ---- .../IFingerprintDaemonCallback.aidl | 29 --- .../fingerprint/IFingerprintService.aidl | 3 + .../IFingerprintServiceReceiver.aidl | 7 +- services/Android.mk | 4 +- services/core/Android.mk | 4 +- .../fingerprint/AuthenticationClient.java | 19 +- .../server/fingerprint/ClientMonitor.java | 20 +- .../server/fingerprint/EnrollClient.java | 16 +- .../server/fingerprint/EnumerateClient.java | 43 +++-- .../fingerprint/FingerprintService.java | 180 +++++++++++------- .../server/fingerprint/RemovalClient.java | 23 +-- 14 files changed, 306 insertions(+), 232 deletions(-) delete mode 100644 core/java/android/hardware/fingerprint/IFingerprintDaemon.aidl delete mode 100644 core/java/android/hardware/fingerprint/IFingerprintDaemonCallback.aidl diff --git a/Android.mk b/Android.mk index 8e8b95a3e8aa5..21bd76b76a62f 100644 --- a/Android.mk +++ b/Android.mk @@ -178,8 +178,6 @@ LOCAL_SRC_FILES += \ core/java/android/hardware/display/IDisplayManager.aidl \ core/java/android/hardware/display/IDisplayManagerCallback.aidl \ core/java/android/hardware/display/IVirtualDisplayCallback.aidl \ - core/java/android/hardware/fingerprint/IFingerprintDaemon.aidl \ - core/java/android/hardware/fingerprint/IFingerprintDaemonCallback.aidl \ core/java/android/hardware/fingerprint/IFingerprintService.aidl \ core/java/android/hardware/fingerprint/IFingerprintServiceLockoutResetCallback.aidl \ core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl \ diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java index aa109de752e35..4b5707890518e 100644 --- a/core/java/android/hardware/fingerprint/FingerprintManager.java +++ b/core/java/android/hardware/fingerprint/FingerprintManager.java @@ -62,6 +62,7 @@ public class FingerprintManager { private static final int MSG_AUTHENTICATION_FAILED = 103; private static final int MSG_ERROR = 104; private static final int MSG_REMOVED = 105; + private static final int MSG_ENUMERATED = 106; // // Error messages from fingerprint hardware during initilization, enrollment, authentication or @@ -116,6 +117,10 @@ public class FingerprintManager { * the above categories. Vendors are responsible for providing error strings for these errors. * @hide */ + public static final int FINGERPRINT_ERROR_VENDOR = 8; + /** + * @hide + */ public static final int FINGERPRINT_ERROR_VENDOR_BASE = 1000; // @@ -167,6 +172,10 @@ public class FingerprintManager { * the above categories. Vendors are responsible for providing error strings for these errors. * @hide */ + public static final int FINGERPRINT_ACQUIRED_VENDOR = 6; + /** + * @hide + */ public static final int FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000; private IFingerprintService mService; @@ -175,6 +184,7 @@ public class FingerprintManager { private AuthenticationCallback mAuthenticationCallback; private EnrollmentCallback mEnrollmentCallback; private RemovalCallback mRemovalCallback; + private EnumerateCallback mEnumerateCallback; private CryptoObject mCryptoObject; private Fingerprint mRemovalFingerprint; private Handler mHandler; @@ -402,6 +412,29 @@ public class FingerprintManager { public void onRemovalSucceeded(Fingerprint fingerprint) { } }; + /** + * Callback structure provided to {@link FingerprintManager#enumerate(int). Users of + * {@link #FingerprintManager()} may optionally provide an implementation of this to + * {@link FingerprintManager#enumerate(int, int, EnumerateCallback)} for listening to + * fingerprint template removal events. + * + * @hide + */ + public static abstract class EnumerateCallback { + /** + * Called when the given fingerprint can't be removed. + * @param errMsgId An associated error message id + * @param errString An error message indicating why the fingerprint id can't be removed + */ + public void onEnumerateError(int errMsgId, CharSequence errString) { } + + /** + * Called when a given fingerprint is successfully removed. + * @param fingerprint the fingerprint template that was removed. + */ + public void onEnumerate(Fingerprint fingerprint) { } + }; + /** * @hide */ @@ -484,7 +517,7 @@ public class FingerprintManager { // Though this may not be a hardware issue, it will cause apps to give up or try // again later. callback.onAuthenticationError(FINGERPRINT_ERROR_HW_UNAVAILABLE, - getErrorString(FINGERPRINT_ERROR_HW_UNAVAILABLE)); + getErrorString(FINGERPRINT_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */)); } } } @@ -534,7 +567,7 @@ public class FingerprintManager { // Though this may not be a hardware issue, it will cause apps to give up or try // again later. callback.onEnrollmentError(FINGERPRINT_ERROR_HW_UNAVAILABLE, - getErrorString(FINGERPRINT_ERROR_HW_UNAVAILABLE)); + getErrorString(FINGERPRINT_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */)); } } } @@ -604,7 +637,29 @@ public class FingerprintManager { Log.w(TAG, "Remote exception in remove: ", e); if (callback != null) { callback.onRemovalError(fp, FINGERPRINT_ERROR_HW_UNAVAILABLE, - getErrorString(FINGERPRINT_ERROR_HW_UNAVAILABLE)); + getErrorString(FINGERPRINT_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */)); + } + } + } + + /** + * Enumerate all fingerprint templates stored in hardware and/or protected storage. + * @param userId the user who this fingerprint belongs to + * @param callback an optional callback to verify that fingerprint templates have been + * successfully removed. May be null of no callback is required. + * + * @hide + */ + @RequiresPermission(MANAGE_FINGERPRINT) + public void enumerate(int userId, @NonNull EnumerateCallback callback) { + if (mService != null) try { + mEnumerateCallback = callback; + mService.enumerate(mToken, userId, mServiceReceiver); + } catch (RemoteException e) { + Log.w(TAG, "Remote exception in enumerate: ", e); + if (callback != null) { + callback.onEnumerateError(FINGERPRINT_ERROR_HW_UNAVAILABLE, + getErrorString(FINGERPRINT_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */)); } } } @@ -800,7 +855,8 @@ public class FingerprintManager { sendEnrollResult((Fingerprint) msg.obj, msg.arg1 /* remaining */); break; case MSG_ACQUIRED: - sendAcquiredResult((Long) msg.obj /* deviceId */, msg.arg1 /* acquire info */); + sendAcquiredResult((Long) msg.obj /* deviceId */, msg.arg1 /* acquire info */, + msg.arg2 /* vendorCode */); break; case MSG_AUTHENTICATION_SUCCEEDED: sendAuthenticatedSucceeded((Fingerprint) msg.obj, msg.arg1 /* userId */); @@ -809,11 +865,15 @@ public class FingerprintManager { sendAuthenticatedFailed(); break; case MSG_ERROR: - sendErrorResult((Long) msg.obj /* deviceId */, msg.arg1 /* errMsgId */); + sendErrorResult((Long) msg.obj /* deviceId */, msg.arg1 /* errMsgId */, + msg.arg2 /* vendorCode */); break; case MSG_REMOVED: sendRemovedResult((Long) msg.obj /* deviceId */, msg.arg1 /* fingerId */, msg.arg2 /* groupId */); + case MSG_ENUMERATED: + sendEnumeratedResult((Long) msg.obj /* deviceId */, msg.arg1 /* fingerId */, + msg.arg2 /* groupId */); } } @@ -834,14 +894,28 @@ public class FingerprintManager { } } - private void sendErrorResult(long deviceId, int errMsgId) { + private void sendEnumeratedResult(long deviceId, int fingerId, int groupId) { + if (mEnumerateCallback != null) { + mEnumerateCallback.onEnumerate(new Fingerprint(null, groupId, fingerId, deviceId)); + } + } + + private void sendErrorResult(long deviceId, int errMsgId, int vendorCode) { + // emulate HAL 2.1 behavior and send real errMsgId + final int clientErrMsgId = errMsgId == FINGERPRINT_ERROR_VENDOR + ? (vendorCode + FINGERPRINT_ERROR_VENDOR_BASE) : errMsgId; if (mEnrollmentCallback != null) { - mEnrollmentCallback.onEnrollmentError(errMsgId, getErrorString(errMsgId)); + mEnrollmentCallback.onEnrollmentError(clientErrMsgId, + getErrorString(errMsgId, vendorCode)); } else if (mAuthenticationCallback != null) { - mAuthenticationCallback.onAuthenticationError(errMsgId, getErrorString(errMsgId)); + mAuthenticationCallback.onAuthenticationError(clientErrMsgId, + getErrorString(errMsgId, vendorCode)); } else if (mRemovalCallback != null) { - mRemovalCallback.onRemovalError(mRemovalFingerprint, errMsgId, - getErrorString(errMsgId)); + mRemovalCallback.onRemovalError(mRemovalFingerprint, clientErrMsgId, + getErrorString(errMsgId, vendorCode)); + } else if (mEnumerateCallback != null) { + mEnumerateCallback.onEnumerateError(clientErrMsgId, + getErrorString(errMsgId, vendorCode)); } } @@ -865,18 +939,21 @@ public class FingerprintManager { } } - private void sendAcquiredResult(long deviceId, int acquireInfo) { + private void sendAcquiredResult(long deviceId, int acquireInfo, int vendorCode) { if (mAuthenticationCallback != null) { mAuthenticationCallback.onAuthenticationAcquired(acquireInfo); } - final String msg = getAcquiredString(acquireInfo); + final String msg = getAcquiredString(acquireInfo, vendorCode); if (msg == null) { return; } + // emulate HAL 2.1 behavior and send real acquiredInfo + final int clientInfo = acquireInfo == FINGERPRINT_ACQUIRED_VENDOR + ? (vendorCode + FINGERPRINT_ACQUIRED_VENDOR_BASE) : acquireInfo; if (mEnrollmentCallback != null) { - mEnrollmentCallback.onEnrollmentHelp(acquireInfo, msg); + mEnrollmentCallback.onEnrollmentHelp(clientInfo, msg); } else if (mAuthenticationCallback != null) { - mAuthenticationCallback.onAuthenticationHelp(acquireInfo, msg); + mAuthenticationCallback.onAuthenticationHelp(clientInfo, msg); } } }; @@ -917,7 +994,7 @@ public class FingerprintManager { } } - private String getErrorString(int errMsg) { + private String getErrorString(int errMsg, int vendorCode) { switch (errMsg) { case FINGERPRINT_ERROR_UNABLE_TO_PROCESS: return mContext.getString( @@ -934,20 +1011,19 @@ public class FingerprintManager { return mContext.getString(com.android.internal.R.string.fingerprint_error_canceled); case FINGERPRINT_ERROR_LOCKOUT: return mContext.getString(com.android.internal.R.string.fingerprint_error_lockout); - default: - if (errMsg >= FINGERPRINT_ERROR_VENDOR_BASE) { - int msgNumber = errMsg - FINGERPRINT_ERROR_VENDOR_BASE; + case FINGERPRINT_ERROR_VENDOR: { String[] msgArray = mContext.getResources().getStringArray( com.android.internal.R.array.fingerprint_error_vendor); - if (msgNumber < msgArray.length) { - return msgArray[msgNumber]; + if (vendorCode < msgArray.length) { + return msgArray[vendorCode]; } } - return null; } + Slog.w(TAG, "Invalid error message: " + errMsg + ", " + vendorCode); + return null; } - private String getAcquiredString(int acquireInfo) { + private String getAcquiredString(int acquireInfo, int vendorCode) { switch (acquireInfo) { case FINGERPRINT_ACQUIRED_GOOD: return null; @@ -966,17 +1042,16 @@ public class FingerprintManager { case FINGERPRINT_ACQUIRED_TOO_FAST: return mContext.getString( com.android.internal.R.string.fingerprint_acquired_too_fast); - default: - if (acquireInfo >= FINGERPRINT_ACQUIRED_VENDOR_BASE) { - int msgNumber = acquireInfo - FINGERPRINT_ACQUIRED_VENDOR_BASE; + case FINGERPRINT_ACQUIRED_VENDOR: { String[] msgArray = mContext.getResources().getStringArray( com.android.internal.R.array.fingerprint_acquired_vendor); - if (msgNumber < msgArray.length) { - return msgArray[msgNumber]; + if (vendorCode < msgArray.length) { + return msgArray[vendorCode]; } } - return null; } + Slog.w(TAG, "Invalid acquired message: " + acquireInfo + ", " + vendorCode); + return null; } private IFingerprintServiceReceiver mServiceReceiver = new IFingerprintServiceReceiver.Stub() { @@ -988,8 +1063,8 @@ public class FingerprintManager { } @Override // binder call - public void onAcquired(long deviceId, int acquireInfo) { - mHandler.obtainMessage(MSG_ACQUIRED, acquireInfo, 0, deviceId).sendToTarget(); + public void onAcquired(long deviceId, int acquireInfo, int vendorCode) { + mHandler.obtainMessage(MSG_ACQUIRED, acquireInfo, vendorCode, deviceId).sendToTarget(); } @Override // binder call @@ -1003,14 +1078,21 @@ public class FingerprintManager { } @Override // binder call - public void onError(long deviceId, int error) { - mHandler.obtainMessage(MSG_ERROR, error, 0, deviceId).sendToTarget(); + public void onError(long deviceId, int error, int vendorCode) { + mHandler.obtainMessage(MSG_ERROR, error, vendorCode, deviceId).sendToTarget(); } @Override // binder call - public void onRemoved(long deviceId, int fingerId, int groupId) { + public void onRemoved(long deviceId, int fingerId, int groupId, int remaining) { + // TODO: propagate remaining mHandler.obtainMessage(MSG_REMOVED, fingerId, groupId, deviceId).sendToTarget(); } + + @Override // binder call + public void onEnumerated(long deviceId, int fingerId, int groupId, int remaining) { + // TODO: propagate remaining + mHandler.obtainMessage(MSG_ENUMERATED, fingerId, groupId, deviceId).sendToTarget(); + } }; } diff --git a/core/java/android/hardware/fingerprint/IFingerprintDaemon.aidl b/core/java/android/hardware/fingerprint/IFingerprintDaemon.aidl deleted file mode 100644 index f40f8a3fdbf26..0000000000000 --- a/core/java/android/hardware/fingerprint/IFingerprintDaemon.aidl +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.hardware.fingerprint; - -import android.hardware.fingerprint.IFingerprintDaemonCallback; - -/** - * Communication channel from FingerprintService to FingerprintDaemon (fingerprintd) - * @hide - */ - -interface IFingerprintDaemon { - int authenticate(long sessionId, int groupId); - int cancelAuthentication(); - int enroll(in byte [] token, int groupId, int timeout); - int cancelEnrollment(); - long preEnroll(); - int remove(int fingerId, int groupId); - long getAuthenticatorId(); - int setActiveGroup(int groupId, in byte[] path); - long openHal(); - int closeHal(); - void init(IFingerprintDaemonCallback callback); - int postEnroll(); - int enumerate(); - int cancelEnumeration(); -} diff --git a/core/java/android/hardware/fingerprint/IFingerprintDaemonCallback.aidl b/core/java/android/hardware/fingerprint/IFingerprintDaemonCallback.aidl deleted file mode 100644 index bd8ad6e50172c..0000000000000 --- a/core/java/android/hardware/fingerprint/IFingerprintDaemonCallback.aidl +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.hardware.fingerprint; - -/** - * Communication channel from the fingerprintd back to FingerprintService. - * @hide - */ - interface IFingerprintDaemonCallback { - void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining); - void onAcquired(long deviceId, int acquiredInfo); - void onAuthenticated(long deviceId, int fingerId, int groupId); - void onError(long deviceId, int error); - void onRemoved(long deviceId, int fingerId, int groupId); - void onEnumerate(long deviceId, in int [] fingerIds, in int [] groupIds); -} diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl index a83397a177341..ae3fc374c9a51 100644 --- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl +++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl @@ -79,4 +79,7 @@ interface IFingerprintService { // Explicitly set the active user (for enrolling work profile) void setActiveUser(int uid); + + // Enumerate all fingerprints + void enumerate(IBinder token, int userId, IFingerprintServiceReceiver receiver); } diff --git a/core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl b/core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl index b024b29fef06b..370383f4a909a 100644 --- a/core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl +++ b/core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl @@ -25,9 +25,10 @@ import android.os.UserHandle; */ oneway interface IFingerprintServiceReceiver { void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining); - void onAcquired(long deviceId, int acquiredInfo); + void onAcquired(long deviceId, int acquiredInfo, int vendorCode); void onAuthenticationSucceeded(long deviceId, in Fingerprint fp, int userId); void onAuthenticationFailed(long deviceId); - void onError(long deviceId, int error); - void onRemoved(long deviceId, int fingerId, int groupId); + void onError(long deviceId, int error, int vendorCode); + void onRemoved(long deviceId, int fingerId, int groupId, int remaining); + void onEnumerated(long deviceId, int fingerId, int groupId, int remaining); } diff --git a/services/Android.mk b/services/Android.mk index 0d57efe27833a..abd1459dc65e4 100644 --- a/services/Android.mk +++ b/services/Android.mk @@ -36,7 +36,9 @@ services := \ voiceinteraction # The convention is to name each service module 'services.$(module_name)' -LOCAL_STATIC_JAVA_LIBRARIES := $(addprefix services.,$(services)) +LOCAL_STATIC_JAVA_LIBRARIES := $(addprefix services.,$(services)) \ + android.hidl.base@1.0-java \ + android.hardware.biometrics.fingerprint@2.1-java ifeq ($(EMMA_INSTRUMENT_FRAMEWORK),true) LOCAL_EMMA_INSTRUMENT := true diff --git a/services/core/Android.mk b/services/core/Android.mk index 1366b3b2d694b..07f14d4ff8a41 100644 --- a/services/core/Android.mk +++ b/services/core/Android.mk @@ -24,7 +24,9 @@ LOCAL_JAVA_LIBRARIES := \ android.hardware.power@1.0-java \ android.hardware.tv.cec@1.0-java -LOCAL_STATIC_JAVA_LIBRARIES := tzdata_update2 +LOCAL_STATIC_JAVA_LIBRARIES := tzdata_update2 \ + android.hidl.base@1.0-java \ + android.hardware.biometrics.fingerprint@2.1-java \ ifneq ($(INCREMENTAL_BUILDS),) LOCAL_PROGUARD_ENABLED := disabled diff --git a/services/core/java/com/android/server/fingerprint/AuthenticationClient.java b/services/core/java/com/android/server/fingerprint/AuthenticationClient.java index d65e25785e392..14f2e86170818 100644 --- a/services/core/java/com/android/server/fingerprint/AuthenticationClient.java +++ b/services/core/java/com/android/server/fingerprint/AuthenticationClient.java @@ -16,17 +16,16 @@ package com.android.server.fingerprint; +import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import android.content.Context; import android.hardware.fingerprint.Fingerprint; import android.hardware.fingerprint.FingerprintManager; -import android.hardware.fingerprint.IFingerprintDaemon; import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.os.IBinder; import android.os.RemoteException; -import android.system.ErrnoException; import android.util.Slog; /** @@ -85,7 +84,7 @@ public abstract class AuthenticationClient extends ClientMonitor { try { Slog.w(TAG, "Forcing lockout (fp driver code should do this!)"); receiver.onError(getHalDeviceId(), - FingerprintManager.FINGERPRINT_ERROR_LOCKOUT); + FingerprintManager.FINGERPRINT_ERROR_LOCKOUT, 0 /* vendorCode */); } catch (RemoteException e) { Slog.w(TAG, "Failed to notify lockout:", e); } @@ -106,7 +105,7 @@ public abstract class AuthenticationClient extends ClientMonitor { */ @Override public int start() { - IFingerprintDaemon daemon = getFingerprintDaemon(); + IBiometricsFingerprint daemon = getFingerprintDaemon(); if (daemon == null) { Slog.w(TAG, "start authentication: no fingeprintd!"); return ERROR_ESRCH; @@ -116,7 +115,7 @@ public abstract class AuthenticationClient extends ClientMonitor { if (result != 0) { Slog.w(TAG, "startAuthentication failed, result=" + result); MetricsLogger.histogram(getContext(), "fingeprintd_auth_start_error", result); - onError(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE); + onError(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */); return result; } if (DEBUG) Slog.w(TAG, "client " + getOwnerString() + " is authenticating..."); @@ -129,13 +128,13 @@ public abstract class AuthenticationClient extends ClientMonitor { @Override public int stop(boolean initiatedByClient) { - IFingerprintDaemon daemon = getFingerprintDaemon(); + IBiometricsFingerprint daemon = getFingerprintDaemon(); if (daemon == null) { Slog.w(TAG, "stopAuthentication: no fingeprintd!"); return ERROR_ESRCH; } try { - final int result = daemon.cancelAuthentication(); + final int result = daemon.cancel(); if (result != 0) { Slog.w(TAG, "stopAuthentication failed, result=" + result); return result; @@ -149,19 +148,19 @@ public abstract class AuthenticationClient extends ClientMonitor { } @Override - public boolean onEnrollResult(int fingerId, int groupId, int rem) { + public boolean onEnrollResult(int fingerId, int groupId, int remaining) { if (DEBUG) Slog.w(TAG, "onEnrollResult() called for authenticate!"); return true; // Invalid for Authenticate } @Override - public boolean onRemoved(int fingerId, int groupId) { + public boolean onRemoved(int fingerId, int groupId, int remaining) { if (DEBUG) Slog.w(TAG, "onRemoved() called for authenticate!"); return true; // Invalid for Authenticate } @Override - public boolean onEnumerationResult(int fingerId, int groupId) { + public boolean onEnumerationResult(int fingerId, int groupId, int remaining) { if (DEBUG) Slog.w(TAG, "onEnumerationResult() called for authenticate!"); return true; // Invalid for Authenticate } diff --git a/services/core/java/com/android/server/fingerprint/ClientMonitor.java b/services/core/java/com/android/server/fingerprint/ClientMonitor.java index 8163b79df73d0..5a1e44574e134 100644 --- a/services/core/java/com/android/server/fingerprint/ClientMonitor.java +++ b/services/core/java/com/android/server/fingerprint/ClientMonitor.java @@ -18,8 +18,8 @@ package com.android.server.fingerprint; import android.Manifest; import android.content.Context; +import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint; import android.hardware.fingerprint.FingerprintManager; -import android.hardware.fingerprint.IFingerprintDaemon; import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.os.IBinder; import android.os.RemoteException; @@ -94,7 +94,7 @@ public abstract class ClientMonitor implements IBinder.DeathRecipient { /** * Gets the fingerprint daemon from the cached state in the container class. */ - public abstract IFingerprintDaemon getFingerprintDaemon(); + public abstract IBiometricsFingerprint getFingerprintDaemon(); // Event callbacks from driver. Inappropriate calls is flagged/logged by the // respective client (e.g. enrolling shouldn't get authenticate events). @@ -102,8 +102,8 @@ public abstract class ClientMonitor implements IBinder.DeathRecipient { // to the next client (e.g. authentication accepts or rejects a fingerprint). public abstract boolean onEnrollResult(int fingerId, int groupId, int rem); public abstract boolean onAuthenticated(int fingerId, int groupId); - public abstract boolean onRemoved(int fingerId, int groupId); - public abstract boolean onEnumerationResult(int fingerId, int groupId); + public abstract boolean onRemoved(int fingerId, int groupId, int remaining); + public abstract boolean onEnumerationResult(int fingerId, int groupId, int remaining); /** * Called when we get notification from fingerprintd that an image has been acquired. @@ -111,11 +111,11 @@ public abstract class ClientMonitor implements IBinder.DeathRecipient { * @param acquiredInfo info about the current image acquisition * @return true if client should be removed */ - public boolean onAcquired(int acquiredInfo) { + public boolean onAcquired(int acquiredInfo, int vendorCode) { if (mReceiver == null) return true; // client not connected try { - mReceiver.onAcquired(getHalDeviceId(), acquiredInfo); + mReceiver.onAcquired(getHalDeviceId(), acquiredInfo, vendorCode); return false; // acquisition continues... } catch (RemoteException e) { Slog.w(TAG, "Failed to invoke sendAcquired:", e); @@ -134,10 +134,10 @@ public abstract class ClientMonitor implements IBinder.DeathRecipient { * @param error * @return true if client should be removed */ - public boolean onError(int error) { + public boolean onError(int error, int vendorCode) { if (mReceiver != null) { try { - mReceiver.onError(getHalDeviceId(), error); + mReceiver.onError(getHalDeviceId(), error, vendorCode); } catch (RemoteException e) { Slog.w(TAG, "Failed to invoke sendError:", e); } @@ -162,7 +162,7 @@ public abstract class ClientMonitor implements IBinder.DeathRecipient { public void binderDied() { mToken = null; mReceiver = null; - onError(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE); + onError(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */); } @Override @@ -170,7 +170,7 @@ public abstract class ClientMonitor implements IBinder.DeathRecipient { try { if (mToken != null) { if (DEBUG) Slog.w(TAG, "removing leaked reference: " + mToken); - onError(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE); + onError(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */); } } finally { super.finalize(); diff --git a/services/core/java/com/android/server/fingerprint/EnrollClient.java b/services/core/java/com/android/server/fingerprint/EnrollClient.java index c70ca7f5b28b5..eddcd5b898656 100644 --- a/services/core/java/com/android/server/fingerprint/EnrollClient.java +++ b/services/core/java/com/android/server/fingerprint/EnrollClient.java @@ -17,8 +17,8 @@ package com.android.server.fingerprint; import android.content.Context; +import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint; import android.hardware.fingerprint.FingerprintManager; -import android.hardware.fingerprint.IFingerprintDaemon; import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.os.IBinder; import android.os.RemoteException; @@ -78,7 +78,7 @@ public abstract class EnrollClient extends ClientMonitor { @Override public int start() { - IFingerprintDaemon daemon = getFingerprintDaemon(); + IBiometricsFingerprint daemon = getFingerprintDaemon(); if (daemon == null) { Slog.w(TAG, "enroll: no fingeprintd!"); return ERROR_ESRCH; @@ -89,7 +89,7 @@ public abstract class EnrollClient extends ClientMonitor { if (result != 0) { Slog.w(TAG, "startEnroll failed, result=" + result); MetricsLogger.histogram(getContext(), "fingerprintd_enroll_start_error", result); - onError(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE); + onError(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */); return result; } } catch (RemoteException e) { @@ -100,13 +100,13 @@ public abstract class EnrollClient extends ClientMonitor { @Override public int stop(boolean initiatedByClient) { - IFingerprintDaemon daemon = getFingerprintDaemon(); + IBiometricsFingerprint daemon = getFingerprintDaemon(); if (daemon == null) { Slog.w(TAG, "stopEnrollment: no fingeprintd!"); return ERROR_ESRCH; } try { - final int result = daemon.cancelEnrollment(); + final int result = daemon.cancel(); if (result != 0) { Slog.w(TAG, "startEnrollCancel failed, result = " + result); return result; @@ -115,19 +115,19 @@ public abstract class EnrollClient extends ClientMonitor { Slog.e(TAG, "stopEnrollment failed", e); } if (initiatedByClient) { - onError(FingerprintManager.FINGERPRINT_ERROR_CANCELED); + onError(FingerprintManager.FINGERPRINT_ERROR_CANCELED, 0 /* vendorCode */); } return 0; } @Override - public boolean onRemoved(int fingerId, int groupId) { + public boolean onRemoved(int fingerId, int groupId, int remaining) { if (DEBUG) Slog.w(TAG, "onRemoved() called for enroll!"); return true; // Invalid for EnrollClient } @Override - public boolean onEnumerationResult(int fingerId, int groupId) { + public boolean onEnumerationResult(int fingerId, int groupId, int remaining) { if (DEBUG) Slog.w(TAG, "onEnumerationResult() called for enroll!"); return true; // Invalid for EnrollClient } diff --git a/services/core/java/com/android/server/fingerprint/EnumerateClient.java b/services/core/java/com/android/server/fingerprint/EnumerateClient.java index 26b191646ddb3..55bf689bd3c64 100644 --- a/services/core/java/com/android/server/fingerprint/EnumerateClient.java +++ b/services/core/java/com/android/server/fingerprint/EnumerateClient.java @@ -17,8 +17,8 @@ package com.android.server.fingerprint; import android.content.Context; +import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint; import android.hardware.fingerprint.FingerprintManager; -import android.hardware.fingerprint.IFingerprintDaemon; import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.os.IBinder; import android.os.RemoteException; @@ -30,14 +30,14 @@ import com.android.internal.logging.MetricsLogger; */ public abstract class EnumerateClient extends ClientMonitor { public EnumerateClient(Context context, long halDeviceId, IBinder token, - IFingerprintServiceReceiver receiver, int userId, int groupId, - boolean restricted, String owner) { + IFingerprintServiceReceiver receiver, int groupId, int userId, + boolean restricted, String owner) { super(context, halDeviceId, token, receiver, userId, groupId, restricted, owner); } @Override public int start() { - IFingerprintDaemon daemon = getFingerprintDaemon(); + IBiometricsFingerprint daemon = getFingerprintDaemon(); // The fingerprint template ids will be removed when we get confirmation from the HAL try { final int result = daemon.enumerate(); @@ -45,50 +45,69 @@ public abstract class EnumerateClient extends ClientMonitor { Slog.w(TAG, "start enumerate for user " + getTargetUserId() + " failed, result=" + result); MetricsLogger.histogram(getContext(), "fingerprintd_enum_start_error", result); - onError(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE); + onError(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */); return result; } } catch (RemoteException e) { - Slog.e(TAG, "startRemove failed", e); + Slog.e(TAG, "startEnumeration failed", e); } return 0; } @Override public int stop(boolean initiatedByClient) { - IFingerprintDaemon daemon = getFingerprintDaemon(); + IBiometricsFingerprint daemon = getFingerprintDaemon(); if (daemon == null) { Slog.w(TAG, "stopAuthentication: no fingeprintd!"); return ERROR_ESRCH; } try { - final int result = daemon.cancelEnumeration(); + final int result = daemon.cancel(); if (result != 0) { Slog.w(TAG, "stop enumeration failed, result=" + result); return result; } } catch (RemoteException e) { - Slog.e(TAG, "stop enumeration failed", e); + Slog.e(TAG, "stopEnumeration failed", e); return ERROR_ESRCH; } + // We don't actually stop enumerate, but inform the client that the cancel operation // succeeded so we can start the next operation. if (initiatedByClient) { - onError(FingerprintManager.FINGERPRINT_ERROR_CANCELED); + onError(FingerprintManager.FINGERPRINT_ERROR_CANCELED, 0 /* vendorCode */); } return 0; // success } @Override - public boolean onEnumerationResult(int fingerId, int groupId) { + public boolean onEnumerationResult(int fingerId, int groupId, int remaining) { IFingerprintServiceReceiver receiver = getReceiver(); if (receiver == null) return true; // client not listening try { - receiver.onRemoved(getHalDeviceId(), fingerId, groupId); + receiver.onEnumerated(getHalDeviceId(), fingerId, groupId, remaining); } catch (RemoteException e) { Slog.w(TAG, "Failed to notify enumerated:", e); } return fingerId == 0; // done when id hits 0 } + + @Override + public boolean onAuthenticated(int fingerId, int groupId) { + if (DEBUG) Slog.w(TAG, "onAuthenticated() called for enumerate!"); + return true; // Invalid for Enumerate. + } + + @Override + public boolean onEnrollResult(int fingerId, int groupId, int rem) { + if (DEBUG) Slog.w(TAG, "onEnrollResult() called for enumerate!"); + return true; // Invalid for Remove + } + + @Override + public boolean onRemoved(int fingerId, int groupId, int remaining) { + if (DEBUG) Slog.w(TAG, "onRemoved() called for enumerate!"); + return true; // Invalid for Authenticate + } } diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java index b0f67a81db280..997222ca876e9 100644 --- a/services/core/java/com/android/server/fingerprint/FingerprintService.java +++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java @@ -37,12 +37,12 @@ import android.os.DeadObjectException; import android.os.Environment; import android.os.Handler; import android.os.IBinder; +import android.os.IHwBinder; import android.os.IRemoteCallback; import android.os.PowerManager; import android.os.PowerManager.WakeLock; import android.os.RemoteException; import android.os.SELinux; -import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; @@ -61,11 +61,12 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint; +import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprintClientCallback; + import android.hardware.fingerprint.Fingerprint; import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.IFingerprintService; -import android.hardware.fingerprint.IFingerprintDaemon; -import android.hardware.fingerprint.IFingerprintDaemonCallback; import android.hardware.fingerprint.IFingerprintServiceReceiver; import static android.Manifest.permission.INTERACT_ACROSS_USERS; @@ -78,7 +79,6 @@ import java.io.File; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -90,11 +90,11 @@ import java.util.List; * * @hide */ -public class FingerprintService extends SystemService implements IBinder.DeathRecipient { +public class FingerprintService extends SystemService implements IHwBinder.DeathRecipient { static final String TAG = "FingerprintService"; static final boolean DEBUG = true; private static final String FP_DATA_DIR = "fpdata"; - private static final String FINGERPRINTD = "android.hardware.fingerprint.IFingerprintDaemon"; + private static final String FINGERPRINT_HIDL = "fingerprint_hal"; private static final int MSG_USER_SWITCHING = 10; private static final String ACTION_LOCKOUT_RESET = "com.android.server.fingerprint.ACTION_LOCKOUT_RESET"; @@ -120,7 +120,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe private long mHalDeviceId; private int mFailedAttempts; @GuardedBy("this") - private IFingerprintDaemon mDaemon; + private IBiometricsFingerprint mDaemon; private final PowerManager mPowerManager; private final AlarmManager mAlarmManager; private final UserManager mUserManager; @@ -130,12 +130,10 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe private PerformanceStats mPerformanceStats; // Normal fingerprint authentications are tracked by mPerformanceMap. - private HashMap mPerformanceMap - = new HashMap(); + private HashMap mPerformanceMap = new HashMap<>(); // Transactions that make use of CryptoObjects are tracked by mCryptoPerformaceMap. - private HashMap mCryptoPerformanceMap - = new HashMap(); + private HashMap mCryptoPerformanceMap = new HashMap<>(); private Handler mHandler = new Handler() { @Override @@ -201,59 +199,61 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe } @Override - public void binderDied() { + public void serviceDied(long cookie) { Slog.v(TAG, "fingerprintd died"); MetricsLogger.count(mContext, "fingerprintd_died", 1); synchronized (this) { mDaemon = null; } mCurrentUserId = UserHandle.USER_CURRENT; - handleError(mHalDeviceId, FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE); + handleError(mHalDeviceId, FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE, + 0 /*vendorCode */); } - public IFingerprintDaemon getFingerprintDaemon() { - synchronized (this) { - if (mDaemon == null) { - mDaemon = IFingerprintDaemon.Stub - .asInterface(ServiceManager.getService(FINGERPRINTD)); - if (mDaemon != null) { - try { - mDaemon.asBinder().linkToDeath(this, 0); - mDaemon.init(mDaemonCallback); - mHalDeviceId = mDaemon.openHal(); - if (DEBUG) Slog.v(TAG, "Fingerprint HAL id: " + mHalDeviceId); - if (mHalDeviceId != 0) { - updateActiveGroup(ActivityManager.getCurrentUser(), null); - } else { - Slog.w(TAG, "Failed to open Fingerprint HAL!"); - MetricsLogger.count(mContext, "fingerprintd_openhal_error", 1); - mDaemon = null; - } - } catch (RemoteException e) { - Slog.e(TAG, "Failed to open fingeprintd HAL", e); - mDaemon = null; // try again later! - } - } else { - Slog.w(TAG, "fingerprint service not available"); - } + public synchronized IBiometricsFingerprint getFingerprintDaemon() { + if (mDaemon == null) { + try { + mDaemon = IBiometricsFingerprint.getService(FINGERPRINT_HIDL); + } catch (java.util.NoSuchElementException e) { + // Service doesn't exist or cannot be opened. Logged below. + } catch (RemoteException e) { + Slog.e(TAG, "Failed to get biometric interface", e); + } + if (mDaemon == null) { + Slog.w(TAG, "fingerprint HIDL not available"); + return null; + } + + mDaemon.asBinder().linkToDeath(this, 0); + + try { + mHalDeviceId = mDaemon.setNotify(mDaemonCallback); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to open fingeprintd HAL", e); + mDaemon = null; // try again later! + } + + if (DEBUG) Slog.v(TAG, "Fingerprint HAL id: " + mHalDeviceId); + if (mHalDeviceId != 0) { + updateActiveGroup(ActivityManager.getCurrentUser(), null); + } else { + Slog.w(TAG, "Failed to open Fingerprint HAL!"); + MetricsLogger.count(mContext, "fingerprintd_openhal_error", 1); + mDaemon = null; } - return mDaemon; } + return mDaemon; } - protected void handleEnumerate(long deviceId, int[] fingerIds, int[] groupIds) { - if (fingerIds.length != groupIds.length) { - Slog.w(TAG, "fingerIds and groupIds differ in length: f[]=" - + Arrays.toString(fingerIds) + ", g[]=" + Arrays.toString(groupIds)); - return; - } - if (DEBUG) Slog.w(TAG, "Enumerate: f[]=" + fingerIds + ", g[]=" + groupIds); - // TODO: update fingerprint/name pairs + protected void handleEnumerate(long deviceId, int fingerId, int groupId, int remaining) { + if (DEBUG) Slog.w(TAG, "Enumerate: fid=" + fingerId + ", gid=" + + groupId + "rem=" + remaining); + // TODO: coordinate names with framework } - protected void handleError(long deviceId, int error) { + protected void handleError(long deviceId, int error, int vendorCode) { ClientMonitor client = mCurrentClient; - if (client != null && client.onError(error)) { + if (client != null && client.onError(error, vendorCode)) { removeClient(client); } if (DEBUG) Slog.v(TAG, "handleError(client=" @@ -269,9 +269,9 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe } } - protected void handleRemoved(long deviceId, int fingerId, int groupId) { + protected void handleRemoved(long deviceId, int fingerId, int groupId, int remaining) { ClientMonitor client = mCurrentClient; - if (client != null && client.onRemoved(fingerId, groupId)) { + if (client != null && client.onRemoved(fingerId, groupId, remaining)) { removeClient(client); } } @@ -288,9 +288,9 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe } } - protected void handleAcquired(long deviceId, int acquiredInfo) { + protected void handleAcquired(long deviceId, int acquiredInfo, int vendorCode) { ClientMonitor client = mCurrentClient; - if (client != null && client.onAcquired(acquiredInfo)) { + if (client != null && client.onAcquired(acquiredInfo, vendorCode)) { removeClient(client); } if (mPerformanceStats != null && !inLockoutMode() @@ -349,7 +349,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe } public long startPreEnroll(IBinder token) { - IFingerprintDaemon daemon = getFingerprintDaemon(); + IBiometricsFingerprint daemon = getFingerprintDaemon(); if (daemon == null) { Slog.w(TAG, "startPreEnroll: no fingeprintd!"); return 0; @@ -363,7 +363,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe } public int startPostEnroll(IBinder token) { - IFingerprintDaemon daemon = getFingerprintDaemon(); + IBiometricsFingerprint daemon = getFingerprintDaemon(); if (daemon == null) { Slog.w(TAG, "startPostEnroll: no fingeprintd!"); return 0; @@ -403,7 +403,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe void startRemove(IBinder token, int fingerId, int groupId, int userId, IFingerprintServiceReceiver receiver, boolean restricted) { - IFingerprintDaemon daemon = getFingerprintDaemon(); + IBiometricsFingerprint daemon = getFingerprintDaemon(); if (daemon == null) { Slog.w(TAG, "startRemove: no fingeprintd!"); return; @@ -416,7 +416,29 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe } @Override - public IFingerprintDaemon getFingerprintDaemon() { + public IBiometricsFingerprint getFingerprintDaemon() { + return FingerprintService.this.getFingerprintDaemon(); + } + }; + startClient(client, true); + } + + void startEnumerate(IBinder token, int userId, + IFingerprintServiceReceiver receiver, boolean restricted) { + IBiometricsFingerprint daemon = getFingerprintDaemon(); + if (daemon == null) { + Slog.w(TAG, "startEnumerate: no fingeprintd!"); + return; + } + EnumerateClient client = new EnumerateClient(getContext(), mHalDeviceId, token, + receiver, userId, userId, restricted, token.toString()) { + @Override + public void notifyUserActivity() { + FingerprintService.this.userActivity(); + } + + @Override + public IBiometricsFingerprint getFingerprintDaemon() { return FingerprintService.this.getFingerprintDaemon(); } }; @@ -580,7 +602,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe } @Override - public IFingerprintDaemon getFingerprintDaemon() { + public IBiometricsFingerprint getFingerprintDaemon() { return FingerprintService.this.getFingerprintDaemon(); } }; @@ -588,7 +610,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe if (inLockoutMode()) { Slog.v(TAG, "In lockout mode; disallowing authentication"); // Don't bother starting the client. Just send the error message. - if (!client.onError(FingerprintManager.FINGERPRINT_ERROR_LOCKOUT)) { + if (!client.onError(FingerprintManager.FINGERPRINT_ERROR_LOCKOUT, 0 /* vendorCode */)) { Slog.w(TAG, "Cannot send timeout message to client"); } return; @@ -607,7 +629,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe userId, groupId, cryptoToken, restricted, opPackageName) { @Override - public IFingerprintDaemon getFingerprintDaemon() { + public IBiometricsFingerprint getFingerprintDaemon() { return FingerprintService.this.getFingerprintDaemon(); } @@ -674,7 +696,8 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe }; } - private IFingerprintDaemonCallback mDaemonCallback = new IFingerprintDaemonCallback.Stub() { + private IBiometricsFingerprintClientCallback mDaemonCallback = + new IBiometricsFingerprintClientCallback.Stub() { @Override public void onEnrollResult(final long deviceId, final int fingerId, final int groupId, @@ -688,11 +711,11 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe } @Override - public void onAcquired(final long deviceId, final int acquiredInfo) { + public void onAcquired(final long deviceId, final int acquiredInfo, final int vendorCode) { mHandler.post(new Runnable() { @Override public void run() { - handleAcquired(deviceId, acquiredInfo); + handleAcquired(deviceId, acquiredInfo, vendorCode); } }); } @@ -708,31 +731,32 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe } @Override - public void onError(final long deviceId, final int error) { + public void onError(final long deviceId, final int error, final int vendorCode) { mHandler.post(new Runnable() { @Override public void run() { - handleError(deviceId, error); + handleError(deviceId, error, vendorCode); } }); } @Override - public void onRemoved(final long deviceId, final int fingerId, final int groupId) { + public void onRemoved(final long deviceId, final int fingerId, final int groupId, final int remaining) { mHandler.post(new Runnable() { @Override public void run() { - handleRemoved(deviceId, fingerId, groupId); + handleRemoved(deviceId, fingerId, groupId, remaining); } }); } @Override - public void onEnumerate(final long deviceId, final int[] fingerIds, final int[] groupIds) { + public void onEnumerate(final long deviceId, final int fingerId, final int groupId, + final int remaining) { mHandler.post(new Runnable() { @Override public void run() { - handleEnumerate(deviceId, fingerIds, groupIds); + handleEnumerate(deviceId, fingerId, groupId, remaining); } }); } @@ -889,6 +913,19 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe } + public void enumerate(final IBinder token, final int userId, + final IFingerprintServiceReceiver receiver) { + checkPermission(MANAGE_FINGERPRINT); // TODO: Maybe have another permission + final boolean restricted = isRestricted(); + mHandler.post(new Runnable() { + @Override + public void run() { + startEnumerate(token, userId, receiver, restricted); + } + }); + + } + @Override // Binder call public boolean isHardwareDetected(long deviceId, String opPackageName) { if (!canUseFingerprint(opPackageName, false /* foregroundOnly */, @@ -1082,7 +1119,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe } private void updateActiveGroup(int userId, String clientPackage) { - IFingerprintDaemon daemon = getFingerprintDaemon(); + IBiometricsFingerprint daemon = getFingerprintDaemon(); if (daemon != null) { try { @@ -1103,7 +1140,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe return; } } - daemon.setActiveGroup(userId, fpDir.getAbsolutePath().getBytes()); + daemon.setActiveGroup(userId, fpDir.getAbsolutePath()); mCurrentUserId = userId; } mCurrentAuthenticatorId = daemon.getAuthenticatorId(); @@ -1155,5 +1192,4 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe public long getAuthenticatorId(String opPackageName) { return mCurrentAuthenticatorId; } - } diff --git a/services/core/java/com/android/server/fingerprint/RemovalClient.java b/services/core/java/com/android/server/fingerprint/RemovalClient.java index f939f4177a24b..ab1b97284998e 100644 --- a/services/core/java/com/android/server/fingerprint/RemovalClient.java +++ b/services/core/java/com/android/server/fingerprint/RemovalClient.java @@ -17,8 +17,8 @@ package com.android.server.fingerprint; import android.content.Context; +import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint; import android.hardware.fingerprint.FingerprintManager; -import android.hardware.fingerprint.IFingerprintDaemon; import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.os.IBinder; import android.os.RemoteException; @@ -41,14 +41,14 @@ public abstract class RemovalClient extends ClientMonitor { @Override public int start() { - IFingerprintDaemon daemon = getFingerprintDaemon(); + IBiometricsFingerprint daemon = getFingerprintDaemon(); // The fingerprint template ids will be removed when we get confirmation from the HAL try { - final int result = daemon.remove(mFingerId, getGroupId()); + final int result = daemon.remove(getGroupId(), mFingerId); if (result != 0) { Slog.w(TAG, "startRemove with id = " + mFingerId + " failed, result=" + result); MetricsLogger.histogram(getContext(), "fingerprintd_remove_start_error", result); - onError(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE); + onError(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */); return result; } } catch (RemoteException e) { @@ -62,7 +62,7 @@ public abstract class RemovalClient extends ClientMonitor { // We don't actually stop remove, but inform the client that the cancel operation succeeded // so we can start the next operation. if (initiatedByClient) { - onError(FingerprintManager.FINGERPRINT_ERROR_CANCELED); + onError(FingerprintManager.FINGERPRINT_ERROR_CANCELED, 0 /* vendorCode */); } return 0; } @@ -70,11 +70,12 @@ public abstract class RemovalClient extends ClientMonitor { /* * @return true if we're done. */ - private boolean sendRemoved(int fingerId, int groupId) { + private boolean sendRemoved(int fingerId, int groupId, int remaining) { IFingerprintServiceReceiver receiver = getReceiver(); try { if (receiver != null) { - receiver.onRemoved(getHalDeviceId(), fingerId, groupId); + // TODO: plumb remaining + receiver.onRemoved(getHalDeviceId(), fingerId, groupId, remaining); } } catch (RemoteException e) { Slog.w(TAG, "Failed to notify Removed:", e); @@ -83,12 +84,12 @@ public abstract class RemovalClient extends ClientMonitor { } @Override - public boolean onRemoved(int fingerId, int groupId) { + public boolean onRemoved(int fingerId, int groupId, int remaining) { if (fingerId != 0) { FingerprintUtils.getInstance().removeFingerprintIdForUser(getContext(), fingerId, getTargetUserId()); } - return sendRemoved(fingerId, getGroupId()); + return sendRemoved(fingerId, getGroupId(), remaining); } @Override @@ -104,9 +105,9 @@ public abstract class RemovalClient extends ClientMonitor { } @Override - public boolean onEnumerationResult(int fingerId, int groupId) { + public boolean onEnumerationResult(int fingerId, int groupId, int remaining) { if (DEBUG) Slog.w(TAG, "onEnumerationResult() called for remove!"); - return false; // Invalid for Remove. + return true; // Invalid for Remove. }