From 5f26c1ace2d63797c585de24bbe7123ba224622e Mon Sep 17 00:00:00 2001 From: Jim Miller Date: Thu, 19 Jan 2017 18:39:06 -0800 Subject: [PATCH] clean up default fingerprint HIDL@2.1 implementation - remove Binder dependency by passing keystore token to onAuthenticated() - move notify() to cpp file Test: recovers from killing keystore, fingerprint unlocks device, FingerprintDialog works with crypto objects. Fixes bug 34264028 Change-Id: Ic0de31603f4bc4147d6faf014af89e787b1ef244 --- .../IBiometricsFingerprintClientCallback.hal | 3 +- .../2.1/default/BiometricsFingerprint.cpp | 131 ++++++++++++------ .../2.1/default/BiometricsFingerprint.h | 71 ++-------- 3 files changed, 104 insertions(+), 101 deletions(-) diff --git a/biometrics/fingerprint/2.1/IBiometricsFingerprintClientCallback.hal b/biometrics/fingerprint/2.1/IBiometricsFingerprintClientCallback.hal index 63435d1463..d913cf1301 100644 --- a/biometrics/fingerprint/2.1/IBiometricsFingerprintClientCallback.hal +++ b/biometrics/fingerprint/2.1/IBiometricsFingerprintClientCallback.hal @@ -43,8 +43,9 @@ interface IBiometricsFingerprintClientCallback { * @param deviceId the instance of this fingerprint device * @param fingerId the fingerprint templetate that was authenticated * @param groupId the groupid for the template that was authenticated + * @param token the hardware authentication token to pass to Keystore.addAuthToken() */ - oneway onAuthenticated(uint64_t deviceId, uint32_t fingerId, uint32_t groupId); + oneway onAuthenticated(uint64_t deviceId, uint32_t fingerId, uint32_t groupId, vec token); /** * Sent when a fingerprint error occurs diff --git a/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp b/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp index 516cd00df5..154b7a66b4 100644 --- a/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp +++ b/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp @@ -14,10 +14,9 @@ * limitations under the License. */ #define LOG_TAG "android.hardware.biometrics.fingerprint@2.1-service" +#define LOG_VERBOSE "android.hardware.biometrics.fingerprint@2.1-service" // For communication with Keystore binder interface -#include -#include #include // for error codes #include @@ -40,23 +39,19 @@ static const uint16_t kVersion = HARDWARE_MODULE_API_VERSION(2, 1); using RequestStatus = android::hardware::biometrics::fingerprint::V2_1::RequestStatus; -sp - BiometricsFingerprint::mClientCallback = nullptr; +BiometricsFingerprint *BiometricsFingerprint::sInstance = nullptr; -// TODO: This is here because HAL 2.1 doesn't have a way to propagate a -// unique token for its driver. Subsequent versions should send a unique -// token for each call to notify(). This is fine as long as there's only -// one fingerprint device on the platform. -fingerprint_device_t *BiometricsFingerprint::sDevice = nullptr; - -BiometricsFingerprint::BiometricsFingerprint(fingerprint_device_t *device) - : mDevice(device) { - sDevice = mDevice; // keep track of the most recent instance +BiometricsFingerprint::BiometricsFingerprint() : mClientCallback(nullptr), mDevice(nullptr) { + sInstance = this; // keep track of the most recent instance + mDevice = openHal(); + if (!mDevice) { + ALOGE("Can't open HAL module"); + } } BiometricsFingerprint::~BiometricsFingerprint() { - ALOG(LOG_VERBOSE, LOG_TAG, "nativeCloseHal()\n"); - if (mDevice == NULL) { + ALOGV(LOG_VERBOSE, LOG_TAG, "~BiometricsFingerprint()\n"); + if (mDevice == nullptr) { ALOGE("No valid device"); return; } @@ -66,7 +61,7 @@ BiometricsFingerprint::~BiometricsFingerprint() { ALOGE("Can't close fingerprint module, error: %d", err); return; } - mDevice = NULL; + mDevice = nullptr; } Return BiometricsFingerprint::ErrorFilter(int32_t error) { @@ -107,6 +102,8 @@ FingerprintError BiometricsFingerprint::VendorErrorFilter(int32_t error, return FingerprintError::ERROR_CANCELED; case FINGERPRINT_ERROR_UNABLE_TO_REMOVE: return FingerprintError::ERROR_UNABLE_TO_REMOVE; + case FINGERPRINT_ERROR_LOCKOUT: + return FingerprintError::ERROR_LOCKOUT; default: if (error >= FINGERPRINT_ERROR_VENDOR_BASE) { // vendor specific code. @@ -114,7 +111,7 @@ FingerprintError BiometricsFingerprint::VendorErrorFilter(int32_t error, return FingerprintError::ERROR_VENDOR; } } - ALOGE("Unknown error from fingerprint vendor library"); + ALOGE("Unknown error from fingerprint vendor library: %d", error); return FingerprintError::ERROR_UNABLE_TO_PROCESS; } @@ -143,13 +140,17 @@ FingerprintAcquiredInfo BiometricsFingerprint::VendorAcquiredFilter( return FingerprintAcquiredInfo::ACQUIRED_VENDOR; } } - ALOGE("Unknown acquiredmsg from fingerprint vendor library"); + ALOGE("Unknown acquiredmsg from fingerprint vendor library: %d", info); return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT; } Return BiometricsFingerprint::setNotify( const sp& clientCallback) { mClientCallback = clientCallback; + // This is here because HAL 2.1 doesn't have a way to propagate a + // unique token for its driver. Subsequent versions should send a unique + // token for each call to setNotify(). This is fine as long as there's only + // one fingerprint device on the platform. return reinterpret_cast(mDevice); } @@ -199,36 +200,44 @@ Return BiometricsFingerprint::authenticate(uint64_t operationId, } IBiometricsFingerprint* BiometricsFingerprint::getInstance() { + if (!sInstance) { + sInstance = new BiometricsFingerprint(); + } + return sInstance; +} + +fingerprint_device_t* BiometricsFingerprint::openHal() { int err; - const hw_module_t *hw_mdl = NULL; - ALOGE("Opening fingerprint hal library..."); + const hw_module_t *hw_mdl = nullptr; + ALOGD("Opening fingerprint hal library..."); if (0 != (err = hw_get_module(FINGERPRINT_HARDWARE_MODULE_ID, &hw_mdl))) { ALOGE("Can't open fingerprint HW Module, error: %d", err); return nullptr; } - if (hw_mdl == NULL) { + if (hw_mdl == nullptr) { ALOGE("No valid fingerprint module"); return nullptr; } fingerprint_module_t const *module = reinterpret_cast(hw_mdl); - if (module->common.methods->open == NULL) { + if (module->common.methods->open == nullptr) { ALOGE("No valid open method"); return nullptr; } - hw_device_t *device = NULL; + hw_device_t *device = nullptr; - if (0 != (err = module->common.methods->open(hw_mdl, NULL, &device))) { + if (0 != (err = module->common.methods->open(hw_mdl, nullptr, &device))) { ALOGE("Can't open fingerprint methods, error: %d", err); return nullptr; } if (kVersion != device->version) { + // enforce version on new devices because of HIDL@2.1 translation layer ALOGE("Wrong fp version. Expected %d, got %d", kVersion, device->version); - return 0; // enforce this on new devices because of HIDL translation layer + return nullptr; } fingerprint_device_t* fp_device = @@ -240,23 +249,67 @@ IBiometricsFingerprint* BiometricsFingerprint::getInstance() { return nullptr; } - return new BiometricsFingerprint(fp_device); + return fp_device; } -void BiometricsFingerprint::notifyKeystore(const uint8_t *auth_token, const size_t auth_token_length) { - if (auth_token != nullptr && auth_token_length > 0) { - // TODO: cache service? - sp sm = android::defaultServiceManager(); - sp<::android::IBinder> binder = sm->getService(String16("android.security.keystore")); - sp service = interface_cast(binder); - if (service != nullptr) { - auto ret = service->addAuthToken(auth_token, auth_token_length); - if (!ret.isOk()) { - ALOGE("Failure sending auth token to KeyStore: %" PRId32, int32_t(ret)); +void BiometricsFingerprint::notify(const fingerprint_msg_t *msg) { + BiometricsFingerprint* thisPtr = static_cast( + BiometricsFingerprint::getInstance()); + if (thisPtr == nullptr || thisPtr->mClientCallback == nullptr) { + ALOGE("Receiving callbacks before the client callback is registered."); + return; + } + const uint64_t devId = reinterpret_cast(thisPtr->mDevice); + switch (msg->type) { + case FINGERPRINT_ERROR: { + int32_t vendorCode = 0; + FingerprintError result = VendorErrorFilter(msg->data.error, &vendorCode); + thisPtr->mClientCallback->onError(devId, result, vendorCode); } - } else { - ALOGE("Unable to communicate with KeyStore"); - } + break; + case FINGERPRINT_ACQUIRED: { + int32_t vendorCode = 0; + FingerprintAcquiredInfo result = + VendorAcquiredFilter(msg->data.acquired.acquired_info, &vendorCode); + thisPtr->mClientCallback->onAcquired(devId, result, vendorCode); + } + break; + case FINGERPRINT_TEMPLATE_ENROLLING: + thisPtr->mClientCallback->onEnrollResult(devId, + msg->data.enroll.finger.fid, + msg->data.enroll.finger.gid, + msg->data.enroll.samples_remaining); + break; + case FINGERPRINT_TEMPLATE_REMOVED: + thisPtr->mClientCallback->onRemoved(devId, + msg->data.removed.finger.fid, + msg->data.removed.finger.gid, + msg->data.removed.remaining_templates); + break; + case FINGERPRINT_AUTHENTICATED: + if (msg->data.authenticated.finger.fid != 0) { + const uint8_t* hat = + reinterpret_cast(&msg->data.authenticated.hat); + const hidl_vec token( + std::vector(hat, hat + sizeof(msg->data.authenticated.hat))); + thisPtr->mClientCallback->onAuthenticated(devId, + msg->data.authenticated.finger.fid, + msg->data.authenticated.finger.gid, + token); + } else { + // Not a recognized fingerprint + thisPtr->mClientCallback->onAuthenticated(devId, + msg->data.authenticated.finger.fid, + msg->data.authenticated.finger.gid, + hidl_vec()); + } + break; + case FINGERPRINT_TEMPLATE_ENUMERATING: + thisPtr->mClientCallback->onEnumerate(devId, + msg->data.enumerated.finger.fid, + msg->data.enumerated.finger.gid, + msg->data.enumerated.remaining_templates); + break; } } diff --git a/biometrics/fingerprint/2.1/default/BiometricsFingerprint.h b/biometrics/fingerprint/2.1/default/BiometricsFingerprint.h index 1f44a1c0e5..652a3e0dff 100644 --- a/biometrics/fingerprint/2.1/default/BiometricsFingerprint.h +++ b/biometrics/fingerprint/2.1/default/BiometricsFingerprint.h @@ -43,7 +43,7 @@ using ::android::sp; struct BiometricsFingerprint : public IBiometricsFingerprint { public: - BiometricsFingerprint(fingerprint_device_t *device); + BiometricsFingerprint(); ~BiometricsFingerprint(); // Method to wrap legacy HAL with BiometricsFingerprint class @@ -60,68 +60,17 @@ public: Return remove(uint32_t gid, uint32_t fid) override; Return setActiveGroup(uint32_t gid, const hidl_string& storePath) override; Return authenticate(uint64_t operationId, uint32_t gid) override; - static void notify(const fingerprint_msg_t *msg) { - if (mClientCallback == nullptr) { - ALOGE("Receiving callbacks before the client callback is registered."); - return; - } - const uint64_t devId = reinterpret_cast(sDevice); - switch (msg->type) { - case FINGERPRINT_ERROR: { - int32_t vendorCode = 0; - FingerprintError result = - VendorErrorFilter(msg->data.error, &vendorCode); - mClientCallback->onError(devId, result, vendorCode); - } - break; - case FINGERPRINT_ACQUIRED: { - int32_t vendorCode = 0; - FingerprintAcquiredInfo result = - VendorAcquiredFilter(msg->data.acquired.acquired_info, - &vendorCode); - mClientCallback->onAcquired(devId, result, vendorCode); - } - break; - case FINGERPRINT_TEMPLATE_ENROLLING: - mClientCallback->onEnrollResult(devId, - msg->data.enroll.finger.fid, - msg->data.enroll.finger.gid, - msg->data.enroll.samples_remaining); - break; - case FINGERPRINT_TEMPLATE_REMOVED: - mClientCallback->onRemoved(devId, - msg->data.removed.finger.fid, - msg->data.removed.finger.gid, - msg->data.removed.remaining_templates); - break; - case FINGERPRINT_AUTHENTICATED: - if (msg->data.authenticated.finger.fid != 0) { - const uint8_t* hat = - reinterpret_cast(&msg->data.authenticated.hat); - notifyKeystore(hat, sizeof(msg->data.authenticated.hat)); - } - mClientCallback->onAuthenticated(devId, - msg->data.authenticated.finger.fid, - msg->data.authenticated.finger.gid); - break; - case FINGERPRINT_TEMPLATE_ENUMERATING: - mClientCallback->onEnumerate(devId, - msg->data.enumerated.finger.fid, - msg->data.enumerated.finger.gid, - msg->data.enumerated.remaining_templates); - break; - } - } + private: - Return ErrorFilter(int32_t error); - static void notifyKeystore(const uint8_t *auth_token, const size_t auth_token_length); - static FingerprintError VendorErrorFilter(int32_t error, - int32_t* vendorCode); - static FingerprintAcquiredInfo VendorAcquiredFilter(int32_t error, - int32_t* vendorCode); - static sp mClientCallback; + static fingerprint_device_t* openHal(); + static void notify(const fingerprint_msg_t *msg); /* Static callback for legacy HAL implementation */ + static Return ErrorFilter(int32_t error); + static FingerprintError VendorErrorFilter(int32_t error, int32_t* vendorCode); + static FingerprintAcquiredInfo VendorAcquiredFilter(int32_t error, int32_t* vendorCode); + static BiometricsFingerprint* sInstance; + + sp mClientCallback; fingerprint_device_t *mDevice; - static fingerprint_device_t *sDevice; // TODO: allow multiple drivers }; } // namespace implementation