• 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 #define LOG_TAG "FaceVirtualHalLockoutTracker"
18 
19 #include "FakeLockoutTracker.h"
20 #include <android-base/logging.h>
21 #include <face.sysprop.h>
22 #include "util/Util.h"
23 
24 using namespace ::android::face::virt;
25 
26 namespace aidl::android::hardware::biometrics::face {
27 
reset(bool dueToTimerExpire)28 void FakeLockoutTracker::reset(bool dueToTimerExpire) {
29     if (!dueToTimerExpire) {
30         mFailedCount = 0;
31         mLastFailedTime = 0;
32     }
33     mTimedFailedCount = 0;
34     mCurrentMode = LockoutMode::kNone;
35     abortTimer();
36 }
37 
addFailedAttempt(ISessionCallback * cb)38 void FakeLockoutTracker::addFailedAttempt(ISessionCallback* cb) {
39     bool lockoutEnabled = FaceHalProperties::lockout_enable().value_or(false);
40     bool timedLockoutenabled = FaceHalProperties::lockout_timed_enable().value_or(false);
41     if (lockoutEnabled) {
42         mFailedCount++;
43         mTimedFailedCount++;
44         mLastFailedTime = Util::getSystemNanoTime();
45         int32_t lockoutTimedThreshold = FaceHalProperties::lockout_timed_threshold().value_or(3);
46         int32_t lockoutPermanetThreshold =
47                 FaceHalProperties::lockout_permanent_threshold().value_or(5);
48         if (mFailedCount >= lockoutPermanetThreshold) {
49             mCurrentMode = LockoutMode::kPermanent;
50             LOG(ERROR) << "FakeLockoutTracker: lockoutPermanent";
51             cb->onLockoutPermanent();
52             abortTimer();
53         } else if (timedLockoutenabled && mTimedFailedCount >= lockoutTimedThreshold) {
54             if (mCurrentMode == LockoutMode::kNone) {
55                 mCurrentMode = LockoutMode::kTimed;
56                 startLockoutTimer(getTimedLockoutDuration(), cb);
57             }
58             LOG(ERROR) << "FakeLockoutTracker: lockoutTimed";
59             cb->onLockoutTimed(getLockoutTimeLeft());
60         }
61     } else {
62         reset();
63     }
64 }
65 
getMode()66 FakeLockoutTracker::LockoutMode FakeLockoutTracker::getMode() {
67     return mCurrentMode;
68 }
69 
getTimedLockoutDuration()70 int32_t FakeLockoutTracker::getTimedLockoutDuration() {
71     return FaceHalProperties::lockout_timed_duration().value_or(10 * 1000);
72 }
73 
getLockoutTimeLeft()74 int64_t FakeLockoutTracker::getLockoutTimeLeft() {
75     int64_t res = 0;
76 
77     if (mLastFailedTime > 0) {
78         auto now = Util::getSystemNanoTime();
79         auto elapsed = (now - mLastFailedTime) / 1000000LL;
80         res = getTimedLockoutDuration() - elapsed;
81         LOG(INFO) << "elapsed=" << elapsed << " now = " << now
82                   << " mLastFailedTime=" << mLastFailedTime << " res=" << res;
83     }
84 
85     return res;
86 }
87 
checkIfLockout(ISessionCallback * cb)88 bool FakeLockoutTracker::checkIfLockout(ISessionCallback* cb) {
89     if (mCurrentMode == LockoutMode::kPermanent) {
90         LOG(ERROR) << "Lockout permanent";
91         cb->onLockoutPermanent();
92         return true;
93     } else if (mCurrentMode == LockoutMode::kTimed) {
94         auto timeLeft = getLockoutTimeLeft();
95         LOG(ERROR) << "Lockout timed " << timeLeft;
96         cb->onLockoutTimed(timeLeft);
97         return true;
98     }
99     return false;
100 }
101 
startLockoutTimer(int64_t timeout,ISessionCallback * cb)102 void FakeLockoutTracker::startLockoutTimer(int64_t timeout, ISessionCallback* cb) {
103     LOG(ERROR) << "startLockoutTimer: to=" << timeout;
104     if (mIsLockoutTimerStarted) return;
105     std::function<void(ISessionCallback*)> action =
106             std::bind(&FakeLockoutTracker::lockoutTimerExpired, this, std::placeholders::_1);
107     std::thread([timeout, action, cb]() {
108         std::this_thread::sleep_for(std::chrono::milliseconds(timeout));
109         action(cb);
110     }).detach();
111 
112     mIsLockoutTimerStarted = true;
113 }
114 
lockoutTimerExpired(ISessionCallback * cb)115 void FakeLockoutTracker::lockoutTimerExpired(ISessionCallback* cb) {
116     LOG(INFO) << "lockout timer expired";
117     mIsLockoutTimerStarted = false;
118 
119     if (mIsLockoutTimerAborted) {
120         mIsLockoutTimerAborted = false;
121         return;
122     }
123 
124     // if more failures seen since the timer started, need to restart timer again
125     auto deltaTime = getLockoutTimeLeft();
126     if (deltaTime <= 0) {
127         cb->onLockoutCleared();
128         reset(true);
129     } else {
130         startLockoutTimer(deltaTime, cb);
131     }
132 }
133 
abortTimer()134 void FakeLockoutTracker::abortTimer() {
135     if (mIsLockoutTimerStarted) mIsLockoutTimerAborted = true;
136 }
137 
138 }  // namespace aidl::android::hardware::biometrics::face
139