1*4d7e907cSAndroid Build Coastguard Worker /*
2*4d7e907cSAndroid Build Coastguard Worker * Copyright (C) 2022 The Android Open Source Project
3*4d7e907cSAndroid Build Coastguard Worker *
4*4d7e907cSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*4d7e907cSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*4d7e907cSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*4d7e907cSAndroid Build Coastguard Worker *
8*4d7e907cSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*4d7e907cSAndroid Build Coastguard Worker *
10*4d7e907cSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*4d7e907cSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*4d7e907cSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4d7e907cSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*4d7e907cSAndroid Build Coastguard Worker * limitations under the License.
15*4d7e907cSAndroid Build Coastguard Worker */
16*4d7e907cSAndroid Build Coastguard Worker
17*4d7e907cSAndroid Build Coastguard Worker #include "FakeFingerprintEngine.h"
18*4d7e907cSAndroid Build Coastguard Worker #include <regex>
19*4d7e907cSAndroid Build Coastguard Worker #include "Fingerprint.h"
20*4d7e907cSAndroid Build Coastguard Worker
21*4d7e907cSAndroid Build Coastguard Worker #include <android-base/logging.h>
22*4d7e907cSAndroid Build Coastguard Worker #include <android-base/parseint.h>
23*4d7e907cSAndroid Build Coastguard Worker
24*4d7e907cSAndroid Build Coastguard Worker #include <fingerprint.sysprop.h>
25*4d7e907cSAndroid Build Coastguard Worker
26*4d7e907cSAndroid Build Coastguard Worker #include "util/CancellationSignal.h"
27*4d7e907cSAndroid Build Coastguard Worker #include "util/Util.h"
28*4d7e907cSAndroid Build Coastguard Worker
29*4d7e907cSAndroid Build Coastguard Worker using namespace ::android::fingerprint::virt;
30*4d7e907cSAndroid Build Coastguard Worker using ::android::base::ParseInt;
31*4d7e907cSAndroid Build Coastguard Worker
32*4d7e907cSAndroid Build Coastguard Worker namespace aidl::android::hardware::biometrics::fingerprint {
33*4d7e907cSAndroid Build Coastguard Worker
FakeFingerprintEngine()34*4d7e907cSAndroid Build Coastguard Worker FakeFingerprintEngine::FakeFingerprintEngine()
35*4d7e907cSAndroid Build Coastguard Worker : mRandom(std::mt19937::default_seed),
36*4d7e907cSAndroid Build Coastguard Worker mWorkMode(WorkMode::kIdle),
37*4d7e907cSAndroid Build Coastguard Worker isLockoutTimerSupported(true) {}
38*4d7e907cSAndroid Build Coastguard Worker
generateChallengeImpl(ISessionCallback * cb)39*4d7e907cSAndroid Build Coastguard Worker void FakeFingerprintEngine::generateChallengeImpl(ISessionCallback* cb) {
40*4d7e907cSAndroid Build Coastguard Worker BEGIN_OP(0);
41*4d7e907cSAndroid Build Coastguard Worker std::uniform_int_distribution<int64_t> dist;
42*4d7e907cSAndroid Build Coastguard Worker auto challenge = dist(mRandom);
43*4d7e907cSAndroid Build Coastguard Worker Fingerprint::cfg().set<std::int64_t>("challenge", challenge);
44*4d7e907cSAndroid Build Coastguard Worker cb->onChallengeGenerated(challenge);
45*4d7e907cSAndroid Build Coastguard Worker }
46*4d7e907cSAndroid Build Coastguard Worker
revokeChallengeImpl(ISessionCallback * cb,int64_t challenge)47*4d7e907cSAndroid Build Coastguard Worker void FakeFingerprintEngine::revokeChallengeImpl(ISessionCallback* cb, int64_t challenge) {
48*4d7e907cSAndroid Build Coastguard Worker BEGIN_OP(0);
49*4d7e907cSAndroid Build Coastguard Worker Fingerprint::cfg().setopt<OptInt64>("challenge", std::nullopt);
50*4d7e907cSAndroid Build Coastguard Worker cb->onChallengeRevoked(challenge);
51*4d7e907cSAndroid Build Coastguard Worker }
52*4d7e907cSAndroid Build Coastguard Worker
enrollImpl(ISessionCallback * cb,const keymaster::HardwareAuthToken & hat,const std::future<void> & cancel)53*4d7e907cSAndroid Build Coastguard Worker void FakeFingerprintEngine::enrollImpl(ISessionCallback* cb,
54*4d7e907cSAndroid Build Coastguard Worker const keymaster::HardwareAuthToken& hat,
55*4d7e907cSAndroid Build Coastguard Worker const std::future<void>& cancel) {
56*4d7e907cSAndroid Build Coastguard Worker BEGIN_OP(0);
57*4d7e907cSAndroid Build Coastguard Worker
58*4d7e907cSAndroid Build Coastguard Worker // Do proper HAT verification in the real implementation.
59*4d7e907cSAndroid Build Coastguard Worker if (hat.mac.empty()) {
60*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Fail: hat";
61*4d7e907cSAndroid Build Coastguard Worker cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
62*4d7e907cSAndroid Build Coastguard Worker return;
63*4d7e907cSAndroid Build Coastguard Worker }
64*4d7e907cSAndroid Build Coastguard Worker
65*4d7e907cSAndroid Build Coastguard Worker waitForFingerDown(cb, cancel);
66*4d7e907cSAndroid Build Coastguard Worker
67*4d7e907cSAndroid Build Coastguard Worker updateContext(WorkMode::kEnroll, cb, const_cast<std::future<void>&>(cancel), 0, hat);
68*4d7e907cSAndroid Build Coastguard Worker }
69*4d7e907cSAndroid Build Coastguard Worker
authenticateImpl(ISessionCallback * cb,int64_t operationId,const std::future<void> & cancel)70*4d7e907cSAndroid Build Coastguard Worker void FakeFingerprintEngine::authenticateImpl(ISessionCallback* cb, int64_t operationId,
71*4d7e907cSAndroid Build Coastguard Worker const std::future<void>& cancel) {
72*4d7e907cSAndroid Build Coastguard Worker BEGIN_OP(0);
73*4d7e907cSAndroid Build Coastguard Worker
74*4d7e907cSAndroid Build Coastguard Worker waitForFingerDown(cb, cancel);
75*4d7e907cSAndroid Build Coastguard Worker
76*4d7e907cSAndroid Build Coastguard Worker updateContext(WorkMode::kAuthenticate, cb, const_cast<std::future<void>&>(cancel), operationId,
77*4d7e907cSAndroid Build Coastguard Worker keymaster::HardwareAuthToken());
78*4d7e907cSAndroid Build Coastguard Worker }
79*4d7e907cSAndroid Build Coastguard Worker
detectInteractionImpl(ISessionCallback * cb,const std::future<void> & cancel)80*4d7e907cSAndroid Build Coastguard Worker void FakeFingerprintEngine::detectInteractionImpl(ISessionCallback* cb,
81*4d7e907cSAndroid Build Coastguard Worker const std::future<void>& cancel) {
82*4d7e907cSAndroid Build Coastguard Worker BEGIN_OP(0);
83*4d7e907cSAndroid Build Coastguard Worker
84*4d7e907cSAndroid Build Coastguard Worker auto detectInteractionSupported = Fingerprint::cfg().get<bool>("detect_interaction");
85*4d7e907cSAndroid Build Coastguard Worker if (!detectInteractionSupported) {
86*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Detect interaction is not supported";
87*4d7e907cSAndroid Build Coastguard Worker cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
88*4d7e907cSAndroid Build Coastguard Worker return;
89*4d7e907cSAndroid Build Coastguard Worker }
90*4d7e907cSAndroid Build Coastguard Worker
91*4d7e907cSAndroid Build Coastguard Worker waitForFingerDown(cb, cancel);
92*4d7e907cSAndroid Build Coastguard Worker
93*4d7e907cSAndroid Build Coastguard Worker updateContext(WorkMode::kDetectInteract, cb, const_cast<std::future<void>&>(cancel), 0,
94*4d7e907cSAndroid Build Coastguard Worker keymaster::HardwareAuthToken());
95*4d7e907cSAndroid Build Coastguard Worker }
96*4d7e907cSAndroid Build Coastguard Worker
updateContext(WorkMode mode,ISessionCallback * cb,std::future<void> & cancel,int64_t operationId,const keymaster::HardwareAuthToken & hat)97*4d7e907cSAndroid Build Coastguard Worker void FakeFingerprintEngine::updateContext(WorkMode mode, ISessionCallback* cb,
98*4d7e907cSAndroid Build Coastguard Worker std::future<void>& cancel, int64_t operationId,
99*4d7e907cSAndroid Build Coastguard Worker const keymaster::HardwareAuthToken& hat) {
100*4d7e907cSAndroid Build Coastguard Worker mCancel = std::move(cancel);
101*4d7e907cSAndroid Build Coastguard Worker mWorkMode = mode;
102*4d7e907cSAndroid Build Coastguard Worker mCb = cb;
103*4d7e907cSAndroid Build Coastguard Worker mOperationId = operationId;
104*4d7e907cSAndroid Build Coastguard Worker mHat = hat;
105*4d7e907cSAndroid Build Coastguard Worker }
106*4d7e907cSAndroid Build Coastguard Worker
fingerDownAction()107*4d7e907cSAndroid Build Coastguard Worker void FakeFingerprintEngine::fingerDownAction() {
108*4d7e907cSAndroid Build Coastguard Worker bool isTerminal = false;
109*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << __func__;
110*4d7e907cSAndroid Build Coastguard Worker switch (mWorkMode) {
111*4d7e907cSAndroid Build Coastguard Worker case WorkMode::kAuthenticate:
112*4d7e907cSAndroid Build Coastguard Worker isTerminal = onAuthenticateFingerDown(mCb, mOperationId, mCancel);
113*4d7e907cSAndroid Build Coastguard Worker break;
114*4d7e907cSAndroid Build Coastguard Worker case WorkMode::kEnroll:
115*4d7e907cSAndroid Build Coastguard Worker isTerminal = onEnrollFingerDown(mCb, mHat, mCancel);
116*4d7e907cSAndroid Build Coastguard Worker break;
117*4d7e907cSAndroid Build Coastguard Worker case WorkMode::kDetectInteract:
118*4d7e907cSAndroid Build Coastguard Worker isTerminal = onDetectInteractFingerDown(mCb, mCancel);
119*4d7e907cSAndroid Build Coastguard Worker break;
120*4d7e907cSAndroid Build Coastguard Worker default:
121*4d7e907cSAndroid Build Coastguard Worker LOG(WARNING) << "unexpected mode: on fingerDownAction(), " << (int)mWorkMode;
122*4d7e907cSAndroid Build Coastguard Worker break;
123*4d7e907cSAndroid Build Coastguard Worker }
124*4d7e907cSAndroid Build Coastguard Worker
125*4d7e907cSAndroid Build Coastguard Worker if (isTerminal) {
126*4d7e907cSAndroid Build Coastguard Worker mWorkMode = WorkMode::kIdle;
127*4d7e907cSAndroid Build Coastguard Worker }
128*4d7e907cSAndroid Build Coastguard Worker }
129*4d7e907cSAndroid Build Coastguard Worker
onEnrollFingerDown(ISessionCallback * cb,const keymaster::HardwareAuthToken &,const std::future<void> & cancel)130*4d7e907cSAndroid Build Coastguard Worker bool FakeFingerprintEngine::onEnrollFingerDown(ISessionCallback* cb,
131*4d7e907cSAndroid Build Coastguard Worker const keymaster::HardwareAuthToken&,
132*4d7e907cSAndroid Build Coastguard Worker const std::future<void>& cancel) {
133*4d7e907cSAndroid Build Coastguard Worker BEGIN_OP(getLatency(Fingerprint::cfg().getopt<OptIntVec>("operation_enroll_latency")));
134*4d7e907cSAndroid Build Coastguard Worker
135*4d7e907cSAndroid Build Coastguard Worker // Force error-out
136*4d7e907cSAndroid Build Coastguard Worker auto err = Fingerprint::cfg().get<std::int32_t>("operation_enroll_error");
137*4d7e907cSAndroid Build Coastguard Worker if (err != 0) {
138*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Fail: operation_enroll_error";
139*4d7e907cSAndroid Build Coastguard Worker auto ec = convertError(err);
140*4d7e907cSAndroid Build Coastguard Worker cb->onError(ec.first, ec.second);
141*4d7e907cSAndroid Build Coastguard Worker return true;
142*4d7e907cSAndroid Build Coastguard Worker }
143*4d7e907cSAndroid Build Coastguard Worker
144*4d7e907cSAndroid Build Coastguard Worker // Format is "<id>:<progress_ms-[acquiredInfo..]>,...:<result>
145*4d7e907cSAndroid Build Coastguard Worker auto nextEnroll = Fingerprint::cfg().get<std::string>("next_enrollment");
146*4d7e907cSAndroid Build Coastguard Worker auto parts = Util::split(nextEnroll, ":");
147*4d7e907cSAndroid Build Coastguard Worker if (parts.size() != 3) {
148*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Fail: invalid next_enrollment:" << nextEnroll;
149*4d7e907cSAndroid Build Coastguard Worker cb->onError(Error::VENDOR, 0 /* vendorError */);
150*4d7e907cSAndroid Build Coastguard Worker return true;
151*4d7e907cSAndroid Build Coastguard Worker }
152*4d7e907cSAndroid Build Coastguard Worker auto enrollmentId = std::stoi(parts[0]);
153*4d7e907cSAndroid Build Coastguard Worker auto progress = Util::parseEnrollmentCapture(parts[1]);
154*4d7e907cSAndroid Build Coastguard Worker for (size_t i = 0; i < progress.size(); i += 2) {
155*4d7e907cSAndroid Build Coastguard Worker auto left = (progress.size() - i) / 2 - 1;
156*4d7e907cSAndroid Build Coastguard Worker auto duration = progress[i][0];
157*4d7e907cSAndroid Build Coastguard Worker auto acquired = progress[i + 1];
158*4d7e907cSAndroid Build Coastguard Worker auto N = acquired.size();
159*4d7e907cSAndroid Build Coastguard Worker
160*4d7e907cSAndroid Build Coastguard Worker for (int j = 0; j < N; j++) {
161*4d7e907cSAndroid Build Coastguard Worker SLEEP_MS(duration / N);
162*4d7e907cSAndroid Build Coastguard Worker
163*4d7e907cSAndroid Build Coastguard Worker if (shouldCancel(cancel)) {
164*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Fail: cancel";
165*4d7e907cSAndroid Build Coastguard Worker cb->onError(Error::CANCELED, 0 /* vendorCode */);
166*4d7e907cSAndroid Build Coastguard Worker return true;
167*4d7e907cSAndroid Build Coastguard Worker }
168*4d7e907cSAndroid Build Coastguard Worker auto ac = convertAcquiredInfo(acquired[j]);
169*4d7e907cSAndroid Build Coastguard Worker cb->onAcquired(ac.first, ac.second);
170*4d7e907cSAndroid Build Coastguard Worker }
171*4d7e907cSAndroid Build Coastguard Worker
172*4d7e907cSAndroid Build Coastguard Worker if (left == 0 && !IS_TRUE(parts[2])) { // end and failed
173*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Fail: requested by caller: " << nextEnroll;
174*4d7e907cSAndroid Build Coastguard Worker Fingerprint::cfg().set<std::string>("next_enrollment", "");
175*4d7e907cSAndroid Build Coastguard Worker cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */);
176*4d7e907cSAndroid Build Coastguard Worker } else { // progress and update props if last time
177*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << "onEnroll: " << enrollmentId << " left: " << left;
178*4d7e907cSAndroid Build Coastguard Worker if (left == 0) {
179*4d7e907cSAndroid Build Coastguard Worker auto enrollments = Fingerprint::cfg().getopt<OptIntVec>("enrollments");
180*4d7e907cSAndroid Build Coastguard Worker enrollments.emplace_back(enrollmentId);
181*4d7e907cSAndroid Build Coastguard Worker Fingerprint::cfg().setopt<OptIntVec>("enrollments", enrollments);
182*4d7e907cSAndroid Build Coastguard Worker Fingerprint::cfg().setopt<OptString>("next_enrollment", std::nullopt);
183*4d7e907cSAndroid Build Coastguard Worker // change authenticatorId after new enrollment
184*4d7e907cSAndroid Build Coastguard Worker auto id = Fingerprint::cfg().get<std::int64_t>("authenticator_id");
185*4d7e907cSAndroid Build Coastguard Worker auto newId = id + 1;
186*4d7e907cSAndroid Build Coastguard Worker Fingerprint::cfg().set<std::int64_t>("authenticator_id", newId);
187*4d7e907cSAndroid Build Coastguard Worker LOG(INFO) << "Enrolled: " << enrollmentId;
188*4d7e907cSAndroid Build Coastguard Worker }
189*4d7e907cSAndroid Build Coastguard Worker cb->onEnrollmentProgress(enrollmentId, left);
190*4d7e907cSAndroid Build Coastguard Worker }
191*4d7e907cSAndroid Build Coastguard Worker }
192*4d7e907cSAndroid Build Coastguard Worker
193*4d7e907cSAndroid Build Coastguard Worker return true;
194*4d7e907cSAndroid Build Coastguard Worker }
195*4d7e907cSAndroid Build Coastguard Worker
onAuthenticateFingerDown(ISessionCallback * cb,int64_t,const std::future<void> & cancel)196*4d7e907cSAndroid Build Coastguard Worker bool FakeFingerprintEngine::onAuthenticateFingerDown(ISessionCallback* cb,
197*4d7e907cSAndroid Build Coastguard Worker int64_t /* operationId */,
198*4d7e907cSAndroid Build Coastguard Worker const std::future<void>& cancel) {
199*4d7e907cSAndroid Build Coastguard Worker BEGIN_OP(getLatency(Fingerprint::cfg().getopt<OptIntVec>("operation_authenticate_latency")));
200*4d7e907cSAndroid Build Coastguard Worker
201*4d7e907cSAndroid Build Coastguard Worker int64_t now = Util::getSystemNanoTime();
202*4d7e907cSAndroid Build Coastguard Worker int64_t duration = Fingerprint::cfg().get<std::int32_t>("operation_authenticate_duration");
203*4d7e907cSAndroid Build Coastguard Worker auto acquired = Fingerprint::cfg().get<std::string>("operation_authenticate_acquired");
204*4d7e907cSAndroid Build Coastguard Worker auto acquiredInfos = Util::parseIntSequence(acquired);
205*4d7e907cSAndroid Build Coastguard Worker int N = acquiredInfos.size();
206*4d7e907cSAndroid Build Coastguard Worker
207*4d7e907cSAndroid Build Coastguard Worker if (N == 0) {
208*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Fail to parse authentiate acquired info: " + acquired;
209*4d7e907cSAndroid Build Coastguard Worker cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
210*4d7e907cSAndroid Build Coastguard Worker return true;
211*4d7e907cSAndroid Build Coastguard Worker }
212*4d7e907cSAndroid Build Coastguard Worker
213*4d7e907cSAndroid Build Coastguard Worker // got lockout?
214*4d7e907cSAndroid Build Coastguard Worker if (checkSensorLockout(cb)) {
215*4d7e907cSAndroid Build Coastguard Worker return FakeLockoutTracker::LockoutMode::kPermanent == mLockoutTracker.getMode();
216*4d7e907cSAndroid Build Coastguard Worker }
217*4d7e907cSAndroid Build Coastguard Worker
218*4d7e907cSAndroid Build Coastguard Worker int i = 0;
219*4d7e907cSAndroid Build Coastguard Worker do {
220*4d7e907cSAndroid Build Coastguard Worker if (Fingerprint::cfg().get<bool>("operation_authenticate_fails")) {
221*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Fail: operation_authenticate_fails";
222*4d7e907cSAndroid Build Coastguard Worker mLockoutTracker.addFailedAttempt();
223*4d7e907cSAndroid Build Coastguard Worker cb->onAuthenticationFailed();
224*4d7e907cSAndroid Build Coastguard Worker return false;
225*4d7e907cSAndroid Build Coastguard Worker }
226*4d7e907cSAndroid Build Coastguard Worker
227*4d7e907cSAndroid Build Coastguard Worker auto err = Fingerprint::cfg().get<std::int32_t>("operation_authenticate_error");
228*4d7e907cSAndroid Build Coastguard Worker if (err != 0) {
229*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Fail: operation_authenticate_error";
230*4d7e907cSAndroid Build Coastguard Worker auto ec = convertError(err);
231*4d7e907cSAndroid Build Coastguard Worker cb->onError(ec.first, ec.second);
232*4d7e907cSAndroid Build Coastguard Worker return true; /* simply terminating current operation for any user inserted error,
233*4d7e907cSAndroid Build Coastguard Worker revisit if tests need*/
234*4d7e907cSAndroid Build Coastguard Worker }
235*4d7e907cSAndroid Build Coastguard Worker
236*4d7e907cSAndroid Build Coastguard Worker if (Fingerprint::cfg().get<bool>("lockout")) {
237*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Fail: lockout";
238*4d7e907cSAndroid Build Coastguard Worker cb->onLockoutPermanent();
239*4d7e907cSAndroid Build Coastguard Worker cb->onError(Error::HW_UNAVAILABLE, 0 /* vendorError */);
240*4d7e907cSAndroid Build Coastguard Worker return true;
241*4d7e907cSAndroid Build Coastguard Worker }
242*4d7e907cSAndroid Build Coastguard Worker
243*4d7e907cSAndroid Build Coastguard Worker if (shouldCancel(cancel)) {
244*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Fail: cancel";
245*4d7e907cSAndroid Build Coastguard Worker cb->onError(Error::CANCELED, 0 /* vendorCode */);
246*4d7e907cSAndroid Build Coastguard Worker return true;
247*4d7e907cSAndroid Build Coastguard Worker }
248*4d7e907cSAndroid Build Coastguard Worker
249*4d7e907cSAndroid Build Coastguard Worker if (i < N) {
250*4d7e907cSAndroid Build Coastguard Worker auto ac = convertAcquiredInfo(acquiredInfos[i]);
251*4d7e907cSAndroid Build Coastguard Worker cb->onAcquired(ac.first, ac.second);
252*4d7e907cSAndroid Build Coastguard Worker i++;
253*4d7e907cSAndroid Build Coastguard Worker }
254*4d7e907cSAndroid Build Coastguard Worker
255*4d7e907cSAndroid Build Coastguard Worker SLEEP_MS(duration / N);
256*4d7e907cSAndroid Build Coastguard Worker } while (!Util::hasElapsed(now, duration));
257*4d7e907cSAndroid Build Coastguard Worker
258*4d7e907cSAndroid Build Coastguard Worker auto id = Fingerprint::cfg().get<std::int32_t>("enrollment_hit");
259*4d7e907cSAndroid Build Coastguard Worker auto enrolls = Fingerprint::cfg().getopt<OptIntVec>("enrollments");
260*4d7e907cSAndroid Build Coastguard Worker auto isEnrolled = std::find(enrolls.begin(), enrolls.end(), id) != enrolls.end();
261*4d7e907cSAndroid Build Coastguard Worker if (id > 0 && isEnrolled) {
262*4d7e907cSAndroid Build Coastguard Worker cb->onAuthenticationSucceeded(id, {} /* hat */);
263*4d7e907cSAndroid Build Coastguard Worker mLockoutTracker.reset();
264*4d7e907cSAndroid Build Coastguard Worker return true;
265*4d7e907cSAndroid Build Coastguard Worker } else {
266*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Fail: fingerprint not enrolled";
267*4d7e907cSAndroid Build Coastguard Worker cb->onAuthenticationFailed();
268*4d7e907cSAndroid Build Coastguard Worker mLockoutTracker.addFailedAttempt();
269*4d7e907cSAndroid Build Coastguard Worker checkSensorLockout(cb);
270*4d7e907cSAndroid Build Coastguard Worker return false;
271*4d7e907cSAndroid Build Coastguard Worker }
272*4d7e907cSAndroid Build Coastguard Worker }
273*4d7e907cSAndroid Build Coastguard Worker
onDetectInteractFingerDown(ISessionCallback * cb,const std::future<void> & cancel)274*4d7e907cSAndroid Build Coastguard Worker bool FakeFingerprintEngine::onDetectInteractFingerDown(ISessionCallback* cb,
275*4d7e907cSAndroid Build Coastguard Worker const std::future<void>& cancel) {
276*4d7e907cSAndroid Build Coastguard Worker BEGIN_OP(getLatency(
277*4d7e907cSAndroid Build Coastguard Worker Fingerprint::cfg().getopt<OptIntVec>("operation_detect_interaction_latency")));
278*4d7e907cSAndroid Build Coastguard Worker
279*4d7e907cSAndroid Build Coastguard Worker int32_t duration =
280*4d7e907cSAndroid Build Coastguard Worker Fingerprint::cfg().get<std::int32_t>("operation_detect_interaction_duration");
281*4d7e907cSAndroid Build Coastguard Worker
282*4d7e907cSAndroid Build Coastguard Worker auto acquired = Fingerprint::cfg().get<std::string>("operation_detect_interaction_acquired");
283*4d7e907cSAndroid Build Coastguard Worker auto acquiredInfos = Util::parseIntSequence(acquired);
284*4d7e907cSAndroid Build Coastguard Worker int N = acquiredInfos.size();
285*4d7e907cSAndroid Build Coastguard Worker int64_t now = Util::getSystemNanoTime();
286*4d7e907cSAndroid Build Coastguard Worker
287*4d7e907cSAndroid Build Coastguard Worker if (N == 0) {
288*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Fail to parse detect interaction acquired info: " + acquired;
289*4d7e907cSAndroid Build Coastguard Worker cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
290*4d7e907cSAndroid Build Coastguard Worker return true;
291*4d7e907cSAndroid Build Coastguard Worker }
292*4d7e907cSAndroid Build Coastguard Worker
293*4d7e907cSAndroid Build Coastguard Worker int i = 0;
294*4d7e907cSAndroid Build Coastguard Worker do {
295*4d7e907cSAndroid Build Coastguard Worker auto err = Fingerprint::cfg().get<std::int32_t>("operation_detect_interaction_error");
296*4d7e907cSAndroid Build Coastguard Worker if (err != 0) {
297*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Fail: operation_detect_interaction_error";
298*4d7e907cSAndroid Build Coastguard Worker auto ec = convertError(err);
299*4d7e907cSAndroid Build Coastguard Worker cb->onError(ec.first, ec.second);
300*4d7e907cSAndroid Build Coastguard Worker return true;
301*4d7e907cSAndroid Build Coastguard Worker }
302*4d7e907cSAndroid Build Coastguard Worker
303*4d7e907cSAndroid Build Coastguard Worker if (shouldCancel(cancel)) {
304*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Fail: cancel";
305*4d7e907cSAndroid Build Coastguard Worker cb->onError(Error::CANCELED, 0 /* vendorCode */);
306*4d7e907cSAndroid Build Coastguard Worker return true;
307*4d7e907cSAndroid Build Coastguard Worker }
308*4d7e907cSAndroid Build Coastguard Worker
309*4d7e907cSAndroid Build Coastguard Worker if (i < N) {
310*4d7e907cSAndroid Build Coastguard Worker auto ac = convertAcquiredInfo(acquiredInfos[i]);
311*4d7e907cSAndroid Build Coastguard Worker cb->onAcquired(ac.first, ac.second);
312*4d7e907cSAndroid Build Coastguard Worker i++;
313*4d7e907cSAndroid Build Coastguard Worker }
314*4d7e907cSAndroid Build Coastguard Worker SLEEP_MS(duration / N);
315*4d7e907cSAndroid Build Coastguard Worker } while (!Util::hasElapsed(now, duration));
316*4d7e907cSAndroid Build Coastguard Worker
317*4d7e907cSAndroid Build Coastguard Worker cb->onInteractionDetected();
318*4d7e907cSAndroid Build Coastguard Worker
319*4d7e907cSAndroid Build Coastguard Worker return true;
320*4d7e907cSAndroid Build Coastguard Worker }
321*4d7e907cSAndroid Build Coastguard Worker
enumerateEnrollmentsImpl(ISessionCallback * cb)322*4d7e907cSAndroid Build Coastguard Worker void FakeFingerprintEngine::enumerateEnrollmentsImpl(ISessionCallback* cb) {
323*4d7e907cSAndroid Build Coastguard Worker BEGIN_OP(0);
324*4d7e907cSAndroid Build Coastguard Worker
325*4d7e907cSAndroid Build Coastguard Worker std::vector<int32_t> ids;
326*4d7e907cSAndroid Build Coastguard Worker for (auto& enrollment : Fingerprint::cfg().getopt<OptIntVec>("enrollments")) {
327*4d7e907cSAndroid Build Coastguard Worker auto id = enrollment.value_or(0);
328*4d7e907cSAndroid Build Coastguard Worker if (id > 0) {
329*4d7e907cSAndroid Build Coastguard Worker ids.push_back(id);
330*4d7e907cSAndroid Build Coastguard Worker }
331*4d7e907cSAndroid Build Coastguard Worker }
332*4d7e907cSAndroid Build Coastguard Worker
333*4d7e907cSAndroid Build Coastguard Worker cb->onEnrollmentsEnumerated(ids);
334*4d7e907cSAndroid Build Coastguard Worker }
335*4d7e907cSAndroid Build Coastguard Worker
removeEnrollmentsImpl(ISessionCallback * cb,const std::vector<int32_t> & enrollmentIds)336*4d7e907cSAndroid Build Coastguard Worker void FakeFingerprintEngine::removeEnrollmentsImpl(ISessionCallback* cb,
337*4d7e907cSAndroid Build Coastguard Worker const std::vector<int32_t>& enrollmentIds) {
338*4d7e907cSAndroid Build Coastguard Worker BEGIN_OP(0);
339*4d7e907cSAndroid Build Coastguard Worker
340*4d7e907cSAndroid Build Coastguard Worker std::vector<std::optional<int32_t>> newEnrollments;
341*4d7e907cSAndroid Build Coastguard Worker std::vector<int32_t> removed;
342*4d7e907cSAndroid Build Coastguard Worker for (auto& enrollment : Fingerprint::cfg().getopt<OptIntVec>("enrollments")) {
343*4d7e907cSAndroid Build Coastguard Worker auto id = enrollment.value_or(0);
344*4d7e907cSAndroid Build Coastguard Worker if (std::find(enrollmentIds.begin(), enrollmentIds.end(), id) != enrollmentIds.end()) {
345*4d7e907cSAndroid Build Coastguard Worker removed.push_back(id);
346*4d7e907cSAndroid Build Coastguard Worker } else if (id > 0) {
347*4d7e907cSAndroid Build Coastguard Worker newEnrollments.emplace_back(id);
348*4d7e907cSAndroid Build Coastguard Worker }
349*4d7e907cSAndroid Build Coastguard Worker }
350*4d7e907cSAndroid Build Coastguard Worker Fingerprint::cfg().setopt<OptIntVec>("enrollments", newEnrollments);
351*4d7e907cSAndroid Build Coastguard Worker
352*4d7e907cSAndroid Build Coastguard Worker cb->onEnrollmentsRemoved(enrollmentIds);
353*4d7e907cSAndroid Build Coastguard Worker }
354*4d7e907cSAndroid Build Coastguard Worker
getAuthenticatorIdImpl(ISessionCallback * cb)355*4d7e907cSAndroid Build Coastguard Worker void FakeFingerprintEngine::getAuthenticatorIdImpl(ISessionCallback* cb) {
356*4d7e907cSAndroid Build Coastguard Worker BEGIN_OP(0);
357*4d7e907cSAndroid Build Coastguard Worker int64_t authenticatorId;
358*4d7e907cSAndroid Build Coastguard Worker if (Fingerprint::cfg().getopt<OptIntVec>("enrollments").size() == 0) {
359*4d7e907cSAndroid Build Coastguard Worker authenticatorId = 0;
360*4d7e907cSAndroid Build Coastguard Worker } else {
361*4d7e907cSAndroid Build Coastguard Worker authenticatorId = Fingerprint::cfg().get<std::int64_t>("authenticator_id");
362*4d7e907cSAndroid Build Coastguard Worker if (authenticatorId == 0) authenticatorId = 1;
363*4d7e907cSAndroid Build Coastguard Worker }
364*4d7e907cSAndroid Build Coastguard Worker cb->onAuthenticatorIdRetrieved(authenticatorId);
365*4d7e907cSAndroid Build Coastguard Worker }
366*4d7e907cSAndroid Build Coastguard Worker
invalidateAuthenticatorIdImpl(ISessionCallback * cb)367*4d7e907cSAndroid Build Coastguard Worker void FakeFingerprintEngine::invalidateAuthenticatorIdImpl(ISessionCallback* cb) {
368*4d7e907cSAndroid Build Coastguard Worker BEGIN_OP(0);
369*4d7e907cSAndroid Build Coastguard Worker int64_t newId;
370*4d7e907cSAndroid Build Coastguard Worker if (Fingerprint::cfg().getopt<OptIntVec>("enrollments").size() == 0) {
371*4d7e907cSAndroid Build Coastguard Worker newId = 0;
372*4d7e907cSAndroid Build Coastguard Worker } else {
373*4d7e907cSAndroid Build Coastguard Worker auto id = Fingerprint::cfg().get<std::int64_t>("authenticator_id");
374*4d7e907cSAndroid Build Coastguard Worker newId = id + 1;
375*4d7e907cSAndroid Build Coastguard Worker }
376*4d7e907cSAndroid Build Coastguard Worker Fingerprint::cfg().set<std::int64_t>("authenticator_id", newId);
377*4d7e907cSAndroid Build Coastguard Worker cb->onAuthenticatorIdInvalidated(newId);
378*4d7e907cSAndroid Build Coastguard Worker }
379*4d7e907cSAndroid Build Coastguard Worker
resetLockoutImpl(ISessionCallback * cb,const keymaster::HardwareAuthToken & hat)380*4d7e907cSAndroid Build Coastguard Worker void FakeFingerprintEngine::resetLockoutImpl(ISessionCallback* cb,
381*4d7e907cSAndroid Build Coastguard Worker const keymaster::HardwareAuthToken& hat) {
382*4d7e907cSAndroid Build Coastguard Worker BEGIN_OP(0);
383*4d7e907cSAndroid Build Coastguard Worker if (hat.mac.empty()) {
384*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Fail: hat in resetLockout()";
385*4d7e907cSAndroid Build Coastguard Worker cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
386*4d7e907cSAndroid Build Coastguard Worker return;
387*4d7e907cSAndroid Build Coastguard Worker }
388*4d7e907cSAndroid Build Coastguard Worker clearLockout(cb);
389*4d7e907cSAndroid Build Coastguard Worker if (isLockoutTimerStarted) isLockoutTimerAborted = true;
390*4d7e907cSAndroid Build Coastguard Worker }
391*4d7e907cSAndroid Build Coastguard Worker
clearLockout(ISessionCallback * cb,bool dueToTimeout)392*4d7e907cSAndroid Build Coastguard Worker void FakeFingerprintEngine::clearLockout(ISessionCallback* cb, bool dueToTimeout) {
393*4d7e907cSAndroid Build Coastguard Worker Fingerprint::cfg().set<bool>("lockout", false);
394*4d7e907cSAndroid Build Coastguard Worker cb->onLockoutCleared();
395*4d7e907cSAndroid Build Coastguard Worker mLockoutTracker.reset(dueToTimeout);
396*4d7e907cSAndroid Build Coastguard Worker }
397*4d7e907cSAndroid Build Coastguard Worker
onPointerDownImpl(int32_t,int32_t,int32_t,float,float)398*4d7e907cSAndroid Build Coastguard Worker ndk::ScopedAStatus FakeFingerprintEngine::onPointerDownImpl(int32_t /*pointerId*/, int32_t /*x*/,
399*4d7e907cSAndroid Build Coastguard Worker int32_t /*y*/, float /*minor*/,
400*4d7e907cSAndroid Build Coastguard Worker float /*major*/) {
401*4d7e907cSAndroid Build Coastguard Worker BEGIN_OP(0);
402*4d7e907cSAndroid Build Coastguard Worker fingerDownAction();
403*4d7e907cSAndroid Build Coastguard Worker return ndk::ScopedAStatus::ok();
404*4d7e907cSAndroid Build Coastguard Worker }
405*4d7e907cSAndroid Build Coastguard Worker
onPointerUpImpl(int32_t)406*4d7e907cSAndroid Build Coastguard Worker ndk::ScopedAStatus FakeFingerprintEngine::onPointerUpImpl(int32_t /*pointerId*/) {
407*4d7e907cSAndroid Build Coastguard Worker BEGIN_OP(0);
408*4d7e907cSAndroid Build Coastguard Worker mFingerIsDown = false;
409*4d7e907cSAndroid Build Coastguard Worker return ndk::ScopedAStatus::ok();
410*4d7e907cSAndroid Build Coastguard Worker }
411*4d7e907cSAndroid Build Coastguard Worker
onUiReadyImpl()412*4d7e907cSAndroid Build Coastguard Worker ndk::ScopedAStatus FakeFingerprintEngine::onUiReadyImpl() {
413*4d7e907cSAndroid Build Coastguard Worker BEGIN_OP(0);
414*4d7e907cSAndroid Build Coastguard Worker return ndk::ScopedAStatus::ok();
415*4d7e907cSAndroid Build Coastguard Worker }
416*4d7e907cSAndroid Build Coastguard Worker
getSensorLocationConfig(SensorLocation & out)417*4d7e907cSAndroid Build Coastguard Worker bool FakeFingerprintEngine::getSensorLocationConfig(SensorLocation& out) {
418*4d7e907cSAndroid Build Coastguard Worker auto loc = Fingerprint::cfg().get<std::string>("sensor_location");
419*4d7e907cSAndroid Build Coastguard Worker auto isValidStr = false;
420*4d7e907cSAndroid Build Coastguard Worker auto dim = Util::split(loc, ":");
421*4d7e907cSAndroid Build Coastguard Worker
422*4d7e907cSAndroid Build Coastguard Worker if (dim.size() < 3 or dim.size() > 4) {
423*4d7e907cSAndroid Build Coastguard Worker if (!loc.empty()) LOG(WARNING) << "Invalid sensor location input (x:y:radius):" + loc;
424*4d7e907cSAndroid Build Coastguard Worker return false;
425*4d7e907cSAndroid Build Coastguard Worker } else {
426*4d7e907cSAndroid Build Coastguard Worker int32_t x, y, r;
427*4d7e907cSAndroid Build Coastguard Worker std::string d = "";
428*4d7e907cSAndroid Build Coastguard Worker if (dim.size() >= 3) {
429*4d7e907cSAndroid Build Coastguard Worker isValidStr = ParseInt(dim[0], &x) && ParseInt(dim[1], &y) && ParseInt(dim[2], &r);
430*4d7e907cSAndroid Build Coastguard Worker }
431*4d7e907cSAndroid Build Coastguard Worker if (dim.size() >= 4) {
432*4d7e907cSAndroid Build Coastguard Worker d = dim[3];
433*4d7e907cSAndroid Build Coastguard Worker }
434*4d7e907cSAndroid Build Coastguard Worker if (isValidStr)
435*4d7e907cSAndroid Build Coastguard Worker out = {.sensorLocationX = x, .sensorLocationY = y, .sensorRadius = r, .display = d};
436*4d7e907cSAndroid Build Coastguard Worker
437*4d7e907cSAndroid Build Coastguard Worker return isValidStr;
438*4d7e907cSAndroid Build Coastguard Worker }
439*4d7e907cSAndroid Build Coastguard Worker }
getSensorLocation()440*4d7e907cSAndroid Build Coastguard Worker SensorLocation FakeFingerprintEngine::getSensorLocation() {
441*4d7e907cSAndroid Build Coastguard Worker SensorLocation location;
442*4d7e907cSAndroid Build Coastguard Worker
443*4d7e907cSAndroid Build Coastguard Worker if (getSensorLocationConfig(location)) {
444*4d7e907cSAndroid Build Coastguard Worker return location;
445*4d7e907cSAndroid Build Coastguard Worker } else {
446*4d7e907cSAndroid Build Coastguard Worker return defaultSensorLocation();
447*4d7e907cSAndroid Build Coastguard Worker }
448*4d7e907cSAndroid Build Coastguard Worker }
449*4d7e907cSAndroid Build Coastguard Worker
defaultSensorLocation()450*4d7e907cSAndroid Build Coastguard Worker SensorLocation FakeFingerprintEngine::defaultSensorLocation() {
451*4d7e907cSAndroid Build Coastguard Worker return SensorLocation();
452*4d7e907cSAndroid Build Coastguard Worker }
453*4d7e907cSAndroid Build Coastguard Worker
convertAcquiredInfo(int32_t code)454*4d7e907cSAndroid Build Coastguard Worker std::pair<AcquiredInfo, int32_t> FakeFingerprintEngine::convertAcquiredInfo(int32_t code) {
455*4d7e907cSAndroid Build Coastguard Worker std::pair<AcquiredInfo, int32_t> res;
456*4d7e907cSAndroid Build Coastguard Worker if (code > FINGERPRINT_ACQUIRED_VENDOR_BASE) {
457*4d7e907cSAndroid Build Coastguard Worker res.first = AcquiredInfo::VENDOR;
458*4d7e907cSAndroid Build Coastguard Worker res.second = code - FINGERPRINT_ACQUIRED_VENDOR_BASE;
459*4d7e907cSAndroid Build Coastguard Worker } else {
460*4d7e907cSAndroid Build Coastguard Worker res.first = (AcquiredInfo)code;
461*4d7e907cSAndroid Build Coastguard Worker res.second = 0;
462*4d7e907cSAndroid Build Coastguard Worker }
463*4d7e907cSAndroid Build Coastguard Worker return res;
464*4d7e907cSAndroid Build Coastguard Worker }
465*4d7e907cSAndroid Build Coastguard Worker
convertError(int32_t code)466*4d7e907cSAndroid Build Coastguard Worker std::pair<Error, int32_t> FakeFingerprintEngine::convertError(int32_t code) {
467*4d7e907cSAndroid Build Coastguard Worker std::pair<Error, int32_t> res;
468*4d7e907cSAndroid Build Coastguard Worker if (code > FINGERPRINT_ERROR_VENDOR_BASE) {
469*4d7e907cSAndroid Build Coastguard Worker res.first = Error::VENDOR;
470*4d7e907cSAndroid Build Coastguard Worker res.second = code - FINGERPRINT_ERROR_VENDOR_BASE;
471*4d7e907cSAndroid Build Coastguard Worker } else {
472*4d7e907cSAndroid Build Coastguard Worker res.first = (Error)code;
473*4d7e907cSAndroid Build Coastguard Worker res.second = 0;
474*4d7e907cSAndroid Build Coastguard Worker }
475*4d7e907cSAndroid Build Coastguard Worker return res;
476*4d7e907cSAndroid Build Coastguard Worker }
477*4d7e907cSAndroid Build Coastguard Worker
getLatency(const std::vector<std::optional<std::int32_t>> & latencyIn)478*4d7e907cSAndroid Build Coastguard Worker int32_t FakeFingerprintEngine::getLatency(
479*4d7e907cSAndroid Build Coastguard Worker const std::vector<std::optional<std::int32_t>>& latencyIn) {
480*4d7e907cSAndroid Build Coastguard Worker int32_t res = DEFAULT_LATENCY;
481*4d7e907cSAndroid Build Coastguard Worker
482*4d7e907cSAndroid Build Coastguard Worker std::vector<int32_t> latency;
483*4d7e907cSAndroid Build Coastguard Worker for (auto x : latencyIn)
484*4d7e907cSAndroid Build Coastguard Worker if (x.has_value()) latency.push_back(*x);
485*4d7e907cSAndroid Build Coastguard Worker
486*4d7e907cSAndroid Build Coastguard Worker switch (latency.size()) {
487*4d7e907cSAndroid Build Coastguard Worker case 0:
488*4d7e907cSAndroid Build Coastguard Worker break;
489*4d7e907cSAndroid Build Coastguard Worker case 1:
490*4d7e907cSAndroid Build Coastguard Worker res = latency[0];
491*4d7e907cSAndroid Build Coastguard Worker break;
492*4d7e907cSAndroid Build Coastguard Worker case 2:
493*4d7e907cSAndroid Build Coastguard Worker res = getRandomInRange(latency[0], latency[1]);
494*4d7e907cSAndroid Build Coastguard Worker break;
495*4d7e907cSAndroid Build Coastguard Worker default:
496*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "ERROR: unexpected input of size " << latency.size();
497*4d7e907cSAndroid Build Coastguard Worker break;
498*4d7e907cSAndroid Build Coastguard Worker }
499*4d7e907cSAndroid Build Coastguard Worker
500*4d7e907cSAndroid Build Coastguard Worker return res;
501*4d7e907cSAndroid Build Coastguard Worker }
502*4d7e907cSAndroid Build Coastguard Worker
getRandomInRange(int32_t bound1,int32_t bound2)503*4d7e907cSAndroid Build Coastguard Worker int32_t FakeFingerprintEngine::getRandomInRange(int32_t bound1, int32_t bound2) {
504*4d7e907cSAndroid Build Coastguard Worker std::uniform_int_distribution<int32_t> dist(std::min(bound1, bound2), std::max(bound1, bound2));
505*4d7e907cSAndroid Build Coastguard Worker return dist(mRandom);
506*4d7e907cSAndroid Build Coastguard Worker }
507*4d7e907cSAndroid Build Coastguard Worker
checkSensorLockout(ISessionCallback * cb)508*4d7e907cSAndroid Build Coastguard Worker bool FakeFingerprintEngine::checkSensorLockout(ISessionCallback* cb) {
509*4d7e907cSAndroid Build Coastguard Worker FakeLockoutTracker::LockoutMode lockoutMode = mLockoutTracker.getMode();
510*4d7e907cSAndroid Build Coastguard Worker if (lockoutMode == FakeLockoutTracker::LockoutMode::kPermanent) {
511*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Fail: lockout permanent";
512*4d7e907cSAndroid Build Coastguard Worker cb->onLockoutPermanent();
513*4d7e907cSAndroid Build Coastguard Worker isLockoutTimerAborted = true;
514*4d7e907cSAndroid Build Coastguard Worker return true;
515*4d7e907cSAndroid Build Coastguard Worker } else if (lockoutMode == FakeLockoutTracker::LockoutMode::kTimed) {
516*4d7e907cSAndroid Build Coastguard Worker int64_t timeLeft = mLockoutTracker.getLockoutTimeLeft();
517*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "Fail: lockout timed " << timeLeft;
518*4d7e907cSAndroid Build Coastguard Worker cb->onLockoutTimed(timeLeft);
519*4d7e907cSAndroid Build Coastguard Worker if (isLockoutTimerSupported && !isLockoutTimerStarted) startLockoutTimer(timeLeft, cb);
520*4d7e907cSAndroid Build Coastguard Worker return true;
521*4d7e907cSAndroid Build Coastguard Worker }
522*4d7e907cSAndroid Build Coastguard Worker return false;
523*4d7e907cSAndroid Build Coastguard Worker }
524*4d7e907cSAndroid Build Coastguard Worker
startLockoutTimer(int64_t timeout,ISessionCallback * cb)525*4d7e907cSAndroid Build Coastguard Worker void FakeFingerprintEngine::startLockoutTimer(int64_t timeout, ISessionCallback* cb) {
526*4d7e907cSAndroid Build Coastguard Worker BEGIN_OP(0);
527*4d7e907cSAndroid Build Coastguard Worker std::function<void(ISessionCallback*)> action =
528*4d7e907cSAndroid Build Coastguard Worker std::bind(&FakeFingerprintEngine::lockoutTimerExpired, this, std::placeholders::_1);
529*4d7e907cSAndroid Build Coastguard Worker std::thread([timeout, action, cb]() {
530*4d7e907cSAndroid Build Coastguard Worker std::this_thread::sleep_for(std::chrono::milliseconds(timeout));
531*4d7e907cSAndroid Build Coastguard Worker action(cb);
532*4d7e907cSAndroid Build Coastguard Worker }).detach();
533*4d7e907cSAndroid Build Coastguard Worker
534*4d7e907cSAndroid Build Coastguard Worker isLockoutTimerStarted = true;
535*4d7e907cSAndroid Build Coastguard Worker }
lockoutTimerExpired(ISessionCallback * cb)536*4d7e907cSAndroid Build Coastguard Worker void FakeFingerprintEngine::lockoutTimerExpired(ISessionCallback* cb) {
537*4d7e907cSAndroid Build Coastguard Worker BEGIN_OP(0);
538*4d7e907cSAndroid Build Coastguard Worker if (!isLockoutTimerAborted) {
539*4d7e907cSAndroid Build Coastguard Worker clearLockout(cb, true);
540*4d7e907cSAndroid Build Coastguard Worker }
541*4d7e907cSAndroid Build Coastguard Worker isLockoutTimerStarted = false;
542*4d7e907cSAndroid Build Coastguard Worker isLockoutTimerAborted = false;
543*4d7e907cSAndroid Build Coastguard Worker }
544*4d7e907cSAndroid Build Coastguard Worker
waitForFingerDown(ISessionCallback * cb,const std::future<void> & cancel)545*4d7e907cSAndroid Build Coastguard Worker void FakeFingerprintEngine::waitForFingerDown(ISessionCallback* cb,
546*4d7e907cSAndroid Build Coastguard Worker const std::future<void>& cancel) {
547*4d7e907cSAndroid Build Coastguard Worker if (mFingerIsDown) {
548*4d7e907cSAndroid Build Coastguard Worker LOG(WARNING) << "waitForFingerDown: mFingerIsDown==true already!";
549*4d7e907cSAndroid Build Coastguard Worker }
550*4d7e907cSAndroid Build Coastguard Worker
551*4d7e907cSAndroid Build Coastguard Worker while (!mFingerIsDown) {
552*4d7e907cSAndroid Build Coastguard Worker if (shouldCancel(cancel)) {
553*4d7e907cSAndroid Build Coastguard Worker LOG(ERROR) << "waitForFingerDown, Fail: cancel";
554*4d7e907cSAndroid Build Coastguard Worker cb->onError(Error::CANCELED, 0 /* vendorCode */);
555*4d7e907cSAndroid Build Coastguard Worker return;
556*4d7e907cSAndroid Build Coastguard Worker }
557*4d7e907cSAndroid Build Coastguard Worker SLEEP_MS(10);
558*4d7e907cSAndroid Build Coastguard Worker }
559*4d7e907cSAndroid Build Coastguard Worker }
560*4d7e907cSAndroid Build Coastguard Worker
561*4d7e907cSAndroid Build Coastguard Worker } // namespace aidl::android::hardware::biometrics::fingerprint
562