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 (at) 2.1-service" 17 #define LOG_VERBOSE "android.hardware.biometrics.fingerprint (at) 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 28 namespace android { 29 namespace hardware { 30 namespace biometrics { 31 namespace fingerprint { 32 namespace V2_1 { 33 namespace implementation { 34 35 // Supported fingerprint HAL version 36 static const uint16_t kVersion = HARDWARE_MODULE_API_VERSION(2, 1); 37 38 using RequestStatus = 39 android::hardware::biometrics::fingerprint::V2_1::RequestStatus; 40 41 BiometricsFingerprint *BiometricsFingerprint::sInstance = nullptr; 42 43 BiometricsFingerprint::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 51 BiometricsFingerprint::~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 66 Return<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. 88 FingerprintError 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. 119 FingerprintAcquiredInfo 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 146 Return<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 156 Return<uint64_t> BiometricsFingerprint::preEnroll() { 157 return mDevice->pre_enroll(mDevice); 158 } 159 160 Return<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 167 Return<RequestStatus> BiometricsFingerprint::postEnroll() { 168 return ErrorFilter(mDevice->post_enroll(mDevice)); 169 } 170 171 Return<uint64_t> BiometricsFingerprint::getAuthenticatorId() { 172 return mDevice->get_authenticator_id(mDevice); 173 } 174 175 Return<RequestStatus> BiometricsFingerprint::cancel() { 176 return ErrorFilter(mDevice->cancel(mDevice)); 177 } 178 179 Return<RequestStatus> BiometricsFingerprint::enumerate() { 180 return ErrorFilter(mDevice->enumerate(mDevice)); 181 } 182 183 Return<RequestStatus> BiometricsFingerprint::remove(uint32_t gid, uint32_t fid) { 184 return ErrorFilter(mDevice->remove(mDevice, gid, fid)); 185 } 186 187 Return<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 201 Return<RequestStatus> BiometricsFingerprint::authenticate(uint64_t operationId, 202 uint32_t gid) { 203 return ErrorFilter(mDevice->authenticate(mDevice, operationId, gid)); 204 } 205 206 IBiometricsFingerprint* BiometricsFingerprint::getInstance() { 207 if (!sInstance) { 208 sInstance = new BiometricsFingerprint(); 209 } 210 return sInstance; 211 } 212 213 fingerprint_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 (at) 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 259 void 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 ALOGD("onError(%d)", result); 272 if (!thisPtr->mClientCallback->onError(devId, result, vendorCode).isOk()) { 273 ALOGE("failed to invoke fingerprint onError callback"); 274 } 275 } 276 break; 277 case FINGERPRINT_ACQUIRED: { 278 int32_t vendorCode = 0; 279 FingerprintAcquiredInfo result = 280 VendorAcquiredFilter(msg->data.acquired.acquired_info, &vendorCode); 281 ALOGD("onAcquired(%d)", result); 282 if (!thisPtr->mClientCallback->onAcquired(devId, result, vendorCode).isOk()) { 283 ALOGE("failed to invoke fingerprint onAcquired callback"); 284 } 285 } 286 break; 287 case FINGERPRINT_TEMPLATE_ENROLLING: 288 ALOGD("onEnrollResult(fid=%d, gid=%d, rem=%d)", 289 msg->data.enroll.finger.fid, 290 msg->data.enroll.finger.gid, 291 msg->data.enroll.samples_remaining); 292 if (!thisPtr->mClientCallback->onEnrollResult(devId, 293 msg->data.enroll.finger.fid, 294 msg->data.enroll.finger.gid, 295 msg->data.enroll.samples_remaining).isOk()) { 296 ALOGE("failed to invoke fingerprint onEnrollResult callback"); 297 } 298 break; 299 case FINGERPRINT_TEMPLATE_REMOVED: 300 ALOGD("onRemove(fid=%d, gid=%d, rem=%d)", 301 msg->data.removed.finger.fid, 302 msg->data.removed.finger.gid, 303 msg->data.removed.remaining_templates); 304 if (!thisPtr->mClientCallback->onRemoved(devId, 305 msg->data.removed.finger.fid, 306 msg->data.removed.finger.gid, 307 msg->data.removed.remaining_templates).isOk()) { 308 ALOGE("failed to invoke fingerprint onRemoved callback"); 309 } 310 break; 311 case FINGERPRINT_AUTHENTICATED: 312 if (msg->data.authenticated.finger.fid != 0) { 313 ALOGD("onAuthenticated(fid=%d, gid=%d)", 314 msg->data.authenticated.finger.fid, 315 msg->data.authenticated.finger.gid); 316 const uint8_t* hat = 317 reinterpret_cast<const uint8_t *>(&msg->data.authenticated.hat); 318 const hidl_vec<uint8_t> token( 319 std::vector<uint8_t>(hat, hat + sizeof(msg->data.authenticated.hat))); 320 if (!thisPtr->mClientCallback->onAuthenticated(devId, 321 msg->data.authenticated.finger.fid, 322 msg->data.authenticated.finger.gid, 323 token).isOk()) { 324 ALOGE("failed to invoke fingerprint onAuthenticated callback"); 325 } 326 } else { 327 // Not a recognized fingerprint 328 if (!thisPtr->mClientCallback->onAuthenticated(devId, 329 msg->data.authenticated.finger.fid, 330 msg->data.authenticated.finger.gid, 331 hidl_vec<uint8_t>()).isOk()) { 332 ALOGE("failed to invoke fingerprint onAuthenticated callback"); 333 } 334 } 335 break; 336 case FINGERPRINT_TEMPLATE_ENUMERATING: 337 ALOGD("onEnumerate(fid=%d, gid=%d, rem=%d)", 338 msg->data.enumerated.finger.fid, 339 msg->data.enumerated.finger.gid, 340 msg->data.enumerated.remaining_templates); 341 if (!thisPtr->mClientCallback->onEnumerate(devId, 342 msg->data.enumerated.finger.fid, 343 msg->data.enumerated.finger.gid, 344 msg->data.enumerated.remaining_templates).isOk()) { 345 ALOGE("failed to invoke fingerprint onEnumerate callback"); 346 } 347 break; 348 } 349 } 350 351 } // namespace implementation 352 } // namespace V2_1 353 } // namespace fingerprint 354 } // namespace biometrics 355 } // namespace hardware 356 } // namespace android 357