xref: /aosp_15_r20/hardware/interfaces/biometrics/face/aidl/default/tests/FakeLockoutTrackerTest.cpp (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1 /*
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 
24 #include "Face.h"
25 #include "FakeLockoutTracker.h"
26 #include "util/Util.h"
27 
28 using namespace ::android::face::virt;
29 using namespace ::aidl::android::hardware::biometrics::face;
30 
31 namespace aidl::android::hardware::biometrics::face {
32 
33 class TestSessionCallback : public BnSessionCallback {
34   public:
onChallengeGenerated(int64_t)35     ndk::ScopedAStatus onChallengeGenerated(int64_t /*challenge*/) override {
36         return ndk::ScopedAStatus::ok();
37     };
onChallengeRevoked(int64_t)38     ::ndk::ScopedAStatus onChallengeRevoked(int64_t /*challenge*/) override {
39         return ndk::ScopedAStatus::ok();
40     };
onError(face::Error,int32_t)41     ::ndk::ScopedAStatus onError(face::Error, int32_t /*vendorCode*/) override {
42         return ndk::ScopedAStatus::ok();
43     };
onEnrollmentProgress(int32_t,int32_t)44     ::ndk::ScopedAStatus onEnrollmentProgress(int32_t /*enrollmentId*/,
45                                               int32_t /*remaining*/) override {
46         return ndk::ScopedAStatus::ok();
47     };
onAuthenticationSucceeded(int32_t,const keymaster::HardwareAuthToken &)48     ::ndk::ScopedAStatus onAuthenticationSucceeded(int32_t /*enrollmentId*/,
49                                                    const keymaster::HardwareAuthToken&) override {
50         return ndk::ScopedAStatus::ok();
51     };
onAuthenticationFailed()52     ::ndk::ScopedAStatus onAuthenticationFailed() override { return ndk::ScopedAStatus::ok(); };
onInteractionDetected()53     ::ndk::ScopedAStatus onInteractionDetected() override { return ndk::ScopedAStatus::ok(); };
onEnrollmentsEnumerated(const std::vector<int32_t> &)54     ::ndk::ScopedAStatus onEnrollmentsEnumerated(const std::vector<int32_t>&) override {
55         return ndk::ScopedAStatus::ok();
56     };
onEnrollmentsRemoved(const std::vector<int32_t> &)57     ::ndk::ScopedAStatus onEnrollmentsRemoved(
58             const std::vector<int32_t>& /*enrollmentIds*/) override {
59         return ndk::ScopedAStatus::ok();
60     };
onAuthenticatorIdRetrieved(int64_t)61     ::ndk::ScopedAStatus onAuthenticatorIdRetrieved(int64_t /*authenticatorId*/) override {
62         return ndk::ScopedAStatus::ok();
63     };
onAuthenticatorIdInvalidated(int64_t)64     ::ndk::ScopedAStatus onAuthenticatorIdInvalidated(int64_t /*authenticatorId*/) override {
65         return ndk::ScopedAStatus::ok();
66     };
onEnrollmentFrame(const EnrollmentFrame &)67     ::ndk::ScopedAStatus onEnrollmentFrame(const EnrollmentFrame&) override {
68         return ndk::ScopedAStatus::ok();
69     }
onFeaturesRetrieved(const std::vector<Feature> &)70     ::ndk::ScopedAStatus onFeaturesRetrieved(const std::vector<Feature>&) {
71         return ndk::ScopedAStatus::ok();
72     };
onFeatureSet(Feature)73     ::ndk::ScopedAStatus onFeatureSet(Feature) override { return ndk::ScopedAStatus::ok(); }
onSessionClosed()74     ::ndk::ScopedAStatus onSessionClosed() override { return ndk::ScopedAStatus::ok(); }
onAuthenticationFrame(const AuthenticationFrame &)75     ::ndk::ScopedAStatus onAuthenticationFrame(const AuthenticationFrame&) override {
76         return ndk::ScopedAStatus::ok();
77     }
78 
onLockoutTimed(int64_t timeLeft)79     ndk::ScopedAStatus onLockoutTimed(int64_t timeLeft) override {
80         mLockoutTimed++;
81         mTimeLeft = timeLeft;
82         return ndk::ScopedAStatus::ok();
83     };
onLockoutPermanent()84     ::ndk::ScopedAStatus onLockoutPermanent() override {
85         mLockoutPermanent++;
86         return ndk::ScopedAStatus::ok();
87     };
onLockoutCleared()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 
100 class 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 
SetUp()106     void SetUp() override {
107         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);
112         mCallback = ndk::SharedRefBase::make<TestSessionCallback>();
113     }
114 
TearDown()115     void TearDown() override {
116         // reset to default
117         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);
122     }
123 
124     FakeLockoutTracker mLockoutTracker;
125     std::shared_ptr<TestSessionCallback> mCallback;
126 };
127 
TEST_F(FakeLockoutTrackerTest,addFailedAttemptDisable)128 TEST_F(FakeLockoutTrackerTest, addFailedAttemptDisable) {
129     Face::cfg().set<bool>("lockout_enable", false);
130     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 
TEST_F(FakeLockoutTrackerTest,addFailedAttemptPermanent)136 TEST_F(FakeLockoutTrackerTest, addFailedAttemptPermanent) {
137     Face::cfg().set<bool>("lockout_enable", true);
138     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 
TEST_F(FakeLockoutTrackerTest,addFailedAttemptLockoutTimed)150 TEST_F(FakeLockoutTrackerTest, addFailedAttemptLockoutTimed) {
151     Face::cfg().set<bool>("lockout_enable", true);
152     Face::cfg().set<bool>("lockout_timed_enable", true);
153     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 
TEST_F(FakeLockoutTrackerTest,addFailedAttemptLockout_TimedThenPermanent)173 TEST_F(FakeLockoutTrackerTest, addFailedAttemptLockout_TimedThenPermanent) {
174     Face::cfg().set<bool>("lockout_enable", true);
175     Face::cfg().set<bool>("lockout_timed_enable", true);
176     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 
TEST_F(FakeLockoutTrackerTest,addFailedAttemptLockoutTimedTwice)187 TEST_F(FakeLockoutTrackerTest, addFailedAttemptLockoutTimedTwice) {
188     Face::cfg().set<bool>("lockout_enable", true);
189     Face::cfg().set<bool>("lockout_timed_enable", true);
190     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 
TEST_F(FakeLockoutTrackerTest,resetLockout)203 TEST_F(FakeLockoutTrackerTest, resetLockout) {
204     Face::cfg().set<bool>("lockout_enable", true);
205     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 
main(int argc,char ** argv)215 int main(int argc, char** argv) {
216     testing::InitGoogleTest(&argc, argv);
217     ABinderProcess_startThreadPool();
218     return RUN_ALL_TESTS();
219 }
220