• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 android.os.Parcel;
20 import android.os.Parcelable;
21 import android.util.BackupUtils;
22 import android.util.Range;
23 import android.util.RecurrenceRule;
24 
25 import com.android.internal.util.Preconditions;
26 
27 import java.io.ByteArrayOutputStream;
28 import java.io.DataInputStream;
29 import java.io.DataOutputStream;
30 import java.io.IOException;
31 import java.time.ZoneId;
32 import java.time.ZonedDateTime;
33 import java.util.Iterator;
34 import java.util.Objects;
35 
36 /**
37  * Policy for networks matching a {@link NetworkTemplate}, including usage cycle
38  * and limits to be enforced.
39  *
40  * @hide
41  */
42 public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
43     private static final int VERSION_INIT = 1;
44     private static final int VERSION_RULE = 2;
45     private static final int VERSION_RAPID = 3;
46 
47     public static final int CYCLE_NONE = -1;
48     public static final long WARNING_DISABLED = -1;
49     public static final long LIMIT_DISABLED = -1;
50     public static final long SNOOZE_NEVER = -1;
51 
52     public NetworkTemplate template;
53     public RecurrenceRule cycleRule;
54     public long warningBytes = WARNING_DISABLED;
55     public long limitBytes = LIMIT_DISABLED;
56     public long lastWarningSnooze = SNOOZE_NEVER;
57     public long lastLimitSnooze = SNOOZE_NEVER;
58     public long lastRapidSnooze = SNOOZE_NEVER;
59     @Deprecated public boolean metered = true;
60     public boolean inferred = false;
61 
62     private static final long DEFAULT_MTU = 1500;
63 
buildRule(int cycleDay, ZoneId cycleTimezone)64     public static RecurrenceRule buildRule(int cycleDay, ZoneId cycleTimezone) {
65         if (cycleDay != NetworkPolicy.CYCLE_NONE) {
66             return RecurrenceRule.buildRecurringMonthly(cycleDay, cycleTimezone);
67         } else {
68             return RecurrenceRule.buildNever();
69         }
70     }
71 
72     @Deprecated
NetworkPolicy(NetworkTemplate template, int cycleDay, String cycleTimezone, long warningBytes, long limitBytes, boolean metered)73     public NetworkPolicy(NetworkTemplate template, int cycleDay, String cycleTimezone,
74             long warningBytes, long limitBytes, boolean metered) {
75         this(template, cycleDay, cycleTimezone, warningBytes, limitBytes, SNOOZE_NEVER,
76                 SNOOZE_NEVER, metered, false);
77     }
78 
79     @Deprecated
NetworkPolicy(NetworkTemplate template, int cycleDay, String cycleTimezone, long warningBytes, long limitBytes, long lastWarningSnooze, long lastLimitSnooze, boolean metered, boolean inferred)80     public NetworkPolicy(NetworkTemplate template, int cycleDay, String cycleTimezone,
81             long warningBytes, long limitBytes, long lastWarningSnooze, long lastLimitSnooze,
82             boolean metered, boolean inferred) {
83         this(template, buildRule(cycleDay, ZoneId.of(cycleTimezone)), warningBytes,
84                 limitBytes, lastWarningSnooze, lastLimitSnooze, metered, inferred);
85     }
86 
87     @Deprecated
NetworkPolicy(NetworkTemplate template, RecurrenceRule cycleRule, long warningBytes, long limitBytes, long lastWarningSnooze, long lastLimitSnooze, boolean metered, boolean inferred)88     public NetworkPolicy(NetworkTemplate template, RecurrenceRule cycleRule, long warningBytes,
89             long limitBytes, long lastWarningSnooze, long lastLimitSnooze, boolean metered,
90             boolean inferred) {
91         this(template, cycleRule, warningBytes, limitBytes, lastWarningSnooze, lastLimitSnooze,
92                 SNOOZE_NEVER, metered, inferred);
93     }
94 
NetworkPolicy(NetworkTemplate template, RecurrenceRule cycleRule, long warningBytes, long limitBytes, long lastWarningSnooze, long lastLimitSnooze, long lastRapidSnooze, boolean metered, boolean inferred)95     public NetworkPolicy(NetworkTemplate template, RecurrenceRule cycleRule, long warningBytes,
96             long limitBytes, long lastWarningSnooze, long lastLimitSnooze, long lastRapidSnooze,
97             boolean metered, boolean inferred) {
98         this.template = Preconditions.checkNotNull(template, "missing NetworkTemplate");
99         this.cycleRule = Preconditions.checkNotNull(cycleRule, "missing RecurrenceRule");
100         this.warningBytes = warningBytes;
101         this.limitBytes = limitBytes;
102         this.lastWarningSnooze = lastWarningSnooze;
103         this.lastLimitSnooze = lastLimitSnooze;
104         this.lastRapidSnooze = lastRapidSnooze;
105         this.metered = metered;
106         this.inferred = inferred;
107     }
108 
NetworkPolicy(Parcel source)109     private NetworkPolicy(Parcel source) {
110         template = source.readParcelable(null);
111         cycleRule = source.readParcelable(null);
112         warningBytes = source.readLong();
113         limitBytes = source.readLong();
114         lastWarningSnooze = source.readLong();
115         lastLimitSnooze = source.readLong();
116         lastRapidSnooze = source.readLong();
117         metered = source.readInt() != 0;
118         inferred = source.readInt() != 0;
119     }
120 
121     @Override
writeToParcel(Parcel dest, int flags)122     public void writeToParcel(Parcel dest, int flags) {
123         dest.writeParcelable(template, flags);
124         dest.writeParcelable(cycleRule, flags);
125         dest.writeLong(warningBytes);
126         dest.writeLong(limitBytes);
127         dest.writeLong(lastWarningSnooze);
128         dest.writeLong(lastLimitSnooze);
129         dest.writeLong(lastRapidSnooze);
130         dest.writeInt(metered ? 1 : 0);
131         dest.writeInt(inferred ? 1 : 0);
132     }
133 
134     @Override
describeContents()135     public int describeContents() {
136         return 0;
137     }
138 
cycleIterator()139     public Iterator<Range<ZonedDateTime>> cycleIterator() {
140         return cycleRule.cycleIterator();
141     }
142 
143     /**
144      * Test if given measurement is over {@link #warningBytes}.
145      */
isOverWarning(long totalBytes)146     public boolean isOverWarning(long totalBytes) {
147         return warningBytes != WARNING_DISABLED && totalBytes >= warningBytes;
148     }
149 
150     /**
151      * Test if given measurement is near enough to {@link #limitBytes} to be
152      * considered over-limit.
153      */
isOverLimit(long totalBytes)154     public boolean isOverLimit(long totalBytes) {
155         // over-estimate, since kernel will trigger limit once first packet
156         // trips over limit.
157         totalBytes += 2 * DEFAULT_MTU;
158         return limitBytes != LIMIT_DISABLED && totalBytes >= limitBytes;
159     }
160 
161     /**
162      * Clear any existing snooze values, setting to {@link #SNOOZE_NEVER}.
163      */
clearSnooze()164     public void clearSnooze() {
165         lastWarningSnooze = SNOOZE_NEVER;
166         lastLimitSnooze = SNOOZE_NEVER;
167         lastRapidSnooze = SNOOZE_NEVER;
168     }
169 
170     /**
171      * Test if this policy has a cycle defined, after which usage should reset.
172      */
hasCycle()173     public boolean hasCycle() {
174         return cycleRule.cycleIterator().hasNext();
175     }
176 
177     @Override
compareTo(NetworkPolicy another)178     public int compareTo(NetworkPolicy another) {
179         if (another == null || another.limitBytes == LIMIT_DISABLED) {
180             // other value is missing or disabled; we win
181             return -1;
182         }
183         if (limitBytes == LIMIT_DISABLED || another.limitBytes < limitBytes) {
184             // we're disabled or other limit is smaller; they win
185             return 1;
186         }
187         return 0;
188     }
189 
190     @Override
hashCode()191     public int hashCode() {
192         return Objects.hash(template, cycleRule, warningBytes, limitBytes,
193                 lastWarningSnooze, lastLimitSnooze, lastRapidSnooze, metered, inferred);
194     }
195 
196     @Override
equals(Object obj)197     public boolean equals(Object obj) {
198         if (obj instanceof NetworkPolicy) {
199             final NetworkPolicy other = (NetworkPolicy) obj;
200             return warningBytes == other.warningBytes
201                     && limitBytes == other.limitBytes
202                     && lastWarningSnooze == other.lastWarningSnooze
203                     && lastLimitSnooze == other.lastLimitSnooze
204                     && lastRapidSnooze == other.lastRapidSnooze
205                     && metered == other.metered
206                     && inferred == other.inferred
207                     && Objects.equals(template, other.template)
208                     && Objects.equals(cycleRule, other.cycleRule);
209         }
210         return false;
211     }
212 
213     @Override
toString()214     public String toString() {
215         return new StringBuilder("NetworkPolicy{")
216                 .append("template=").append(template)
217                 .append(" cycleRule=").append(cycleRule)
218                 .append(" warningBytes=").append(warningBytes)
219                 .append(" limitBytes=").append(limitBytes)
220                 .append(" lastWarningSnooze=").append(lastWarningSnooze)
221                 .append(" lastLimitSnooze=").append(lastLimitSnooze)
222                 .append(" lastRapidSnooze=").append(lastRapidSnooze)
223                 .append(" metered=").append(metered)
224                 .append(" inferred=").append(inferred)
225                 .append("}").toString();
226     }
227 
228     public static final Creator<NetworkPolicy> CREATOR = new Creator<NetworkPolicy>() {
229         @Override
230         public NetworkPolicy createFromParcel(Parcel in) {
231             return new NetworkPolicy(in);
232         }
233 
234         @Override
235         public NetworkPolicy[] newArray(int size) {
236             return new NetworkPolicy[size];
237         }
238     };
239 
getBytesForBackup()240     public byte[] getBytesForBackup() throws IOException {
241         ByteArrayOutputStream baos = new ByteArrayOutputStream();
242         DataOutputStream out = new DataOutputStream(baos);
243 
244         out.writeInt(VERSION_RAPID);
245         out.write(template.getBytesForBackup());
246         cycleRule.writeToStream(out);
247         out.writeLong(warningBytes);
248         out.writeLong(limitBytes);
249         out.writeLong(lastWarningSnooze);
250         out.writeLong(lastLimitSnooze);
251         out.writeLong(lastRapidSnooze);
252         out.writeInt(metered ? 1 : 0);
253         out.writeInt(inferred ? 1 : 0);
254         return baos.toByteArray();
255     }
256 
getNetworkPolicyFromBackup(DataInputStream in)257     public static NetworkPolicy getNetworkPolicyFromBackup(DataInputStream in) throws IOException,
258             BackupUtils.BadVersionException {
259         final int version = in.readInt();
260         if (version < VERSION_INIT || version > VERSION_RAPID) {
261             throw new BackupUtils.BadVersionException("Unknown backup version: " + version);
262         }
263 
264         final NetworkTemplate template = NetworkTemplate.getNetworkTemplateFromBackup(in);
265         final RecurrenceRule cycleRule;
266         if (version >= VERSION_RULE) {
267             cycleRule = new RecurrenceRule(in);
268         } else {
269             final int cycleDay = in.readInt();
270             final String cycleTimezone = BackupUtils.readString(in);
271             cycleRule = buildRule(cycleDay, ZoneId.of(cycleTimezone));
272         }
273         final long warningBytes = in.readLong();
274         final long limitBytes = in.readLong();
275         final long lastWarningSnooze = in.readLong();
276         final long lastLimitSnooze = in.readLong();
277         final long lastRapidSnooze;
278         if (version >= VERSION_RAPID) {
279             lastRapidSnooze = in.readLong();
280         } else {
281             lastRapidSnooze = SNOOZE_NEVER;
282         }
283         final boolean metered = in.readInt() == 1;
284         final boolean inferred = in.readInt() == 1;
285         return new NetworkPolicy(template, cycleRule, warningBytes, limitBytes, lastWarningSnooze,
286                 lastLimitSnooze, lastRapidSnooze, metered, inferred);
287     }
288 }
289