Loading src/java/com/android/internal/telephony/RetryManager.java +9 −6 Original line number Diff line number Diff line Loading @@ -22,11 +22,10 @@ import android.os.PersistableBundle; import android.os.SystemProperties; import android.telephony.CarrierConfigManager; import android.telephony.Rlog; import android.telephony.data.ApnSetting; import android.text.TextUtils; import android.util.Pair; import com.android.internal.telephony.dataconnection.ApnSetting; import java.util.ArrayList; import java.util.Random; Loading Loading @@ -506,7 +505,9 @@ public class RetryManager { if (++index == mWaitingApns.size()) index = 0; // Stop if we find the non-failed APN. if (mWaitingApns.get(index).permanentFailed == false) break; if (!mWaitingApns.get(index).getPermanentFailed()) { break; } // If we've already cycled through all the APNs, that means there is no APN we can try if (index == mCurrentApnIndex) return null; Loading Loading @@ -553,7 +554,9 @@ public class RetryManager { if (++index >= mWaitingApns.size()) index = 0; // Stop if we find the non-failed APN. if (mWaitingApns.get(index).permanentFailed == false) break; if (!mWaitingApns.get(index).getPermanentFailed()) { break; } // If we've already cycled through all the APNs, that means all APNs have // permanently failed Loading Loading @@ -594,7 +597,7 @@ public class RetryManager { * */ public void markApnPermanentFailed(ApnSetting apn) { if (apn != null) { apn.permanentFailed = true; apn.setPermanentFailed(true); } } Loading Loading @@ -627,7 +630,7 @@ public class RetryManager { configureRetry(); for (ApnSetting apn : mWaitingApns) { apn.permanentFailed = false; apn.setPermanentFailed(false); } log("Setting " + mWaitingApns.size() + " waiting APNs."); Loading src/java/com/android/internal/telephony/dataconnection/ApnContext.java +11 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.net.NetworkCapabilities; import android.net.NetworkConfig; import android.net.NetworkRequest; import android.telephony.Rlog; import android.telephony.data.ApnSetting; import android.text.TextUtils; import android.util.LocalLog; import android.util.SparseIntArray; Loading Loading @@ -128,6 +129,14 @@ public class ApnContext { return mApnType; } /** * Gets the APN type bitmask. * @return The APN type bitmask */ public int getApnTypeBitmask() { return ApnSetting.getApnTypesBitmaskFromString(mApnType); } /** * Get the data call async channel. * @return The data call async channel Loading Loading @@ -392,8 +401,8 @@ public class ApnContext { String provisioningApn = mPhone.getContext().getResources() .getString(R.string.mobile_provisioning_apn); if (!TextUtils.isEmpty(provisioningApn) && (mApnSetting != null) && (mApnSetting.apn != null)) { return (mApnSetting.apn.equals(provisioningApn)); (mApnSetting != null) && (mApnSetting.getApnName() != null)) { return (mApnSetting.getApnName().equals(provisioningApn)); } else { return false; } Loading src/java/com/android/internal/telephony/dataconnection/ApnSetting.javadeleted 100644 → 0 +0 −832 File deleted.Preview size limit exceeded, changes collapsed. Show changes src/java/com/android/internal/telephony/dataconnection/ApnSettingUtils.java 0 → 100644 +215 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.telephony.dataconnection; import android.content.Context; import android.os.PersistableBundle; import android.telephony.CarrierConfigManager; import android.telephony.Rlog; import android.telephony.ServiceState; import android.telephony.data.ApnSetting; import android.util.Log; import com.android.internal.telephony.Phone; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.uicc.IccRecords; import java.util.Arrays; import java.util.HashSet; /** * This class represents a apn setting for create PDP link */ public class ApnSettingUtils { static final String LOG_TAG = "ApnSetting"; private static final boolean DBG = false; private static boolean iccidMatches(String mvnoData, String iccId) { String[] mvnoIccidList = mvnoData.split(","); for (String mvnoIccid : mvnoIccidList) { if (iccId.startsWith(mvnoIccid)) { Log.d(LOG_TAG, "mvno icc id match found"); return true; } } return false; } private static boolean imsiMatches(String imsiDB, String imsiSIM) { // Note: imsiDB value has digit number or 'x' character for seperating USIM information // for MVNO operator. And then digit number is matched at same order and 'x' character // could replace by any digit number. // ex) if imsiDB inserted '310260x10xxxxxx' for GG Operator, // that means first 6 digits, 8th and 9th digit // should be set in USIM for GG Operator. int len = imsiDB.length(); if (len <= 0) return false; if (len > imsiSIM.length()) return false; for (int idx = 0; idx < len; idx++) { char c = imsiDB.charAt(idx); if ((c == 'x') || (c == 'X') || (c == imsiSIM.charAt(idx))) { continue; } else { return false; } } return true; } /** * Check if MVNO type and data match IccRecords. * * @param r the IccRecords * @param mvnoType the MVNO type * @param mvnoMatchData the MVNO match data * @return {@code true} if MVNO type and data match IccRecords, {@code false} otherwise. */ public static boolean mvnoMatches(IccRecords r, int mvnoType, String mvnoMatchData) { if (mvnoType == ApnSetting.MVNO_TYPE_SPN) { if ((r.getServiceProviderName() != null) && r.getServiceProviderName().equalsIgnoreCase(mvnoMatchData)) { return true; } } else if (mvnoType == ApnSetting.MVNO_TYPE_IMSI) { String imsiSIM = r.getIMSI(); if ((imsiSIM != null) && imsiMatches(mvnoMatchData, imsiSIM)) { return true; } } else if (mvnoType == ApnSetting.MVNO_TYPE_GID) { String gid1 = r.getGid1(); int mvno_match_data_length = mvnoMatchData.length(); if ((gid1 != null) && (gid1.length() >= mvno_match_data_length) && gid1.substring(0, mvno_match_data_length).equalsIgnoreCase(mvnoMatchData)) { return true; } } else if (mvnoType == ApnSetting.MVNO_TYPE_ICCID) { String iccId = r.getIccId(); if ((iccId != null) && iccidMatches(mvnoMatchData, iccId)) { return true; } } return false; } /** * Check if this APN type is metered. * * @param type the APN type * @param phone the phone object * @return {@code true} if the APN type is metered, {@code false} otherwise. */ public static boolean isMeteredApnType(String type, Phone phone) { if (phone == null) { return true; } boolean isRoaming = phone.getServiceState().getDataRoaming(); boolean isIwlan = phone.getServiceState().getRilDataRadioTechnology() == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN; int subId = phone.getSubId(); String carrierConfig; // First check if the device is in IWLAN mode. If yes, use the IWLAN metered APN list. Then // check if the device is roaming. If yes, use the roaming metered APN list. Otherwise, use // the normal metered APN list. if (isIwlan) { carrierConfig = CarrierConfigManager.KEY_CARRIER_METERED_IWLAN_APN_TYPES_STRINGS; } else if (isRoaming) { carrierConfig = CarrierConfigManager.KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS; } else { carrierConfig = CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS; } if (DBG) { Rlog.d(LOG_TAG, "isMeteredApnType: isRoaming=" + isRoaming + ", isIwlan=" + isIwlan); } CarrierConfigManager configManager = (CarrierConfigManager) phone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE); if (configManager == null) { Rlog.e(LOG_TAG, "Carrier config service is not available"); return true; } PersistableBundle b = configManager.getConfigForSubId(subId); if (b == null) { Rlog.e(LOG_TAG, "Can't get the config. subId = " + subId); return true; } String[] meteredApnTypes = b.getStringArray(carrierConfig); if (meteredApnTypes == null) { Rlog.e(LOG_TAG, carrierConfig + " is not available. " + "subId = " + subId); return true; } HashSet<String> meteredApnSet = new HashSet<>(Arrays.asList(meteredApnTypes)); if (DBG) { Rlog.d(LOG_TAG, "For subId = " + subId + ", metered APN types are " + Arrays.toString(meteredApnSet.toArray())); } // If all types of APN are metered, then this APN setting must be metered. if (meteredApnSet.contains(PhoneConstants.APN_TYPE_ALL)) { if (DBG) Rlog.d(LOG_TAG, "All APN types are metered."); return true; } if (meteredApnSet.contains(type)) { if (DBG) Rlog.d(LOG_TAG, type + " is metered."); return true; } else if (type.equals(PhoneConstants.APN_TYPE_ALL)) { // Assuming no configuration error, if at least one APN type is // metered, then this APN setting is metered. if (meteredApnSet.size() > 0) { if (DBG) Rlog.d(LOG_TAG, "APN_TYPE_ALL APN is metered."); return true; } } if (DBG) Rlog.d(LOG_TAG, type + " is not metered."); return false; } /** * Check if this APN setting is metered. * * @param phone The phone object * @return True if this APN setting is metered, otherwise false. */ public static boolean isMetered(ApnSetting apn, Phone phone) { if (phone == null) { return true; } String[] types = ApnSetting.getApnTypesStringFromBitmask( apn.getApnTypeBitmask()).split(","); for (String type : types) { // If one of the APN type is metered, then this APN setting is metered. if (isMeteredApnType(type, phone)) { return true; } } return false; } } src/java/com/android/internal/telephony/dataconnection/DataConnection.java +23 −17 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.telephony.AccessNetworkConstants; import android.telephony.Rlog; import android.telephony.ServiceState; import android.telephony.TelephonyManager; import android.telephony.data.ApnSetting; import android.telephony.data.DataCallResponse; import android.telephony.data.DataProfile; import android.telephony.data.DataService; Loading Loading @@ -443,9 +444,9 @@ public class DataConnection extends StateMachine { return; } if (apn != null && apn.mtu != PhoneConstants.UNSET_MTU) { lp.setMtu(apn.mtu); if (DBG) log("MTU set by APN to: " + apn.mtu); if (apn != null && apn.getMtu() != PhoneConstants.UNSET_MTU) { lp.setMtu(apn.getMtu()); if (DBG) log("MTU set by APN to: " + apn.getMtu()); return; } Loading Loading @@ -502,9 +503,12 @@ public class DataConnection extends StateMachine { * @param cp is the connection parameters */ private void onConnect(ConnectionParams cp) { if (DBG) log("onConnect: carrier='" + mApnSetting.carrier + "' APN='" + mApnSetting.apn + "' proxy='" + mApnSetting.proxy + "' port='" + mApnSetting.port + "'"); if (DBG) { log("onConnect: carrier='" + mApnSetting.getEntryName() + "' APN='" + mApnSetting.getApnName() + "' proxy='" + mApnSetting.getProxyAddressAsString() + "' port='" + mApnSetting.getProxyPort() + "'"); } if (cp.mApnContext != null) cp.mApnContext.requestLog("DataConnection.onConnect"); // Check if we should fake an error. Loading Loading @@ -783,12 +787,12 @@ public class DataConnection extends StateMachine { // Do not apply the race condition workaround for MMS APN // if Proxy is an IP-address. // Otherwise, the default APN will not be restored anymore. if (!mApnSetting.types[0].equals(PhoneConstants.APN_TYPE_MMS) || !isIpAddress(mApnSetting.mmsProxy)) { if (!isIpAddress(mApnSetting.getMmsProxyAddressAsString())) { log(String.format( "isDnsOk: return false apn.types[0]=%s APN_TYPE_MMS=%s isIpAddress(%s)=%s", mApnSetting.types[0], PhoneConstants.APN_TYPE_MMS, mApnSetting.mmsProxy, isIpAddress(mApnSetting.mmsProxy))); "isDnsOk: return false apn.types=%d APN_TYPE_MMS=%s isIpAddress(%s)=%s", mApnSetting.getApnTypeBitmask(), PhoneConstants.APN_TYPE_MMS, mApnSetting.getMmsProxyAddressAsString(), isIpAddress(mApnSetting.getMmsProxyAddressAsString()))); return false; } } Loading Loading @@ -922,7 +926,7 @@ public class DataConnection extends StateMachine { // Do we need a restricted network to satisfy the request? // Is this network metered? If not, then don't add restricted if (!mApnSetting.isMetered(mPhone)) { if (!ApnSettingUtils.isMetered(mApnSetting, mPhone)) { return; } Loading @@ -935,10 +939,12 @@ public class DataConnection extends StateMachine { result.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); if (mApnSetting != null) { for (String type : mApnSetting.types) { final String[] types = ApnSetting.getApnTypesStringFromBitmask( mApnSetting.getApnTypeBitmask()).split(","); for (String type : types) { if (!mRestrictedNetworkOverride && (mConnectionParams != null && mConnectionParams.mUnmeteredUseOnly) && ApnSetting.isMeteredApnType(type, mPhone)) { && ApnSettingUtils.isMeteredApnType(type, mPhone)) { log("Dropped the metered " + type + " for the unmetered data call."); continue; } Loading Loading @@ -999,7 +1005,7 @@ public class DataConnection extends StateMachine { // 2. The non-restricted data and is intended for unmetered use only. if (((mConnectionParams != null && mConnectionParams.mUnmeteredUseOnly) && !mRestrictedNetworkOverride) || !mApnSetting.isMetered(mPhone)) { || !ApnSettingUtils.isMetered(mApnSetting, mPhone)) { result.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); } else { result.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); Loading Loading @@ -1170,7 +1176,7 @@ public class DataConnection extends StateMachine { // only NOT be set only if we're in DcInactiveState. mApnSetting = apnContext.getApnSetting(); } if (mApnSetting == null || !mApnSetting.canHandleType(apnContext.getApnType())) { if (mApnSetting == null || !mApnSetting.canHandleType(apnContext.getApnTypeBitmask())) { if (DBG) { log("initConnection: incompatible apnSetting in ConnectionParams cp=" + cp + " dc=" + DataConnection.this); Loading Loading @@ -1683,7 +1689,7 @@ public class DataConnection extends StateMachine { mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, mNetworkInfo.getReason(), null); mNetworkInfo.setExtraInfo(mApnSetting.apn); mNetworkInfo.setExtraInfo(mApnSetting.getApnName()); updateTcpBufferSizes(mRilRat); final NetworkMisc misc = new NetworkMisc(); Loading Loading
src/java/com/android/internal/telephony/RetryManager.java +9 −6 Original line number Diff line number Diff line Loading @@ -22,11 +22,10 @@ import android.os.PersistableBundle; import android.os.SystemProperties; import android.telephony.CarrierConfigManager; import android.telephony.Rlog; import android.telephony.data.ApnSetting; import android.text.TextUtils; import android.util.Pair; import com.android.internal.telephony.dataconnection.ApnSetting; import java.util.ArrayList; import java.util.Random; Loading Loading @@ -506,7 +505,9 @@ public class RetryManager { if (++index == mWaitingApns.size()) index = 0; // Stop if we find the non-failed APN. if (mWaitingApns.get(index).permanentFailed == false) break; if (!mWaitingApns.get(index).getPermanentFailed()) { break; } // If we've already cycled through all the APNs, that means there is no APN we can try if (index == mCurrentApnIndex) return null; Loading Loading @@ -553,7 +554,9 @@ public class RetryManager { if (++index >= mWaitingApns.size()) index = 0; // Stop if we find the non-failed APN. if (mWaitingApns.get(index).permanentFailed == false) break; if (!mWaitingApns.get(index).getPermanentFailed()) { break; } // If we've already cycled through all the APNs, that means all APNs have // permanently failed Loading Loading @@ -594,7 +597,7 @@ public class RetryManager { * */ public void markApnPermanentFailed(ApnSetting apn) { if (apn != null) { apn.permanentFailed = true; apn.setPermanentFailed(true); } } Loading Loading @@ -627,7 +630,7 @@ public class RetryManager { configureRetry(); for (ApnSetting apn : mWaitingApns) { apn.permanentFailed = false; apn.setPermanentFailed(false); } log("Setting " + mWaitingApns.size() + " waiting APNs."); Loading
src/java/com/android/internal/telephony/dataconnection/ApnContext.java +11 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.net.NetworkCapabilities; import android.net.NetworkConfig; import android.net.NetworkRequest; import android.telephony.Rlog; import android.telephony.data.ApnSetting; import android.text.TextUtils; import android.util.LocalLog; import android.util.SparseIntArray; Loading Loading @@ -128,6 +129,14 @@ public class ApnContext { return mApnType; } /** * Gets the APN type bitmask. * @return The APN type bitmask */ public int getApnTypeBitmask() { return ApnSetting.getApnTypesBitmaskFromString(mApnType); } /** * Get the data call async channel. * @return The data call async channel Loading Loading @@ -392,8 +401,8 @@ public class ApnContext { String provisioningApn = mPhone.getContext().getResources() .getString(R.string.mobile_provisioning_apn); if (!TextUtils.isEmpty(provisioningApn) && (mApnSetting != null) && (mApnSetting.apn != null)) { return (mApnSetting.apn.equals(provisioningApn)); (mApnSetting != null) && (mApnSetting.getApnName() != null)) { return (mApnSetting.getApnName().equals(provisioningApn)); } else { return false; } Loading
src/java/com/android/internal/telephony/dataconnection/ApnSetting.javadeleted 100644 → 0 +0 −832 File deleted.Preview size limit exceeded, changes collapsed. Show changes
src/java/com/android/internal/telephony/dataconnection/ApnSettingUtils.java 0 → 100644 +215 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.telephony.dataconnection; import android.content.Context; import android.os.PersistableBundle; import android.telephony.CarrierConfigManager; import android.telephony.Rlog; import android.telephony.ServiceState; import android.telephony.data.ApnSetting; import android.util.Log; import com.android.internal.telephony.Phone; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.uicc.IccRecords; import java.util.Arrays; import java.util.HashSet; /** * This class represents a apn setting for create PDP link */ public class ApnSettingUtils { static final String LOG_TAG = "ApnSetting"; private static final boolean DBG = false; private static boolean iccidMatches(String mvnoData, String iccId) { String[] mvnoIccidList = mvnoData.split(","); for (String mvnoIccid : mvnoIccidList) { if (iccId.startsWith(mvnoIccid)) { Log.d(LOG_TAG, "mvno icc id match found"); return true; } } return false; } private static boolean imsiMatches(String imsiDB, String imsiSIM) { // Note: imsiDB value has digit number or 'x' character for seperating USIM information // for MVNO operator. And then digit number is matched at same order and 'x' character // could replace by any digit number. // ex) if imsiDB inserted '310260x10xxxxxx' for GG Operator, // that means first 6 digits, 8th and 9th digit // should be set in USIM for GG Operator. int len = imsiDB.length(); if (len <= 0) return false; if (len > imsiSIM.length()) return false; for (int idx = 0; idx < len; idx++) { char c = imsiDB.charAt(idx); if ((c == 'x') || (c == 'X') || (c == imsiSIM.charAt(idx))) { continue; } else { return false; } } return true; } /** * Check if MVNO type and data match IccRecords. * * @param r the IccRecords * @param mvnoType the MVNO type * @param mvnoMatchData the MVNO match data * @return {@code true} if MVNO type and data match IccRecords, {@code false} otherwise. */ public static boolean mvnoMatches(IccRecords r, int mvnoType, String mvnoMatchData) { if (mvnoType == ApnSetting.MVNO_TYPE_SPN) { if ((r.getServiceProviderName() != null) && r.getServiceProviderName().equalsIgnoreCase(mvnoMatchData)) { return true; } } else if (mvnoType == ApnSetting.MVNO_TYPE_IMSI) { String imsiSIM = r.getIMSI(); if ((imsiSIM != null) && imsiMatches(mvnoMatchData, imsiSIM)) { return true; } } else if (mvnoType == ApnSetting.MVNO_TYPE_GID) { String gid1 = r.getGid1(); int mvno_match_data_length = mvnoMatchData.length(); if ((gid1 != null) && (gid1.length() >= mvno_match_data_length) && gid1.substring(0, mvno_match_data_length).equalsIgnoreCase(mvnoMatchData)) { return true; } } else if (mvnoType == ApnSetting.MVNO_TYPE_ICCID) { String iccId = r.getIccId(); if ((iccId != null) && iccidMatches(mvnoMatchData, iccId)) { return true; } } return false; } /** * Check if this APN type is metered. * * @param type the APN type * @param phone the phone object * @return {@code true} if the APN type is metered, {@code false} otherwise. */ public static boolean isMeteredApnType(String type, Phone phone) { if (phone == null) { return true; } boolean isRoaming = phone.getServiceState().getDataRoaming(); boolean isIwlan = phone.getServiceState().getRilDataRadioTechnology() == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN; int subId = phone.getSubId(); String carrierConfig; // First check if the device is in IWLAN mode. If yes, use the IWLAN metered APN list. Then // check if the device is roaming. If yes, use the roaming metered APN list. Otherwise, use // the normal metered APN list. if (isIwlan) { carrierConfig = CarrierConfigManager.KEY_CARRIER_METERED_IWLAN_APN_TYPES_STRINGS; } else if (isRoaming) { carrierConfig = CarrierConfigManager.KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS; } else { carrierConfig = CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS; } if (DBG) { Rlog.d(LOG_TAG, "isMeteredApnType: isRoaming=" + isRoaming + ", isIwlan=" + isIwlan); } CarrierConfigManager configManager = (CarrierConfigManager) phone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE); if (configManager == null) { Rlog.e(LOG_TAG, "Carrier config service is not available"); return true; } PersistableBundle b = configManager.getConfigForSubId(subId); if (b == null) { Rlog.e(LOG_TAG, "Can't get the config. subId = " + subId); return true; } String[] meteredApnTypes = b.getStringArray(carrierConfig); if (meteredApnTypes == null) { Rlog.e(LOG_TAG, carrierConfig + " is not available. " + "subId = " + subId); return true; } HashSet<String> meteredApnSet = new HashSet<>(Arrays.asList(meteredApnTypes)); if (DBG) { Rlog.d(LOG_TAG, "For subId = " + subId + ", metered APN types are " + Arrays.toString(meteredApnSet.toArray())); } // If all types of APN are metered, then this APN setting must be metered. if (meteredApnSet.contains(PhoneConstants.APN_TYPE_ALL)) { if (DBG) Rlog.d(LOG_TAG, "All APN types are metered."); return true; } if (meteredApnSet.contains(type)) { if (DBG) Rlog.d(LOG_TAG, type + " is metered."); return true; } else if (type.equals(PhoneConstants.APN_TYPE_ALL)) { // Assuming no configuration error, if at least one APN type is // metered, then this APN setting is metered. if (meteredApnSet.size() > 0) { if (DBG) Rlog.d(LOG_TAG, "APN_TYPE_ALL APN is metered."); return true; } } if (DBG) Rlog.d(LOG_TAG, type + " is not metered."); return false; } /** * Check if this APN setting is metered. * * @param phone The phone object * @return True if this APN setting is metered, otherwise false. */ public static boolean isMetered(ApnSetting apn, Phone phone) { if (phone == null) { return true; } String[] types = ApnSetting.getApnTypesStringFromBitmask( apn.getApnTypeBitmask()).split(","); for (String type : types) { // If one of the APN type is metered, then this APN setting is metered. if (isMeteredApnType(type, phone)) { return true; } } return false; } }
src/java/com/android/internal/telephony/dataconnection/DataConnection.java +23 −17 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.telephony.AccessNetworkConstants; import android.telephony.Rlog; import android.telephony.ServiceState; import android.telephony.TelephonyManager; import android.telephony.data.ApnSetting; import android.telephony.data.DataCallResponse; import android.telephony.data.DataProfile; import android.telephony.data.DataService; Loading Loading @@ -443,9 +444,9 @@ public class DataConnection extends StateMachine { return; } if (apn != null && apn.mtu != PhoneConstants.UNSET_MTU) { lp.setMtu(apn.mtu); if (DBG) log("MTU set by APN to: " + apn.mtu); if (apn != null && apn.getMtu() != PhoneConstants.UNSET_MTU) { lp.setMtu(apn.getMtu()); if (DBG) log("MTU set by APN to: " + apn.getMtu()); return; } Loading Loading @@ -502,9 +503,12 @@ public class DataConnection extends StateMachine { * @param cp is the connection parameters */ private void onConnect(ConnectionParams cp) { if (DBG) log("onConnect: carrier='" + mApnSetting.carrier + "' APN='" + mApnSetting.apn + "' proxy='" + mApnSetting.proxy + "' port='" + mApnSetting.port + "'"); if (DBG) { log("onConnect: carrier='" + mApnSetting.getEntryName() + "' APN='" + mApnSetting.getApnName() + "' proxy='" + mApnSetting.getProxyAddressAsString() + "' port='" + mApnSetting.getProxyPort() + "'"); } if (cp.mApnContext != null) cp.mApnContext.requestLog("DataConnection.onConnect"); // Check if we should fake an error. Loading Loading @@ -783,12 +787,12 @@ public class DataConnection extends StateMachine { // Do not apply the race condition workaround for MMS APN // if Proxy is an IP-address. // Otherwise, the default APN will not be restored anymore. if (!mApnSetting.types[0].equals(PhoneConstants.APN_TYPE_MMS) || !isIpAddress(mApnSetting.mmsProxy)) { if (!isIpAddress(mApnSetting.getMmsProxyAddressAsString())) { log(String.format( "isDnsOk: return false apn.types[0]=%s APN_TYPE_MMS=%s isIpAddress(%s)=%s", mApnSetting.types[0], PhoneConstants.APN_TYPE_MMS, mApnSetting.mmsProxy, isIpAddress(mApnSetting.mmsProxy))); "isDnsOk: return false apn.types=%d APN_TYPE_MMS=%s isIpAddress(%s)=%s", mApnSetting.getApnTypeBitmask(), PhoneConstants.APN_TYPE_MMS, mApnSetting.getMmsProxyAddressAsString(), isIpAddress(mApnSetting.getMmsProxyAddressAsString()))); return false; } } Loading Loading @@ -922,7 +926,7 @@ public class DataConnection extends StateMachine { // Do we need a restricted network to satisfy the request? // Is this network metered? If not, then don't add restricted if (!mApnSetting.isMetered(mPhone)) { if (!ApnSettingUtils.isMetered(mApnSetting, mPhone)) { return; } Loading @@ -935,10 +939,12 @@ public class DataConnection extends StateMachine { result.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); if (mApnSetting != null) { for (String type : mApnSetting.types) { final String[] types = ApnSetting.getApnTypesStringFromBitmask( mApnSetting.getApnTypeBitmask()).split(","); for (String type : types) { if (!mRestrictedNetworkOverride && (mConnectionParams != null && mConnectionParams.mUnmeteredUseOnly) && ApnSetting.isMeteredApnType(type, mPhone)) { && ApnSettingUtils.isMeteredApnType(type, mPhone)) { log("Dropped the metered " + type + " for the unmetered data call."); continue; } Loading Loading @@ -999,7 +1005,7 @@ public class DataConnection extends StateMachine { // 2. The non-restricted data and is intended for unmetered use only. if (((mConnectionParams != null && mConnectionParams.mUnmeteredUseOnly) && !mRestrictedNetworkOverride) || !mApnSetting.isMetered(mPhone)) { || !ApnSettingUtils.isMetered(mApnSetting, mPhone)) { result.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); } else { result.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); Loading Loading @@ -1170,7 +1176,7 @@ public class DataConnection extends StateMachine { // only NOT be set only if we're in DcInactiveState. mApnSetting = apnContext.getApnSetting(); } if (mApnSetting == null || !mApnSetting.canHandleType(apnContext.getApnType())) { if (mApnSetting == null || !mApnSetting.canHandleType(apnContext.getApnTypeBitmask())) { if (DBG) { log("initConnection: incompatible apnSetting in ConnectionParams cp=" + cp + " dc=" + DataConnection.this); Loading Loading @@ -1683,7 +1689,7 @@ public class DataConnection extends StateMachine { mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, mNetworkInfo.getReason(), null); mNetworkInfo.setExtraInfo(mApnSetting.apn); mNetworkInfo.setExtraInfo(mApnSetting.getApnName()); updateTcpBufferSizes(mRilRat); final NetworkMisc misc = new NetworkMisc(); Loading