From a34dc46c360d42d843f5fcba22d35862139bacee Mon Sep 17 00:00:00 2001 From: Jim Miller Date: Thu, 7 May 2015 18:52:53 -0700 Subject: [PATCH] Move from native FingerprintService implementation to fingerprintd This adds a new service, fingerprintd, that manages fingerprint hardware from a separate process. It provides a binder interface that FingerprintManager uses to talk to the fingerprint HAL. Change-Id: I64b92589f4d75743ebe96894f07bec515945c61e --- fingerprintd/Android.mk | 33 +++ fingerprintd/FingerprintDaemonProxy.cpp | 238 ++++++++++++++++++++ fingerprintd/FingerprintDaemonProxy.h | 62 +++++ fingerprintd/IFingerprintDaemon.cpp | 186 +++++++++++++++ fingerprintd/IFingerprintDaemon.h | 84 +++++++ fingerprintd/IFingerprintDaemonCallback.cpp | 91 ++++++++ fingerprintd/IFingerprintDaemonCallback.h | 55 +++++ fingerprintd/fingerprintd.cpp | 55 +++++ 8 files changed, 804 insertions(+) create mode 100644 fingerprintd/Android.mk create mode 100644 fingerprintd/FingerprintDaemonProxy.cpp create mode 100644 fingerprintd/FingerprintDaemonProxy.h create mode 100644 fingerprintd/IFingerprintDaemon.cpp create mode 100644 fingerprintd/IFingerprintDaemon.h create mode 100644 fingerprintd/IFingerprintDaemonCallback.cpp create mode 100644 fingerprintd/IFingerprintDaemonCallback.h create mode 100644 fingerprintd/fingerprintd.cpp diff --git a/fingerprintd/Android.mk b/fingerprintd/Android.mk new file mode 100644 index 000000000..48b95258a --- /dev/null +++ b/fingerprintd/Android.mk @@ -0,0 +1,33 @@ +# +# 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. +# + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_CFLAGS := -Wall -Wextra -Werror -Wunused +LOCAL_SRC_FILES := \ + FingerprintDaemonProxy.cpp \ + IFingerprintDaemon.cpp \ + IFingerprintDaemonCallback.cpp \ + fingerprintd.cpp +LOCAL_MODULE := fingerprintd +LOCAL_SHARED_LIBRARIES := \ + libbinder \ + liblog \ + libhardware \ + libutils \ + libkeystore_binder +include $(BUILD_EXECUTABLE) diff --git a/fingerprintd/FingerprintDaemonProxy.cpp b/fingerprintd/FingerprintDaemonProxy.cpp new file mode 100644 index 000000000..2091a2c56 --- /dev/null +++ b/fingerprintd/FingerprintDaemonProxy.cpp @@ -0,0 +1,238 @@ +/* + * 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_TAG "fingerprintd" + +#include +#include +#include +#include +#include +#include // for error codes +#include + +#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(fingerprint_msg_t msg) { + FingerprintDaemonProxy* instance = FingerprintDaemonProxy::getInstance(); + const sp 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: + ALOGD("onError(%d)", msg.data.error); + callback->onError(device, msg.data.error); + break; + case FINGERPRINT_ACQUIRED: + ALOGD("onAcquired(%d)", msg.data.acquired.acquired_info); + callback->onAcquired(device, msg.data.acquired.acquired_info); + break; + case FINGERPRINT_AUTHENTICATED: + ALOGD("onAuthenticated(fid=%d, gid=%d)", + msg.data.authenticated.finger.fid, + msg.data.authenticated.finger.gid); + if (msg.data.authenticated.finger.fid != 0) { + 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); + break; + case FINGERPRINT_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); + break; + case FINGERPRINT_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); + break; + default: + ALOGE("invalid msg: %d", msg.type); + return; + } +} + +void FingerprintDaemonProxy::notifyKeystore(uint8_t *auth_token, 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 != ResponseCode::NO_ERROR) { + ALOGE("Falure sending auth token to KeyStore: %d", ret); + } + } else { + ALOGE("Unable to communicate with KeyStore"); + } + } +} + +void FingerprintDaemonProxy::init(const sp& 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) { + 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 %d\n", tokenSize); + return -1; + } + const hw_auth_token_t* authToken = reinterpret_cast(token); + return mDevice->enroll(mDevice, authToken, groupId, timeout); +} + +uint64_t FingerprintDaemonProxy::preEnroll() { + return mDevice->pre_enroll(mDevice); +} + +int32_t FingerprintDaemonProxy::stopEnrollment() { + ALOG(LOG_VERBOSE, LOG_TAG, "stopEnrollment()\n"); + return mDevice->cancel(mDevice); +} + +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); +} + +int32_t FingerprintDaemonProxy::stopAuthentication() { + ALOG(LOG_VERBOSE, LOG_TAG, "stopAuthentication()\n"); + return mDevice->cancel(mDevice); +} + +int32_t FingerprintDaemonProxy::remove(int32_t fingerId, int32_t groupId) { + ALOG(LOG_VERBOSE, LOG_TAG, "remove(fid=%d, gid=%d)\n", fingerId, groupId); + fingerprint_finger_id_t finger; + finger.fid = fingerId; + finger.gid = groupId; + return mDevice->remove(mDevice, finger); +} + +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) { + ALOGE("Path name is too long\n"); + 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, %d)", groupId, path_name, pathlen); + return mDevice->set_active_group(mDevice, groupId, path_name); + return -1; +} + +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 (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 +} + +int32_t FingerprintDaemonProxy::closeHal() { + return -ENOSYS; // TODO +} + +void FingerprintDaemonProxy::binderDied(const wp& who) { + ALOGD("binder died"); + if (IInterface::asBinder(mCallback) == who) { + mCallback = NULL; + } +} + +} diff --git a/fingerprintd/FingerprintDaemonProxy.h b/fingerprintd/FingerprintDaemonProxy.h new file mode 100644 index 000000000..95c926bda --- /dev/null +++ b/fingerprintd/FingerprintDaemonProxy.h @@ -0,0 +1,62 @@ +/* + * 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& 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 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 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& who); + void notifyKeystore(uint8_t *auth_token, size_t auth_token_length); + static void hal_notify_callback(fingerprint_msg_t msg); + + static FingerprintDaemonProxy* sInstance; + fingerprint_module_t const* mModule; + fingerprint_device_t* mDevice; + sp mCallback; +}; + +} // namespace android + +#endif // FINGERPRINT_DAEMON_PROXY_H_ diff --git a/fingerprintd/IFingerprintDaemon.cpp b/fingerprintd/IFingerprintDaemon.cpp new file mode 100644 index 000000000..112097984 --- /dev/null +++ b/fingerprintd/IFingerprintDaemon.cpp @@ -0,0 +1,186 @@ +/* + * 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. +*/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include // for error code +#include +#include +#include +#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"); + +const android::String16 +IFingerprintDaemon::descriptor("android.hardware.fingerprint.IFingerprintDaemon"); + +const android::String16& +IFingerprintDaemon::getInterfaceDescriptor() const { + return IFingerprintDaemon::descriptor; +} + +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(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 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 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(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 callback = + interface_cast(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); +} + + +}; // namespace android diff --git a/fingerprintd/IFingerprintDaemon.h b/fingerprintd/IFingerprintDaemon.h new file mode 100644 index 000000000..fe3f64b93 --- /dev/null +++ b/fingerprintd/IFingerprintDaemon.h @@ -0,0 +1,84 @@ +/* + * 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 +#include + +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, + }; + + IFingerprintDaemon() { } + virtual ~IFingerprintDaemon() { } + virtual const android::String16& getInterfaceDescriptor() const; + + // Binder interface methods + virtual void init(const sp& 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 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 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 - C++ client interface not needed + static const android::String16 descriptor; + static void hal_notify_callback(fingerprint_msg_t msg); +}; + +// ---------------------------------------------------------------------------- + +class BnFingerprintDaemon: public BnInterface { + 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_ + diff --git a/fingerprintd/IFingerprintDaemonCallback.cpp b/fingerprintd/IFingerprintDaemonCallback.cpp new file mode 100644 index 000000000..44d8020ae --- /dev/null +++ b/fingerprintd/IFingerprintDaemonCallback.cpp @@ -0,0 +1,91 @@ +/* + * 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_TAG "IFingerprintDaemonCallback" +#include +#include +#include +#include + +#include "IFingerprintDaemonCallback.h" + +namespace android { + +class BpFingerprintDaemonCallback : public BpInterface +{ +public: + BpFingerprintDaemonCallback(const sp& impl) : + BpInterface(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, const int32_t* fpIds, const int32_t* gpIds, + int32_t sz) { + Parcel data, reply; + data.writeInterfaceToken(IFingerprintDaemonCallback::getInterfaceDescriptor()); + data.writeInt64(devId); + data.writeInt32Array(sz, fpIds); + data.writeInt32Array(sz, gpIds); + return remote()->transact(ON_ENUMERATE, data, &reply, IBinder::FLAG_ONEWAY); + } +}; + +IMPLEMENT_META_INTERFACE(FingerprintDaemonCallback, + "android.hardware.fingerprint.IFingerprintDaemonCallback"); + +}; // namespace android diff --git a/fingerprintd/IFingerprintDaemonCallback.h b/fingerprintd/IFingerprintDaemonCallback.h new file mode 100644 index 000000000..6e32213b4 --- /dev/null +++ b/fingerprintd/IFingerprintDaemonCallback.h @@ -0,0 +1,55 @@ +/* + * 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 +#include +#include +#include + +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, const int32_t* fpIds, const int32_t* gpIds, + int32_t sz) = 0; + + DECLARE_META_INTERFACE(FingerprintDaemonCallback); +}; + +}; // namespace android + +#endif // IFINGERPRINT_DAEMON_CALLBACK_H_ diff --git a/fingerprintd/fingerprintd.cpp b/fingerprintd/fingerprintd.cpp new file mode 100644 index 000000000..8fa7ed18e --- /dev/null +++ b/fingerprintd/fingerprintd.cpp @@ -0,0 +1,55 @@ +/* + * 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_TAG "fingerprintd" + +#include +#include + +#include +#include +#include +#include + +#include +#include // for error codes + +#include +#include +#include + +#include "FingerprintDaemonProxy.h" + +int main() { + ALOGI("Starting " LOG_TAG); + android::sp serviceManager = android::defaultServiceManager(); + android::sp 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; + } + + /* + * We're the only thread in existence, so we're just going to process + * Binder transaction as a single-threaded program. + */ + android::IPCThreadState::self()->joinThreadPool(); + ALOGI("Done"); + return 0; +}