BiometricsFingerprint.cpp revision 7f7eb474ce3e57cc7582ea5fece1dd5108cd7158
1/*
2 * Copyright (C) 2016 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
18// For communication with Keystore binder interface
19#include <binder/IServiceManager.h>
20#include <keystore/IKeystoreService.h>
21#include <keystore/keystore.h> // for error codes
22#include <hardware/hw_auth_token.h>
23
24#include <hardware/hardware.h>
25#include <hardware/fingerprint.h>
26#include "BiometricsFingerprint.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
41sp<IBiometricsFingerprintClientCallback>
42    BiometricsFingerprint::mClientCallback = nullptr;
43
44// TODO: This is here because HAL 2.1 doesn't have a way to propagate a
45// unique token for its driver. Subsequent versions should send a unique
46// token for each call to notify(). This is fine as long as there's only
47// one fingerprint device on the platform.
48fingerprint_device_t *BiometricsFingerprint::sDevice = nullptr;
49
50BiometricsFingerprint::BiometricsFingerprint(fingerprint_device_t *device)
51    : mDevice(device) {
52    sDevice = mDevice; // keep track of the most recent instance
53}
54
55BiometricsFingerprint::~BiometricsFingerprint() {
56    ALOG(LOG_VERBOSE, LOG_TAG, "nativeCloseHal()\n");
57    if (mDevice == NULL) {
58        ALOGE("No valid device");
59        return;
60    }
61    int err;
62    if (0 != (err = mDevice->common.close(
63            reinterpret_cast<hw_device_t*>(mDevice)))) {
64        ALOGE("Can't close fingerprint module, error: %d", err);
65        return;
66    }
67    mDevice = NULL;
68}
69
70Return<RequestStatus> BiometricsFingerprint::ErrorFilter(int32_t error) {
71    switch(error) {
72        case 0: return RequestStatus::SYS_OK;
73        case -2: return RequestStatus::SYS_ENOENT;
74        case -4: return RequestStatus::SYS_EINTR;
75        case -5: return RequestStatus::SYS_EIO;
76        case -11: return RequestStatus::SYS_EAGAIN;
77        case -12: return RequestStatus::SYS_ENOMEM;
78        case -13: return RequestStatus::SYS_EACCES;
79        case -14: return RequestStatus::SYS_EFAULT;
80        case -16: return RequestStatus::SYS_EBUSY;
81        case -22: return RequestStatus::SYS_EINVAL;
82        case -28: return RequestStatus::SYS_ENOSPC;
83        case -110: return RequestStatus::SYS_ETIMEDOUT;
84        default:
85            ALOGE("An unknown error returned from fingerprint vendor library");
86            return RequestStatus::SYS_UNKNOWN;
87    }
88}
89
90// Translate from errors returned by traditional HAL (see fingerprint.h) to
91// HIDL-compliant FingerprintError.
92FingerprintError BiometricsFingerprint::VendorErrorFilter(int32_t error,
93            int32_t* vendorCode) {
94    *vendorCode = 0;
95    switch(error) {
96        case FINGERPRINT_ERROR_HW_UNAVAILABLE:
97            return FingerprintError::ERROR_HW_UNAVAILABLE;
98        case FINGERPRINT_ERROR_UNABLE_TO_PROCESS:
99            return FingerprintError::ERROR_UNABLE_TO_PROCESS;
100        case FINGERPRINT_ERROR_TIMEOUT:
101            return FingerprintError::ERROR_TIMEOUT;
102        case FINGERPRINT_ERROR_NO_SPACE:
103            return FingerprintError::ERROR_NO_SPACE;
104        case FINGERPRINT_ERROR_CANCELED:
105            return FingerprintError::ERROR_CANCELED;
106        case FINGERPRINT_ERROR_UNABLE_TO_REMOVE:
107            return FingerprintError::ERROR_UNABLE_TO_REMOVE;
108        default:
109            if (error >= FINGERPRINT_ERROR_VENDOR_BASE) {
110                // vendor specific code.
111                *vendorCode = error - FINGERPRINT_ERROR_VENDOR_BASE;
112                return FingerprintError::ERROR_VENDOR;
113            }
114    }
115    ALOGE("Unknown error from fingerprint vendor library");
116    return FingerprintError::ERROR_UNABLE_TO_PROCESS;
117}
118
119// Translate acquired messages returned by traditional HAL (see fingerprint.h)
120// to HIDL-compliant FingerprintAcquiredInfo.
121FingerprintAcquiredInfo BiometricsFingerprint::VendorAcquiredFilter(
122        int32_t info, int32_t* vendorCode) {
123    *vendorCode = 0;
124    switch(info) {
125        case FINGERPRINT_ACQUIRED_GOOD:
126            return FingerprintAcquiredInfo::ACQUIRED_GOOD;
127        case FINGERPRINT_ACQUIRED_PARTIAL:
128            return FingerprintAcquiredInfo::ACQUIRED_PARTIAL;
129        case FINGERPRINT_ACQUIRED_INSUFFICIENT:
130            return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT;
131        case FINGERPRINT_ACQUIRED_IMAGER_DIRTY:
132            return FingerprintAcquiredInfo::ACQUIRED_IMAGER_DIRTY;
133        case FINGERPRINT_ACQUIRED_TOO_SLOW:
134            return FingerprintAcquiredInfo::ACQUIRED_TOO_SLOW;
135        case FINGERPRINT_ACQUIRED_TOO_FAST:
136            return FingerprintAcquiredInfo::ACQUIRED_TOO_FAST;
137        default:
138            if (info >= FINGERPRINT_ACQUIRED_VENDOR_BASE) {
139                // vendor specific code.
140                *vendorCode = info - FINGERPRINT_ACQUIRED_VENDOR_BASE;
141                return FingerprintAcquiredInfo::ACQUIRED_VENDOR;
142            }
143    }
144    ALOGE("Unknown acquiredmsg from fingerprint vendor library");
145    return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT;
146}
147
148Return<uint64_t> BiometricsFingerprint::setNotify(
149        const sp<IBiometricsFingerprintClientCallback>& clientCallback) {
150    mClientCallback = clientCallback;
151    return reinterpret_cast<uint64_t>(mDevice);
152}
153
154Return<uint64_t> BiometricsFingerprint::preEnroll()  {
155    return mDevice->pre_enroll(mDevice);
156}
157
158Return<RequestStatus> BiometricsFingerprint::enroll(const hidl_array<uint8_t, 69>& hat,
159        uint32_t gid, uint32_t timeoutSec) {
160    const hw_auth_token_t* authToken =
161        reinterpret_cast<const hw_auth_token_t*>(hat.data());
162    return ErrorFilter(mDevice->enroll(mDevice, authToken, gid, timeoutSec));
163}
164
165Return<RequestStatus> BiometricsFingerprint::postEnroll() {
166    return ErrorFilter(mDevice->post_enroll(mDevice));
167}
168
169Return<uint64_t> BiometricsFingerprint::getAuthenticatorId() {
170    return mDevice->get_authenticator_id(mDevice);
171}
172
173Return<RequestStatus> BiometricsFingerprint::cancel() {
174    return ErrorFilter(mDevice->cancel(mDevice));
175}
176
177Return<RequestStatus> BiometricsFingerprint::enumerate()  {
178    return ErrorFilter(mDevice->enumerate(mDevice));
179}
180
181Return<RequestStatus> BiometricsFingerprint::remove(uint32_t gid, uint32_t fid) {
182    return ErrorFilter(mDevice->remove(mDevice, gid, fid));
183}
184
185Return<RequestStatus> BiometricsFingerprint::setActiveGroup(uint32_t gid,
186        const hidl_string& storePath) {
187    if (storePath.size() >= PATH_MAX || storePath.size() <= 0) {
188        ALOGE("Bad path length: %zd", storePath.size());
189    }
190    return ErrorFilter(mDevice->set_active_group(mDevice, gid,
191                                                    storePath.c_str()));
192}
193
194Return<RequestStatus> BiometricsFingerprint::authenticate(uint64_t operationId,
195        uint32_t gid) {
196    return ErrorFilter(mDevice->authenticate(mDevice, operationId, gid));
197}
198
199IBiometricsFingerprint* BiometricsFingerprint::getInstance() {
200    int err;
201    const hw_module_t *hw_mdl = NULL;
202    ALOGE("Opening fingerprint hal library...");
203    if (0 != (err = hw_get_module(FINGERPRINT_HARDWARE_MODULE_ID, &hw_mdl))) {
204        ALOGE("Can't open fingerprint HW Module, error: %d", err);
205        return nullptr;
206    }
207
208    if (hw_mdl == NULL) {
209        ALOGE("No valid fingerprint module");
210        return nullptr;
211    }
212
213    fingerprint_module_t const *module =
214        reinterpret_cast<const fingerprint_module_t*>(hw_mdl);
215    if (module->common.methods->open == NULL) {
216        ALOGE("No valid open method");
217        return nullptr;
218    }
219
220    hw_device_t *device = NULL;
221
222    if (0 != (err = module->common.methods->open(hw_mdl, NULL, &device))) {
223        ALOGE("Can't open fingerprint methods, error: %d", err);
224        return nullptr;
225    }
226
227    if (kVersion != device->version) {
228        ALOGE("Wrong fp version. Expected %d, got %d", kVersion, device->version);
229        return 0; // enforce this on new devices because of HIDL translation layer
230    }
231
232    fingerprint_device_t* fp_device =
233        reinterpret_cast<fingerprint_device_t*>(device);
234
235    if (0 != (err =
236            fp_device->set_notify(fp_device, BiometricsFingerprint::notify))) {
237        ALOGE("Can't register fingerprint module callback, error: %d", err);
238        return nullptr;
239    }
240
241    return new BiometricsFingerprint(fp_device);
242}
243
244void BiometricsFingerprint::notifyKeystore(const uint8_t *auth_token, const size_t auth_token_length) {
245    if (auth_token != nullptr && auth_token_length > 0) {
246        // TODO: cache service?
247        sp<IServiceManager> sm = android::defaultServiceManager();
248        sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
249        sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
250        if (service != nullptr) {
251            status_t ret = service->addAuthToken(auth_token, auth_token_length);
252            if (ret != ResponseCode::NO_ERROR) {
253                ALOGE("Falure sending auth token to KeyStore: %d", ret);
254            }
255        } else {
256            ALOGE("Unable to communicate with KeyStore");
257        }
258    }
259}
260
261} // namespace implementation
262}  // namespace V2_1
263}  // namespace fingerprint
264}  // namespace biometrics
265}  // namespace hardware
266}  // namespace android
267