1 /*
2  * Copyright (C) 2022 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 
17 #include <android/binder_process.h>
18 #include <fingerprint.sysprop.h>
19 #include <gtest/gtest.h>
20 
21 #include <aidl/android/hardware/biometrics/fingerprint/BnSessionCallback.h>
22 
23 #include "FakeFingerprintEngine.h"
24 #include "Fingerprint.h"
25 #include "util/Util.h"
26 
27 using namespace ::android::fingerprint::virt;
28 using namespace ::aidl::android::hardware::biometrics::fingerprint;
29 using namespace ::aidl::android::hardware::keymaster;
30 
31 namespace aidl::android::hardware::biometrics::fingerprint {
32 
33 class TestSessionCallback : public BnSessionCallback {
34   public:
onChallengeGenerated(int64_t challenge)35     ndk::ScopedAStatus onChallengeGenerated(int64_t challenge) override {
36         mLastChallenge = challenge;
37         return ndk::ScopedAStatus::ok();
38     };
onChallengeRevoked(int64_t challenge)39     ::ndk::ScopedAStatus onChallengeRevoked(int64_t challenge) override {
40         mLastChallengeRevoked = challenge;
41         return ndk::ScopedAStatus::ok();
42     };
onError(fingerprint::Error error,int32_t vendorCode)43     ::ndk::ScopedAStatus onError(fingerprint::Error error, int32_t vendorCode) override {
44         mError = error;
45         mErrorVendorCode = vendorCode;
46         return ndk::ScopedAStatus::ok();
47     };
onEnrollmentProgress(int32_t enrollmentId,int32_t remaining)48     ::ndk::ScopedAStatus onEnrollmentProgress(int32_t enrollmentId, int32_t remaining) override {
49         if (remaining == 0) mLastEnrolled = enrollmentId;
50         return ndk::ScopedAStatus::ok();
51     };
52 
onAuthenticationSucceeded(int32_t enrollmentId,const keymaster::HardwareAuthToken &)53     ::ndk::ScopedAStatus onAuthenticationSucceeded(int32_t enrollmentId,
54                                                    const keymaster::HardwareAuthToken&) override {
55         mLastAuthenticated = enrollmentId;
56         mAuthenticateFailed = false;
57         return ndk::ScopedAStatus::ok();
58     };
onAuthenticationFailed()59     ::ndk::ScopedAStatus onAuthenticationFailed() override {
60         mLastAuthenticated = 0;
61         mAuthenticateFailed = true;
62         return ndk::ScopedAStatus::ok();
63     };
onInteractionDetected()64     ::ndk::ScopedAStatus onInteractionDetected() override {
65         mInteractionDetectedCount++;
66         return ndk::ScopedAStatus::ok();
67     };
onAcquired(AcquiredInfo info,int32_t vendorCode)68     ndk::ScopedAStatus onAcquired(AcquiredInfo info, int32_t vendorCode) override {
69         mLastAcquiredInfo = (int32_t)info;
70         mLastAcquiredVendorCode = vendorCode;
71         mLastAcquiredCount++;
72         return ndk::ScopedAStatus::ok();
73     }
onEnrollmentsEnumerated(const std::vector<int32_t> & enrollmentIds)74     ::ndk::ScopedAStatus onEnrollmentsEnumerated(
75             const std::vector<int32_t>& enrollmentIds) override {
76         mLastEnrollmentEnumerated = enrollmentIds;
77         return ndk::ScopedAStatus::ok();
78     };
onEnrollmentsRemoved(const std::vector<int32_t> & enrollmentIds)79     ::ndk::ScopedAStatus onEnrollmentsRemoved(const std::vector<int32_t>& enrollmentIds) override {
80         mLastEnrollmentRemoved = enrollmentIds;
81         return ndk::ScopedAStatus::ok();
82     };
onAuthenticatorIdRetrieved(int64_t authenticatorId)83     ::ndk::ScopedAStatus onAuthenticatorIdRetrieved(int64_t authenticatorId) override {
84         mLastAuthenticatorId = authenticatorId;
85         return ndk::ScopedAStatus::ok();
86     };
onAuthenticatorIdInvalidated(int64_t authenticatorId)87     ::ndk::ScopedAStatus onAuthenticatorIdInvalidated(int64_t authenticatorId) override {
88         mLastAuthenticatorId = authenticatorId;
89         mAuthenticatorIdInvalidated = true;
90         return ndk::ScopedAStatus::ok();
91     };
onLockoutPermanent()92     ::ndk::ScopedAStatus onLockoutPermanent() override {
93         mLockoutPermanent = true;
94         return ndk::ScopedAStatus::ok();
95     };
onLockoutTimed(int64_t)96     ndk::ScopedAStatus onLockoutTimed(int64_t /* timeout */) override {
97         mLockoutTimed = true;
98         return ndk::ScopedAStatus::ok();
99     }
onLockoutCleared()100     ndk::ScopedAStatus onLockoutCleared() override {
101         mLockoutCleared = true;
102         return ndk::ScopedAStatus::ok();
103     }
onSessionClosed()104     ndk::ScopedAStatus onSessionClosed() override { return ndk::ScopedAStatus::ok(); }
105 
106     Error mError = Error::UNKNOWN;
107     int32_t mErrorVendorCode = 0;
108     int64_t mLastChallenge = -1;
109     int64_t mLastChallengeRevoked = -1;
110     int32_t mLastEnrolled = -1;
111     int32_t mLastAuthenticated = -1;
112     int64_t mLastAuthenticatorId = -1;
113     std::vector<int32_t> mLastEnrollmentEnumerated;
114     std::vector<int32_t> mLastEnrollmentRemoved;
115     bool mAuthenticateFailed = false;
116     bool mAuthenticatorIdInvalidated = false;
117     bool mLockoutPermanent = false;
118     bool mLockoutTimed = false;
119     bool mLockoutCleared = false;
120     int mInteractionDetectedCount = 0;
121     int32_t mLastAcquiredInfo = -1;
122     int32_t mLastAcquiredVendorCode = -1;
123     int32_t mLastAcquiredCount = 0;
124 };
125 
126 class FakeFingerprintEngineTest : public ::testing::Test {
127   protected:
SetUp()128     void SetUp() override {
129         Fingerprint::cfg().setopt<OptIntVec>("operation_enroll_latency", {0});
130         Fingerprint::cfg().setopt<OptIntVec>("operation_authenticate_latency", {0});
131         Fingerprint::cfg().setopt<OptIntVec>("operation_detect_interaction_latency", {0});
132         mCallback = ndk::SharedRefBase::make<TestSessionCallback>();
133     }
134 
TearDown()135     void TearDown() override {
136         Fingerprint::cfg().set<std::int32_t>("operation_authenticate_error", 0);
137         Fingerprint::cfg().set<std::int32_t>("operation_detect_interaction_error", 0);
138         Fingerprint::cfg().set<std::string>("operation_authenticate_acquired", "");
139         Fingerprint::cfg().setopt<OptIntVec>("operation_enroll_latency", {});
140         Fingerprint::cfg().setopt<OptIntVec>("operation_authenticate_latency", {});
141         Fingerprint::cfg().setopt<OptIntVec>("operation_detect_interaction_latency", {});
142         Fingerprint::cfg().set<bool>("operation_authenticate_fails", false);
143     }
144 
145     FakeFingerprintEngine mEngine;
146     std::shared_ptr<TestSessionCallback> mCallback;
147     std::promise<void> mCancel;
148 };
149 
TEST_F(FakeFingerprintEngineTest,GenerateChallenge)150 TEST_F(FakeFingerprintEngineTest, GenerateChallenge) {
151     mEngine.generateChallengeImpl(mCallback.get());
152     ASSERT_EQ(Fingerprint::cfg().get<std::int64_t>("challenge"), mCallback->mLastChallenge);
153 }
154 
TEST_F(FakeFingerprintEngineTest,RevokeChallenge)155 TEST_F(FakeFingerprintEngineTest, RevokeChallenge) {
156     auto challenge = Fingerprint::cfg().get<std::int64_t>("challenge");
157     mEngine.revokeChallengeImpl(mCallback.get(), challenge);
158     ASSERT_FALSE((Fingerprint::cfg().getopt<OptInt64>("challenge")).has_value());
159     ASSERT_EQ(challenge, mCallback->mLastChallengeRevoked);
160 }
161 
TEST_F(FakeFingerprintEngineTest,ResetLockout)162 TEST_F(FakeFingerprintEngineTest, ResetLockout) {
163     Fingerprint::cfg().get<bool>("lockout");
164     keymaster::HardwareAuthToken hat{.mac = {2, 4}};
165     mEngine.resetLockoutImpl(mCallback.get(), hat);
166     ASSERT_FALSE(Fingerprint::cfg().get<bool>("lockout"));
167 }
168 
TEST_F(FakeFingerprintEngineTest,AuthenticatorId)169 TEST_F(FakeFingerprintEngineTest, AuthenticatorId) {
170     Fingerprint::cfg().setopt<OptIntVec>("enrollments", {1});
171     Fingerprint::cfg().set<std::int64_t>("authenticator_id", 50);
172     mEngine.getAuthenticatorIdImpl(mCallback.get());
173     ASSERT_EQ(50, mCallback->mLastAuthenticatorId);
174     ASSERT_FALSE(mCallback->mAuthenticatorIdInvalidated);
175 }
176 
TEST_F(FakeFingerprintEngineTest,AuthenticatorIdInvalidate)177 TEST_F(FakeFingerprintEngineTest, AuthenticatorIdInvalidate) {
178     Fingerprint::cfg().set<std::int64_t>("authenticator_id", 500);
179     mEngine.invalidateAuthenticatorIdImpl(mCallback.get());
180     ASSERT_NE(500, Fingerprint::cfg().get<std::int64_t>("authenticator_id"));
181     ASSERT_TRUE(mCallback->mAuthenticatorIdInvalidated);
182 }
183 
TEST_F(FakeFingerprintEngineTest,Enroll)184 TEST_F(FakeFingerprintEngineTest, Enroll) {
185     Fingerprint::cfg().setopt<OptIntVec>("enrollments", {});
186     Fingerprint::cfg().set<std::string>("next_enrollment", "4:0,0:true");
187     keymaster::HardwareAuthToken hat{.mac = {2, 4}};
188     mEngine.notifyFingerdown();
189     mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
190     ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kEnroll);
191     mEngine.fingerDownAction();
192     ASSERT_FALSE(Fingerprint::cfg().getopt<OptString>("next_enrollment").has_value());
193     ASSERT_EQ(1, Fingerprint::cfg().getopt<OptIntVec>("enrollments").size());
194     ASSERT_EQ(4, Fingerprint::cfg().getopt<OptIntVec>("enrollments")[0].value());
195     ASSERT_EQ(4, mCallback->mLastEnrolled);
196     ASSERT_EQ(1, mCallback->mLastAcquiredInfo);
197     ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kIdle);
198 }
199 
TEST_F(FakeFingerprintEngineTest,EnrollCancel)200 TEST_F(FakeFingerprintEngineTest, EnrollCancel) {
201     Fingerprint::cfg().setopt<OptIntVec>("enrollments", {});
202     auto next = "4:0,0:true";
203     Fingerprint::cfg().set<std::string>("next_enrollment", next);
204     keymaster::HardwareAuthToken hat{.mac = {2, 4}};
205     mCancel.set_value();
206     mEngine.notifyFingerdown();
207     mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
208     mEngine.fingerDownAction();
209     ASSERT_EQ(Error::CANCELED, mCallback->mError);
210     ASSERT_EQ(-1, mCallback->mLastEnrolled);
211     ASSERT_EQ(0, Fingerprint::cfg().getopt<OptIntVec>("enrollments").size());
212     ASSERT_EQ(next, Fingerprint::cfg().get<std::string>("next_enrollment"));
213 }
214 
TEST_F(FakeFingerprintEngineTest,EnrollFail)215 TEST_F(FakeFingerprintEngineTest, EnrollFail) {
216     Fingerprint::cfg().setopt<OptIntVec>("enrollments", {});
217     auto next = "2:0,0:false";
218     Fingerprint::cfg().set<std::string>("next_enrollment", next);
219     keymaster::HardwareAuthToken hat{.mac = {2, 4}};
220     mEngine.notifyFingerdown();
221     mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
222     mEngine.fingerDownAction();
223     ASSERT_EQ(Error::UNABLE_TO_PROCESS, mCallback->mError);
224     ASSERT_EQ(-1, mCallback->mLastEnrolled);
225     ASSERT_EQ(0, Fingerprint::cfg().getopt<OptIntVec>("enrollments").size());
226     ASSERT_FALSE(Fingerprint::cfg().getopt<OptString>("next_enrollment").has_value());
227 }
228 
TEST_F(FakeFingerprintEngineTest,EnrollAcquired)229 TEST_F(FakeFingerprintEngineTest, EnrollAcquired) {
230     Fingerprint::cfg().setopt<OptIntVec>("enrollments", {});
231     Fingerprint::cfg().set<std::string>("next_enrollment", "4:0,5-[12,1013]:true");
232     keymaster::HardwareAuthToken hat{.mac = {2, 4}};
233     int32_t prevCnt = mCallback->mLastAcquiredCount;
234     mEngine.notifyFingerdown();
235     mEngine.enrollImpl(mCallback.get(), hat, mCancel.get_future());
236     mEngine.fingerDownAction();
237     ASSERT_FALSE(Fingerprint::cfg().getopt<OptString>("next_enrollment").has_value());
238     ASSERT_EQ(1, Fingerprint::cfg().getopt<OptIntVec>("enrollments").size());
239     ASSERT_EQ(4, Fingerprint::cfg().getopt<OptIntVec>("enrollments")[0].value());
240     ASSERT_EQ(4, mCallback->mLastEnrolled);
241     ASSERT_EQ(prevCnt + 3, mCallback->mLastAcquiredCount);
242     ASSERT_EQ(7, mCallback->mLastAcquiredInfo);
243     ASSERT_EQ(13, mCallback->mLastAcquiredVendorCode);
244 }
245 
TEST_F(FakeFingerprintEngineTest,Authenticate)246 TEST_F(FakeFingerprintEngineTest, Authenticate) {
247     Fingerprint::cfg().setopt<OptIntVec>("enrollments", {1, 2});
248     Fingerprint::cfg().set<std::int32_t>("enrollment_hit", 2);
249     mEngine.notifyFingerdown();
250     mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
251     ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kAuthenticate);
252     mEngine.fingerDownAction();
253     ASSERT_FALSE(mCallback->mAuthenticateFailed);
254     ASSERT_EQ(2, mCallback->mLastAuthenticated);
255     ASSERT_EQ(1, mCallback->mLastAcquiredInfo);
256     ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kIdle);
257 }
258 
TEST_F(FakeFingerprintEngineTest,AuthenticateCancel)259 TEST_F(FakeFingerprintEngineTest, AuthenticateCancel) {
260     Fingerprint::cfg().setopt<OptIntVec>("enrollments", {2});
261     Fingerprint::cfg().set<std::int32_t>("enrollment_hit", 2);
262     mCancel.set_value();
263     mEngine.notifyFingerdown();
264     mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
265     mEngine.fingerDownAction();
266     ASSERT_EQ(Error::CANCELED, mCallback->mError);
267     ASSERT_EQ(-1, mCallback->mLastAuthenticated);
268 }
269 
TEST_F(FakeFingerprintEngineTest,AuthenticateNotSet)270 TEST_F(FakeFingerprintEngineTest, AuthenticateNotSet) {
271     Fingerprint::cfg().setopt<OptIntVec>("enrollments", {1, 2});
272     Fingerprint::cfg().setopt<OptInt32>("enrollment_hit", std::nullopt);
273     mEngine.notifyFingerdown();
274     mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
275     mEngine.fingerDownAction();
276     ASSERT_TRUE(mCallback->mAuthenticateFailed);
277 }
278 
TEST_F(FakeFingerprintEngineTest,AuthenticateNotEnrolled)279 TEST_F(FakeFingerprintEngineTest, AuthenticateNotEnrolled) {
280     Fingerprint::cfg().setopt<OptIntVec>("enrollments", {1, 2});
281     Fingerprint::cfg().set<std::int32_t>("enrollment_hit", 3);
282     mEngine.notifyFingerdown();
283     mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
284     mEngine.fingerDownAction();
285     ASSERT_TRUE(mCallback->mAuthenticateFailed);
286     ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kAuthenticate);
287 }
288 
TEST_F(FakeFingerprintEngineTest,AuthenticateLockout)289 TEST_F(FakeFingerprintEngineTest, AuthenticateLockout) {
290     Fingerprint::cfg().setopt<OptIntVec>("enrollments", {22, 2});
291     Fingerprint::cfg().set<std::int32_t>("enrollment_hit", 2);
292     Fingerprint::cfg().set<bool>("lockout", true);
293     mEngine.notifyFingerdown();
294     mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
295     mEngine.fingerDownAction();
296     ASSERT_TRUE(mCallback->mLockoutPermanent);
297     ASSERT_NE(mCallback->mError, Error::UNKNOWN);
298 }
299 
TEST_F(FakeFingerprintEngineTest,AuthenticateError8)300 TEST_F(FakeFingerprintEngineTest, AuthenticateError8) {
301     Fingerprint::cfg().set<std::int32_t>("operation_authenticate_error", 8);
302     mEngine.notifyFingerdown();
303     mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
304     mEngine.fingerDownAction();
305     ASSERT_EQ(mCallback->mError, (Error)8);
306     ASSERT_EQ(mCallback->mErrorVendorCode, 0);
307 }
308 
TEST_F(FakeFingerprintEngineTest,AuthenticateError9)309 TEST_F(FakeFingerprintEngineTest, AuthenticateError9) {
310     Fingerprint::cfg().set<std::int32_t>("operation_authenticate_error", 1009);
311     mEngine.notifyFingerdown();
312     mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
313     mEngine.fingerDownAction();
314     ASSERT_EQ(mCallback->mError, (Error)7);
315     ASSERT_EQ(mCallback->mErrorVendorCode, 9);
316 }
317 
TEST_F(FakeFingerprintEngineTest,AuthenticateFails)318 TEST_F(FakeFingerprintEngineTest, AuthenticateFails) {
319     Fingerprint::cfg().set<bool>("operation_authenticate_fails", true);
320     mEngine.notifyFingerdown();
321     mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
322     mEngine.fingerDownAction();
323     ASSERT_TRUE(mCallback->mAuthenticateFailed);
324     ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kAuthenticate);
325 }
326 
TEST_F(FakeFingerprintEngineTest,AuthenticateAcquired)327 TEST_F(FakeFingerprintEngineTest, AuthenticateAcquired) {
328     Fingerprint::cfg().set<bool>("lockout", false);
329     Fingerprint::cfg().setopt<OptIntVec>("enrollments", {1, 2});
330     Fingerprint::cfg().set<std::int32_t>("enrollment_hit", 2);
331     Fingerprint::cfg().set<std::string>("operation_authenticate_acquired", "4,1009");
332     int32_t prevCount = mCallback->mLastAcquiredCount;
333     mEngine.notifyFingerdown();
334     mEngine.authenticateImpl(mCallback.get(), 0, mCancel.get_future());
335     mEngine.fingerDownAction();
336     ASSERT_FALSE(mCallback->mAuthenticateFailed);
337     ASSERT_EQ(2, mCallback->mLastAuthenticated);
338     ASSERT_EQ(prevCount + 2, mCallback->mLastAcquiredCount);
339     ASSERT_EQ(7, mCallback->mLastAcquiredInfo);
340     ASSERT_EQ(9, mCallback->mLastAcquiredVendorCode);
341 }
342 
TEST_F(FakeFingerprintEngineTest,InteractionDetect)343 TEST_F(FakeFingerprintEngineTest, InteractionDetect) {
344     Fingerprint::cfg().set<bool>("detect_interaction", true);
345     Fingerprint::cfg().setopt<OptIntVec>("enrollments", {1, 2});
346     Fingerprint::cfg().set<std::int32_t>("enrollment_hit", 2);
347     Fingerprint::cfg().set<std::string>("operation_detect_interaction_acquired", "");
348     mEngine.notifyFingerdown();
349     mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
350     ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kDetectInteract);
351     mEngine.fingerDownAction();
352     ASSERT_EQ(1, mCallback->mInteractionDetectedCount);
353     ASSERT_EQ(1, mCallback->mLastAcquiredInfo);
354     ASSERT_EQ(mEngine.getWorkMode(), FakeFingerprintEngine::WorkMode::kIdle);
355 }
356 
TEST_F(FakeFingerprintEngineTest,InteractionDetectCancel)357 TEST_F(FakeFingerprintEngineTest, InteractionDetectCancel) {
358     Fingerprint::cfg().set<bool>("detect_interaction", true);
359     Fingerprint::cfg().setopt<OptIntVec>("enrollments", {1, 2});
360     Fingerprint::cfg().set<std::int32_t>("enrollment_hit", 2);
361     mCancel.set_value();
362     mEngine.notifyFingerdown();
363     mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
364     mEngine.fingerDownAction();
365     ASSERT_EQ(Error::CANCELED, mCallback->mError);
366     ASSERT_EQ(0, mCallback->mInteractionDetectedCount);
367 }
368 
TEST_F(FakeFingerprintEngineTest,InteractionDetectNotSet)369 TEST_F(FakeFingerprintEngineTest, InteractionDetectNotSet) {
370     Fingerprint::cfg().set<bool>("detect_interaction", true);
371     Fingerprint::cfg().setopt<OptIntVec>("enrollments", {1, 2});
372     Fingerprint::cfg().setopt<OptInt32>("enrollment_hit", std::nullopt);
373     mEngine.notifyFingerdown();
374     mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
375     mEngine.fingerDownAction();
376     ASSERT_EQ(1, mCallback->mInteractionDetectedCount);
377 }
378 
TEST_F(FakeFingerprintEngineTest,InteractionDetectNotEnrolled)379 TEST_F(FakeFingerprintEngineTest, InteractionDetectNotEnrolled) {
380     Fingerprint::cfg().setopt<OptIntVec>("enrollments", {1, 2});
381     Fingerprint::cfg().set<std::int32_t>("enrollment_hit", 25);
382     mEngine.notifyFingerdown();
383     mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
384     mEngine.fingerDownAction();
385     ASSERT_EQ(1, mCallback->mInteractionDetectedCount);
386 }
387 
TEST_F(FakeFingerprintEngineTest,InteractionDetectError)388 TEST_F(FakeFingerprintEngineTest, InteractionDetectError) {
389     Fingerprint::cfg().set<bool>("detect_interaction", true);
390     Fingerprint::cfg().set<std::int32_t>("operation_detect_interaction_error", 8);
391     mEngine.notifyFingerdown();
392     mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
393     mEngine.fingerDownAction();
394     ASSERT_EQ(0, mCallback->mInteractionDetectedCount);
395     ASSERT_EQ(mCallback->mError, (Error)8);
396     ASSERT_EQ(mCallback->mErrorVendorCode, 0);
397 }
398 
TEST_F(FakeFingerprintEngineTest,InteractionDetectAcquired)399 TEST_F(FakeFingerprintEngineTest, InteractionDetectAcquired) {
400     Fingerprint::cfg().set<bool>("detect_interaction", true);
401     Fingerprint::cfg().setopt<OptIntVec>("enrollments", {1, 2});
402     Fingerprint::cfg().set<std::int32_t>("enrollment_hit", 2);
403     Fingerprint::cfg().set<std::string>("operation_detect_interaction_acquired", "4,1013");
404     int32_t prevCount = mCallback->mLastAcquiredCount;
405     mEngine.notifyFingerdown();
406     mEngine.detectInteractionImpl(mCallback.get(), mCancel.get_future());
407     mEngine.fingerDownAction();
408     ASSERT_EQ(1, mCallback->mInteractionDetectedCount);
409     ASSERT_EQ(prevCount + 2, mCallback->mLastAcquiredCount);
410     ASSERT_EQ(7, mCallback->mLastAcquiredInfo);
411     ASSERT_EQ(13, mCallback->mLastAcquiredVendorCode);
412 }
413 
TEST_F(FakeFingerprintEngineTest,EnumerateEnrolled)414 TEST_F(FakeFingerprintEngineTest, EnumerateEnrolled) {
415     Fingerprint::cfg().setopt<OptIntVec>("enrollments", {2, 4, 8});
416     mEngine.enumerateEnrollmentsImpl(mCallback.get());
417     ASSERT_EQ(3, mCallback->mLastEnrollmentEnumerated.size());
418     for (auto id : Fingerprint::cfg().getopt<OptIntVec>("enrollments")) {
419         ASSERT_TRUE(std::find(mCallback->mLastEnrollmentEnumerated.begin(),
420                               mCallback->mLastEnrollmentEnumerated.end(),
421                               id) != mCallback->mLastEnrollmentEnumerated.end());
422     }
423 }
424 
TEST_F(FakeFingerprintEngineTest,RemoveEnrolled)425 TEST_F(FakeFingerprintEngineTest, RemoveEnrolled) {
426     Fingerprint::cfg().setopt<OptIntVec>("enrollments", {2, 4, 8, 1});
427     mEngine.removeEnrollmentsImpl(mCallback.get(), {2, 8});
428     auto enrolls = Fingerprint::cfg().getopt<OptIntVec>("enrollments");
429     ASSERT_EQ(2, mCallback->mLastEnrollmentRemoved.size());
430     for (auto id : {2, 8}) {
431         ASSERT_TRUE(std::find(mCallback->mLastEnrollmentRemoved.begin(),
432                               mCallback->mLastEnrollmentRemoved.end(),
433                               id) != mCallback->mLastEnrollmentRemoved.end());
434     }
435     ASSERT_EQ(2, enrolls.size());
436     for (auto id : {1, 4}) {
437         ASSERT_TRUE(std::find(enrolls.begin(), enrolls.end(), id) != enrolls.end());
438     }
439 }
440 
TEST_F(FakeFingerprintEngineTest,parseIntSequence)441 TEST_F(FakeFingerprintEngineTest, parseIntSequence) {
442     std::vector<int32_t> seqV;
443     seqV = Util::parseIntSequence("");
444     ASSERT_EQ(0, seqV.size());
445     seqV = Util::parseIntSequence("2");
446     ASSERT_EQ(1, seqV.size());
447     ASSERT_EQ(2, seqV[0]);
448     seqV = Util::parseIntSequence("2,3,4");
449     std::vector<int32_t> expV{2, 3, 4};
450     ASSERT_EQ(expV, seqV);
451     seqV = Util::parseIntSequence("2,3,a");
452     ASSERT_EQ(0, seqV.size());
453     seqV = Util::parseIntSequence("2, 3, 4");
454     ASSERT_EQ(expV, seqV);
455     seqV = Util::parseIntSequence("123,456");
456     ASSERT_EQ(2, seqV.size());
457     std::vector<int32_t> expV1{123, 456};
458     ASSERT_EQ(expV1, seqV);
459     seqV = Util::parseIntSequence("12f3,456");
460     ASSERT_EQ(0, seqV.size());
461 }
462 
TEST_F(FakeFingerprintEngineTest,parseEnrollmentCaptureOk)463 TEST_F(FakeFingerprintEngineTest, parseEnrollmentCaptureOk) {
464     std::vector<std::vector<int32_t>> ecV;
465     ecV = Util::parseEnrollmentCapture("100,200,300");
466     ASSERT_EQ(6, ecV.size());
467     std::vector<std::vector<int32_t>> expE{{100}, {200}, {300}};
468     std::vector<int32_t> defC{1};
469     for (int i = 0; i < ecV.size(); i += 2) {
470         ASSERT_EQ(expE[i / 2], ecV[i]);
471         ASSERT_EQ(defC, ecV[i + 1]);
472     }
473     ecV = Util::parseEnrollmentCapture("100");
474     ASSERT_EQ(2, ecV.size());
475     ASSERT_EQ(expE[0], ecV[0]);
476     ASSERT_EQ(defC, ecV[1]);
477 
478     ecV = Util::parseEnrollmentCapture("100-[5,6,7]");
479     std::vector<int32_t> expC{5, 6, 7};
480     ASSERT_EQ(2, ecV.size());
481     for (int i = 0; i < ecV.size(); i += 2) {
482         ASSERT_EQ(expE[i / 2], ecV[i]);
483         ASSERT_EQ(expC, ecV[i + 1]);
484     }
485     ecV = Util::parseEnrollmentCapture("100-[5,6,7], 200, 300-[9,10]");
486     std::vector<std::vector<int32_t>> expC1{{5, 6, 7}, {1}, {9, 10}};
487     ASSERT_EQ(6, ecV.size());
488     for (int i = 0; i < ecV.size(); i += 2) {
489         ASSERT_EQ(expE[i / 2], ecV[i]);
490         ASSERT_EQ(expC1[i / 2], ecV[i + 1]);
491     }
492     ecV = Util::parseEnrollmentCapture("100-[5,6,7], 200-[2,1], 300-[9]");
493     std::vector<std::vector<int32_t>> expC2{{5, 6, 7}, {2, 1}, {9}};
494     ASSERT_EQ(ecV.size(), 6);
495     for (int i = 0; i < ecV.size(); i += 2) {
496         ASSERT_EQ(expE[i / 2], ecV[i]);
497         ASSERT_EQ(expC2[i / 2], ecV[i + 1]);
498     }
499 }
500 
TEST_F(FakeFingerprintEngineTest,parseEnrollmentCaptureFail)501 TEST_F(FakeFingerprintEngineTest, parseEnrollmentCaptureFail) {
502     std::vector<std::string> badStr{"10c",         "100-5",   "100-[5,6,7", "100-5,6,7]",
503                                     "100,2x0,300", "200-[f]", "a,b"};
504     std::vector<std::vector<int32_t>> ecV;
505     for (const auto& s : badStr) {
506         ecV = Util::parseEnrollmentCapture(s);
507         ASSERT_EQ(ecV.size(), 0);
508     }
509 }
510 
TEST_F(FakeFingerprintEngineTest,randomLatency)511 TEST_F(FakeFingerprintEngineTest, randomLatency) {
512     Fingerprint::cfg().setopt<OptIntVec>("operation_detect_interaction_latency", {});
513     ASSERT_EQ(DEFAULT_LATENCY, mEngine.getLatency(Fingerprint::cfg().getopt<OptIntVec>(
514                                        "operation_detect_interaction_latency")));
515     Fingerprint::cfg().setopt<OptIntVec>("operation_detect_interaction_latency", {10});
516     ASSERT_EQ(10, mEngine.getLatency(Fingerprint::cfg().getopt<OptIntVec>(
517                           "operation_detect_interaction_latency")));
518     Fingerprint::cfg().setopt<OptIntVec>("operation_detect_interaction_latency", {1, 1000});
519     std::set<int32_t> latencySet;
520     for (int i = 0; i < 100; i++) {
521         latencySet.insert(mEngine.getLatency(
522                 Fingerprint::cfg().getopt<OptIntVec>("operation_detect_interaction_latency")));
523     }
524     ASSERT_TRUE(latencySet.size() > 95);
525 }
526 
TEST_F(FakeFingerprintEngineTest,lockoutTimer)527 TEST_F(FakeFingerprintEngineTest, lockoutTimer) {
528     mEngine.startLockoutTimer(200, mCallback.get());
529     ASSERT_TRUE(mEngine.getLockoutTimerStarted());
530     std::this_thread::sleep_for(std::chrono::milliseconds(250));
531     ASSERT_FALSE(mEngine.getLockoutTimerStarted());
532     ASSERT_TRUE(mCallback->mLockoutCleared);
533 }
534 }  // namespace aidl::android::hardware::biometrics::fingerprint
535 
main(int argc,char ** argv)536 int main(int argc, char** argv) {
537     testing::InitGoogleTest(&argc, argv);
538     ABinderProcess_startThreadPool();
539     return RUN_ALL_TESTS();
540 }
541