1 /*
2  * Copyright (C) 2011 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 android.net;
18 
19 import static com.android.internal.util.Preconditions.checkNotNull;
20 
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 
24 import java.util.Objects;
25 
26 /**
27  * Policy for networks matching a {@link NetworkTemplate}, including usage cycle
28  * and limits to be enforced.
29  *
30  * @hide
31  */
32 public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
33     public static final int CYCLE_NONE = -1;
34     public static final long WARNING_DISABLED = -1;
35     public static final long LIMIT_DISABLED = -1;
36     public static final long SNOOZE_NEVER = -1;
37 
38     public NetworkTemplate template;
39     public int cycleDay;
40     public String cycleTimezone;
41     public long warningBytes;
42     public long limitBytes;
43     public long lastWarningSnooze;
44     public long lastLimitSnooze;
45     public boolean metered;
46     public boolean inferred;
47 
48     private static final long DEFAULT_MTU = 1500;
49 
50     @Deprecated
NetworkPolicy(NetworkTemplate template, int cycleDay, String cycleTimezone, long warningBytes, long limitBytes, boolean metered)51     public NetworkPolicy(NetworkTemplate template, int cycleDay, String cycleTimezone,
52             long warningBytes, long limitBytes, boolean metered) {
53         this(template, cycleDay, cycleTimezone, warningBytes, limitBytes, SNOOZE_NEVER,
54                 SNOOZE_NEVER, metered, false);
55     }
56 
NetworkPolicy(NetworkTemplate template, int cycleDay, String cycleTimezone, long warningBytes, long limitBytes, long lastWarningSnooze, long lastLimitSnooze, boolean metered, boolean inferred)57     public NetworkPolicy(NetworkTemplate template, int cycleDay, String cycleTimezone,
58             long warningBytes, long limitBytes, long lastWarningSnooze, long lastLimitSnooze,
59             boolean metered, boolean inferred) {
60         this.template = checkNotNull(template, "missing NetworkTemplate");
61         this.cycleDay = cycleDay;
62         this.cycleTimezone = checkNotNull(cycleTimezone, "missing cycleTimezone");
63         this.warningBytes = warningBytes;
64         this.limitBytes = limitBytes;
65         this.lastWarningSnooze = lastWarningSnooze;
66         this.lastLimitSnooze = lastLimitSnooze;
67         this.metered = metered;
68         this.inferred = inferred;
69     }
70 
NetworkPolicy(Parcel in)71     public NetworkPolicy(Parcel in) {
72         template = in.readParcelable(null);
73         cycleDay = in.readInt();
74         cycleTimezone = in.readString();
75         warningBytes = in.readLong();
76         limitBytes = in.readLong();
77         lastWarningSnooze = in.readLong();
78         lastLimitSnooze = in.readLong();
79         metered = in.readInt() != 0;
80         inferred = in.readInt() != 0;
81     }
82 
83     @Override
writeToParcel(Parcel dest, int flags)84     public void writeToParcel(Parcel dest, int flags) {
85         dest.writeParcelable(template, flags);
86         dest.writeInt(cycleDay);
87         dest.writeString(cycleTimezone);
88         dest.writeLong(warningBytes);
89         dest.writeLong(limitBytes);
90         dest.writeLong(lastWarningSnooze);
91         dest.writeLong(lastLimitSnooze);
92         dest.writeInt(metered ? 1 : 0);
93         dest.writeInt(inferred ? 1 : 0);
94     }
95 
96     @Override
describeContents()97     public int describeContents() {
98         return 0;
99     }
100 
101     /**
102      * Test if given measurement is over {@link #warningBytes}.
103      */
isOverWarning(long totalBytes)104     public boolean isOverWarning(long totalBytes) {
105         return warningBytes != WARNING_DISABLED && totalBytes >= warningBytes;
106     }
107 
108     /**
109      * Test if given measurement is near enough to {@link #limitBytes} to be
110      * considered over-limit.
111      */
isOverLimit(long totalBytes)112     public boolean isOverLimit(long totalBytes) {
113         // over-estimate, since kernel will trigger limit once first packet
114         // trips over limit.
115         totalBytes += 2 * DEFAULT_MTU;
116         return limitBytes != LIMIT_DISABLED && totalBytes >= limitBytes;
117     }
118 
119     /**
120      * Clear any existing snooze values, setting to {@link #SNOOZE_NEVER}.
121      */
clearSnooze()122     public void clearSnooze() {
123         lastWarningSnooze = SNOOZE_NEVER;
124         lastLimitSnooze = SNOOZE_NEVER;
125     }
126 
127     /**
128      * Test if this policy has a cycle defined, after which usage should reset.
129      */
hasCycle()130     public boolean hasCycle() {
131         return cycleDay != CYCLE_NONE;
132     }
133 
134     @Override
compareTo(NetworkPolicy another)135     public int compareTo(NetworkPolicy another) {
136         if (another == null || another.limitBytes == LIMIT_DISABLED) {
137             // other value is missing or disabled; we win
138             return -1;
139         }
140         if (limitBytes == LIMIT_DISABLED || another.limitBytes < limitBytes) {
141             // we're disabled or other limit is smaller; they win
142             return 1;
143         }
144         return 0;
145     }
146 
147     @Override
hashCode()148     public int hashCode() {
149         return Objects.hash(template, cycleDay, cycleTimezone, warningBytes, limitBytes,
150                 lastWarningSnooze, lastLimitSnooze, metered, inferred);
151     }
152 
153     @Override
equals(Object obj)154     public boolean equals(Object obj) {
155         if (obj instanceof NetworkPolicy) {
156             final NetworkPolicy other = (NetworkPolicy) obj;
157             return cycleDay == other.cycleDay && warningBytes == other.warningBytes
158                     && limitBytes == other.limitBytes
159                     && lastWarningSnooze == other.lastWarningSnooze
160                     && lastLimitSnooze == other.lastLimitSnooze && metered == other.metered
161                     && inferred == other.inferred
162                     && Objects.equals(cycleTimezone, other.cycleTimezone)
163                     && Objects.equals(template, other.template);
164         }
165         return false;
166     }
167 
168     @Override
toString()169     public String toString() {
170         final StringBuilder builder = new StringBuilder("NetworkPolicy");
171         builder.append("[").append(template).append("]:");
172         builder.append(" cycleDay=").append(cycleDay);
173         builder.append(", cycleTimezone=").append(cycleTimezone);
174         builder.append(", warningBytes=").append(warningBytes);
175         builder.append(", limitBytes=").append(limitBytes);
176         builder.append(", lastWarningSnooze=").append(lastWarningSnooze);
177         builder.append(", lastLimitSnooze=").append(lastLimitSnooze);
178         builder.append(", metered=").append(metered);
179         builder.append(", inferred=").append(inferred);
180         return builder.toString();
181     }
182 
183     public static final Creator<NetworkPolicy> CREATOR = new Creator<NetworkPolicy>() {
184         @Override
185         public NetworkPolicy createFromParcel(Parcel in) {
186             return new NetworkPolicy(in);
187         }
188 
189         @Override
190         public NetworkPolicy[] newArray(int size) {
191             return new NetworkPolicy[size];
192         }
193     };
194 }
195