1 /* 2 * Copyright (C) 2006 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 com.android.internal.telephony.dataconnection; 18 19 import android.content.Context; 20 import android.hardware.radio.V1_0.ApnTypes; 21 import android.os.PersistableBundle; 22 import android.provider.Telephony.Carriers; 23 import android.telephony.CarrierConfigManager; 24 import android.telephony.Rlog; 25 import android.telephony.ServiceState; 26 import android.text.TextUtils; 27 import android.util.Log; 28 29 import com.android.internal.annotations.VisibleForTesting; 30 import com.android.internal.telephony.Phone; 31 import com.android.internal.telephony.PhoneConstants; 32 import com.android.internal.telephony.RILConstants; 33 import com.android.internal.telephony.uicc.IccRecords; 34 35 import java.util.ArrayList; 36 import java.util.Arrays; 37 import java.util.HashSet; 38 import java.util.List; 39 import java.util.Objects; 40 41 /** 42 * This class represents a apn setting for create PDP link 43 */ 44 public class ApnSetting { 45 46 static final String LOG_TAG = "ApnSetting"; 47 48 private static final boolean DBG = false; 49 private static final boolean VDBG = false; 50 51 static final String V2_FORMAT_REGEX = "^\\[ApnSettingV2\\]\\s*"; 52 static final String V3_FORMAT_REGEX = "^\\[ApnSettingV3\\]\\s*"; 53 static final String V4_FORMAT_REGEX = "^\\[ApnSettingV4\\]\\s*"; 54 static final String V5_FORMAT_REGEX = "^\\[ApnSettingV5\\]\\s*"; 55 static final String TAG = "ApnSetting"; 56 57 public final String carrier; 58 public final String apn; 59 public final String proxy; 60 public final String port; 61 public final String mmsc; 62 public final String mmsProxy; 63 public final String mmsPort; 64 public final String user; 65 public final String password; 66 public final int authType; 67 public final String[] types; 68 public final int typesBitmap; 69 public final int id; 70 public final String numeric; 71 public final String protocol; 72 public final String roamingProtocol; 73 public final int mtu; 74 75 /** 76 * Current status of APN 77 * true : enabled APN, false : disabled APN. 78 */ 79 public final boolean carrierEnabled; 80 /** 81 * Radio Access Technology info 82 * To check what values can hold, refer to ServiceState.java. 83 * This should be spread to other technologies, 84 * but currently only used for LTE(14) and EHRPD(13). 85 * 86 * @deprecated use {@code networkTypeBitmask} instead 87 */ 88 @Deprecated 89 private final int bearer; 90 /** 91 * Radio Access Technology info 92 * To check what values can hold, refer to ServiceState.java. This is a bitmask of radio 93 * technologies in ServiceState. 94 * This should be spread to other technologies, 95 * but currently only used for LTE(14) and EHRPD(13). 96 * 97 * @deprecated use {@code networkTypeBitmask} instead 98 */ 99 @Deprecated 100 public final int bearerBitmask; 101 102 /** 103 * Radio Technology (Network Type) info 104 * To check what values can hold, refer to TelephonyManager.java. This is a bitmask of radio 105 * technologies ({@code NETWORK_TYPE_} constants) in {@link TelephonyManager}. 106 */ 107 public final int networkTypeBitmask; 108 109 /* ID of the profile in the modem */ 110 public final int profileId; 111 public final boolean modemCognitive; 112 public final int maxConns; 113 public final int waitTime; 114 public final int maxConnsTime; 115 116 /** 117 * MVNO match type. Possible values: 118 * "spn": Service provider name. 119 * "imsi": IMSI. 120 * "gid": Group identifier level 1. 121 * "iccid": ICCID 122 */ 123 public final String mvnoType; 124 /** 125 * MVNO data. Examples: 126 * "spn": A MOBILE, BEN NL 127 * "imsi": 302720x94, 2060188 128 * "gid": 4E, 33 129 * "iccid": 898603 etc. 130 */ 131 public final String mvnoMatchData; 132 133 /** 134 * The APN set id. 135 * 136 * APNs that are part of the same set should be preferred together, e.g. if the 137 * user selects a default APN with apnSetId=1, then we will prefer all APNs with apnSetId=1. 138 * 139 * If the apnSetId=Carriers.NO_SET_SET (=0) then the APN is not part of a set. 140 */ 141 public final int apnSetId; 142 143 /** 144 * Indicates this APN setting is permanently failed and cannot be 145 * retried by the retry manager anymore. 146 * */ 147 public boolean permanentFailed = false; 148 149 /** 150 * @deprecated this constructor is no longer supported. Use the other constructor which takes 151 * a network type bitmask instead of the deprecated bearer bitmask and bearer field. 152 * */ 153 @Deprecated 154 public ApnSetting(int id, String numeric, String carrier, String apn, 155 String proxy, String port, 156 String mmsc, String mmsProxy, String mmsPort, 157 String user, String password, int authType, String[] types, 158 String protocol, String roamingProtocol, boolean carrierEnabled, int bearer, 159 int bearerBitmask, int profileId, boolean modemCognitive, int maxConns, 160 int waitTime, int maxConnsTime, int mtu, String mvnoType, 161 String mvnoMatchData) { 162 this.id = id; 163 this.numeric = numeric; 164 this.carrier = carrier; 165 this.apn = apn; 166 this.proxy = proxy; 167 this.port = port; 168 this.mmsc = mmsc; 169 this.mmsProxy = mmsProxy; 170 this.mmsPort = mmsPort; 171 this.user = user; 172 this.password = password; 173 this.authType = authType; 174 this.types = new String[types.length]; 175 int apnBitmap = 0; 176 for (int i = 0; i < types.length; i++) { 177 this.types[i] = types[i].toLowerCase(); 178 apnBitmap |= getApnBitmask(this.types[i]); 179 } 180 this.typesBitmap = apnBitmap; 181 this.protocol = protocol; 182 this.roamingProtocol = roamingProtocol; 183 this.carrierEnabled = carrierEnabled; 184 this.bearer = bearer; 185 this.bearerBitmask = (bearerBitmask | ServiceState.getBitmaskForTech(bearer)); 186 this.profileId = profileId; 187 this.modemCognitive = modemCognitive; 188 this.maxConns = maxConns; 189 this.waitTime = waitTime; 190 this.maxConnsTime = maxConnsTime; 191 this.mtu = mtu; 192 this.mvnoType = mvnoType; 193 this.mvnoMatchData = mvnoMatchData; 194 this.apnSetId = Carriers.NO_SET_SET; 195 this.networkTypeBitmask = ServiceState.convertBearerBitmaskToNetworkTypeBitmask( 196 this.bearerBitmask); 197 } 198 199 // Constructor with default apn set id 200 public ApnSetting(int id, String numeric, String carrier, String apn, 201 String proxy, String port, 202 String mmsc, String mmsProxy, String mmsPort, 203 String user, String password, int authType, String[] types, 204 String protocol, String roamingProtocol, boolean carrierEnabled, 205 int networkTypeBitmask, int profileId, boolean modemCognitive, int maxConns, 206 int waitTime, int maxConnsTime, int mtu, String mvnoType, 207 String mvnoMatchData) { 208 this(id, numeric, carrier, apn, proxy, port, mmsc, mmsProxy, mmsPort, user, password, 209 authType, types, protocol, roamingProtocol, carrierEnabled, networkTypeBitmask, 210 profileId, modemCognitive, maxConns, waitTime, maxConnsTime, mtu, mvnoType, 211 mvnoMatchData, Carriers.NO_SET_SET); 212 } 213 214 public ApnSetting(int id, String numeric, String carrier, String apn, 215 String proxy, String port, 216 String mmsc, String mmsProxy, String mmsPort, 217 String user, String password, int authType, String[] types, 218 String protocol, String roamingProtocol, boolean carrierEnabled, 219 int networkTypeBitmask, int profileId, boolean modemCognitive, int maxConns, 220 int waitTime, int maxConnsTime, int mtu, String mvnoType, 221 String mvnoMatchData, int apnSetId) { 222 this.id = id; 223 this.numeric = numeric; 224 this.carrier = carrier; 225 this.apn = apn; 226 this.proxy = proxy; 227 this.port = port; 228 this.mmsc = mmsc; 229 this.mmsProxy = mmsProxy; 230 this.mmsPort = mmsPort; 231 this.user = user; 232 this.password = password; 233 this.authType = authType; 234 this.types = new String[types.length]; 235 int apnBitmap = 0; 236 for (int i = 0; i < types.length; i++) { 237 this.types[i] = types[i].toLowerCase(); 238 apnBitmap |= getApnBitmask(this.types[i]); 239 } 240 this.typesBitmap = apnBitmap; 241 this.protocol = protocol; 242 this.roamingProtocol = roamingProtocol; 243 this.carrierEnabled = carrierEnabled; 244 this.bearer = 0; 245 this.bearerBitmask = 246 ServiceState.convertNetworkTypeBitmaskToBearerBitmask(networkTypeBitmask); 247 this.networkTypeBitmask = networkTypeBitmask; 248 this.profileId = profileId; 249 this.modemCognitive = modemCognitive; 250 this.maxConns = maxConns; 251 this.waitTime = waitTime; 252 this.maxConnsTime = maxConnsTime; 253 this.mtu = mtu; 254 this.mvnoType = mvnoType; 255 this.mvnoMatchData = mvnoMatchData; 256 this.apnSetId = apnSetId; 257 } 258 259 public ApnSetting(ApnSetting apn) { 260 this(apn.id, apn.numeric, apn.carrier, apn.apn, apn.proxy, apn.port, apn.mmsc, apn.mmsProxy, 261 apn.mmsPort, apn.user, apn.password, apn.authType, apn.types, apn.protocol, 262 apn.roamingProtocol, apn.carrierEnabled, apn.networkTypeBitmask, apn.profileId, 263 apn.modemCognitive, apn.maxConns, apn.waitTime, apn.maxConnsTime, 264 apn.mtu, apn.mvnoType, apn.mvnoMatchData, apn.apnSetId); 265 } 266 267 /** 268 * Creates an ApnSetting object from a string. 269 * 270 * @param data the string to read. 271 * 272 * The string must be in one of two formats (newlines added for clarity, 273 * spaces are optional): 274 * 275 * v1 format: 276 * <carrier>, <apn>, <proxy>, <port>, <user>, <password>, <server>, 277 * <mmsc>, <mmsproxy>, <mmsport>, <mcc>, <mnc>, <authtype>, 278 * <type>[| <type>...], 279 * 280 * v2 format: 281 * [ApnSettingV2] <carrier>, <apn>, <proxy>, <port>, <user>, <password>, <server>, 282 * <mmsc>, <mmsproxy>, <mmsport>, <mcc>, <mnc>, <authtype>, 283 * <type>[| <type>...], <protocol>, <roaming_protocol>, <carrierEnabled>, <bearerBitmask>, 284 * 285 * v3 format: 286 * [ApnSettingV3] <carrier>, <apn>, <proxy>, <port>, <user>, <password>, <server>, 287 * <mmsc>, <mmsproxy>, <mmsport>, <mcc>, <mnc>, <authtype>, 288 * <type>[| <type>...], <protocol>, <roaming_protocol>, <carrierEnabled>, <bearerBitmask>, 289 * <profileId>, <modemCognitive>, <maxConns>, <waitTime>, <maxConnsTime>, <mtu>, 290 * <mvnoType>, <mvnoMatchData> 291 * 292 * v4 format: 293 * [ApnSettingV4] <carrier>, <apn>, <proxy>, <port>, <user>, <password>, <server>, 294 * <mmsc>, <mmsproxy>, <mmsport>, <mcc>, <mnc>, <authtype>, 295 * <type>[| <type>...], <protocol>, <roaming_protocol>, <carrierEnabled>, <bearerBitmask>, 296 * <profileId>, <modemCognitive>, <maxConns>, <waitTime>, <maxConnsTime>, <mtu>, 297 * <mvnoType>, <mvnoMatchData>, <networkTypeBitmask> 298 * 299 * v5 format: 300 * [ApnSettingV5] <carrier>, <apn>, <proxy>, <port>, <user>, <password>, <server>, 301 * <mmsc>, <mmsproxy>, <mmsport>, <mcc>, <mnc>, <authtype>, 302 * <type>[| <type>...], <protocol>, <roaming_protocol>, <carrierEnabled>, <bearerBitmask>, 303 * <profileId>, <modemCognitive>, <maxConns>, <waitTime>, <maxConnsTime>, <mtu>, 304 * <mvnoType>, <mvnoMatchData>, <networkTypeBitmask>, <apnSetId> 305 * 306 * Note that the strings generated by toString() do not contain the username 307 * and password and thus cannot be read by this method. 308 */ 309 public static ApnSetting fromString(String data) { 310 if (data == null) return null; 311 312 int version; 313 // matches() operates on the whole string, so append .* to the regex. 314 if (data.matches(V5_FORMAT_REGEX + ".*")) { 315 version = 5; 316 data = data.replaceFirst(V5_FORMAT_REGEX, ""); 317 } else if (data.matches(V4_FORMAT_REGEX + ".*")) { 318 version = 4; 319 data = data.replaceFirst(V4_FORMAT_REGEX, ""); 320 } else if (data.matches(V3_FORMAT_REGEX + ".*")) { 321 version = 3; 322 data = data.replaceFirst(V3_FORMAT_REGEX, ""); 323 } else if (data.matches(V2_FORMAT_REGEX + ".*")) { 324 version = 2; 325 data = data.replaceFirst(V2_FORMAT_REGEX, ""); 326 } else { 327 version = 1; 328 } 329 330 String[] a = data.split("\\s*,\\s*"); 331 if (a.length < 14) { 332 return null; 333 } 334 335 int authType; 336 try { 337 authType = Integer.parseInt(a[12]); 338 } catch (NumberFormatException e) { 339 authType = 0; 340 } 341 342 String[] typeArray; 343 String protocol, roamingProtocol; 344 boolean carrierEnabled; 345 int bearerBitmask = 0; 346 int networkTypeBitmask = 0; 347 int profileId = 0; 348 boolean modemCognitive = false; 349 int maxConns = 0; 350 int waitTime = 0; 351 int maxConnsTime = 0; 352 int mtu = PhoneConstants.UNSET_MTU; 353 String mvnoType = ""; 354 String mvnoMatchData = ""; 355 int apnSetId = Carriers.NO_SET_SET; 356 if (version == 1) { 357 typeArray = new String[a.length - 13]; 358 System.arraycopy(a, 13, typeArray, 0, a.length - 13); 359 protocol = RILConstants.SETUP_DATA_PROTOCOL_IP; 360 roamingProtocol = RILConstants.SETUP_DATA_PROTOCOL_IP; 361 carrierEnabled = true; 362 } else { 363 if (a.length < 18) { 364 return null; 365 } 366 typeArray = a[13].split("\\s*\\|\\s*"); 367 protocol = a[14]; 368 roamingProtocol = a[15]; 369 carrierEnabled = Boolean.parseBoolean(a[16]); 370 371 bearerBitmask = ServiceState.getBitmaskFromString(a[17]); 372 373 if (a.length > 22) { 374 modemCognitive = Boolean.parseBoolean(a[19]); 375 try { 376 profileId = Integer.parseInt(a[18]); 377 maxConns = Integer.parseInt(a[20]); 378 waitTime = Integer.parseInt(a[21]); 379 maxConnsTime = Integer.parseInt(a[22]); 380 } catch (NumberFormatException e) { 381 } 382 } 383 if (a.length > 23) { 384 try { 385 mtu = Integer.parseInt(a[23]); 386 } catch (NumberFormatException e) { 387 } 388 } 389 if (a.length > 25) { 390 mvnoType = a[24]; 391 mvnoMatchData = a[25]; 392 } 393 if (a.length > 26) { 394 networkTypeBitmask = ServiceState.getBitmaskFromString(a[26]); 395 } 396 if (a.length > 27) { 397 apnSetId = Integer.parseInt(a[27]); 398 } 399 } 400 401 // If both bearerBitmask and networkTypeBitmask were specified, bearerBitmask would be 402 // ignored. 403 if (networkTypeBitmask == 0) { 404 networkTypeBitmask = 405 ServiceState.convertBearerBitmaskToNetworkTypeBitmask(bearerBitmask); 406 } 407 return new ApnSetting(-1, a[10] + a[11], a[0], a[1], a[2], a[3], a[7], a[8], a[9], a[4], 408 a[5], authType, typeArray, protocol, roamingProtocol, carrierEnabled, 409 networkTypeBitmask, profileId, modemCognitive, maxConns, waitTime, maxConnsTime, 410 mtu, mvnoType, mvnoMatchData, apnSetId); 411 } 412 413 /** 414 * Creates an array of ApnSetting objects from a string. 415 * 416 * @param data the string to read. 417 * 418 * Builds on top of the same format used by fromString, but allows for multiple entries 419 * separated by "; ". 420 */ 421 public static List<ApnSetting> arrayFromString(String data) { 422 List<ApnSetting> retVal = new ArrayList<ApnSetting>(); 423 if (TextUtils.isEmpty(data)) { 424 return retVal; 425 } 426 String[] apnStrings = data.split("\\s*;\\s*"); 427 for (String apnString : apnStrings) { 428 ApnSetting apn = fromString(apnString); 429 if (apn != null) { 430 retVal.add(apn); 431 } 432 } 433 return retVal; 434 } 435 436 @Override 437 public String toString() { 438 StringBuilder sb = new StringBuilder(); 439 sb.append("[ApnSettingV5] ") 440 .append(carrier) 441 .append(", ").append(id) 442 .append(", ").append(numeric) 443 .append(", ").append(apn) 444 .append(", ").append(proxy) 445 .append(", ").append(mmsc) 446 .append(", ").append(mmsProxy) 447 .append(", ").append(mmsPort) 448 .append(", ").append(port) 449 .append(", ").append(authType).append(", "); 450 for (int i = 0; i < types.length; i++) { 451 sb.append(types[i]); 452 if (i < types.length - 1) { 453 sb.append(" | "); 454 } 455 } 456 sb.append(", ").append(protocol); 457 sb.append(", ").append(roamingProtocol); 458 sb.append(", ").append(carrierEnabled); 459 sb.append(", ").append(bearer); 460 sb.append(", ").append(bearerBitmask); 461 sb.append(", ").append(profileId); 462 sb.append(", ").append(modemCognitive); 463 sb.append(", ").append(maxConns); 464 sb.append(", ").append(waitTime); 465 sb.append(", ").append(maxConnsTime); 466 sb.append(", ").append(mtu); 467 sb.append(", ").append(mvnoType); 468 sb.append(", ").append(mvnoMatchData); 469 sb.append(", ").append(permanentFailed); 470 sb.append(", ").append(networkTypeBitmask); 471 sb.append(", ").append(apnSetId); 472 return sb.toString(); 473 } 474 475 /** 476 * Returns true if there are MVNO params specified. 477 */ 478 public boolean hasMvnoParams() { 479 return !TextUtils.isEmpty(mvnoType) && !TextUtils.isEmpty(mvnoMatchData); 480 } 481 482 public boolean canHandleType(String type) { 483 if (!carrierEnabled) return false; 484 boolean wildcardable = true; 485 if (PhoneConstants.APN_TYPE_IA.equalsIgnoreCase(type)) wildcardable = false; 486 for (String t : types) { 487 // DEFAULT handles all, and HIPRI is handled by DEFAULT 488 if (t.equalsIgnoreCase(type) || 489 (wildcardable && t.equalsIgnoreCase(PhoneConstants.APN_TYPE_ALL)) || 490 (t.equalsIgnoreCase(PhoneConstants.APN_TYPE_DEFAULT) && 491 type.equalsIgnoreCase(PhoneConstants.APN_TYPE_HIPRI))) { 492 return true; 493 } 494 } 495 return false; 496 } 497 498 private static boolean iccidMatches(String mvnoData, String iccId) { 499 String[] mvnoIccidList = mvnoData.split(","); 500 for (String mvnoIccid : mvnoIccidList) { 501 if (iccId.startsWith(mvnoIccid)) { 502 Log.d(TAG, "mvno icc id match found"); 503 return true; 504 } 505 } 506 return false; 507 } 508 509 private static boolean imsiMatches(String imsiDB, String imsiSIM) { 510 // Note: imsiDB value has digit number or 'x' character for seperating USIM information 511 // for MVNO operator. And then digit number is matched at same order and 'x' character 512 // could replace by any digit number. 513 // ex) if imsiDB inserted '310260x10xxxxxx' for GG Operator, 514 // that means first 6 digits, 8th and 9th digit 515 // should be set in USIM for GG Operator. 516 int len = imsiDB.length(); 517 int idxCompare = 0; 518 519 if (len <= 0) return false; 520 if (len > imsiSIM.length()) return false; 521 522 for (int idx=0; idx<len; idx++) { 523 char c = imsiDB.charAt(idx); 524 if ((c == 'x') || (c == 'X') || (c == imsiSIM.charAt(idx))) { 525 continue; 526 } else { 527 return false; 528 } 529 } 530 return true; 531 } 532 533 public static boolean mvnoMatches(IccRecords r, String mvnoType, String mvnoMatchData) { 534 if (mvnoType.equalsIgnoreCase("spn")) { 535 if ((r.getServiceProviderName() != null) && 536 r.getServiceProviderName().equalsIgnoreCase(mvnoMatchData)) { 537 return true; 538 } 539 } else if (mvnoType.equalsIgnoreCase("imsi")) { 540 String imsiSIM = r.getIMSI(); 541 if ((imsiSIM != null) && imsiMatches(mvnoMatchData, imsiSIM)) { 542 return true; 543 } 544 } else if (mvnoType.equalsIgnoreCase("gid")) { 545 String gid1 = r.getGid1(); 546 int mvno_match_data_length = mvnoMatchData.length(); 547 if ((gid1 != null) && (gid1.length() >= mvno_match_data_length) && 548 gid1.substring(0, mvno_match_data_length).equalsIgnoreCase(mvnoMatchData)) { 549 return true; 550 } 551 } else if (mvnoType.equalsIgnoreCase("iccid")) { 552 String iccId = r.getIccId(); 553 if ((iccId != null) && iccidMatches(mvnoMatchData, iccId)) { 554 return true; 555 } 556 } 557 558 return false; 559 } 560 561 /** 562 * Check if this APN type is metered. 563 * 564 * @param type The APN type 565 * @param phone The phone object 566 * @return True if the APN type is metered, otherwise false. 567 */ 568 public static boolean isMeteredApnType(String type, Phone phone) { 569 if (phone == null) { 570 return true; 571 } 572 573 boolean isRoaming = phone.getServiceState().getDataRoaming(); 574 boolean isIwlan = phone.getServiceState().getRilDataRadioTechnology() 575 == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN; 576 int subId = phone.getSubId(); 577 578 String carrierConfig; 579 // First check if the device is in IWLAN mode. If yes, use the IWLAN metered APN list. Then 580 // check if the device is roaming. If yes, use the roaming metered APN list. Otherwise, use 581 // the normal metered APN list. 582 if (isIwlan) { 583 carrierConfig = CarrierConfigManager.KEY_CARRIER_METERED_IWLAN_APN_TYPES_STRINGS; 584 } else if (isRoaming) { 585 carrierConfig = CarrierConfigManager.KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS; 586 } else { 587 carrierConfig = CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS; 588 } 589 590 if (DBG) { 591 Rlog.d(LOG_TAG, "isMeteredApnType: isRoaming=" + isRoaming + ", isIwlan=" + isIwlan); 592 } 593 594 CarrierConfigManager configManager = (CarrierConfigManager) 595 phone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE); 596 if (configManager == null) { 597 Rlog.e(LOG_TAG, "Carrier config service is not available"); 598 return true; 599 } 600 601 PersistableBundle b = configManager.getConfigForSubId(subId); 602 if (b == null) { 603 Rlog.e(LOG_TAG, "Can't get the config. subId = " + subId); 604 return true; 605 } 606 607 String[] meteredApnTypes = b.getStringArray(carrierConfig); 608 if (meteredApnTypes == null) { 609 Rlog.e(LOG_TAG, carrierConfig + " is not available. " + "subId = " + subId); 610 return true; 611 } 612 613 HashSet<String> meteredApnSet = new HashSet<>(Arrays.asList(meteredApnTypes)); 614 if (DBG) { 615 Rlog.d(LOG_TAG, "For subId = " + subId + ", metered APN types are " 616 + Arrays.toString(meteredApnSet.toArray())); 617 } 618 619 // If all types of APN are metered, then this APN setting must be metered. 620 if (meteredApnSet.contains(PhoneConstants.APN_TYPE_ALL)) { 621 if (DBG) Rlog.d(LOG_TAG, "All APN types are metered."); 622 return true; 623 } 624 625 if (meteredApnSet.contains(type)) { 626 if (DBG) Rlog.d(LOG_TAG, type + " is metered."); 627 return true; 628 } else if (type.equals(PhoneConstants.APN_TYPE_ALL)) { 629 // Assuming no configuration error, if at least one APN type is 630 // metered, then this APN setting is metered. 631 if (meteredApnSet.size() > 0) { 632 if (DBG) Rlog.d(LOG_TAG, "APN_TYPE_ALL APN is metered."); 633 return true; 634 } 635 } 636 637 if (DBG) Rlog.d(LOG_TAG, type + " is not metered."); 638 return false; 639 } 640 641 /** 642 * Check if this APN setting is metered. 643 * 644 * @param phone The phone object 645 * @return True if this APN setting is metered, otherwise false. 646 */ 647 public boolean isMetered(Phone phone) { 648 if (phone == null) { 649 return true; 650 } 651 652 for (String type : types) { 653 // If one of the APN type is metered, then this APN setting is metered. 654 if (isMeteredApnType(type, phone)) { 655 return true; 656 } 657 } 658 return false; 659 } 660 661 // TODO - if we have this function we should also have hashCode. 662 // Also should handle changes in type order and perhaps case-insensitivity 663 @Override 664 public boolean equals(Object o) { 665 if (o instanceof ApnSetting == false) { 666 return false; 667 } 668 669 ApnSetting other = (ApnSetting) o; 670 671 return carrier.equals(other.carrier) 672 && id == other.id 673 && numeric.equals(other.numeric) 674 && apn.equals(other.apn) 675 && proxy.equals(other.proxy) 676 && mmsc.equals(other.mmsc) 677 && mmsProxy.equals(other.mmsProxy) 678 && TextUtils.equals(mmsPort, other.mmsPort) 679 && port.equals(other.port) 680 && TextUtils.equals(user, other.user) 681 && TextUtils.equals(password, other.password) 682 && authType == other.authType 683 && Arrays.deepEquals(types, other.types) 684 && typesBitmap == other.typesBitmap 685 && protocol.equals(other.protocol) 686 && roamingProtocol.equals(other.roamingProtocol) 687 && carrierEnabled == other.carrierEnabled 688 && bearer == other.bearer 689 && bearerBitmask == other.bearerBitmask 690 && profileId == other.profileId 691 && modemCognitive == other.modemCognitive 692 && maxConns == other.maxConns 693 && waitTime == other.waitTime 694 && maxConnsTime == other.maxConnsTime 695 && mtu == other.mtu 696 && mvnoType.equals(other.mvnoType) 697 && mvnoMatchData.equals(other.mvnoMatchData) 698 && networkTypeBitmask == other.networkTypeBitmask 699 && apnSetId == other.apnSetId; 700 } 701 702 /** 703 * Compare two APN settings 704 * 705 * Note: This method does not compare 'id', 'bearer', 'bearerBitmask', 'networkTypeBitmask'. 706 * We only use this for determining if tearing a data call is needed when conditions change. See 707 * cleanUpConnectionsOnUpdatedApns in DcTracker. 708 * 709 * @param o the other object to compare 710 * @param isDataRoaming True if the device is on data roaming 711 * @return True if the two APN settings are same 712 */ 713 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) 714 public boolean equals(Object o, boolean isDataRoaming) { 715 if (!(o instanceof ApnSetting)) { 716 return false; 717 } 718 719 ApnSetting other = (ApnSetting) o; 720 721 return carrier.equals(other.carrier) 722 && numeric.equals(other.numeric) 723 && apn.equals(other.apn) 724 && proxy.equals(other.proxy) 725 && mmsc.equals(other.mmsc) 726 && mmsProxy.equals(other.mmsProxy) 727 && TextUtils.equals(mmsPort, other.mmsPort) 728 && port.equals(other.port) 729 && TextUtils.equals(user, other.user) 730 && TextUtils.equals(password, other.password) 731 && authType == other.authType 732 && Arrays.deepEquals(types, other.types) 733 && typesBitmap == other.typesBitmap 734 && (isDataRoaming || protocol.equals(other.protocol)) 735 && (!isDataRoaming || roamingProtocol.equals(other.roamingProtocol)) 736 && carrierEnabled == other.carrierEnabled 737 && profileId == other.profileId 738 && modemCognitive == other.modemCognitive 739 && maxConns == other.maxConns 740 && waitTime == other.waitTime 741 && maxConnsTime == other.maxConnsTime 742 && mtu == other.mtu 743 && mvnoType.equals(other.mvnoType) 744 && mvnoMatchData.equals(other.mvnoMatchData) 745 && apnSetId == other.apnSetId; 746 } 747 748 /** 749 * Check if neither mention DUN and are substantially similar 750 * 751 * @param other The other APN settings to compare 752 * @return True if two APN settings are similar 753 */ 754 public boolean similar(ApnSetting other) { 755 return (!this.canHandleType(PhoneConstants.APN_TYPE_DUN) 756 && !other.canHandleType(PhoneConstants.APN_TYPE_DUN) 757 && Objects.equals(this.apn, other.apn) 758 && !typeSameAny(this, other) 759 && xorEquals(this.proxy, other.proxy) 760 && xorEquals(this.port, other.port) 761 && xorEquals(this.protocol, other.protocol) 762 && xorEquals(this.roamingProtocol, other.roamingProtocol) 763 && this.carrierEnabled == other.carrierEnabled 764 && this.bearerBitmask == other.bearerBitmask 765 && this.profileId == other.profileId 766 && Objects.equals(this.mvnoType, other.mvnoType) 767 && Objects.equals(this.mvnoMatchData, other.mvnoMatchData) 768 && xorEquals(this.mmsc, other.mmsc) 769 && xorEquals(this.mmsProxy, other.mmsProxy) 770 && xorEquals(this.mmsPort, other.mmsPort)) 771 && this.networkTypeBitmask == other.networkTypeBitmask 772 && this.apnSetId == other.apnSetId; 773 } 774 775 // check whether the types of two APN same (even only one type of each APN is same) 776 private boolean typeSameAny(ApnSetting first, ApnSetting second) { 777 if (VDBG) { 778 StringBuilder apnType1 = new StringBuilder(first.apn + ": "); 779 for (int index1 = 0; index1 < first.types.length; index1++) { 780 apnType1.append(first.types[index1]); 781 apnType1.append(","); 782 } 783 784 StringBuilder apnType2 = new StringBuilder(second.apn + ": "); 785 for (int index1 = 0; index1 < second.types.length; index1++) { 786 apnType2.append(second.types[index1]); 787 apnType2.append(","); 788 } 789 Rlog.d(LOG_TAG, "APN1: is " + apnType1); 790 Rlog.d(LOG_TAG, "APN2: is " + apnType2); 791 } 792 793 for (int index1 = 0; index1 < first.types.length; index1++) { 794 for (int index2 = 0; index2 < second.types.length; index2++) { 795 if (first.types[index1].equals(PhoneConstants.APN_TYPE_ALL) 796 || second.types[index2].equals(PhoneConstants.APN_TYPE_ALL) 797 || first.types[index1].equals(second.types[index2])) { 798 if (VDBG) Rlog.d(LOG_TAG, "typeSameAny: return true"); 799 return true; 800 } 801 } 802 } 803 804 if (VDBG) Rlog.d(LOG_TAG, "typeSameAny: return false"); 805 return false; 806 } 807 808 // equal or one is not specified 809 private boolean xorEquals(String first, String second) { 810 return (Objects.equals(first, second) 811 || TextUtils.isEmpty(first) 812 || TextUtils.isEmpty(second)); 813 } 814 815 // Helper function to convert APN string into a 32-bit bitmask. 816 private static int getApnBitmask(String apn) { 817 switch (apn) { 818 case PhoneConstants.APN_TYPE_DEFAULT: return ApnTypes.DEFAULT; 819 case PhoneConstants.APN_TYPE_MMS: return ApnTypes.MMS; 820 case PhoneConstants.APN_TYPE_SUPL: return ApnTypes.SUPL; 821 case PhoneConstants.APN_TYPE_DUN: return ApnTypes.DUN; 822 case PhoneConstants.APN_TYPE_HIPRI: return ApnTypes.HIPRI; 823 case PhoneConstants.APN_TYPE_FOTA: return ApnTypes.FOTA; 824 case PhoneConstants.APN_TYPE_IMS: return ApnTypes.IMS; 825 case PhoneConstants.APN_TYPE_CBS: return ApnTypes.CBS; 826 case PhoneConstants.APN_TYPE_IA: return ApnTypes.IA; 827 case PhoneConstants.APN_TYPE_EMERGENCY: return ApnTypes.EMERGENCY; 828 case PhoneConstants.APN_TYPE_ALL: return ApnTypes.ALL; 829 default: return ApnTypes.NONE; 830 } 831 } 832 } 833