blob: 8564f6b8e21b778c6c9073706bffff64a6a6ff44 [file] [log] [blame]
Jeff Pu3e7448d2023-12-07 17:25:22 +00001/*
2 * Copyright (C) 2023 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 <aidl/android/hardware/biometrics/face/BnSessionCallback.h>
18#include <android/binder_process.h>
19#include <face.sysprop.h>
20#include <gtest/gtest.h>
21
22#include <android-base/logging.h>
23
Jeff Pua3c57362024-06-10 15:03:50 +000024#include "Face.h"
Jeff Pu3e7448d2023-12-07 17:25:22 +000025#include "FakeLockoutTracker.h"
26#include "util/Util.h"
27
28using namespace ::android::face::virt;
29using namespace ::aidl::android::hardware::biometrics::face;
30
31namespace aidl::android::hardware::biometrics::face {
32
33class TestSessionCallback : public BnSessionCallback {
34 public:
35 ndk::ScopedAStatus onChallengeGenerated(int64_t /*challenge*/) override {
36 return ndk::ScopedAStatus::ok();
37 };
38 ::ndk::ScopedAStatus onChallengeRevoked(int64_t /*challenge*/) override {
39 return ndk::ScopedAStatus::ok();
40 };
41 ::ndk::ScopedAStatus onError(face::Error, int32_t /*vendorCode*/) override {
42 return ndk::ScopedAStatus::ok();
43 };
44 ::ndk::ScopedAStatus onEnrollmentProgress(int32_t /*enrollmentId*/,
45 int32_t /*remaining*/) override {
46 return ndk::ScopedAStatus::ok();
47 };
48 ::ndk::ScopedAStatus onAuthenticationSucceeded(int32_t /*enrollmentId*/,
49 const keymaster::HardwareAuthToken&) override {
50 return ndk::ScopedAStatus::ok();
51 };
52 ::ndk::ScopedAStatus onAuthenticationFailed() override { return ndk::ScopedAStatus::ok(); };
53 ::ndk::ScopedAStatus onInteractionDetected() override { return ndk::ScopedAStatus::ok(); };
54 ::ndk::ScopedAStatus onEnrollmentsEnumerated(const std::vector<int32_t>&) override {
55 return ndk::ScopedAStatus::ok();
56 };
57 ::ndk::ScopedAStatus onEnrollmentsRemoved(
58 const std::vector<int32_t>& /*enrollmentIds*/) override {
59 return ndk::ScopedAStatus::ok();
60 };
61 ::ndk::ScopedAStatus onAuthenticatorIdRetrieved(int64_t /*authenticatorId*/) override {
62 return ndk::ScopedAStatus::ok();
63 };
64 ::ndk::ScopedAStatus onAuthenticatorIdInvalidated(int64_t /*authenticatorId*/) override {
65 return ndk::ScopedAStatus::ok();
66 };
67 ::ndk::ScopedAStatus onEnrollmentFrame(const EnrollmentFrame&) override {
68 return ndk::ScopedAStatus::ok();
69 }
70 ::ndk::ScopedAStatus onFeaturesRetrieved(const std::vector<Feature>&) {
71 return ndk::ScopedAStatus::ok();
72 };
73 ::ndk::ScopedAStatus onFeatureSet(Feature) override { return ndk::ScopedAStatus::ok(); }
74 ::ndk::ScopedAStatus onSessionClosed() override { return ndk::ScopedAStatus::ok(); }
75 ::ndk::ScopedAStatus onAuthenticationFrame(const AuthenticationFrame&) override {
76 return ndk::ScopedAStatus::ok();
77 }
78
79 ndk::ScopedAStatus onLockoutTimed(int64_t timeLeft) override {
80 mLockoutTimed++;
81 mTimeLeft = timeLeft;
82 return ndk::ScopedAStatus::ok();
83 };
84 ::ndk::ScopedAStatus onLockoutPermanent() override {
85 mLockoutPermanent++;
86 return ndk::ScopedAStatus::ok();
87 };
88 ::ndk::ScopedAStatus onLockoutCleared() override {
89 mTimeLeft = 0;
90 mLockoutTimed = 0;
91 mLockoutPermanent = 0;
92 return ndk::ScopedAStatus::ok();
93 };
94
95 int64_t mTimeLeft = 0;
96 int mLockoutTimed = 0;
97 int mLockoutPermanent = 0;
98};
99
100class FakeLockoutTrackerTest : public ::testing::Test {
101 protected:
102 static constexpr int32_t LOCKOUT_TIMED_THRESHOLD = 3;
103 static constexpr int32_t LOCKOUT_PERMANENT_THRESHOLD = 5;
104 static constexpr int32_t LOCKOUT_TIMED_DURATION = 100;
105
106 void SetUp() override {
Jeff Pua3c57362024-06-10 15:03:50 +0000107 Face::cfg().set<std::int32_t>("lockout_timed_threshold", LOCKOUT_TIMED_THRESHOLD);
108 Face::cfg().set<std::int32_t>("lockout_timed_duration", LOCKOUT_TIMED_DURATION);
109 Face::cfg().set<std::int32_t>("lockout_permanent_threshold", LOCKOUT_PERMANENT_THRESHOLD);
110 Face::cfg().set<bool>("lockout_enable", false);
111 Face::cfg().set<bool>("lockout", false);
Jeff Pu3e7448d2023-12-07 17:25:22 +0000112 mCallback = ndk::SharedRefBase::make<TestSessionCallback>();
113 }
114
115 void TearDown() override {
116 // reset to default
Jeff Pua3c57362024-06-10 15:03:50 +0000117 Face::cfg().set<std::int32_t>("lockout_timed_threshold", 5);
118 Face::cfg().set<std::int32_t>("lockout_timed_duration", 20);
119 Face::cfg().set<std::int32_t>("lockout_permanent_threshold", 10000);
120 Face::cfg().set<bool>("lockout_enable", false);
121 Face::cfg().set<bool>("lockout", false);
Jeff Pu3e7448d2023-12-07 17:25:22 +0000122 }
123
124 FakeLockoutTracker mLockoutTracker;
125 std::shared_ptr<TestSessionCallback> mCallback;
126};
127
128TEST_F(FakeLockoutTrackerTest, addFailedAttemptDisable) {
Jeff Pua3c57362024-06-10 15:03:50 +0000129 Face::cfg().set<bool>("lockout_enable", false);
Jeff Pu3e7448d2023-12-07 17:25:22 +0000130 for (int i = 0; i < LOCKOUT_TIMED_THRESHOLD + 1; i++)
131 mLockoutTracker.addFailedAttempt(mCallback.get());
132 ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kNone);
133 ASSERT_EQ(0, mCallback->mLockoutTimed);
134}
135
136TEST_F(FakeLockoutTrackerTest, addFailedAttemptPermanent) {
Jeff Pua3c57362024-06-10 15:03:50 +0000137 Face::cfg().set<bool>("lockout_enable", true);
Jeff Pu3e7448d2023-12-07 17:25:22 +0000138 ASSERT_FALSE(mLockoutTracker.checkIfLockout(mCallback.get()));
139 for (int i = 0; i < LOCKOUT_PERMANENT_THRESHOLD - 1; i++)
140 mLockoutTracker.addFailedAttempt(mCallback.get());
141 ASSERT_NE(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kPermanent);
142 ASSERT_EQ(0, mCallback->mLockoutPermanent);
143 mLockoutTracker.addFailedAttempt(mCallback.get());
144 ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kPermanent);
145 ASSERT_EQ(1, mCallback->mLockoutPermanent);
146 ASSERT_TRUE(mLockoutTracker.checkIfLockout(mCallback.get()));
147 ASSERT_EQ(2, mCallback->mLockoutPermanent);
148}
149
150TEST_F(FakeLockoutTrackerTest, addFailedAttemptLockoutTimed) {
Jeff Pua3c57362024-06-10 15:03:50 +0000151 Face::cfg().set<bool>("lockout_enable", true);
152 Face::cfg().set<bool>("lockout_timed_enable", true);
Jeff Pu3e7448d2023-12-07 17:25:22 +0000153 ASSERT_FALSE(mLockoutTracker.checkIfLockout(mCallback.get()));
154 for (int i = 0; i < LOCKOUT_TIMED_THRESHOLD; i++)
155 mLockoutTracker.addFailedAttempt(mCallback.get());
156 ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kTimed);
157 ASSERT_EQ(1, mCallback->mLockoutTimed);
158 ASSERT_TRUE(mLockoutTracker.checkIfLockout(mCallback.get()));
159 ASSERT_EQ(2, mCallback->mLockoutTimed);
160 // time left
161 int N = 5;
162 int64_t prevTimeLeft = INT_MAX;
163 for (int i = 0; i < N; i++) {
164 SLEEP_MS(LOCKOUT_TIMED_DURATION / N + 1);
165 int64_t currTimeLeft = mLockoutTracker.getLockoutTimeLeft();
166 ASSERT_TRUE(currTimeLeft < prevTimeLeft);
167 prevTimeLeft = currTimeLeft;
168 }
169 SLEEP_MS(LOCKOUT_TIMED_DURATION / N);
170 ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kNone);
171}
172
173TEST_F(FakeLockoutTrackerTest, addFailedAttemptLockout_TimedThenPermanent) {
Jeff Pua3c57362024-06-10 15:03:50 +0000174 Face::cfg().set<bool>("lockout_enable", true);
175 Face::cfg().set<bool>("lockout_timed_enable", true);
Jeff Pu3e7448d2023-12-07 17:25:22 +0000176 ASSERT_FALSE(mLockoutTracker.checkIfLockout(mCallback.get()));
177 for (int i = 0; i < LOCKOUT_TIMED_THRESHOLD; i++)
178 mLockoutTracker.addFailedAttempt(mCallback.get());
179 ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kTimed);
180 SLEEP_MS(LOCKOUT_TIMED_DURATION + 20);
181 ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kNone);
182 for (int i = 0; i < LOCKOUT_PERMANENT_THRESHOLD - LOCKOUT_TIMED_THRESHOLD; i++)
183 mLockoutTracker.addFailedAttempt(mCallback.get());
184 ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kPermanent);
185}
186
187TEST_F(FakeLockoutTrackerTest, addFailedAttemptLockoutTimedTwice) {
Jeff Pua3c57362024-06-10 15:03:50 +0000188 Face::cfg().set<bool>("lockout_enable", true);
189 Face::cfg().set<bool>("lockout_timed_enable", true);
Jeff Pu3e7448d2023-12-07 17:25:22 +0000190 ASSERT_FALSE(mLockoutTracker.checkIfLockout(mCallback.get()));
191 ASSERT_EQ(0, mCallback->mLockoutTimed);
192 for (int i = 0; i < LOCKOUT_TIMED_THRESHOLD; i++)
193 mLockoutTracker.addFailedAttempt(mCallback.get());
194 SLEEP_MS(LOCKOUT_TIMED_DURATION / 2);
195 mLockoutTracker.addFailedAttempt(mCallback.get());
196 SLEEP_MS(LOCKOUT_TIMED_DURATION);
197 ASSERT_EQ(2, mCallback->mLockoutTimed);
198 ASSERT_TRUE(mLockoutTracker.checkIfLockout(mCallback.get()));
199 SLEEP_MS(LOCKOUT_TIMED_DURATION);
200 ASSERT_FALSE(mLockoutTracker.checkIfLockout(mCallback.get()));
201}
202
203TEST_F(FakeLockoutTrackerTest, resetLockout) {
Jeff Pua3c57362024-06-10 15:03:50 +0000204 Face::cfg().set<bool>("lockout_enable", true);
Jeff Pu3e7448d2023-12-07 17:25:22 +0000205 ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kNone);
206 for (int i = 0; i < LOCKOUT_PERMANENT_THRESHOLD; i++)
207 mLockoutTracker.addFailedAttempt(mCallback.get());
208 ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kPermanent);
209 mLockoutTracker.reset();
210 ASSERT_FALSE(mLockoutTracker.checkIfLockout(mCallback.get()));
211}
212
213} // namespace aidl::android::hardware::biometrics::face
214
215int main(int argc, char** argv) {
216 testing::InitGoogleTest(&argc, argv);
217 ABinderProcess_startThreadPool();
218 return RUN_ALL_TESTS();
219}