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