blob: b38575de363363cd94bc411bc141067d5fb86f12 [file] [log] [blame]
Jan Altensen1813ff92019-08-20 23:20:25 +02001/*
2 * Copyright (C) 2019 The LineageOS 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.samsung"
17
18#include <android-base/logging.h>
19
20#include <hardware/hw_auth_token.h>
21
22#include <hardware/fingerprint.h>
23#include <hardware/hardware.h>
24#include "BiometricsFingerprint.h"
25
26#include <dlfcn.h>
27#include <inttypes.h>
28#include <unistd.h>
29
30namespace android {
31namespace hardware {
32namespace biometrics {
33namespace fingerprint {
34namespace V2_1 {
35namespace implementation {
36
37using RequestStatus = android::hardware::biometrics::fingerprint::V2_1::RequestStatus;
38
39BiometricsFingerprint* BiometricsFingerprint::sInstance = nullptr;
40
41BiometricsFingerprint::BiometricsFingerprint() : mClientCallback(nullptr) {
42 sInstance = this; // keep track of the most recent instance
43 if (!openHal()) {
44 LOG(ERROR) << "Can't open HAL module";
45 }
46}
47
48BiometricsFingerprint::~BiometricsFingerprint() {
49 if (ss_fingerprint_close() != 0) {
50 LOG(ERROR) << "Can't close HAL module";
51 }
52}
53
54Return<RequestStatus> BiometricsFingerprint::ErrorFilter(int32_t error) {
55 switch (error) {
56 case 0:
57 return RequestStatus::SYS_OK;
58 case -2:
59 return RequestStatus::SYS_ENOENT;
60 case -4:
61 return RequestStatus::SYS_EINTR;
62 case -5:
63 return RequestStatus::SYS_EIO;
64 case -11:
65 return RequestStatus::SYS_EAGAIN;
66 case -12:
67 return RequestStatus::SYS_ENOMEM;
68 case -13:
69 return RequestStatus::SYS_EACCES;
70 case -14:
71 return RequestStatus::SYS_EFAULT;
72 case -16:
73 return RequestStatus::SYS_EBUSY;
74 case -22:
75 return RequestStatus::SYS_EINVAL;
76 case -28:
77 return RequestStatus::SYS_ENOSPC;
78 case -110:
79 return RequestStatus::SYS_ETIMEDOUT;
80 default:
81 LOG(ERROR) << "An unknown error returned from fingerprint vendor library: " << 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, 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 LOG(ERROR) << "Unknown error from fingerprint vendor library: " << 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(int32_t info,
119 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 LOG(ERROR) << "Unknown acquiredmsg from fingerprint vendor library: " << info;
142 return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT;
143}
144
145Return<uint64_t> BiometricsFingerprint::setNotify(
146 const sp<IBiometricsFingerprintClientCallback>& clientCallback) {
147 std::lock_guard<std::mutex> lock(mClientCallbackMutex);
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>(this);
154}
155
156Return<uint64_t> BiometricsFingerprint::preEnroll() {
157 return ss_fingerprint_pre_enroll();
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 = reinterpret_cast<const hw_auth_token_t*>(hat.data());
163
164 return ErrorFilter(ss_fingerprint_enroll(authToken, gid, timeoutSec));
165}
166
167Return<RequestStatus> BiometricsFingerprint::postEnroll() {
168 return ErrorFilter(ss_fingerprint_post_enroll());
169}
170
171Return<uint64_t> BiometricsFingerprint::getAuthenticatorId() {
172 return ss_fingerprint_get_auth_id();
173}
174
175Return<RequestStatus> BiometricsFingerprint::cancel() {
Jan Altensen41de6a32019-08-21 23:34:48 +0200176 int32_t ret = ss_fingerprint_cancel();
177
178#ifdef CALL_NOTIFY_ON_CANCEL
179 if (ret == 0) {
180 fingerprint_msg_t msg{};
181 msg.type = FINGERPRINT_ERROR;
182 msg.data.error = FINGERPRINT_ERROR_CANCELED;
183 notify(&msg);
184 }
185#endif
186
187 return ErrorFilter(ret);
Jan Altensen1813ff92019-08-20 23:20:25 +0200188}
189
190Return<RequestStatus> BiometricsFingerprint::enumerate() {
191 if (ss_fingerprint_enumerate != nullptr) {
192 return ErrorFilter(ss_fingerprint_enumerate());
193 }
194
195 return RequestStatus::SYS_UNKNOWN;
196}
197
198Return<RequestStatus> BiometricsFingerprint::remove(uint32_t gid, uint32_t fid) {
199 return ErrorFilter(ss_fingerprint_remove(gid, fid));
200}
201
202Return<RequestStatus> BiometricsFingerprint::setActiveGroup(uint32_t gid,
203 const hidl_string& storePath) {
204 if (storePath.size() >= PATH_MAX || storePath.size() <= 0) {
205 LOG(ERROR) << "Bad path length: " << storePath.size();
206 return RequestStatus::SYS_EINVAL;
207 }
208
209 if (access(storePath.c_str(), W_OK)) {
210 return RequestStatus::SYS_EINVAL;
211 }
212
213 return ErrorFilter(ss_fingerprint_set_active_group(gid, storePath.c_str()));
214}
215
216Return<RequestStatus> BiometricsFingerprint::authenticate(uint64_t operationId, uint32_t gid) {
217 return ErrorFilter(ss_fingerprint_authenticate(operationId, gid));
218}
219
220IBiometricsFingerprint* BiometricsFingerprint::getInstance() {
221 if (!sInstance) {
222 sInstance = new BiometricsFingerprint();
223 }
224 return sInstance;
225}
226
227bool BiometricsFingerprint::openHal() {
228 void* handle = dlopen("libbauthserver.so", RTLD_NOW);
229 if (handle) {
230 int err;
231
232 ss_fingerprint_close =
233 reinterpret_cast<typeof(ss_fingerprint_close)>(dlsym(handle, "ss_fingerprint_close"));
234 ss_fingerprint_open =
235 reinterpret_cast<typeof(ss_fingerprint_open)>(dlsym(handle, "ss_fingerprint_open"));
236
237 ss_set_notify_callback = reinterpret_cast<typeof(ss_set_notify_callback)>(
238 dlsym(handle, "ss_set_notify_callback"));
239 ss_fingerprint_pre_enroll = reinterpret_cast<typeof(ss_fingerprint_pre_enroll)>(
240 dlsym(handle, "ss_fingerprint_pre_enroll"));
241 ss_fingerprint_enroll =
242 reinterpret_cast<typeof(ss_fingerprint_enroll)>(dlsym(handle, "ss_fingerprint_enroll"));
243 ss_fingerprint_post_enroll = reinterpret_cast<typeof(ss_fingerprint_post_enroll)>(
244 dlsym(handle, "ss_fingerprint_post_enroll"));
245 ss_fingerprint_get_auth_id = reinterpret_cast<typeof(ss_fingerprint_get_auth_id)>(
246 dlsym(handle, "ss_fingerprint_get_auth_id"));
247 ss_fingerprint_cancel =
248 reinterpret_cast<typeof(ss_fingerprint_cancel)>(dlsym(handle, "ss_fingerprint_cancel"));
249 ss_fingerprint_enumerate = reinterpret_cast<typeof(ss_fingerprint_enumerate)>(
250 dlsym(handle, "ss_fingerprint_enumerate"));
251 ss_fingerprint_remove =
252 reinterpret_cast<typeof(ss_fingerprint_remove)>(dlsym(handle, "ss_fingerprint_remove"));
253 ss_fingerprint_set_active_group = reinterpret_cast<typeof(ss_fingerprint_set_active_group)>(
254 dlsym(handle, "ss_fingerprint_set_active_group"));
255 ss_fingerprint_authenticate = reinterpret_cast<typeof(ss_fingerprint_authenticate)>(
256 dlsym(handle, "ss_fingerprint_authenticate"));
257
258 if ((err = ss_fingerprint_open(nullptr)) != 0) {
259 LOG(ERROR) << "Can't open fingerprint, error: " << err;
260 return false;
261 }
262
263 if ((err = ss_set_notify_callback(BiometricsFingerprint::notify)) != 0) {
264 LOG(ERROR) << "Can't register fingerprint module callback, error: " << err;
265 return false;
266 }
267
268 return true;
269 }
270
271 return false;
272}
273
274void BiometricsFingerprint::notify(const fingerprint_msg_t* msg) {
275 BiometricsFingerprint* thisPtr =
276 static_cast<BiometricsFingerprint*>(BiometricsFingerprint::getInstance());
277 std::lock_guard<std::mutex> lock(thisPtr->mClientCallbackMutex);
278 if (thisPtr == nullptr || thisPtr->mClientCallback == nullptr) {
279 LOG(ERROR) << "Receiving callbacks before the client callback is registered.";
280 return;
281 }
282 const uint64_t devId = 1;
283 switch (msg->type) {
284 case FINGERPRINT_ERROR: {
285 int32_t vendorCode = 0;
286 FingerprintError result = VendorErrorFilter(msg->data.error, &vendorCode);
287 LOG(DEBUG) << "onError(" << static_cast<int>(result) << ")";
288 if (!thisPtr->mClientCallback->onError(devId, result, vendorCode).isOk()) {
289 LOG(ERROR) << "failed to invoke fingerprint onError callback";
290 }
291 } break;
292 case FINGERPRINT_ACQUIRED: {
293 int32_t vendorCode = 0;
294 FingerprintAcquiredInfo result =
295 VendorAcquiredFilter(msg->data.acquired.acquired_info, &vendorCode);
296 LOG(DEBUG) << "onAcquired(" << static_cast<int>(result) << ")";
297 if (!thisPtr->mClientCallback->onAcquired(devId, result, vendorCode).isOk()) {
298 LOG(ERROR) << "failed to invoke fingerprint onAcquired callback";
299 }
300 } break;
301 case FINGERPRINT_TEMPLATE_ENROLLING:
Danny Wood16d1a362019-12-23 11:37:10 +0000302#ifdef USES_PERCENTAGE_SAMPLES
303 const_cast<fingerprint_msg_t*>(msg)->data.enroll.samples_remaining =
304 100 - msg->data.enroll.samples_remaining;
305#endif
Danny Woode893e322020-02-22 06:36:04 +0000306#ifdef CALL_CANCEL_ON_ENROLL_COMPLETION
307 if(msg->data.enroll.samples_remaining == 0) {
308 thisPtr->ss_fingerprint_cancel();
309 }
310#endif
Jan Altensen1813ff92019-08-20 23:20:25 +0200311 LOG(DEBUG) << "onEnrollResult(fid=" << msg->data.enroll.finger.fid
312 << ", gid=" << msg->data.enroll.finger.gid
313 << ", rem=" << msg->data.enroll.samples_remaining << ")";
Danny Wood16d1a362019-12-23 11:37:10 +0000314 if (!thisPtr->mClientCallback
Jan Altensen1813ff92019-08-20 23:20:25 +0200315 ->onEnrollResult(devId, msg->data.enroll.finger.fid,
316 msg->data.enroll.finger.gid, msg->data.enroll.samples_remaining)
317 .isOk()) {
Jan Altensen1813ff92019-08-20 23:20:25 +0200318 LOG(ERROR) << "failed to invoke fingerprint onEnrollResult callback";
319 }
320 break;
321 case FINGERPRINT_TEMPLATE_REMOVED:
322 LOG(DEBUG) << "onRemove(fid=" << msg->data.removed.finger.fid
323 << ", gid=" << msg->data.removed.finger.gid
324 << ", rem=" << msg->data.removed.remaining_templates << ")";
325 if (!thisPtr->mClientCallback
326 ->onRemoved(devId, msg->data.removed.finger.fid, msg->data.removed.finger.gid,
327 msg->data.removed.remaining_templates)
328 .isOk()) {
329 LOG(ERROR) << "failed to invoke fingerprint onRemoved callback";
330 }
331 break;
332 case FINGERPRINT_AUTHENTICATED:
333 LOG(DEBUG) << "onAuthenticated(fid=" << msg->data.authenticated.finger.fid
334 << ", gid=" << msg->data.authenticated.finger.gid << ")";
335 if (msg->data.authenticated.finger.fid != 0) {
336 const uint8_t* hat = reinterpret_cast<const uint8_t*>(&msg->data.authenticated.hat);
337 const hidl_vec<uint8_t> token(
338 std::vector<uint8_t>(hat, hat + sizeof(msg->data.authenticated.hat)));
339 if (!thisPtr->mClientCallback
340 ->onAuthenticated(devId, msg->data.authenticated.finger.fid,
341 msg->data.authenticated.finger.gid, token)
342 .isOk()) {
343 LOG(ERROR) << "failed to invoke fingerprint onAuthenticated callback";
344 }
345 } else {
346 // Not a recognized fingerprint
347 if (!thisPtr->mClientCallback
348 ->onAuthenticated(devId, msg->data.authenticated.finger.fid,
349 msg->data.authenticated.finger.gid, hidl_vec<uint8_t>())
350 .isOk()) {
351 LOG(ERROR) << "failed to invoke fingerprint onAuthenticated callback";
352 }
353 }
354 break;
355 case FINGERPRINT_TEMPLATE_ENUMERATING:
356 LOG(DEBUG) << "onEnumerate(fid=" << msg->data.enumerated.finger.fid
357 << ", gid=" << msg->data.enumerated.finger.gid
358 << ", rem=" << msg->data.enumerated.remaining_templates << ")";
359 if (!thisPtr->mClientCallback
360 ->onEnumerate(devId, msg->data.enumerated.finger.fid,
361 msg->data.enumerated.finger.gid,
362 msg->data.enumerated.remaining_templates)
363 .isOk()) {
364 LOG(ERROR) << "failed to invoke fingerprint onEnumerate callback";
365 }
366 break;
367 }
368}
369
370} // namespace implementation
371} // namespace V2_1
372} // namespace fingerprint
373} // namespace biometrics
374} // namespace hardware
375} // namespace android