Merge "Remove obsolete version of LinkCapacityEstimate" into sc-dev
diff --git a/src/java/com/android/internal/telephony/CarrierInfoManager.java b/src/java/com/android/internal/telephony/CarrierInfoManager.java
index c73214a..00f8c39 100644
--- a/src/java/com/android/internal/telephony/CarrierInfoManager.java
+++ b/src/java/com/android/internal/telephony/CarrierInfoManager.java
@@ -254,7 +254,13 @@
return;
}
mLastAccessResetCarrierKey = now;
- deleteCarrierInfoForImsiEncryption(context);
+ int[] subIds = context.getSystemService(SubscriptionManager.class)
+ .getSubscriptionIds(mPhoneId);
+ if (subIds == null || subIds.length < 1) {
+ Log.e(LOG_TAG, "Could not reset carrier keys, subscription for mPhoneId=" + mPhoneId);
+ return;
+ }
+ deleteCarrierInfoForImsiEncryption(context, subIds[0]);
Intent resetIntent = new Intent(TelephonyIntents.ACTION_CARRIER_CERTIFICATE_DOWNLOAD);
SubscriptionManager.putPhoneIdAndSubIdExtra(resetIntent, mPhoneId);
context.sendBroadcastAsUser(resetIntent, UserHandle.ALL);
@@ -264,12 +270,12 @@
* Deletes all the keys for a given Carrier from the device keystore.
* @param context Context
*/
- public static void deleteCarrierInfoForImsiEncryption(Context context) {
- Log.i(LOG_TAG, "deleting carrier key from db");
+ public static void deleteCarrierInfoForImsiEncryption(Context context, int subId) {
+ Log.i(LOG_TAG, "deleting carrier key from db for subId=" + subId);
String mcc = "";
String mnc = "";
- final TelephonyManager telephonyManager =
- (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+ final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class)
+ .createForSubscriptionId(subId);
String simOperator = telephonyManager.getSimOperator();
if (!TextUtils.isEmpty(simOperator)) {
mcc = simOperator.substring(0, 3);
diff --git a/src/java/com/android/internal/telephony/CarrierServiceStateTracker.java b/src/java/com/android/internal/telephony/CarrierServiceStateTracker.java
index 005ee71..64dc7ec 100644
--- a/src/java/com/android/internal/telephony/CarrierServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/CarrierServiceStateTracker.java
@@ -39,6 +39,7 @@
import android.telephony.TelephonyManager.NetworkTypeBitMask;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.util.ArrayUtils;
import com.android.internal.telephony.util.NotificationChannelController;
import com.android.telephony.Rlog;
@@ -272,8 +273,9 @@
Rlog.e(LOG_TAG, "isCarrierConfigEnableNr: Cannot get config " + mPhone.getSubId());
return false;
}
- return config.getInt(CarrierConfigManager.KEY_CARRIER_NR_AVAILABILITY_INT)
- != CarrierConfigManager.CARRIER_NR_AVAILABILITY_NONE;
+ int[] nrAvailabilities = config.getIntArray(
+ CarrierConfigManager.KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY);
+ return !ArrayUtils.isEmpty(nrAvailabilities);
}
private boolean checkSupportedBitmask(@NetworkTypeBitMask long supportedBitmask,
diff --git a/src/java/com/android/internal/telephony/CellBroadcastServiceManager.java b/src/java/com/android/internal/telephony/CellBroadcastServiceManager.java
index a991153..7045171 100644
--- a/src/java/com/android/internal/telephony/CellBroadcastServiceManager.java
+++ b/src/java/com/android/internal/telephony/CellBroadcastServiceManager.java
@@ -74,11 +74,27 @@
mPhone = phone;
}
+ private boolean cbMessagesDisabledByOem() {
+ if (mContext != null && mContext.getResources() != null) {
+ return mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_disable_all_cb_messages);
+ } else {
+ return false;
+ }
+ }
+
/**
* Send a GSM CB message to the CellBroadcastServiceManager's handler.
* @param m the message
*/
public void sendGsmMessageToHandler(Message m) {
+ if (cbMessagesDisabledByOem()) {
+ Log.d(TAG, "GSM CB message ignored - CB messages disabled by OEM.");
+ CellBroadcastStatsLog.write(CellBroadcastStatsLog.CB_MESSAGE_FILTERED,
+ CellBroadcastStatsLog.CELL_BROADCAST_MESSAGE_FILTERED__TYPE__GSM,
+ CellBroadcastStatsLog.CELL_BROADCAST_MESSAGE_FILTERED__FILTER__DISABLED_BY_OEM);
+ return;
+ }
m.what = EVENT_NEW_GSM_SMS_CB;
mModuleCellBroadcastHandler.sendMessage(m);
}
@@ -88,6 +104,13 @@
* @param sms the SmsMessage to forward
*/
public void sendCdmaMessageToHandler(SmsMessage sms) {
+ if (cbMessagesDisabledByOem()) {
+ Log.d(TAG, "CDMA CB message ignored - CB messages disabled by OEM.");
+ CellBroadcastStatsLog.write(CellBroadcastStatsLog.CB_MESSAGE_FILTERED,
+ CellBroadcastStatsLog.CELL_BROADCAST_MESSAGE_FILTERED__TYPE__CDMA,
+ CellBroadcastStatsLog.CELL_BROADCAST_MESSAGE_FILTERED__FILTER__DISABLED_BY_OEM);
+ return;
+ }
Message m = Message.obtain();
m.what = EVENT_NEW_CDMA_SMS_CB;
m.obj = sms;
@@ -99,6 +122,13 @@
* @param sms the SCP message
*/
public void sendCdmaScpMessageToHandler(SmsMessage sms, RemoteCallback callback) {
+ if (cbMessagesDisabledByOem()) {
+ Log.d(TAG, "CDMA SCP CB message ignored - CB messages disabled by OEM.");
+ CellBroadcastStatsLog.write(CellBroadcastStatsLog.CB_MESSAGE_FILTERED,
+ CellBroadcastStatsLog.CELL_BROADCAST_MESSAGE_FILTERED__TYPE__CDMA_SPC,
+ CellBroadcastStatsLog.CELL_BROADCAST_MESSAGE_FILTERED__FILTER__DISABLED_BY_OEM);
+ return;
+ }
Message m = Message.obtain();
m.what = EVENT_NEW_CDMA_SCP_MESSAGE;
m.obj = Pair.create(sms, callback);
diff --git a/src/java/com/android/internal/telephony/CellularNetworkService.java b/src/java/com/android/internal/telephony/CellularNetworkService.java
index 902ccd6..afbd381 100644
--- a/src/java/com/android/internal/telephony/CellularNetworkService.java
+++ b/src/java/com/android/internal/telephony/CellularNetworkService.java
@@ -33,9 +33,11 @@
import android.telephony.NetworkRegistrationInfo;
import android.telephony.NetworkService;
import android.telephony.NetworkServiceCallback;
+import android.telephony.NrVopsSupportInfo;
import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.telephony.VopsSupportInfo;
import android.text.TextUtils;
import com.android.telephony.Rlog;
@@ -476,9 +478,7 @@
boolean isEndcAvailable = false;
boolean isNrAvailable = false;
boolean isDcNrRestricted = false;
- LteVopsSupportInfo vopsInfo = new LteVopsSupportInfo(
- LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE,
- LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE);
+ VopsSupportInfo vopsInfo = null;
android.hardware.radio.V1_6.RegStateResult.AccessTechnologySpecificInfo info =
regResult.accessTechnologySpecificInfo;
@@ -498,6 +498,13 @@
info.eutranInfo().lteVopsInfo.isVopsSupported,
info.eutranInfo().lteVopsInfo.isEmcBearerSupported);
break;
+ case AccessTechnologySpecificInfo.hidl_discriminator.ngranInfo:
+ android.hardware.radio.V1_6.RegStateResult
+ .AccessTechnologySpecificInfo.NgranRegistrationInfo ngranInfo =
+ regResult.accessTechnologySpecificInfo.ngranInfo();
+ vopsInfo = new NrVopsSupportInfo(ngranInfo.nrVopsInfo.vopsSupported,
+ ngranInfo.nrVopsInfo.emcSupported, ngranInfo.nrVopsInfo.emfSupported);
+ break;
case AccessTechnologySpecificInfo.hidl_discriminator.geranInfo:
android.hardware.radio.V1_6.RegStateResult
.AccessTechnologySpecificInfo.GeranRegistrationInfo geranInfo =
diff --git a/src/java/com/android/internal/telephony/CommandsInterface.java b/src/java/com/android/internal/telephony/CommandsInterface.java
index 7c192ec..6ae0b1f 100644
--- a/src/java/com/android/internal/telephony/CommandsInterface.java
+++ b/src/java/com/android/internal/telephony/CommandsInterface.java
@@ -2649,4 +2649,12 @@
*/
default void setDataThrottling(Message result, WorkSource workSource,
int dataThrottlingAction, long completionWindowMillis) {};
+
+ /**
+ * Request to get the current slicing configuration including URSP rules and
+ * NSSAIs (configured, allowed and rejected).
+ *
+ * @param result Message that will be sent back to handler.
+ */
+ default void getSlicingConfig(Message result) {};
}
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index ae12749..494ca06 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -1889,7 +1889,7 @@
@Override
public void deleteCarrierInfoForImsiEncryption() {
- CarrierInfoManager.deleteCarrierInfoForImsiEncryption(mContext);
+ CarrierInfoManager.deleteCarrierInfoForImsiEncryption(mContext, getSubId());
}
@Override
@@ -4622,10 +4622,9 @@
loge("didn't get the carrier_nr_availability_int from the carrier config.");
return;
}
- mIsCarrierNrSupported = config.getInt(
- CarrierConfigManager.KEY_CARRIER_NR_AVAILABILITY_INT,
- CarrierConfigManager.CARRIER_NR_AVAILABILITY_NSA)
- != CarrierConfigManager.CARRIER_NR_AVAILABILITY_NONE;
+ int[] nrAvailabilities = config.getIntArray(
+ CarrierConfigManager.KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY);
+ mIsCarrierNrSupported = !ArrayUtils.isEmpty(nrAvailabilities);
}
private void updateCdmaRoamingSettingsAfterCarrierConfigChanged(PersistableBundle config) {
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index a12fec5..9d7444d 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -2698,6 +2698,18 @@
mCi.nvResetConfig(2 /* erase NV */, response);
}
+ /**
+ * Erase data saved in the SharedPreference. Used for network reset
+ *
+ */
+ public boolean eraseDataInSharedPreferences() {
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
+ SharedPreferences.Editor editor = sp.edit();
+ Rlog.d(LOG_TAG, "Erase all data saved in SharedPreferences");
+ editor.clear();
+ return editor.commit();
+ }
+
public void setSystemSelectionChannels(List<RadioAccessSpecifier> specifiers,
Message response) {
mCi.setSystemSelectionChannels(specifiers, response);
@@ -4763,6 +4775,14 @@
return mLinkBandwidthEstimator;
}
+ /**
+ * Request to get the current slicing configuration including URSP rules and
+ * NSSAIs (configured, allowed and rejected).
+ */
+ public void getSlicingConfig(Message response) {
+ mCi.getSlicingConfig(response);
+ }
+
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("Phone: subId=" + getSubId());
pw.println(" mPhoneId=" + mPhoneId);
diff --git a/src/java/com/android/internal/telephony/PhoneConfigurationManager.java b/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
index 82cf5fe..d92f96d 100644
--- a/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
+++ b/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
@@ -312,7 +312,7 @@
}
public int getNumberOfModemsWithSimultaneousDataConnections() {
- return mStaticCapability.getMaxActiveInternetData();
+ return mStaticCapability.getMaxActiveDataSubscriptions();
}
private void notifyCapabilityChanged() {
diff --git a/src/java/com/android/internal/telephony/RIL.java b/src/java/com/android/internal/telephony/RIL.java
index 9d02918..53f876c 100644
--- a/src/java/com/android/internal/telephony/RIL.java
+++ b/src/java/com/android/internal/telephony/RIL.java
@@ -1595,7 +1595,18 @@
if (RILJ_LOGD) {
riljLog("getVoiceRegistrationState: overrideHalVersion=" + overrideHalVersion);
}
+
if ((overrideHalVersion == null
+ || overrideHalVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6))
+ && mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+ final android.hardware.radio.V1_6.IRadio radioProxy16 =
+ (android.hardware.radio.V1_6.IRadio) radioProxy;
+ try {
+ radioProxy16.getVoiceRegistrationState_1_6(rr.mSerial);
+ } catch (RemoteException | RuntimeException e) {
+ handleRadioProxyExceptionForRR(rr, "getVoiceRegistrationState_1_6", e);
+ }
+ } else if ((overrideHalVersion == null
|| overrideHalVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5))
&& mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
final android.hardware.radio.V1_5.IRadio radioProxy15 =
@@ -1628,7 +1639,18 @@
if (RILJ_LOGD) {
riljLog("getDataRegistrationState: overrideHalVersion=" + overrideHalVersion);
}
+
if ((overrideHalVersion == null
+ || overrideHalVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6))
+ && mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+ final android.hardware.radio.V1_6.IRadio radioProxy16 =
+ (android.hardware.radio.V1_6.IRadio) radioProxy;
+ try {
+ radioProxy16.getDataRegistrationState_1_6(rr.mSerial);
+ } catch (RemoteException | RuntimeException e) {
+ handleRadioProxyExceptionForRR(rr, "getDataRegistrationState_1_6", e);
+ }
+ } else if ((overrideHalVersion == null
|| overrideHalVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5))
&& mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
final android.hardware.radio.V1_5.IRadio radioProxy15 =
@@ -1935,8 +1957,8 @@
new android.hardware.radio.V1_6.TrafficDescriptor();
OptionalDnn optionalDnn = new OptionalDnn();
- if (trafficDescriptor.getDnn() != null) {
- optionalDnn.value(trafficDescriptor.getDnn());
+ if (trafficDescriptor.getDataNetworkName() != null) {
+ optionalDnn.value(trafficDescriptor.getDataNetworkName());
}
td.dnn = optionalDnn;
@@ -5955,6 +5977,32 @@
}
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void getSlicingConfig(Message result) {
+ android.hardware.radio.V1_6.IRadio radioProxy16 = getRadioV16(result);
+
+ if (radioProxy16 != null) {
+ RILRequest rr = obtainRequest(RIL_REQUEST_GET_SLICING_CONFIG, result,
+ mRILDefaultWorkSource);
+
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
+ try {
+ radioProxy16.getSlicingConfig(rr.mSerial);
+ } catch (RemoteException | RuntimeException e) {
+ handleRadioProxyExceptionForRR(rr, "getSlicingConfig", e);
+ }
+ } else {
+ if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "getSlicingConfig: REQUEST_NOT_SUPPORTED");
+ AsyncResult.forMessage(result, null,
+ CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+ result.sendToTarget();
+ }
+ }
+
//***** Private Methods
/** Helper that gets V1.6 of the radio interface OR sends back REQUEST_NOT_SUPPORTED */
@Nullable private android.hardware.radio.V1_6.IRadio getRadioV16(Message msg) {
@@ -6932,6 +6980,8 @@
return "RIL_REQUEST_SET_ALLOWED_NETWORK_TYPE_BITMAP";
case RIL_REQUEST_GET_ALLOWED_NETWORK_TYPES_BITMAP:
return "RIL_REQUEST_GET_ALLOWED_NETWORK_TYPE_BITMAP";
+ case RIL_REQUEST_GET_SLICING_CONFIG:
+ return "RIL_REQUEST_GET_SLICING_CONFIG";
default: return "<unknown request>";
}
}
@@ -7659,7 +7709,14 @@
? null : td.dnn.value();
String osAppId = td.osAppId.getDiscriminator() == OptionalOsAppId.hidl_discriminator.noinit
? null : new String(arrayListToPrimitiveArray(td.osAppId.value().osAppId));
- return new TrafficDescriptor(dnn, osAppId);
+ TrafficDescriptor.Builder builder = new TrafficDescriptor.Builder();
+ if (dnn != null) {
+ builder.setDataNetworkName(dnn);
+ }
+ if (osAppId != null) {
+ builder.setOsAppId(osAppId);
+ }
+ return builder.build();
}
/**
diff --git a/src/java/com/android/internal/telephony/RadioConfig.java b/src/java/com/android/internal/telephony/RadioConfig.java
index 4cb61dc..32b24fe 100644
--- a/src/java/com/android/internal/telephony/RadioConfig.java
+++ b/src/java/com/android/internal/telephony/RadioConfig.java
@@ -16,7 +16,6 @@
package com.android.internal.telephony;
-import static android.telephony.PhoneCapability.DEVICE_NR_CAPABILITY_NONE;
import static android.telephony.PhoneCapability.DEVICE_NR_CAPABILITY_NSA;
import static android.telephony.PhoneCapability.DEVICE_NR_CAPABILITY_SA;
@@ -34,7 +33,6 @@
import android.hardware.radio.V1_0.RadioResponseType;
import android.hardware.radio.config.V1_0.IRadioConfig;
import android.hardware.radio.config.V1_1.ModemsConfig;
-import android.net.ConnectivityManager;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.HwBinder;
@@ -42,6 +40,7 @@
import android.os.Registrant;
import android.os.RemoteException;
import android.os.WorkSource;
+import android.telephony.TelephonyManager;
import android.util.SparseArray;
import com.android.internal.telephony.uicc.IccSlotStatus;
@@ -49,6 +48,7 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
import java.util.NoSuchElementException;
import java.util.concurrent.atomic.AtomicLong;
@@ -81,7 +81,7 @@
private final SparseArray<RILRequest> mRequestList = new SparseArray<RILRequest>();
/* default work source which will blame phone process */
private final WorkSource mDefaultWorkSource;
- private final int mDeviceNrCapability;
+ private final int[] mDeviceNrCapabilities;
private static RadioConfig sRadioConfig;
private static final Object sLock = new Object();
@@ -96,10 +96,16 @@
}
}
+ private boolean isMobileDataCapable(Context context) {
+ final TelephonyManager tm = context.getSystemService(TelephonyManager.class);
+ if (tm == null) {
+ return false;
+ }
+ return tm.isDataCapable();
+ }
+
private RadioConfig(Context context, HalVersion radioHalVersion) {
- ConnectivityManager cm = (ConnectivityManager) context.getSystemService(
- Context.CONNECTIVITY_SERVICE);
- mIsMobileNetworkSupported = cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
+ mIsMobileNetworkSupported = isMobileDataCapable(context);
mRadioConfigResponse = new RadioConfigResponse(this, radioHalVersion);
mRadioConfigIndication = new RadioConfigIndication(this);
@@ -112,9 +118,19 @@
com.android.internal.R.bool.config_telephony5gStandalone);
boolean is5gNonStandalone = context.getResources().getBoolean(
com.android.internal.R.bool.config_telephony5gNonStandalone);
- mDeviceNrCapability =
- (is5gStandalone ? DEVICE_NR_CAPABILITY_SA : DEVICE_NR_CAPABILITY_NONE) | (
- is5gNonStandalone ? DEVICE_NR_CAPABILITY_NSA : DEVICE_NR_CAPABILITY_NONE);
+
+ if (!is5gStandalone && !is5gNonStandalone) {
+ mDeviceNrCapabilities = new int[0];
+ } else {
+ List<Integer> list = new ArrayList<>();
+ if (is5gNonStandalone) {
+ list.add(DEVICE_NR_CAPABILITY_NSA);
+ }
+ if (is5gStandalone) {
+ list.add(DEVICE_NR_CAPABILITY_SA);
+ }
+ mDeviceNrCapabilities = list.stream().mapToInt(Integer::valueOf).toArray();
+ }
}
/**
@@ -573,8 +589,8 @@
/**
* Returns the device's nr capability.
*/
- public int getDeviceNrCapability() {
- return mDeviceNrCapability;
+ public int[] getDeviceNrCapabilities() {
+ return mDeviceNrCapabilities;
}
static ArrayList<IccSlotStatus> convertHalSlotStatus(
diff --git a/src/java/com/android/internal/telephony/RadioConfigResponse.java b/src/java/com/android/internal/telephony/RadioConfigResponse.java
index a640cb7..88e5e80 100644
--- a/src/java/com/android/internal/telephony/RadioConfigResponse.java
+++ b/src/java/com/android/internal/telephony/RadioConfigResponse.java
@@ -20,6 +20,8 @@
import static android.telephony.TelephonyManager
.CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE;
import static android.telephony.TelephonyManager.CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE;
+import static android.telephony.TelephonyManager.CAPABILITY_SLICING_CONFIG_SUPPORTED;
+import static android.telephony.TelephonyManager.CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING;
import static android.telephony.TelephonyManager.RadioInterfaceCapability;
import android.hardware.radio.V1_0.RadioError;
@@ -141,7 +143,7 @@
}
return new PhoneCapability(maxActiveVoiceCalls, maxActiveData, logicalModemList,
- validationBeforeSwitchSupported, mRadioConfig.getDeviceNrCapability());
+ validationBeforeSwitchSupported, mRadioConfig.getDeviceNrCapabilities());
}
/**
* Response function for IRadioConfig.getPhoneCapability().
@@ -306,6 +308,10 @@
Rlog.d(TAG, "CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE");
caps.add(CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE);
Rlog.d(TAG, "CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE");
+ caps.add(CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING);
+ Rlog.d(TAG, "CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING");
+ caps.add(CAPABILITY_SLICING_CONFIG_SUPPORTED);
+ Rlog.d(TAG, "CAPABILITY_SLICING_CONFIG_SUPPORTED");
}
}
return caps;
diff --git a/src/java/com/android/internal/telephony/RadioIndication.java b/src/java/com/android/internal/telephony/RadioIndication.java
index e3e188c..16d2fe0 100644
--- a/src/java/com/android/internal/telephony/RadioIndication.java
+++ b/src/java/com/android/internal/telephony/RadioIndication.java
@@ -87,6 +87,7 @@
import android.hardware.radio.V1_2.CellConnectionStatus;
import android.hardware.radio.V1_6.IRadioIndication;
import android.hardware.radio.V1_6.PhysicalChannelConfig.Band;
+import android.hardware.radio.V1_6.PhonebookRecordInfo;
import android.os.AsyncResult;
import android.os.RemoteException;
import android.sysprop.TelephonyProperties;
@@ -1072,6 +1073,26 @@
}
/**
+ * Indicates when the phonebook is changed.
+ *
+ * @param indicationType RadioIndicationType
+ */
+ public void simPhonebookChanged(int indicationType) {
+
+ }
+
+ /**
+ * Indicates the content of all the used records in the SIM phonebook.
+ *
+ * @param indicationType RadioIndicationType
+ * @param records Content of the SIM phonebook records
+ */
+ public void simPhonebookRecordsReceived(int indicationType, int status,
+ ArrayList<PhonebookRecordInfo> records) {
+
+ }
+
+ /**
* Indicate that a registration failure has occurred.
*
* @param cellIdentity a CellIdentity the CellIdentity of the Cell
diff --git a/src/java/com/android/internal/telephony/RadioResponse.java b/src/java/com/android/internal/telephony/RadioResponse.java
index f86b787..313ef0b 100644
--- a/src/java/com/android/internal/telephony/RadioResponse.java
+++ b/src/java/com/android/internal/telephony/RadioResponse.java
@@ -56,6 +56,7 @@
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.data.DataCallResponse;
+import android.telephony.data.SlicingConfig;
import android.text.TextUtils;
import com.android.internal.telephony.dataconnection.KeepaliveStatus;
@@ -1998,6 +1999,31 @@
return iccCardStatus;
}
+ /**
+ * @param info Response info struct containing response type, serial no. and error.
+ */
+ public void getSimPhonebookRecordsResponse(
+ android.hardware.radio.V1_6.RadioResponseInfo responseInfo) {
+ }
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error.
+ * @param pbCapacity Contains the adn, email, anr capacities in the sim card.
+ */
+ public void getSimPhonebookCapacityResponse(
+ android.hardware.radio.V1_6.RadioResponseInfo responseInfo,
+ android.hardware.radio.V1_6.PhonebookCapacity pbCapacity) {
+ }
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error.
+ * @param updatedRecordIndex The index of the updated record.
+ */
+ public void updateSimPhonebookRecordsResponse(
+ android.hardware.radio.V1_6.RadioResponseInfo responseInfo,
+ int updatedRecordIndex) {
+ }
+
private void responseIccCardStatus(RadioResponseInfo responseInfo, CardStatus cardStatus) {
RILRequest rr = mRil.processResponse(responseInfo);
@@ -3077,10 +3103,11 @@
RILRequest rr = mRil.processResponse_1_6(info);
if (rr != null) {
+ SlicingConfig ret = new SlicingConfig(slicingConfig);
if (info.error == RadioError.NONE) {
- sendMessageResponse(rr.mResult, slicingConfig);
+ sendMessageResponse(rr.mResult, ret);
}
- mRil.processResponseDone_1_6(rr, info, slicingConfig);
+ mRil.processResponseDone_1_6(rr, info, ret);
}
}
}
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index 9ba46cf..5807b54 100755
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -431,7 +431,6 @@
Context context = mPhone.getContext();
mPhone.notifyPhoneStateChanged();
- mPhone.notifyCallForwardingIndicator();
if (!SubscriptionManager.isValidSubscriptionId(mPrevSubId)) {
// just went from invalid to valid subId, so notify with current service
@@ -5073,6 +5072,7 @@
updateReportingCriteria(config);
updateOperatorNamePattern(config);
mCdnr.updateEfFromCarrierConfig(config);
+ mPhone.notifyCallForwardingIndicator();
// Sometimes the network registration information comes before carrier config is ready.
// For some cases like roaming/non-roaming overriding, we need carrier config. So it's
diff --git a/src/java/com/android/internal/telephony/SubscriptionController.java b/src/java/com/android/internal/telephony/SubscriptionController.java
index 781d4d1..1044169 100644
--- a/src/java/com/android/internal/telephony/SubscriptionController.java
+++ b/src/java/com/android/internal/telephony/SubscriptionController.java
@@ -1352,8 +1352,6 @@
setDisplayName = true;
Uri uri = insertEmptySubInfoRecord(uniqueId, slotIndex);
if (DBG) logdl("[addSubInfoRecord] New record created: " + uri);
- SubscriptionManager subManager = SubscriptionManager.from(mContext);
- subManager.restoreSimSpecificSettingsForIccIdFromBackup(uniqueId);
} else { // there are matching records in the database for the given ICC_ID
int subId = cursor.getInt(0);
int oldSimInfoId = cursor.getInt(1);
@@ -2139,6 +2137,45 @@
}
}
+ /**
+ * Set contacts that allow device to device status sharing.
+ * @param contacts contacts to set
+ * @param subscriptionId
+ * @return the number of records updated
+ */
+ @Override
+ public int setDeviceToDeviceStatusSharingContacts(String contacts, int subscriptionId) {
+ if (DBG) {
+ logd("[setDeviceToDeviceStatusSharingContacts]- contacts:" + contacts
+ + " subId:" + subscriptionId);
+ }
+
+ enforceModifyPhoneState("setDeviceToDeviceStatusSharingContacts");
+
+ // Now that all security checks passes, perform the operation as ourselves.
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ validateSubId(subscriptionId);
+ ContentValues value = new ContentValues(1);
+ value.put(SubscriptionManager.D2D_STATUS_SHARING_SELECTED_CONTACTS, contacts);
+ if (DBG) {
+ logd("[setDeviceToDeviceStatusSharingContacts]- contacts:" + contacts
+ + " set");
+ }
+
+ int result = updateDatabase(value, subscriptionId, true);
+
+ // Refresh the Cache of Active Subscription Info List
+ refreshCachedActiveSubscriptionInfoList();
+
+ notifySubscriptionInfoChanged();
+
+ return result;
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
public void syncGroupedSetting(int refSubId) {
logd("syncGroupedSetting");
try (Cursor cursor = mContext.getContentResolver().query(
@@ -3157,6 +3194,7 @@
case SubscriptionManager.ALLOWED_NETWORK_TYPES:
case SubscriptionManager.VOIMS_OPT_IN_STATUS:
case SubscriptionManager.D2D_STATUS_SHARING:
+ case SubscriptionManager.D2D_STATUS_SHARING_SELECTED_CONTACTS:
resultValue = cursor.getString(0);
break;
default:
diff --git a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
index 717e674..9132e5e 100644
--- a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
+++ b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
@@ -457,8 +457,10 @@
// At this phase, the subscription list is accessible. Treating NOT_READY
// as equivalent to ABSENT, once the rest of the system can handle it.
sIccId[phoneId] = ICCID_STRING_FOR_NO_SIM;
- updateSubscriptionInfoByIccId(phoneId, false /* updateEmbeddedSubs */);
+ } else {
+ sIccId[phoneId] = null;
}
+ updateSubscriptionInfoByIccId(phoneId, false /* updateEmbeddedSubs */);
broadcastSimStateChanged(phoneId, IccCardConstants.INTENT_VALUE_ICC_NOT_READY,
null);
@@ -579,15 +581,26 @@
* 2. ACTION_SIM_STATE_CHANGED/ACTION_SIM_CARD_STATE_CHANGED
* /ACTION_SIM_APPLICATION_STATE_CHANGED
* 3. ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED
- * 4. ACTION_CARRIER_CONFIG_CHANGED
+ * 4. restore sim-specific settings
+ * 5. ACTION_CARRIER_CONFIG_CHANGED
*/
broadcastSimStateChanged(phoneId, IccCardConstants.INTENT_VALUE_ICC_LOADED, null);
broadcastSimCardStateChanged(phoneId, TelephonyManager.SIM_STATE_PRESENT);
broadcastSimApplicationStateChanged(phoneId, TelephonyManager.SIM_STATE_LOADED);
updateSubscriptionCarrierId(phoneId, IccCardConstants.INTENT_VALUE_ICC_LOADED);
+ /* Sim-specific settings restore depends on knowing both the mccmnc and the carrierId of the
+ sim which is why it must be done after #updateSubscriptionCarrierId(). It is done before
+ carrier config update to avoid any race conditions with user settings that depend on
+ carrier config*/
+ restoreSimSpecificSettingsForPhone(phoneId);
updateCarrierServices(phoneId, IccCardConstants.INTENT_VALUE_ICC_LOADED);
}
+ private void restoreSimSpecificSettingsForPhone(int phoneId) {
+ SubscriptionManager subManager = SubscriptionManager.from(sContext);
+ subManager.restoreSimSpecificSettingsForIccIdFromBackup(sIccId[phoneId]);
+ }
+
private void updateCarrierServices(int phoneId, String simState) {
CarrierConfigManager configManager =
(CarrierConfigManager) sContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
@@ -707,7 +720,7 @@
mSubscriptionController.clearSubInfoRecord(phoneId);
// If SIM is not absent, insert new record or update existing record.
- if (!ICCID_STRING_FOR_NO_SIM.equals(sIccId[phoneId])) {
+ if (!ICCID_STRING_FOR_NO_SIM.equals(sIccId[phoneId]) && sIccId[phoneId] != null) {
logd("updateSubscriptionInfoByIccId: adding subscription info record: iccid: "
+ sIccId[phoneId] + ", phoneId:" + phoneId);
mSubscriptionManager.addSubscriptionInfoRecord(sIccId[phoneId], phoneId);
diff --git a/src/java/com/android/internal/telephony/d2d/MessageTypeAndValueHelper.java b/src/java/com/android/internal/telephony/d2d/MessageTypeAndValueHelper.java
new file mode 100644
index 0000000..2d36051
--- /dev/null
+++ b/src/java/com/android/internal/telephony/d2d/MessageTypeAndValueHelper.java
@@ -0,0 +1,97 @@
+/*
+ * 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.internal.telephony.d2d;
+
+import android.telecom.Connection;
+import android.telecom.DiagnosticCall;
+import android.telephony.TelephonyManager;
+
+import com.android.internal.telephony.BiMap;
+
+/**
+ * Helper class to map between the message types and values used in {@link Communicator} and those
+ * defined in the public API in {@link DiagnosticCall}.
+ */
+public class MessageTypeAndValueHelper {
+ // Maps between the local message and value types defined here and those defined in the
+ // DiagnosticCall class as part of the actual API.
+
+ /**
+ * Convert between the local message type (e.g.
+ * {@link Communicator#MESSAGE_CALL_RADIO_ACCESS_TYPE})
+ * and
+ * the ones referred to in {@link DiagnosticCall}.
+ */
+ public static final BiMap<Integer, Integer> MSG_TYPE_TO_DC_MSG_TYPE = new BiMap<>();
+
+ /**
+ * Convert between the local RAT type (e.g. {@link Communicator#RADIO_ACCESS_TYPE_IWLAN}) and
+ * the ones
+ * referred to by {@link DiagnosticCall#MESSAGE_CALL_NETWORK_TYPE}.
+ */
+ public static final BiMap<Integer, Integer> RAT_TYPE_TO_DC_NETWORK_TYPE = new BiMap<>();
+
+ /**
+ * Convert between the local codec (e.g. {@link Communicator#AUDIO_CODEC_AMR_WB}) and the ones
+ * referred to by {@link DiagnosticCall#MESSAGE_CALL_AUDIO_CODEC}.
+ */
+ public static final BiMap<Integer, Integer> CODEC_TO_DC_CODEC = new BiMap<>();
+
+ /**
+ * Convert between the local battery state (e.g. {@link Communicator#BATTERY_STATE_GOOD}) and
+ * the ones referred to by {@link DiagnosticCall#MESSAGE_DEVICE_BATTERY_STATE}.
+ */
+ public static final BiMap<Integer, Integer> BATTERY_STATE_TO_DC_BATTERY_STATE = new BiMap();
+
+ /**
+ * Convert between the local battery state (e.g. {@link Communicator#COVERAGE_GOOD}) and the
+ * ones referred to by {@link DiagnosticCall#MESSAGE_DEVICE_NETWORK_COVERAGE}.
+ */
+ public static final BiMap<Integer, Integer> COVERAGE_TO_DC_COVERAGE = new BiMap();
+
+ static {
+ MSG_TYPE_TO_DC_MSG_TYPE.put(Communicator.MESSAGE_CALL_RADIO_ACCESS_TYPE,
+ DiagnosticCall.MESSAGE_CALL_NETWORK_TYPE);
+ MSG_TYPE_TO_DC_MSG_TYPE.put(Communicator.MESSAGE_CALL_AUDIO_CODEC,
+ DiagnosticCall.MESSAGE_CALL_AUDIO_CODEC);
+ MSG_TYPE_TO_DC_MSG_TYPE.put(Communicator.MESSAGE_DEVICE_BATTERY_STATE,
+ DiagnosticCall.MESSAGE_DEVICE_BATTERY_STATE);
+ MSG_TYPE_TO_DC_MSG_TYPE.put(Communicator.MESSAGE_DEVICE_NETWORK_COVERAGE,
+ DiagnosticCall.MESSAGE_DEVICE_NETWORK_COVERAGE);
+
+ RAT_TYPE_TO_DC_NETWORK_TYPE.put(Communicator.RADIO_ACCESS_TYPE_LTE,
+ TelephonyManager.NETWORK_TYPE_LTE);
+ RAT_TYPE_TO_DC_NETWORK_TYPE.put(Communicator.RADIO_ACCESS_TYPE_IWLAN,
+ TelephonyManager.NETWORK_TYPE_IWLAN);
+ RAT_TYPE_TO_DC_NETWORK_TYPE.put(Communicator.RADIO_ACCESS_TYPE_NR,
+ TelephonyManager.NETWORK_TYPE_NR);
+
+ CODEC_TO_DC_CODEC.put(Communicator.AUDIO_CODEC_EVS, Connection.AUDIO_CODEC_EVS_WB);
+ CODEC_TO_DC_CODEC.put(Communicator.AUDIO_CODEC_AMR_WB, Connection.AUDIO_CODEC_AMR_WB);
+ CODEC_TO_DC_CODEC.put(Communicator.AUDIO_CODEC_AMR_NB, Connection.AUDIO_CODEC_AMR);
+
+ BATTERY_STATE_TO_DC_BATTERY_STATE.put(Communicator.BATTERY_STATE_LOW,
+ DiagnosticCall.BATTERY_STATE_LOW);
+ BATTERY_STATE_TO_DC_BATTERY_STATE.put(Communicator.BATTERY_STATE_GOOD,
+ DiagnosticCall.BATTERY_STATE_GOOD);
+ BATTERY_STATE_TO_DC_BATTERY_STATE.put(Communicator.BATTERY_STATE_CHARGING,
+ DiagnosticCall.BATTERY_STATE_CHARGING);
+
+ COVERAGE_TO_DC_COVERAGE.put(Communicator.COVERAGE_POOR, DiagnosticCall.COVERAGE_POOR);
+ COVERAGE_TO_DC_COVERAGE.put(Communicator.COVERAGE_GOOD, DiagnosticCall.COVERAGE_GOOD);
+ }
+}
diff --git a/src/java/com/android/internal/telephony/dataconnection/ApnContext.java b/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
index f0e9f12..eeb4bd3 100644
--- a/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
+++ b/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
@@ -450,12 +450,10 @@
synchronized (mRefCountLock) {
for (NetworkRequest nr : mNetworkRequests) {
if (excludeDun &&
- nr.networkCapabilities.hasCapability(
- NetworkCapabilities.NET_CAPABILITY_DUN)) {
+ nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
continue;
}
- if (!nr.networkCapabilities.hasCapability(
- NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)) {
+ if (!nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)) {
return true;
}
}
@@ -534,10 +532,9 @@
}
static @ApnType int getApnTypeFromNetworkRequest(NetworkRequest nr) {
- NetworkCapabilities nc = nr.networkCapabilities;
// For now, ignore the bandwidth stuff
- if (nc.getTransportTypes().length > 0 &&
- nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) == false) {
+ if (nr.getTransportTypes().length > 0
+ && !nr.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
return ApnSetting.TYPE_NONE;
}
@@ -546,50 +543,50 @@
int apnType = ApnSetting.TYPE_NONE;
boolean error = false;
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
+ if (nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
apnType = ApnSetting.TYPE_DEFAULT;
}
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
+ if (nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
if (apnType != ApnSetting.TYPE_NONE) error = true;
apnType = ApnSetting.TYPE_MMS;
}
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
+ if (nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
if (apnType != ApnSetting.TYPE_NONE) error = true;
apnType = ApnSetting.TYPE_SUPL;
}
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
+ if (nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
if (apnType != ApnSetting.TYPE_NONE) error = true;
apnType = ApnSetting.TYPE_DUN;
}
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
+ if (nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
if (apnType != ApnSetting.TYPE_NONE) error = true;
apnType = ApnSetting.TYPE_FOTA;
}
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
+ if (nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
if (apnType != ApnSetting.TYPE_NONE) error = true;
apnType = ApnSetting.TYPE_IMS;
}
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
+ if (nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
if (apnType != ApnSetting.TYPE_NONE) error = true;
apnType = ApnSetting.TYPE_CBS;
}
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_IA)) {
+ if (nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_IA)) {
if (apnType != ApnSetting.TYPE_NONE) error = true;
apnType = ApnSetting.TYPE_IA;
}
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)) {
+ if (nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)) {
if (apnType != ApnSetting.TYPE_NONE) error = true;
apnType = ApnSetting.TYPE_EMERGENCY;
}
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_MCX)) {
+ if (nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_MCX)) {
if (apnType != ApnSetting.TYPE_NONE) error = true;
apnType = ApnSetting.TYPE_MCX;
}
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_XCAP)) {
+ if (nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_XCAP)) {
if (apnType != ApnSetting.TYPE_NONE) error = true;
apnType = ApnSetting.TYPE_XCAP;
}
- if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)) {
+ if (nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)) {
if (apnType != ApnSetting.TYPE_NONE) error = true;
apnType = ApnSetting.TYPE_ENTERPRISE;
}
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
index 0737ab3..c2ae9ce 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
@@ -99,6 +99,7 @@
import com.android.internal.util.Protocol;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
+import com.android.net.module.util.NetworkCapabilitiesUtils;
import com.android.telephony.Rlog;
import java.io.FileDescriptor;
@@ -111,6 +112,7 @@
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.Map;
@@ -570,7 +572,9 @@
ERROR_RADIO_NOT_AVAILABLE,
ERROR_INVALID_ARG,
ERROR_STALE,
- ERROR_DATA_SERVICE_SPECIFIC_ERROR;
+ ERROR_DATA_SERVICE_SPECIFIC_ERROR,
+ ERROR_DUPLICATE_CID,
+ ERROR_NO_DEFAULT_CONNECTION;
public int mFailCause;
@@ -643,7 +647,7 @@
public void updateQosParameters(final @Nullable DataCallResponse response) {
if (response == null) {
mDefaultQos = null;
- mQosBearerSessions = null;
+ mQosBearerSessions.clear();
return;
}
@@ -886,8 +890,8 @@
String dnn = null;
String osAppId = null;
if (cp.mApnContext.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE) {
- // TODO: update osAppId to use NetworkCapability API once it's available
- osAppId = ApnSetting.getApnTypesStringFromBitmask(mApnSetting.getApnTypeBitmask());
+ osAppId = NetworkCapabilities.getCapabilityCarrierName(
+ NetworkCapabilities.NET_CAPABILITY_ENTERPRISE);
} else {
dnn = mApnSetting.getApnName();
}
@@ -1316,6 +1320,7 @@
mApnContexts.clear();
mApnSetting = null;
mUnmeteredUseOnly = false;
+ mEnterpriseUse = false;
mRestrictedNetworkOverride = false;
mDcFailCause = DataFailCause.NONE;
mDisabledApnTypeBitMask = 0;
@@ -1327,6 +1332,10 @@
mIsSuspended = false;
mHandoverState = HANDOVER_STATE_IDLE;
mHandoverFailureMode = DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN;
+ mSliceInfo = null;
+ mDefaultQos = null;
+ mQosBearerSessions.clear();
+ mTrafficDescriptors.clear();
}
/**
@@ -1359,6 +1368,14 @@
result = SetupResult.ERROR_DATA_SERVICE_SPECIFIC_ERROR;
result.mFailCause = DataFailCause.getFailCause(response.getCause());
}
+ } else if (cp.mApnContext.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE
+ && mDcController.getActiveDcByCid(response.getId()) != null) {
+ if (DBG) log("DataConnection already exists for cid: " + response.getId());
+ result = SetupResult.ERROR_DUPLICATE_CID;
+ } else if (cp.mApnContext.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE
+ && !mDcController.isDefaultDataActive()) {
+ if (DBG) log("No default data connection currently active");
+ result = SetupResult.ERROR_NO_DEFAULT_CONNECTION;
} else {
if (DBG) log("onSetupConnectionCompleted received successful DataCallResponse");
mCid = response.getId();
@@ -1580,9 +1597,20 @@
log("updateLinkBandwidthsFromBandwidthEstimator, UL= "
+ uplinkBandwidthKbps + " DL= " + downlinkBandwidthKbps);
}
- mDownlinkBandwidth = downlinkBandwidthKbps;
- mUplinkBandwidth = uplinkBandwidthKbps;
+ boolean downlinkUpdated = false;
+ boolean uplinkUpdated = false;
+ if (downlinkBandwidthKbps > 0) {
+ mDownlinkBandwidth = downlinkBandwidthKbps;
+ downlinkUpdated = true;
+ }
+ if (uplinkBandwidthKbps > 0) {
+ mUplinkBandwidth = uplinkBandwidthKbps;
+ uplinkUpdated = true;
+ }
+ if (!downlinkUpdated || !uplinkUpdated) {
+ fallBackToCarrierConfigValues(downlinkUpdated, uplinkUpdated);
+ }
if (mNetworkAgent != null) {
mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), DataConnection.this);
}
@@ -1648,13 +1676,20 @@
private boolean mRestrictedNetworkOverride = false;
/**
+ * Indicates if this data connection supports enterprise use. Note that this flag should be
+ * populated when data becomes active. Once it is set, the value cannot be changed because
+ * setting it will cause this data connection to lose immutable network capabilities, which can
+ * cause issues in connectivity service.
+ */
+ private boolean mEnterpriseUse = false;
+
+ /**
* Check if this data connection should be restricted. We should call this when data connection
* becomes active, or when we want to re-evaluate the conditions to decide if we need to
* unstrict the data connection.
*
* @return True if this data connection needs to be restricted.
*/
-
private boolean shouldRestrictNetwork() {
// first, check if there is any network request that containing restricted capability
// (i.e. Do not have NET_CAPABILITY_NOT_RESTRICTED in the request)
@@ -1725,6 +1760,25 @@
}
/**
+ * Check if this data connection supports enterprise use. We call this when the data connection
+ * becomes active or when we want to reevaluate the conditions to decide if we need to update
+ * the network agent capabilities.
+ *
+ * @return True if this data connection supports enterprise use.
+ */
+ private boolean isEnterpriseUse() {
+ boolean enterpriseTrafficDescriptor = mTrafficDescriptors
+ .stream()
+ .anyMatch(td -> td.getOsAppId() != null && td.getOsAppId().equals(
+ NetworkCapabilities.getCapabilityCarrierName(
+ NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)));
+ boolean enterpriseApnContext = mApnContexts.keySet()
+ .stream()
+ .anyMatch(ac -> ac.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE);
+ return enterpriseTrafficDescriptor || enterpriseApnContext;
+ }
+
+ /**
* Get the network capabilities for this data connection.
*
* @return the {@link NetworkCapabilities} of this data connection.
@@ -1733,8 +1787,9 @@
final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
boolean hasInternet = false;
+ boolean unmeteredApns = false;
- if (mApnSetting != null) {
+ if (mApnSetting != null && !mEnterpriseUse) {
final String[] types = ApnSetting.getApnTypesStringFromBitmask(
mApnSetting.getApnTypeBitmask() & ~mDisabledApnTypeBitMask).split(",");
for (String type : types) {
@@ -1808,26 +1863,26 @@
builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
}
- // Mark NOT_METERED in the following cases:
- // 1. All APNs in the APN settings are unmetered.
- // 2. The non-restricted data is intended for unmetered use only.
- if ((mUnmeteredUseOnly && !mRestrictedNetworkOverride)
- || !ApnSettingUtils.isMetered(mApnSetting, mPhone)) {
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
- } else {
- builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
- }
-
- // TODO: Need to remove the use of hidden API deduceRestrictedCapability
- if (builder.build().deduceRestrictedCapability()) {
- builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+ if (!ApnSettingUtils.isMetered(mApnSetting, mPhone)) {
+ unmeteredApns = true;
}
}
- for (ApnContext ctx : mApnContexts.keySet()) {
- if (ctx.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE) {
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE);
- }
+ // Mark NOT_METERED in the following cases:
+ // 1. All APNs in the APN settings are unmetered.
+ // 2. The non-restricted data is intended for unmetered use only.
+ if (unmeteredApns || (mUnmeteredUseOnly && !mRestrictedNetworkOverride)) {
+ builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
+ } else {
+ builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
+ }
+
+ if (NetworkCapabilitiesUtils.inferRestrictedCapability(builder.build())) {
+ builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+ }
+
+ if (mEnterpriseUse) {
+ builder.addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE);
}
if (mRestrictedNetworkOverride) {
@@ -1841,6 +1896,7 @@
builder.setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
.setSubscriptionId(mSubId).build());
+ builder.setSubIds(Collections.singleton(mSubId));
if (!mPhone.getServiceState().getDataRoaming()) {
builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
@@ -2560,6 +2616,12 @@
DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN);
transitionTo(mInactiveState);
break;
+ case ERROR_DUPLICATE_CID:
+ // TODO (b/180988471): Properly handle the case when an existing cid is
+ // returned by tearing down the network agent if enterprise changed.
+ case ERROR_NO_DEFAULT_CONNECTION:
+ // TODO (b/180988471): Properly handle the case when a default data
+ // connection doesn't exist.
case ERROR_INVALID_ARG:
// The addresses given from the RIL are bad
tearDownData(cp);
@@ -2671,6 +2733,9 @@
final NetworkAgentConfig.Builder configBuilder = new NetworkAgentConfig.Builder();
configBuilder.setLegacyType(ConnectivityManager.TYPE_MOBILE);
configBuilder.setLegacyTypeName(NETWORK_TYPE);
+ int networkType = getNetworkType();
+ configBuilder.setLegacySubType(networkType);
+ configBuilder.setLegacySubTypeName(TelephonyManager.getNetworkTypeName(networkType));
configBuilder.setLegacyExtraInfo(mApnSetting.getApnName());
final CarrierSignalAgent carrierSignalAgent = mPhone.getCarrierSignalAgent();
if (carrierSignalAgent.hasRegisteredReceivers(TelephonyManager
@@ -2690,10 +2755,12 @@
}
mUnmeteredUseOnly = isUnmeteredUseOnly();
+ mEnterpriseUse = isEnterpriseUse();
if (DBG) {
log("mRestrictedNetworkOverride = " + mRestrictedNetworkOverride
- + ", mUnmeteredUseOnly = " + mUnmeteredUseOnly);
+ + ", mUnmeteredUseOnly = " + mUnmeteredUseOnly
+ + ", mEnterpriseUse = " + mEnterpriseUse);
}
// Always register a VcnNetworkPolicyChangeListener, regardless of whether this is a
@@ -3039,7 +3106,7 @@
if (handle < 0) {
loge("No slot found for stopSocketKeepalive! " + slotId);
mNetworkAgent.sendSocketKeepaliveEvent(
- slotId, SocketKeepalive.NO_KEEPALIVE);
+ slotId, SocketKeepalive.ERROR_NO_SUCH_SLOT);
retVal = HANDLED;
break;
} else {
@@ -3813,6 +3880,7 @@
pw.println("mUserData=" + mUserData);
pw.println("mRestrictedNetworkOverride=" + mRestrictedNetworkOverride);
pw.println("mUnmeteredUseOnly=" + mUnmeteredUseOnly);
+ pw.println("mEnterpriseUse=" + mEnterpriseUse);
pw.println("mUnmeteredOverride=" + mUnmeteredOverride);
pw.println("mCongestedOverride=" + mCongestedOverride);
pw.println("mDownlinkBandwidth" + mDownlinkBandwidth);
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcController.java b/src/java/com/android/internal/telephony/dataconnection/DcController.java
index a4241c7..edf71b3 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcController.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcController.java
@@ -26,6 +26,7 @@
import android.os.RegistrantList;
import android.telephony.AccessNetworkConstants;
import android.telephony.DataFailCause;
+import android.telephony.data.ApnSetting;
import android.telephony.data.DataCallResponse;
import com.android.internal.telephony.DctConstants;
@@ -161,6 +162,14 @@
}
}
+ boolean isDefaultDataActive() {
+ synchronized (mDcListAll) {
+ return mDcListActiveByCid.values().stream()
+ .anyMatch(dc -> dc.getApnContexts().stream()
+ .anyMatch(apn -> apn.getApnTypeBitmask() == ApnSetting.TYPE_DEFAULT));
+ }
+ }
+
@Override
public void handleMessage(Message msg) {
AsyncResult ar;
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcNetworkAgent.java b/src/java/com/android/internal/telephony/dataconnection/DcNetworkAgent.java
index 9ef3569..8d63563 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcNetworkAgent.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcNetworkAgent.java
@@ -26,6 +26,7 @@
import android.net.NetworkCapabilities;
import android.net.NetworkProvider;
import android.net.QosFilter;
+import android.net.QosSessionAttributes;
import android.net.SocketKeepalive;
import android.net.Uri;
import android.os.Message;
@@ -36,7 +37,7 @@
import android.telephony.NetworkRegistrationInfo;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
-import android.telephony.data.EpsBearerQosSessionAttributes;
+import android.telephony.data.NrQosSessionAttributes;
import android.telephony.data.QosBearerSession;
import android.util.ArrayMap;
import android.util.LocalLog;
@@ -106,9 +107,6 @@
mNetworkCapabilities = dc.getNetworkCapabilities();
mTransportType = transportType;
mDataConnection = dc;
- int networkType = getNetworkType();
- setLegacySubtype(networkType, TelephonyManager.getNetworkTypeName(networkType));
- setLegacyExtraInfo(dc.getApnSetting().getApnName());
if (dc.getLinkProperties() != null) {
checkDuplicateInterface(mId, dc.getLinkProperties().getInterfaceName());
logd("created for data connection " + dc.getName() + ", "
@@ -378,12 +376,13 @@
}
public void notifyQosSessionAvailable(final int qosCallbackId, final int sessionId,
- @NonNull final EpsBearerQosSessionAttributes attributes) {
+ @NonNull final QosSessionAttributes attributes) {
super.sendQosSessionAvailable(qosCallbackId, sessionId, attributes);
}
- public void notifyQosSessionLost(final int qosCallbackId, final int sessionId) {
- super.sendQosSessionLost(qosCallbackId, sessionId);
+ public void notifyQosSessionLost(final int qosCallbackId,
+ final int sessionId, final int qosSessionType) {
+ super.sendQosSessionLost(qosCallbackId, sessionId, qosSessionType);
}
@Override
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
index 7f6f306..16fdbb2 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
@@ -32,6 +32,8 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AlarmManager;
+import android.app.Notification;
+import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
@@ -62,6 +64,7 @@
import android.os.RegistrantList;
import android.os.SystemClock;
import android.os.SystemProperties;
+import android.os.UserHandle;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
@@ -99,6 +102,7 @@
import android.util.SparseArray;
import android.view.WindowManager;
+import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.DctConstants;
import com.android.internal.telephony.EventLogTags;
@@ -118,6 +122,7 @@
import com.android.internal.telephony.metrics.DataStallRecoveryStats;
import com.android.internal.telephony.metrics.TelephonyMetrics;
import com.android.internal.telephony.util.ArrayUtils;
+import com.android.internal.telephony.util.NotificationChannelController;
import com.android.internal.telephony.util.TelephonyUtils;
import com.android.internal.util.AsyncChannel;
import com.android.telephony.Rlog;
@@ -149,6 +154,7 @@
private static final boolean VDBG = false; // STOPSHIP if true
private static final boolean VDBG_STALL = false; // STOPSHIP if true
private static final boolean RADIO_TESTS = false;
+ private static final String NOTIFICATION_TAG = DcTracker.class.getSimpleName();
@IntDef(value = {
REQUEST_TYPE_NORMAL,
@@ -255,6 +261,9 @@
private static final String INTENT_DATA_STALL_ALARM_EXTRA_TRANSPORT_TYPE =
"data_stall_alarm_extra_transport_type";
+ // Unique id for no data notification on setup data permanently failed.
+ private static final int NO_DATA_NOTIFICATION = 1001;
+
/** The higher index has higher priority. */
private static final DctConstants.State[] DATA_CONNECTION_STATE_PRIORITIES = {
DctConstants.State.IDLE,
@@ -2304,9 +2313,13 @@
protected void startReconnect(long delay, ApnContext apnContext,
@RequestNetworkType int requestType) {
+ apnContext.setState(DctConstants.State.RETRYING);
Message msg = obtainMessage(DctConstants.EVENT_DATA_RECONNECT,
mPhone.getSubId(), requestType, apnContext);
cancelReconnect(apnContext);
+
+ // Wait a bit before trying the next APN, so that
+ // we're not tying up the RIL command channel
sendMessageDelayed(msg, delay);
if (DBG) {
@@ -2919,6 +2932,16 @@
startNetStatPoll();
startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
+
+ PersistableBundle b = getCarrierConfig();
+ if (apnContext.getApnTypeBitmask() == ApnSetting.TYPE_DEFAULT
+ && b.getBoolean(CarrierConfigManager
+ .KEY_DISPLAY_NO_DATA_NOTIFICATION_ON_PERMANENT_FAILURE_BOOL)) {
+ NotificationManager notificationManager = (NotificationManager)
+ mPhone.getContext().getSystemService(Context.NOTIFICATION_SERVICE);
+ notificationManager.cancel(Integer.toString(mPhone.getSubId()),
+ NO_DATA_NOTIFICATION);
+ }
}
/**
@@ -2994,10 +3017,13 @@
mPhone.getContext().unregisterReceiver(mProvisionBroadcastReceiver);
mProvisionBroadcastReceiver = null;
}
+
if ((!isProvApn) || mIsProvisioning) {
- // Hide any provisioning notification.
- cm.setProvisioningNotificationVisible(false, ConnectivityManager.TYPE_MOBILE,
- INTENT_PROVISION + ":" + mPhone.getPhoneId());
+ if (mIsProvisioning) {
+ // Hide any notification that was showing previously
+ hideProvisioningNotification();
+ }
+
// Complete the connection normally notifying the world we're connected.
// We do this if this isn't a special provisioning apn or if we've been
// told its time to provision.
@@ -3021,9 +3047,10 @@
mTelephonyManager.getNetworkOperatorName());
mPhone.getContext().registerReceiver(mProvisionBroadcastReceiver,
new IntentFilter(INTENT_PROVISION));
+
// Put up user notification that sign-in is required.
- cm.setProvisioningNotificationVisible(true, ConnectivityManager.TYPE_MOBILE,
- INTENT_PROVISION + ":" + mPhone.getPhoneId());
+ showProvisioningNotification();
+
// Turn off radio to save battery and avoid wasting carrier resources.
// The network isn't usable and network validation will just fail anyhow.
setRadio(false);
@@ -3085,6 +3112,34 @@
log("cause=" + DataFailCause.toString(cause)
+ ", mark apn as permanent failed. apn = " + apn);
apnContext.markApnPermanentFailed(apn);
+
+ PersistableBundle b = getCarrierConfig();
+ if (apnContext.getApnTypeBitmask() == ApnSetting.TYPE_DEFAULT
+ && b.getBoolean(CarrierConfigManager
+ .KEY_DISPLAY_NO_DATA_NOTIFICATION_ON_PERMANENT_FAILURE_BOOL)) {
+ NotificationManager notificationManager = (NotificationManager)
+ mPhone.getContext().getSystemService(Context.NOTIFICATION_SERVICE);
+
+ CharSequence title = mPhone.getContext().getText(
+ com.android.internal.R.string.RestrictedOnDataTitle);
+ CharSequence details = mPhone.getContext().getText(
+ com.android.internal.R.string.RestrictedStateContent);
+
+ Notification notification = new Notification.Builder(mPhone.getContext(),
+ NotificationChannelController.CHANNEL_ID_MOBILE_DATA_STATUS)
+ .setWhen(System.currentTimeMillis())
+ .setAutoCancel(true)
+ .setSmallIcon(com.android.internal.R.drawable.stat_sys_warning)
+ .setTicker(title)
+ .setColor(mPhone.getContext().getResources().getColor(
+ com.android.internal.R.color.system_notification_accent_color))
+ .setContentTitle(title)
+ .setStyle(new Notification.BigTextStyle().bigText(details))
+ .setContentText(details)
+ .build();
+ notificationManager.notify(Integer.toString(mPhone.getSubId()),
+ NO_DATA_NOTIFICATION, notification);
+ }
}
int newRequestType = calculateNewRetryRequestType(handoverFailureMode, requestType,
@@ -3111,10 +3166,6 @@
+ ". Request type=" + requestTypeToString(requestType) + ", Retry in "
+ delay + "ms.");
}
- apnContext.setState(DctConstants.State.RETRYING);
- // Wait a bit before trying the next APN, so that
- // we're not tying up the RIL command channel
-
startReconnect(delay, apnContext, requestType);
} else {
// If we are not going to retry any APN, set this APN context to failed state.
@@ -4086,10 +4137,6 @@
for (DataConnection dc : mDataConnections.values()) {
dc.sendMessage(DataConnection.EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED);
}
- if (mPhone.getLinkBandwidthEstimator() != null) {
- mPhone.getLinkBandwidthEstimator().sendMessage(obtainMessage(
- LinkBandwidthEstimator.MSG_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED));
- }
}
/**
@@ -4387,7 +4434,7 @@
boolean isNrNsa = (networkType == TelephonyManager.NETWORK_TYPE_LTE
|| networkType == TelephonyManager.NETWORK_TYPE_LTE_CA)
&& (overrideNetworkType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA
- || overrideNetworkType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE);
+ || overrideNetworkType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED);
boolean is5GHysteresisActive = mPhone.getDisplayInfoController().is5GHysteresisActive();
// True if device is on NR SA or NR NSA, or neither but 5G hysteresis is active
@@ -5339,6 +5386,9 @@
cleanUpAllConnectionsInternal(false, Phone.REASON_IWLAN_DATA_SERVICE_DIED);
}
}
+ } else {
+ //reset throttling after binding to data service
+ mDataThrottler.reset();
}
mDataServiceBound = bound;
}
@@ -5472,4 +5522,49 @@
public @NonNull DataThrottler getDataThrottler() {
return mDataThrottler;
}
+
+ private void showProvisioningNotification() {
+ final Intent intent = new Intent(DcTracker.INTENT_PROVISION);
+ intent.putExtra(DcTracker.EXTRA_PROVISION_PHONE_ID, mPhone.getPhoneId());
+ final PendingIntent pendingIntent = PendingIntent.getBroadcast(
+ mPhone.getContext(), 0 /* requestCode */, intent, PendingIntent.FLAG_IMMUTABLE);
+
+ final Resources r = mPhone.getContext().getResources();
+ final String title = r.getString(R.string.network_available_sign_in, 0);
+ final String details = mTelephonyManager.getNetworkOperator(mPhone.getSubId());
+ final Notification.Builder builder = new Notification.Builder(mPhone.getContext())
+ .setWhen(System.currentTimeMillis())
+ .setSmallIcon(R.drawable.stat_notify_rssi_in_range)
+ .setChannelId(NotificationChannelController.CHANNEL_ID_MOBILE_DATA_STATUS)
+ .setAutoCancel(true)
+ .setTicker(title)
+ .setColor(mPhone.getContext().getColor(
+ com.android.internal.R.color.system_notification_accent_color))
+ .setContentTitle(title)
+ .setContentText(details)
+ .setContentIntent(pendingIntent)
+ .setLocalOnly(true)
+ .setOnlyAlertOnce(true);
+
+ final Notification notification = builder.build();
+ try {
+ getNotificationManager().notify(NOTIFICATION_TAG, mPhone.getPhoneId(), notification);
+ } catch (final NullPointerException npe) {
+ Log.e(mLogTag, "showProvisioningNotification: error showing notification", npe);
+ }
+ }
+
+ private void hideProvisioningNotification() {
+ try {
+ getNotificationManager().cancel(NOTIFICATION_TAG, mPhone.getPhoneId());
+ } catch (final NullPointerException npe) {
+ Log.e(mLogTag, "hideProvisioningNotification: error hiding notification", npe);
+ }
+ }
+
+ private NotificationManager getNotificationManager() {
+ return (NotificationManager) mPhone.getContext()
+ .createContextAsUser(UserHandle.ALL, 0 /* flags */)
+ .getSystemService(Context.NOTIFICATION_SERVICE);
+ }
}
diff --git a/src/java/com/android/internal/telephony/dataconnection/LinkBandwidthEstimator.java b/src/java/com/android/internal/telephony/dataconnection/LinkBandwidthEstimator.java
index c60759e..100b1b9 100644
--- a/src/java/com/android/internal/telephony/dataconnection/LinkBandwidthEstimator.java
+++ b/src/java/com/android/internal/telephony/dataconnection/LinkBandwidthEstimator.java
@@ -21,14 +21,17 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
+import android.content.SharedPreferences;
import android.hardware.display.DisplayManager;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
+import android.os.AsyncResult;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.Message;
import android.os.OutcomeReceiver;
+import android.preference.PreferenceManager;
import android.telephony.AccessNetworkConstants;
import android.telephony.CellIdentity;
import android.telephony.CellIdentityGsm;
@@ -81,7 +84,6 @@
static final int MSG_NR_FREQUENCY_CHANGED = 6;
@VisibleForTesting
static final int MSG_NR_STATE_CHANGED = 7;
- static final int MSG_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED = 8;
// TODO: move the following parameters to xml file
private static final int TRAFFIC_STATS_POLL_INTERVAL_MS = 1_000;
@@ -91,8 +93,10 @@
private static final int BYTE_DELTA_ACC_THRESHOLD_MAX_KB = 5_000;
private static final int MODEM_POLL_TIME_DELTA_MAX_MS = 15_000;
private static final int FILTER_UPDATE_MAX_INTERVAL_MS = 5_100;
+ // BW samples with Tx or Rx time below the following value is ignored.
+ private static final int TX_RX_TIME_MIN_MS = 200;
// The large time constant used in BW filter
- private static final int TIME_CONSTANT_LARGE_SEC = 30;
+ private static final int TIME_CONSTANT_LARGE_SEC = 6;
// The small time constant used in BW filter
private static final int TIME_CONSTANT_SMALL_SEC = 6;
// If RSSI changes by more than the below value, update BW filter with small time constant
@@ -105,20 +109,32 @@
// over Rx time ratio is above the following value, use Tx time + Rx time as Rx time.
private static final int TX_OVER_RX_TIME_RATIO_THRESHOLD_NUM = 3;
private static final int TX_OVER_RX_TIME_RATIO_THRESHOLD_DEN = 2;
- // Default Link bandwidth value if the RAT entry is not found in carrier config table.
+ // Default Link bandwidth value if the RAT entry is not found in static BW table.
private static final int DEFAULT_LINK_BAND_WIDTH_KBPS = 14;
// If Tx or Rx link bandwidth change is above the following value, send the BW update
- private static final int BW_UPDATE_THRESHOLD_PERCENT = 40;
+ private static final int BW_UPDATE_THRESHOLD_PERCENT = 15;
// To be used in link bandwidth estimation, each TrafficStats poll sample needs to be above
// a predefine threshold.
- // For RAT with carrier config above HIGH_BANDWIDTH_THRESHOLD_KBPS, it uses the following table.
- // For others RATs, the thresholds are derived from the default carrier config BW values.
+ // For RAT with static BW above HIGH_BANDWIDTH_THRESHOLD_KBPS, it uses the following table.
+ // For others RATs, the thresholds are derived from the static BW values.
// The following table is defined per signal level, int [NUM_SIGNAL_LEVEL].
- static final int HIGH_BANDWIDTH_THRESHOLD_KBPS = 5000;
- static final int[] LINK_BANDWIDTH_BYTE_DELTA_THRESHOLD_KB = {250, 500, 750, 1000, 1000};
+ private static final int HIGH_BANDWIDTH_THRESHOLD_KBPS = 5000;
+ //Array dimension : int [NUM_LINK_DIRECTION][NUM_SIGNAL_LEVEL]
+ private static final int[][] BYTE_DELTA_THRESHOLD_KB =
+ {{200, 300, 400, 600, 1000}, {400, 600, 800, 1000, 1000}};
// Used to derive byte count threshold from avg BW
- static final int AVG_BW_TO_LOW_BW_RATIO = 4;
+ private static final int AVG_BW_TO_LOW_BW_RATIO = 4;
+ private static final int BYTE_DELTA_THRESHOLD_MIN_KB = 10;
+ private static final int MAX_ERROR_PERCENT = 100 * 100;
+ private static final String[] AVG_BW_PER_RAT = {
+ "GPRS:24,24", "EDGE:70,18", "UMTS:115,115", "CDMA:14,14",
+ "CDMA - 1xRTT:30,30", "CDMA - EvDo rev. 0:750,48", "CDMA - EvDo rev. A:950,550",
+ "HSDPA:4300,620", "HSUPA:4300,1800", "HSPA:4300,1800", "CDMA - EvDo rev. B:1500,550",
+ "CDMA - eHRPD:750,48", "HSPA+:13000,3400", "TD_SCDMA:115,115",
+ "LTE:30000,15000", "NR_NSA:47000,18000",
+ "NR_NSA_MMWAVE:145000,60000", "NR:145000,60000"};
+ private static final Map<String, Pair<Integer, Integer>> AVG_BW_PER_RAT_MAP = new ArrayMap<>();
// To be used in the long term avg, each count needs to be above the following value
static final int BW_STATS_COUNT_THRESHOLD = 5;
@@ -135,7 +151,7 @@
private boolean mScreenOn = false;
private boolean mIsOnDefaultRoute = false;
private long mLastModemPollTimeMs;
-
+ private boolean mLastTrafficValid = true;
private long mLastMobileTxBytes;
private long mLastMobileRxBytes;
private long mTxBytesDeltaAcc;
@@ -154,18 +170,40 @@
private long mFilterUpdateTimeMs;
private int mBandwidthUpdateSignalDbm = -1;
+ private int mBandwidthUpdateSignalLevel = -1;
private int mBandwidthUpdateDataRat = TelephonyManager.NETWORK_TYPE_UNKNOWN;
private String mBandwidthUpdatePlmn = "";
private BandwidthState mTxState = new BandwidthState(LINK_TX);
private BandwidthState mRxState = new BandwidthState(LINK_RX);
+ private static void initAvgBwPerRatTable() {
+ for (String config : AVG_BW_PER_RAT) {
+ int rxKbps = 14;
+ int txKbps = 14;
+ String[] kv = config.split(":");
+ if (kv.length == 2) {
+ String[] split = kv[1].split(",");
+ if (split.length == 2) {
+ try {
+ rxKbps = Integer.parseInt(split[0]);
+ txKbps = Integer.parseInt(split[1]);
+ } catch (NumberFormatException ignored) {
+ }
+ }
+ AVG_BW_PER_RAT_MAP.put(kv[0], new Pair<>(rxKbps, txKbps));
+ }
+ }
+ }
+
private final DisplayManager.DisplayListener mDisplayListener =
new DisplayManager.DisplayListener() {
@Override
- public void onDisplayAdded(int displayId) { }
+ public void onDisplayAdded(int displayId) {
+ }
@Override
- public void onDisplayRemoved(int displayId) { }
+ public void onDisplayRemoved(int displayId) {
+ }
@Override
public void onDisplayChanged(int displayId) {
@@ -215,12 +253,14 @@
mConnectivityManager.registerDefaultNetworkCallback(mDefaultNetworkCallback, this);
mTelephonyManager.registerTelephonyCallback(new HandlerExecutor(this),
mTelephonyCallback);
- mPlaceholderNetwork = new NetworkBandwidth("", "");
+ mPlaceholderNetwork = new NetworkBandwidth("");
+ initAvgBwPerRatTable();
registerDataServiceState();
}
@Override
public void handleMessage(Message msg) {
+ AsyncResult ar;
switch (msg.what) {
case MSG_SCREEN_STATE_CHANGED:
handleScreenStateChanged((boolean) msg.obj);
@@ -240,9 +280,7 @@
case MSG_NR_FREQUENCY_CHANGED:
// fall through
case MSG_NR_STATE_CHANGED:
- // fall through
- case MSG_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED:
- checkUpdateColdStartValueResetFilter();
+ updateStaticBwValueResetFilter();
break;
default:
Rlog.e(TAG, "invalid message " + msg.what);
@@ -312,13 +350,24 @@
long mobileRxBytes = mTelephonyFacade.getMobileRxBytes();
long txBytesDelta = mobileTxBytes - mLastMobileTxBytes;
long rxBytesDelta = mobileRxBytes - mLastMobileRxBytes;
- mLastMobileTxBytes = mobileTxBytes;
- mLastMobileRxBytes = mobileRxBytes;
- mTxBytesDeltaAcc += txBytesDelta;
- mRxBytesDeltaAcc += rxBytesDelta;
+
// Schedule the next traffic stats poll
sendEmptyMessageDelayed(MSG_TRAFFIC_STATS_POLL, TRAFFIC_STATS_POLL_INTERVAL_MS);
+ mLastMobileTxBytes = mobileTxBytes;
+ mLastMobileRxBytes = mobileRxBytes;
+ // Sometimes TrafficStats byte counts return invalid values
+ // Ignore two polls if it happens
+ boolean trafficValid = txBytesDelta >= 0 && rxBytesDelta >= 0;
+ if (!mLastTrafficValid || !trafficValid) {
+ mLastTrafficValid = trafficValid;
+ Rlog.e(TAG, " run into invalid traffic count");
+ return;
+ }
+
+ mTxBytesDeltaAcc += txBytesDelta;
+ mRxBytesDeltaAcc += rxBytesDelta;
+
boolean doModemPoll = true;
// Check if it meets the requirement to request modem activity
long txByteDeltaThr = Math.min(mTxState.mByteDeltaAccThr / TRAFFIC_MODEM_POLL_BYTE_RATIO,
@@ -339,10 +388,10 @@
if (doModemPoll) {
StringBuilder sb = new StringBuilder();
- logd(sb.append("TxByteDelta ").append(txBytesDelta)
- .append(" RxByteDelta ").append(rxBytesDelta)
- .append("TxByteDeltaAcc ").append(mTxBytesDeltaAcc)
- .append(" RxByteDeltaAcc ").append(mRxBytesDeltaAcc)
+ logd(sb.append("txByteDelta ").append(txBytesDelta)
+ .append(" rxByteDelta ").append(rxBytesDelta)
+ .append(" txByteDeltaAcc ").append(mTxBytesDeltaAcc)
+ .append(" rxByteDeltaAcc ").append(mRxBytesDeltaAcc)
.append(" trigger modem activity request").toString());
updateDataRatCellIdentity();
// Filter update will happen after the request
@@ -368,7 +417,9 @@
updateBandwidthTxRxSamples(result);
updateTxRxBandwidthFilterSendToDataConnection();
mLastModemActivityInfo = result;
+ // Update for next poll
resetByteDeltaAcc();
+ invalidateTxRxSamples();
}
private void resetByteDeltaAcc() {
@@ -376,9 +427,12 @@
mRxBytesDeltaAcc = 0;
}
+ private void invalidateTxRxSamples() {
+ mTxState.mBwSampleValid = false;
+ mRxState.mBwSampleValid = false;
+ }
+
private void updateBandwidthTxRxSamples(ModemActivityInfo modemActivityInfo) {
- mTxState.mBandwidthSampleValid = false;
- mRxState.mBandwidthSampleValid = false;
if (mLastModemActivityInfo == null || modemActivityInfo == null
|| mNetworkCapabilities == null) {
return;
@@ -404,25 +458,24 @@
mTxState.updateBandwidthSample(mTxBytesDeltaAcc, txTimeDeltaMs);
mRxState.updateBandwidthSample(mRxBytesDeltaAcc, rxTimeBwEstMs);
- int l2TxTputKbps = mNetworkCapabilities.getLinkUpstreamBandwidthKbps();
- int l2RxTputKbps = mNetworkCapabilities.getLinkDownstreamBandwidthKbps();
+ int reportedTxTputKbps = mNetworkCapabilities.getLinkUpstreamBandwidthKbps();
+ int reportedRxTputKbps = mNetworkCapabilities.getLinkDownstreamBandwidthKbps();
StringBuilder sb = new StringBuilder();
- logd(sb.append(" dBm=").append(mSignalStrengthDbm)
- .append(" level=").append(mSignalLevel)
- .append(" rat=").append(getDataRatName(mDataRat))
- .append(" plmn=").append(mPlmn)
- .append(" tac=").append(mTac)
- .append(" l2TxKbps=").append(l2TxTputKbps)
- .append(" l2RxKbps=").append(l2RxTputKbps)
- .append(" txMs=").append(txTimeDeltaMs)
- .append(" rxMs=").append(rxTimeDeltaMs)
- .append(" txKB=").append(mTxBytesDeltaAcc / 1024)
- .append(" rxKB=").append(mRxBytesDeltaAcc / 1024)
- .append(" TxMbps=").append(mTxState.mBandwidthSampleKbps / 1024)
- .append(" RxMbps=").append(mRxState.mBandwidthSampleKbps / 1024)
- .append(" TxValid=").append(mTxState.mBandwidthSampleValid)
- .append(" RxValid=").append(mRxState.mBandwidthSampleValid)
+ logd(sb.append("UpdateBwSample")
+ .append(" dBm ").append(mSignalStrengthDbm)
+ .append(" level ").append(mSignalLevel)
+ .append(" rat ").append(getDataRatName(mDataRat))
+ .append(" plmn ").append(mPlmn)
+ .append(" tac ").append(mTac)
+ .append(" reportedTxKbps ").append(reportedTxTputKbps)
+ .append(" reportedRxKbps ").append(reportedRxTputKbps)
+ .append(" txMs ").append(txTimeDeltaMs)
+ .append(" rxMs ").append(rxTimeDeltaMs)
+ .append(" txKB ").append(mTxBytesDeltaAcc / 1024)
+ .append(" rxKB ").append(mRxBytesDeltaAcc / 1024)
+ .append(" txKBThr ").append(mTxState.mByteDeltaAccThr / 1024)
+ .append(" rxKBThr ").append(mRxState.mByteDeltaAccThr / 1024)
.toString());
}
@@ -439,65 +492,112 @@
mTxState.updateBandwidthFilter();
mRxState.updateBandwidthFilter();
- int txDeltaKbps = Math.abs(mTxState.mLastReportedBwKbps - mTxState.mFilterKbps);
- int rxDeltaKbps = Math.abs(mRxState.mLastReportedBwKbps - mRxState.mFilterKbps);
- if ((txDeltaKbps * 100 > BW_UPDATE_THRESHOLD_PERCENT * mTxState.mLastReportedBwKbps)
- || (rxDeltaKbps * 100 > BW_UPDATE_THRESHOLD_PERCENT
- * mRxState.mLastReportedBwKbps)
+ if (mTxState.hasLargeBwChange()
+ || mRxState.hasLargeBwChange()
|| mBandwidthUpdateDataRat != mDataRat
+ || mBandwidthUpdateSignalLevel != mSignalLevel
|| !mBandwidthUpdatePlmn.equals(mPlmn)) {
- sendLinkBandwidthToDataConnection(mTxState.mFilterKbps, mRxState.mFilterKbps);
- mTxState.mLastReportedBwKbps = mTxState.mFilterKbps;
- mRxState.mLastReportedBwKbps = mRxState.mFilterKbps;
+ mTxState.mLastReportedBwKbps = mTxState.mAvgUsedKbps < 0 ? -1 : mTxState.mFilterKbps;
+ mRxState.mLastReportedBwKbps = mRxState.mAvgUsedKbps < 0 ? -1 : mRxState.mFilterKbps;
+ sendLinkBandwidthToDataConnection(
+ mTxState.mLastReportedBwKbps,
+ mRxState.mLastReportedBwKbps);
}
mBandwidthUpdateSignalDbm = mSignalStrengthDbm;
+ mBandwidthUpdateSignalLevel = mSignalLevel;
mBandwidthUpdateDataRat = mDataRat;
mBandwidthUpdatePlmn = mPlmn;
+
+ mTxState.calculateError();
+ mRxState.calculateError();
}
private class BandwidthState {
private final int mLink;
int mFilterKbps;
- int mByteDeltaAccThr;
- int mBandwidthSampleKbps;
- boolean mBandwidthSampleValid;
- long mBandwidthSampleValidTimeMs;
- int mBandwidthColdStartKbps;
+ int mByteDeltaAccThr = BYTE_DELTA_THRESHOLD_KB[0][0];
+ int mAvgUsedKbps;
+ int mBwSampleKbps;
+ boolean mBwSampleValid;
+ long mBwSampleValidTimeMs;
+ int mStaticBwKbps;
int mLastReportedBwKbps;
+ private final Map<String, EstimationError> mErrorMap = new ArrayMap<>();
+
+ private class EstimationError {
+ final String mRatName;
+ final long[] mBwEstIntNse = new long[NUM_SIGNAL_LEVEL];
+ final long[] mBwEstExtNse = new long[NUM_SIGNAL_LEVEL];
+ final long[] mStaticBwNse = new long[NUM_SIGNAL_LEVEL];
+ final int[] mCount = new int[NUM_SIGNAL_LEVEL];
+
+ EstimationError(String ratName) {
+ mRatName = ratName;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ return sb.append(mRatName)
+ .append("\n Internal\n").append(printAvgError(mBwEstIntNse, mCount))
+ .append("\n External\n").append(printAvgError(mBwEstExtNse, mCount))
+ .append("\n StaticBw\n").append(printAvgError(mStaticBwNse, mCount))
+ .toString();
+ }
+
+ private String printAvgError(long[] stats, int[] count) {
+ StringBuilder sb = new StringBuilder();
+ for (int k = 0; k < NUM_SIGNAL_LEVEL; k++) {
+ int avgStat = (count[k] >= BW_STATS_COUNT_THRESHOLD && stats[k] >= 0)
+ ? (int) Math.sqrt(stats[k] / count[k]) : 0;
+ sb.append(" " + avgStat);
+ }
+ return sb.toString();
+ }
+ }
BandwidthState(int link) {
mLink = link;
}
+ private EstimationError lookupEstimationError(String dataRatName) {
+ EstimationError ans = mErrorMap.get(dataRatName);
+ if (ans == null) {
+ ans = new EstimationError(dataRatName);
+ mErrorMap.put(dataRatName, ans);
+ }
+ return ans;
+ }
+
private void updateBandwidthSample(long bytesDelta, long timeDeltaMs) {
if (bytesDelta < mByteDeltaAccThr) {
return;
}
- if (timeDeltaMs <= 0) {
+ if (timeDeltaMs < TX_RX_TIME_MIN_MS) {
return;
}
int linkBandwidthKbps = (int) (bytesDelta * 8 * 1000 / timeDeltaMs / 1024);
- mBandwidthSampleValid = true;
- mBandwidthSampleKbps = linkBandwidthKbps;
+ mBwSampleValid = true;
+ mBwSampleKbps = linkBandwidthKbps;
String dataRatName = getDataRatName(mDataRat);
NetworkBandwidth network = lookupNetwork(mPlmn, dataRatName);
// Update per RAT stats of all TAC
- network.linkBandwidthStats.increment(linkBandwidthKbps, mLink, mSignalLevel);
+ network.update(linkBandwidthKbps, mLink, mSignalLevel);
// Update per TAC stats
- LocalAreaNetworkBandwidth localNetwork = lookupLocalNetwork(mPlmn, mTac, dataRatName);
- localNetwork.linkBandwidthStats.increment(linkBandwidthKbps, mLink, mSignalLevel);
+ network = lookupNetwork(mPlmn, mTac, dataRatName);
+ network.update(linkBandwidthKbps, mLink, mSignalLevel);
}
private void updateBandwidthFilter() {
int avgKbps = getAvgLinkBandwidthKbps();
// Feed the filter with the long term avg if there is no valid BW sample so that filter
// will gradually converge the long term avg.
- int filterInKbps = mBandwidthSampleValid ? mBandwidthSampleKbps : avgKbps;
+ int filterInKbps = mBwSampleValid ? mBwSampleKbps : avgKbps;
long currTimeMs = mTelephonyFacade.getElapsedSinceBootMillis();
- int timeDeltaSec = (int) (currTimeMs - mBandwidthSampleValidTimeMs) / 1000;
+ int timeDeltaSec = (int) (currTimeMs - mBwSampleValidTimeMs) / 1000;
// If the operation condition changes significantly since the last update
// or the sample has higher BW, use a faster filter. Otherwise, use a slow filter
@@ -505,19 +605,18 @@
if (Math.abs(mBandwidthUpdateSignalDbm - mSignalStrengthDbm) > RSSI_DELTA_THRESHOLD_DB
|| !mBandwidthUpdatePlmn.equals(mPlmn)
|| mBandwidthUpdateDataRat != mDataRat
- || (mBandwidthSampleValid && mBandwidthSampleKbps > avgKbps)) {
+ || (mBwSampleValid && mBwSampleKbps > avgKbps)) {
timeConstantSec = TIME_CONSTANT_SMALL_SEC;
} else {
timeConstantSec = TIME_CONSTANT_LARGE_SEC;
}
// Update timestamp for next iteration
- if (mBandwidthSampleValid) {
- mBandwidthSampleValidTimeMs = currTimeMs;
- mBandwidthSampleValid = false;
+ if (mBwSampleValid) {
+ mBwSampleValidTimeMs = currTimeMs;
}
if (filterInKbps == mFilterKbps) {
- logd(mLink + " skip filter because the same input / current = " + filterInKbps);
+ logv(mLink + " skip filter because the same input / current = " + filterInKbps);
return;
}
@@ -526,7 +625,7 @@
mFilterKbps = alpha == 0 ? filterInKbps : ((mFilterKbps * alpha
+ filterInKbps * FILTER_SCALE - filterInKbps * alpha) / FILTER_SCALE);
StringBuilder sb = new StringBuilder();
- logd(sb.append(mLink)
+ logv(sb.append(mLink)
.append(" lastSampleWeight=").append(alpha)
.append("/").append(FILTER_SCALE)
.append(" filterInKbps=").append(filterInKbps)
@@ -538,31 +637,35 @@
private int getAvgUsedLinkBandwidthKbps() {
// Check if current TAC/RAT/level has enough stats
String dataRatName = getDataRatName(mDataRat);
- LinkBandwidthStats linkBandwidthStats =
- lookupLocalNetwork(mPlmn, mTac, dataRatName).linkBandwidthStats;
- int count = linkBandwidthStats.getCount(mLink, mSignalLevel);
+ NetworkBandwidth network = lookupNetwork(mPlmn, mTac, dataRatName);
+ int count = network.getCount(mLink, mSignalLevel);
if (count >= BW_STATS_COUNT_THRESHOLD) {
- return (int) (linkBandwidthStats.getValue(mLink, mSignalLevel) / count);
+ return (int) (network.getValue(mLink, mSignalLevel) / count);
}
// Check if current RAT/level has enough stats
- linkBandwidthStats = lookupNetwork(mPlmn, dataRatName).linkBandwidthStats;
- count = linkBandwidthStats.getCount(mLink, mSignalLevel);
+ network = lookupNetwork(mPlmn, dataRatName);
+ count = network.getCount(mLink, mSignalLevel);
if (count >= BW_STATS_COUNT_THRESHOLD) {
- return (int) (linkBandwidthStats.getValue(mLink, mSignalLevel) / count);
+ return (int) (network.getValue(mLink, mSignalLevel) / count);
}
return -1;
}
- /** get a long term avg value (PLMN/RAT/TAC/level dependent) or carrier config value */
- private int getAvgLinkBandwidthKbps() {
- int avgUsagKbps = getAvgUsedLinkBandwidthKbps();
+ private int getCurrentCount() {
+ String dataRatName = getDataRatName(mDataRat);
+ NetworkBandwidth network = lookupNetwork(mPlmn, dataRatName);
+ return network.getCount(mLink, mSignalLevel);
+ }
- if (avgUsagKbps > 0) {
- return avgUsagKbps;
+ /** get a long term avg value (PLMN/RAT/TAC/level dependent) or static value */
+ private int getAvgLinkBandwidthKbps() {
+ mAvgUsedKbps = getAvgUsedLinkBandwidthKbps();
+ if (mAvgUsedKbps > 0) {
+ return mAvgUsedKbps;
}
- // Fall back to cold start value
- return mBandwidthColdStartKbps;
+ // Fall back to static value
+ return mStaticBwKbps;
}
private void resetBandwidthFilter() {
@@ -571,11 +674,11 @@
private void updateByteCountThr() {
// For high BW RAT cases, use predefined value + threshold derived from avg usage BW
- if (mBandwidthColdStartKbps > HIGH_BANDWIDTH_THRESHOLD_KBPS) {
+ if (mStaticBwKbps > HIGH_BANDWIDTH_THRESHOLD_KBPS) {
int lowBytes = calculateByteCountThreshold(getAvgUsedLinkBandwidthKbps(),
MODEM_POLL_MIN_INTERVAL_MS);
// Start with a predefined value
- mByteDeltaAccThr = LINK_BANDWIDTH_BYTE_DELTA_THRESHOLD_KB[mSignalLevel] * 1024;
+ mByteDeltaAccThr = BYTE_DELTA_THRESHOLD_KB[mLink][mSignalLevel] * 1024;
if (lowBytes > 0) {
// Raise the threshold if the avg usage BW is high
mByteDeltaAccThr = Math.max(lowBytes, mByteDeltaAccThr);
@@ -584,43 +687,75 @@
}
return;
}
- // For low BW RAT cases, derive the threshold from carrier config BW values
- mByteDeltaAccThr = calculateByteCountThreshold(mBandwidthColdStartKbps,
+ // For low BW RAT cases, derive the threshold from avg BW values
+ mByteDeltaAccThr = calculateByteCountThreshold(mStaticBwKbps,
MODEM_POLL_MIN_INTERVAL_MS);
+
+ mByteDeltaAccThr = Math.max(mByteDeltaAccThr, BYTE_DELTA_THRESHOLD_MIN_KB * 1024);
// Low BW RAT threshold value should be no more than high BW one.
- mByteDeltaAccThr = Math.min(mByteDeltaAccThr,
- LINK_BANDWIDTH_BYTE_DELTA_THRESHOLD_KB[0] * 1024);
+ mByteDeltaAccThr = Math.min(mByteDeltaAccThr, BYTE_DELTA_THRESHOLD_KB[mLink][0] * 1024);
}
// Calculate a byte count threshold for the given avg BW and observation window size
private int calculateByteCountThreshold(int avgBwKbps, int durationMs) {
return avgBwKbps / 8 * durationMs / AVG_BW_TO_LOW_BW_RATIO;
}
+
+ public boolean hasLargeBwChange() {
+ int deltaKbps = Math.abs(mLastReportedBwKbps - mFilterKbps);
+ return mAvgUsedKbps > 0
+ && deltaKbps * 100 > BW_UPDATE_THRESHOLD_PERCENT * mLastReportedBwKbps;
+ }
+
+ public void calculateError() {
+ if (!mBwSampleValid || getCurrentCount() <= BW_STATS_COUNT_THRESHOLD + 1) {
+ return;
+ }
+ int bwEstExtErrPercent = calculateErrorPercent(mLastReportedBwKbps, mBwSampleKbps);
+ int bwEstAvgErrPercent = calculateErrorPercent(mAvgUsedKbps, mBwSampleKbps);
+ int bwEstIntErrPercent = calculateErrorPercent(mFilterKbps, mBwSampleKbps);
+ int coldStartErrPercent = calculateErrorPercent(mStaticBwKbps, mBwSampleKbps);
+ EstimationError err = lookupEstimationError(getDataRatName(mDataRat));
+ err.mBwEstIntNse[mSignalLevel] += bwEstIntErrPercent * bwEstIntErrPercent;
+ err.mBwEstExtNse[mSignalLevel] += bwEstExtErrPercent * bwEstExtErrPercent;
+ err.mStaticBwNse[mSignalLevel] += coldStartErrPercent * coldStartErrPercent;
+ err.mCount[mSignalLevel]++;
+ StringBuilder sb = new StringBuilder();
+ logd(sb.append(mLink)
+ .append(" sampKbps ").append(mBwSampleKbps)
+ .append(" filtKbps ").append(mFilterKbps)
+ .append(" reportKbps ").append(mLastReportedBwKbps)
+ .append(" avgUsedKbps ").append(mAvgUsedKbps)
+ .append(" csKbps ").append(mStaticBwKbps)
+ .append(" intErrPercent ").append(bwEstIntErrPercent)
+ .append(" avgErrPercent ").append(bwEstAvgErrPercent)
+ .append(" extErrPercent ").append(bwEstExtErrPercent)
+ .append(" csErrPercent ").append(coldStartErrPercent)
+ .toString());
+ }
+
+ private int calculateErrorPercent(int inKbps, int bwSampleKbps) {
+ int errorKbps = inKbps - bwSampleKbps;
+ int errorPercent = bwSampleKbps > 0 ? (errorKbps * 100 / bwSampleKbps) : 0;
+ return Math.max(-MAX_ERROR_PERCENT, Math.min(errorPercent, MAX_ERROR_PERCENT));
+ }
}
/**
* Update the byte count threshold.
- * It should be called whenever the RAT, signal level or carrier config is changed.
- * For the RAT with high BW (4G and beyond), use LINK_BANDWIDTH_BYTE_DELTA_THRESHOLD_KB table.
- * For other RATs, derive the threshold based on the carrier config avg BW values.
+ * It should be called whenever the RAT or signal level is changed.
+ * For the RAT with high BW (4G and beyond), use BYTE_DELTA_THRESHOLD_KB table.
+ * For other RATs, derive the threshold based on the static BW values.
*/
private void updateByteCountThr() {
mTxState.updateByteCountThr();
mRxState.updateByteCountThr();
- logd("ByteAccThr tx:" + mTxState.mByteDeltaAccThr + " rx:" + mRxState.mByteDeltaAccThr);
}
- // Reset BW filter to a long term avg value (PLMN/RAT/TAC dependent) or carrier config value.
- // It should be called whenever PLMN/RAT/carrier config is changed;
+ // Reset BW filter to a long term avg value (PLMN/RAT/TAC dependent) or static BW value.
+ // It should be called whenever PLMN/RAT or static BW value is changed;
private void resetBandwidthFilter() {
StringBuilder sb = new StringBuilder();
- logd(sb.append("Reset BW filter ")
- .append(" dBm=").append(mSignalStrengthDbm)
- .append(" level=").append(mSignalLevel)
- .append(" rat=").append(getDataRatName(mDataRat))
- .append(" plmn=").append(mPlmn)
- .append(" tac=").append(mTac)
- .toString());
mTxState.resetBandwidthFilter();
mRxState.resetBandwidthFilter();
}
@@ -634,7 +769,7 @@
if (dc == null) {
return;
}
- logd("Update DC BW, tx " + linkBandwidthTxKps + " rx " + linkBandwidthRxKps);
+ logv("send to DC tx " + linkBandwidthTxKps + " rx " + linkBandwidthRxKps);
dc.updateLinkBandwidthEstimation(linkBandwidthTxKps, linkBandwidthRxKps);
}
@@ -669,33 +804,37 @@
return TelephonyManager.getNetworkTypeName(rat);
}
- // Update BW cold start values.
+ // Update avg BW values.
// It should be called whenever the RAT could be changed.
- // return true if cold start value is changed;
- private boolean updateColdStartValueFromCarrierConfig() {
- DcTracker dt = mPhone.getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
- if (dt == null) {
- return false;
- }
- String dataRatName = getDataRatName(mDataRat);
- Pair<Integer, Integer> values = dt.getLinkBandwidthsFromCarrierConfig(dataRatName);
+ // return true if avg value is changed;
+ private boolean updateStaticBwValue(int dataRat) {
+ Pair<Integer, Integer> values = getStaticAvgBw(dataRat);
if (values == null) {
- Rlog.e(TAG, dataRatName + " returns null CarrierConfig BW");
- mTxState.mBandwidthColdStartKbps = DEFAULT_LINK_BAND_WIDTH_KBPS;
- mRxState.mBandwidthColdStartKbps = DEFAULT_LINK_BAND_WIDTH_KBPS;
+ mTxState.mStaticBwKbps = DEFAULT_LINK_BAND_WIDTH_KBPS;
+ mRxState.mStaticBwKbps = DEFAULT_LINK_BAND_WIDTH_KBPS;
return true;
}
- if (mTxState.mBandwidthColdStartKbps != values.second
- || mRxState.mBandwidthColdStartKbps != values.first) {
- mTxState.mBandwidthColdStartKbps = values.second;
- mRxState.mBandwidthColdStartKbps = values.first;
+ if (mTxState.mStaticBwKbps != values.second
+ || mRxState.mStaticBwKbps != values.first) {
+ mTxState.mStaticBwKbps = values.second;
+ mRxState.mStaticBwKbps = values.first;
return true;
}
return false;
}
- private void checkUpdateColdStartValueResetFilter() {
- if (updateColdStartValueFromCarrierConfig()) {
+ /** get per-RAT static bandwidth value */
+ public Pair<Integer, Integer> getStaticAvgBw(int dataRat) {
+ String dataRatName = getDataRatName(dataRat);
+ Pair<Integer, Integer> values = AVG_BW_PER_RAT_MAP.get(dataRatName);
+ if (values == null) {
+ Rlog.e(TAG, dataRatName + " is not found in Avg BW table");
+ }
+ return values;
+ }
+
+ private void updateStaticBwValueResetFilter() {
+ if (updateStaticBwValue(mDataRat)) {
updateByteCountThr();
resetBandwidthFilter();
updateTxRxBandwidthFilterSendToDataConnection();
@@ -735,7 +874,7 @@
if (dataRat != mDataRat) {
updatedRat = true;
mDataRat = dataRat;
- updateColdStartValueFromCarrierConfig();
+ updateStaticBwValue(mDataRat);
updateByteCountThr();
}
}
@@ -773,14 +912,19 @@
}
}
+ void logv(String msg) {
+ if (DBG) Rlog.v(TAG, msg);
+ }
+
void logd(String msg) {
if (DBG) Rlog.d(TAG, msg);
mLocalLog.log(msg);
}
+ @VisibleForTesting
+ static final int UNKNOWN_TAC = -1;
// Map with NetworkKey as the key and NetworkBandwidth as the value.
// NetworkKey is specified by the PLMN, data RAT and TAC of network.
- // If TAC is not available, default TAC value (-1) is used.
// NetworkBandwidth represents the bandwidth related stats of each network.
private final Map<NetworkKey, NetworkBandwidth> mNetworkMap = new ArrayMap<>();
private static class NetworkKey {
@@ -792,11 +936,6 @@
mTac = tac;
mDataRat = dataRat;
}
- NetworkKey(String plmn, String dataRat) {
- mPlmn = plmn;
- mTac = -1;
- mDataRat = dataRat;
- }
@Override
public boolean equals(@Nullable Object o) {
if (o == null || !(o instanceof NetworkKey) || hashCode() != o.hashCode()) {
@@ -817,92 +956,110 @@
public int hashCode() {
return Objects.hash(mPlmn, mDataRat, mTac);
}
-
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("Plmn").append(mPlmn)
+ .append("Rat").append(mDataRat)
+ .append("Tac").append(mTac)
+ .toString();
+ return sb.toString();
+ }
}
+
+ @NonNull
private NetworkBandwidth lookupNetwork(String plmn, String dataRat) {
- if (plmn == null) {
+ return lookupNetwork(plmn, UNKNOWN_TAC, dataRat);
+ }
+
+ /** Look up NetworkBandwidth and create a new one if it doesn't exist */
+ @VisibleForTesting
+ @NonNull
+ public NetworkBandwidth lookupNetwork(String plmn, int tac, String dataRat) {
+ if (plmn == null || dataRat.equals(
+ TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_UNKNOWN))) {
return mPlaceholderNetwork;
}
- NetworkKey key = new NetworkKey(plmn, dataRat);
+ NetworkKey key = new NetworkKey(plmn, tac, dataRat);
NetworkBandwidth ans = mNetworkMap.get(key);
if (ans == null) {
- ans = new NetworkBandwidth(plmn, dataRat);
+ ans = new NetworkBandwidth(key.toString());
mNetworkMap.put(key, ans);
}
return ans;
}
- private static class NetworkBandwidth {
- protected final String mPlmn;
- protected final NetworkKey mKey;
- protected final String mDataRat;
- public final LinkBandwidthStats linkBandwidthStats;
- NetworkBandwidth(String plmn, String dataRat) {
- mKey = new NetworkKey(plmn, dataRat);
- mPlmn = plmn;
- mDataRat = dataRat;
- linkBandwidthStats = new LinkBandwidthStats();
+ /** A class holding link bandwidth related stats */
+ @VisibleForTesting
+ public class NetworkBandwidth {
+ private final String mKey;
+ NetworkBandwidth(String key) {
+ mKey = key;
}
+
+ /** Update link bandwidth stats */
+ public void update(long value, int link, int level) {
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(
+ mPhone.getContext());
+ String valueKey = getValueKey(link, level);
+ String countKey = getCountKey(link, level);
+ SharedPreferences.Editor editor = sp.edit();
+ long currValue = sp.getLong(valueKey, 0);
+ int currCount = sp.getInt(countKey, 0);
+ editor.putLong(valueKey, currValue + value);
+ editor.putInt(countKey, currCount + 1);
+ editor.apply();
+ }
+
+ private String getValueKey(int link, int level) {
+ return getDataKey(link, level) + "Data";
+ }
+
+ private String getCountKey(int link, int level) {
+ return getDataKey(link, level) + "Count";
+ }
+
+ private String getDataKey(int link, int level) {
+ StringBuilder sb = new StringBuilder();
+ return sb.append(mKey)
+ .append("Link").append(link)
+ .append("Level").append(level)
+ .toString();
+ }
+
+ /** Get the accumulated bandwidth value */
+ public long getValue(int link, int level) {
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(
+ mPhone.getContext());
+ String valueKey = getValueKey(link, level);
+ return sp.getLong(valueKey, 0);
+ }
+
+ /** Get the accumulated bandwidth count */
+ public int getCount(int link, int level) {
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(
+ mPhone.getContext());
+ String countKey = getCountKey(link, level);
+ return sp.getInt(countKey, 0);
+ }
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
- sb.append(" PLMN ").append(mPlmn)
- .append(" RAT ").append(mDataRat)
- .append(" Stats \n").append(linkBandwidthStats);
- return sb.toString();
- }
- }
-
- private LocalAreaNetworkBandwidth lookupLocalNetwork(String plmn, int tac, String dataRat) {
- NetworkKey key = new NetworkKey(plmn, tac, dataRat);
- LocalAreaNetworkBandwidth ans = (LocalAreaNetworkBandwidth) mNetworkMap.get(key);
- if (ans == null) {
- ans = new LocalAreaNetworkBandwidth(plmn, tac, dataRat);
- mNetworkMap.put(key, ans);
- }
- return ans;
- }
-
- private static class LocalAreaNetworkBandwidth extends NetworkBandwidth {
- private final int mTac;
- LocalAreaNetworkBandwidth(String plmn, int tac, String dataRat) {
- super(plmn, dataRat);
- mTac = tac;
- }
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append(" PLMN ").append(mPlmn)
- .append(" RAT ").append(mDataRat)
- .append(" TAC ").append(mTac)
- .append(" Stats \n").append(linkBandwidthStats);
- return sb.toString();
- }
- }
-
- private static class LinkBandwidthStats {
- // Stats per signal level
- private final long[][] mValue = new long[NUM_LINK_DIRECTION][NUM_SIGNAL_LEVEL];
- private final int[][] mCount = new int[NUM_LINK_DIRECTION][NUM_SIGNAL_LEVEL];
- void increment(long value, int link, int level) {
- mValue[link][level] += value;
- mCount[link][level]++;
- }
- int getCount(int link, int level) {
- return mCount[link][level];
- }
- long getValue(int link, int level) {
- return mValue[link][level];
- }
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < NUM_LINK_DIRECTION; i++) {
- sb.append(" i = " + i);
- for (int j = 0; j < NUM_SIGNAL_LEVEL; j++) {
- sb.append(" j = " + j);
- sb.append(" value: " + mValue[i][j]);
- sb.append(" count: " + mCount[i][j]);
+ sb.append(mKey);
+ sb.append("\n");
+ for (int link = 0; link < NUM_LINK_DIRECTION; link++) {
+ sb.append((link == 0 ? "tx" : "rx"));
+ sb.append("\n avgKbps");
+ for (int level = 0; level < NUM_SIGNAL_LEVEL; level++) {
+ int count = getCount(link, level);
+ int avgKbps = count == 0 ? 0 : (int) (getValue(link, level) / count);
+ sb.append(" ").append(avgKbps);
+ }
+ sb.append("\n count");
+ for (int level = 0; level < NUM_SIGNAL_LEVEL; level++) {
+ int count = getCount(link, level);
+ sb.append(" ").append(count);
}
sb.append("\n");
}
@@ -917,11 +1074,21 @@
IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " ");
pw.increaseIndent();
pw.println("current PLMN " + mPlmn + " TAC " + mTac + " RAT " + getDataRatName(mDataRat));
- pw.println("all recent networks ");
+ pw.println("all networks visited since device boot");
for (NetworkBandwidth network : mNetworkMap.values()) {
pw.println(network.toString());
}
+ pw.println("Tx NRMSE");
+ for (BandwidthState.EstimationError err : mTxState.mErrorMap.values()) {
+ pw.println(err.toString());
+ }
+
+ pw.println("Rx NRMSE");
+ for (BandwidthState.EstimationError err : mRxState.mErrorMap.values()) {
+ pw.println(err.toString());
+ }
+
try {
mLocalLog.dump(fd, pw, args);
} catch (Exception e) {
@@ -931,4 +1098,5 @@
pw.println();
pw.flush();
}
+
}
diff --git a/src/java/com/android/internal/telephony/dataconnection/QosCallbackTracker.java b/src/java/com/android/internal/telephony/dataconnection/QosCallbackTracker.java
index 94055f9..e44f03d 100644
--- a/src/java/com/android/internal/telephony/dataconnection/QosCallbackTracker.java
+++ b/src/java/com/android/internal/telephony/dataconnection/QosCallbackTracker.java
@@ -19,8 +19,11 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.net.LinkAddress;
+import android.net.QosSession;
import android.telephony.data.EpsQos;
+import android.telephony.data.NrQos;
import android.telephony.data.EpsBearerQosSessionAttributes;
+import android.telephony.data.NrQosSessionAttributes;
import android.telephony.data.QosBearerFilter;
import android.telephony.data.QosBearerSession;
@@ -179,25 +182,41 @@
@NonNull final QosBearerSession session, @NonNull IFilter filter) {
QosBearerFilter qosBearerFilter = getMatchingQosBearerFilter(session, filter);
List<InetSocketAddress> remoteAddresses = new ArrayList<>();
- EpsQos qos = (EpsQos) session.getQos();
if(qosBearerFilter.getRemoteAddresses().size() > 0) {
remoteAddresses.add(
new InetSocketAddress(qosBearerFilter.getRemoteAddresses().get(0).getAddress(),
qosBearerFilter.getRemotePortRange().getStart()));
}
- EpsBearerQosSessionAttributes epsBearerAttr =
- new EpsBearerQosSessionAttributes(qos.getQci(),
- qos.getUplinkBandwidth().getMaxBitrateKbps(),
- qos.getDownlinkBandwidth().getMaxBitrateKbps(),
- qos.getDownlinkBandwidth().getGuaranteedBitrateKbps(),
- qos.getUplinkBandwidth().getGuaranteedBitrateKbps(),
- remoteAddresses);
- mDcNetworkAgent.notifyQosSessionAvailable(
- callbackId, session.getQosBearerSessionId(), epsBearerAttr);
+
+ if (session.getQos() instanceof EpsQos) {
+ EpsQos qos = (EpsQos) session.getQos();
+ EpsBearerQosSessionAttributes epsBearerAttr =
+ new EpsBearerQosSessionAttributes(qos.getQci(),
+ qos.getUplinkBandwidth().getMaxBitrateKbps(),
+ qos.getDownlinkBandwidth().getMaxBitrateKbps(),
+ qos.getDownlinkBandwidth().getGuaranteedBitrateKbps(),
+ qos.getUplinkBandwidth().getGuaranteedBitrateKbps(),
+ remoteAddresses);
+ mDcNetworkAgent.notifyQosSessionAvailable(
+ callbackId, session.getQosBearerSessionId(), epsBearerAttr);
+ } else {
+ NrQos qos = (NrQos) session.getQos();
+ NrQosSessionAttributes nrQosAttr =
+ new NrQosSessionAttributes(qos.get5Qi(), qos.getQfi(),
+ qos.getUplinkBandwidth().getMaxBitrateKbps(),
+ qos.getDownlinkBandwidth().getMaxBitrateKbps(),
+ qos.getDownlinkBandwidth().getGuaranteedBitrateKbps(),
+ qos.getUplinkBandwidth().getGuaranteedBitrateKbps(),
+ qos.getAveragingWindow(), remoteAddresses);
+ mDcNetworkAgent.notifyQosSessionAvailable(
+ callbackId, session.getQosBearerSessionId(), nrQosAttr);
+ }
}
private void sendSessionLost(final int callbackId, @NonNull final QosBearerSession session) {
- mDcNetworkAgent.notifyQosSessionLost(callbackId, session.getQosBearerSessionId());
+ mDcNetworkAgent.notifyQosSessionLost(callbackId, session.getQosBearerSessionId(),
+ session.getQos() instanceof EpsQos ?
+ QosSession.TYPE_EPS_BEARER : QosSession.TYPE_NR_BEARER);
}
public interface IFilter {
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
index 6228619..d7aad9f 100755
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
@@ -3797,6 +3797,15 @@
}
cqm.saveCallQuality(callQuality);
mCallQualityMetrics.put(callId, cqm);
+
+ ImsPhoneConnection conn = findConnection(imsCall);
+ if (conn != null) {
+ Bundle report = new Bundle();
+ report.putParcelable(android.telecom.Connection.EXTRA_CALL_QUALITY_REPORT,
+ callQuality);
+ conn.onConnectionEvent(android.telecom.Connection.EVENT_CALL_QUALITY_REPORT,
+ report);
+ }
}
/**
@@ -4295,7 +4304,7 @@
// the only thing we can do here is splitting the usage into half rx and half tx.
// Uid -1 indicates this is for the overall device data usage.
vtDataUsageSnapshot.combineValues(new NetworkStats.Entry(
- NetworkStats.IFACE_VT, -1, NetworkStats.SET_FOREGROUND,
+ getVtInterface(), -1, NetworkStats.SET_FOREGROUND,
NetworkStats.TAG_NONE, NetworkStats.METERED_YES, isRoaming,
NetworkStats.DEFAULT_NETWORK_YES, delta / 2, 0, delta / 2, 0, 0));
mVtDataUsageSnapshot = vtDataUsageSnapshot;
@@ -4318,12 +4327,17 @@
// Since the modem only reports the total vt data usage rather than rx/tx separately,
// the only thing we can do here is splitting the usage into half rx and half tx.
vtDataUsageUidSnapshot.combineValues(new NetworkStats.Entry(
- NetworkStats.IFACE_VT, mDefaultDialerUid.get(),
+ getVtInterface(), mDefaultDialerUid.get(),
NetworkStats.SET_FOREGROUND, NetworkStats.TAG_NONE, NetworkStats.METERED_YES,
isRoaming, NetworkStats.DEFAULT_NETWORK_YES, delta / 2, 0, delta / 2, 0, 0));
mVtDataUsageUidSnapshot = vtDataUsageUidSnapshot;
}
+ @VisibleForTesting(visibility = PRIVATE)
+ public String getVtInterface() {
+ return NetworkStats.IFACE_VT + mPhone.getSubId();
+ }
+
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@Override
protected void log(String msg) {
diff --git a/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java b/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
index a6eaa03..d1e7ad2 100644
--- a/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
+++ b/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
@@ -275,7 +275,7 @@
* @param pw Print writer
* @param args Arguments
*/
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (args != null && args.length > 0) {
boolean reset = true;
if (args.length > 1 && "--keep".equals(args[1])) {
@@ -488,10 +488,12 @@
pw.print("Start time in minutes: " + callSession.startTimeMinutes);
pw.print(", phone: " + callSession.phoneId);
if (callSession.eventsDropped) {
- pw.println(" Events dropped: " + callSession.eventsDropped);
+ pw.println(", events dropped: " + callSession.eventsDropped);
+ } else {
+ pw.println("");
}
- pw.println(" Events: ");
+ pw.println("Events: ");
pw.increaseIndent();
for (TelephonyCallSession.Event event : callSession.events) {
pw.print(event.delay);
@@ -544,9 +546,16 @@
for (SmsSession.Event event : smsSession.events) {
pw.print(event.delay);
pw.print(" T=");
- pw.println(smsSessionEventToString(event.type));
- // Only show more info for tx/rx sms
- if (event.type == SmsSession.Event.Type.SMS_RECEIVED) {
+ if (event.type == SmsSession.Event.Type.RIL_SERVICE_STATE_CHANGED) {
+ pw.println(smsSessionEventToString(event.type)
+ + "(" + "Data RAT " + event.serviceState.dataRat
+ + " Voice RAT " + event.serviceState.voiceRat
+ + " Channel Number " + event.serviceState.channelNumber
+ + " NR Frequency Range " + event.serviceState.nrFrequencyRange
+ + " NR State " + event.serviceState.nrState
+ + ")");
+ } else if (event.type == SmsSession.Event.Type.SMS_RECEIVED) {
+ pw.println(smsSessionEventToString(event.type));
pw.increaseIndent();
switch (event.smsType) {
case SmsSession.Event.SmsType.SMS_TYPE_SMS_PP:
@@ -570,6 +579,7 @@
pw.decreaseIndent();
} else if (event.type == SmsSession.Event.Type.SMS_SEND
|| event.type == SmsSession.Event.Type.SMS_SEND_RESULT) {
+ pw.println(smsSessionEventToString(event.type));
pw.increaseIndent();
pw.println("ReqId=" + event.rilRequestId);
pw.println("E=" + event.errorCode);
@@ -577,6 +587,7 @@
pw.println("ImsE=" + event.imsError);
pw.decreaseIndent();
} else if (event.type == SmsSession.Event.Type.INCOMPLETE_SMS_RECEIVED) {
+ pw.println(smsSessionEventToString(event.type));
pw.increaseIndent();
pw.println("Received: " + event.incompleteSms.receivedParts + "/"
+ event.incompleteSms.totalParts);
@@ -1082,7 +1093,7 @@
TelephonyServiceState serviceState = mLastServiceState.get(phoneId);
if (serviceState != null) {
smsSession.addEvent(smsSession.startElapsedTimeMs, new SmsSessionEventBuilder(
- TelephonyCallSession.Event.Type.RIL_SERVICE_STATE_CHANGED)
+ SmsSession.Event.Type.RIL_SERVICE_STATE_CHANGED)
.setServiceState(serviceState));
}
@@ -1136,7 +1147,7 @@
}
}
- private SmsSession finishSmsSession(InProgressSmsSession inProgressSmsSession) {
+ private synchronized SmsSession finishSmsSession(InProgressSmsSession inProgressSmsSession) {
SmsSession smsSession = new SmsSession();
smsSession.events = new SmsSession.Event[inProgressSmsSession.events.size()];
inProgressSmsSession.events.toArray(smsSession.events);
@@ -1818,12 +1829,10 @@
*/
private synchronized void writeOnSmsSolicitedResponse(int phoneId, int rilSerial, int rilError,
SmsResponse response) {
-
InProgressSmsSession smsSession = mInProgressSmsSessions.get(phoneId);
if (smsSession == null) {
Rlog.e(TAG, "SMS session is missing");
} else {
-
int errorCode = SmsResponse.NO_ERROR_CODE;
long messageId = 0L;
if (response != null) {
@@ -2441,7 +2450,9 @@
int smsTech = getSmsTech(smsSource, smsFormat == SmsSession.Event.Format.SMS_FORMAT_3GPP2);
InProgressSmsSession smsSession = startNewSmsSession(phoneId);
- for (long time : timestamps) {
+
+ long startElapsedTimeMillis = SystemClock.elapsedRealtime();
+ for (int i = 0; i < timestamps.length; i++) {
SmsSessionEventBuilder eventBuilder =
new SmsSessionEventBuilder(SmsSession.Event.Type.SMS_RECEIVED)
.setFormat(smsFormat)
@@ -2450,7 +2461,8 @@
.setSmsType(type)
.setBlocked(blocked)
.setMessageId(messageId);
- smsSession.addEvent(time, eventBuilder);
+ long interval = (i > 0) ? timestamps[i] - timestamps[i - 1] : 0;
+ smsSession.addEvent(startElapsedTimeMillis + interval, eventBuilder);
}
finishSmsSession(smsSession);
}
diff --git a/src/java/com/android/internal/telephony/vendor/VendorPhoneSwitcher.java b/src/java/com/android/internal/telephony/vendor/VendorPhoneSwitcher.java
index 48103e2..33de2d1 100644
--- a/src/java/com/android/internal/telephony/vendor/VendorPhoneSwitcher.java
+++ b/src/java/com/android/internal/telephony/vendor/VendorPhoneSwitcher.java
@@ -19,7 +19,6 @@
import static android.telephony.SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
import static android.telephony.SubscriptionManager.INVALID_PHONE_INDEX;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-import static android.telephony.TelephonyManager.RADIO_POWER_UNAVAILABLE;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -30,35 +29,24 @@
import android.os.AsyncResult;
import android.os.Looper;
import android.os.Message;
-import android.os.Registrant;
import android.os.SystemProperties;
-import android.telephony.data.ApnSetting;
-import android.telephony.Rlog;
import android.telephony.SubscriptionManager;
-
-import android.text.TextUtils;
+import android.telephony.data.ApnSetting;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.CallManager;
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.dataconnection.DcRequest;
-import com.android.internal.telephony.dataconnection.DataEnabledSettings;
import com.android.internal.telephony.GsmCdmaCall;
-import com.android.internal.telephony.imsphone.ImsPhone;
-import com.android.internal.telephony.imsphone.ImsPhoneCall;
-import com.android.internal.telephony.ITelephonyRegistry;
import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.PhoneSwitcher;
-import com.android.internal.telephony.SubscriptionController;
import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.telephony.dataconnection.DataEnabledSettings;
+import com.android.internal.telephony.dataconnection.DcRequest;
+import com.android.internal.telephony.imsphone.ImsPhone;
+import com.android.internal.telephony.imsphone.ImsPhoneCall;
-import java.lang.Integer;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
@@ -382,8 +370,7 @@
/* Determine the phone id on which PS attach needs to be done
*/
protected int phoneIdForRequest(NetworkRequest netRequest, int apnType) {
- int subId = getSubIdFromNetworkSpecifier(netRequest.networkCapabilities
- .getNetworkSpecifier());
+ int subId = getSubIdFromNetworkSpecifier(netRequest.getNetworkSpecifier());
if (subId == DEFAULT_SUBSCRIPTION_ID) return mPreferredDataPhoneId;
if (subId == INVALID_SUBSCRIPTION_ID) return INVALID_PHONE_INDEX;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CellularNetworkServiceTest.java b/tests/telephonytests/src/com/android/internal/telephony/CellularNetworkServiceTest.java
index 3ff9995..17d9576 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CellularNetworkServiceTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CellularNetworkServiceTest.java
@@ -32,8 +32,10 @@
import android.telephony.NetworkRegistrationInfo;
import android.telephony.NetworkService;
import android.telephony.NetworkServiceCallback;
+import android.telephony.NrVopsSupportInfo;
import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
+import android.telephony.VopsSupportInfo;
import android.test.suitebuilder.annotation.MediumTest;
import com.android.internal.R;
@@ -156,7 +158,7 @@
assertTrue(false);
}
- LteVopsSupportInfo lteVopsSupportInfo =
+ VopsSupportInfo lteVopsSupportInfo =
new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE,
LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE);
@@ -173,4 +175,276 @@
assertTrue(false);
}
}
+
+ @Test
+ @MediumTest
+ public void testGetNetworkRegistrationInfoV1_5() {
+ // common parameters
+ int regState = NetworkRegistrationInfo.REGISTRATION_STATE_HOME;
+ int radioTech = ServiceState.RIL_RADIO_TECHNOLOGY_LTE;
+ int reasonForDenial = 0;
+
+ // voice services
+ List<Integer> availableVoiceServices = new ArrayList<>(Arrays.asList(new Integer[] {
+ NetworkRegistrationInfo.SERVICE_TYPE_VOICE,
+ NetworkRegistrationInfo.SERVICE_TYPE_SMS,
+ NetworkRegistrationInfo.SERVICE_TYPE_VIDEO
+ }));
+
+ // Default value per 24.008
+ int maxDataCalls = 16;
+ // data service
+ List<Integer> availableDataServices = Arrays.asList(
+ NetworkRegistrationInfo.SERVICE_TYPE_DATA);
+
+ // ENDC parameters
+ boolean isEndcAvailable = true;
+ boolean isDcNrRestricted = false;
+ boolean isNrAvailable = true;
+
+ // LTE VoPS parameters
+ boolean isVopsSupported = true;
+ boolean isEmcBearerSupported = true;
+
+ android.hardware.radio.V1_5.RegStateResult regResult =
+ new android.hardware.radio.V1_5.RegStateResult();
+
+ regResult.regState = regState;
+ regResult.rat = radioTech;
+ regResult.reasonForDenial = reasonForDenial;
+
+ android.hardware.radio.V1_5.RegStateResult.AccessTechnologySpecificInfo
+ .EutranRegistrationInfo eutranInfo = new android.hardware.radio.V1_5
+ .RegStateResult.AccessTechnologySpecificInfo.EutranRegistrationInfo();
+ eutranInfo.lteVopsInfo.isVopsSupported = isVopsSupported;
+ eutranInfo.lteVopsInfo.isEmcBearerSupported = isEmcBearerSupported;
+ eutranInfo.nrIndicators.isEndcAvailable = isEndcAvailable;
+ eutranInfo.nrIndicators.isDcNrRestricted = isDcNrRestricted;
+ eutranInfo.nrIndicators.isNrAvailable = isNrAvailable;
+ regResult.accessTechnologySpecificInfo.eutranInfo(eutranInfo);
+
+ VopsSupportInfo vops = new LteVopsSupportInfo(
+ LteVopsSupportInfo.LTE_STATUS_SUPPORTED, LteVopsSupportInfo.LTE_STATUS_SUPPORTED);
+
+ mSimulatedCommands.setVoiceRegStateResult(regResult);
+ mSimulatedCommands.setDataRegStateResult(regResult);
+
+ // test voice registration state
+ try {
+ mBinder.requestNetworkRegistrationInfo(0, NetworkRegistrationInfo.DOMAIN_CS, mCallback);
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+
+ NetworkRegistrationInfo expectedState = new NetworkRegistrationInfo(
+ NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+ regState, ServiceState.rilRadioTechnologyToNetworkType(radioTech), reasonForDenial,
+ false, availableVoiceServices, null, "", false, 0, 0, 0);
+
+ try {
+ verify(mCallback, timeout(1000).times(1)).onRequestNetworkRegistrationInfoComplete(
+ eq(NetworkServiceCallback.RESULT_SUCCESS), eq(expectedState));
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+
+ // test data registration state
+ try {
+ mBinder.requestNetworkRegistrationInfo(0, NetworkRegistrationInfo.DOMAIN_PS, mCallback);
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+
+ expectedState = new NetworkRegistrationInfo(
+ NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+ regState, ServiceState.rilRadioTechnologyToNetworkType(radioTech), reasonForDenial,
+ false, availableDataServices, null, "", maxDataCalls, isDcNrRestricted,
+ isNrAvailable, isEndcAvailable, vops);
+
+ try {
+ verify(mCallback, timeout(1000).times(1)).onRequestNetworkRegistrationInfoComplete(
+ eq(NetworkServiceCallback.RESULT_SUCCESS), eq(expectedState));
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+ }
+
+ @Test
+ @MediumTest
+ public void testGetNetworkRegistrationInfoV1_6WithLte() {
+ // common parameters
+ int regState = NetworkRegistrationInfo.REGISTRATION_STATE_HOME;
+ int radioTech = ServiceState.RIL_RADIO_TECHNOLOGY_LTE;
+ int reasonForDenial = 0;
+
+ // voice services
+ List<Integer> availableVoiceServices = new ArrayList<>(Arrays.asList(new Integer[] {
+ NetworkRegistrationInfo.SERVICE_TYPE_VOICE,
+ NetworkRegistrationInfo.SERVICE_TYPE_SMS,
+ NetworkRegistrationInfo.SERVICE_TYPE_VIDEO
+ }));
+
+ // Default value per 24.008
+ int maxDataCalls = 16;
+ // data service
+ List<Integer> availableDataServices = Arrays.asList(
+ NetworkRegistrationInfo.SERVICE_TYPE_DATA);
+
+ // ENDC parameters
+ boolean isEndcAvailable = true;
+ boolean isDcNrRestricted = false;
+ boolean isNrAvailable = true;
+
+ // LTE VoPS parameters
+ boolean isVopsSupported = true;
+ boolean isEmcBearerSupported = true;
+
+ android.hardware.radio.V1_6.RegStateResult regResult =
+ new android.hardware.radio.V1_6.RegStateResult();
+
+ regResult.regState = regState;
+ regResult.rat = radioTech;
+ regResult.reasonForDenial = reasonForDenial;
+
+ android.hardware.radio.V1_5.RegStateResult.AccessTechnologySpecificInfo
+ .EutranRegistrationInfo eutranInfo = new android.hardware.radio.V1_5
+ .RegStateResult.AccessTechnologySpecificInfo.EutranRegistrationInfo();
+ eutranInfo.lteVopsInfo.isVopsSupported = isVopsSupported;
+ eutranInfo.lteVopsInfo.isEmcBearerSupported = isEmcBearerSupported;
+ eutranInfo.nrIndicators.isEndcAvailable = isEndcAvailable;
+ eutranInfo.nrIndicators.isDcNrRestricted = isDcNrRestricted;
+ eutranInfo.nrIndicators.isNrAvailable = isNrAvailable;
+ regResult.accessTechnologySpecificInfo.eutranInfo(eutranInfo);
+
+ VopsSupportInfo vops = new LteVopsSupportInfo(
+ LteVopsSupportInfo.LTE_STATUS_SUPPORTED, LteVopsSupportInfo.LTE_STATUS_SUPPORTED);
+
+ mSimulatedCommands.setVoiceRegStateResult(regResult);
+ mSimulatedCommands.setDataRegStateResult(regResult);
+
+ // test voice registration state
+ try {
+ mBinder.requestNetworkRegistrationInfo(0, NetworkRegistrationInfo.DOMAIN_CS, mCallback);
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+
+ NetworkRegistrationInfo expectedState = new NetworkRegistrationInfo(
+ NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+ regState, ServiceState.rilRadioTechnologyToNetworkType(radioTech), reasonForDenial,
+ false, availableVoiceServices, null, "", false, 0, 0, 0);
+
+ try {
+ verify(mCallback, timeout(1000).times(1)).onRequestNetworkRegistrationInfoComplete(
+ eq(NetworkServiceCallback.RESULT_SUCCESS), eq(expectedState));
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+
+ // test data registration state
+ try {
+ mBinder.requestNetworkRegistrationInfo(0, NetworkRegistrationInfo.DOMAIN_PS, mCallback);
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+
+ expectedState = new NetworkRegistrationInfo(
+ NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+ regState, ServiceState.rilRadioTechnologyToNetworkType(radioTech), reasonForDenial,
+ false, availableDataServices, null, "", maxDataCalls, isDcNrRestricted,
+ isNrAvailable, isEndcAvailable, vops);
+
+ try {
+ verify(mCallback, timeout(1000).times(1)).onRequestNetworkRegistrationInfoComplete(
+ eq(NetworkServiceCallback.RESULT_SUCCESS), eq(expectedState));
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+ }
+
+
+ @Test
+ @MediumTest
+ public void testGetNetworkRegistrationInfoV1_6WithNr() {
+ // common parameters
+ int regState = NetworkRegistrationInfo.REGISTRATION_STATE_HOME;
+ int radioTech = ServiceState.RIL_RADIO_TECHNOLOGY_NR;
+ int reasonForDenial = 0;
+
+ // voice services
+ List<Integer> availableVoiceServices = new ArrayList<>(Arrays.asList(new Integer[] {
+ NetworkRegistrationInfo.SERVICE_TYPE_VOICE,
+ NetworkRegistrationInfo.SERVICE_TYPE_SMS,
+ NetworkRegistrationInfo.SERVICE_TYPE_VIDEO
+ }));
+
+ // Default value per 24.008
+ int maxDataCalls = 16;
+ // data service
+ List<Integer> availableDataServices = Arrays.asList(
+ NetworkRegistrationInfo.SERVICE_TYPE_DATA);
+
+ // NR VoPS parameters
+ byte vopsSupported = android.hardware.radio.V1_6.VopsIndicator.VOPS_OVER_3GPP;
+ byte emcSupported = android.hardware.radio.V1_6.EmcIndicator.EMC_NR_CONNECTED_TO_5GCN;
+ byte emfSupported = android.hardware.radio.V1_6.EmfIndicator.EMF_NR_CONNECTED_TO_5GCN;
+
+ android.hardware.radio.V1_6.RegStateResult regResult =
+ new android.hardware.radio.V1_6.RegStateResult();
+
+ regResult.regState = regState;
+ regResult.rat = radioTech;
+ regResult.reasonForDenial = reasonForDenial;
+
+
+ android.hardware.radio.V1_6.RegStateResult.AccessTechnologySpecificInfo
+ .NgranRegistrationInfo ngranInfo = new android.hardware.radio.V1_6
+ .RegStateResult.AccessTechnologySpecificInfo.NgranRegistrationInfo();
+ ngranInfo.nrVopsInfo.vopsSupported = vopsSupported;
+ ngranInfo.nrVopsInfo.emcSupported = emcSupported;
+ ngranInfo.nrVopsInfo.emfSupported = emfSupported;
+ regResult.accessTechnologySpecificInfo.ngranInfo(ngranInfo);
+
+ VopsSupportInfo vops = new NrVopsSupportInfo(vopsSupported, emcSupported, emfSupported);
+ mSimulatedCommands.setVoiceRegStateResult(regResult);
+ mSimulatedCommands.setDataRegStateResult(regResult);
+
+ // test voice registration state
+ try {
+ mBinder.requestNetworkRegistrationInfo(0, NetworkRegistrationInfo.DOMAIN_CS, mCallback);
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+
+ NetworkRegistrationInfo expectedState = new NetworkRegistrationInfo(
+ NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+ regState, ServiceState.rilRadioTechnologyToNetworkType(radioTech), reasonForDenial,
+ false, availableVoiceServices, null, "", false, 0, 0, 0);
+
+ try {
+ verify(mCallback, timeout(1000).times(1)).onRequestNetworkRegistrationInfoComplete(
+ eq(NetworkServiceCallback.RESULT_SUCCESS), eq(expectedState));
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+
+ // test data registration state
+ try {
+ mBinder.requestNetworkRegistrationInfo(0, NetworkRegistrationInfo.DOMAIN_PS, mCallback);
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+
+ expectedState = new NetworkRegistrationInfo(
+ NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+ regState, ServiceState.rilRadioTechnologyToNetworkType(radioTech), reasonForDenial,
+ false, availableDataServices, null, "", maxDataCalls, false, false, false, vops);
+
+ try {
+ verify(mCallback, timeout(1000).times(1)).onRequestNetworkRegistrationInfoComplete(
+ eq(NetworkServiceCallback.RESULT_SUCCESS), eq(expectedState));
+ } catch (RemoteException e) {
+ assertTrue(false);
+ }
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CellularNetworkValidatorTest.java b/tests/telephonytests/src/com/android/internal/telephony/CellularNetworkValidatorTest.java
index 74ced90..2c1e18b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CellularNetworkValidatorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CellularNetworkValidatorTest.java
@@ -57,9 +57,9 @@
public class CellularNetworkValidatorTest extends TelephonyTest {
private CellularNetworkValidator mValidatorUT;
private static final PhoneCapability CAPABILITY_WITH_VALIDATION_SUPPORTED =
- new PhoneCapability(1, 1, null, true, PhoneCapability.DEVICE_NR_CAPABILITY_NONE);
+ new PhoneCapability(1, 1, null, true, new int[0]);
private static final PhoneCapability CAPABILITY_WITHOUT_VALIDATION_SUPPORTED =
- new PhoneCapability(1, 1, null, false, PhoneCapability.DEVICE_NR_CAPABILITY_NONE);
+ new PhoneCapability(1, 1, null, false, new int[0]);
private final CellIdentityLte mCellIdentityLte1 = new CellIdentityLte(123, 456, 0, 0, 111);
private final CellIdentityLte mCellIdentityLte2 = new CellIdentityLte(321, 654, 0, 0, 222);
@Mock
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
index f2cb869..b96056a 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
@@ -279,6 +279,8 @@
return TestApplication.getAppContext().getSystemService(name);
case Context.POWER_WHITELIST_MANAGER:
return mPowerWhitelistManager;
+ case Context.LOCATION_SERVICE:
+ return mLocationManager;
default:
return null;
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java b/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java
index 826594d..f2624af 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java
@@ -116,7 +116,8 @@
+ Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED + " INTEGER DEFAULT 0, "
+ Telephony.SimInfo.COLUMN_RCS_CONFIG + " BLOB,"
+ Telephony.SimInfo.COLUMN_ALLOWED_NETWORK_TYPES_FOR_REASONS + " TEXT,"
- + Telephony.SimInfo.COLUMN_D2D_STATUS_SHARING + " INTEGER DEFAULT 0"
+ + Telephony.SimInfo.COLUMN_D2D_STATUS_SHARING + " INTEGER DEFAULT 0,"
+ + Telephony.SimInfo.COLUMN_D2D_STATUS_SHARING_SELECTED_CONTACTS + "TEXT"
+ ");";
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/PhoneCapabilityTest.java b/tests/telephonytests/src/com/android/internal/telephony/PhoneCapabilityTest.java
index da986e4..2410625 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/PhoneCapabilityTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/PhoneCapabilityTest.java
@@ -16,6 +16,7 @@
package com.android.internal.telephony;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
@@ -38,21 +39,22 @@
ModemInfo modemInfo = new ModemInfo(1, 2, true, false);
List<ModemInfo> logicalModemList = new ArrayList<>();
logicalModemList.add(modemInfo);
- int deviceNrCapability = PhoneCapability.DEVICE_NR_CAPABILITY_NONE;
+ int[] deviceNrCapabilities = new int[]{PhoneCapability.DEVICE_NR_CAPABILITY_SA};
PhoneCapability capability = new PhoneCapability(maxActiveVoiceCalls, maxActiveData,
- logicalModemList, false, deviceNrCapability);
+ logicalModemList, false, deviceNrCapabilities);
- assertEquals(maxActiveVoiceCalls, capability.getMaxActivePacketSwitchedVoiceCalls());
- assertEquals(maxActiveData, capability.getMaxActiveInternetData());
+ assertEquals(maxActiveVoiceCalls, capability.getMaxActiveVoiceSubscriptions());
+ assertEquals(maxActiveData, capability.getMaxActiveDataSubscriptions());
assertEquals(1, capability.getLogicalModemList().size());
assertEquals(modemInfo, capability.getLogicalModemList().get(0));
- assertEquals(deviceNrCapability, capability.getDeviceNrCapabilityBitmask());
+ assertArrayEquals(deviceNrCapabilities, capability.getDeviceNrCapabilities());
+
PhoneCapability toCompare = new PhoneCapability(maxActiveVoiceCalls + 1, maxActiveData - 1,
- logicalModemList, false, PhoneCapability.DEVICE_NR_CAPABILITY_NSA);
+ logicalModemList, false, deviceNrCapabilities);
assertEquals(capability,
new PhoneCapability(maxActiveVoiceCalls, maxActiveData, logicalModemList,
- false, deviceNrCapability));
+ false, deviceNrCapabilities));
assertNotEquals(capability, toCompare);
}
@@ -64,21 +66,21 @@
ModemInfo modemInfo = new ModemInfo(1, 2, true, false);
List<ModemInfo> logicalModemList = new ArrayList<>();
logicalModemList.add(modemInfo);
- int deviceNrCapability = PhoneCapability.DEVICE_NR_CAPABILITY_NONE;
+ int[] deviceNrCapabilities = new int[]{};
PhoneCapability capability = new PhoneCapability(maxActiveVoiceCalls, maxActiveData,
- logicalModemList, false, PhoneCapability.DEVICE_NR_CAPABILITY_NONE);
+ logicalModemList, false, deviceNrCapabilities);
Parcel parcel = Parcel.obtain();
capability.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
PhoneCapability toCompare = PhoneCapability.CREATOR.createFromParcel(parcel);
- assertEquals(maxActiveVoiceCalls, toCompare.getMaxActivePacketSwitchedVoiceCalls());
- assertEquals(maxActiveData, toCompare.getMaxActiveInternetData());
+ assertEquals(maxActiveVoiceCalls, toCompare.getMaxActiveVoiceSubscriptions());
+ assertEquals(maxActiveData, toCompare.getMaxActiveDataSubscriptions());
assertEquals(1, toCompare.getLogicalModemList().size());
assertEquals(modemInfo, toCompare.getLogicalModemList().get(0));
- assertEquals(deviceNrCapability, toCompare.getDeviceNrCapabilityBitmask());
+ assertArrayEquals(deviceNrCapabilities, toCompare.getDeviceNrCapabilities());
assertEquals(capability, toCompare);
}
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java
index 2ca5a27..3485f49 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java
@@ -123,8 +123,7 @@
public void setUp() throws Exception {
super.setUp(getClass().getSimpleName());
- PhoneCapability phoneCapability = new PhoneCapability(1, 1, null, false,
- PhoneCapability.DEVICE_NR_CAPABILITY_NONE);
+ PhoneCapability phoneCapability = new PhoneCapability(1, 1, null, false, new int[0]);
doReturn(phoneCapability).when(mPhoneConfigurationManager).getCurrentPhoneCapability();
doReturn(Call.State.ACTIVE).when(mActiveCall).getState();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/RILTest.java b/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
index c495e72..7c81bda 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
@@ -43,6 +43,7 @@
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_IMSI;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_RADIO_CAPABILITY;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SIM_STATUS;
+import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SLICING_CONFIG;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SMSC_ADDRESS;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_UICC_APPLICATIONS_ENABLEMENT;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_HANGUP;
@@ -2821,4 +2822,18 @@
mRILUnderTest.setCompatVersion(testRequest, RIL.RADIO_HAL_VERSION_1_5);
assertEquals(RIL.RADIO_HAL_VERSION_1_3, mRILUnderTest.getCompatVersion(testRequest));
}
+
+ @FlakyTest
+ @Test
+ public void testGetSlicingConfig() throws Exception {
+ // Use Radio HAL v1.6
+ try {
+ replaceInstance(RIL.class, "mRadioVersion", mRILUnderTest, mRadioVersionV16);
+ } catch (Exception e) {
+ }
+ mRILUnderTest.getSlicingConfig(obtainMessage());
+ verify(mRadioProxy).getSlicingConfig(mSerialNumberCaptor.capture());
+ verifyRILResponse_1_6(
+ mRILUnderTest, mSerialNumberCaptor.getValue(), RIL_REQUEST_GET_SLICING_CONFIG);
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/RadioConfigResponseTest.java b/tests/telephonytests/src/com/android/internal/telephony/RadioConfigResponseTest.java
index 0e2e983..a346ece 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/RadioConfigResponseTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/RadioConfigResponseTest.java
@@ -52,6 +52,10 @@
assertFalse(
caps.contains(
TelephonyManager.CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE));
+ assertFalse(
+ caps.contains(TelephonyManager.CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING));
+ assertFalse(
+ caps.contains(TelephonyManager.CAPABILITY_SLICING_CONFIG_SUPPORTED));
}
@Test
@@ -64,6 +68,10 @@
assertFalse(
caps.contains(
TelephonyManager.CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE));
+ assertFalse(
+ caps.contains(TelephonyManager.CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING));
+ assertFalse(
+ caps.contains(TelephonyManager.CAPABILITY_SLICING_CONFIG_SUPPORTED));
}
@Test
@@ -76,5 +84,9 @@
assertTrue(
caps.contains(
TelephonyManager.CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE));
+ assertTrue(
+ caps.contains(TelephonyManager.CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING));
+ assertTrue(
+ caps.contains(TelephonyManager.CAPABILITY_SLICING_CONFIG_SUPPORTED));
}
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/RadioInterfaceCapabilityControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/RadioInterfaceCapabilityControllerTest.java
index efd9280..e8e1124 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/RadioInterfaceCapabilityControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/RadioInterfaceCapabilityControllerTest.java
@@ -29,6 +29,7 @@
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -52,6 +53,11 @@
super.setUp(getClass().getSimpleName());
}
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
@Test
public void testRadioInterfaceCapabilities() {
final RadioInterfaceCapabilityController capabilities =
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
index b7a4ba0..0bef358 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
@@ -82,6 +82,7 @@
import android.telephony.LteVopsSupportInfo;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.NetworkService;
+import android.telephony.NrVopsSupportInfo;
import android.telephony.PhysicalChannelConfig;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
@@ -2372,7 +2373,7 @@
@Test
@SmallTest
- public void testOnVopsInfoChanged() {
+ public void testOnLteVopsInfoChanged() {
ServiceState ss = new ServiceState();
ss.setVoiceRegState(ServiceState.STATE_IN_SERVICE);
ss.setDataRegState(ServiceState.STATE_IN_SERVICE);
@@ -2433,6 +2434,70 @@
@Test
@SmallTest
+ public void testOnNrVopsInfoChanged() {
+ ServiceState ss = new ServiceState();
+ ss.setVoiceRegState(ServiceState.STATE_IN_SERVICE);
+ ss.setDataRegState(ServiceState.STATE_IN_SERVICE);
+ sst.mSS = ss;
+
+ CellIdentityLte cellId =
+ new CellIdentityLte(1, 1, 5, 1, new int[] {1, 2}, 5000, "001", "01", "test",
+ "tst", Collections.emptyList(), null);
+ NrVopsSupportInfo nrVopsSupportInfo = new NrVopsSupportInfo(
+ NrVopsSupportInfo.NR_STATUS_VOPS_NOT_SUPPORTED,
+ NrVopsSupportInfo.NR_STATUS_EMC_NOT_SUPPORTED,
+ NrVopsSupportInfo.NR_STATUS_EMF_NOT_SUPPORTED);
+
+ NetworkRegistrationInfo dataResult = new NetworkRegistrationInfo(
+ NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+ NetworkRegistrationInfo.REGISTRATION_STATE_HOME, TelephonyManager.NETWORK_TYPE_NR,
+ 0, false, null, cellId, "00101", 1, false, false, false, nrVopsSupportInfo);
+ sst.mPollingContext[0] = 2;
+
+ sst.sendMessage(sst.obtainMessage(
+ ServiceStateTracker.EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION,
+ new AsyncResult(sst.mPollingContext, dataResult, null)));
+ NetworkRegistrationInfo voiceResult = new NetworkRegistrationInfo(
+ NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+ NetworkRegistrationInfo.REGISTRATION_STATE_HOME,
+ TelephonyManager.NETWORK_TYPE_NR, 0,
+ false, null, cellId, "00101", false, 0, 0, 0);
+ sst.sendMessage(sst.obtainMessage(
+ ServiceStateTracker.EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION,
+ new AsyncResult(sst.mPollingContext, voiceResult, null)));
+
+ waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+ assertEquals(ServiceState.STATE_IN_SERVICE, sst.getCurrentDataConnectionState());
+ NetworkRegistrationInfo sSnetworkRegistrationInfo =
+ sst.mSS.getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS,
+ AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+ assertEquals(nrVopsSupportInfo,
+ sSnetworkRegistrationInfo.getDataSpecificInfo().getVopsSupportInfo());
+
+ nrVopsSupportInfo = new NrVopsSupportInfo(
+ NrVopsSupportInfo.NR_STATUS_VOPS_3GPP_SUPPORTED,
+ NrVopsSupportInfo.NR_STATUS_EMC_5GCN_ONLY,
+ NrVopsSupportInfo.NR_STATUS_EMF_5GCN_ONLY);
+ dataResult = new NetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS,
+ AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+ NetworkRegistrationInfo.REGISTRATION_STATE_HOME,
+ TelephonyManager.NETWORK_TYPE_NR, 0, false, null, cellId, "00101",
+ 1, false, false, false, nrVopsSupportInfo);
+ sst.mPollingContext[0] = 1;
+ sst.sendMessage(sst.obtainMessage(
+ ServiceStateTracker.EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION,
+ new AsyncResult(sst.mPollingContext, dataResult, null)));
+ waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+
+ sSnetworkRegistrationInfo =
+ sst.mSS.getNetworkRegistrationInfo(2, 1);
+ assertEquals(nrVopsSupportInfo,
+ sSnetworkRegistrationInfo.getDataSpecificInfo().getVopsSupportInfo());
+ }
+
+
+ @Test
+ @SmallTest
public void testEriLoading() {
sst.obtainMessage(GsmCdmaPhone.EVENT_CARRIER_CONFIG_CHANGED, null).sendToTarget();
waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
index 84cedbd..40fa229 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
@@ -47,7 +47,6 @@
import android.telephony.SignalStrength;
import android.telephony.SignalThresholdInfo;
import android.telephony.TelephonyManager;
-import android.telephony.data.ApnSetting;
import android.telephony.data.DataCallResponse;
import android.telephony.data.DataProfile;
import android.telephony.data.NetworkSliceInfo;
@@ -164,6 +163,9 @@
private IccIoResult mIccIoResultForApduLogicalChannel;
private int mChannelId = IccOpenLogicalChannelResponse.INVALID_CHANNEL;
+ private Object mDataRegStateResult;
+ private Object mVoiceRegStateResult;
+
int mPausedResponseCount;
ArrayList<Message> mPausedResponses = new ArrayList<Message>();
@@ -1002,14 +1004,17 @@
public void getVoiceRegistrationState(Message result) {
mGetVoiceRegistrationStateCallCount.incrementAndGet();
- VoiceRegStateResult ret = new VoiceRegStateResult();
- ret.regState = mVoiceRegState;
- ret.rat = mVoiceRadioTech;
- ret.cssSupported = mCssSupported;
- ret.roamingIndicator = mRoamingIndicator;
- ret.systemIsInPrl = mSystemIsInPrl;
- ret.defaultRoamingIndicator = mDefaultRoamingIndicator;
- ret.reasonForDenial = mReasonForDenial;
+ Object ret = mVoiceRegStateResult;
+ if (ret == null) {
+ ret = new VoiceRegStateResult();
+ ((VoiceRegStateResult) ret).regState = mVoiceRegState;
+ ((VoiceRegStateResult) ret).rat = mVoiceRadioTech;
+ ((VoiceRegStateResult) ret).cssSupported = mCssSupported;
+ ((VoiceRegStateResult) ret).roamingIndicator = mRoamingIndicator;
+ ((VoiceRegStateResult) ret).systemIsInPrl = mSystemIsInPrl;
+ ((VoiceRegStateResult) ret).defaultRoamingIndicator = mDefaultRoamingIndicator;
+ ((VoiceRegStateResult) ret).reasonForDenial = mReasonForDenial;
+ }
resultSuccess(result, ret);
}
@@ -1030,14 +1035,17 @@
}
@Override
- public void getDataRegistrationState (Message result) {
+ public void getDataRegistrationState(Message result) {
mGetDataRegistrationStateCallCount.incrementAndGet();
- DataRegStateResult ret = new DataRegStateResult();
- ret.regState = mDataRegState;
- ret.rat = mDataRadioTech;
- ret.maxDataCalls = mMaxDataCalls;
- ret.reasonDataDenied = mReasonForDenial;
+ Object ret = mDataRegStateResult;
+ if (ret == null) {
+ ret = new DataRegStateResult();
+ ((DataRegStateResult) ret).regState = mDataRegState;
+ ((DataRegStateResult) ret).rat = mDataRadioTech;
+ ((DataRegStateResult) ret).maxDataCalls = mMaxDataCalls;
+ ((DataRegStateResult) ret).reasonDataDenied = mReasonForDenial;
+ }
resultSuccess(result, ret);
}
@@ -1207,14 +1215,6 @@
}
}
- // Store different cids to simulate concurrent IMS and default data calls
- if ((dataProfile.getSupportedApnTypesBitmask() & ApnSetting.TYPE_IMS)
- == ApnSetting.TYPE_IMS) {
- mSetupDataCallResult.cid = 0;
- } else {
- mSetupDataCallResult.cid = 1;
- }
-
DataCallResponse response = RIL.convertDataCallResult(mSetupDataCallResult);
if (mDcSuccess) {
resultSuccess(result, response);
@@ -2435,4 +2435,21 @@
SimulatedCommandsVerifier.getInstance().releasePduSessionId(message, pduSessionId);
resultSuccess(message, null);
}
+
+ @Override
+ public void getSlicingConfig(Message result) {
+ SimulatedCommandsVerifier.getInstance().getSlicingConfig(result);
+ resultSuccess(result, null);
+ }
+
+ @VisibleForTesting
+ public void setDataRegStateResult(Object regStateResult) {
+ mDataRegStateResult = regStateResult;
+ }
+
+ @VisibleForTesting
+ public void setVoiceRegStateResult(Object regStateResult) {
+ mVoiceRegStateResult = regStateResult;
+ }
+
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommandsVerifier.java b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommandsVerifier.java
index 5cfd036..c4d54ff 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommandsVerifier.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommandsVerifier.java
@@ -1492,4 +1492,8 @@
@Override
public void releasePduSessionId(Message result, int pduSessionId) {
}
+
+ @Override
+ public void getSlicingConfig(Message result) {
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SlidingWindowEventCounterTest.java b/tests/telephonytests/src/com/android/internal/telephony/SlidingWindowEventCounterTest.java
index 55a9c86..da8b4c2 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SlidingWindowEventCounterTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SlidingWindowEventCounterTest.java
@@ -21,15 +21,18 @@
import android.os.SystemClock;
+import androidx.test.runner.AndroidJUnit4;
+
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
-public class SlidingWindowEventCounterTest extends TelephonyTest {
+@RunWith(AndroidJUnit4.class)
+public class SlidingWindowEventCounterTest {
long mInitialTime;
@Before
public void setUp() throws Exception {
- super.setUp(getClass().getSimpleName());
mInitialTime = SystemClock.elapsedRealtime();
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
index f9199f7..5b8be32 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
@@ -88,6 +88,7 @@
private static final String FAKE_ICCID_1 = "89012604200000000000";
private static final String FAKE_MCC_MNC_1 = "123456";
private static final String FAKE_MCC_MNC_2 = "456789";
+ private static final int FAKE_PHONE_ID_1 = 0;
private SubscriptionInfoUpdater mUpdater;
private IccRecords mIccRecord;
@@ -239,17 +240,17 @@
@SmallTest
public void testSimNotReady() throws Exception {
mUpdater.updateInternalIccState(
- IccCardConstants.INTENT_VALUE_ICC_NOT_READY, null, FAKE_SUB_ID_1);
+ IccCardConstants.INTENT_VALUE_ICC_NOT_READY, null, FAKE_PHONE_ID_1);
processAllMessages();
assertFalse(mUpdater.isSubInfoInitialized());
verify(mSubscriptionContent, never()).put(anyString(), any());
CarrierConfigManager mConfigManager = (CarrierConfigManager)
mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
- verify(mConfigManager, never()).updateConfigForPhoneId(eq(FAKE_SUB_ID_1),
+ verify(mConfigManager, never()).updateConfigForPhoneId(eq(FAKE_PHONE_ID_1),
eq(IccCardConstants.INTENT_VALUE_ICC_NOT_READY));
- verify(mSubscriptionController, never()).clearSubInfo();
- verify(mSubscriptionController, never()).notifySubscriptionInfoChanged();
+ verify(mSubscriptionController).clearSubInfoRecord(FAKE_PHONE_ID_1);
+ verify(mSubscriptionController).notifySubscriptionInfoChanged();
}
@Test
@@ -259,19 +260,19 @@
doReturn(true).when(mIccCard).isEmptyProfile();
mUpdater.updateInternalIccState(
- IccCardConstants.INTENT_VALUE_ICC_NOT_READY, null, FAKE_SUB_ID_1);
+ IccCardConstants.INTENT_VALUE_ICC_NOT_READY, null, FAKE_PHONE_ID_1);
processAllMessages();
assertTrue(mUpdater.isSubInfoInitialized());
// Sub info should be cleared and change should be notified.
- verify(mSubscriptionController).clearSubInfoRecord(eq(FAKE_SUB_ID_1));
+ verify(mSubscriptionController).clearSubInfoRecord(eq(FAKE_PHONE_ID_1));
verify(mSubscriptionController).notifySubscriptionInfoChanged();
// No new sub should be added.
verify(mSubscriptionManager, never()).addSubscriptionInfoRecord(any(), anyInt());
verify(mSubscriptionContent, never()).put(anyString(), any());
CarrierConfigManager mConfigManager = (CarrierConfigManager)
mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
- verify(mConfigManager).updateConfigForPhoneId(eq(FAKE_SUB_ID_1),
+ verify(mConfigManager).updateConfigForPhoneId(eq(FAKE_PHONE_ID_1),
eq(IccCardConstants.INTENT_VALUE_ICC_NOT_READY));
}
@@ -286,24 +287,24 @@
doReturn(false).when(mSubInfo).areUiccApplicationsEnabled();
mUpdater.updateInternalIccState(
- IccCardConstants.INTENT_VALUE_ICC_NOT_READY, null, FAKE_SUB_ID_1);
+ IccCardConstants.INTENT_VALUE_ICC_NOT_READY, null, FAKE_PHONE_ID_1);
processAllMessages();
assertTrue(mUpdater.isSubInfoInitialized());
// Sub info should be cleared and change should be notified.
- verify(mSubscriptionController).clearSubInfoRecord(eq(FAKE_SUB_ID_1));
+ verify(mSubscriptionController).clearSubInfoRecord(eq(FAKE_PHONE_ID_1));
verify(mSubscriptionController).notifySubscriptionInfoChanged();
// No new sub should be added.
verify(mSubscriptionManager, never()).addSubscriptionInfoRecord(any(), anyInt());
verify(mSubscriptionContent, never()).put(anyString(), any());
CarrierConfigManager mConfigManager = (CarrierConfigManager)
mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
- verify(mConfigManager).updateConfigForPhoneId(eq(FAKE_SUB_ID_1),
+ verify(mConfigManager).updateConfigForPhoneId(eq(FAKE_PHONE_ID_1),
eq(IccCardConstants.INTENT_VALUE_ICC_NOT_READY));
// When becomes ABSENT, UICC_APPLICATIONS_ENABLED should be reset to true.
mUpdater.updateInternalIccState(
- IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, FAKE_SUB_ID_1);
+ IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, FAKE_PHONE_ID_1);
processAllMessages();
ArgumentCaptor<ContentValues> valueCapture = ArgumentCaptor.forClass(ContentValues.class);
verify(mContentProvider).update(eq(SubscriptionManager.CONTENT_URI), valueCapture.capture(),
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
index 16e61dc..1362b33 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
@@ -15,6 +15,8 @@
*/
package com.android.internal.telephony;
+import static android.telephony.PhysicalChannelConfig.PHYSICAL_CELL_ID_UNKNOWN;
+import static android.telephony.ServiceState.FREQUENCY_RANGE_LOW;
import static android.telephony.SubscriptionManager.ACTION_DEFAULT_SUBSCRIPTION_CHANGED;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import static android.telephony.TelephonyManager.ACTION_MULTI_SIM_CONFIG_CHANGED;
@@ -23,19 +25,29 @@
import static android.telephony.TelephonyManager.RADIO_POWER_UNAVAILABLE;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.content.Intent;
+import android.content.pm.UserInfo;
import android.net.LinkProperties;
+import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.UserHandle;
import android.telephony.AccessNetworkConstants;
import android.telephony.Annotation;
+import android.telephony.CellIdentity;
+import android.telephony.CellIdentityGsm;
+import android.telephony.CellLocation;
import android.telephony.LinkCapacityEstimate;
import android.telephony.PhoneCapability;
+import android.telephony.PhysicalChannelConfig;
import android.telephony.PreciseDataConnectionState;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
@@ -47,6 +59,8 @@
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import androidx.annotation.NonNull;
+
import com.android.server.TelephonyRegistry;
import org.junit.After;
@@ -56,6 +70,7 @@
import org.mockito.Mock;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -75,6 +90,9 @@
private TelephonyDisplayInfo mTelephonyDisplayInfo;
private int mSrvccState = -1;
private int mRadioPowerState = RADIO_POWER_UNAVAILABLE;
+ private List<PhysicalChannelConfig> mPhysicalChannelConfigs;
+ private TelephonyRegistry.ConfigurationProvider mMockConfigurationProvider;
+ private CellLocation mCellLocation;
// All events contribute to TelephonyRegistry#isPhoneStatePermissionRequired
private static final Set<Integer> READ_PHONE_STATE_EVENTS;
@@ -140,7 +158,9 @@
TelephonyCallback.RadioPowerStateListener,
TelephonyCallback.PreciseDataConnectionStateListener,
TelephonyCallback.DisplayInfoListener,
- TelephonyCallback.LinkCapacityEstimateChangedListener {
+ TelephonyCallback.LinkCapacityEstimateChangedListener,
+ TelephonyCallback.PhysicalChannelConfigListener,
+ TelephonyCallback.CellLocationListener {
// This class isn't mockable to get invocation counts because the IBinder is null and
// crashes the TelephonyRegistry. Make a cheesy verify(times()) alternative.
public AtomicInteger invocationCount = new AtomicInteger(0);
@@ -178,7 +198,17 @@
@Override
public void onLinkCapacityEstimateChanged(
List<LinkCapacityEstimate> linkCapacityEstimateList) {
- mLinkCapacityEstimateList = linkCapacityEstimateList;
+ mLinkCapacityEstimateList = linkCapacityEstimateList;
+ }
+
+ @Override
+ public void onCellLocationChanged(CellLocation location) {
+ mCellLocation = location;
+ }
+
+ @Override
+ public void onPhysicalChannelConfigChanged(@NonNull List<PhysicalChannelConfig> configs) {
+ mPhysicalChannelConfigs = configs;
}
}
@@ -197,12 +227,13 @@
@Before
public void setUp() throws Exception {
super.setUp("TelephonyRegistryTest");
- TelephonyRegistry.ConfigurationProvider mockConfigurationProvider =
- mock(TelephonyRegistry.ConfigurationProvider.class);
- when(mockConfigurationProvider.getRegistrationLimit()).thenReturn(-1);
- when(mockConfigurationProvider.isRegistrationLimitEnabledInPlatformCompat(anyInt()))
+ mMockConfigurationProvider = mock(TelephonyRegistry.ConfigurationProvider.class);
+ when(mMockConfigurationProvider.getRegistrationLimit()).thenReturn(-1);
+ when(mMockConfigurationProvider.isRegistrationLimitEnabledInPlatformCompat(anyInt()))
.thenReturn(false);
- mTelephonyRegistry = new TelephonyRegistry(mContext, mockConfigurationProvider);
+ when(mMockConfigurationProvider.isCallStateReadPhoneStateEnforcedInPlatformCompat(
+ anyString(), any())).thenReturn(false);
+ mTelephonyRegistry = new TelephonyRegistry(mContext, mMockConfigurationProvider);
addTelephonyRegistryService();
mTelephonyCallback = new TelephonyCallbackWrapper();
mTelephonyCallback.init(mSimpleExecutor);
@@ -222,8 +253,7 @@
doReturn(mMockSubInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
doReturn(0/*slotIndex*/).when(mMockSubInfo).getSimSlotIndex();
// mTelephonyRegistry.listen with notifyNow = true should trigger callback immediately.
- PhoneCapability phoneCapability = new PhoneCapability(1, 2, null, false,
- PhoneCapability.DEVICE_NR_CAPABILITY_NONE);
+ PhoneCapability phoneCapability = new PhoneCapability(1, 2, null, false, new int[0]);
int[] events = {TelephonyCallback.EVENT_PHONE_CAPABILITY_CHANGED};
mTelephonyRegistry.notifyPhoneCapabilityChanged(phoneCapability);
mTelephonyRegistry.listenWithEventList(0, mContext.getOpPackageName(),
@@ -232,8 +262,7 @@
assertEquals(phoneCapability, mPhoneCapability);
// notifyPhoneCapabilityChanged with a new capability. Callback should be triggered.
- phoneCapability = new PhoneCapability(3, 2, null, false,
- PhoneCapability.DEVICE_NR_CAPABILITY_NONE);
+ phoneCapability = new PhoneCapability(3, 2, null, false, new int[0]);
mTelephonyRegistry.notifyPhoneCapabilityChanged(phoneCapability);
processAllMessages();
assertEquals(phoneCapability, mPhoneCapability);
@@ -422,6 +451,33 @@
assertEquals(4, mTelephonyCallback.invocationCount.get());
}
+ @Test
+ public void testPhysicalChannelConfigChanged() {
+ // Return a slotIndex / phoneId of 0 for all sub ids given.
+ doReturn(mMockSubInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
+ doReturn(0/*slotIndex*/).when(mMockSubInfo).getSimSlotIndex();
+
+ final int subId = 1;
+ int[] events = {TelephonyCallback.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED};
+ // Construct PhysicalChannelConfig with minimum fields set (The default value for
+ // frequencyRange and band fields throw IAE)
+ PhysicalChannelConfig config = new PhysicalChannelConfig.Builder()
+ .setFrequencyRange(FREQUENCY_RANGE_LOW)
+ .setBand(1)
+ .setPhysicalCellId(2)
+ .build();
+ List<PhysicalChannelConfig> configs = new ArrayList<>(1);
+ configs.add(config);
+
+ mTelephonyRegistry.notifyPhysicalChannelConfigForSubscriber(subId, configs);
+ mTelephonyRegistry.listenWithEventList(subId, mContext.getOpPackageName(),
+ mContext.getAttributionTag(), mTelephonyCallback.callback, events, true);
+ processAllMessages();
+
+ assertNotNull(mPhysicalChannelConfigs);
+ assertEquals(PHYSICAL_CELL_ID_UNKNOWN, mPhysicalChannelConfigs.get(0).getPhysicalCellId());
+ }
+
/**
* Test listen to events that require READ_PHONE_STATE permission.
*/
@@ -439,6 +495,32 @@
}
/**
+ * Test enforcement of READ_PHONE_STATE for call state related events.
+ */
+ @Test
+ public void testCallStateChangedPermission() {
+ int[] events = new int[] {TelephonyCallback.EVENT_CALL_STATE_CHANGED,
+ TelephonyCallback.EVENT_LEGACY_CALL_STATE_CHANGED};
+ // Disable change ID for READ_PHONE_STATE enforcement
+ when(mMockConfigurationProvider.isCallStateReadPhoneStateEnforcedInPlatformCompat(
+ anyString(), any())).thenReturn(false);
+ // Start without READ_PHONE_STATE permission
+ mContextFixture.addCallingOrSelfPermission("");
+ assertSecurityExceptionNotThrown(events);
+ // Grant permission
+ mContextFixture.addCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE);
+ assertSecurityExceptionNotThrown(events);
+ //Enable READ_PHONE_STATE enforcement
+ when(mMockConfigurationProvider.isCallStateReadPhoneStateEnforcedInPlatformCompat(
+ anyString(), any())).thenReturn(true);
+ assertSecurityExceptionNotThrown(events);
+ // revoke READ_PHONE_STATE permission
+ mContextFixture.removeCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE);
+ assertSecurityExceptionThrown(events);
+
+ }
+
+ /**
* Test listen to events that require READ_PRECISE_PHONE_STATE permission.
*/
@Test
@@ -542,6 +624,51 @@
assertEquals(displayInfo, mTelephonyDisplayInfo);
}
+ @Test
+ public void testNotifyCellLocationForSubscriberByUserSwitched() throws RemoteException {
+ final int phoneId = 0;
+ final int subId = 1;
+
+ // Return a slotIndex / phoneId of 0 for subId 1.
+ doReturn(new int[] {subId}).when(mSubscriptionController).getSubId(phoneId);
+ doReturn(mMockSubInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(subId);
+ doReturn(phoneId).when(mMockSubInfo).getSimSlotIndex();
+ mServiceManagerMockedServices.put("isub", mSubscriptionController);
+ doReturn(mSubscriptionController).when(mSubscriptionController)
+ .queryLocalInterface(anyString());
+
+ UserInfo userInfo = new UserInfo(UserHandle.myUserId(), "" /* name */, 0 /* flags */);
+ doReturn(userInfo).when(mIActivityManager).getCurrentUser();
+
+ doReturn(true).when(mLocationManager).isLocationEnabledForUser(any(UserHandle.class));
+
+ CellIdentity cellIdentity = new CellIdentityGsm(-1, -1, -1, -1, null, null, null, null,
+ Collections.emptyList());
+ mTelephonyRegistry.notifyCellLocationForSubscriber(subId, cellIdentity);
+ processAllMessages();
+
+ // Listen to EVENT_CELL_LOCATION_CHANGED for the current user Id.
+ int[] events = {TelephonyCallback.EVENT_CELL_LOCATION_CHANGED};
+ mTelephonyRegistry.listenWithEventList(subId, mContext.getOpPackageName(),
+ mContext.getAttributionTag(), mTelephonyCallback.callback, events, false);
+
+ // Broadcast ACTION_USER_SWITCHED for USER_SYSTEM. Callback should be triggered.
+ mCellLocation = null;
+ mContext.sendBroadcast(new Intent(Intent.ACTION_USER_SWITCHED));
+
+ processAllMessages();
+ assertEquals(cellIdentity.asCellLocation(), mCellLocation);
+
+ // Broadcast ACTION_USER_SWITCHED for the current user Id + 1. Callback shouldn't be
+ // triggered.
+ userInfo.id++;
+ mCellLocation = null;
+ mContext.sendBroadcast(new Intent(Intent.ACTION_USER_SWITCHED));
+
+ processAllMessages();
+ assertEquals(null, mCellLocation);
+ }
+
private void assertSecurityExceptionThrown(int[] event) {
try {
mTelephonyRegistry.listenWithEventList(
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
index 035bcdf..b1f0e2e 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
@@ -41,6 +41,7 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
import android.net.vcn.VcnManager;
@@ -326,6 +327,8 @@
protected LinkBandwidthEstimator mLinkBandwidthEstimator;
@Mock
protected PinStorage mPinStorage;
+ @Mock
+ protected LocationManager mLocationManager;
protected ActivityManager mActivityManager;
protected ImsCallProfile mImsCallProfile;
@@ -484,6 +487,7 @@
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
mVcnManager = mContext.getSystemService(VcnManager.class);
+ mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
//mTelephonyComponentFactory
doReturn(mTelephonyComponentFactory).when(mTelephonyComponentFactory).inject(anyString());
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
index f26c373..a6cdcae 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
@@ -42,6 +42,7 @@
import android.content.IntentFilter;
import android.content.pm.ServiceInfo;
+import android.hardware.radio.V1_0.SetupDataCallResult;
import android.net.InetAddresses;
import android.net.KeepalivePacketData;
import android.net.LinkAddress;
@@ -83,8 +84,10 @@
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
+import java.util.Collections;
public class DataConnectionTest extends TelephonyTest {
+ private static final int DEFAULT_DC_CID = 10;
@Mock
DcTesterFailBringUpAll mDcTesterFailBringUpAll;
@@ -95,9 +98,13 @@
@Mock
ApnContext mApnContext;
@Mock
+ ApnContext mEnterpriseApnContext;
+ @Mock
DcFailBringUp mDcFailBringUp;
@Mock
DataCallSessionStats mDataCallSessionStats;
+ @Mock
+ DataConnection mDefaultDc;
private DataConnection mDc;
private DataConnectionTestHandler mDataConnectionTestHandler;
@@ -289,6 +296,7 @@
ServiceState.RIL_RADIO_TECHNOLOGY_UMTS);
doReturn(mApn1).when(mApnContext).getApnSetting();
doReturn(ApnSetting.TYPE_DEFAULT_STRING).when(mApnContext).getApnType();
+ doReturn(ApnSetting.TYPE_DEFAULT).when(mApnContext).getApnTypeBitmask();
mDcFailBringUp.saveParameters(0, 0, -2);
doReturn(mDcFailBringUp).when(mDcTesterFailBringUpAll).getDcFailBringUp();
@@ -352,8 +360,13 @@
return (boolean) method.invoke(mDc);
}
- private SetupResult setLinkProperties(DataCallResponse response,
- LinkProperties linkProperties)
+ private boolean isEnterpriseUse() throws Exception {
+ Method method = DataConnection.class.getDeclaredMethod("isEnterpriseUse");
+ method.setAccessible(true);
+ return (boolean) method.invoke(mDc);
+ }
+
+ private SetupResult setLinkProperties(DataCallResponse response, LinkProperties linkProperties)
throws Exception {
Class[] cArgs = new Class[2];
cArgs[0] = DataCallResponse.class;
@@ -373,9 +386,7 @@
@SmallTest
public void testConnectEvent() throws Exception {
testSanity();
-
- mDc.sendMessage(DataConnection.EVENT_CONNECT, mCp);
- waitForMs(200);
+ connectEvent(true);
verify(mCT, times(1)).registerForVoiceCallStarted(any(Handler.class),
eq(DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_STARTED), eq(null));
@@ -408,15 +419,15 @@
assertEquals("spmode.ne.jp", dpCaptor.getValue().getApn());
if (tdCaptor.getValue() != null) {
if (mApnContext.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE) {
- assertEquals(null, tdCaptor.getValue().getDnn());
+ assertEquals(null, tdCaptor.getValue().getDataNetworkName());
assertTrue(tdCaptor.getValue().getOsAppId()
.contains(ApnSetting.TYPE_ENTERPRISE_STRING));
} else {
- assertEquals("spmode.ne.jp", tdCaptor.getValue().getDnn());
+ assertEquals("spmode.ne.jp", tdCaptor.getValue().getDataNetworkName());
assertEquals(null, tdCaptor.getValue().getOsAppId());
}
}
- assertEquals("DcActiveState", getCurrentState().getName());
+ assertTrue(mDc.isActive());
assertEquals(mDc.getPduSessionId(), 1);
assertEquals(3, mDc.getPcscfAddresses().length);
@@ -426,13 +437,85 @@
}
@Test
+ public void testConnectEventDuplicateContextIds() throws Exception {
+ setUpDefaultData();
+
+ // Create successful result with the same CID as default
+ SetupDataCallResult result = new SetupDataCallResult();
+ result.status = 0;
+ result.suggestedRetryTime = -1;
+ result.cid = DEFAULT_DC_CID;
+ result.active = 2;
+ result.type = "IP";
+ result.ifname = FAKE_IFNAME;
+ result.addresses = FAKE_ADDRESS;
+ result.dnses = FAKE_DNS;
+ result.gateways = FAKE_GATEWAY;
+ result.pcscf = FAKE_PCSCF_ADDRESS;
+ result.mtu = 1440;
+ mSimulatedCommands.setDataCallResult(true, result);
+
+ // Try to connect ENTERPRISE with the same CID as default
+ replaceInstance(ConnectionParams.class, "mApnContext", mCp, mEnterpriseApnContext);
+ doReturn(mApn1).when(mEnterpriseApnContext).getApnSetting();
+ doReturn(ApnSetting.TYPE_ENTERPRISE_STRING).when(mEnterpriseApnContext).getApnType();
+ doReturn(ApnSetting.TYPE_ENTERPRISE).when(mEnterpriseApnContext).getApnTypeBitmask();
+
+ // Verify that ENTERPRISE wasn't set up
+ connectEvent(false);
+ assertEquals("DcInactiveState", getCurrentState().getName());
+
+ // Change the CID
+ result.cid = DEFAULT_DC_CID + 1;
+ mSimulatedCommands.setDataCallResult(true, result);
+
+ // Verify that ENTERPRISE was set up
+ connectEvent(true);
+ assertTrue(mDc.getNetworkCapabilities().hasCapability(
+ NetworkCapabilities.NET_CAPABILITY_ENTERPRISE));
+ }
+
+ @Test
+ public void testConnectEventNoDefaultData() throws Exception {
+ assertFalse(mDefaultDc.isActive());
+
+ // Try to connect ENTERPRISE when default data doesn't exist
+ replaceInstance(ConnectionParams.class, "mApnContext", mCp, mEnterpriseApnContext);
+ doReturn(mApn1).when(mEnterpriseApnContext).getApnSetting();
+ doReturn(ApnSetting.TYPE_ENTERPRISE_STRING).when(mEnterpriseApnContext).getApnType();
+ doReturn(ApnSetting.TYPE_ENTERPRISE).when(mEnterpriseApnContext).getApnTypeBitmask();
+
+ // Verify that ENTERPRISE wasn't set up
+ connectEvent(false);
+ assertEquals("DcInactiveState", getCurrentState().getName());
+
+ // Set up default data
+ replaceInstance(ConnectionParams.class, "mApnContext", mCp, mApnContext);
+ setUpDefaultData();
+
+ // Verify that ENTERPRISE was set up
+ replaceInstance(ConnectionParams.class, "mApnContext", mCp, mEnterpriseApnContext);
+ connectEvent(true);
+ assertTrue(mDc.getNetworkCapabilities().hasCapability(
+ NetworkCapabilities.NET_CAPABILITY_ENTERPRISE));
+ }
+
+ private void setUpDefaultData() throws Exception {
+ replaceInstance(DataConnection.class, "mCid", mDefaultDc, DEFAULT_DC_CID);
+ doReturn(true).when(mDefaultDc).isActive();
+ doReturn(Arrays.asList(mApnContext)).when(mDefaultDc).getApnContexts();
+ mDcc.addActiveDcByCid(mDefaultDc);
+ assertTrue(mDefaultDc.getApnContexts().stream()
+ .anyMatch(apn -> apn.getApnTypeBitmask() == ApnSetting.TYPE_DEFAULT));
+ }
+
+ @Test
@SmallTest
public void testDisconnectEvent() throws Exception {
testConnectEvent();
mDc.setPduSessionId(5);
- mDc.sendMessage(DataConnection.EVENT_DISCONNECT, mDcp);
- waitForMs(100);
+ disconnectEvent();
verify(mSimulatedCommandsVerifier, times(1)).unregisterForLceInfo(any(Handler.class));
verify(mSimulatedCommandsVerifier, times(1))
@@ -617,12 +700,9 @@
CarrierConfigManager.KEY_CARRIER_WWAN_DISALLOWED_APN_TYPES_STRING_ARRAY,
new String[] {"supl"});
- mDc.sendMessage(DataConnection.EVENT_DISCONNECT, mDcp);
- waitForMs(100);
+ disconnectEvent();
doReturn(mApn1).when(mApnContext).getApnSetting();
- doReturn(ApnSetting.TYPE_ENTERPRISE).when(mApnContext).getApnTypeBitmask();
- mDc.sendMessage(DataConnection.EVENT_CONNECT, mCp);
- waitForMs(200);
+ connectEvent(true);
assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN));
@@ -630,6 +710,42 @@
.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET));
assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL));
+ assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
+ .hasCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE));
+ }
+
+ @Test
+ @SmallTest
+ public void testEnterpriseNetworkCapability() throws Exception {
+ mContextFixture.getCarrierConfigBundle().putStringArray(
+ CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
+ new String[] { "default" });
+ doReturn(mApn2).when(mApnContext).getApnSetting();
+ testConnectEvent();
+
+ assertTrue("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
+ .hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN));
+ assertTrue("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
+ .hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET));
+ assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
+ .hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS));
+ assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
+ .hasCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE));
+
+ disconnectEvent();
+ setUpDefaultData();
+ replaceInstance(ConnectionParams.class, "mApnContext", mCp, mEnterpriseApnContext);
+ doReturn(mApn1).when(mEnterpriseApnContext).getApnSetting();
+ doReturn(ApnSetting.TYPE_ENTERPRISE_STRING).when(mEnterpriseApnContext).getApnType();
+ doReturn(ApnSetting.TYPE_ENTERPRISE).when(mEnterpriseApnContext).getApnTypeBitmask();
+ connectEvent(true);
+
+ assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
+ .hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN));
+ assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
+ .hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET));
+ assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
+ .hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL));
assertTrue("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
.hasCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE));
}
@@ -673,12 +789,14 @@
assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_CONGESTED));
mDc.onMeterednessChanged(true);
+ waitForMs(100);
assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED));
assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_CONGESTED));
mDc.onMeterednessChanged(false);
+ waitForMs(100);
assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED));
assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
@@ -697,12 +815,14 @@
assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_CONGESTED));
mDc.onCongestednessChanged(true);
+ waitForMs(100);
assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED));
assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_CONGESTED));
mDc.onCongestednessChanged(false);
+ waitForMs(100);
assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED));
assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
@@ -710,6 +830,16 @@
}
@Test
+ public void testSubIds() throws Exception {
+ mContextFixture.getCarrierConfigBundle().putStringArray(
+ CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
+ new String[] { "default" });
+ testConnectEvent();
+
+ assertEquals(Collections.singleton(0), getNetworkCapabilities().getSubIds());
+ }
+
+ @Test
public void testShouldSkip464Xlat() throws Exception {
assertFalse(testShouldSkip464XlatEvent(mApn1));
disconnectEvent();
@@ -729,16 +859,19 @@
method.setAccessible(true);
doReturn(apn).when(mApnContext).getApnSetting();
- connectEvent();
+ doReturn(apn.getApnTypeBitmask()).when(mApnContext).getApnTypeBitmask();
+ connectEvent(true);
logd(getNetworkCapabilities().toString());
return (Boolean) method.invoke(mDc);
}
- private void connectEvent() throws Exception {
+ private void connectEvent(boolean validate) {
mDc.sendMessage(DataConnection.EVENT_CONNECT, mCp);
waitForMs(200);
- assertEquals("DcActiveState", getCurrentState().getName());
+ if (validate) {
+ assertTrue(mDc.isActive());
+ }
}
private void disconnectEvent() throws Exception {
@@ -749,7 +882,7 @@
@Test
@SmallTest
- public void testIsIpAddress() throws Exception {
+ public void testIsIpAddress() {
// IPv4
assertTrue(DataConnection.isIpAddress("1.2.3.4"));
assertTrue(DataConnection.isIpAddress("127.0.0.1"));
@@ -1056,6 +1189,24 @@
}
@Test
+ public void testIsEnterpriseUse() throws Exception {
+ assertFalse(isEnterpriseUse());
+ assertFalse(mDc.getNetworkCapabilities().hasCapability(
+ NetworkCapabilities.NET_CAPABILITY_ENTERPRISE));
+
+ setUpDefaultData();
+ replaceInstance(ConnectionParams.class, "mApnContext", mCp, mEnterpriseApnContext);
+ doReturn(mApn1).when(mEnterpriseApnContext).getApnSetting();
+ doReturn(ApnSetting.TYPE_ENTERPRISE_STRING).when(mEnterpriseApnContext).getApnType();
+ doReturn(ApnSetting.TYPE_ENTERPRISE).when(mEnterpriseApnContext).getApnTypeBitmask();
+ connectEvent(true);
+
+ assertTrue(isEnterpriseUse());
+ assertTrue(mDc.getNetworkCapabilities().hasCapability(
+ NetworkCapabilities.NET_CAPABILITY_ENTERPRISE));
+ }
+
+ @Test
@SmallTest
public void testGetDisallowedApnTypes() throws Exception {
mContextFixture.getCarrierConfigBundle().putStringArray(
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
index 0c7cc1b..a1b91e5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
@@ -127,6 +127,7 @@
public static final String FAKE_APN6 = "FAKE APN 6";
public static final String FAKE_APN7 = "FAKE APN 7";
public static final String FAKE_APN8 = "FAKE APN 8";
+ public static final String FAKE_APN9 = "FAKE APN 9";
public static final String FAKE_IFNAME = "FAKE IFNAME";
public static final String FAKE_PCSCF_ADDRESS = "22.33.44.55";
public static final String FAKE_GATEWAY = "11.22.33.44";
@@ -208,18 +209,12 @@
private String mFakeApn1Types = "default,supl";
- private int mNetworkTypeBitmask = NETWORK_TYPE_LTE_BITMASK;
-
private int mRowIdOffset = 0;
public void setFakeApn1Types(String apnTypes) {
mFakeApn1Types = apnTypes;
}
- public void setFakeApn1NetworkTypeBitmask(int networkTypeBitmask) {
- mNetworkTypeBitmask = networkTypeBitmask;
- }
-
public void setRowIdOffset(int rowIdOffset) {
mRowIdOffset = rowIdOffset;
}
@@ -294,7 +289,7 @@
0, // mtu
"", // mvno_type
"", // mnvo_match_data
- mNetworkTypeBitmask, // network_type_bitmask
+ NETWORK_TYPE_LTE_BITMASK, // network_type_bitmask
0, // apn_set_id
-1, // carrier_id
-1 // skip_464xlat
@@ -466,7 +461,7 @@
});
mc.addRow(new Object[]{
- 2169, // id
+ 2169 + mRowIdOffset, // id
FAKE_PLMN, // numeric
"sp-mode", // name
FAKE_APN7, // apn
@@ -499,7 +494,7 @@
});
mc.addRow(new Object[]{
- 2170, // id
+ 2170 + mRowIdOffset, // id
FAKE_PLMN, // numeric
"IMS", // name
FAKE_APN8, // apn
@@ -531,6 +526,39 @@
-1 // skip_464xlat
});
+ mc.addRow(new Object[]{
+ 2171 + mRowIdOffset, // id
+ FAKE_PLMN, // numeric
+ "sp-mode nr", // name
+ FAKE_APN9, // apn
+ "", // proxy
+ "", // port
+ "", // mmsc
+ "", // mmsproxy
+ "", // mmsport
+ "", // user
+ "", // password
+ -1, // authtype
+ "default,enterprise", // types
+ "IP", // protocol
+ "IP", // roaming_protocol
+ 1, // carrier_enabled
+ ServiceState.RIL_RADIO_TECHNOLOGY_LTE, // bearer
+ 0, // bearer_bitmask
+ 0, // profile_id
+ 1, // modem_cognitive
+ 0, // max_conns
+ 0, // wait_time
+ 0, // max_conns_time
+ 0, // mtu
+ "", // mvno_type
+ "", // mnvo_match_data
+ NETWORK_TYPE_NR_BITMASK, // network_type_bitmask
+ 0, // apn_set_id
+ -1, // carrier_id
+ -1 // skip_464xlat
+ });
+
return mc;
}
} else if (isPathPrefixMatch(uri,
@@ -776,8 +804,6 @@
@Test
@MediumTest
public void testDataSetup() throws Exception {
- mSimulatedCommands.setDataCallResult(true, createSetupDataCallResult());
-
DataConnectionReasons dataConnectionReasons = new DataConnectionReasons();
boolean allowed = isDataAllowed(dataConnectionReasons);
assertFalse(dataConnectionReasons.toString(), allowed);
@@ -950,8 +976,7 @@
waitForMs(200);
// expected tear down all metered DataConnections
verify(mSimulatedCommandsVerifier, times(2)).deactivateDataCall(
- eq(DataService.REQUEST_REASON_NORMAL), anyInt(),
- any(Message.class));
+ anyInt(), eq(DataService.REQUEST_REASON_NORMAL), any(Message.class));
assertEquals(DctConstants.State.IDLE, mDct.getState(ApnSetting.TYPE_DEFAULT_STRING));
assertEquals(DctConstants.State.IDLE, mDct.getState(ApnSetting.TYPE_MMS_STRING));
@@ -1164,30 +1189,37 @@
// Test the ENTERPRISE APN setup.
@Test
- @SmallTest
public void testTrySetupDataEnterpriseApn() {
- mApnSettingContentProvider.setFakeApn1Types("default,enterprise");
- mApnSettingContentProvider.setFakeApn1NetworkTypeBitmask(NETWORK_TYPE_NR_BITMASK);
+ mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
+ sendInitializationEvents();
+
+ ArgumentCaptor<TrafficDescriptor> tdCaptor =
+ ArgumentCaptor.forClass(TrafficDescriptor.class);
+ verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
+ eq(AccessNetworkType.EUTRAN), any(DataProfile.class), eq(false), eq(false),
+ eq(DataService.REQUEST_REASON_NORMAL), any(), anyInt(), any(), tdCaptor.capture(),
+ anyBoolean(), any(Message.class));
+ assertEquals("FAKE APN 1", tdCaptor.getValue().getDataNetworkName());
+ assertEquals(null, tdCaptor.getValue().getOsAppId());
+
mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_NR)
.setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
.build();
doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
anyInt(), anyInt());
- initApns(ApnSetting.TYPE_ENTERPRISE_STRING,
- new String[]{ApnSetting.TYPE_ENTERPRISE_STRING, ApnSetting.TYPE_DEFAULT_STRING});
+ SetupDataCallResult result = createSetupDataCallResult();
+ result.cid = 10;
+ mSimulatedCommands.setDataCallResult(true, result);
mDct.enableApn(ApnSetting.TYPE_ENTERPRISE, DcTracker.REQUEST_TYPE_NORMAL, null);
+ waitForMs(200);
- sendInitializationEvents();
-
- ArgumentCaptor<TrafficDescriptor> tdCaptor =
- ArgumentCaptor.forClass(TrafficDescriptor.class);
verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
eq(AccessNetworkType.NGRAN), any(DataProfile.class), eq(false), eq(false),
eq(DataService.REQUEST_REASON_NORMAL), any(), anyInt(), any(), tdCaptor.capture(),
anyBoolean(), any(Message.class));
- assertEquals(null, tdCaptor.getValue().getDnn());
- assertTrue(tdCaptor.getValue().getOsAppId().contains(ApnSetting.TYPE_ENTERPRISE_STRING));
+ assertEquals(null, tdCaptor.getValue().getDataNetworkName());
+ assertTrue(tdCaptor.getValue().getOsAppId().equals("ENTERPRISE"));
}
@Test
@@ -1556,7 +1588,6 @@
mApnSettingContentProvider.setFakeApn1Types("default,supl,dun");
// Enable the default apn
- mSimulatedCommands.setDataCallResult(true, createSetupDataCallResult());
mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
@@ -2339,8 +2370,6 @@
@Test
public void testRatChanged() throws Exception {
- mSimulatedCommands.setDataCallResult(true, createSetupDataCallResult());
-
DataConnectionReasons dataConnectionReasons = new DataConnectionReasons();
boolean allowed = isDataAllowed(dataConnectionReasons);
assertFalse(dataConnectionReasons.toString(), allowed);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/LinkBandwidthEstimatorTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/LinkBandwidthEstimatorTest.java
index 52b1013..e48f183 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/LinkBandwidthEstimatorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/LinkBandwidthEstimatorTest.java
@@ -19,13 +19,16 @@
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static com.android.internal.telephony.dataconnection.LinkBandwidthEstimator.BW_STATS_COUNT_THRESHOLD;
-import static com.android.internal.telephony.dataconnection.LinkBandwidthEstimator.MSG_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED;
+import static com.android.internal.telephony.dataconnection.LinkBandwidthEstimator.LINK_RX;
+import static com.android.internal.telephony.dataconnection.LinkBandwidthEstimator.LINK_TX;
import static com.android.internal.telephony.dataconnection.LinkBandwidthEstimator.MSG_DEFAULT_NETWORK_CHANGED;
import static com.android.internal.telephony.dataconnection.LinkBandwidthEstimator.MSG_MODEM_ACTIVITY_RETURNED;
import static com.android.internal.telephony.dataconnection.LinkBandwidthEstimator.MSG_NR_FREQUENCY_CHANGED;
import static com.android.internal.telephony.dataconnection.LinkBandwidthEstimator.MSG_SCREEN_STATE_CHANGED;
import static com.android.internal.telephony.dataconnection.LinkBandwidthEstimator.MSG_SIGNAL_STRENGTH_CHANGED;
+import static com.android.internal.telephony.dataconnection.LinkBandwidthEstimator.UNKNOWN_TAC;
+import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
@@ -70,7 +73,6 @@
new ModemActivityInfo(100L, 0, 0, TX_TIME_1_MS, RX_TIME_2_MS);
private NetworkCapabilities mNetworkCapabilities;
private CellIdentityLte mCellIdentity;
- private Pair<Integer, Integer> mDefaultBwKbps;
private long mElapsedTimeMs = 0;
private long mTxBytes = 0;
private long mRxBytes = 0;
@@ -78,7 +80,7 @@
TelephonyFacade mTelephonyFacade;
@Mock
DataConnection mDataConnection;
- NetworkRegistrationInfo mNri;
+ private NetworkRegistrationInfo mNri;
@Before
public void setUp() throws Exception {
@@ -88,7 +90,6 @@
.build();
mCellIdentity = new CellIdentityLte(310, 260, 1234, 123456, 366);
- mDefaultBwKbps = new Pair<>(30_000, 15_000);
mNri = new NetworkRegistrationInfo.Builder()
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
.build();
@@ -98,8 +99,8 @@
when(mTelephonyFacade.getMobileTxBytes()).thenReturn(0L);
when(mPhone.getCurrentCellIdentity()).thenReturn(mCellIdentity);
when(mDcTracker.getDataConnectionByApnType(anyString())).thenReturn(mDataConnection);
- when(mDcTracker.getLinkBandwidthsFromCarrierConfig(anyString())).thenReturn(mDefaultBwKbps);
when(mSignalStrength.getDbm()).thenReturn(-100);
+ when(mSignalStrength.getLevel()).thenReturn(1);
mLBE = new LinkBandwidthEstimator(mPhone, mTelephonyFacade);
mLBE.obtainMessage(MSG_DEFAULT_NETWORK_CHANGED, mNetworkCapabilities).sendToTarget();
processAllMessages();
@@ -166,7 +167,7 @@
processAllMessages();
verify(mTelephonyManager, times(2)).requestModemActivityInfo(any(), any());
- verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(15_000), eq(30_000));
+ verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(-1), eq(-1));
}
@Test
@@ -196,7 +197,7 @@
processAllMessages();
verify(mTelephonyManager, times(2)).requestModemActivityInfo(any(), any());
- verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(15_000), eq(30_000));
+ verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(-1), eq(-1));
}
@Test
@@ -224,7 +225,7 @@
moveTimeForward(1_100);
processAllMessages();
}
- verify(mTelephonyManager, times(4)).requestModemActivityInfo(any(), any());
+ verify(mTelephonyManager, times(2)).requestModemActivityInfo(any(), any());
}
@Test
@@ -260,14 +261,12 @@
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_NR)
.build();
when(mServiceState.getNetworkRegistrationInfo(anyInt(), anyInt())).thenReturn(mNri);
- mDefaultBwKbps = new Pair<>(300_000, 150_000);
- when(mDcTracker.getLinkBandwidthsFromCarrierConfig(anyString())).thenReturn(mDefaultBwKbps);
addElapsedTime(6000);
moveTimeForward(6000);
processAllMessages();
verify(mTelephonyManager, times(0)).requestModemActivityInfo(any(), any());
- verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(150_000), eq(300_000));
+ verify(mDataConnection, times(2)).updateLinkBandwidthEstimation(eq(-1), eq(-1));
}
@Test
@@ -277,7 +276,7 @@
for (int i = 0; i < BW_STATS_COUNT_THRESHOLD + 2; i++) {
addTxBytes(10_000L);
- addRxBytes(300_000L);
+ addRxBytes(500_000L);
addElapsedTime(5_100);
moveTimeForward(5_100);
processAllMessages();
@@ -286,8 +285,8 @@
processAllMessages();
}
- verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(15_000), eq(30_000));
- verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(15_000), eq(17_274));
+ verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(-1), eq(-1));
+ verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(-1), eq(19_597));
addTxBytes(20_000L);
addRxBytes(50_000L);
@@ -297,29 +296,50 @@
moveTimeForward(6000);
processAllMessages();
- verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(15_000), eq(25_327));
+ verify(mDataConnection, times(2)).updateLinkBandwidthEstimation(eq(-1), eq(-1));
}
@Test
- public void testCarrierConfigChangeTriggerBandwidthUpdate() throws Exception {
- mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
- addTxBytes(10_000L);
- addRxBytes(19_000L);
- addElapsedTime(2000);
- moveTimeForward(2000);
- processAllMessages();
-
- addTxBytes(10_000L);
- addRxBytes(19_000L);
- when(mSignalStrength.getLevel()).thenReturn(2);
- mDefaultBwKbps = new Pair<>(50_000, 20_000);
- when(mDcTracker.getLinkBandwidthsFromCarrierConfig(anyString())).thenReturn(mDefaultBwKbps);
- mLBE.obtainMessage(MSG_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED).sendToTarget();
- addElapsedTime(6000);
- moveTimeForward(6000);
- processAllMessages();
-
- verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(20_000), eq(50_000));
+ public void testAvgBwForAllPossibleRat() throws Exception {
+ Pair<Integer, Integer> values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_GPRS);
+ assertEquals(24, (int) values.second);
+ values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_EDGE);
+ assertEquals(18, (int) values.second);
+ values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_UMTS);
+ assertEquals(115, (int) values.second);
+ values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_CDMA);
+ assertEquals(14, (int) values.second);
+ values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_1xRTT);
+ assertEquals(30, (int) values.second);
+ values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_EVDO_0);
+ assertEquals(48, (int) values.second);
+ values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_EVDO_A);
+ assertEquals(550, (int) values.second);
+ values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_HSDPA);
+ assertEquals(620, (int) values.second);
+ values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_HSUPA);
+ assertEquals(1800, (int) values.second);
+ values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_HSPA);
+ assertEquals(1800, (int) values.second);
+ values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_EVDO_B);
+ assertEquals(550, (int) values.second);
+ values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_EHRPD);
+ assertEquals(750, (int) values.first);
+ values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_HSPAP);
+ assertEquals(3400, (int) values.second);
+ values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_TD_SCDMA);
+ assertEquals(115, (int) values.first);
+ values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_LTE);
+ assertEquals(15000, (int) values.second);
+ when(mServiceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED);
+ when(mServiceState.getNrFrequencyRange()).thenReturn(ServiceState.FREQUENCY_RANGE_MMWAVE);
+ values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_LTE);
+ assertEquals(145000, (int) values.first);
+ when(mServiceState.getNrFrequencyRange()).thenReturn(ServiceState.FREQUENCY_RANGE_UNKNOWN);
+ values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_LTE);
+ assertEquals(47000, (int) values.first);
+ values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_NR);
+ assertEquals(145_000, (int) values.first);
}
@Test
@@ -336,14 +356,12 @@
when(mServiceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED);
when(mServiceState.getNrFrequencyRange()).thenReturn(ServiceState.FREQUENCY_RANGE_MMWAVE);
when(mSignalStrength.getLevel()).thenReturn(2);
- mDefaultBwKbps = new Pair<>(500_000, 200_000);
- when(mDcTracker.getLinkBandwidthsFromCarrierConfig(anyString())).thenReturn(mDefaultBwKbps);
mLBE.obtainMessage(MSG_NR_FREQUENCY_CHANGED).sendToTarget();
addElapsedTime(6000);
moveTimeForward(6000);
processAllMessages();
- verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(200_000), eq(500_000));
+ verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(-1), eq(-1));
}
@Test
@@ -353,7 +371,7 @@
for (int i = 0; i < BW_STATS_COUNT_THRESHOLD + 2; i++) {
addTxBytes(10_000L);
- addRxBytes(300_000L);
+ addRxBytes(500_000L);
addElapsedTime(5_100);
moveTimeForward(5_100);
processAllMessages();
@@ -364,8 +382,8 @@
verify(mTelephonyManager, times(BW_STATS_COUNT_THRESHOLD + 2))
.requestModemActivityInfo(any(), any());
- verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(15_000), eq(30_000));
- verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(15_000), eq(17_274));
+ verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(-1), eq(-1));
+ verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(-1), eq(19_597));
}
@Test
@@ -375,7 +393,7 @@
for (int i = 0; i < BW_STATS_COUNT_THRESHOLD; i++) {
addTxBytes(10_000L);
- addRxBytes(300_000L);
+ addRxBytes(500_000L);
addElapsedTime(5_100);
moveTimeForward(5_100);
processAllMessages();
@@ -388,7 +406,7 @@
when(mPhone.getCurrentCellIdentity()).thenReturn(mCellIdentity);
for (int i = BW_STATS_COUNT_THRESHOLD; i < 3 * BW_STATS_COUNT_THRESHOLD; i++) {
addTxBytes(10_000L);
- addRxBytes(400_000L);
+ addRxBytes(500_000L);
addElapsedTime(5_100);
moveTimeForward(5_100);
processAllMessages();
@@ -397,18 +415,20 @@
processAllMessages();
}
- verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(15_000), eq(30_000));
- verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(15_000), eq(17_300));
+ verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(-1), eq(-1));
+ verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(-1), eq(19_597));
}
@Test
public void testUseAllTacStatsIfNoEnoughDataWithCurrentTac() throws Exception {
mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
processAllMessages();
+ mLBE.obtainMessage(MSG_SIGNAL_STRENGTH_CHANGED, mSignalStrength).sendToTarget();
+ processAllMessages();
for (int i = 0; i < BW_STATS_COUNT_THRESHOLD; i++) {
addTxBytes(10_000L);
- addRxBytes(300_000L);
+ addRxBytes(900_000L);
addElapsedTime(5_100);
moveTimeForward(5_100);
processAllMessages();
@@ -421,7 +441,7 @@
when(mPhone.getCurrentCellIdentity()).thenReturn(mCellIdentity);
for (int i = BW_STATS_COUNT_THRESHOLD; i < BW_STATS_COUNT_THRESHOLD * 3 / 2; i++) {
addTxBytes(10_000L);
- addRxBytes(400_000L);
+ addRxBytes(1_000_000L);
addElapsedTime(5_100);
moveTimeForward(5_100);
processAllMessages();
@@ -430,8 +450,18 @@
processAllMessages();
}
- verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(15_000), eq(30_000));
- verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(15_000), eq(17_300));
+ LinkBandwidthEstimator.NetworkBandwidth network = mLBE.lookupNetwork("310260", 366, "LTE");
+ assertEquals(BW_STATS_COUNT_THRESHOLD - 1, network.getCount(LINK_RX, 1));
+ assertEquals(900_000L * 8 * 1000 / 200 / 1024 * (BW_STATS_COUNT_THRESHOLD - 1),
+ network.getValue(LINK_RX, 1));
+ network = mLBE.lookupNetwork("310260", 367, "LTE");
+ assertEquals(2, network.getCount(LINK_RX, 1));
+ assertEquals(1_000_000L * 8 * 1000 / 200 / 1024 * 2,
+ network.getValue(LINK_RX, 1));
+ network = mLBE.lookupNetwork("310260", UNKNOWN_TAC, "LTE");
+ assertEquals(BW_STATS_COUNT_THRESHOLD * 3 / 2 - 1, network.getCount(LINK_RX, 1));
+ assertEquals(218_748, network.getValue(LINK_RX, 1));
+ verify(mDataConnection, times(2)).updateLinkBandwidthEstimation(eq(-1), eq(-1));
}
@Test
@@ -441,7 +471,7 @@
for (int i = 0; i < BW_STATS_COUNT_THRESHOLD + 5; i++) {
addTxBytes(10_000L);
- addRxBytes(300_000L);
+ addRxBytes(500_000L);
addElapsedTime(5_100);
moveTimeForward(5_100);
processAllMessages();
@@ -450,8 +480,8 @@
processAllMessages();
}
- verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(15_000), eq(30_000));
- verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(15_000), eq(17_274));
+ verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(-1), eq(-1));
+ verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(-1), eq(19_597));
mCellIdentity = new CellIdentityLte(320, 265, 1234, 123456, 366);
when(mPhone.getCurrentCellIdentity()).thenReturn(mCellIdentity);
@@ -462,6 +492,56 @@
moveTimeForward(5_100);
processAllMessages();
- verify(mDataConnection, times(2)).updateLinkBandwidthEstimation(eq(15_000), eq(30_000));
+ verify(mDataConnection, times(2)).updateLinkBandwidthEstimation(eq(-1), eq(-1));
+ }
+
+ @Test
+ public void testIgnoreLowTxRxTime() throws Exception {
+ mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
+ processAllMessages();
+
+ for (int i = 0; i < BW_STATS_COUNT_THRESHOLD + 5; i++) {
+ addTxBytes(10_000L);
+ addRxBytes(500_000L);
+ addElapsedTime(5_100);
+ moveTimeForward(5_100);
+ processAllMessages();
+ mLBE.obtainMessage(MSG_MODEM_ACTIVITY_RETURNED, new ModemActivityInfo(
+ i * 5_100L, 0, 0, TX_TIME_2_MS, i * 80)).sendToTarget();
+ processAllMessages();
+ }
+
+ verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(-1), eq(-1));
+ verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(anyInt(), anyInt());
+ }
+
+ @Test
+ public void testUseHighTxRxByteEdge() throws Exception {
+ mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
+ processAllMessages();
+ mNri = new NetworkRegistrationInfo.Builder()
+ .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_EDGE)
+ .build();
+ when(mServiceState.getNetworkRegistrationInfo(anyInt(), anyInt())).thenReturn(mNri);
+ mLBE.obtainMessage(MSG_SIGNAL_STRENGTH_CHANGED, mSignalStrength).sendToTarget();
+ processAllMessages();
+ for (int i = 0; i < BW_STATS_COUNT_THRESHOLD + 5; i++) {
+ addTxBytes(12_000L);
+ addRxBytes(12_000L);
+ addElapsedTime(5_100);
+ moveTimeForward(5_100);
+ processAllMessages();
+ mLBE.obtainMessage(MSG_MODEM_ACTIVITY_RETURNED, new ModemActivityInfo(
+ i * 5_100L, 0, 0, TX_TIME_2_MS, i * RX_TIME_2_MS * 5)).sendToTarget();
+ processAllMessages();
+ }
+
+ LinkBandwidthEstimator.NetworkBandwidth network = mLBE.lookupNetwork("310260", 366, "EDGE");
+
+ assertEquals(0, network.getCount(LINK_TX, 1));
+ assertEquals(BW_STATS_COUNT_THRESHOLD + 4, network.getCount(LINK_RX, 1));
+ assertEquals(12_000L * 8 / 1024 * (BW_STATS_COUNT_THRESHOLD + 4),
+ network.getValue(LINK_RX, 1));
+ verify(mDataConnection, times(1)).updateLinkBandwidthEstimation(eq(-1), eq(92));
}
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/QosCallbackTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/QosCallbackTrackerTest.java
index d886b3d..7434662 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/QosCallbackTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/QosCallbackTrackerTest.java
@@ -258,7 +258,7 @@
qosSessions.remove(1);
mQosCallbackTracker.updateSessions(qosSessions);
- verify(mDcNetworkAgent, times(1)).notifyQosSessionLost(eq(1), eq(1235));
+ verify(mDcNetworkAgent, times(1)).notifyQosSessionLost(eq(1), eq(1235), eq(1));
}
@Test
@@ -380,8 +380,8 @@
// Update empty QOS sessions list
mQosCallbackTracker.updateSessions(new ArrayList<>());
- verify(mDcNetworkAgent, times(1)).notifyQosSessionLost(eq(1), eq(1234));
- verify(mDcNetworkAgent, times(1)).notifyQosSessionLost(eq(2), eq(1235));
+ verify(mDcNetworkAgent, times(1)).notifyQosSessionLost(eq(1), eq(1234), eq(1));
+ verify(mDcNetworkAgent, times(1)).notifyQosSessionLost(eq(2), eq(1235), eq(1));
}
@Test
@@ -423,8 +423,8 @@
// Update empty QOS sessions list
mQosCallbackTracker.updateSessions(new ArrayList<>());
- verify(mDcNetworkAgent, times(1)).notifyQosSessionLost(eq(1), eq(1234));
- verify(mDcNetworkAgent, times(1)).notifyQosSessionLost(eq(2), eq(1235));
+ verify(mDcNetworkAgent, times(1)).notifyQosSessionLost(eq(1), eq(1234), eq(1));
+ verify(mDcNetworkAgent, times(1)).notifyQosSessionLost(eq(2), eq(1235), eq(1));
}
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
index ceb5acc..aacfd4a 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
@@ -1376,7 +1376,7 @@
if (rxBytes != 0 || txBytes != 0) {
expectedStats = expectedStats.addEntry(
- new Entry(NetworkStats.IFACE_VT, UID_ALL, SET_FOREGROUND,
+ new Entry(mCTUT.getVtInterface(), UID_ALL, SET_FOREGROUND,
TAG_NONE, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, rxBytes, 0L,
txBytes, 0L, 0L));
}