BiometricsFingerprint.cpp revision 750ede4cf9c0f09b14bfbd8c6066292bd27a7f33
1/* 2 * Copyright (C) 2017 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#define LOG_TAG "android.hardware.biometrics.fingerprint@2.1-service" 17#define LOG_VERBOSE "android.hardware.biometrics.fingerprint@2.1-service" 18 19#include <hardware/hw_auth_token.h> 20 21#include <hardware/hardware.h> 22#include <hardware/fingerprint.h> 23#include "BiometricsFingerprint.h" 24 25#include <inttypes.h> 26 27namespace android { 28namespace hardware { 29namespace biometrics { 30namespace fingerprint { 31namespace V2_1 { 32namespace implementation { 33 34// Supported fingerprint HAL version 35static const uint16_t kVersion = HARDWARE_MODULE_API_VERSION(2, 1); 36 37using RequestStatus = 38 android::hardware::biometrics::fingerprint::V2_1::RequestStatus; 39 40BiometricsFingerprint *BiometricsFingerprint::sInstance = nullptr; 41 42BiometricsFingerprint::BiometricsFingerprint() : mClientCallback(nullptr), mDevice(nullptr) { 43 sInstance = this; // keep track of the most recent instance 44 mDevice = openHal(); 45 if (!mDevice) { 46 ALOGE("Can't open HAL module"); 47 } 48} 49 50BiometricsFingerprint::~BiometricsFingerprint() { 51 ALOGV("~BiometricsFingerprint()"); 52 if (mDevice == nullptr) { 53 ALOGE("No valid device"); 54 return; 55 } 56 int err; 57 if (0 != (err = mDevice->common.close( 58 reinterpret_cast<hw_device_t*>(mDevice)))) { 59 ALOGE("Can't close fingerprint module, error: %d", err); 60 return; 61 } 62 mDevice = nullptr; 63} 64 65Return<RequestStatus> BiometricsFingerprint::ErrorFilter(int32_t error) { 66 switch(error) { 67 case 0: return RequestStatus::SYS_OK; 68 case -2: return RequestStatus::SYS_ENOENT; 69 case -4: return RequestStatus::SYS_EINTR; 70 case -5: return RequestStatus::SYS_EIO; 71 case -11: return RequestStatus::SYS_EAGAIN; 72 case -12: return RequestStatus::SYS_ENOMEM; 73 case -13: return RequestStatus::SYS_EACCES; 74 case -14: return RequestStatus::SYS_EFAULT; 75 case -16: return RequestStatus::SYS_EBUSY; 76 case -22: return RequestStatus::SYS_EINVAL; 77 case -28: return RequestStatus::SYS_ENOSPC; 78 case -110: return RequestStatus::SYS_ETIMEDOUT; 79 default: 80 ALOGE("An unknown error returned from fingerprint vendor library: %d", error); 81 return RequestStatus::SYS_UNKNOWN; 82 } 83} 84 85// Translate from errors returned by traditional HAL (see fingerprint.h) to 86// HIDL-compliant FingerprintError. 87FingerprintError BiometricsFingerprint::VendorErrorFilter(int32_t error, 88 int32_t* vendorCode) { 89 *vendorCode = 0; 90 switch(error) { 91 case FINGERPRINT_ERROR_HW_UNAVAILABLE: 92 return FingerprintError::ERROR_HW_UNAVAILABLE; 93 case FINGERPRINT_ERROR_UNABLE_TO_PROCESS: 94 return FingerprintError::ERROR_UNABLE_TO_PROCESS; 95 case FINGERPRINT_ERROR_TIMEOUT: 96 return FingerprintError::ERROR_TIMEOUT; 97 case FINGERPRINT_ERROR_NO_SPACE: 98 return FingerprintError::ERROR_NO_SPACE; 99 case FINGERPRINT_ERROR_CANCELED: 100 return FingerprintError::ERROR_CANCELED; 101 case FINGERPRINT_ERROR_UNABLE_TO_REMOVE: 102 return FingerprintError::ERROR_UNABLE_TO_REMOVE; 103 case FINGERPRINT_ERROR_LOCKOUT: 104 return FingerprintError::ERROR_LOCKOUT; 105 default: 106 if (error >= FINGERPRINT_ERROR_VENDOR_BASE) { 107 // vendor specific code. 108 *vendorCode = error - FINGERPRINT_ERROR_VENDOR_BASE; 109 return FingerprintError::ERROR_VENDOR; 110 } 111 } 112 ALOGE("Unknown error from fingerprint vendor library: %d", error); 113 return FingerprintError::ERROR_UNABLE_TO_PROCESS; 114} 115 116// Translate acquired messages returned by traditional HAL (see fingerprint.h) 117// to HIDL-compliant FingerprintAcquiredInfo. 118FingerprintAcquiredInfo BiometricsFingerprint::VendorAcquiredFilter( 119 int32_t info, int32_t* vendorCode) { 120 *vendorCode = 0; 121 switch(info) { 122 case FINGERPRINT_ACQUIRED_GOOD: 123 return FingerprintAcquiredInfo::ACQUIRED_GOOD; 124 case FINGERPRINT_ACQUIRED_PARTIAL: 125 return FingerprintAcquiredInfo::ACQUIRED_PARTIAL; 126 case FINGERPRINT_ACQUIRED_INSUFFICIENT: 127 return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT; 128 case FINGERPRINT_ACQUIRED_IMAGER_DIRTY: 129 return FingerprintAcquiredInfo::ACQUIRED_IMAGER_DIRTY; 130 case FINGERPRINT_ACQUIRED_TOO_SLOW: 131 return FingerprintAcquiredInfo::ACQUIRED_TOO_SLOW; 132 case FINGERPRINT_ACQUIRED_TOO_FAST: 133 return FingerprintAcquiredInfo::ACQUIRED_TOO_FAST; 134 default: 135 if (info >= FINGERPRINT_ACQUIRED_VENDOR_BASE) { 136 // vendor specific code. 137 *vendorCode = info - FINGERPRINT_ACQUIRED_VENDOR_BASE; 138 return FingerprintAcquiredInfo::ACQUIRED_VENDOR; 139 } 140 } 141 ALOGE("Unknown acquiredmsg from fingerprint vendor library: %d", info); 142 return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT; 143} 144 145Return<uint64_t> BiometricsFingerprint::setNotify( 146 const sp<IBiometricsFingerprintClientCallback>& clientCallback) { 147 mClientCallback = clientCallback; 148 // This is here because HAL 2.1 doesn't have a way to propagate a 149 // unique token for its driver. Subsequent versions should send a unique 150 // token for each call to setNotify(). This is fine as long as there's only 151 // one fingerprint device on the platform. 152 return reinterpret_cast<uint64_t>(mDevice); 153} 154 155Return<uint64_t> BiometricsFingerprint::preEnroll() { 156 return mDevice->pre_enroll(mDevice); 157} 158 159Return<RequestStatus> BiometricsFingerprint::enroll(const hidl_array<uint8_t, 69>& hat, 160 uint32_t gid, uint32_t timeoutSec) { 161 const hw_auth_token_t* authToken = 162 reinterpret_cast<const hw_auth_token_t*>(hat.data()); 163 return ErrorFilter(mDevice->enroll(mDevice, authToken, gid, timeoutSec)); 164} 165 166Return<RequestStatus> BiometricsFingerprint::postEnroll() { 167 return ErrorFilter(mDevice->post_enroll(mDevice)); 168} 169 170Return<uint64_t> BiometricsFingerprint::getAuthenticatorId() { 171 return mDevice->get_authenticator_id(mDevice); 172} 173 174Return<RequestStatus> BiometricsFingerprint::cancel() { 175 return ErrorFilter(mDevice->cancel(mDevice)); 176} 177 178Return<RequestStatus> BiometricsFingerprint::enumerate() { 179 return ErrorFilter(mDevice->enumerate(mDevice)); 180} 181 182Return<RequestStatus> BiometricsFingerprint::remove(uint32_t gid, uint32_t fid) { 183 return ErrorFilter(mDevice->remove(mDevice, gid, fid)); 184} 185 186Return<RequestStatus> BiometricsFingerprint::setActiveGroup(uint32_t gid, 187 const hidl_string& storePath) { 188 if (storePath.size() >= PATH_MAX || storePath.size() <= 0) { 189 ALOGE("Bad path length: %zd", storePath.size()); 190 } 191 return ErrorFilter(mDevice->set_active_group(mDevice, gid, 192 storePath.c_str())); 193} 194 195Return<RequestStatus> BiometricsFingerprint::authenticate(uint64_t operationId, 196 uint32_t gid) { 197 return ErrorFilter(mDevice->authenticate(mDevice, operationId, gid)); 198} 199 200IBiometricsFingerprint* BiometricsFingerprint::getInstance() { 201 if (!sInstance) { 202 sInstance = new BiometricsFingerprint(); 203 } 204 return sInstance; 205} 206 207fingerprint_device_t* BiometricsFingerprint::openHal() { 208 int err; 209 const hw_module_t *hw_mdl = nullptr; 210 ALOGD("Opening fingerprint hal library..."); 211 if (0 != (err = hw_get_module(FINGERPRINT_HARDWARE_MODULE_ID, &hw_mdl))) { 212 ALOGE("Can't open fingerprint HW Module, error: %d", err); 213 return nullptr; 214 } 215 216 if (hw_mdl == nullptr) { 217 ALOGE("No valid fingerprint module"); 218 return nullptr; 219 } 220 221 fingerprint_module_t const *module = 222 reinterpret_cast<const fingerprint_module_t*>(hw_mdl); 223 if (module->common.methods->open == nullptr) { 224 ALOGE("No valid open method"); 225 return nullptr; 226 } 227 228 hw_device_t *device = nullptr; 229 230 if (0 != (err = module->common.methods->open(hw_mdl, nullptr, &device))) { 231 ALOGE("Can't open fingerprint methods, error: %d", err); 232 return nullptr; 233 } 234 235 if (kVersion != device->version) { 236 // enforce version on new devices because of HIDL@2.1 translation layer 237 ALOGE("Wrong fp version. Expected %d, got %d", kVersion, device->version); 238 return nullptr; 239 } 240 241 fingerprint_device_t* fp_device = 242 reinterpret_cast<fingerprint_device_t*>(device); 243 244 if (0 != (err = 245 fp_device->set_notify(fp_device, BiometricsFingerprint::notify))) { 246 ALOGE("Can't register fingerprint module callback, error: %d", err); 247 return nullptr; 248 } 249 250 return fp_device; 251} 252 253void BiometricsFingerprint::notify(const fingerprint_msg_t *msg) { 254 BiometricsFingerprint* thisPtr = static_cast<BiometricsFingerprint*>( 255 BiometricsFingerprint::getInstance()); 256 if (thisPtr == nullptr || thisPtr->mClientCallback == nullptr) { 257 ALOGE("Receiving callbacks before the client callback is registered."); 258 return; 259 } 260 const uint64_t devId = reinterpret_cast<uint64_t>(thisPtr->mDevice); 261 switch (msg->type) { 262 case FINGERPRINT_ERROR: { 263 int32_t vendorCode = 0; 264 FingerprintError result = VendorErrorFilter(msg->data.error, &vendorCode); 265 if (!thisPtr->mClientCallback->onError(devId, result, vendorCode).isOk()) { 266 ALOGE("failed to invoke fingerprint onError callback"); 267 } 268 } 269 break; 270 case FINGERPRINT_ACQUIRED: { 271 int32_t vendorCode = 0; 272 FingerprintAcquiredInfo result = 273 VendorAcquiredFilter(msg->data.acquired.acquired_info, &vendorCode); 274 if (!thisPtr->mClientCallback->onAcquired(devId, result, vendorCode).isOk()) { 275 ALOGE("failed to invoke fingerprint onAcquired callback"); 276 } 277 } 278 break; 279 case FINGERPRINT_TEMPLATE_ENROLLING: 280 if (!thisPtr->mClientCallback->onEnrollResult(devId, 281 msg->data.enroll.finger.fid, 282 msg->data.enroll.finger.gid, 283 msg->data.enroll.samples_remaining).isOk()) { 284 ALOGE("failed to invoke fingerprint onEnrollResult callback"); 285 } 286 break; 287 case FINGERPRINT_TEMPLATE_REMOVED: 288 if (!thisPtr->mClientCallback->onRemoved(devId, 289 msg->data.removed.finger.fid, 290 msg->data.removed.finger.gid, 291 msg->data.removed.remaining_templates).isOk()) { 292 ALOGE("failed to invoke fingerprint onRemoved callback"); 293 } 294 break; 295 case FINGERPRINT_AUTHENTICATED: 296 if (msg->data.authenticated.finger.fid != 0) { 297 const uint8_t* hat = 298 reinterpret_cast<const uint8_t *>(&msg->data.authenticated.hat); 299 const hidl_vec<uint8_t> token( 300 std::vector<uint8_t>(hat, hat + sizeof(msg->data.authenticated.hat))); 301 if (!thisPtr->mClientCallback->onAuthenticated(devId, 302 msg->data.authenticated.finger.fid, 303 msg->data.authenticated.finger.gid, 304 token).isOk()) { 305 ALOGE("failed to invoke fingerprint onAuthenticated callback"); 306 } 307 } else { 308 // Not a recognized fingerprint 309 if (!thisPtr->mClientCallback->onAuthenticated(devId, 310 msg->data.authenticated.finger.fid, 311 msg->data.authenticated.finger.gid, 312 hidl_vec<uint8_t>()).isOk()) { 313 ALOGE("failed to invoke fingerprint onAuthenticated callback"); 314 } 315 } 316 break; 317 case FINGERPRINT_TEMPLATE_ENUMERATING: 318 if (!thisPtr->mClientCallback->onEnumerate(devId, 319 msg->data.enumerated.finger.fid, 320 msg->data.enumerated.finger.gid, 321 msg->data.enumerated.remaining_templates).isOk()) { 322 ALOGE("failed to invoke fingerprint onEnumerate callback"); 323 } 324 break; 325 } 326} 327 328} // namespace implementation 329} // namespace V2_1 330} // namespace fingerprint 331} // namespace biometrics 332} // namespace hardware 333} // namespace android 334