2 * Copyright (C) 2011 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 import static com.android.internal.util.Preconditions.checkNotNull;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 import android.util.BackupUtils;
25 import java.io.ByteArrayOutputStream;
26 import java.io.DataInputStream;
27 import java.io.DataOutputStream;
28 import java.io.IOException;
29 import java.util.Objects;
32 * Policy for networks matching a {@link NetworkTemplate}, including usage cycle
33 * and limits to be enforced.
37 public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> {
39 * Current Version of the Backup Serializer.
41 private static final int BACKUP_VERSION = 1;
43 public static final int CYCLE_NONE = -1;
44 public static final long WARNING_DISABLED = -1;
45 public static final long LIMIT_DISABLED = -1;
46 public static final long SNOOZE_NEVER = -1;
48 public NetworkTemplate template;
50 public String cycleTimezone;
51 public long warningBytes;
52 public long limitBytes;
53 public long lastWarningSnooze;
54 public long lastLimitSnooze;
55 public boolean metered;
56 public boolean inferred;
58 private static final long DEFAULT_MTU = 1500;
61 public NetworkPolicy(NetworkTemplate template, int cycleDay, String cycleTimezone,
62 long warningBytes, long limitBytes, boolean metered) {
63 this(template, cycleDay, cycleTimezone, warningBytes, limitBytes, SNOOZE_NEVER,
64 SNOOZE_NEVER, metered, false);
67 public NetworkPolicy(NetworkTemplate template, int cycleDay, String cycleTimezone,
68 long warningBytes, long limitBytes, long lastWarningSnooze, long lastLimitSnooze,
69 boolean metered, boolean inferred) {
70 this.template = checkNotNull(template, "missing NetworkTemplate");
71 this.cycleDay = cycleDay;
72 this.cycleTimezone = checkNotNull(cycleTimezone, "missing cycleTimezone");
73 this.warningBytes = warningBytes;
74 this.limitBytes = limitBytes;
75 this.lastWarningSnooze = lastWarningSnooze;
76 this.lastLimitSnooze = lastLimitSnooze;
77 this.metered = metered;
78 this.inferred = inferred;
81 public NetworkPolicy(Parcel in) {
82 template = in.readParcelable(null);
83 cycleDay = in.readInt();
84 cycleTimezone = in.readString();
85 warningBytes = in.readLong();
86 limitBytes = in.readLong();
87 lastWarningSnooze = in.readLong();
88 lastLimitSnooze = in.readLong();
89 metered = in.readInt() != 0;
90 inferred = in.readInt() != 0;
94 public void writeToParcel(Parcel dest, int flags) {
95 dest.writeParcelable(template, flags);
96 dest.writeInt(cycleDay);
97 dest.writeString(cycleTimezone);
98 dest.writeLong(warningBytes);
99 dest.writeLong(limitBytes);
100 dest.writeLong(lastWarningSnooze);
101 dest.writeLong(lastLimitSnooze);
102 dest.writeInt(metered ? 1 : 0);
103 dest.writeInt(inferred ? 1 : 0);
107 public int describeContents() {
112 * Test if given measurement is over {@link #warningBytes}.
114 public boolean isOverWarning(long totalBytes) {
115 return warningBytes != WARNING_DISABLED && totalBytes >= warningBytes;
119 * Test if given measurement is near enough to {@link #limitBytes} to be
120 * considered over-limit.
122 public boolean isOverLimit(long totalBytes) {
123 // over-estimate, since kernel will trigger limit once first packet
125 totalBytes += 2 * DEFAULT_MTU;
126 return limitBytes != LIMIT_DISABLED && totalBytes >= limitBytes;
130 * Clear any existing snooze values, setting to {@link #SNOOZE_NEVER}.
132 public void clearSnooze() {
133 lastWarningSnooze = SNOOZE_NEVER;
134 lastLimitSnooze = SNOOZE_NEVER;
138 * Test if this policy has a cycle defined, after which usage should reset.
140 public boolean hasCycle() {
141 return cycleDay != CYCLE_NONE;
145 public int compareTo(NetworkPolicy another) {
146 if (another == null || another.limitBytes == LIMIT_DISABLED) {
147 // other value is missing or disabled; we win
150 if (limitBytes == LIMIT_DISABLED || another.limitBytes < limitBytes) {
151 // we're disabled or other limit is smaller; they win
158 public int hashCode() {
159 return Objects.hash(template, cycleDay, cycleTimezone, warningBytes, limitBytes,
160 lastWarningSnooze, lastLimitSnooze, metered, inferred);
164 public boolean equals(Object obj) {
165 if (obj instanceof NetworkPolicy) {
166 final NetworkPolicy other = (NetworkPolicy) obj;
167 return cycleDay == other.cycleDay && warningBytes == other.warningBytes
168 && limitBytes == other.limitBytes
169 && lastWarningSnooze == other.lastWarningSnooze
170 && lastLimitSnooze == other.lastLimitSnooze && metered == other.metered
171 && inferred == other.inferred
172 && Objects.equals(cycleTimezone, other.cycleTimezone)
173 && Objects.equals(template, other.template);
179 public String toString() {
180 final StringBuilder builder = new StringBuilder("NetworkPolicy");
181 builder.append("[").append(template).append("]:");
182 builder.append(" cycleDay=").append(cycleDay);
183 builder.append(", cycleTimezone=").append(cycleTimezone);
184 builder.append(", warningBytes=").append(warningBytes);
185 builder.append(", limitBytes=").append(limitBytes);
186 builder.append(", lastWarningSnooze=").append(lastWarningSnooze);
187 builder.append(", lastLimitSnooze=").append(lastLimitSnooze);
188 builder.append(", metered=").append(metered);
189 builder.append(", inferred=").append(inferred);
190 return builder.toString();
193 public static final Creator<NetworkPolicy> CREATOR = new Creator<NetworkPolicy>() {
195 public NetworkPolicy createFromParcel(Parcel in) {
196 return new NetworkPolicy(in);
200 public NetworkPolicy[] newArray(int size) {
201 return new NetworkPolicy[size];
205 public byte[] getBytesForBackup() throws IOException {
206 ByteArrayOutputStream baos = new ByteArrayOutputStream();
207 DataOutputStream out = new DataOutputStream(baos);
209 out.writeInt(BACKUP_VERSION);
210 out.write(template.getBytesForBackup());
211 out.writeInt(cycleDay);
212 BackupUtils.writeString(out, cycleTimezone);
213 out.writeLong(warningBytes);
214 out.writeLong(limitBytes);
215 out.writeLong(lastWarningSnooze);
216 out.writeLong(lastLimitSnooze);
217 out.writeInt(metered ? 1 : 0);
218 out.writeInt(inferred ? 1 : 0);
219 return baos.toByteArray();
222 public static NetworkPolicy getNetworkPolicyFromBackup(DataInputStream in) throws IOException,
223 BackupUtils.BadVersionException {
224 int version = in.readInt();
225 if (version < 1 || version > BACKUP_VERSION) {
226 throw new BackupUtils.BadVersionException("Unknown Backup Serialization Version");
229 NetworkTemplate template = NetworkTemplate.getNetworkTemplateFromBackup(in);
230 int cycleDay = in.readInt();
231 String cycleTimeZone = BackupUtils.readString(in);
232 long warningBytes = in.readLong();
233 long limitBytes = in.readLong();
234 long lastWarningSnooze = in.readLong();
235 long lastLimitSnooze = in.readLong();
236 boolean metered = in.readInt() == 1;
237 boolean inferred = in.readInt() == 1;
238 return new NetworkPolicy(template, cycleDay, cycleTimeZone, warningBytes, limitBytes,
239 lastWarningSnooze, lastLimitSnooze, metered, inferred);