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