diff --git a/fingerprintd/Android.mk b/fingerprintd/Android.mk index 48b95258a..55803cfe1 100644 --- a/fingerprintd/Android.mk +++ b/fingerprintd/Android.mk @@ -26,8 +26,11 @@ LOCAL_SRC_FILES := \ LOCAL_MODULE := fingerprintd LOCAL_SHARED_LIBRARIES := \ libbinder \ + libhidlbase \ + libhidltransport \ liblog \ libhardware \ libutils \ - libkeystore_binder + libkeystore_binder \ + android.hardware.biometrics.fingerprint@2.1 include $(BUILD_EXECUTABLE) diff --git a/fingerprintd/FingerprintDaemonProxy.cpp b/fingerprintd/FingerprintDaemonProxy.cpp index 1c7da30c3..0119e5541 100644 --- a/fingerprintd/FingerprintDaemonProxy.cpp +++ b/fingerprintd/FingerprintDaemonProxy.cpp @@ -16,10 +16,10 @@ #define LOG_TAG "fingerprintd" +#include +#include +#include #include -#include -#include -#include #include #include // for error codes #include @@ -28,12 +28,45 @@ namespace android { -FingerprintDaemonProxy* FingerprintDaemonProxy::sInstance = NULL; +using hardware::hidl_string; +using hardware::Return; +using hardware::biometrics::fingerprint::V2_1::FingerprintMsg; +using hardware::biometrics::fingerprint::V2_1::RequestStatus; +using hardware::biometrics::fingerprint::V2_1::FingerprintError; +using hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprintClientCallback; +using Type = hardware::biometrics::fingerprint::V2_1::FingerprintMsgType; +using IBiometricsFingerprint = hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprint; -// Supported fingerprint HAL version -static const uint16_t kVersion = HARDWARE_MODULE_API_VERSION(2, 0); +FingerprintDaemonProxy* FingerprintDaemonProxy::sInstance = nullptr; +static sp gBFP = nullptr; +static sp gClientCallback = nullptr; -FingerprintDaemonProxy::FingerprintDaemonProxy() : mModule(NULL), mDevice(NULL), mCallback(NULL) { +template +constexpr typename std::underlying_type::type to_native(E e) { + return static_cast::type>(e); +} + +const ssize_t hw_auth_token_size = 69; + +namespace hardware { + +class BiometricsFingerprintClientCallback : public IBiometricsFingerprintClientCallback { + public: + BiometricsFingerprintClientCallback() {}; + virtual ~BiometricsFingerprintClientCallback() = default; + Return notify(const FingerprintMsg& msg) { + FingerprintDaemonProxy::hal_notify_callback(msg); + return Void(); + } +}; + +IBiometricsFingerprintClientCallback* HIDL_FETCH_IBiometricsFingerprintClientCallback(const char* /* name */) { + return new BiometricsFingerprintClientCallback(); +} + +} // namespace hardware + +FingerprintDaemonProxy::FingerprintDaemonProxy() : mCallback(nullptr) { } @@ -41,76 +74,75 @@ FingerprintDaemonProxy::~FingerprintDaemonProxy() { closeHal(); } -void FingerprintDaemonProxy::hal_notify_callback(const fingerprint_msg_t *msg) { +void FingerprintDaemonProxy::hal_notify_callback(const hardware::biometrics::fingerprint::V2_1::FingerprintMsg &msg) { FingerprintDaemonProxy* instance = FingerprintDaemonProxy::getInstance(); const sp callback = instance->mCallback; - if (callback == NULL) { + if (callback == nullptr) { ALOGE("Invalid callback object"); return; } - const int64_t device = (int64_t) instance->mDevice; - switch (msg->type) { - case FINGERPRINT_ERROR: - ALOGD("onError(%d)", msg->data.error); - callback->onError(device, msg->data.error); + switch (msg.type) { + case Type::ERROR: + ALOGD("onError(%d)", msg.data.error); + callback->onError(0, to_native(msg.data.error)); break; - case FINGERPRINT_ACQUIRED: - ALOGD("onAcquired(%d)", msg->data.acquired.acquired_info); - callback->onAcquired(device, msg->data.acquired.acquired_info); + case Type::ACQUIRED: + ALOGD("onAcquired(%d)", msg.data.acquired.acquiredInfo); + callback->onAcquired(0, to_native(msg.data.acquired.acquiredInfo)); break; - case FINGERPRINT_AUTHENTICATED: + case Type::AUTHENTICATED: ALOGD("onAuthenticated(fid=%d, gid=%d)", - msg->data.authenticated.finger.fid, - msg->data.authenticated.finger.gid); - if (msg->data.authenticated.finger.fid != 0) { - const uint8_t* hat = reinterpret_cast(&msg->data.authenticated.hat); - instance->notifyKeystore(hat, sizeof(msg->data.authenticated.hat)); + msg.data.authenticated.finger.fid, + msg.data.authenticated.finger.gid); + if (msg.data.authenticated.finger.fid != 0) { + const uint8_t* hat = reinterpret_cast(&msg.data.authenticated.hat); + instance->notifyKeystore(hat, sizeof(msg.data.authenticated.hat)); } - callback->onAuthenticated(device, - msg->data.authenticated.finger.fid, - msg->data.authenticated.finger.gid); + callback->onAuthenticated(0, + msg.data.authenticated.finger.fid, + msg.data.authenticated.finger.gid); break; - case FINGERPRINT_TEMPLATE_ENROLLING: + case Type::TEMPLATE_ENROLLING: ALOGD("onEnrollResult(fid=%d, gid=%d, rem=%d)", - msg->data.enroll.finger.fid, - msg->data.enroll.finger.gid, - msg->data.enroll.samples_remaining); - callback->onEnrollResult(device, - msg->data.enroll.finger.fid, - msg->data.enroll.finger.gid, - msg->data.enroll.samples_remaining); + msg.data.enroll.finger.fid, + msg.data.enroll.finger.gid, + msg.data.enroll.samplesRemaining); + callback->onEnrollResult(0, + msg.data.enroll.finger.fid, + msg.data.enroll.finger.gid, + msg.data.enroll.samplesRemaining); break; - case FINGERPRINT_TEMPLATE_REMOVED: + case Type::TEMPLATE_REMOVED: ALOGD("onRemove(fid=%d, gid=%d)", - msg->data.removed.finger.fid, - msg->data.removed.finger.gid); - callback->onRemoved(device, - msg->data.removed.finger.fid, - msg->data.removed.finger.gid); + msg.data.removed.finger.fid, + msg.data.removed.finger.gid); + callback->onRemoved(0, + msg.data.removed.finger.fid, + msg.data.removed.finger.gid); break; - case FINGERPRINT_TEMPLATE_ENUMERATING: + case Type::TEMPLATE_ENUMERATING: ALOGD("onEnumerate(fid=%d, gid=%d, rem=%d)", - msg->data.enumerated.finger.fid, - msg->data.enumerated.finger.gid, - msg->data.enumerated.remaining_templates); - callback->onEnumerate(device, - msg->data.enumerated.finger.fid, - msg->data.enumerated.finger.gid, - msg->data.enumerated.remaining_templates); + msg.data.enumerated.finger.fid, + msg.data.enumerated.finger.gid, + msg.data.enumerated.remainingTemplates); + callback->onEnumerate(0, + msg.data.enumerated.finger.fid, + msg.data.enumerated.finger.gid, + msg.data.enumerated.remainingTemplates); break; default: - ALOGE("invalid msg type: %d", msg->type); + ALOGE("invalid msg type: %d", msg.type); return; } } void FingerprintDaemonProxy::notifyKeystore(const uint8_t *auth_token, const size_t auth_token_length) { - if (auth_token != NULL && auth_token_length > 0) { + if (auth_token != nullptr && auth_token_length > 0) { // TODO: cache service? sp < IServiceManager > sm = defaultServiceManager(); sp < IBinder > binder = sm->getService(String16("android.security.keystore")); sp < IKeystoreService > service = interface_cast < IKeystoreService > (binder); - if (service != NULL) { + if (service != nullptr) { status_t ret = service->addAuthToken(auth_token, auth_token_length); if (ret != ResponseCode::NO_ERROR) { ALOGE("Falure sending auth token to KeyStore: %d", ret); @@ -122,7 +154,7 @@ void FingerprintDaemonProxy::notifyKeystore(const uint8_t *auth_token, const siz } void FingerprintDaemonProxy::init(const sp& callback) { - if (mCallback != NULL && IInterface::asBinder(callback) != IInterface::asBinder(mCallback)) { + if (mCallback != nullptr && IInterface::asBinder(callback) != IInterface::asBinder(mCallback)) { IInterface::asBinder(mCallback)->unlinkToDeath(this); } IInterface::asBinder(callback)->linkToDeath(this); @@ -132,49 +164,99 @@ void FingerprintDaemonProxy::init(const sp& callback int32_t FingerprintDaemonProxy::enroll(const uint8_t* token, ssize_t tokenSize, int32_t groupId, int32_t timeout) { ALOG(LOG_VERBOSE, LOG_TAG, "enroll(gid=%d, timeout=%d)\n", groupId, timeout); - if (tokenSize != sizeof(hw_auth_token_t) ) { - ALOG(LOG_VERBOSE, LOG_TAG, "enroll() : invalid token size %zu\n", tokenSize); + if (tokenSize != hw_auth_token_size) { + ALOG(LOG_VERBOSE, LOG_TAG, "enroll() : invalid token size %zd, expected %zd\n", tokenSize, hw_auth_token_size); return -1; } - const hw_auth_token_t* authToken = reinterpret_cast(token); - return mDevice->enroll(mDevice, authToken, groupId, timeout); + + hardware::hidl_array hat(token); + Return ret = gBFP->enroll(hat, groupId, timeout); + if (!ret.getStatus().isOk()) { + ALOGE("Unknown transport error"); + return -1; + } + + RequestStatus status = ret; + return to_native(status); } uint64_t FingerprintDaemonProxy::preEnroll() { - return mDevice->pre_enroll(mDevice); + return gBFP->preEnroll(); } int32_t FingerprintDaemonProxy::postEnroll() { - return mDevice->post_enroll(mDevice); + Return ret = gBFP->postEnroll(); + if (!ret.getStatus().isOk()) { + ALOGE("Unknown transport error"); + return -1; + } + + RequestStatus status = ret; + return to_native(status); } int32_t FingerprintDaemonProxy::stopEnrollment() { ALOG(LOG_VERBOSE, LOG_TAG, "stopEnrollment()\n"); - return mDevice->cancel(mDevice); + Return ret = gBFP->cancel(); + if (!ret.getStatus().isOk()) { + ALOGE("Unknown transport error"); + return -1; + } + + RequestStatus status = ret; + return to_native(status); } int32_t FingerprintDaemonProxy::authenticate(uint64_t sessionId, uint32_t groupId) { ALOG(LOG_VERBOSE, LOG_TAG, "authenticate(sid=%" PRId64 ", gid=%d)\n", sessionId, groupId); - return mDevice->authenticate(mDevice, sessionId, groupId); + Return ret = gBFP->authenticate(sessionId, groupId); + if (!ret.getStatus().isOk()) { + ALOGE("Unknown transport error"); + return -1; + } + + RequestStatus status = ret; + return to_native(status); } int32_t FingerprintDaemonProxy::stopAuthentication() { ALOG(LOG_VERBOSE, LOG_TAG, "stopAuthentication()\n"); - return mDevice->cancel(mDevice); + Return ret = gBFP->cancel(); + if (!ret.getStatus().isOk()) { + ALOGE("Unknown transport error"); + return -1; + } + + RequestStatus status = ret; + return to_native(status); } int32_t FingerprintDaemonProxy::remove(int32_t fingerId, int32_t groupId) { ALOG(LOG_VERBOSE, LOG_TAG, "remove(fid=%d, gid=%d)\n", fingerId, groupId); - return mDevice->remove(mDevice, groupId, fingerId); + Return ret = gBFP->remove(groupId, fingerId); + if (!ret.getStatus().isOk()) { + ALOGE("Unknown transport error"); + return -1; + } + + RequestStatus status = ret; + return to_native(status); } int32_t FingerprintDaemonProxy::enumerate() { ALOG(LOG_VERBOSE, LOG_TAG, "enumerate()\n"); - return mDevice->enumerate(mDevice); + Return ret = gBFP->enumerate(); + if (!ret.getStatus().isOk()) { + ALOGE("Unknown transport error"); + return -1; + } + + RequestStatus status = ret; + return to_native(status); } uint64_t FingerprintDaemonProxy::getAuthenticatorId() { - return mDevice->get_authenticator_id(mDevice); + return gBFP->getAuthenticatorId(); } int32_t FingerprintDaemonProxy::setActiveGroup(int32_t groupId, const uint8_t* path, @@ -183,74 +265,35 @@ int32_t FingerprintDaemonProxy::setActiveGroup(int32_t groupId, const uint8_t* p ALOGE("Bad path length: %zd", pathlen); return -1; } - // Convert to null-terminated string - char path_name[PATH_MAX]; - memcpy(path_name, path, pathlen); - path_name[pathlen] = '\0'; - ALOG(LOG_VERBOSE, LOG_TAG, "setActiveGroup(%d, %s, %zu)", groupId, path_name, pathlen); - return mDevice->set_active_group(mDevice, groupId, path_name); + hidl_string pathname; + pathname.setToExternal(reinterpret_cast(path), pathlen); + ALOG(LOG_VERBOSE, LOG_TAG, "setActiveGroup(%d, %s, %zu)", groupId, pathname.c_str(), pathlen); + Return ret = gBFP->setActiveGroup(groupId, pathname); + if (!ret.getStatus().isOk()) { + ALOGE("Unknown transport error"); + return -1; + } + + RequestStatus status = ret; + return to_native(status); } int64_t FingerprintDaemonProxy::openHal() { - ALOG(LOG_VERBOSE, LOG_TAG, "nativeOpenHal()\n"); - int err; - const hw_module_t *hw_module = NULL; - if (0 != (err = hw_get_module(FINGERPRINT_HARDWARE_MODULE_ID, &hw_module))) { - ALOGE("Can't open fingerprint HW Module, error: %d", err); - return 0; + if (gBFP == nullptr) { + // TODO(b/31632518) + gBFP = IBiometricsFingerprint::getService("fingerprint"); + if(gBFP == nullptr) { + ALOGE("Can't get service fingerprint"); + return 0; + } } - if (NULL == hw_module) { - ALOGE("No valid fingerprint module"); - return 0; - } - - mModule = reinterpret_cast(hw_module); - - if (mModule->common.methods->open == NULL) { - ALOGE("No valid open method"); - return 0; - } - - hw_device_t *device = NULL; - - if (0 != (err = mModule->common.methods->open(hw_module, NULL, &device))) { - ALOGE("Can't open fingerprint methods, error: %d", err); - return 0; - } - - if (kVersion != device->version) { - ALOGE("Wrong fp version. Expected %d, got %d", kVersion, device->version); - // return 0; // FIXME - } - - mDevice = reinterpret_cast(device); - err = mDevice->set_notify(mDevice, hal_notify_callback); - if (err < 0) { - ALOGE("Failed in call to set_notify(), err=%d", err); - return 0; - } - - // Sanity check - remove - if (mDevice->notify != hal_notify_callback) { - ALOGE("NOTIFY not set properly: %p != %p", mDevice->notify, hal_notify_callback); - } - - ALOG(LOG_VERBOSE, LOG_TAG, "fingerprint HAL successfully initialized"); - return reinterpret_cast(mDevice); // This is just a handle + gClientCallback = hardware::HIDL_FETCH_IBiometricsFingerprintClientCallback(nullptr); + gBFP->setNotify(gClientCallback); + return reinterpret_cast(gBFP.get()); } int32_t FingerprintDaemonProxy::closeHal() { - ALOG(LOG_VERBOSE, LOG_TAG, "nativeCloseHal()\n"); - if (mDevice == NULL) { - ALOGE("No valid device"); - return -ENOSYS; - } - int err; - if (0 != (err = mDevice->common.close(reinterpret_cast(mDevice)))) { - ALOGE("Can't close fingerprint module, error: %d", err); - return err; - } - mDevice = NULL; + // Obsolete, return 0 for compatibility reasons. return 0; } @@ -261,8 +304,8 @@ void FingerprintDaemonProxy::binderDied(const wp& who) { ALOGE("Can't close fingerprint device, error: %d", err); } if (IInterface::asBinder(mCallback) == who) { - mCallback = NULL; + mCallback = nullptr; } } -} +} // namespace android diff --git a/fingerprintd/FingerprintDaemonProxy.h b/fingerprintd/FingerprintDaemonProxy.h index 145b4c936..715344c85 100644 --- a/fingerprintd/FingerprintDaemonProxy.h +++ b/fingerprintd/FingerprintDaemonProxy.h @@ -22,6 +22,8 @@ namespace android { +using hardware::biometrics::fingerprint::V2_1::RequestStatus; + class FingerprintDaemonProxy : public BnFingerprintDaemon { public: static FingerprintDaemonProxy* getInstance() { @@ -45,17 +47,16 @@ class FingerprintDaemonProxy : public BnFingerprintDaemon { virtual int32_t setActiveGroup(int32_t groupId, const uint8_t* path, ssize_t pathLen); virtual int64_t openHal(); virtual int32_t closeHal(); + static void hal_notify_callback(const hardware::biometrics::fingerprint::V2_1::FingerprintMsg &msg); private: FingerprintDaemonProxy(); virtual ~FingerprintDaemonProxy(); void binderDied(const wp& who); void notifyKeystore(const uint8_t *auth_token, const size_t auth_token_length); - static void hal_notify_callback(const fingerprint_msg_t *msg); + int32_t HandleTransportError(const RequestStatus error); static FingerprintDaemonProxy* sInstance; - fingerprint_module_t const* mModule; - fingerprint_device_t* mDevice; sp mCallback; }; diff --git a/fingerprintd/IFingerprintDaemon.h b/fingerprintd/IFingerprintDaemon.h index 23c36ff87..c5cdbfe18 100644 --- a/fingerprintd/IFingerprintDaemon.h +++ b/fingerprintd/IFingerprintDaemon.h @@ -17,6 +17,8 @@ #ifndef IFINGERPRINT_DAEMON_H_ #define IFINGERPRINT_DAEMON_H_ +#include +#include #include #include @@ -69,7 +71,7 @@ class IFingerprintDaemon : public IInterface, public IBinder::DeathRecipient { // DECLARE_META_INTERFACE - C++ client interface not needed static const android::String16 descriptor; - static void hal_notify_callback(const fingerprint_msg_t *msg); + static void hal_notify_callback(const hardware::biometrics::fingerprint::V2_1::FingerprintMsg &msg); }; // ----------------------------------------------------------------------------