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