msm8937-common: Add custom biometrics

This commit is contained in:
TheScarastic 2017-12-16 17:05:08 +05:30 committed by Isaac Chen
parent d8d90bde50
commit 265678c804
17 changed files with 1766 additions and 7 deletions

31
biometrics/Android.mk Normal file
View file

@ -0,0 +1,31 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := android.hardware.biometrics.fingerprint@2.1-service.xiaomi_msm8937
LOCAL_INIT_RC := android.hardware.biometrics.fingerprint@2.1-service.xiaomi_msm8937.rc
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_SRC_FILES := \
BiometricsFingerprint.cpp \
service.cpp \
fingerprintd/FingerprintDaemonCallbackProxy.cpp \
fingerprintd/FingerprintDaemonProxy.cpp \
fingerprintd/IFingerprintDaemonCallback.cpp \
fingerprintd/IFingerprintDaemon.cpp \
fingerprintd/wrapper.cpp
LOCAL_SHARED_LIBRARIES := \
libbinder \
libcutils \
liblog \
libhidlbase \
libhidltransport \
libhardware \
libutils \
libhwbinder \
libkeystore_binder \
android.hardware.biometrics.fingerprint@2.1 \
include $(BUILD_EXECUTABLE)
include $(call all-makefiles-under,$(LOCAL_PATH))

View file

@ -0,0 +1,369 @@
/*
* Copyright (C) 2017 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.
*/
#define LOG_TAG "android.hardware.biometrics.fingerprint@2.0-service"
#define LOG_VERBOSE "android.hardware.biometrics.fingerprint@2.0-service"
#include <hardware/hw_auth_token.h>
#include <hardware/hardware.h>
#include <hardware/fingerprint.h>
#include "BiometricsFingerprint.h"
#include <cutils/properties.h>
#include <inttypes.h>
#include <unistd.h>
fingerprint_device_t* getWrapperService(fingerprint_notify_t);
namespace android {
namespace hardware {
namespace biometrics {
namespace fingerprint {
namespace V2_1 {
namespace implementation {
// Supported fingerprint HAL version
static bool is_goodix = false;
using RequestStatus =
android::hardware::biometrics::fingerprint::V2_1::RequestStatus;
BiometricsFingerprint *BiometricsFingerprint::sInstance = nullptr;
BiometricsFingerprint::BiometricsFingerprint() : mClientCallback(nullptr), mDevice(nullptr) {
sInstance = this; // keep track of the most recent instance
char vend [PROPERTY_VALUE_MAX];
property_get("ro.boot.fpsensor", vend, NULL);
if (!strcmp(vend, "fpc")) {
is_goodix = false;
mDevice = openHal();
} else if (!strcmp(vend, "gdx")) {
is_goodix = true;
mDevice = getWrapperService(BiometricsFingerprint::notify);
}
if (!mDevice) {
ALOGE("Can't open HAL module");
}
}
BiometricsFingerprint::~BiometricsFingerprint() {
ALOGV("~BiometricsFingerprint()");
if (mDevice == nullptr) {
ALOGE("No valid device");
return;
}
int err;
if (0 != (err = mDevice->common.close(
reinterpret_cast<hw_device_t*>(mDevice)))) {
ALOGE("Can't close fingerprint module, error: %d", err);
return;
}
mDevice = nullptr;
}
Return<RequestStatus> BiometricsFingerprint::ErrorFilter(int32_t error) {
switch(error) {
case 0: return RequestStatus::SYS_OK;
case -2: return RequestStatus::SYS_ENOENT;
case -4: return RequestStatus::SYS_EINTR;
case -5: return RequestStatus::SYS_EIO;
case -11: return RequestStatus::SYS_EAGAIN;
case -12: return RequestStatus::SYS_ENOMEM;
case -13: return RequestStatus::SYS_EACCES;
case -14: return RequestStatus::SYS_EFAULT;
case -16: return RequestStatus::SYS_EBUSY;
case -22: return RequestStatus::SYS_EINVAL;
case -28: return RequestStatus::SYS_ENOSPC;
case -110: return RequestStatus::SYS_ETIMEDOUT;
default:
ALOGE("An unknown error returned from fingerprint vendor library: %d", error);
return RequestStatus::SYS_UNKNOWN;
}
}
// Translate from errors returned by traditional HAL (see fingerprint.h) to
// HIDL-compliant FingerprintError.
FingerprintError BiometricsFingerprint::VendorErrorFilter(int32_t error,
int32_t* vendorCode) {
*vendorCode = 0;
switch(error) {
case FINGERPRINT_ERROR_HW_UNAVAILABLE:
return FingerprintError::ERROR_HW_UNAVAILABLE;
case FINGERPRINT_ERROR_UNABLE_TO_PROCESS:
return FingerprintError::ERROR_UNABLE_TO_PROCESS;
case FINGERPRINT_ERROR_TIMEOUT:
return FingerprintError::ERROR_TIMEOUT;
case FINGERPRINT_ERROR_NO_SPACE:
return FingerprintError::ERROR_NO_SPACE;
case FINGERPRINT_ERROR_CANCELED:
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.
*vendorCode = error - FINGERPRINT_ERROR_VENDOR_BASE;
return FingerprintError::ERROR_VENDOR;
}
}
ALOGE("Unknown error from fingerprint vendor library: %d", error);
return FingerprintError::ERROR_UNABLE_TO_PROCESS;
}
// Translate acquired messages returned by traditional HAL (see fingerprint.h)
// to HIDL-compliant FingerprintAcquiredInfo.
FingerprintAcquiredInfo BiometricsFingerprint::VendorAcquiredFilter(
int32_t info, int32_t* vendorCode) {
*vendorCode = 0;
switch(info) {
case FINGERPRINT_ACQUIRED_GOOD:
return FingerprintAcquiredInfo::ACQUIRED_GOOD;
case FINGERPRINT_ACQUIRED_PARTIAL:
return FingerprintAcquiredInfo::ACQUIRED_PARTIAL;
case FINGERPRINT_ACQUIRED_INSUFFICIENT:
return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT;
case FINGERPRINT_ACQUIRED_IMAGER_DIRTY:
return FingerprintAcquiredInfo::ACQUIRED_IMAGER_DIRTY;
case FINGERPRINT_ACQUIRED_TOO_SLOW:
return FingerprintAcquiredInfo::ACQUIRED_TOO_SLOW;
case FINGERPRINT_ACQUIRED_TOO_FAST:
return FingerprintAcquiredInfo::ACQUIRED_TOO_FAST;
default:
if (info >= FINGERPRINT_ACQUIRED_VENDOR_BASE) {
// vendor specific code.
*vendorCode = info - FINGERPRINT_ACQUIRED_VENDOR_BASE;
return FingerprintAcquiredInfo::ACQUIRED_VENDOR;
}
}
ALOGE("Unknown acquiredmsg from fingerprint vendor library: %d", info);
return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT;
}
Return<uint64_t> BiometricsFingerprint::setNotify(
const sp<IBiometricsFingerprintClientCallback>& 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<uint64_t>(mDevice);
}
Return<uint64_t> BiometricsFingerprint::preEnroll() {
return mDevice->pre_enroll(mDevice);
}
Return<RequestStatus> BiometricsFingerprint::enroll(const hidl_array<uint8_t, 69>& hat,
uint32_t gid, uint32_t timeoutSec) {
const hw_auth_token_t* authToken =
reinterpret_cast<const hw_auth_token_t*>(hat.data());
return ErrorFilter(mDevice->enroll(mDevice, authToken, gid, timeoutSec));
}
Return<RequestStatus> BiometricsFingerprint::postEnroll() {
return ErrorFilter(mDevice->post_enroll(mDevice));
}
Return<uint64_t> BiometricsFingerprint::getAuthenticatorId() {
return mDevice->get_authenticator_id(mDevice);
}
Return<RequestStatus> BiometricsFingerprint::cancel() {
fingerprint_msg_t msg;
msg.type = FINGERPRINT_ERROR;
msg.data.error = FINGERPRINT_ERROR_CANCELED;
mDevice->notify(&msg);
return ErrorFilter(mDevice->cancel(mDevice));
}
#define MAX_FINGERPRINTS 100
typedef int (*enumerate_2_0)(struct fingerprint_device *dev, fingerprint_finger_id_t *results,
uint32_t *max_size);
Return<RequestStatus> BiometricsFingerprint::enumerate() {
fingerprint_finger_id_t results[MAX_FINGERPRINTS];
uint32_t n = MAX_FINGERPRINTS;
enumerate_2_0 enumerate = (enumerate_2_0) mDevice->enumerate;
int ret = enumerate(mDevice, results, &n);
if (ret == 0 && mClientCallback != nullptr) {
ALOGD("Got %d enumerated templates", n);
for (uint32_t i = 0; i < n; i++) {
const uint64_t devId = reinterpret_cast<uint64_t>(mDevice);
const auto& fp = results[i];
ALOGD("onEnumerate(fid=%d, gid=%d)", fp.fid, fp.gid);
if (!mClientCallback->onEnumerate(devId, fp.fid, fp.gid, n - i - 1).isOk()) {
ALOGE("failed to invoke fingerprint onEnumerate callback");
}
}
}
return ErrorFilter(ret);
}
Return<RequestStatus> BiometricsFingerprint::remove(uint32_t gid, uint32_t fid) {
return ErrorFilter(mDevice->remove(mDevice, gid, fid));
}
Return<RequestStatus> BiometricsFingerprint::setActiveGroup(uint32_t gid,
const hidl_string& storePath) {
if (storePath.size() >= PATH_MAX || storePath.size() <= 0) {
ALOGE("Bad path length: %zd", storePath.size());
return RequestStatus::SYS_EINVAL;
}
if (access(storePath.c_str(), W_OK)) {
return RequestStatus::SYS_EINVAL;
}
int ret = mDevice->set_active_group(mDevice, gid, storePath.c_str());
if ((ret > 0) && is_goodix)
ret = 0;
return ErrorFilter(ret);
}
Return<RequestStatus> BiometricsFingerprint::authenticate(uint64_t operationId,
uint32_t gid) {
return ErrorFilter(mDevice->authenticate(mDevice, operationId, gid));
}
IBiometricsFingerprint* BiometricsFingerprint::getInstance() {
if (!sInstance) {
sInstance = new BiometricsFingerprint();
}
return sInstance;
}
fingerprint_device_t* BiometricsFingerprint::openHal() {
int err;
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 == nullptr) {
ALOGE("No valid fingerprint module");
return nullptr;
}
fingerprint_module_t const *module =
reinterpret_cast<const fingerprint_module_t*>(hw_mdl);
if (module->common.methods->open == nullptr) {
ALOGE("No valid open method");
return nullptr;
}
hw_device_t *device = nullptr;
if (0 != (err = module->common.methods->open(hw_mdl, nullptr, &device))) {
ALOGE("Can't open fingerprint methods, error: %d", err);
return nullptr;
}
fingerprint_device_t* fp_device =
reinterpret_cast<fingerprint_device_t*>(device);
if (0 != (err =
fp_device->set_notify(fp_device, BiometricsFingerprint::notify))) {
ALOGE("Can't register fingerprint module callback, error: %d", err);
return nullptr;
}
return fp_device;
}
void BiometricsFingerprint::notify(const fingerprint_msg_t *msg) {
BiometricsFingerprint* thisPtr = static_cast<BiometricsFingerprint*>(
BiometricsFingerprint::getInstance());
if (thisPtr == nullptr || thisPtr->mClientCallback == nullptr) {
ALOGE("Receiving callbacks before the client callback is registered.");
return;
}
const uint64_t devId = reinterpret_cast<uint64_t>(thisPtr->mDevice);
switch (msg->type) {
case FINGERPRINT_ERROR: {
int32_t vendorCode = 0;
FingerprintError result = VendorErrorFilter(msg->data.error, &vendorCode);
if (!thisPtr->mClientCallback->onError(devId, result, vendorCode).isOk()) {
ALOGE("failed to invoke fingerprint onError callback");
}
}
break;
case FINGERPRINT_ACQUIRED: {
int32_t vendorCode = 0;
FingerprintAcquiredInfo result =
VendorAcquiredFilter(msg->data.acquired.acquired_info, &vendorCode);
if (!thisPtr->mClientCallback->onAcquired(devId, result, vendorCode).isOk()) {
ALOGE("failed to invoke fingerprint onAcquired callback");
}
}
break;
case FINGERPRINT_TEMPLATE_ENROLLING:
if (!thisPtr->mClientCallback->onEnrollResult(devId,
msg->data.enroll.finger.fid,
msg->data.enroll.finger.gid,
msg->data.enroll.samples_remaining).isOk()) {
ALOGE("failed to invoke fingerprint onEnrollResult callback");
}
break;
case FINGERPRINT_TEMPLATE_REMOVED:
if (!thisPtr->mClientCallback->onRemoved(devId,
msg->data.removed.finger.fid,
msg->data.removed.finger.gid,
msg->data.removed.remaining_templates).isOk()) {
ALOGE("failed to invoke fingerprint onRemoved callback");
}
break;
case FINGERPRINT_AUTHENTICATED:
if (msg->data.authenticated.finger.fid != 0) {
const uint8_t* hat =
reinterpret_cast<const uint8_t *>(&msg->data.authenticated.hat);
const hidl_vec<uint8_t> token(
std::vector<uint8_t>(hat, hat + sizeof(msg->data.authenticated.hat)));
if (!thisPtr->mClientCallback->onAuthenticated(devId,
msg->data.authenticated.finger.fid,
msg->data.authenticated.finger.gid,
token).isOk()) {
ALOGE("failed to invoke fingerprint onAuthenticated callback");
}
} else {
// Not a recognized fingerprint
if (!thisPtr->mClientCallback->onAuthenticated(devId,
msg->data.authenticated.finger.fid,
msg->data.authenticated.finger.gid,
hidl_vec<uint8_t>()).isOk()) {
ALOGE("failed to invoke fingerprint onAuthenticated callback");
}
}
break;
case FINGERPRINT_TEMPLATE_ENUMERATING:
// ignored, won't happen for 2.0 HALs
break;
}
}
} // namespace implementation
} // namespace V2_1
} // namespace fingerprint
} // namespace biometrics
} // namespace hardware
} // namespace android

View file

@ -0,0 +1,83 @@
/*
* Copyright (C) 2017 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.
*/
#ifndef ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_1_BIOMETRICSFINGERPRINT_H
#define ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_1_BIOMETRICSFINGERPRINT_H
#include <log/log.h>
#include <android/log.h>
#include <hardware/hardware.h>
#include <hardware/fingerprint.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
#include <android/hardware/biometrics/fingerprint/2.1/IBiometricsFingerprint.h>
namespace android {
namespace hardware {
namespace biometrics {
namespace fingerprint {
namespace V2_1 {
namespace implementation {
using ::android::hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprint;
using ::android::hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprintClientCallback;
using ::android::hardware::biometrics::fingerprint::V2_1::RequestStatus;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::hidl_vec;
using ::android::hardware::hidl_string;
using ::android::sp;
struct BiometricsFingerprint : public IBiometricsFingerprint {
public:
BiometricsFingerprint();
~BiometricsFingerprint();
// Method to wrap legacy HAL with BiometricsFingerprint class
static IBiometricsFingerprint* getInstance();
// Methods from ::android::hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprint follow.
Return<uint64_t> setNotify(const sp<IBiometricsFingerprintClientCallback>& clientCallback) override;
Return<uint64_t> preEnroll() override;
Return<RequestStatus> enroll(const hidl_array<uint8_t, 69>& hat, uint32_t gid, uint32_t timeoutSec) override;
Return<RequestStatus> postEnroll() override;
Return<uint64_t> getAuthenticatorId() override;
Return<RequestStatus> cancel() override;
Return<RequestStatus> enumerate() override;
Return<RequestStatus> remove(uint32_t gid, uint32_t fid) override;
Return<RequestStatus> setActiveGroup(uint32_t gid, const hidl_string& storePath) override;
Return<RequestStatus> authenticate(uint64_t operationId, uint32_t gid) override;
private:
static fingerprint_device_t* openHal();
static void notify(const fingerprint_msg_t *msg); /* Static callback for legacy HAL implementation */
static Return<RequestStatus> 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<IBiometricsFingerprintClientCallback> mClientCallback;
fingerprint_device_t *mDevice;
};
} // namespace implementation
} // namespace V2_1
} // namespace fingerprint
} // namespace biometrics
} // namespace hardware
} // namespace android
#endif // ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_1_BIOMETRICSFINGERPRINT_H

View file

@ -0,0 +1,8 @@
service fps_hal /vendor/bin/hw/android.hardware.biometrics.fingerprint@2.1-service.xiaomi_msm8937
# "class hal" causes a race condition on some devices due to files created
# in /data. As a workaround, postpone startup until later in boot once
# /data is mounted.
class late_start
user system
group system input
disabled

View file

@ -0,0 +1,132 @@
/*
* Copyright (C) 2017 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.
*/
#define LOG_NDEBUG 0
#define LOG_TAG "FingerprintDaemonCallbackProxy"
#include <stdlib.h>
#include <utils/String16.h>
#include <utils/Log.h>
#include <hardware/hardware.h>
#include <hardware/hw_auth_token.h>
#include <hardware/fingerprint.h>
#include "IFingerprintDaemonCallback.h"
#include "FingerprintDaemonCallbackProxy.h"
using namespace android;
fingerprint_notify_t FingerprintDaemonCallbackProxy::mNotify = NULL;
FingerprintDaemonCallbackProxy::FingerprintDaemonCallbackProxy() {
}
FingerprintDaemonCallbackProxy::~FingerprintDaemonCallbackProxy() {
}
status_t FingerprintDaemonCallbackProxy::onEnrollResult(int64_t devId, int32_t fpId, int32_t gpId,
int32_t rem) {
fingerprint_msg_t message;
message.type = FINGERPRINT_TEMPLATE_ENROLLING;
message.data.enroll.finger.fid = fpId;
message.data.enroll.finger.gid = gpId;
message.data.enroll.samples_remaining = rem;
if(mNotify != NULL) {
mNotify(&message);
} else {
ALOGE("onEnrollResult mDevice is NULL");
}
return 0;
}
status_t FingerprintDaemonCallbackProxy::onAcquired(int64_t devId, int32_t acquiredInfo) {
fingerprint_msg_t message;
message.type = FINGERPRINT_ACQUIRED;
message.data.acquired.acquired_info = (fingerprint_acquired_info_t)acquiredInfo;
if(mNotify != NULL) {
mNotify(&message);
} else {
ALOGE("onAcquired mDevice is NULL");
}
return 0;
}
status_t FingerprintDaemonCallbackProxy::onAuthenticated(int64_t devId, int32_t fingerId,
int32_t groupId) {
fingerprint_msg_t message;
message.type = FINGERPRINT_AUTHENTICATED;
message.data.authenticated.finger.fid = fingerId;
message.data.authenticated.finger.gid = groupId;
if(mNotify != NULL) {
mNotify(&message);
} else {
ALOGE("onAuthenticated mDevice is NULL");
}
return 0;
}
status_t FingerprintDaemonCallbackProxy::onError(int64_t devId, int32_t error) {
fingerprint_msg_t message;
message.type = FINGERPRINT_ERROR;
message.data.error = (fingerprint_error_t)error;
if(mNotify != NULL) {
mNotify(&message);
} else {
ALOGE("onError mDevice is NULL");
}
return 0;
}
status_t FingerprintDaemonCallbackProxy::onRemoved(int64_t devId,
int32_t fingerId, int32_t groupId) {
fingerprint_msg_t message;
message.type = FINGERPRINT_TEMPLATE_REMOVED;
message.data.removed.finger.fid = fingerId;
message.data.removed.finger.gid = groupId;
if(mNotify != NULL) {
mNotify(&message);
} else {
ALOGE("onRemoved mDevice is NULL");
}
return 0;
}
status_t FingerprintDaemonCallbackProxy::onEnumerate(int64_t devId,
const int32_t fingerId, const int32_t groupId, int32_t remaining) {
fingerprint_msg_t message;
message.type = FINGERPRINT_TEMPLATE_ENUMERATING;
message.data.enumerated.finger.fid = fingerId;
message.data.enumerated.finger.gid = groupId;
message.data.enumerated.remaining_templates = remaining;
if(mNotify != NULL) {
mNotify(&message);
} else {
ALOGE("onEnumerate mDevice is NULL");
}
return 0;
}

View file

@ -0,0 +1,46 @@
/*
* Copyright (C) 2017 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.
*/
#ifndef FINGERPRINT_DAEMON_CALLBACK_PROXY_H_
#define FINGERPRINT_DAEMON_CALLBACK_PROXY_H_
#include <hardware/fingerprint.h>
#include "IFingerprintDaemonCallback.h"
namespace android {
class FingerprintDaemonCallbackProxy: public BnFingerprintDaemonCallback {
public:
virtual status_t onEnrollResult(int64_t devId, int32_t fpId, int32_t gpId, int32_t rem);
virtual status_t onAcquired(int64_t devId, int32_t acquiredInfo);
virtual status_t onAuthenticated(int64_t devId, int32_t fingerId, int32_t groupId);
virtual status_t onError(int64_t devId, int32_t error);
virtual status_t onRemoved(int64_t devId, int32_t fingerId, int32_t groupId);
virtual status_t onEnumerate(int64_t devId, const int32_t fpId, const int32_t gpId,
int32_t rem);
FingerprintDaemonCallbackProxy();
virtual ~FingerprintDaemonCallbackProxy();
static void setDevice(fingerprint_notify_t notify) {
mNotify = notify;
}
private:
static fingerprint_notify_t mNotify;
};
}
#endif // FINGERPRINT_DAEMON_CALLBACK_PROXY_H_

View file

@ -0,0 +1,249 @@
/*
* 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.
*/
#define LOG_NDEBUG 0
#define LOG_TAG "FingerprintDaemonProxy"
#include <cutils/properties.h>
#include <binder/IServiceManager.h>
#include <hardware/hardware.h>
#include <hardware/fingerprint.h>
#include <hardware/hw_auth_token.h>
#include <keystore/IKeystoreService.h>
#include <keystore/keystore.h> // for error codes
#include <utils/Log.h>
#include "FingerprintDaemonProxy.h"
namespace android {
FingerprintDaemonProxy* FingerprintDaemonProxy::sInstance = NULL;
// Supported fingerprint HAL version
static const uint16_t kVersion = HARDWARE_MODULE_API_VERSION(2, 0);
FingerprintDaemonProxy::FingerprintDaemonProxy() : mModule(NULL), mDevice(NULL), mCallback(NULL) {
}
FingerprintDaemonProxy::~FingerprintDaemonProxy() {
closeHal();
}
void FingerprintDaemonProxy::hal_notify_callback(const fingerprint_msg_t *msg) {
FingerprintDaemonProxy* instance = FingerprintDaemonProxy::getInstance();
const sp<IFingerprintDaemonCallback> callback = instance->mCallback;
if (callback == NULL) {
ALOGE("Invalid callback object");
return;
}
const int64_t device = (int64_t) instance->mDevice;
switch (msg->type) {
case FINGERPRINT_ERROR:
callback->onError(device, msg->data.error);
break;
case FINGERPRINT_ACQUIRED:
callback->onAcquired(device, msg->data.acquired.acquired_info);
break;
case FINGERPRINT_AUTHENTICATED:
if (msg->data.authenticated.finger.fid != 0) {
const uint8_t* hat = reinterpret_cast<const uint8_t *>(&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);
break;
case FINGERPRINT_TEMPLATE_ENROLLING:
callback->onEnrollResult(device,
msg->data.enroll.finger.fid,
msg->data.enroll.finger.gid,
msg->data.enroll.samples_remaining);
break;
case FINGERPRINT_TEMPLATE_REMOVED:
callback->onRemoved(device,
msg->data.removed.finger.fid,
msg->data.removed.finger.gid);
break;
case FINGERPRINT_TEMPLATE_ENUMERATING:
callback->onEnumerate(device,
msg->data.enumerated.finger.fid,
msg->data.enumerated.finger.gid,
msg->data.enumerated.remaining_templates);
break;
default:
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) {
// 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) {
status_t ret = service->addAuthToken(auth_token, auth_token_length);
if (ret != (int)ResponseCode::NO_ERROR) {
ALOGE("Falure sending auth token to KeyStore: %d", ret);
}
} else {
ALOGE("Unable to communicate with KeyStore");
}
}
}
void FingerprintDaemonProxy::init(const sp<IFingerprintDaemonCallback>& callback) {
if (mCallback != NULL && IInterface::asBinder(callback) != IInterface::asBinder(mCallback)) {
IInterface::asBinder(mCallback)->unlinkToDeath(this);
}
IInterface::asBinder(callback)->linkToDeath(this);
mCallback = callback;
}
int32_t FingerprintDaemonProxy::enroll(const uint8_t* token, ssize_t tokenSize, int32_t groupId,
int32_t timeout) {
if (tokenSize != sizeof(hw_auth_token_t) ) {
ALOGE("enroll() : invalid token size %zu\n", tokenSize);
return -1;
}
const hw_auth_token_t* authToken = reinterpret_cast<const hw_auth_token_t*>(token);
return mDevice->enroll(mDevice, authToken, groupId, timeout);
}
uint64_t FingerprintDaemonProxy::preEnroll() {
return mDevice->pre_enroll(mDevice);
}
int32_t FingerprintDaemonProxy::postEnroll() {
return mDevice->post_enroll(mDevice);
}
int32_t FingerprintDaemonProxy::stopEnrollment() {
return mDevice->cancel(mDevice);
}
int32_t FingerprintDaemonProxy::authenticate(uint64_t sessionId, uint32_t groupId) {
return mDevice->authenticate(mDevice, sessionId, groupId);
}
int32_t FingerprintDaemonProxy::stopAuthentication() {
return mDevice->cancel(mDevice);
}
int32_t FingerprintDaemonProxy::remove(int32_t fingerId, int32_t groupId) {
return mDevice->remove(mDevice, groupId, fingerId);
}
int32_t FingerprintDaemonProxy::enumerate() {
return mDevice->enumerate(mDevice);
}
int32_t FingerprintDaemonProxy::cancel() {
int ret = mDevice->cancel(mDevice);
return ret;
}
uint64_t FingerprintDaemonProxy::getAuthenticatorId() {
return mDevice->get_authenticator_id(mDevice);
}
int32_t FingerprintDaemonProxy::setActiveGroup(int32_t groupId, const uint8_t* path,
ssize_t pathlen) {
if (pathlen >= PATH_MAX || pathlen <= 0) {
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';
return mDevice->set_active_group(mDevice, groupId, path_name);
}
int64_t FingerprintDaemonProxy::openHal() {
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 (NULL == hw_module) {
ALOGE("No valid fingerprint module");
return 0;
}
mModule = reinterpret_cast<const fingerprint_module_t*>(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;
}
mDevice = reinterpret_cast<fingerprint_device_t*>(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);
}
ALOGE("fingerprint HAL successfully initialized");
return reinterpret_cast<int64_t>(mDevice); // This is just a handle
}
int32_t FingerprintDaemonProxy::closeHal() {
if (mDevice == NULL) {
ALOGE("No valid device");
return -ENOSYS;
}
int err;
if (0 != (err = mDevice->common.close(reinterpret_cast<hw_device_t*>(mDevice)))) {
ALOGE("Can't close fingerprint module, error: %d", err);
return err;
}
mDevice = NULL;
return 0;
}
void FingerprintDaemonProxy::binderDied(const wp<IBinder>& who) {
int err;
if (0 != (err = closeHal())) {
ALOGE("Can't close fingerprint device, error: %d", err);
}
if (IInterface::asBinder(mCallback) == who) {
mCallback = NULL;
}
}
}

View file

@ -0,0 +1,65 @@
/*
* 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.
*/
#ifndef FINGERPRINT_DAEMON_PROXY_H_
#define FINGERPRINT_DAEMON_PROXY_H_
#include "IFingerprintDaemon.h"
#include "IFingerprintDaemonCallback.h"
namespace android {
class FingerprintDaemonProxy : public BnFingerprintDaemon {
public:
static FingerprintDaemonProxy* getInstance() {
if (sInstance == NULL) {
sInstance = new FingerprintDaemonProxy();
}
return sInstance;
}
// These reflect binder methods.
virtual void init(const sp<IFingerprintDaemonCallback>& callback);
virtual int32_t enroll(const uint8_t* token, ssize_t tokenLength, int32_t groupId, int32_t timeout);
virtual uint64_t preEnroll();
virtual int32_t postEnroll();
virtual int32_t stopEnrollment();
virtual int32_t authenticate(uint64_t sessionId, uint32_t groupId);
virtual int32_t stopAuthentication();
virtual int32_t remove(int32_t fingerId, int32_t groupId);
virtual int32_t enumerate();
virtual int32_t cancel();
virtual uint64_t getAuthenticatorId();
virtual int32_t setActiveGroup(int32_t groupId, const uint8_t* path, ssize_t pathLen);
virtual int64_t openHal();
virtual int32_t closeHal();
private:
FingerprintDaemonProxy();
virtual ~FingerprintDaemonProxy();
void binderDied(const wp<IBinder>& who);
void notifyKeystore(const uint8_t *auth_token, const size_t auth_token_length);
static void hal_notify_callback(const fingerprint_msg_t *msg);
static FingerprintDaemonProxy* sInstance;
fingerprint_module_t const* mModule;
fingerprint_device_t* mDevice;
sp<IFingerprintDaemonCallback> mCallback;
};
} // namespace android
#endif // FINGERPRINT_DAEMON_PROXY_H_

View file

@ -0,0 +1,334 @@
/*
* Copyright 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.
*/
#define LOG_NDEBUG 0
#include <inttypes.h>
#define LOG_TAG "FingerprintDaemon"
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/PermissionCache.h>
#include <utils/String16.h>
#include <utils/Looper.h>
#include <keystore/IKeystoreService.h>
#include <keystore/keystore.h> // for error code
#include <hardware/hardware.h>
#include <hardware/fingerprint.h>
#include <hardware/hw_auth_token.h>
#include "IFingerprintDaemon.h"
#include "IFingerprintDaemonCallback.h"
namespace android {
static const String16 USE_FINGERPRINT_PERMISSION("android.permission.USE_FINGERPRINT");
static const String16 MANAGE_FINGERPRINT_PERMISSION("android.permission.MANAGE_FINGERPRINT");
static const String16 HAL_FINGERPRINT_PERMISSION("android.permission.MANAGE_FINGERPRINT"); // TODO
static const String16 DUMP_PERMISSION("android.permission.DUMP");
status_t BnFingerprintDaemon::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
uint32_t flags) {
switch(code) {
case AUTHENTICATE: {
CHECK_INTERFACE(IFingerprintDaemon, data, reply);
if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) {
return PERMISSION_DENIED;
}
const uint64_t sessionId = data.readInt64();
const uint32_t groupId = data.readInt32();
const int32_t ret = authenticate(sessionId, groupId);
reply->writeNoException();
reply->writeInt32(ret);
return NO_ERROR;
};
case CANCEL_AUTHENTICATION: {
CHECK_INTERFACE(IFingerprintDaemon, data, reply);
if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) {
return PERMISSION_DENIED;
}
const int32_t ret = stopAuthentication();
reply->writeNoException();
reply->writeInt32(ret);
return NO_ERROR;
}
case ENROLL: {
CHECK_INTERFACE(IFingerprintDaemon, data, reply);
if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) {
return PERMISSION_DENIED;
}
const ssize_t tokenSize = data.readInt32();
const uint8_t* token = static_cast<const uint8_t *>(data.readInplace(tokenSize));
const int32_t groupId = data.readInt32();
const int32_t timeout = data.readInt32();
const int32_t ret = enroll(token, tokenSize, groupId, timeout);
reply->writeNoException();
reply->writeInt32(ret);
return NO_ERROR;
}
case CANCEL_ENROLLMENT: {
CHECK_INTERFACE(IFingerprintDaemon, data, reply);
if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) {
return PERMISSION_DENIED;
}
const int32_t ret = stopEnrollment();
reply->writeNoException();
reply->writeInt32(ret);
return NO_ERROR;
}
case PRE_ENROLL: {
CHECK_INTERFACE(IFingerprintDaemon, data, reply);
if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) {
return PERMISSION_DENIED;
}
const uint64_t ret = preEnroll();
reply->writeNoException();
reply->writeInt64(ret);
return NO_ERROR;
}
case POST_ENROLL: {
CHECK_INTERFACE(IFingerprintDaemon, data, reply);
if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) {
return PERMISSION_DENIED;
}
const int32_t ret = postEnroll();
reply->writeNoException();
reply->writeInt32(ret);
return NO_ERROR;
}
case REMOVE: {
CHECK_INTERFACE(IFingerprintDaemon, data, reply);
if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) {
return PERMISSION_DENIED;
}
const int32_t fingerId = data.readInt32();
const int32_t groupId = data.readInt32();
const int32_t ret = remove(fingerId, groupId);
reply->writeNoException();
reply->writeInt32(ret);
return NO_ERROR;
}
case ENUMERATE: {
CHECK_INTERFACE(IFingerprintDaemon, data, reply);
if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) {
return PERMISSION_DENIED;
}
const int32_t ret = enumerate();
reply->writeNoException();
reply->writeInt32(ret);
return NO_ERROR;
}
case GET_AUTHENTICATOR_ID: {
CHECK_INTERFACE(IFingerprintDaemon, data, reply);
if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) {
return PERMISSION_DENIED;
}
const uint64_t ret = getAuthenticatorId();
reply->writeNoException();
reply->writeInt64(ret);
return NO_ERROR;
}
case SET_ACTIVE_GROUP: {
CHECK_INTERFACE(IFingerprintDaemon, data, reply);
if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) {
return PERMISSION_DENIED;
}
const int32_t group = data.readInt32();
const ssize_t pathSize = data.readInt32();
const uint8_t* path = static_cast<const uint8_t *>(data.readInplace(pathSize));
const int32_t ret = setActiveGroup(group, path, pathSize);
reply->writeNoException();
reply->writeInt32(ret);
return NO_ERROR;
}
case OPEN_HAL: {
CHECK_INTERFACE(IFingerprintDaemon, data, reply);
if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) {
return PERMISSION_DENIED;
}
const int64_t ret = openHal();
reply->writeNoException();
reply->writeInt64(ret);
return NO_ERROR;
}
case CLOSE_HAL: {
CHECK_INTERFACE(IFingerprintDaemon, data, reply);
if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) {
return PERMISSION_DENIED;
}
const int32_t ret = closeHal();
reply->writeNoException();
reply->writeInt32(ret);
return NO_ERROR;
}
case INIT: {
CHECK_INTERFACE(IFingerprintDaemon, data, reply);
if (!checkPermission(HAL_FINGERPRINT_PERMISSION)) {
return PERMISSION_DENIED;
}
sp<IFingerprintDaemonCallback> callback =
interface_cast<IFingerprintDaemonCallback>(data.readStrongBinder());
init(callback);
reply->writeNoException();
return NO_ERROR;
}
default:
return BBinder::onTransact(code, data, reply, flags);
}
};
bool BnFingerprintDaemon::checkPermission(const String16& permission) {
const IPCThreadState* ipc = IPCThreadState::self();
const int calling_pid = ipc->getCallingPid();
const int calling_uid = ipc->getCallingUid();
return PermissionCache::checkPermission(permission, calling_pid, calling_uid);
}
class BpFingerprintDaemon : public BpInterface<IFingerprintDaemon> {
public:
BpFingerprintDaemon(const sp<IBinder> & impl) :
BpInterface<IFingerprintDaemon>(impl) {
}
virtual void init(const sp<IFingerprintDaemonCallback>& callback) {
Parcel data, reply;
data.writeInterfaceToken(descriptor);
data.writeStrongBinder(callback->asBinder(callback));
remote()->transact(INIT, data, &reply);
reply.readExceptionCode();
return;
}
virtual int32_t enroll(const uint8_t* token, ssize_t tokenLength, int32_t groupId, int32_t timeout) {
Parcel data, reply;
data.writeInterfaceToken(descriptor);
data.writeInt32(tokenLength);
data.write(token, tokenLength);
data.writeInt32(groupId);
data.writeInt32(timeout);
remote()->transact(ENROLL, data, &reply);
reply.readExceptionCode();
return reply.readInt32();
}
virtual uint64_t preEnroll() {
Parcel data, reply;
data.writeInterfaceToken(descriptor);
remote()->transact(PRE_ENROLL, data, &reply);
reply.readExceptionCode();
return reply.readInt64();
}
virtual int32_t postEnroll() {
Parcel data, reply;
data.writeInterfaceToken(descriptor);
remote()->transact(POST_ENROLL, data, &reply);
reply.readExceptionCode();
return reply.readInt32();
}
virtual int32_t stopEnrollment() {
Parcel data, reply;
data.writeInterfaceToken(descriptor);
remote()->transact(CANCEL_ENROLLMENT, data, &reply);
reply.readExceptionCode();
return reply.readInt32();
}
virtual int32_t authenticate(uint64_t sessionId, uint32_t groupId) {
Parcel data, reply;
data.writeInterfaceToken(descriptor);
data.writeInt64(sessionId);
data.writeInt32(groupId);
remote()->transact(AUTHENTICATE, data, &reply);
reply.readExceptionCode();
return reply.readInt32();
}
virtual int32_t stopAuthentication() {
Parcel data, reply;
data.writeInterfaceToken(descriptor);
remote()->transact(CANCEL_AUTHENTICATION, data, &reply);
reply.readExceptionCode();
return reply.readInt32();
}
virtual int32_t remove(int32_t fingerId, int32_t groupId) {
Parcel data, reply;
data.writeInterfaceToken(descriptor);
data.writeInt32(fingerId);
data.writeInt32(groupId);
remote()->transact(REMOVE, data, &reply);
reply.readExceptionCode();
return reply.readInt32();
}
virtual int32_t enumerate() {
Parcel data, reply;
data.writeInterfaceToken(descriptor);
remote()->transact(ENUMERATE, data, &reply);
reply.readExceptionCode();
return reply.readInt32();
}
virtual uint64_t getAuthenticatorId() {
Parcel data, reply;
data.writeInterfaceToken(descriptor);
remote()->transact(GET_AUTHENTICATOR_ID, data, &reply);
reply.readExceptionCode();
return reply.readInt64();
}
virtual int32_t setActiveGroup(int32_t groupId, const uint8_t* path, ssize_t pathLen) {
Parcel data, reply;
data.writeInterfaceToken(descriptor);
data.writeInt32(groupId);
data.writeInt32(pathLen);
data.write(path, pathLen);
remote()->transact(SET_ACTIVE_GROUP, data, &reply);
reply.readExceptionCode();
return reply.readInt32();
}
virtual int64_t openHal() {
Parcel data, reply;
data.writeInterfaceToken(descriptor);
remote()->transact(OPEN_HAL, data, &reply);
reply.readExceptionCode();
return reply.readInt64();
}
virtual int32_t closeHal() {
Parcel data, reply;
data.writeInterfaceToken(descriptor);
remote()->transact(CLOSE_HAL, data, &reply);
reply.readExceptionCode();
return reply.readInt32();
}
virtual void binderDied(const wp<IBinder> __unused &who) {
ALOGE("binderDied()");
return;
}
virtual void hal_notify_callback(const fingerprint_msg_t __unused *msg) {
ALOGE("Daemon hal_notify_callback");
return;
}
};
IMPLEMENT_META_INTERFACE(FingerprintDaemon, "android.hardware.fingerprint.IFingerprintDaemon");
}; // namespace android

View file

@ -0,0 +1,89 @@
/*
* 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.
*/
#ifndef IFINGERPRINT_DAEMON_H_
#define IFINGERPRINT_DAEMON_H_
#include <binder/IInterface.h>
#include <binder/Parcel.h>
namespace android {
class IFingerprintDaemonCallback;
/*
* Abstract base class for native implementation of FingerprintService.
*
* Note: This must be kept manually in sync with IFingerprintDaemon.aidl
*/
class IFingerprintDaemon : public IInterface, public IBinder::DeathRecipient {
public:
enum {
AUTHENTICATE = IBinder::FIRST_CALL_TRANSACTION + 0,
CANCEL_AUTHENTICATION = IBinder::FIRST_CALL_TRANSACTION + 1,
ENROLL = IBinder::FIRST_CALL_TRANSACTION + 2,
CANCEL_ENROLLMENT = IBinder::FIRST_CALL_TRANSACTION + 3,
PRE_ENROLL = IBinder::FIRST_CALL_TRANSACTION + 4,
REMOVE = IBinder::FIRST_CALL_TRANSACTION + 5,
GET_AUTHENTICATOR_ID = IBinder::FIRST_CALL_TRANSACTION + 6,
SET_ACTIVE_GROUP = IBinder::FIRST_CALL_TRANSACTION + 7,
OPEN_HAL = IBinder::FIRST_CALL_TRANSACTION + 8,
CLOSE_HAL = IBinder::FIRST_CALL_TRANSACTION + 9,
INIT = IBinder::FIRST_CALL_TRANSACTION + 10,
POST_ENROLL = IBinder::FIRST_CALL_TRANSACTION + 11,
ENUMERATE = IBinder::FIRST_CALL_TRANSACTION + 12,
};
// IFingerprintDaemon() { }
// virtual ~IFingerprintDaemon() { }
// virtual const android::String16& getInterfaceDescriptor() const;
// Binder interface methods
virtual void init(const sp<IFingerprintDaemonCallback>& callback) = 0;
virtual int32_t enroll(const uint8_t* token, ssize_t tokenLength, int32_t groupId,
int32_t timeout) = 0;
virtual uint64_t preEnroll() = 0;
virtual int32_t postEnroll() = 0;
virtual int32_t stopEnrollment() = 0;
virtual int32_t authenticate(uint64_t sessionId, uint32_t groupId) = 0;
virtual int32_t stopAuthentication() = 0;
virtual int32_t remove(int32_t fingerId, int32_t groupId) = 0;
virtual int32_t enumerate() = 0;
virtual uint64_t getAuthenticatorId() = 0;
virtual int32_t setActiveGroup(int32_t groupId, const uint8_t* path, ssize_t pathLen) = 0;
virtual int64_t openHal() = 0;
virtual int32_t closeHal() = 0;
DECLARE_META_INTERFACE(FingerprintDaemon);
// DECLARE_META_INTERFACE - C++ client interface not needed
static void hal_notify_callback(const fingerprint_msg_t *msg);
};
// ----------------------------------------------------------------------------
class BnFingerprintDaemon: public BnInterface<IFingerprintDaemon> {
public:
virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
uint32_t flags = 0);
private:
bool checkPermission(const String16& permission);
};
} // namespace android
#endif // IFINGERPRINT_DAEMON_H_

View file

@ -0,0 +1,147 @@
/*
* 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.
*/
#define LOG_NDEBUG 0
#define LOG_TAG "IFingerprintDaemonCallback"
#include <stdint.h>
#include <sys/types.h>
#include <utils/Log.h>
#include <binder/Parcel.h>
#include "IFingerprintDaemonCallback.h"
namespace android {
status_t BnFingerprintDaemonCallback::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
uint32_t flags) {
switch (code) {
case ON_ENROLL_RESULT: {
CHECK_INTERFACE(IFingerprintDaemonCallback, data, reply);
int64_t devId = data.readInt64();
int32_t fpId = data.readInt32();
int32_t gpId = data.readInt32();
int32_t rem = data.readInt32();
onEnrollResult(devId, fpId, gpId, rem);
return NO_ERROR;
}
case ON_ACQUIRED: {
CHECK_INTERFACE(IFingerprintDaemonCallback, data, reply);
int64_t devId = data.readInt64();
int32_t acquiredInfo = data.readInt32();
onAcquired(devId, acquiredInfo);
return NO_ERROR;
}
case ON_AUTHENTICATED: {
CHECK_INTERFACE(IFingerprintDaemonCallback, data, reply);
int64_t devId = data.readInt64();
int32_t fpId = data.readInt32();
int32_t gpId = data.readInt32();
onAuthenticated(devId, fpId, gpId);
return NO_ERROR;
}
case ON_ERROR: {
CHECK_INTERFACE(IFingerprintDaemonCallback, data, reply);
int64_t devId = data.readInt64();
int32_t error = data.readInt32();
onError(devId, error);
return NO_ERROR;
}
case ON_REMOVED: {
CHECK_INTERFACE(IFingerprintDaemonCallback, data, reply);
int64_t devId = data.readInt64();
int32_t fpId = data.readInt32();
int32_t gpId = data.readInt32();
onRemoved(devId, fpId, gpId);
return NO_ERROR;
}
case ON_ENUMERATE: {
CHECK_INTERFACE(IFingerprintDaemonCallback, data, reply);
int64_t devId = data.readInt64();
int32_t fpId = data.readInt32();
int32_t gpId = data.readInt32();
int32_t rem = data.readInt32();
onEnumerate(devId, fpId, gpId, rem);
return NO_ERROR;
}
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
class BpFingerprintDaemonCallback : public BpInterface<IFingerprintDaemonCallback>
{
public:
BpFingerprintDaemonCallback(const sp<IBinder>& impl) :
BpInterface<IFingerprintDaemonCallback>(impl) {
}
virtual status_t onEnrollResult(int64_t devId, int32_t fpId, int32_t gpId, int32_t rem) {
Parcel data, reply;
data.writeInterfaceToken(IFingerprintDaemonCallback::getInterfaceDescriptor());
data.writeInt64(devId);
data.writeInt32(fpId);
data.writeInt32(gpId);
data.writeInt32(rem);
return remote()->transact(ON_ENROLL_RESULT, data, &reply, IBinder::FLAG_ONEWAY);
}
virtual status_t onAcquired(int64_t devId, int32_t acquiredInfo) {
Parcel data, reply;
data.writeInterfaceToken(IFingerprintDaemonCallback::getInterfaceDescriptor());
data.writeInt64(devId);
data.writeInt32(acquiredInfo);
return remote()->transact(ON_ACQUIRED, data, &reply, IBinder::FLAG_ONEWAY);
}
virtual status_t onAuthenticated(int64_t devId, int32_t fpId, int32_t gpId) {
Parcel data, reply;
data.writeInterfaceToken(IFingerprintDaemonCallback::getInterfaceDescriptor());
data.writeInt64(devId);
data.writeInt32(fpId);
data.writeInt32(gpId);
return remote()->transact(ON_AUTHENTICATED, data, &reply, IBinder::FLAG_ONEWAY);
}
virtual status_t onError(int64_t devId, int32_t error) {
Parcel data, reply;
data.writeInterfaceToken(IFingerprintDaemonCallback::getInterfaceDescriptor());
data.writeInt64(devId);
data.writeInt32(error);
return remote()->transact(ON_ERROR, data, &reply, IBinder::FLAG_ONEWAY);
}
virtual status_t onRemoved(int64_t devId, int32_t fpId, int32_t gpId) {
Parcel data, reply;
data.writeInterfaceToken(IFingerprintDaemonCallback::getInterfaceDescriptor());
data.writeInt64(devId);
data.writeInt32(fpId);
data.writeInt32(gpId);
return remote()->transact(ON_REMOVED, data, &reply, IBinder::FLAG_ONEWAY);
}
virtual status_t onEnumerate(int64_t devId, int32_t fpId, int32_t gpId, int32_t rem) {
Parcel data, reply;
data.writeInterfaceToken(IFingerprintDaemonCallback::getInterfaceDescriptor());
data.writeInt64(devId);
data.writeInt32(fpId);
data.writeInt32(gpId);
data.writeInt32(rem);
return remote()->transact(ON_ENUMERATE, data, &reply, IBinder::FLAG_ONEWAY);
}
};
IMPLEMENT_META_INTERFACE(FingerprintDaemonCallback,
"android.hardware.fingerprint.IFingerprintDaemonCallback");
}; // namespace android

View file

@ -0,0 +1,60 @@
/*
* 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.
*/
#ifndef IFINGERPRINT_DAEMON_CALLBACK_H_
#define IFINGERPRINT_DAEMON_CALLBACK_H_
#include <inttypes.h>
#include <utils/Errors.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
namespace android {
/*
* Communication channel back to FingerprintService.java
*/
class IFingerprintDaemonCallback : public IInterface {
public:
// must be kept in sync with IFingerprintService.aidl
enum {
ON_ENROLL_RESULT = IBinder::FIRST_CALL_TRANSACTION + 0,
ON_ACQUIRED = IBinder::FIRST_CALL_TRANSACTION + 1,
ON_AUTHENTICATED = IBinder::FIRST_CALL_TRANSACTION + 2,
ON_ERROR = IBinder::FIRST_CALL_TRANSACTION + 3,
ON_REMOVED = IBinder::FIRST_CALL_TRANSACTION + 4,
ON_ENUMERATE = IBinder::FIRST_CALL_TRANSACTION + 5,
};
virtual status_t onEnrollResult(int64_t devId, int32_t fpId, int32_t gpId, int32_t rem) = 0;
virtual status_t onAcquired(int64_t devId, int32_t acquiredInfo) = 0;
virtual status_t onAuthenticated(int64_t devId, int32_t fingerId, int32_t groupId) = 0;
virtual status_t onError(int64_t devId, int32_t error) = 0;
virtual status_t onRemoved(int64_t devId, int32_t fingerId, int32_t groupId) = 0;
virtual status_t onEnumerate(int64_t devId, int32_t fingerId, int32_t groupId, int32_t rem) = 0;
DECLARE_META_INTERFACE(FingerprintDaemonCallback);
};
class BnFingerprintDaemonCallback: public BnInterface<IFingerprintDaemonCallback> {
public:
virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
uint32_t flags = 0);
};
}; // namespace android
#endif // IFINGERPRINT_DAEMON_CALLBACK_H_

View file

@ -0,0 +1,78 @@
/*
* 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.
*/
#define LOG_NDEBUG 0
#define LOG_TAG "FingerprintHal"
#include <unistd.h>
#include <cutils/log.h>
#include <hardware/fingerprint.h>
#include <binder/IServiceManager.h>
#include "FingerprintDaemonProxy.h"
#include "IFingerprintDaemon.h"
#include "IFingerprintDaemonCallback.h"
#include "FingerprintDaemonCallbackProxy.h"
using namespace android;
sp<IFingerprintDaemon> g_service = NULL;
fingerprint_device_t* getWrapperService();
class BinderDiednotify: public IBinder::DeathRecipient {
public:
void binderDied(const wp<IBinder> __unused &who) {
ALOGE("binderDied");
g_service = NULL;
}
};
static sp<BinderDiednotify> gDeathRecipient = new BinderDiednotify();
fingerprint_device_t* getWrapperService(fingerprint_notify_t notify) {
int64_t ret = 0;
do {
if (g_service == NULL) {
ALOGE("getService g_servie is NULL");
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(android::FingerprintDaemonProxy::descriptor);
if (binder == NULL) {
ALOGE("getService failed");
sleep(1);
continue;
}
g_service = interface_cast<IFingerprintDaemon>(binder);
binder->linkToDeath(gDeathRecipient, NULL, 0);
if (g_service != NULL) {
ALOGE("getService succeed");
sp<android::FingerprintDaemonCallbackProxy> callback =
new FingerprintDaemonCallbackProxy();
FingerprintDaemonCallbackProxy::setDevice(notify);
g_service->init(callback);
ret = g_service->openHal();
if (ret == 0) {
ALOGE("getService openHal failed!");
g_service = NULL;
}
}
}
} while (0);
return reinterpret_cast<fingerprint_device_t*>(ret);
}

68
biometrics/service.cpp Normal file
View file

@ -0,0 +1,68 @@
/*
* Copyright (C) 2017 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.
*/
#define LOG_TAG "android.hardware.biometrics.fingerprint@2.1-service.xiaomi_msm8937"
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/PermissionCache.h>
#include <binder/ProcessState.h>
#include <utils/String16.h>
#include <keystore/keystore.h> // for error codes
#include <android/log.h>
#include <hidl/HidlSupport.h>
#include <hidl/HidlTransportSupport.h>
#include <android/hardware/biometrics/fingerprint/2.1/IBiometricsFingerprint.h>
#include <android/hardware/biometrics/fingerprint/2.1/types.h>
#include "BiometricsFingerprint.h"
#include "fingerprintd/FingerprintDaemonProxy.h"
using android::hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprint;
using android::hardware::biometrics::fingerprint::V2_1::implementation::BiometricsFingerprint;
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
using android::sp;
int main() {
ALOGE("Start fingerprintd");
android::sp<android::IServiceManager> serviceManager = android::defaultServiceManager();
android::sp<android::FingerprintDaemonProxy> proxy =
android::FingerprintDaemonProxy::getInstance();
android::status_t ret = serviceManager->addService(
android::FingerprintDaemonProxy::descriptor, proxy);
if (ret != android::OK) {
ALOGE("Couldn't register " LOG_TAG " binder service!");
return -1;
}
ALOGE("Start biometrics");
android::sp<IBiometricsFingerprint> bio = BiometricsFingerprint::getInstance();
configureRpcThreadpool(1, false /*callerWillJoin*/);
if (bio != nullptr) {
ret = bio->registerAsService();
if (ret != android::OK) {
ALOGE("Cannot register BiometricsFingerprint service: %d", ret);
}
} else {
ALOGE("Can't create instance of BiometricsFingerprint, nullptr");
}
android::IPCThreadState::self()->joinThreadPool(); // run binder service fingerprintd part
return 0; // should never get here
}

View file

@ -1,6 +1,6 @@
# Fingerprint
PRODUCT_PACKAGES += \
fingerprintd
android.hardware.biometrics.fingerprint@2.1-service.xiaomi_msm8937
# Permissions
PRODUCT_COPY_FILES += \

View file

@ -417,17 +417,14 @@ service gx_fpd /vendor/bin/gx_fpd
on property:persist.sys.fp.vendor=switchf
stop gx_fpd
setprop persist.sys.fp.vendor searchf
start fingerprintd
setprop ro.boot.fpsensor fpc
start fps_hal
on property:persist.sys.fp.vendor=goodix
setprop persist.sys.fp.onstart 1
setprop ro.boot.fpsensor gdx
on property:persist.sys.fp.onstart=1
start fingerprintd
on property:ro.boot.fpsensor=gdx
setprop ro.hardware.fingerprint goodix
start fps_hal
service time_daemon /vendor/bin/time_daemon
class main

View file

@ -1,3 +1,6 @@
# Biometric
/(vendor|system/vendor)/bin/hw/android\.hardware\.biometrics\.fingerprint@2\.1-service\.xiaomi_msm8937 u:object_r:hal_fingerprint_default_exec:s0
# Block devices
/dev/block/bootdevice/by-name/persist u:object_r:persist_block_device:s0
/dev/block/bootdevice/by-name/userdata u:object_r:userdata_block_device:s0