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