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 android.net.ConnectivityManager.TYPE_ETHERNET;
     20 import static android.net.ConnectivityManager.TYPE_WIFI;
     21 import static android.net.ConnectivityManager.TYPE_WIMAX;
     22 import static android.net.NetworkIdentity.scrubSubscriberId;
     23 import static android.telephony.TelephonyManager.NETWORK_CLASS_2_G;
     24 import static android.telephony.TelephonyManager.NETWORK_CLASS_3_G;
     25 import static android.telephony.TelephonyManager.NETWORK_CLASS_4_G;
     26 import static android.telephony.TelephonyManager.NETWORK_CLASS_UNKNOWN;
     27 import static android.telephony.TelephonyManager.getNetworkClass;
     28 import static com.android.internal.util.ArrayUtils.contains;
     29 
     30 import android.content.res.Resources;
     31 import android.os.Parcel;
     32 import android.os.Parcelable;
     33 
     34 import com.android.internal.util.Objects;
     35 
     36 /**
     37  * Template definition used to generically match {@link NetworkIdentity},
     38  * usually when collecting statistics.
     39  *
     40  * @hide
     41  */
     42 public class NetworkTemplate implements Parcelable {
     43 
     44     /** {@hide} */
     45     public static final int MATCH_MOBILE_ALL = 1;
     46     /** {@hide} */
     47     public static final int MATCH_MOBILE_3G_LOWER = 2;
     48     /** {@hide} */
     49     public static final int MATCH_MOBILE_4G = 3;
     50     /** {@hide} */
     51     public static final int MATCH_WIFI = 4;
     52     /** {@hide} */
     53     public static final int MATCH_ETHERNET = 5;
     54 
     55     /**
     56      * Set of {@link NetworkInfo#getType()} that reflect data usage.
     57      */
     58     private static final int[] DATA_USAGE_NETWORK_TYPES;
     59 
     60     static {
     61         DATA_USAGE_NETWORK_TYPES = Resources.getSystem().getIntArray(
     62                 com.android.internal.R.array.config_data_usage_network_types);
     63     }
     64 
     65     /**
     66      * Template to combine all {@link ConnectivityManager#TYPE_MOBILE} style
     67      * networks together. Only uses statistics for requested IMSI.
     68      */
     69     public static NetworkTemplate buildTemplateMobileAll(String subscriberId) {
     70         return new NetworkTemplate(MATCH_MOBILE_ALL, subscriberId);
     71     }
     72 
     73     /**
     74      * Template to combine all {@link ConnectivityManager#TYPE_MOBILE} style
     75      * networks together that roughly meet a "3G" definition, or lower. Only
     76      * uses statistics for requested IMSI.
     77      */
     78     public static NetworkTemplate buildTemplateMobile3gLower(String subscriberId) {
     79         return new NetworkTemplate(MATCH_MOBILE_3G_LOWER, subscriberId);
     80     }
     81 
     82     /**
     83      * Template to combine all {@link ConnectivityManager#TYPE_MOBILE} style
     84      * networks together that meet a "4G" definition. Only uses statistics for
     85      * requested IMSI.
     86      */
     87     public static NetworkTemplate buildTemplateMobile4g(String subscriberId) {
     88         return new NetworkTemplate(MATCH_MOBILE_4G, subscriberId);
     89     }
     90 
     91     /**
     92      * Template to combine all {@link ConnectivityManager#TYPE_WIFI} style
     93      * networks together.
     94      */
     95     public static NetworkTemplate buildTemplateWifi() {
     96         return new NetworkTemplate(MATCH_WIFI, null);
     97     }
     98 
     99     /**
    100      * Template to combine all {@link ConnectivityManager#TYPE_ETHERNET} style
    101      * networks together.
    102      */
    103     public static NetworkTemplate buildTemplateEthernet() {
    104         return new NetworkTemplate(MATCH_ETHERNET, null);
    105     }
    106 
    107     private final int mMatchRule;
    108     private final String mSubscriberId;
    109 
    110     /** {@hide} */
    111     public NetworkTemplate(int matchRule, String subscriberId) {
    112         this.mMatchRule = matchRule;
    113         this.mSubscriberId = subscriberId;
    114     }
    115 
    116     private NetworkTemplate(Parcel in) {
    117         mMatchRule = in.readInt();
    118         mSubscriberId = in.readString();
    119     }
    120 
    121     /** {@inheritDoc} */
    122     public void writeToParcel(Parcel dest, int flags) {
    123         dest.writeInt(mMatchRule);
    124         dest.writeString(mSubscriberId);
    125     }
    126 
    127     /** {@inheritDoc} */
    128     public int describeContents() {
    129         return 0;
    130     }
    131 
    132     @Override
    133     public String toString() {
    134         final String scrubSubscriberId = scrubSubscriberId(mSubscriberId);
    135         return "NetworkTemplate: matchRule=" + getMatchRuleName(mMatchRule) + ", subscriberId="
    136                 + scrubSubscriberId;
    137     }
    138 
    139     @Override
    140     public int hashCode() {
    141         return Objects.hashCode(mMatchRule, mSubscriberId);
    142     }
    143 
    144     @Override
    145     public boolean equals(Object obj) {
    146         if (obj instanceof NetworkTemplate) {
    147             final NetworkTemplate other = (NetworkTemplate) obj;
    148             return mMatchRule == other.mMatchRule
    149                     && Objects.equal(mSubscriberId, other.mSubscriberId);
    150         }
    151         return false;
    152     }
    153 
    154     /** {@hide} */
    155     public int getMatchRule() {
    156         return mMatchRule;
    157     }
    158 
    159     /** {@hide} */
    160     public String getSubscriberId() {
    161         return mSubscriberId;
    162     }
    163 
    164     /**
    165      * Test if given {@link NetworkIdentity} matches this template.
    166      */
    167     public boolean matches(NetworkIdentity ident) {
    168         switch (mMatchRule) {
    169             case MATCH_MOBILE_ALL:
    170                 return matchesMobile(ident);
    171             case MATCH_MOBILE_3G_LOWER:
    172                 return matchesMobile3gLower(ident);
    173             case MATCH_MOBILE_4G:
    174                 return matchesMobile4g(ident);
    175             case MATCH_WIFI:
    176                 return matchesWifi(ident);
    177             case MATCH_ETHERNET:
    178                 return matchesEthernet(ident);
    179             default:
    180                 throw new IllegalArgumentException("unknown network template");
    181         }
    182     }
    183 
    184     /**
    185      * Check if mobile network with matching IMSI.
    186      */
    187     private boolean matchesMobile(NetworkIdentity ident) {
    188         if (ident.mType == TYPE_WIMAX) {
    189             // TODO: consider matching against WiMAX subscriber identity
    190             return true;
    191         } else {
    192             return (contains(DATA_USAGE_NETWORK_TYPES, ident.mType)
    193                     && Objects.equal(mSubscriberId, ident.mSubscriberId));
    194         }
    195     }
    196 
    197     /**
    198      * Check if mobile network classified 3G or lower with matching IMSI.
    199      */
    200     private boolean matchesMobile3gLower(NetworkIdentity ident) {
    201         if (ident.mType == TYPE_WIMAX) {
    202             return false;
    203         } else if (matchesMobile(ident)) {
    204             switch (getNetworkClass(ident.mSubType)) {
    205                 case NETWORK_CLASS_UNKNOWN:
    206                 case NETWORK_CLASS_2_G:
    207                 case NETWORK_CLASS_3_G:
    208                     return true;
    209             }
    210         }
    211         return false;
    212     }
    213 
    214     /**
    215      * Check if mobile network classified 4G with matching IMSI.
    216      */
    217     private boolean matchesMobile4g(NetworkIdentity ident) {
    218         if (ident.mType == TYPE_WIMAX) {
    219             // TODO: consider matching against WiMAX subscriber identity
    220             return true;
    221         } else if (matchesMobile(ident)) {
    222             switch (getNetworkClass(ident.mSubType)) {
    223                 case NETWORK_CLASS_4_G:
    224                     return true;
    225             }
    226         }
    227         return false;
    228     }
    229 
    230     /**
    231      * Check if matches Wi-Fi network template.
    232      */
    233     private boolean matchesWifi(NetworkIdentity ident) {
    234         if (ident.mType == TYPE_WIFI) {
    235             return true;
    236         }
    237         return false;
    238     }
    239 
    240     /**
    241      * Check if matches Ethernet network template.
    242      */
    243     private boolean matchesEthernet(NetworkIdentity ident) {
    244         if (ident.mType == TYPE_ETHERNET) {
    245             return true;
    246         }
    247         return false;
    248     }
    249 
    250     private static String getMatchRuleName(int matchRule) {
    251         switch (matchRule) {
    252             case MATCH_MOBILE_3G_LOWER:
    253                 return "MOBILE_3G_LOWER";
    254             case MATCH_MOBILE_4G:
    255                 return "MOBILE_4G";
    256             case MATCH_MOBILE_ALL:
    257                 return "MOBILE_ALL";
    258             case MATCH_WIFI:
    259                 return "WIFI";
    260             case MATCH_ETHERNET:
    261                 return "ETHERNET";
    262             default:
    263                 return "UNKNOWN";
    264         }
    265     }
    266 
    267     public static final Creator<NetworkTemplate> CREATOR = new Creator<NetworkTemplate>() {
    268         public NetworkTemplate createFromParcel(Parcel in) {
    269             return new NetworkTemplate(in);
    270         }
    271 
    272         public NetworkTemplate[] newArray(int size) {
    273             return new NetworkTemplate[size];
    274         }
    275     };
    276 }
    277