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 import android.util.BackupUtils; 24 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; 30 31 /** 32 * Policy for networks matching a {@link NetworkTemplate}, including usage cycle 33 * and limits to be enforced. 34 * 35 * @hide 36 */ 37 public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> { 38 /** 39 * Current Version of the Backup Serializer. 40 */ 41 private static final int BACKUP_VERSION = 1; 42 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; 47 48 public NetworkTemplate template; 49 public int cycleDay; 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; 57 58 private static final long DEFAULT_MTU = 1500; 59 60 @Deprecated NetworkPolicy(NetworkTemplate template, int cycleDay, String cycleTimezone, long warningBytes, long limitBytes, boolean metered)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); 65 } 66 NetworkPolicy(NetworkTemplate template, int cycleDay, String cycleTimezone, long warningBytes, long limitBytes, long lastWarningSnooze, long lastLimitSnooze, boolean metered, boolean inferred)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; 79 } 80 NetworkPolicy(Parcel in)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; 91 } 92 93 @Override writeToParcel(Parcel dest, int flags)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); 104 } 105 106 @Override describeContents()107 public int describeContents() { 108 return 0; 109 } 110 111 /** 112 * Test if given measurement is over {@link #warningBytes}. 113 */ isOverWarning(long totalBytes)114 public boolean isOverWarning(long totalBytes) { 115 return warningBytes != WARNING_DISABLED && totalBytes >= warningBytes; 116 } 117 118 /** 119 * Test if given measurement is near enough to {@link #limitBytes} to be 120 * considered over-limit. 121 */ isOverLimit(long totalBytes)122 public boolean isOverLimit(long totalBytes) { 123 // over-estimate, since kernel will trigger limit once first packet 124 // trips over limit. 125 totalBytes += 2 * DEFAULT_MTU; 126 return limitBytes != LIMIT_DISABLED && totalBytes >= limitBytes; 127 } 128 129 /** 130 * Clear any existing snooze values, setting to {@link #SNOOZE_NEVER}. 131 */ clearSnooze()132 public void clearSnooze() { 133 lastWarningSnooze = SNOOZE_NEVER; 134 lastLimitSnooze = SNOOZE_NEVER; 135 } 136 137 /** 138 * Test if this policy has a cycle defined, after which usage should reset. 139 */ hasCycle()140 public boolean hasCycle() { 141 return cycleDay != CYCLE_NONE; 142 } 143 144 @Override compareTo(NetworkPolicy another)145 public int compareTo(NetworkPolicy another) { 146 if (another == null || another.limitBytes == LIMIT_DISABLED) { 147 // other value is missing or disabled; we win 148 return -1; 149 } 150 if (limitBytes == LIMIT_DISABLED || another.limitBytes < limitBytes) { 151 // we're disabled or other limit is smaller; they win 152 return 1; 153 } 154 return 0; 155 } 156 157 @Override hashCode()158 public int hashCode() { 159 return Objects.hash(template, cycleDay, cycleTimezone, warningBytes, limitBytes, 160 lastWarningSnooze, lastLimitSnooze, metered, inferred); 161 } 162 163 @Override equals(Object obj)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); 174 } 175 return false; 176 } 177 178 @Override toString()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(); 191 } 192 193 public static final Creator<NetworkPolicy> CREATOR = new Creator<NetworkPolicy>() { 194 @Override 195 public NetworkPolicy createFromParcel(Parcel in) { 196 return new NetworkPolicy(in); 197 } 198 199 @Override 200 public NetworkPolicy[] newArray(int size) { 201 return new NetworkPolicy[size]; 202 } 203 }; 204 getBytesForBackup()205 public byte[] getBytesForBackup() throws IOException { 206 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 207 DataOutputStream out = new DataOutputStream(baos); 208 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(); 220 } 221 getNetworkPolicyFromBackup(DataInputStream in)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"); 227 } 228 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); 240 } 241 } 242