1 /*
2  * Copyright (C) 2018 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 "RateLimiter.h"
18 #include <utils/Timers.h>
19 
20 namespace hardware {
21 namespace google {
22 namespace pixelstats {
23 namespace V1_0 {
24 namespace implementation {
25 
26 // for tests only
TurnBackHours(int32_t hours)27 void RateLimiter::TurnBackHours(int32_t hours) {
28     nsecs_at_rollover_ = systemTime(SYSTEM_TIME_BOOTTIME) - s2ns(hours * 60 * 60);
29 }
30 
31 // Update the 24hr limit for all actions
SetOverallDailyLimit(int32_t limit)32 void RateLimiter::SetOverallDailyLimit(int32_t limit) {
33     std::lock_guard<std::mutex> lock(lock_);
34     overall_limit_ = limit;
35 }
36 
37 // Returns true if you should rate limit the action reporting, false if not.
38 // limit: the number of times the action can occur within 24hrs.
RateLimit(int32_t action,int32_t limit)39 bool RateLimiter::RateLimit(int32_t action, int32_t limit) {
40     std::lock_guard<std::mutex> lock(lock_);
41     int64_t nsecsNow = systemTime(SYSTEM_TIME_BOOTTIME);
42 
43     if (nsecsNow < nsecs_at_rollover_) {
44         return true;  // fail safe, rate limit.
45     }
46     int64_t elapsed = nsecsNow - nsecs_at_rollover_;
47     constexpr int64_t kDaySeconds = 60 * 60 * 24;
48     if (nanoseconds_to_seconds(elapsed) > kDaySeconds) {
49         counts_.clear();
50         overall_count_ = 0;
51         nsecs_at_rollover_ = nsecsNow;
52     }
53 
54     if (++counts_[action] > limit) return true;
55     if (overall_limit_ && ++overall_count_ > overall_limit_) return true;
56     return false;
57 }
58 
59 }  // namespace implementation
60 }  // namespace V1_0
61 }  // namespace pixelstats
62 }  // namespace google
63 }  // namespace hardware
64