1 /*
2  * Copyright (C) 2019 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 package com.android.server.wifi.util;
18 
19 import com.android.server.wifi.Clock;
20 
21 /**
22  * Manages a quota that is reset at the beginning of each new time period.
23  */
24 public class TimedQuotaManager {
25     private final Clock mClock;
26 
27     private final long mQuota;
28     private final long mPeriodMillis;
29     private final long mStartTimeMillis;
30 
31     /**
32      * The number of elapsed periods between {@link #mStartTimeMillis} and the time of the last call
33      * to {@link #requestQuota()}.
34      */
35     private long mLastPeriod;
36     /** How much quota has been consumed in the current period. */
37     private long mConsumedQuota;
38 
39     /**
40      * Constructor.
41      * @param clock Clock instance.
42      * @param quota the maximum quota for a given period.
43      * @param periodMillis the quota will be reset at the beginning of each new period.
44      */
TimedQuotaManager(Clock clock, long quota, long periodMillis)45     public TimedQuotaManager(Clock clock, long quota, long periodMillis) {
46         mClock = clock;
47         mQuota = quota;
48         mPeriodMillis = periodMillis;
49         mStartTimeMillis = clock.getElapsedSinceBootMillis();
50         mLastPeriod = 0;
51         mConsumedQuota = 0;
52     }
53 
54     /**
55      * Requests one quota. If there is sufficient remaining quota for the current period,
56      * returns true and consumes one quota. Otherwise, returns false.
57      */
requestQuota()58     public boolean requestQuota() {
59         long currentPeriod = getCurrentPeriod();
60         if (mLastPeriod < currentPeriod) {
61             mLastPeriod = currentPeriod;
62             mConsumedQuota = 0;
63         }
64         if (mConsumedQuota < mQuota) {
65             mConsumedQuota++;
66             return true;
67         }
68         return false;
69     }
70 
getCurrentPeriod()71     private long getCurrentPeriod() {
72         return (mClock.getElapsedSinceBootMillis() - mStartTimeMillis) / mPeriodMillis;
73     }
74 
75     @Override
toString()76     public String toString() {
77         return "TimedQuotaManager{"
78                 + "mQuota=" + mQuota
79                 + ", mPeriodMillis=" + mPeriodMillis
80                 + ", mStartTimeMillis=" + mStartTimeMillis
81                 + ", mLastPeriod=" + mLastPeriod
82                 + ", mConsumedQuota=" + mConsumedQuota
83                 + '}';
84     }
85 }
86