blob: 4e8005214e4f747eb77774b97addc535d0d3ddc1 [file] [log] [blame]
Joe Bolingerde94aa02021-12-09 17:00:32 -08001/*
Jeff Pu52653182022-10-12 16:27:23 -04002 * Copyright (C) 2022 The Android Open Source Project
Joe Bolingerde94aa02021-12-09 17:00:32 -08003 *
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
17#include "FakeFingerprintEngine.h"
Jeff Pu52653182022-10-12 16:27:23 -040018#include <regex>
Jeff Pu63f33c72022-07-28 16:06:23 -040019#include "Fingerprint.h"
Joe Bolingerde94aa02021-12-09 17:00:32 -080020
Joe Bolingerde94aa02021-12-09 17:00:32 -080021#include <android-base/logging.h>
Jeff Pu63f33c72022-07-28 16:06:23 -040022#include <android-base/parseint.h>
Joshua McCloskeyc8c0bad2022-05-10 05:17:44 +000023
24#include <fingerprint.sysprop.h>
Joe Bolingerde94aa02021-12-09 17:00:32 -080025
Joshua McCloskeyc8c0bad2022-05-10 05:17:44 +000026#include "util/CancellationSignal.h"
Joshua McCloskeydb009a52022-05-10 05:18:20 +000027#include "util/Util.h"
Joe Bolingerde94aa02021-12-09 17:00:32 -080028
29using namespace ::android::fingerprint::virt;
Jeff Pu63f33c72022-07-28 16:06:23 -040030using ::android::base::ParseInt;
Joe Bolingerde94aa02021-12-09 17:00:32 -080031
32namespace aidl::android::hardware::biometrics::fingerprint {
33
Jeff Pudef5b042023-05-25 14:28:16 -040034FakeFingerprintEngine::FakeFingerprintEngine()
Jeff Pu29df1e92023-10-06 14:12:44 +000035 : mRandom(std::mt19937::default_seed),
36 mWorkMode(WorkMode::kIdle),
37 isLockoutTimerSupported(true) {}
Jeff Pudef5b042023-05-25 14:28:16 -040038
Joe Bolingerde94aa02021-12-09 17:00:32 -080039void FakeFingerprintEngine::generateChallengeImpl(ISessionCallback* cb) {
40 BEGIN_OP(0);
41 std::uniform_int_distribution<int64_t> dist;
42 auto challenge = dist(mRandom);
43 FingerprintHalProperties::challenge(challenge);
44 cb->onChallengeGenerated(challenge);
45}
46
47void FakeFingerprintEngine::revokeChallengeImpl(ISessionCallback* cb, int64_t challenge) {
48 BEGIN_OP(0);
49 FingerprintHalProperties::challenge({});
50 cb->onChallengeRevoked(challenge);
51}
52
53void FakeFingerprintEngine::enrollImpl(ISessionCallback* cb,
54 const keymaster::HardwareAuthToken& hat,
55 const std::future<void>& cancel) {
Jeff Pudef5b042023-05-25 14:28:16 -040056 BEGIN_OP(0);
Jeff Pu5055e3c2023-07-27 11:26:50 -040057
58 // Do proper HAT verification in the real implementation.
59 if (hat.mac.empty()) {
60 LOG(ERROR) << "Fail: hat";
61 cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
62 return;
63 }
64
Jeff Pudef5b042023-05-25 14:28:16 -040065 updateContext(WorkMode::kEnroll, cb, const_cast<std::future<void>&>(cancel), 0, hat);
66}
67
68void FakeFingerprintEngine::authenticateImpl(ISessionCallback* cb, int64_t operationId,
69 const std::future<void>& cancel) {
70 BEGIN_OP(0);
71 updateContext(WorkMode::kAuthenticate, cb, const_cast<std::future<void>&>(cancel), operationId,
72 keymaster::HardwareAuthToken());
73}
74
75void FakeFingerprintEngine::detectInteractionImpl(ISessionCallback* cb,
76 const std::future<void>& cancel) {
77 BEGIN_OP(0);
78
79 auto detectInteractionSupported =
80 FingerprintHalProperties::detect_interaction().value_or(false);
81 if (!detectInteractionSupported) {
82 LOG(ERROR) << "Detect interaction is not supported";
83 cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
84 return;
85 }
86
87 updateContext(WorkMode::kDetectInteract, cb, const_cast<std::future<void>&>(cancel), 0,
88 keymaster::HardwareAuthToken());
89}
90
91void FakeFingerprintEngine::updateContext(WorkMode mode, ISessionCallback* cb,
92 std::future<void>& cancel, int64_t operationId,
93 const keymaster::HardwareAuthToken& hat) {
94 mCancel = std::move(cancel);
95 mWorkMode = mode;
96 mCb = cb;
97 mOperationId = operationId;
98 mHat = hat;
99}
100
101void FakeFingerprintEngine::fingerDownAction() {
Jeff Pu073af182023-07-12 18:53:52 +0000102 bool isTerminal = false;
Jeff Pudef5b042023-05-25 14:28:16 -0400103 LOG(INFO) << __func__;
104 switch (mWorkMode) {
105 case WorkMode::kAuthenticate:
Jeff Pu073af182023-07-12 18:53:52 +0000106 isTerminal = onAuthenticateFingerDown(mCb, mOperationId, mCancel);
Jeff Pudef5b042023-05-25 14:28:16 -0400107 break;
108 case WorkMode::kEnroll:
Jeff Pu073af182023-07-12 18:53:52 +0000109 isTerminal = onEnrollFingerDown(mCb, mHat, mCancel);
Jeff Pudef5b042023-05-25 14:28:16 -0400110 break;
111 case WorkMode::kDetectInteract:
Jeff Pu073af182023-07-12 18:53:52 +0000112 isTerminal = onDetectInteractFingerDown(mCb, mCancel);
Jeff Pudef5b042023-05-25 14:28:16 -0400113 break;
114 default:
115 LOG(WARNING) << "unexpected mode: on fingerDownAction(), " << (int)mWorkMode;
116 break;
117 }
Jeff Pu073af182023-07-12 18:53:52 +0000118
119 if (isTerminal) {
120 mWorkMode = WorkMode::kIdle;
121 }
Jeff Pudef5b042023-05-25 14:28:16 -0400122}
123
Jeff Pu073af182023-07-12 18:53:52 +0000124bool FakeFingerprintEngine::onEnrollFingerDown(ISessionCallback* cb,
Jeff Pu5055e3c2023-07-27 11:26:50 -0400125 const keymaster::HardwareAuthToken&,
Jeff Pudef5b042023-05-25 14:28:16 -0400126 const std::future<void>& cancel) {
Jeff Pu52653182022-10-12 16:27:23 -0400127 BEGIN_OP(getLatency(FingerprintHalProperties::operation_enroll_latency()));
Joe Bolingerde94aa02021-12-09 17:00:32 -0800128
Jeff Pu343ca942022-09-14 15:56:30 -0400129 // Force error-out
130 auto err = FingerprintHalProperties::operation_enroll_error().value_or(0);
131 if (err != 0) {
132 LOG(ERROR) << "Fail: operation_enroll_error";
133 auto ec = convertError(err);
134 cb->onError(ec.first, ec.second);
Jeff Pu073af182023-07-12 18:53:52 +0000135 return true;
Joe Bolingerde94aa02021-12-09 17:00:32 -0800136 }
137
Jeff Pu343ca942022-09-14 15:56:30 -0400138 // Format is "<id>:<progress_ms-[acquiredInfo..]>,...:<result>
Joe Bolingerde94aa02021-12-09 17:00:32 -0800139 auto nextEnroll = FingerprintHalProperties::next_enrollment().value_or("");
Joshua McCloskeydb009a52022-05-10 05:18:20 +0000140 auto parts = Util::split(nextEnroll, ":");
Joe Bolingerde94aa02021-12-09 17:00:32 -0800141 if (parts.size() != 3) {
Jeff Pu343ca942022-09-14 15:56:30 -0400142 LOG(ERROR) << "Fail: invalid next_enrollment:" << nextEnroll;
Joe Bolingerde94aa02021-12-09 17:00:32 -0800143 cb->onError(Error::VENDOR, 0 /* vendorError */);
Jeff Pu073af182023-07-12 18:53:52 +0000144 return true;
Joe Bolingerde94aa02021-12-09 17:00:32 -0800145 }
146 auto enrollmentId = std::stoi(parts[0]);
Jeff Pu484d2e72023-09-25 15:11:19 +0000147 auto progress = Util::parseEnrollmentCapture(parts[1]);
Jeff Pu343ca942022-09-14 15:56:30 -0400148 for (size_t i = 0; i < progress.size(); i += 2) {
149 auto left = (progress.size() - i) / 2 - 1;
150 auto duration = progress[i][0];
151 auto acquired = progress[i + 1];
152 auto N = acquired.size();
Joe Bolingerde94aa02021-12-09 17:00:32 -0800153
Jeff Pu343ca942022-09-14 15:56:30 -0400154 for (int j = 0; j < N; j++) {
155 SLEEP_MS(duration / N);
156
157 if (shouldCancel(cancel)) {
158 LOG(ERROR) << "Fail: cancel";
159 cb->onError(Error::CANCELED, 0 /* vendorCode */);
Jeff Pu073af182023-07-12 18:53:52 +0000160 return true;
Jeff Pu343ca942022-09-14 15:56:30 -0400161 }
162 auto ac = convertAcquiredInfo(acquired[j]);
163 cb->onAcquired(ac.first, ac.second);
Joe Bolingerde94aa02021-12-09 17:00:32 -0800164 }
165
Joe Bolingerde94aa02021-12-09 17:00:32 -0800166 if (left == 0 && !IS_TRUE(parts[2])) { // end and failed
167 LOG(ERROR) << "Fail: requested by caller: " << nextEnroll;
168 FingerprintHalProperties::next_enrollment({});
169 cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */);
170 } else { // progress and update props if last time
Jeff Pu343ca942022-09-14 15:56:30 -0400171 LOG(INFO) << "onEnroll: " << enrollmentId << " left: " << left;
Joe Bolingerde94aa02021-12-09 17:00:32 -0800172 if (left == 0) {
173 auto enrollments = FingerprintHalProperties::enrollments();
174 enrollments.emplace_back(enrollmentId);
175 FingerprintHalProperties::enrollments(enrollments);
176 FingerprintHalProperties::next_enrollment({});
Jeff Pu343ca942022-09-14 15:56:30 -0400177 // change authenticatorId after new enrollment
178 auto id = FingerprintHalProperties::authenticator_id().value_or(0);
179 auto newId = id + 1;
180 FingerprintHalProperties::authenticator_id(newId);
Joe Bolingerde94aa02021-12-09 17:00:32 -0800181 LOG(INFO) << "Enrolled: " << enrollmentId;
182 }
183 cb->onEnrollmentProgress(enrollmentId, left);
184 }
185 }
Jeff Pu073af182023-07-12 18:53:52 +0000186
187 return true;
Joe Bolingerde94aa02021-12-09 17:00:32 -0800188}
189
Jeff Pu073af182023-07-12 18:53:52 +0000190bool FakeFingerprintEngine::onAuthenticateFingerDown(ISessionCallback* cb,
Jeff Pudef5b042023-05-25 14:28:16 -0400191 int64_t /* operationId */,
192 const std::future<void>& cancel) {
Jeff Pu52653182022-10-12 16:27:23 -0400193 BEGIN_OP(getLatency(FingerprintHalProperties::operation_authenticate_latency()));
Joe Bolingerde94aa02021-12-09 17:00:32 -0800194
Jeff Pu343ca942022-09-14 15:56:30 -0400195 int64_t now = Util::getSystemNanoTime();
196 int64_t duration = FingerprintHalProperties::operation_authenticate_duration().value_or(10);
197 auto acquired = FingerprintHalProperties::operation_authenticate_acquired().value_or("1");
Jeff Pu484d2e72023-09-25 15:11:19 +0000198 auto acquiredInfos = Util::parseIntSequence(acquired);
Jeff Pu343ca942022-09-14 15:56:30 -0400199 int N = acquiredInfos.size();
200
201 if (N == 0) {
202 LOG(ERROR) << "Fail to parse authentiate acquired info: " + acquired;
203 cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
Jeff Pu073af182023-07-12 18:53:52 +0000204 return true;
Jeff Pu343ca942022-09-14 15:56:30 -0400205 }
206
Jeff Pu52653182022-10-12 16:27:23 -0400207 // got lockout?
Jeff Pu073af182023-07-12 18:53:52 +0000208 if (checkSensorLockout(cb)) {
209 return FakeLockoutTracker::LockoutMode::kPermanent == mLockoutTracker.getMode();
210 }
Jeff Pu52653182022-10-12 16:27:23 -0400211
Jeff Pu343ca942022-09-14 15:56:30 -0400212 int i = 0;
Joe Bolingerde94aa02021-12-09 17:00:32 -0800213 do {
214 if (FingerprintHalProperties::operation_authenticate_fails().value_or(false)) {
215 LOG(ERROR) << "Fail: operation_authenticate_fails";
Jeff Pu52653182022-10-12 16:27:23 -0400216 mLockoutTracker.addFailedAttempt();
Jeff Pu343ca942022-09-14 15:56:30 -0400217 cb->onAuthenticationFailed();
Jeff Pu073af182023-07-12 18:53:52 +0000218 return false;
Jeff Pu343ca942022-09-14 15:56:30 -0400219 }
220
221 auto err = FingerprintHalProperties::operation_authenticate_error().value_or(0);
222 if (err != 0) {
223 LOG(ERROR) << "Fail: operation_authenticate_error";
224 auto ec = convertError(err);
225 cb->onError(ec.first, ec.second);
Jeff Pu073af182023-07-12 18:53:52 +0000226 return true; /* simply terminating current operation for any user inserted error,
227 revisit if tests need*/
Joe Bolingerde94aa02021-12-09 17:00:32 -0800228 }
229
230 if (FingerprintHalProperties::lockout().value_or(false)) {
231 LOG(ERROR) << "Fail: lockout";
232 cb->onLockoutPermanent();
233 cb->onError(Error::HW_UNAVAILABLE, 0 /* vendorError */);
Jeff Pu073af182023-07-12 18:53:52 +0000234 return true;
Joe Bolingerde94aa02021-12-09 17:00:32 -0800235 }
236
237 if (shouldCancel(cancel)) {
238 LOG(ERROR) << "Fail: cancel";
239 cb->onError(Error::CANCELED, 0 /* vendorCode */);
Jeff Pu073af182023-07-12 18:53:52 +0000240 return true;
Joe Bolingerde94aa02021-12-09 17:00:32 -0800241 }
242
Jeff Pu343ca942022-09-14 15:56:30 -0400243 if (i < N) {
244 auto ac = convertAcquiredInfo(acquiredInfos[i]);
245 cb->onAcquired(ac.first, ac.second);
246 i++;
Joe Bolingerde94aa02021-12-09 17:00:32 -0800247 }
248
Jeff Pu343ca942022-09-14 15:56:30 -0400249 SLEEP_MS(duration / N);
Joshua McCloskeydb009a52022-05-10 05:18:20 +0000250 } while (!Util::hasElapsed(now, duration));
Joe Bolingerde94aa02021-12-09 17:00:32 -0800251
Jeff Pu343ca942022-09-14 15:56:30 -0400252 auto id = FingerprintHalProperties::enrollment_hit().value_or(0);
253 auto enrolls = FingerprintHalProperties::enrollments();
254 auto isEnrolled = std::find(enrolls.begin(), enrolls.end(), id) != enrolls.end();
255 if (id > 0 && isEnrolled) {
256 cb->onAuthenticationSucceeded(id, {} /* hat */);
Jeff Pu52653182022-10-12 16:27:23 -0400257 mLockoutTracker.reset();
Jeff Pu073af182023-07-12 18:53:52 +0000258 return true;
Jeff Pu343ca942022-09-14 15:56:30 -0400259 } else {
260 LOG(ERROR) << "Fail: fingerprint not enrolled";
261 cb->onAuthenticationFailed();
Jeff Pu52653182022-10-12 16:27:23 -0400262 mLockoutTracker.addFailedAttempt();
Jeff Pu437516e2023-06-28 15:21:21 +0000263 checkSensorLockout(cb);
Jeff Pu8fec5562023-07-20 13:07:04 +0000264 return false;
Jeff Pu343ca942022-09-14 15:56:30 -0400265 }
Joe Bolingerde94aa02021-12-09 17:00:32 -0800266}
267
Jeff Pu073af182023-07-12 18:53:52 +0000268bool FakeFingerprintEngine::onDetectInteractFingerDown(ISessionCallback* cb,
Jeff Pudef5b042023-05-25 14:28:16 -0400269 const std::future<void>& cancel) {
Jeff Pu52653182022-10-12 16:27:23 -0400270 BEGIN_OP(getLatency(FingerprintHalProperties::operation_detect_interaction_latency()));
Joe Bolingerde94aa02021-12-09 17:00:32 -0800271
Jeff Pu343ca942022-09-14 15:56:30 -0400272 int64_t duration =
273 FingerprintHalProperties::operation_detect_interaction_duration().value_or(10);
Jeff Pu52653182022-10-12 16:27:23 -0400274
Jeff Pu343ca942022-09-14 15:56:30 -0400275 auto acquired = FingerprintHalProperties::operation_detect_interaction_acquired().value_or("1");
Jeff Pu484d2e72023-09-25 15:11:19 +0000276 auto acquiredInfos = Util::parseIntSequence(acquired);
Jeff Pu343ca942022-09-14 15:56:30 -0400277 int N = acquiredInfos.size();
278 int64_t now = Util::getSystemNanoTime();
279
280 if (N == 0) {
281 LOG(ERROR) << "Fail to parse detect interaction acquired info: " + acquired;
282 cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
Jeff Pu073af182023-07-12 18:53:52 +0000283 return true;
Joe Bolingerde94aa02021-12-09 17:00:32 -0800284 }
285
Jeff Pu343ca942022-09-14 15:56:30 -0400286 int i = 0;
287 do {
288 auto err = FingerprintHalProperties::operation_detect_interaction_error().value_or(0);
289 if (err != 0) {
290 LOG(ERROR) << "Fail: operation_detect_interaction_error";
291 auto ec = convertError(err);
292 cb->onError(ec.first, ec.second);
Jeff Pu073af182023-07-12 18:53:52 +0000293 return true;
Jeff Pu343ca942022-09-14 15:56:30 -0400294 }
295
296 if (shouldCancel(cancel)) {
297 LOG(ERROR) << "Fail: cancel";
298 cb->onError(Error::CANCELED, 0 /* vendorCode */);
Jeff Pu073af182023-07-12 18:53:52 +0000299 return true;
Jeff Pu343ca942022-09-14 15:56:30 -0400300 }
301
302 if (i < N) {
303 auto ac = convertAcquiredInfo(acquiredInfos[i]);
304 cb->onAcquired(ac.first, ac.second);
305 i++;
306 }
307 SLEEP_MS(duration / N);
308 } while (!Util::hasElapsed(now, duration));
Joe Bolingerde94aa02021-12-09 17:00:32 -0800309
Joe Bolingerde94aa02021-12-09 17:00:32 -0800310 cb->onInteractionDetected();
Jeff Pu073af182023-07-12 18:53:52 +0000311
312 return true;
Joe Bolingerde94aa02021-12-09 17:00:32 -0800313}
314
315void FakeFingerprintEngine::enumerateEnrollmentsImpl(ISessionCallback* cb) {
316 BEGIN_OP(0);
317
318 std::vector<int32_t> ids;
319 for (auto& enrollment : FingerprintHalProperties::enrollments()) {
320 auto id = enrollment.value_or(0);
321 if (id > 0) {
322 ids.push_back(id);
323 }
324 }
325
326 cb->onEnrollmentsEnumerated(ids);
327}
328
329void FakeFingerprintEngine::removeEnrollmentsImpl(ISessionCallback* cb,
330 const std::vector<int32_t>& enrollmentIds) {
331 BEGIN_OP(0);
332
333 std::vector<std::optional<int32_t>> newEnrollments;
334 std::vector<int32_t> removed;
335 for (auto& enrollment : FingerprintHalProperties::enrollments()) {
336 auto id = enrollment.value_or(0);
337 if (std::find(enrollmentIds.begin(), enrollmentIds.end(), id) != enrollmentIds.end()) {
338 removed.push_back(id);
339 } else if (id > 0) {
340 newEnrollments.emplace_back(id);
341 }
342 }
343 FingerprintHalProperties::enrollments(newEnrollments);
344
345 cb->onEnrollmentsRemoved(enrollmentIds);
346}
347
348void FakeFingerprintEngine::getAuthenticatorIdImpl(ISessionCallback* cb) {
349 BEGIN_OP(0);
Jeff Pu343ca942022-09-14 15:56:30 -0400350 int64_t authenticatorId;
351 if (FingerprintHalProperties::enrollments().size() == 0) {
352 authenticatorId = 0;
353 } else {
354 authenticatorId = FingerprintHalProperties::authenticator_id().value_or(0);
355 if (authenticatorId == 0) authenticatorId = 1;
Jeff Pu63f33c72022-07-28 16:06:23 -0400356 }
357 cb->onAuthenticatorIdRetrieved(authenticatorId);
Joe Bolingerde94aa02021-12-09 17:00:32 -0800358}
359
360void FakeFingerprintEngine::invalidateAuthenticatorIdImpl(ISessionCallback* cb) {
361 BEGIN_OP(0);
Jeff Pu343ca942022-09-14 15:56:30 -0400362 int64_t newId;
363 if (FingerprintHalProperties::enrollments().size() == 0) {
364 newId = 0;
365 } else {
366 auto id = FingerprintHalProperties::authenticator_id().value_or(0);
367 newId = id + 1;
368 }
Joe Bolingerde94aa02021-12-09 17:00:32 -0800369 FingerprintHalProperties::authenticator_id(newId);
370 cb->onAuthenticatorIdInvalidated(newId);
371}
372
373void FakeFingerprintEngine::resetLockoutImpl(ISessionCallback* cb,
Jeff Pu343ca942022-09-14 15:56:30 -0400374 const keymaster::HardwareAuthToken& hat) {
Joe Bolingerde94aa02021-12-09 17:00:32 -0800375 BEGIN_OP(0);
Jeff Pu343ca942022-09-14 15:56:30 -0400376 if (hat.mac.empty()) {
377 LOG(ERROR) << "Fail: hat in resetLockout()";
378 cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
379 return;
380 }
Jeff Puc6f21462023-08-04 13:41:37 +0000381 clearLockout(cb);
Jeff Pu29df1e92023-10-06 14:12:44 +0000382 if (isLockoutTimerStarted) isLockoutTimerAborted = true;
Jeff Puc6f21462023-08-04 13:41:37 +0000383}
384
385void FakeFingerprintEngine::clearLockout(ISessionCallback* cb) {
Joe Bolingerde94aa02021-12-09 17:00:32 -0800386 FingerprintHalProperties::lockout(false);
387 cb->onLockoutCleared();
Jeff Pu52653182022-10-12 16:27:23 -0400388 mLockoutTracker.reset();
Joe Bolingerde94aa02021-12-09 17:00:32 -0800389}
390
Jeff Pu63f33c72022-07-28 16:06:23 -0400391ndk::ScopedAStatus FakeFingerprintEngine::onPointerDownImpl(int32_t /*pointerId*/, int32_t /*x*/,
392 int32_t /*y*/, float /*minor*/,
393 float /*major*/) {
394 BEGIN_OP(0);
Jeff Pudef5b042023-05-25 14:28:16 -0400395 fingerDownAction();
Jeff Pu63f33c72022-07-28 16:06:23 -0400396 return ndk::ScopedAStatus::ok();
397}
398
399ndk::ScopedAStatus FakeFingerprintEngine::onPointerUpImpl(int32_t /*pointerId*/) {
400 BEGIN_OP(0);
401 return ndk::ScopedAStatus::ok();
402}
403
404ndk::ScopedAStatus FakeFingerprintEngine::onUiReadyImpl() {
405 BEGIN_OP(0);
406 return ndk::ScopedAStatus::ok();
407}
408
409bool FakeFingerprintEngine::getSensorLocationConfig(SensorLocation& out) {
410 auto loc = FingerprintHalProperties::sensor_location().value_or("");
411 auto isValidStr = false;
412 auto dim = Util::split(loc, ":");
413
414 if (dim.size() < 3 or dim.size() > 4) {
415 if (!loc.empty()) LOG(WARNING) << "Invalid sensor location input (x:y:radius):" + loc;
416 return false;
417 } else {
418 int32_t x, y, r;
419 std::string d = "";
420 if (dim.size() >= 3) {
421 isValidStr = ParseInt(dim[0], &x) && ParseInt(dim[1], &y) && ParseInt(dim[2], &r);
422 }
423 if (dim.size() >= 4) {
424 d = dim[3];
425 }
Jeff Pudef5b042023-05-25 14:28:16 -0400426 if (isValidStr)
427 out = {.sensorLocationX = x, .sensorLocationY = y, .sensorRadius = r, .display = d};
Jeff Pu63f33c72022-07-28 16:06:23 -0400428
429 return isValidStr;
430 }
431}
432SensorLocation FakeFingerprintEngine::getSensorLocation() {
433 SensorLocation location;
434
435 if (getSensorLocationConfig(location)) {
436 return location;
437 } else {
438 return defaultSensorLocation();
439 }
440}
441
442SensorLocation FakeFingerprintEngine::defaultSensorLocation() {
Jeff Pudef5b042023-05-25 14:28:16 -0400443 return SensorLocation();
Jeff Pu63f33c72022-07-28 16:06:23 -0400444}
Jeff Pu343ca942022-09-14 15:56:30 -0400445
Jeff Pu343ca942022-09-14 15:56:30 -0400446std::pair<AcquiredInfo, int32_t> FakeFingerprintEngine::convertAcquiredInfo(int32_t code) {
447 std::pair<AcquiredInfo, int32_t> res;
448 if (code > FINGERPRINT_ACQUIRED_VENDOR_BASE) {
449 res.first = AcquiredInfo::VENDOR;
450 res.second = code - FINGERPRINT_ACQUIRED_VENDOR_BASE;
451 } else {
452 res.first = (AcquiredInfo)code;
453 res.second = 0;
454 }
455 return res;
456}
457
458std::pair<Error, int32_t> FakeFingerprintEngine::convertError(int32_t code) {
459 std::pair<Error, int32_t> res;
460 if (code > FINGERPRINT_ERROR_VENDOR_BASE) {
461 res.first = Error::VENDOR;
462 res.second = code - FINGERPRINT_ERROR_VENDOR_BASE;
463 } else {
464 res.first = (Error)code;
465 res.second = 0;
466 }
467 return res;
468}
469
Jeff Pu52653182022-10-12 16:27:23 -0400470int32_t FakeFingerprintEngine::getLatency(
471 const std::vector<std::optional<std::int32_t>>& latencyIn) {
472 int32_t res = DEFAULT_LATENCY;
473
474 std::vector<int32_t> latency;
475 for (auto x : latencyIn)
476 if (x.has_value()) latency.push_back(*x);
477
478 switch (latency.size()) {
479 case 0:
480 break;
481 case 1:
482 res = latency[0];
483 break;
484 case 2:
485 res = getRandomInRange(latency[0], latency[1]);
486 break;
487 default:
488 LOG(ERROR) << "ERROR: unexpected input of size " << latency.size();
489 break;
490 }
491
492 return res;
493}
494
495int32_t FakeFingerprintEngine::getRandomInRange(int32_t bound1, int32_t bound2) {
496 std::uniform_int_distribution<int32_t> dist(std::min(bound1, bound2), std::max(bound1, bound2));
497 return dist(mRandom);
498}
499
Jeff Pu437516e2023-06-28 15:21:21 +0000500bool FakeFingerprintEngine::checkSensorLockout(ISessionCallback* cb) {
501 FakeLockoutTracker::LockoutMode lockoutMode = mLockoutTracker.getMode();
502 if (lockoutMode == FakeLockoutTracker::LockoutMode::kPermanent) {
503 LOG(ERROR) << "Fail: lockout permanent";
504 cb->onLockoutPermanent();
Jeff Puc6f21462023-08-04 13:41:37 +0000505 isLockoutTimerAborted = true;
Jeff Pu437516e2023-06-28 15:21:21 +0000506 return true;
507 } else if (lockoutMode == FakeLockoutTracker::LockoutMode::kTimed) {
508 int64_t timeLeft = mLockoutTracker.getLockoutTimeLeft();
509 LOG(ERROR) << "Fail: lockout timed " << timeLeft;
510 cb->onLockoutTimed(timeLeft);
Jeff Puc6f21462023-08-04 13:41:37 +0000511 if (isLockoutTimerSupported && !isLockoutTimerStarted) startLockoutTimer(timeLeft, cb);
Jeff Pu437516e2023-06-28 15:21:21 +0000512 return true;
513 }
514 return false;
515}
Jeff Puc6f21462023-08-04 13:41:37 +0000516
517void FakeFingerprintEngine::startLockoutTimer(int64_t timeout, ISessionCallback* cb) {
518 BEGIN_OP(0);
519 std::function<void(ISessionCallback*)> action =
520 std::bind(&FakeFingerprintEngine::lockoutTimerExpired, this, std::placeholders::_1);
521 std::thread([timeout, action, cb]() {
522 std::this_thread::sleep_for(std::chrono::milliseconds(timeout));
523 action(cb);
524 }).detach();
525
526 isLockoutTimerStarted = true;
527}
528void FakeFingerprintEngine::lockoutTimerExpired(ISessionCallback* cb) {
Jeff Pu29df1e92023-10-06 14:12:44 +0000529 BEGIN_OP(0);
Jeff Puc6f21462023-08-04 13:41:37 +0000530 if (!isLockoutTimerAborted) {
531 clearLockout(cb);
532 }
533 isLockoutTimerStarted = false;
534 isLockoutTimerAborted = false;
535}
Joe Bolingerde94aa02021-12-09 17:00:32 -0800536} // namespace aidl::android::hardware::biometrics::fingerprint