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 29 namespace android { 30 31 FingerprintDaemonProxy* FingerprintDaemonProxy::sInstance = NULL; 32 33 // Supported fingerprint HAL version 34 static const uint16_t kVersion = HARDWARE_MODULE_API_VERSION(2, 0); 35 36 FingerprintDaemonProxy::FingerprintDaemonProxy() : mModule(NULL), mDevice(NULL), mCallback(NULL) { 37 38 } 39 40 FingerprintDaemonProxy::~FingerprintDaemonProxy() { 41 closeHal(); 42 } 43 44 void 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 case FINGERPRINT_TEMPLATE_ENUMERATING: 92 ALOGD("onEnumerate(fid=%d, gid=%d, rem=%d)", 93 msg->data.enumerated.finger.fid, 94 msg->data.enumerated.finger.gid, 95 msg->data.enumerated.remaining_templates); 96 callback->onEnumerate(device, 97 msg->data.enumerated.finger.fid, 98 msg->data.enumerated.finger.gid, 99 msg->data.enumerated.remaining_templates); 100 break; 101 default: 102 ALOGE("invalid msg type: %d", msg->type); 103 return; 104 } 105 } 106 107 void FingerprintDaemonProxy::notifyKeystore(const uint8_t *auth_token, const size_t auth_token_length) { 108 if (auth_token != NULL && auth_token_length > 0) { 109 // TODO: cache service? 110 sp < IServiceManager > sm = defaultServiceManager(); 111 sp < IBinder > binder = sm->getService(String16("android.security.keystore")); 112 sp < IKeystoreService > service = interface_cast < IKeystoreService > (binder); 113 if (service != NULL) { 114 status_t ret = service->addAuthToken(auth_token, auth_token_length); 115 if (ret != ResponseCode::NO_ERROR) { 116 ALOGE("Falure sending auth token to KeyStore: %d", ret); 117 } 118 } else { 119 ALOGE("Unable to communicate with KeyStore"); 120 } 121 } 122 } 123 124 void FingerprintDaemonProxy::init(const sp<IFingerprintDaemonCallback>& callback) { 125 if (mCallback != NULL && IInterface::asBinder(callback) != IInterface::asBinder(mCallback)) { 126 IInterface::asBinder(mCallback)->unlinkToDeath(this); 127 } 128 IInterface::asBinder(callback)->linkToDeath(this); 129 mCallback = callback; 130 } 131 132 int32_t FingerprintDaemonProxy::enroll(const uint8_t* token, ssize_t tokenSize, int32_t groupId, 133 int32_t timeout) { 134 ALOG(LOG_VERBOSE, LOG_TAG, "enroll(gid=%d, timeout=%d)\n", groupId, timeout); 135 if (tokenSize != sizeof(hw_auth_token_t) ) { 136 ALOG(LOG_VERBOSE, LOG_TAG, "enroll() : invalid token size %zu\n", tokenSize); 137 return -1; 138 } 139 const hw_auth_token_t* authToken = reinterpret_cast<const hw_auth_token_t*>(token); 140 return mDevice->enroll(mDevice, authToken, groupId, timeout); 141 } 142 143 uint64_t FingerprintDaemonProxy::preEnroll() { 144 return mDevice->pre_enroll(mDevice); 145 } 146 147 int32_t FingerprintDaemonProxy::postEnroll() { 148 return mDevice->post_enroll(mDevice); 149 } 150 151 int32_t FingerprintDaemonProxy::stopEnrollment() { 152 ALOG(LOG_VERBOSE, LOG_TAG, "stopEnrollment()\n"); 153 return mDevice->cancel(mDevice); 154 } 155 156 int32_t FingerprintDaemonProxy::authenticate(uint64_t sessionId, uint32_t groupId) { 157 ALOG(LOG_VERBOSE, LOG_TAG, "authenticate(sid=%" PRId64 ", gid=%d)\n", sessionId, groupId); 158 return mDevice->authenticate(mDevice, sessionId, groupId); 159 } 160 161 int32_t FingerprintDaemonProxy::stopAuthentication() { 162 ALOG(LOG_VERBOSE, LOG_TAG, "stopAuthentication()\n"); 163 return mDevice->cancel(mDevice); 164 } 165 166 int32_t FingerprintDaemonProxy::remove(int32_t fingerId, int32_t groupId) { 167 ALOG(LOG_VERBOSE, LOG_TAG, "remove(fid=%d, gid=%d)\n", fingerId, groupId); 168 return mDevice->remove(mDevice, groupId, fingerId); 169 } 170 171 int32_t FingerprintDaemonProxy::enumerate() { 172 ALOG(LOG_VERBOSE, LOG_TAG, "enumerate()\n"); 173 return mDevice->enumerate(mDevice); 174 } 175 176 uint64_t FingerprintDaemonProxy::getAuthenticatorId() { 177 return mDevice->get_authenticator_id(mDevice); 178 } 179 180 int32_t FingerprintDaemonProxy::setActiveGroup(int32_t groupId, const uint8_t* path, 181 ssize_t pathlen) { 182 if (pathlen >= PATH_MAX || pathlen <= 0) { 183 ALOGE("Bad path length: %zd", pathlen); 184 return -1; 185 } 186 // Convert to null-terminated string 187 char path_name[PATH_MAX]; 188 memcpy(path_name, path, pathlen); 189 path_name[pathlen] = '\0'; 190 ALOG(LOG_VERBOSE, LOG_TAG, "setActiveGroup(%d, %s, %zu)", groupId, path_name, pathlen); 191 return mDevice->set_active_group(mDevice, groupId, path_name); 192 } 193 194 int64_t FingerprintDaemonProxy::openHal() { 195 ALOG(LOG_VERBOSE, LOG_TAG, "nativeOpenHal()\n"); 196 int err; 197 const hw_module_t *hw_module = NULL; 198 if (0 != (err = hw_get_module(FINGERPRINT_HARDWARE_MODULE_ID, &hw_module))) { 199 ALOGE("Can't open fingerprint HW Module, error: %d", err); 200 return 0; 201 } 202 if (NULL == hw_module) { 203 ALOGE("No valid fingerprint module"); 204 return 0; 205 } 206 207 mModule = reinterpret_cast<const fingerprint_module_t*>(hw_module); 208 209 if (mModule->common.methods->open == NULL) { 210 ALOGE("No valid open method"); 211 return 0; 212 } 213 214 hw_device_t *device = NULL; 215 216 if (0 != (err = mModule->common.methods->open(hw_module, NULL, &device))) { 217 ALOGE("Can't open fingerprint methods, error: %d", err); 218 return 0; 219 } 220 221 if (kVersion != device->version) { 222 ALOGE("Wrong fp version. Expected %d, got %d", kVersion, device->version); 223 // return 0; // FIXME 224 } 225 226 mDevice = reinterpret_cast<fingerprint_device_t*>(device); 227 err = mDevice->set_notify(mDevice, hal_notify_callback); 228 if (err < 0) { 229 ALOGE("Failed in call to set_notify(), err=%d", err); 230 return 0; 231 } 232 233 // Sanity check - remove 234 if (mDevice->notify != hal_notify_callback) { 235 ALOGE("NOTIFY not set properly: %p != %p", mDevice->notify, hal_notify_callback); 236 } 237 238 ALOG(LOG_VERBOSE, LOG_TAG, "fingerprint HAL successfully initialized"); 239 return reinterpret_cast<int64_t>(mDevice); // This is just a handle 240 } 241 242 int32_t FingerprintDaemonProxy::closeHal() { 243 ALOG(LOG_VERBOSE, LOG_TAG, "nativeCloseHal()\n"); 244 if (mDevice == NULL) { 245 ALOGE("No valid device"); 246 return -ENOSYS; 247 } 248 int err; 249 if (0 != (err = mDevice->common.close(reinterpret_cast<hw_device_t*>(mDevice)))) { 250 ALOGE("Can't close fingerprint module, error: %d", err); 251 return err; 252 } 253 mDevice = NULL; 254 return 0; 255 } 256 257 void FingerprintDaemonProxy::binderDied(const wp<IBinder>& who) { 258 ALOGD("binder died"); 259 int err; 260 if (0 != (err = closeHal())) { 261 ALOGE("Can't close fingerprint device, error: %d", err); 262 } 263 if (IInterface::asBinder(mCallback) == who) { 264 mCallback = NULL; 265 } 266 } 267 268 } 269