1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "fingerprintd" 18 19#include <binder/IServiceManager.h> 20#include <hardware/hardware.h> 21#include <hardware/fingerprint.h> 22#include <hardware/hw_auth_token.h> 23#include <keystore/IKeystoreService.h> 24#include <keystore/keystore.h> // for error codes 25#include <utils/Log.h> 26 27#include "FingerprintDaemonProxy.h" 28 29namespace android { 30 31FingerprintDaemonProxy* FingerprintDaemonProxy::sInstance = NULL; 32 33// Supported fingerprint HAL version 34static const uint16_t kVersion = HARDWARE_MODULE_API_VERSION(2, 0); 35 36FingerprintDaemonProxy::FingerprintDaemonProxy() : mModule(NULL), mDevice(NULL), mCallback(NULL) { 37 38} 39 40FingerprintDaemonProxy::~FingerprintDaemonProxy() { 41 closeHal(); 42} 43 44void FingerprintDaemonProxy::hal_notify_callback(const fingerprint_msg_t *msg) { 45 FingerprintDaemonProxy* instance = FingerprintDaemonProxy::getInstance(); 46 const sp<IFingerprintDaemonCallback> callback = instance->mCallback; 47 if (callback == NULL) { 48 ALOGE("Invalid callback object"); 49 return; 50 } 51 const int64_t device = (int64_t) instance->mDevice; 52 switch (msg->type) { 53 case FINGERPRINT_ERROR: 54 ALOGD("onError(%d)", msg->data.error); 55 callback->onError(device, msg->data.error); 56 break; 57 case FINGERPRINT_ACQUIRED: 58 ALOGD("onAcquired(%d)", msg->data.acquired.acquired_info); 59 callback->onAcquired(device, msg->data.acquired.acquired_info); 60 break; 61 case FINGERPRINT_AUTHENTICATED: 62 ALOGD("onAuthenticated(fid=%d, gid=%d)", 63 msg->data.authenticated.finger.fid, 64 msg->data.authenticated.finger.gid); 65 if (msg->data.authenticated.finger.fid != 0) { 66 const uint8_t* hat = reinterpret_cast<const uint8_t *>(&msg->data.authenticated.hat); 67 instance->notifyKeystore(hat, sizeof(msg->data.authenticated.hat)); 68 } 69 callback->onAuthenticated(device, 70 msg->data.authenticated.finger.fid, 71 msg->data.authenticated.finger.gid); 72 break; 73 case FINGERPRINT_TEMPLATE_ENROLLING: 74 ALOGD("onEnrollResult(fid=%d, gid=%d, rem=%d)", 75 msg->data.enroll.finger.fid, 76 msg->data.enroll.finger.gid, 77 msg->data.enroll.samples_remaining); 78 callback->onEnrollResult(device, 79 msg->data.enroll.finger.fid, 80 msg->data.enroll.finger.gid, 81 msg->data.enroll.samples_remaining); 82 break; 83 case FINGERPRINT_TEMPLATE_REMOVED: 84 ALOGD("onRemove(fid=%d, gid=%d)", 85 msg->data.removed.finger.fid, 86 msg->data.removed.finger.gid); 87 callback->onRemoved(device, 88 msg->data.removed.finger.fid, 89 msg->data.removed.finger.gid); 90 break; 91 default: 92 ALOGE("invalid msg type: %d", msg->type); 93 return; 94 } 95} 96 97void FingerprintDaemonProxy::notifyKeystore(const uint8_t *auth_token, const size_t auth_token_length) { 98 if (auth_token != NULL && auth_token_length > 0) { 99 // TODO: cache service? 100 sp < IServiceManager > sm = defaultServiceManager(); 101 sp < IBinder > binder = sm->getService(String16("android.security.keystore")); 102 sp < IKeystoreService > service = interface_cast < IKeystoreService > (binder); 103 if (service != NULL) { 104 status_t ret = service->addAuthToken(auth_token, auth_token_length); 105 if (ret != ResponseCode::NO_ERROR) { 106 ALOGE("Falure sending auth token to KeyStore: %d", ret); 107 } 108 } else { 109 ALOGE("Unable to communicate with KeyStore"); 110 } 111 } 112} 113 114void FingerprintDaemonProxy::init(const sp<IFingerprintDaemonCallback>& callback) { 115 if (mCallback != NULL && IInterface::asBinder(callback) != IInterface::asBinder(mCallback)) { 116 IInterface::asBinder(mCallback)->unlinkToDeath(this); 117 } 118 IInterface::asBinder(callback)->linkToDeath(this); 119 mCallback = callback; 120} 121 122int32_t FingerprintDaemonProxy::enroll(const uint8_t* token, ssize_t tokenSize, int32_t groupId, 123 int32_t timeout) { 124 ALOG(LOG_VERBOSE, LOG_TAG, "enroll(gid=%d, timeout=%d)\n", groupId, timeout); 125 if (tokenSize != sizeof(hw_auth_token_t) ) { 126 ALOG(LOG_VERBOSE, LOG_TAG, "enroll() : invalid token size %zu\n", tokenSize); 127 return -1; 128 } 129 const hw_auth_token_t* authToken = reinterpret_cast<const hw_auth_token_t*>(token); 130 return mDevice->enroll(mDevice, authToken, groupId, timeout); 131} 132 133uint64_t FingerprintDaemonProxy::preEnroll() { 134 return mDevice->pre_enroll(mDevice); 135} 136 137int32_t FingerprintDaemonProxy::postEnroll() { 138 return mDevice->post_enroll(mDevice); 139} 140 141int32_t FingerprintDaemonProxy::stopEnrollment() { 142 ALOG(LOG_VERBOSE, LOG_TAG, "stopEnrollment()\n"); 143 return mDevice->cancel(mDevice); 144} 145 146int32_t FingerprintDaemonProxy::authenticate(uint64_t sessionId, uint32_t groupId) { 147 ALOG(LOG_VERBOSE, LOG_TAG, "authenticate(sid=%" PRId64 ", gid=%d)\n", sessionId, groupId); 148 return mDevice->authenticate(mDevice, sessionId, groupId); 149} 150 151int32_t FingerprintDaemonProxy::stopAuthentication() { 152 ALOG(LOG_VERBOSE, LOG_TAG, "stopAuthentication()\n"); 153 return mDevice->cancel(mDevice); 154} 155 156int32_t FingerprintDaemonProxy::remove(int32_t fingerId, int32_t groupId) { 157 ALOG(LOG_VERBOSE, LOG_TAG, "remove(fid=%d, gid=%d)\n", fingerId, groupId); 158 return mDevice->remove(mDevice, groupId, fingerId); 159} 160 161uint64_t FingerprintDaemonProxy::getAuthenticatorId() { 162 return mDevice->get_authenticator_id(mDevice); 163} 164 165int32_t FingerprintDaemonProxy::setActiveGroup(int32_t groupId, const uint8_t* path, 166 ssize_t pathlen) { 167 if (pathlen >= PATH_MAX || pathlen <= 0) { 168 ALOGE("Bad path length: %zd", pathlen); 169 return -1; 170 } 171 // Convert to null-terminated string 172 char path_name[PATH_MAX]; 173 memcpy(path_name, path, pathlen); 174 path_name[pathlen] = '\0'; 175 ALOG(LOG_VERBOSE, LOG_TAG, "setActiveGroup(%d, %s, %zu)", groupId, path_name, pathlen); 176 return mDevice->set_active_group(mDevice, groupId, path_name); 177} 178 179int64_t FingerprintDaemonProxy::openHal() { 180 ALOG(LOG_VERBOSE, LOG_TAG, "nativeOpenHal()\n"); 181 int err; 182 const hw_module_t *hw_module = NULL; 183 if (0 != (err = hw_get_module(FINGERPRINT_HARDWARE_MODULE_ID, &hw_module))) { 184 ALOGE("Can't open fingerprint HW Module, error: %d", err); 185 return 0; 186 } 187 if (NULL == hw_module) { 188 ALOGE("No valid fingerprint module"); 189 return 0; 190 } 191 192 mModule = reinterpret_cast<const fingerprint_module_t*>(hw_module); 193 194 if (mModule->common.methods->open == NULL) { 195 ALOGE("No valid open method"); 196 return 0; 197 } 198 199 hw_device_t *device = NULL; 200 201 if (0 != (err = mModule->common.methods->open(hw_module, NULL, &device))) { 202 ALOGE("Can't open fingerprint methods, error: %d", err); 203 return 0; 204 } 205 206 if (kVersion != device->version) { 207 ALOGE("Wrong fp version. Expected %d, got %d", kVersion, device->version); 208 // return 0; // FIXME 209 } 210 211 mDevice = reinterpret_cast<fingerprint_device_t*>(device); 212 err = mDevice->set_notify(mDevice, hal_notify_callback); 213 if (err < 0) { 214 ALOGE("Failed in call to set_notify(), err=%d", err); 215 return 0; 216 } 217 218 // Sanity check - remove 219 if (mDevice->notify != hal_notify_callback) { 220 ALOGE("NOTIFY not set properly: %p != %p", mDevice->notify, hal_notify_callback); 221 } 222 223 ALOG(LOG_VERBOSE, LOG_TAG, "fingerprint HAL successfully initialized"); 224 return reinterpret_cast<int64_t>(mDevice); // This is just a handle 225} 226 227int32_t FingerprintDaemonProxy::closeHal() { 228 ALOG(LOG_VERBOSE, LOG_TAG, "nativeCloseHal()\n"); 229 if (mDevice == NULL) { 230 ALOGE("No valid device"); 231 return -ENOSYS; 232 } 233 int err; 234 if (0 != (err = mDevice->common.close(reinterpret_cast<hw_device_t*>(mDevice)))) { 235 ALOGE("Can't close fingerprint module, error: %d", err); 236 return err; 237 } 238 mDevice = NULL; 239 return 0; 240} 241 242void FingerprintDaemonProxy::binderDied(const wp<IBinder>& who) { 243 ALOGD("binder died"); 244 int err; 245 if (0 != (err = closeHal())) { 246 ALOGE("Can't close fingerprint device, error: %d", err); 247 } 248 if (IInterface::asBinder(mCallback) == who) { 249 mCallback = NULL; 250 } 251} 252 253} 254