blob: c17a2c77fbaf9f610769b5924b6c67203db2912f [file] [log] [blame]
/*
* Copyright (C) 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.telephony.qns;
import static android.telephony.ims.ImsMmTelManager.WIFI_MODE_CELLULAR_PREFERRED;
import static android.telephony.ims.ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED;
import static com.android.telephony.qns.wfc.WfcCarrierConfigManager.CONFIG_DEFAULT_VOWIFI_REGISTATION_TIMER;
import static com.android.telephony.qns.wfc.WfcCarrierConfigManager.KEY_QNS_VOWIFI_REGISTATION_TIMER_FOR_VOWIFI_ACTIVATION_INT;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.net.NetworkCapabilities;
import android.os.Handler;
import android.os.PersistableBundle;
import android.os.SystemClock;
import android.telephony.AccessNetworkConstants;
import android.telephony.Annotation.NetCapability;
import android.telephony.CarrierConfigManager;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
import android.text.TextUtils;
import android.util.Log;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/** This class contains QualifiedNetworksService specific utility functions */
class QnsUtils {
private static final String CARRIER_ID_PREFIX = "carrier_config_carrierid_";
/**
* Get supported APN types
*
* @param apnTypeBitmask bitmask of APN types.
* @return list of APN types
*/
@ApnSetting.ApnType
static List<Integer> getApnTypes(int apnTypeBitmask) {
List<Integer> types = new ArrayList<>();
if ((apnTypeBitmask & ApnSetting.TYPE_DEFAULT) == ApnSetting.TYPE_DEFAULT) {
types.add(ApnSetting.TYPE_DEFAULT);
apnTypeBitmask &= ~ApnSetting.TYPE_DEFAULT;
}
while (apnTypeBitmask != 0) {
int highestApnTypeBit = Integer.highestOneBit(apnTypeBitmask);
types.add(highestApnTypeBit);
apnTypeBitmask &= ~highestApnTypeBit;
}
return types;
}
/**
* Get names of AccessNetworkTypes
*
* @param accessNetworkTypes list of accessNetworkType
* @return String of AccessNetworkTypes name
*/
static String getStringAccessNetworkTypes(List<Integer> accessNetworkTypes) {
if (accessNetworkTypes == null || accessNetworkTypes.size() == 0) {
return "[empty]";
}
List<String> types = new ArrayList<>();
for (Integer net : accessNetworkTypes) {
types.add(QnsConstants.accessNetworkTypeToString(net));
}
return TextUtils.join("|", types);
}
/**
* Get a subId per slot id.
*
* @param context Context
* @param slotId slot id.
* @return Subscription id per slot id.
*/
static int getSubId(Context context, int slotId) {
try {
return getSubscriptionInfo(context, slotId).getSubscriptionId();
} catch (IllegalStateException e) {
return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
}
}
/**
* This method validates the slot index.
*
* @param context Context
* @param slotIndex slot index
* @return returns true if slotIndex is valid; otherwise false.
*/
static boolean isValidSlotIndex(Context context, int slotIndex) {
TelephonyManager tm = context.getSystemService(TelephonyManager.class);
return slotIndex >= 0 && tm != null && slotIndex < tm.getActiveModemCount();
}
static boolean isDefaultDataSubs(int slotId) {
int ddsSlotId =
SubscriptionManager.getSlotIndex(
SubscriptionManager.getDefaultDataSubscriptionId());
if (ddsSlotId != SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
return ddsSlotId == slotId;
}
return false;
}
static long getSystemElapsedRealTime() {
return SystemClock.elapsedRealtime();
}
private static SubscriptionInfo getSubscriptionInfo(Context context, int slotId)
throws IllegalStateException {
SubscriptionManager sm = context.getSystemService(SubscriptionManager.class);
SubscriptionInfo info = sm.getActiveSubscriptionInfoForSimSlotIndex(slotId);
if (info == null) {
throw new IllegalStateException("Subscription info is null.");
}
return info;
}
/** isCrossSimCallingEnabled */
public static boolean isCrossSimCallingEnabled(QnsImsManager imsManager) {
try {
return imsManager.isCrossSimCallingEnabled();
} catch (Exception e) {
// Fail to query Cross-SIM calling setting, just return false to avoid an exception.
}
return false;
}
/** isWfcEnabled */
public static boolean isWfcEnabled(
QnsImsManager imsManager, QnsProvisioningListener listener, boolean roaming) {
try {
boolean bWfcEnabledByUser;
boolean bWfcEnabledByPlatform = imsManager.isWfcEnabledByPlatform();
boolean bWfcProvisionedOnDevice = imsManager.isWfcProvisionedOnDevice();
if (roaming) {
bWfcEnabledByUser = imsManager.isWfcRoamingEnabledByUser();
try {
boolean bWfcRoamingEnabled =
listener.getLastProvisioningWfcRoamingEnabledInfo();
bWfcEnabledByUser = bWfcEnabledByUser && (bWfcRoamingEnabled);
} catch (Exception e) {
log("got exception e:" + e);
}
} else {
bWfcEnabledByUser = imsManager.isWfcEnabledByUser();
}
log(
"isWfcEnabled slot:"
+ imsManager.getSlotIndex()
+ " byUser:"
+ bWfcEnabledByUser
+ " byPlatform:"
+ bWfcEnabledByPlatform
+ " ProvisionedOnDevice:"
+ bWfcProvisionedOnDevice
+ " roam:"
+ roaming);
return bWfcEnabledByUser && bWfcEnabledByPlatform && bWfcProvisionedOnDevice;
} catch (Exception e) {
loge("isWfcEnabled exception:" + e);
// Fail to query, just return false to avoid an exception.
}
return false;
}
/** isWfcEnabledByPlatform */
public static boolean isWfcEnabledByPlatform(QnsImsManager imsManager) {
try {
boolean bWfcEnabledByPlatform = imsManager.isWfcEnabledByPlatform();
log(
"isWfcEnabledByPlatform:"
+ bWfcEnabledByPlatform
+ " slot:"
+ imsManager.getSlotIndex());
return bWfcEnabledByPlatform;
} catch (Exception e) {
loge("isWfcEnabledByPlatform exception:" + e);
// Fail to query, just return false to avoid an exception.
}
return false;
}
/** getWfcMode */
public static int getWfcMode(QnsImsManager imsManager, boolean roaming) {
try {
int wfcMode = imsManager.getWfcMode(roaming);
log(
"getWfcMode slot:"
+ imsManager.getSlotIndex()
+ " wfcMode:"
+ wfcMode
+ " roaming:"
+ roaming);
return wfcMode;
} catch (Exception e) {
// Fail to query, just return false to avoid an exception.
}
return roaming ? WIFI_MODE_WIFI_PREFERRED : WIFI_MODE_CELLULAR_PREFERRED;
}
/**
* This method provides the access network type for the given data registration state and
* Network Type. It will return value as UNKNOWN(0) if registration state is not in service.
*
* @param dataRegState Data registration state.
* @param dataNetworkType Data network type
* @return int value of the AccessNetworkType mapped to NetworkType. And UNKNOWN(0) if
* registration state is not in service.
*/
static int getCellularAccessNetworkType(int dataRegState, int dataNetworkType) {
if (dataRegState == ServiceState.STATE_IN_SERVICE) {
return QnsConstants.networkTypeToAccessNetworkType(dataNetworkType);
}
return AccessNetworkConstants.AccessNetworkType.UNKNOWN;
}
static boolean isWifiCallingAvailable(Context context, int slotId) {
try {
int subId = QnsUtils.getSubId(context, slotId);
TelephonyManager telephonyManager =
context.getSystemService(TelephonyManager.class).createForSubscriptionId(subId);
return telephonyManager.isWifiCallingAvailable();
} catch (Exception e) {
loge("isWifiCallingAvailable has exception : " + e);
}
return false;
}
@AccessNetworkConstants.TransportType
static int getTransportTypeFromAccessNetwork(
@AccessNetworkConstants.RadioAccessNetworkType int accessNetwork) {
if (accessNetwork == AccessNetworkConstants.AccessNetworkType.IWLAN) {
return AccessNetworkConstants.TRANSPORT_TYPE_WLAN;
} else if (accessNetwork != AccessNetworkConstants.AccessNetworkType.UNKNOWN) {
return AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
}
return AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
}
/**
* Get Set of network capabilities from string joined by {@code |}, space is ignored. If input
* string contains unknown capability or malformatted(e.g. empty string), -1 is included in the
* returned set.
*
* @param capabilitiesString capability strings joined by {@code |}
* @return Set of capabilities
*/
@NetCapability
static Set<Integer> getNetworkCapabilitiesFromString(@NonNull String capabilitiesString) {
// e.g. "IMS|" is not allowed
if (!capabilitiesString.matches("(\\s*[a-zA-Z]+\\s*)(\\|\\s*[a-zA-Z]+\\s*)*")) {
return Collections.singleton(-1);
}
return Arrays.stream(capabilitiesString.split("\\s*\\|\\s*"))
.map(String::trim)
.map(QnsUtils::getNetworkCapabilityFromString)
.collect(Collectors.toSet());
}
/**
* Returns another transport type.
* @param transportType transport type
* @return another transport type of input parameter
*/
@AccessNetworkConstants.TransportType
static int getOtherTransportType(@AccessNetworkConstants.TransportType int transportType) {
if (transportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
return AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
} else if (transportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
return AccessNetworkConstants.TRANSPORT_TYPE_WLAN;
}
return AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
}
/**
* Convert network capabilities to string.
*
* <p>This is for debugging and logging purposes only.
*
* @param netCaps Network capabilities.
* @return Network capabilities in string format.
*/
@NonNull
static String networkCapabilitiesToString(
@NetCapability @Nullable Collection<Integer> netCaps) {
if (netCaps == null || netCaps.isEmpty()) return "";
return "["
+ netCaps.stream()
.map(QnsUtils::networkCapabilityToString)
.collect(Collectors.joining("|"))
+ "]";
}
/**
* Convert a network capability to string.
*
* <p>This is for debugging and logging purposes only.
*
* @param netCap Network capability.
* @return Network capability in string format.
*/
@NonNull
static String networkCapabilityToString(@NetCapability int netCap) {
switch (netCap) {
case NetworkCapabilities.NET_CAPABILITY_MMS:
return "MMS";
case NetworkCapabilities.NET_CAPABILITY_SUPL:
return "SUPL";
case NetworkCapabilities.NET_CAPABILITY_DUN:
return "DUN";
case NetworkCapabilities.NET_CAPABILITY_FOTA:
return "FOTA";
case NetworkCapabilities.NET_CAPABILITY_IMS:
return "IMS";
case NetworkCapabilities.NET_CAPABILITY_CBS:
return "CBS";
case NetworkCapabilities.NET_CAPABILITY_WIFI_P2P:
return "WIFI_P2P";
case NetworkCapabilities.NET_CAPABILITY_IA:
return "IA";
case NetworkCapabilities.NET_CAPABILITY_RCS:
return "RCS";
case NetworkCapabilities.NET_CAPABILITY_XCAP:
return "XCAP";
case NetworkCapabilities.NET_CAPABILITY_EIMS:
return "EIMS";
case NetworkCapabilities.NET_CAPABILITY_NOT_METERED:
return "NOT_METERED";
case NetworkCapabilities.NET_CAPABILITY_INTERNET:
return "INTERNET";
case NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED:
return "NOT_RESTRICTED";
case NetworkCapabilities.NET_CAPABILITY_TRUSTED:
return "TRUSTED";
case NetworkCapabilities.NET_CAPABILITY_NOT_VPN:
return "NOT_VPN";
case NetworkCapabilities.NET_CAPABILITY_VALIDATED:
return "VALIDATED";
case NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL:
return "CAPTIVE_PORTAL";
case NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING:
return "NOT_ROAMING";
case NetworkCapabilities.NET_CAPABILITY_FOREGROUND:
return "FOREGROUND";
case NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED:
return "NOT_CONGESTED";
case NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED:
return "NOT_SUSPENDED";
case NetworkCapabilities.NET_CAPABILITY_OEM_PAID:
return "OEM_PAID";
case NetworkCapabilities.NET_CAPABILITY_MCX:
return "MCX";
case NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY:
return "PARTIAL_CONNECTIVITY";
case NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED:
return "TEMPORARILY_NOT_METERED";
case NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE:
return "OEM_PRIVATE";
case NetworkCapabilities.NET_CAPABILITY_VEHICLE_INTERNAL:
return "VEHICLE_INTERNAL";
case NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED:
return "NOT_VCN_MANAGED";
case NetworkCapabilities.NET_CAPABILITY_ENTERPRISE:
return "ENTERPRISE";
case NetworkCapabilities.NET_CAPABILITY_VSIM:
return "VSIM";
case NetworkCapabilities.NET_CAPABILITY_BIP:
return "BIP";
case NetworkCapabilities.NET_CAPABILITY_HEAD_UNIT:
return "HEAD_UNIT";
case NetworkCapabilities.NET_CAPABILITY_MMTEL:
return "MMTEL";
case NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY:
return "PRIORITIZE_LATENCY";
case NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH:
return "PRIORITIZE_BANDWIDTH";
default:
return "Unknown(" + netCap + ")";
}
}
/**
* Get the network capability from the string.
*
* @param capabilityString The capability in string format
* @return The network capability. -1 if not found.
*/
@NetCapability
static int getNetworkCapabilityFromString(@NonNull String capabilityString) {
switch (capabilityString.toUpperCase(Locale.ROOT)) {
case "MMS":
return NetworkCapabilities.NET_CAPABILITY_MMS;
case "SUPL":
return NetworkCapabilities.NET_CAPABILITY_SUPL;
case "DUN":
return NetworkCapabilities.NET_CAPABILITY_DUN;
case "FOTA":
return NetworkCapabilities.NET_CAPABILITY_FOTA;
case "IMS":
return NetworkCapabilities.NET_CAPABILITY_IMS;
case "CBS":
return NetworkCapabilities.NET_CAPABILITY_CBS;
case "XCAP":
return NetworkCapabilities.NET_CAPABILITY_XCAP;
case "EIMS":
return NetworkCapabilities.NET_CAPABILITY_EIMS;
case "INTERNET":
return NetworkCapabilities.NET_CAPABILITY_INTERNET;
case "MCX":
return NetworkCapabilities.NET_CAPABILITY_MCX;
case "VSIM":
return NetworkCapabilities.NET_CAPABILITY_VSIM;
case "BIP":
return NetworkCapabilities.NET_CAPABILITY_BIP;
case "ENTERPRISE":
return NetworkCapabilities.NET_CAPABILITY_ENTERPRISE;
case "PRIORITIZE_BANDWIDTH":
return NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH;
case "PRIORITIZE_LATENCY":
return NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY;
default:
return -1;
}
}
/**
* Get the network capability from the apn type.
*
* @param apnType apn type.
* @return network capability
*/
@NetCapability
static int getNetCapabilityFromApnType(int apnType) {
switch (apnType) {
case ApnSetting.TYPE_IMS:
return NetworkCapabilities.NET_CAPABILITY_IMS;
case ApnSetting.TYPE_EMERGENCY:
return NetworkCapabilities.NET_CAPABILITY_EIMS;
case ApnSetting.TYPE_MMS:
return NetworkCapabilities.NET_CAPABILITY_MMS;
case ApnSetting.TYPE_XCAP:
return NetworkCapabilities.NET_CAPABILITY_XCAP;
case ApnSetting.TYPE_CBS:
return NetworkCapabilities.NET_CAPABILITY_CBS;
default:
throw new IllegalArgumentException("Unsupported apnType: " + apnType);
}
}
/**
* Get the apn type from the network capability.
*
* @param netCapability network capability.
* @return apn type.
*/
static int getApnTypeFromNetCapability(@NetCapability int netCapability) {
switch (netCapability) {
case NetworkCapabilities.NET_CAPABILITY_IMS:
return ApnSetting.TYPE_IMS;
case NetworkCapabilities.NET_CAPABILITY_EIMS:
return ApnSetting.TYPE_EMERGENCY;
case NetworkCapabilities.NET_CAPABILITY_MMS:
return ApnSetting.TYPE_MMS;
case NetworkCapabilities.NET_CAPABILITY_XCAP:
return ApnSetting.TYPE_XCAP;
case NetworkCapabilities.NET_CAPABILITY_CBS:
return ApnSetting.TYPE_CBS;
default:
throw new IllegalArgumentException("Unsupported netCapability: " + netCapability);
}
}
/**
* Convert a network capability to string.
*
* <p>This is for debugging and logging purposes only.
*
* @param netCapability Network capability.
* @return Network capability in string format.
*/
@NonNull
static String getNameOfNetCapability(@NetCapability int netCapability) {
switch (netCapability) {
case NetworkCapabilities.NET_CAPABILITY_IMS:
return "ims";
case NetworkCapabilities.NET_CAPABILITY_EIMS:
return "eims";
case NetworkCapabilities.NET_CAPABILITY_MMS:
return "mms";
case NetworkCapabilities.NET_CAPABILITY_CBS:
return "cbs";
case NetworkCapabilities.NET_CAPABILITY_XCAP:
return "xcap";
default:
throw new IllegalArgumentException("Unsupported netCapability: " + netCapability);
}
}
/**
* Get the network capability from the string.
*
* @param types string array of APN types.
* @return list of Network Capabilities
*/
@NetCapability
static List<Integer> getNetCapabilitiesFromApnTypesString(@NonNull String[] types) {
int apnTypesBitmask = 0;
for (String str : types) {
apnTypesBitmask |= ApnSetting.getApnTypeInt(str);
}
return getNetCapabilitiesFromApnTypeBitmask(apnTypesBitmask);
}
/**
* Get a list of supported network capabilities from apnTypeBitmask
*
* @param apnTypeBitmask bitmask of APN types.
* @return list of Network Capabilities
*/
static List<Integer> getNetCapabilitiesFromApnTypeBitmask(int apnTypeBitmask) {
List<Integer> netCapabilities = new ArrayList<>();
List<Integer> apnTypes = getApnTypes(apnTypeBitmask);
for (int apnType : apnTypes) {
try {
netCapabilities.add(getNetCapabilityFromApnType(apnType));
} catch (IllegalArgumentException e) {
continue;
}
}
return netCapabilities;
}
static PersistableBundle readQnsDefaultConfigFromAssets(Context context, int qnsCarrierID) {
if (qnsCarrierID == TelephonyManager.UNKNOWN_CARRIER_ID) {
return null;
}
return readConfigFromAssets(context, CARRIER_ID_PREFIX + qnsCarrierID + "_");
}
static synchronized <T> T getConfig(
PersistableBundle carrierConfigBundle,
PersistableBundle assetConfigBundle,
String key) {
// TODO: PersistableBundle.get is deprecated.
if (carrierConfigBundle == null || carrierConfigBundle.get(key) == null) {
log("key not set in pb file: " + key);
if (assetConfigBundle == null || assetConfigBundle.get(key) == null) {
return (T) getDefaultValueForKey(key);
} else {
return (T) assetConfigBundle.get(key);
}
}
return (T) carrierConfigBundle.get(key);
}
static synchronized <T> T getDefaultValueForKey(String key) {
switch (key) {
case QnsCarrierConfigManager.KEY_QNS_SUPPORT_WFC_DURING_AIRPLANE_MODE_BOOL:
case QnsCarrierConfigManager.KEY_BLOCK_IPV6_ONLY_WIFI_BOOL:
case CarrierConfigManager.ImsVoice.KEY_CARRIER_VOLTE_ROAMING_AVAILABLE_BOOL:
return (T) Boolean.valueOf(true);
case QnsCarrierConfigManager
.KEY_QNS_ALLOW_VIDEO_OVER_IWLAN_WITH_CELLULAR_LIMITED_CASE_BOOL:
case QnsCarrierConfigManager.KEY_QNS_HO_GUARDING_BY_PREFERENCE_BOOL:
case QnsCarrierConfigManager.KEY_QNS_SUPPORT_SERVICE_BARRING_CHECK_BOOL:
case QnsCarrierConfigManager
.KEY_ROAM_TRANSPORT_TYPE_SELECTION_WITHOUT_SIGNAL_STRENGTH_BOOL:
case QnsCarrierConfigManager.KEY_PREFER_CURRENT_TRANSPORT_TYPE_IN_VOICE_CALL_BOOL:
case QnsCarrierConfigManager.KEY_POLICY_OVERRIDE_CELL_PREF_TO_IMS_PREF_HOME_BOOL:
case QnsCarrierConfigManager
.KEY_QNS_ROVE_OUT_POLICY_WITH_WIFI_BAD_GUARDTIMER_CONDITIONS_BOOL:
case QnsCarrierConfigManager.KEY_QNS_ALLOW_IMS_OVER_IWLAN_CELLULAR_LIMITED_CASE_BOOL:
case QnsCarrierConfigManager.KEY_BLOCK_IWLAN_IN_INTERNATIONAL_ROAMING_WITHOUT_WWAN_BOOL:
case QnsCarrierConfigManager
.KEY_IN_CALL_HO_DECISION_WLAN_TO_WWAN_WITHOUT_VOPS_CONDITION_BOOL:
return (T) Boolean.valueOf(false);
case QnsCarrierConfigManager.KEY_SIP_DIALOG_SESSION_POLICY_INT:
return (T) Integer.valueOf(QnsConstants.SIP_DIALOG_SESSION_POLICY_NONE);
case QnsCarrierConfigManager.KEY_QNS_CELLULAR_SS_THRESHOLDBACKHAUL_TIMER_MS_INT:
return (T) Integer.valueOf(QnsConstants.KEY_DEFAULT_VALUE);
case QnsCarrierConfigManager.KEY_QNS_WIFI_RSSI_THRESHOLDBACKHAUL_TIMER_MS_INT:
return (T) Integer.valueOf(QnsConstants.DEFAULT_WIFI_BACKHAUL_TIMER);
case QnsCarrierConfigManager.KEY_QNS_IMS_TRANSPORT_TYPE_INT:
return (T) Integer.valueOf(QnsConstants.TRANSPORT_TYPE_ALLOWED_BOTH);
case QnsCarrierConfigManager.KEY_QNS_MMS_TRANSPORT_TYPE_INT:
case QnsCarrierConfigManager.KEY_QNS_XCAP_TRANSPORT_TYPE_INT:
case QnsCarrierConfigManager.KEY_QNS_CBS_TRANSPORT_TYPE_INT:
case QnsCarrierConfigManager.KEY_QNS_SOS_TRANSPORT_TYPE_INT:
return (T) Integer.valueOf(QnsConstants.TRANSPORT_TYPE_ALLOWED_WWAN);
case QnsCarrierConfigManager.KEY_QNS_XCAP_RAT_PREFERENCE_INT:
case QnsCarrierConfigManager.KEY_QNS_SOS_RAT_PREFERENCE_INT:
case QnsCarrierConfigManager.KEY_QNS_MMS_RAT_PREFERENCE_INT:
case QnsCarrierConfigManager.KEY_QNS_CBS_RAT_PREFERENCE_INT:
return (T) Integer.valueOf(QnsConstants.RAT_PREFERENCE_DEFAULT);
case KEY_QNS_VOWIFI_REGISTATION_TIMER_FOR_VOWIFI_ACTIVATION_INT:
return (T) Integer.valueOf(CONFIG_DEFAULT_VOWIFI_REGISTATION_TIMER);
case CarrierConfigManager.ImsVoice.KEY_VOICE_RTP_JITTER_THRESHOLD_MILLIS_INT:
case CarrierConfigManager.ImsVoice.KEY_VOICE_RTP_PACKET_LOSS_RATE_THRESHOLD_INT:
return (T) Integer.valueOf(QnsConstants.INVALID_VALUE);
case QnsCarrierConfigManager.KEY_QNS_MEDIA_THRESHOLD_RTP_PACKET_LOSS_TIME_MILLIS_INT:
return (T) Integer.valueOf(QnsConstants.KEY_DEFAULT_PACKET_LOSS_TIME_MILLIS);
case CarrierConfigManager.ImsVoice.KEY_VOICE_RTP_INACTIVITY_TIME_THRESHOLD_MILLIS_LONG:
return (T) Long.valueOf(QnsConstants.INVALID_VALUE);
case QnsCarrierConfigManager
.KEY_QNS_IN_CALL_ROVEIN_ALLOWED_COUNT_AND_FALLBACK_REASON_INT_ARRAY:
return (T)
new int[] {
QnsConstants.MAX_COUNT_INVALID, QnsConstants.FALLBACK_REASON_INVALID
};
case QnsCarrierConfigManager
.KEY_WAITING_TIME_FOR_PREFERRED_TRANSPORT_WHEN_POWER_ON_INT_ARRAY:
case QnsCarrierConfigManager.KEY_NON_IMS_WWAN_HYSTERESIS_TIMER_MS_INT_ARRAY:
case QnsCarrierConfigManager.KEY_NON_IMS_WLAN_HYSTERESIS_TIMER_MS_INT_ARRAY:
return (T)
new int[] {QnsConstants.KEY_DEFAULT_VALUE, QnsConstants.KEY_DEFAULT_VALUE};
case QnsCarrierConfigManager.KEY_QNS_IMS_NETWORK_ENABLE_HO_HYSTERESIS_TIMER_INT:
return (T) Integer.valueOf(QnsConstants.COVERAGE_BOTH);
case QnsCarrierConfigManager
.KEY_QNS_HO_RESTRICT_TIME_WITH_LOW_RTP_QUALITY_MILLIS_INT_ARRAY:
return (T)
new int[] {
QnsConstants.KEY_DEFAULT_IWLAN_AVOID_TIME_LOW_RTP_QUALITY_MILLIS,
QnsConstants.KEY_DEFAULT_WWAN_AVOID_TIME_LOW_RTP_QUALITY_MILLIS,
};
case QnsCarrierConfigManager.KEY_IMS_WWAN_HYSTERESIS_TIMER_MS_INT_ARRAY:
case QnsCarrierConfigManager.KEY_IMS_WLAN_HYSTERESIS_TIMER_MS_INT_ARRAY:
return (T)
new int[] {
QnsConstants.KEY_DEFAULT_HYST_TIMER,
QnsConstants.KEY_DEFAULT_HYST_TIMER,
QnsConstants.KEY_DEFAULT_HYST_TIMER
};
case QnsCarrierConfigManager.KEY_MINIMUM_HANDOVER_GUARDING_TIMER_MS_INT:
return (T) Integer.valueOf(QnsConstants.CONFIG_DEFAULT_MIN_HANDOVER_GUARDING_TIMER);
case QnsCarrierConfigManager
.KEY_CHOOSE_WFC_PREFERRED_TRANSPORT_IN_BOTH_BAD_CONDITION_INT_ARRAY:
return (T) new int[] {};
case QnsCarrierConfigManager.KEY_IMS_CELLULAR_ALLOWED_RAT_STRING_ARRAY:
return (T) new String[] {"LTE", "NR"};
case QnsCarrierAnspSupportConfig.KEY_IDLE_NGRAN_SSRSRP_INT_ARRAY:
case QnsCarrierAnspSupportConfig.KEY_VOICE_NGRAN_SSRSRP_INT_ARRAY:
case QnsCarrierAnspSupportConfig.KEY_VIDEO_NGRAN_SSRSRP_INT_ARRAY:
return (T)
new int[] {
QnsConstants.KEY_DEFAULT_THRESHOLD_SSRSRP_GOOD,
QnsConstants.KEY_DEFAULT_THRESHOLD_SSRSRP_BAD,
QnsCarrierConfigManager.QnsConfigArray.INVALID
};
case QnsCarrierAnspSupportConfig.KEY_IDLE_EUTRAN_RSRP_INT_ARRAY:
case QnsCarrierAnspSupportConfig.KEY_VOICE_EUTRAN_RSRP_INT_ARRAY:
case QnsCarrierAnspSupportConfig.KEY_VIDEO_EUTRAN_RSRP_INT_ARRAY:
return (T)
new int[] {
QnsConstants.KEY_DEFAULT_THRESHOLD_RSRP_GOOD,
QnsConstants.KEY_DEFAULT_THRESHOLD_RSRP_BAD,
QnsCarrierConfigManager.QnsConfigArray.INVALID
};
case QnsCarrierAnspSupportConfig.KEY_IDLE_UTRAN_RSCP_INT_ARRAY:
case QnsCarrierAnspSupportConfig.KEY_VOICE_UTRAN_RSCP_INT_ARRAY:
case QnsCarrierAnspSupportConfig.KEY_VIDEO_UTRAN_RSCP_INT_ARRAY:
return (T)
new int[] {
QnsConstants.KEY_DEFAULT_THRESHOLD_RSCP_GOOD,
QnsConstants.KEY_DEFAULT_THRESHOLD_RSCP_BAD,
QnsCarrierConfigManager.QnsConfigArray.INVALID
};
case QnsCarrierAnspSupportConfig.KEY_IDLE_GERAN_RSSI_INT_ARRAY:
case QnsCarrierAnspSupportConfig.KEY_VOICE_GERAN_RSSI_INT_ARRAY:
case QnsCarrierAnspSupportConfig.KEY_VIDEO_GERAN_RSSI_INT_ARRAY:
return (T)
new int[] {
QnsConstants.KEY_DEFAULT_THRESHOLD_GERAN_RSSI_GOOD,
QnsConstants.KEY_DEFAULT_THRESHOLD_GERAN_RSSI_BAD,
QnsCarrierConfigManager.QnsConfigArray.INVALID
};
case QnsCarrierAnspSupportConfig.KEY_IDLE_WIFI_RSSI_INT_ARRAY:
case QnsCarrierAnspSupportConfig.KEY_VOICE_WIFI_RSSI_INT_ARRAY:
case QnsCarrierAnspSupportConfig.KEY_VIDEO_WIFI_RSSI_INT_ARRAY:
return (T)
new int[] {
QnsConstants.KEY_DEFAULT_THRESHOLD_WIFI_RSSI_GOOD,
QnsConstants.KEY_DEFAULT_THRESHOLD_WIFI_RSSI_BAD
};
case QnsCarrierAnspSupportConfig.KEY_OVERRIDE_WIFI_PREF_IDLE_WIFI_RSSI_INT_ARRAY:
case QnsCarrierAnspSupportConfig.KEY_OVERRIDE_WIFI_PREF_VOICE_WIFI_RSSI_INT_ARRAY:
case QnsCarrierAnspSupportConfig.KEY_OVERRIDE_WIFI_PREF_VIDEO_WIFI_RSSI_INT_ARRAY:
case CarrierConfigManager.Ims.KEY_IMS_PDN_ENABLED_IN_NO_VOPS_SUPPORT_INT_ARRAY:
return (T) new int[] {};
case QnsCarrierConfigManager.KEY_QNS_WLAN_RTT_BACKHAUL_CHECK_ON_ICMP_PING_STRING:
return (T) "";
case QnsCarrierConfigManager
.KEY_QNS_FALLBACK_ON_INITIAL_CONNECTION_FAILURE_STRING_ARRAY:
return (T) new String[] {};
default:
break;
}
return (T) null;
}
static synchronized int getConfigCarrierId(Context context, int slotId) {
TelephonyManager tm = context.getSystemService(TelephonyManager.class);
tm = tm.createForSubscriptionId(QnsUtils.getSubId(context, slotId));
return tm.getSimCarrierId();
}
private static String getAssetFileName(Context context, String carrierIDConfig) {
String[] configFileNameList;
try {
configFileNameList = context.getAssets().list("");
for (String fileName : configFileNameList) {
if (fileName.startsWith(carrierIDConfig)) {
log("matched file: " + fileName);
return fileName;
}
}
} catch (Exception e) {
loge("getFileName, can't find " + carrierIDConfig + " asset");
}
return null;
}
private static PersistableBundle readConfigFromAssets(Context context, String carrierIDConfig) {
PersistableBundle bundleFromAssets = new PersistableBundle();
String fileName = getAssetFileName(context, carrierIDConfig);
InputStream inputStream = null;
InputStreamReader inputStreamReader = null;
try {
inputStream = context.getAssets().open(fileName);
inputStreamReader = new InputStreamReader(inputStream);
Stream<String> streamOfString = new BufferedReader(inputStreamReader).lines();
String streamToString = streamOfString.collect(Collectors.joining());
String configTag = "carrier_config";
int begin = streamToString.indexOf(configTag);
int end = streamToString.lastIndexOf(configTag) + configTag.length();
String bundleString = "<" + streamToString.substring(begin, end) + ">";
InputStream targetStream = new ByteArrayInputStream(bundleString.getBytes());
bundleFromAssets = PersistableBundle.readFromStream(targetStream);
log("bundleFromAssets created : " + bundleFromAssets);
} catch (Exception e) {
loge("readConfigFromAssets, e: " + e);
} finally {
if (inputStreamReader != null) {
try {
inputStreamReader.close();
} catch (Exception e) {
loge("inputStreamReader.close e:" + e);
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (Exception e) {
loge("inputStream.close e:" + e);
}
}
}
return bundleFromAssets;
}
protected static void loge(String log) {
Log.e(QnsUtils.class.getSimpleName(), log);
}
protected static void log(String log) {
Log.d(QnsUtils.class.getSimpleName(), log);
}
protected static class QnsExecutor implements Executor {
private final Handler mHandler;
QnsExecutor(Handler handler) {
mHandler = handler;
}
@Override
public void execute(Runnable command) {
if (!mHandler.post(command)) {
throw new RejectedExecutionException(mHandler + " is shutting down");
}
}
}
}