Home | History | Annotate | Download | only in net
      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
     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 
     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 
     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
     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
    107     public int describeContents() {
    108         return 0;
    109     }
    110 
    111     /**
    112      * Test if given measurement is over {@link #warningBytes}.
    113      */
    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      */
    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      */
    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      */
    140     public boolean hasCycle() {
    141         return cycleDay != CYCLE_NONE;
    142     }
    143 
    144     @Override
    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
    158     public int hashCode() {
    159         return Objects.hash(template, cycleDay, cycleTimezone, warningBytes, limitBytes,
    160                 lastWarningSnooze, lastLimitSnooze, metered, inferred);
    161     }
    162 
    163     @Override
    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
    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 
    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 
    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