blob: f9e07b815c7f82fbe5a8c9ae39c5efc2db33d075 [file] [log] [blame]
/*
* Copyright 2021 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.data;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StringDef;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.net.LinkProperties;
import android.net.NetworkCapabilities;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.PersistableBundle;
import android.os.RegistrantList;
import android.telephony.Annotation.ApnType;
import android.telephony.Annotation.NetCapability;
import android.telephony.Annotation.NetworkType;
import android.telephony.CarrierConfigManager;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
import android.util.IndentingPrintWriter;
import com.android.internal.R;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.data.DataRetryManager.DataRetryRule;
import com.android.telephony.Rlog;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
/**
* DataConfigManager is the source of all data related configuration from carrier config and
* resource overlay. DataConfigManager is created to reduce the excessive access to the
* {@link CarrierConfigManager}. All the data config will be loaded once and stored here.
*/
public class DataConfigManager extends Handler {
private static final int EVENT_CARRIER_CONFIG_CHANGED = 1;
/** Indicates the bandwidth estimation source is from the modem. */
private static final String BANDWIDTH_SOURCE_MODEM_STRING_VALUE = "modem";
/** Indicates the bandwidth estimation source is from the static carrier config. */
private static final String BANDWIDTH_SOURCE_CARRIER_CONFIG_STRING_VALUE = "carrier_config";
/** Indicates the bandwidth estimation source is from {@link LinkBandwidthEstimator}. */
private static final String BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR_STRING_VALUE =
"bandwidth_estimator";
/** Default downlink and uplink bandwidth value in kbps. */
private static final int DEFAULT_BANDWIDTH = 14;
/** Network type GPRS. Should not be used outside of DataConfigManager. */
private static final String DATA_CONFIG_NETWORK_TYPE_GPRS = "GPRS";
/** Network type EDGE. Should not be used outside of DataConfigManager. */
private static final String DATA_CONFIG_NETWORK_TYPE_EDGE = "EDGE";
/** Network type UMTS. Should not be used outside of DataConfigManager. */
private static final String DATA_CONFIG_NETWORK_TYPE_UMTS = "UMTS";
/** Network type CDMA. Should not be used outside of DataConfigManager. */
private static final String DATA_CONFIG_NETWORK_TYPE_CDMA = "CDMA";
/** Network type 1xRTT. Should not be used outside of DataConfigManager. */
private static final String DATA_CONFIG_NETWORK_TYPE_1xRTT = "1xRTT";
/** Network type EvDo Rev 0. Should not be used outside of DataConfigManager. */
private static final String DATA_CONFIG_NETWORK_TYPE_EVDO_0 = "EvDo_0";
/** Network type EvDo Rev A. Should not be used outside of DataConfigManager. */
private static final String DATA_CONFIG_NETWORK_TYPE_EVDO_A = "EvDo_A";
/** Network type HSDPA. Should not be used outside of DataConfigManager. */
private static final String DATA_CONFIG_NETWORK_TYPE_HSDPA = "HSDPA";
/** Network type HSUPA. Should not be used outside of DataConfigManager. */
private static final String DATA_CONFIG_NETWORK_TYPE_HSUPA = "HSUPA";
/** Network type HSPA. Should not be used outside of DataConfigManager. */
private static final String DATA_CONFIG_NETWORK_TYPE_HSPA = "HSPA";
/** Network type EvDo Rev B. Should not be used outside of DataConfigManager. */
private static final String DATA_CONFIG_NETWORK_TYPE_EVDO_B = "EvDo_B";
/** Network type eHRPD. Should not be used outside of DataConfigManager. */
private static final String DATA_CONFIG_NETWORK_TYPE_EHRPD = "eHRPD";
/** Network type iDEN. Should not be used outside of DataConfigManager. */
private static final String DATA_CONFIG_NETWORK_TYPE_IDEN = "iDEN";
/** Network type LTE. Should not be used outside of DataConfigManager. */
// TODO: Public only for use by DcTracker. This should be private once DcTracker is removed.
public static final String DATA_CONFIG_NETWORK_TYPE_LTE = "LTE";
/** Network type HSPA+. Should not be used outside of DataConfigManager. */
private static final String DATA_CONFIG_NETWORK_TYPE_HSPAP = "HSPA+";
/** Network type GSM. Should not be used outside of DataConfigManager. */
private static final String DATA_CONFIG_NETWORK_TYPE_GSM = "GSM";
/** Network type IWLAN. Should not be used outside of DataConfigManager. */
private static final String DATA_CONFIG_NETWORK_TYPE_IWLAN = "IWLAN";
/** Network type TD_SCDMA. Should not be used outside of DataConfigManager. */
private static final String DATA_CONFIG_NETWORK_TYPE_TD_SCDMA = "TD_SCDMA";
/** Network type LTE_CA. Should not be used outside of DataConfigManager. */
private static final String DATA_CONFIG_NETWORK_TYPE_LTE_CA = "LTE_CA";
/** Network type NR_NSA. Should not be used outside of DataConfigManager. */
// TODO: Public only for use by DcTracker. This should be private once DcTracker is removed.
public static final String DATA_CONFIG_NETWORK_TYPE_NR_NSA = "NR_NSA";
/** Network type NR_NSA_MMWAVE. Should not be used outside of DataConfigManager. */
// TODO: Public only for use by DcTracker. This should be private once DcTracker is removed.
public static final String DATA_CONFIG_NETWORK_TYPE_NR_NSA_MMWAVE = "NR_NSA_MMWAVE";
/** Network type NR_SA. Should not be used outside of DataConfigManager. */
private static final String DATA_CONFIG_NETWORK_TYPE_NR_SA = "NR_SA";
/** Network type NR_SA_MMWAVE. Should not be used outside of DataConfigManager. */
private static final String DATA_CONFIG_NETWORK_TYPE_NR_SA_MMWAVE = "NR_SA_MMWAVE";
@StringDef(prefix = {"DATA_CONFIG_NETWORK_TYPE_"}, value = {
DATA_CONFIG_NETWORK_TYPE_GPRS,
DATA_CONFIG_NETWORK_TYPE_EDGE,
DATA_CONFIG_NETWORK_TYPE_UMTS,
DATA_CONFIG_NETWORK_TYPE_CDMA,
DATA_CONFIG_NETWORK_TYPE_1xRTT,
DATA_CONFIG_NETWORK_TYPE_EVDO_0,
DATA_CONFIG_NETWORK_TYPE_EVDO_A,
DATA_CONFIG_NETWORK_TYPE_HSDPA,
DATA_CONFIG_NETWORK_TYPE_HSUPA,
DATA_CONFIG_NETWORK_TYPE_HSPA,
DATA_CONFIG_NETWORK_TYPE_EVDO_B,
DATA_CONFIG_NETWORK_TYPE_EHRPD,
DATA_CONFIG_NETWORK_TYPE_IDEN,
DATA_CONFIG_NETWORK_TYPE_LTE,
DATA_CONFIG_NETWORK_TYPE_HSPAP,
DATA_CONFIG_NETWORK_TYPE_GSM,
DATA_CONFIG_NETWORK_TYPE_IWLAN,
DATA_CONFIG_NETWORK_TYPE_TD_SCDMA,
DATA_CONFIG_NETWORK_TYPE_LTE_CA,
DATA_CONFIG_NETWORK_TYPE_NR_NSA,
DATA_CONFIG_NETWORK_TYPE_NR_NSA_MMWAVE,
DATA_CONFIG_NETWORK_TYPE_NR_SA,
DATA_CONFIG_NETWORK_TYPE_NR_SA_MMWAVE,
})
@Retention(RetentionPolicy.SOURCE)
private @interface DataConfigNetworkType {}
private @NonNull final Phone mPhone;
private @NonNull final String mLogTag;
/** The registrants list for config update event. */
private @NonNull final RegistrantList mConfigUpdateRegistrants = new RegistrantList();
private @NonNull final CarrierConfigManager mCarrierConfigManager;
private @NonNull PersistableBundle mCarrierConfig = null;
private @NonNull Resources mResources = null;
/** The network capability priority map */
private @NonNull final Map<Integer, Integer> mNetworkCapabilityPriorityMap =
new ConcurrentHashMap<>();
/** The data retry rules */
private @NonNull final List<DataRetryRule> mDataRetryRules = new ArrayList<>();
/** The metered APN types for home network */
private @NonNull final @ApnType List<Integer> mMeteredApnTypes = new ArrayList<>();
/** The metered APN types for roaming network */
private @NonNull final @ApnType List<Integer> mRoamingMeteredApnTypes =
new ArrayList<>();
/** The network types that only support single data networks */
private @NonNull final @NetworkType List<Integer> mSingleDataNetworkTypeList =
new ArrayList<>();
/** The network types that support temporarily not metered */
private @NonNull final @DataConfigNetworkType Set<String> mUnmeteredNetworkTypes =
new HashSet<>();
/** A map of network types to the downlink and uplink bandwidth values for that network type */
private @NonNull final @DataConfigNetworkType Map<String, DataNetwork.NetworkBandwidth>
mBandwidthMap = new ConcurrentHashMap<>();
/** A map of network types to the TCP buffer sizes for that network type */
private @NonNull final @DataConfigNetworkType Map<String, String> mTcpBufferSizeMap =
new ConcurrentHashMap<>();
/**
* Constructor
*
* @param phone The phone instance.
* @param looper The looper to be used by the handler. Currently the handler thread is the
* phone process's main thread.
*/
public DataConfigManager(@NonNull Phone phone, @NonNull Looper looper) {
super(looper);
mPhone = phone;
mLogTag = "DCM-" + mPhone.getPhoneId();
log("DataConfigManager created.");
mCarrierConfigManager = mPhone.getContext().getSystemService(CarrierConfigManager.class);
IntentFilter filter = new IntentFilter();
filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
mPhone.getContext().registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
if (mPhone.getPhoneId() == intent.getIntExtra(
CarrierConfigManager.EXTRA_SLOT_INDEX,
SubscriptionManager.INVALID_SIM_SLOT_INDEX)) {
sendEmptyMessage(EVENT_CARRIER_CONFIG_CHANGED);
}
}
}
}, filter, null, mPhone);
// Must be called to set mCarrierConfig and mResources to non-null values
updateConfig();
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case EVENT_CARRIER_CONFIG_CHANGED:
log("EVENT_CARRIER_CONFIG_CHANGED");
updateConfig();
break;
default:
loge("Unexpected message " + msg.what);
}
}
/**
* @return {@code true} if the configuration is carrier specific. {@code false} if the
* configuration is the default (i.e. SIM not inserted).
*/
public boolean isConfigCarrierSpecific() {
return mCarrierConfig.getBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL);
}
/**
* Update the configuration.
*/
private void updateConfig() {
if (mCarrierConfigManager != null) {
mCarrierConfig = mCarrierConfigManager.getConfigForSubId(mPhone.getSubId());
}
if (mCarrierConfig == null) {
mCarrierConfig = CarrierConfigManager.getDefaultConfig();
}
mResources = SubscriptionManager.getResourcesForSubId(mPhone.getContext(),
mPhone.getSubId());
updateNetworkCapabilityPriority();
updateDataRetryRules();
updateMeteredApnTypes();
updateSingleDataNetworkTypeList();
updateUnmeteredNetworkTypes();
updateBandwidths();
updateTcpBuffers();
log("Data config updated. Config is " + (isConfigCarrierSpecific() ? "" : "not ")
+ "carrier specific.");
mConfigUpdateRegistrants.notifyRegistrants();
}
/**
* Update the network capability priority from carrier config.
*/
private void updateNetworkCapabilityPriority() {
synchronized (this) {
mNetworkCapabilityPriorityMap.clear();
String[] capabilityPriorityStrings = mCarrierConfig.getStringArray(
CarrierConfigManager.KEY_TELEPHONY_NETWORK_CAPABILITY_PRIORITIES_STRING_ARRAY);
if (capabilityPriorityStrings != null) {
for (String capabilityPriorityString : capabilityPriorityStrings) {
capabilityPriorityString = capabilityPriorityString.trim().toUpperCase();
String[] tokens = capabilityPriorityString.split(":");
if (tokens.length != 2) {
loge("Invalid config \"" + capabilityPriorityString + "\"");
continue;
}
int netCap = DataUtils.getNetworkCapabilityFromString(tokens[0]);
if (netCap < 0) {
loge("Invalid config \"" + capabilityPriorityString + "\"");
continue;
}
int priority = Integer.parseInt(tokens[1]);
mNetworkCapabilityPriorityMap.put(netCap, priority);
}
}
}
}
/**
* Get the priority of a network capability.
*
* @param capability The network capability
* @return The priority range from 0 ~ 100. 100 is the highest priority.
*/
public int getNetworkCapabilityPriority(@NetCapability int capability) {
if (mNetworkCapabilityPriorityMap.containsKey(capability)) {
return mNetworkCapabilityPriorityMap.get(capability);
}
return 0;
}
/**
* Update the data retry rules from the carrier config.
*/
private void updateDataRetryRules() {
synchronized (this) {
mDataRetryRules.clear();
String[] dataRetryRulesStrings = mCarrierConfig.getStringArray(
CarrierConfigManager.KEY_TELEPHONY_DATA_RETRY_RULES_STRING_ARRAY);
if (dataRetryRulesStrings != null) {
Arrays.stream(dataRetryRulesStrings)
.map(DataRetryRule::new)
.forEach(mDataRetryRules::add);
}
}
}
/**
* @return The data retry rules from carrier config.
*/
public @NonNull List<DataRetryRule> getDataRetryRules() {
return Collections.unmodifiableList(mDataRetryRules);
}
/**
* @return Whether data roaming is enabled by default in carrier config.
*/
public boolean isDataRoamingEnabledByDefault() {
return mCarrierConfig.getBoolean(
CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
}
/**
* Update the home and roaming metered APN types from the carrier config.
*/
private void updateMeteredApnTypes() {
synchronized (this) {
mMeteredApnTypes.clear();
String[] meteredApnTypes = mCarrierConfig.getStringArray(
CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS);
if (meteredApnTypes != null) {
Arrays.stream(meteredApnTypes)
.map(ApnSetting::getApnTypeInt)
.forEach(mMeteredApnTypes::add);
}
mRoamingMeteredApnTypes.clear();
String[] roamingMeteredApns = mCarrierConfig.getStringArray(
CarrierConfigManager.KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS);
if (roamingMeteredApns != null) {
Arrays.stream(roamingMeteredApns)
.map(ApnSetting::getApnTypeInt)
.forEach(mRoamingMeteredApnTypes::add);
}
}
}
/**
* @return The metered APN types when connected to a home network
*/
public @NonNull @ApnType List<Integer> getMeteredApnTypes() {
return Collections.unmodifiableList(mMeteredApnTypes);
}
/**
* @return The metered APN types when roaming
*/
public @NonNull @ApnType List<Integer> getMeteredApnTypesWhenRoaming() {
return Collections.unmodifiableList(mRoamingMeteredApnTypes);
}
/**
* @return Whether to use data activity for RRC detection
*/
public boolean shouldUseDataActivityForRrcDetection() {
return mCarrierConfig.getBoolean(
CarrierConfigManager.KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL);
}
/**
* Update the network types for only single data networks from the carrier config.
*/
private void updateSingleDataNetworkTypeList() {
synchronized (this) {
mSingleDataNetworkTypeList.clear();
int[] singleDataNetworkTypeList = mCarrierConfig.getIntArray(
CarrierConfigManager.KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY);
if (singleDataNetworkTypeList != null) {
Arrays.stream(singleDataNetworkTypeList)
.map(ServiceState::rilRadioTechnologyToNetworkType)
.distinct()
.forEach(mSingleDataNetworkTypeList::add);
}
}
}
/**
* @return The list of {@link NetworkType} that only supports single data networks
*/
public @NonNull @NetworkType List<Integer> getNetworkTypesOnlySupportSingleDataNetwork() {
return Collections.unmodifiableList(mSingleDataNetworkTypeList);
}
/**
* @return Whether {@link NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED}
* is supported by the carrier
*/
public boolean isTempNotMeteredSupportedByCarrier() {
return mCarrierConfig.getBoolean(
CarrierConfigManager.KEY_NETWORK_TEMP_NOT_METERED_SUPPORTED_BOOL);
}
/**
* Update the network types that are temporarily not metered from the carrier config.
*/
private void updateUnmeteredNetworkTypes() {
synchronized (this) {
mUnmeteredNetworkTypes.clear();
String[] unmeteredNetworkTypes = mCarrierConfig.getStringArray(
CarrierConfigManager.KEY_UNMETERED_NETWORK_TYPES_STRING_ARRAY);
if (unmeteredNetworkTypes != null) {
mUnmeteredNetworkTypes.addAll(Arrays.asList(unmeteredNetworkTypes));
}
}
}
/**
* Get the meteredness for the network type from the carrier config.
*
* @param networkType The network type to check meteredness for
* @param serviceState The service state, used to determine NR state
* @return Whether the carrier considers the given network type unmetered
*/
public boolean isNetworkTypeUnmeteredByCarrier(@NetworkType int networkType,
@NonNull ServiceState serviceState) {
return mUnmeteredNetworkTypes.contains(
getDataConfigNetworkType(networkType, serviceState));
}
/**
* @return Whether NR is considered unmetered by the carrier when roaming
*/
public boolean isNrUnmeteredWhenRoaming() {
return mCarrierConfig.getBoolean(
CarrierConfigManager.KEY_UNMETERED_NR_NSA_WHEN_ROAMING_BOOL);
}
/**
* Update the downlink and uplink bandwidth values from the carrier config.
*/
private void updateBandwidths() {
synchronized (this) {
mBandwidthMap.clear();
String[] bandwidths = mCarrierConfig.getStringArray(
CarrierConfigManager.KEY_BANDWIDTH_STRING_ARRAY);
boolean useLte = mCarrierConfig.getBoolean(CarrierConfigManager
.KEY_BANDWIDTH_NR_NSA_USE_LTE_VALUE_FOR_UPLINK_BOOL);
if (bandwidths != null) {
for (String bandwidth : bandwidths) {
// split1[0] = network type as string
// split1[1] = downlink,uplink
String[] split1 = bandwidth.split(":");
if (split1.length != 2) {
loge("Invalid bandwidth: " + bandwidth);
continue;
}
// split2[0] = downlink bandwidth in kbps
// split2[1] = uplink bandwidth in kbps
String[] split2 = split1[1].split(",");
if (split2.length != 2) {
loge("Invalid bandwidth values: " + Arrays.toString(split2));
continue;
}
int downlink, uplink;
try {
downlink = Integer.parseInt(split2[0]);
uplink = Integer.parseInt(split2[1]);
} catch (NumberFormatException e) {
loge("Exception parsing bandwidth values for network type " + split1[0]
+ ": " + e);
continue;
}
if (useLte && split1[0].startsWith("NR")) {
// We can get it directly from mBandwidthMap because LTE is defined before
// the NR values in CarrierConfigManager#KEY_BANDWIDTH_STRING_ARRAY.
uplink = mBandwidthMap.get(DATA_CONFIG_NETWORK_TYPE_LTE)
.uplinkBandwidthKbps;
}
mBandwidthMap.put(split1[0],
new DataNetwork.NetworkBandwidth(downlink, uplink));
}
}
}
}
/**
* Get the bandwidth estimate from the carrier config.
*
* @param networkType The network type to get the bandwidth for
* @param serviceState The service state, used to determine NR state
* @return The pre-configured bandwidth estimate from carrier config.
*/
public @NonNull DataNetwork.NetworkBandwidth getBandwidthForNetworkType(
@NetworkType int networkType, @NonNull ServiceState serviceState) {
DataNetwork.NetworkBandwidth bandwidth = mBandwidthMap.get(
getDataConfigNetworkType(networkType, serviceState));
if (bandwidth != null) {
return bandwidth;
}
return new DataNetwork.NetworkBandwidth(DEFAULT_BANDWIDTH, DEFAULT_BANDWIDTH);
}
/**
* @return Whether data throttling should be reset when the TAC changes from the carrier config.
*/
public boolean shouldResetDataThrottlingWhenTacChanges() {
return mCarrierConfig.getBoolean(
CarrierConfigManager.KEY_UNTHROTTLE_DATA_RETRY_WHEN_TAC_CHANGES_BOOL);
}
/**
* @return The data service package override string from the carrier config.
*/
public String getDataServicePackageName() {
return mCarrierConfig.getString(
CarrierConfigManager.KEY_CARRIER_DATA_SERVICE_WWAN_PACKAGE_OVERRIDE_STRING);
}
/**
* @return The default MTU value in bytes from the carrier config.
*/
public int getDefaultMtu() {
// TODO: Move values from mcc/mnc overlays to carrier configs
return mCarrierConfig.getInt(CarrierConfigManager.KEY_DEFAULT_MTU_INT);
}
/**
* Update the TCP buffer sizes from the carrier config.
*/
private void updateTcpBuffers() {
synchronized (this) {
mTcpBufferSizeMap.clear();
String[] buffers = mCarrierConfig.getStringArray(
CarrierConfigManager.KEY_TCP_BUFFERS_STRING_ARRAY);
if (buffers != null) {
for (String buffer : buffers) {
// split[0] = network type as string
// split[1] = rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max
String[] split = buffer.split(":");
if (split.length != 2) {
loge("Invalid TCP buffer sizes: " + buffer);
continue;
}
if (split[1].split(",").length != 6) {
loge("Invalid TCP buffer sizes for " + split[0] + ": " + split[1]);
continue;
}
mTcpBufferSizeMap.put(split[0], split[1]);
}
}
}
}
/**
* Get the TCP config string, used by {@link LinkProperties#setTcpBufferSizes(String)}.
* The config string will have the following form, with values in bytes:
* "read_min,read_default,read_max,write_min,write_default,write_max"
*
* @param networkType The network type. Note that {@link TelephonyManager#NETWORK_TYPE_LTE_CA}
* can be used for LTE CA even though it's not a radio access technology.
* @param serviceState The service state, used to determine NR state.
* @return The TCP configuration string for the given network type or null if unavailable.
*/
public @Nullable String getTcpConfigString(@NetworkType int networkType,
@NonNull ServiceState serviceState) {
// TODO: Move values from mcc/mnc overlays to carrier configs
return mTcpBufferSizeMap.get(getDataConfigNetworkType(networkType, serviceState));
}
/**
* @return The delay in millisecond for IMS graceful tear down. If IMS/RCS de-registration
* does not complete within the window, the data network will be torn down after timeout.
*/
public long getImsDeregistrationDelay() {
return mResources.getInteger(R.integer.config_delay_for_ims_dereg_millis);
}
/**
* @return {@code true} if PDN should persist when IWLAN data service restarted/crashed.
* {@code false} will cause all data networks on IWLAN torn down if IWLAN data service crashes.
*/
public boolean shouldPersistIwlanDataNetworksWhenDataServiceRestarted() {
return mResources.getBoolean(com.android.internal.R.bool
.config_wlan_data_service_conn_persistence_on_restart);
}
/**
* @return The bandwidth estimation source.
*/
public @DataNetwork.BandwidthEstimationSource int getBandwidthEstimateSource() {
String source = mResources.getString(
com.android.internal.R.string.config_bandwidthEstimateSource);
switch (source) {
case BANDWIDTH_SOURCE_MODEM_STRING_VALUE:
return DataNetwork.BANDWIDTH_SOURCE_MODEM;
case BANDWIDTH_SOURCE_CARRIER_CONFIG_STRING_VALUE:
return DataNetwork.BANDWIDTH_SOURCE_CARRIER_CONFIG;
case BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR_STRING_VALUE:
return DataNetwork.BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR;
default:
loge("Invalid bandwidth estimation source config: " + source);
return DataNetwork.BANDWIDTH_SOURCE_UNKNOWN;
}
}
/**
* Get the data config network type based on the given network type and service state
*
* @param networkType The network type
* @param serviceState The service state, used to determine NR state
* @return The equivalent data config network type
*/
public static @NonNull @DataConfigNetworkType String getDataConfigNetworkType(
@NetworkType int networkType, @NonNull ServiceState serviceState) {
// TODO: Make method private once DataConnection is removed
if ((networkType == TelephonyManager.NETWORK_TYPE_LTE
|| networkType == TelephonyManager.NETWORK_TYPE_LTE_CA)
&& (serviceState.getNrState() == NetworkRegistrationInfo.NR_STATE_CONNECTED)) {
return serviceState.getNrFrequencyRange() == ServiceState.FREQUENCY_RANGE_MMWAVE
? DATA_CONFIG_NETWORK_TYPE_NR_NSA_MMWAVE : DATA_CONFIG_NETWORK_TYPE_NR_NSA;
} else if (networkType == TelephonyManager.NETWORK_TYPE_NR
&& serviceState.getNrFrequencyRange() == ServiceState.FREQUENCY_RANGE_MMWAVE) {
return DATA_CONFIG_NETWORK_TYPE_NR_SA_MMWAVE;
}
return networkTypeToDataConfigNetworkType(networkType);
}
/**
* Get the data config network type for the given network type
*
* @param networkType The network type
* @return The equivalent data config network type
*/
private static @NonNull @DataConfigNetworkType String networkTypeToDataConfigNetworkType(
@NetworkType int networkType) {
switch (networkType) {
case TelephonyManager.NETWORK_TYPE_GPRS:
return DATA_CONFIG_NETWORK_TYPE_GPRS;
case TelephonyManager.NETWORK_TYPE_EDGE:
return DATA_CONFIG_NETWORK_TYPE_EDGE;
case TelephonyManager.NETWORK_TYPE_UMTS:
return DATA_CONFIG_NETWORK_TYPE_UMTS;
case TelephonyManager.NETWORK_TYPE_HSDPA:
return DATA_CONFIG_NETWORK_TYPE_HSDPA;
case TelephonyManager.NETWORK_TYPE_HSUPA:
return DATA_CONFIG_NETWORK_TYPE_HSUPA;
case TelephonyManager.NETWORK_TYPE_HSPA:
return DATA_CONFIG_NETWORK_TYPE_HSPA;
case TelephonyManager.NETWORK_TYPE_CDMA:
return DATA_CONFIG_NETWORK_TYPE_CDMA;
case TelephonyManager.NETWORK_TYPE_EVDO_0:
return DATA_CONFIG_NETWORK_TYPE_EVDO_0;
case TelephonyManager.NETWORK_TYPE_EVDO_A:
return DATA_CONFIG_NETWORK_TYPE_EVDO_A;
case TelephonyManager.NETWORK_TYPE_EVDO_B:
return DATA_CONFIG_NETWORK_TYPE_EVDO_B;
case TelephonyManager.NETWORK_TYPE_1xRTT:
return DATA_CONFIG_NETWORK_TYPE_1xRTT;
case TelephonyManager.NETWORK_TYPE_LTE:
return DATA_CONFIG_NETWORK_TYPE_LTE;
case TelephonyManager.NETWORK_TYPE_EHRPD:
return DATA_CONFIG_NETWORK_TYPE_EHRPD;
case TelephonyManager.NETWORK_TYPE_IDEN:
return DATA_CONFIG_NETWORK_TYPE_IDEN;
case TelephonyManager.NETWORK_TYPE_HSPAP:
return DATA_CONFIG_NETWORK_TYPE_HSPAP;
case TelephonyManager.NETWORK_TYPE_GSM:
return DATA_CONFIG_NETWORK_TYPE_GSM;
case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
return DATA_CONFIG_NETWORK_TYPE_TD_SCDMA;
case TelephonyManager.NETWORK_TYPE_IWLAN:
return DATA_CONFIG_NETWORK_TYPE_IWLAN;
case TelephonyManager.NETWORK_TYPE_LTE_CA:
return DATA_CONFIG_NETWORK_TYPE_LTE_CA;
case TelephonyManager.NETWORK_TYPE_NR:
return DATA_CONFIG_NETWORK_TYPE_NR_SA;
default:
return "";
}
}
/**
* Registration point for subscription info ready
*
* @param h handler to notify
* @param what what code of message when delivered
*/
public void registerForConfigUpdate(Handler h, int what) {
mConfigUpdateRegistrants.addUnique(h, what, null);
}
/**
*
* @param h The original handler passed in {@link #registerForConfigUpdate(Handler, int)}.
*/
public void unregisterForConfigUpdate(Handler h) {
mConfigUpdateRegistrants.remove(h);
}
/**
* Log debug messages.
* @param s debug messages
*/
private void log(@NonNull String s) {
Rlog.d(mLogTag, s);
}
/**
* Log error messages.
* @param s error messages
*/
private void loge(@NonNull String s) {
Rlog.e(mLogTag, s);
}
/**
* Dump the state of DataConfigManager
*
* @param fd File descriptor
* @param printWriter Print writer
* @param args Arguments
*/
public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " ");
pw.println(DataConfigManager.class.getSimpleName() + "-" + mPhone.getPhoneId() + ":");
pw.increaseIndent();
pw.println("isConfigCarrierSpecific=" + isConfigCarrierSpecific());
pw.println("Network capability priority:");
pw.increaseIndent();
mNetworkCapabilityPriorityMap.forEach((key, value) -> pw.print(
DataUtils.networkCapabilityToString(key) + ":" + value + " "));
pw.decreaseIndent();
pw.println();
pw.println("Data retry rules:");
pw.increaseIndent();
mDataRetryRules.forEach(pw::println);
pw.decreaseIndent();
pw.println("Metered APN types=" + mMeteredApnTypes.stream()
.map(ApnSetting::getApnTypeString).collect(Collectors.joining(",")));
pw.println("Roaming metered APN types=" + mRoamingMeteredApnTypes.stream()
.map(ApnSetting::getApnTypeString).collect(Collectors.joining(",")));
pw.println("Single data network types=" + mSingleDataNetworkTypeList.stream()
.map(TelephonyManager::getNetworkTypeName).collect(Collectors.joining(",")));
pw.println("Unmetered network types=" + String.join(",", mUnmeteredNetworkTypes));
pw.println("Bandwidths:");
pw.increaseIndent();
mBandwidthMap.forEach((key, value) -> pw.println(key + ":" + value));
pw.decreaseIndent();
pw.println("shouldUseDataActivityForRrcDetection="
+ shouldUseDataActivityForRrcDetection());
pw.println("isTempNotMeteredSupportedByCarrier=" + isTempNotMeteredSupportedByCarrier());
pw.println("shouldResetDataThrottlingWhenTacChanges="
+ shouldResetDataThrottlingWhenTacChanges());
pw.println("Data service package name=" + getDataServicePackageName());
pw.println("Default MTU=" + getDefaultMtu());
pw.println("TCP buffer sizes:");
pw.increaseIndent();
mTcpBufferSizeMap.forEach((key, value) -> pw.println(key + ":" + value));
pw.decreaseIndent();
pw.println("getImsDeregistrationDelay=" + getImsDeregistrationDelay());
pw.println("shouldPersistIwlanDataNetworksWhenDataServiceRestarted="
+ shouldPersistIwlanDataNetworksWhenDataServiceRestarted());
pw.println("Bandwidth estimation source=" + mResources.getString(
com.android.internal.R.string.config_bandwidthEstimateSource));
pw.decreaseIndent();
}
}