Merge "Fixed the mismatched protocol anomaly detector" into tm-qpr-dev am: 087c47037c
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/opt/telephony/+/20956705
Change-Id: I8f8d3bb832a712094220746df28c691b1b2b67dc
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/OWNERS b/OWNERS
index 94509fe..1c2928e 100644
--- a/OWNERS
+++ b/OWNERS
@@ -14,8 +14,14 @@
sasindran@google.com
tgunn@google.com
tjstuart@google.com
+tnd@google.com
xiaotonj@google.com
+# Temporarily reduced the owner during refactoring
+per-file SubscriptionController.java=set noparent
+per-file SubscriptionController.java=jackyu@google.com,amruthr@google.com
+per-file SubscriptionInfoUpdater.java=set noparent
+per-file SubscriptionInfoUpdater.java=jackyu@google.com,amruthr@google.com
diff --git a/proto/src/persist_atoms.proto b/proto/src/persist_atoms.proto
index 6a75c3f..3a79cdc 100644
--- a/proto/src/persist_atoms.proto
+++ b/proto/src/persist_atoms.proto
@@ -190,10 +190,10 @@
// NOTE: StatsLog functions use int in place of enum
message VoiceCallSession {
+ reserved 4;
optional int32 bearer_at_start = 1;
optional int32 bearer_at_end = 2;
optional int32 direction = 3;
- optional int32 setup_duration = 4;
optional bool setup_failed = 5;
optional int32 disconnect_reason_code = 6;
optional int32 disconnect_extra_code = 7;
diff --git a/src/java/com/android/internal/telephony/CarrierActionAgent.java b/src/java/com/android/internal/telephony/CarrierActionAgent.java
index 42a4f23..6d74c18 100644
--- a/src/java/com/android/internal/telephony/CarrierActionAgent.java
+++ b/src/java/com/android/internal/telephony/CarrierActionAgent.java
@@ -27,6 +27,7 @@
import android.os.RegistrantList;
import android.provider.Settings;
import android.provider.Telephony;
+import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.LocalLog;
import android.util.Log;
@@ -93,7 +94,11 @@
// ignore rebroadcast since carrier apps are direct boot aware.
return;
}
- sendMessage(obtainMessage(EVENT_SIM_STATE_CHANGED, iccState));
+ final int phoneId = intent.getIntExtra(PhoneConstants.PHONE_KEY,
+ SubscriptionManager.INVALID_PHONE_INDEX);
+ if (mPhone.getPhoneId() == phoneId) {
+ sendMessage(obtainMessage(EVENT_SIM_STATE_CHANGED, iccState));
+ }
}
}
};
diff --git a/src/java/com/android/internal/telephony/CarrierSignalAgent.java b/src/java/com/android/internal/telephony/CarrierSignalAgent.java
index 2914ff9..8509c5e 100644
--- a/src/java/com/android/internal/telephony/CarrierSignalAgent.java
+++ b/src/java/com/android/internal/telephony/CarrierSignalAgent.java
@@ -48,7 +48,6 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -102,26 +101,24 @@
/**
* This is a list of supported signals from CarrierSignalAgent
*/
- private static final Set<String> VALID_CARRIER_SIGNAL_ACTIONS = new HashSet<>(Arrays.asList(
+ private static final Set<String> VALID_CARRIER_SIGNAL_ACTIONS = Set.of(
TelephonyManager.ACTION_CARRIER_SIGNAL_PCO_VALUE,
TelephonyManager.ACTION_CARRIER_SIGNAL_REDIRECTED,
TelephonyManager.ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED,
TelephonyManager.ACTION_CARRIER_SIGNAL_RESET,
- TelephonyManager.ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE));
+ TelephonyManager.ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE);
- private static final Map<String, String> NEW_ACTION_TO_COMPAT_MAP =
- new HashMap<String, String>() {{
- put(TelephonyManager.ACTION_CARRIER_SIGNAL_PCO_VALUE,
- TelephonyIntents.ACTION_CARRIER_SIGNAL_PCO_VALUE);
- put(TelephonyManager.ACTION_CARRIER_SIGNAL_REDIRECTED,
- TelephonyIntents.ACTION_CARRIER_SIGNAL_REDIRECTED);
- put(TelephonyManager.ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED,
- TelephonyIntents.ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED);
- put(TelephonyManager.ACTION_CARRIER_SIGNAL_RESET,
- TelephonyIntents.ACTION_CARRIER_SIGNAL_RESET);
- put(TelephonyManager.ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE,
- TelephonyIntents.ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE);
- }};
+ private static final Map<String, String> NEW_ACTION_TO_COMPAT_MAP = Map.of(
+ TelephonyManager.ACTION_CARRIER_SIGNAL_PCO_VALUE,
+ TelephonyIntents.ACTION_CARRIER_SIGNAL_PCO_VALUE,
+ TelephonyManager.ACTION_CARRIER_SIGNAL_REDIRECTED,
+ TelephonyIntents.ACTION_CARRIER_SIGNAL_REDIRECTED,
+ TelephonyManager.ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED,
+ TelephonyIntents.ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED,
+ TelephonyManager.ACTION_CARRIER_SIGNAL_RESET,
+ TelephonyIntents.ACTION_CARRIER_SIGNAL_RESET,
+ TelephonyManager.ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE,
+ TelephonyIntents.ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE);
private static final Map<String, String> COMPAT_ACTION_TO_NEW_MAP = NEW_ACTION_TO_COMPAT_MAP
.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
diff --git a/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java b/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
index 3293558..7738b44 100755
--- a/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
@@ -182,11 +182,6 @@
mCi.unregisterForCallWaitingInfo(this);
// Prior to phone switch to GSM, if CDMA has any emergency call
// data will be in disabled state, after switching to GSM enable data.
- if (mIsInEmergencyCall) {
- if (!mPhone.isUsingNewDataStack()) {
- mPhone.getDataEnabledSettings().setInternalDataEnabled(true);
- }
- }
} else {
mConnections = new GsmCdmaConnection[MAX_CONNECTIONS_CDMA];
mPendingCallInEcm = false;
@@ -400,9 +395,6 @@
//CDMA
public void setIsInEmergencyCall() {
mIsInEmergencyCall = true;
- if (!mPhone.isUsingNewDataStack()) {
- mPhone.getDataEnabledSettings().setInternalDataEnabled(false);
- }
mPhone.notifyEmergencyCallRegistrants(true);
mPhone.sendEmergencyCallStateChange(true);
}
@@ -1754,9 +1746,6 @@
}
if (!inEcm) {
// Re-initiate data connection
- if (!mPhone.isUsingNewDataStack()) {
- mPhone.getDataEnabledSettings().setInternalDataEnabled(true);
- }
mPhone.notifyEmergencyCallRegistrants(false);
}
mPhone.sendEmergencyCallStateChange(false);
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index 76a8d57..932461c 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -64,7 +64,6 @@
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
-import android.telephony.AccessNetworkConstants;
import android.telephony.Annotation.DataActivityType;
import android.telephony.Annotation.RadioPowerState;
import android.telephony.BarringInfo;
@@ -82,7 +81,6 @@
import android.telephony.TelephonyManager;
import android.telephony.UiccAccessRule;
import android.telephony.UssdResponse;
-import android.telephony.data.ApnSetting;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
@@ -94,9 +92,6 @@
import com.android.internal.telephony.data.AccessNetworksManager;
import com.android.internal.telephony.data.DataNetworkController;
import com.android.internal.telephony.data.LinkBandwidthEstimator;
-import com.android.internal.telephony.dataconnection.DataEnabledSettings;
-import com.android.internal.telephony.dataconnection.DcTracker;
-import com.android.internal.telephony.dataconnection.TransportManager;
import com.android.internal.telephony.emergency.EmergencyNumberTracker;
import com.android.internal.telephony.gsm.GsmMmiCode;
import com.android.internal.telephony.gsm.SuppServiceNotification;
@@ -271,8 +266,6 @@
private CarrierKeyDownloadManager mCDM;
private CarrierInfoManager mCIM;
- private final SettingsObserver mSettingsObserver;
-
private final ImsManagerFactory mImsManagerFactory;
private final CarrierPrivilegesTracker mCarrierPrivilegesTracker;
@@ -316,10 +309,6 @@
mAccessNetworksManager = mTelephonyComponentFactory
.inject(AccessNetworksManager.class.getName())
.makeAccessNetworksManager(this, getLooper());
- if (!isUsingNewDataStack()) {
- mTransportManager = mTelephonyComponentFactory.inject(TransportManager.class.getName())
- .makeTransportManager(this);
- }
// SST/DSM depends on SSC, so SSC is instanced before SST/DSM
mSignalStrengthController = mTelephonyComponentFactory.inject(
SignalStrengthController.class.getName()).makeSignalStrengthController(this);
@@ -328,10 +317,6 @@
mEmergencyNumberTracker = mTelephonyComponentFactory
.inject(EmergencyNumberTracker.class.getName()).makeEmergencyNumberTracker(
this, this.mCi);
- if (!isUsingNewDataStack()) {
- mDataEnabledSettings = mTelephonyComponentFactory
- .inject(DataEnabledSettings.class.getName()).makeDataEnabledSettings(this);
- }
mDeviceStateMonitor = mTelephonyComponentFactory.inject(DeviceStateMonitor.class.getName())
.makeDeviceStateMonitor(this);
@@ -340,20 +325,9 @@
mDisplayInfoController = mTelephonyComponentFactory.inject(
DisplayInfoController.class.getName()).makeDisplayInfoController(this);
- if (isUsingNewDataStack()) {
- mDataNetworkController = mTelephonyComponentFactory.inject(
- DataNetworkController.class.getName())
- .makeDataNetworkController(this, getLooper());
- } else {
- // DcTracker uses ServiceStateTracker and DisplayInfoController so needs to be created
- // after they are instantiated
- for (int transport : mAccessNetworksManager.getAvailableTransports()) {
- DcTracker dcTracker = mTelephonyComponentFactory.inject(DcTracker.class.getName())
- .makeDcTracker(this, transport);
- mDcTrackers.put(transport, dcTracker);
- mAccessNetworksManager.registerDataThrottler(dcTracker.getDataThrottler());
- }
- }
+ mDataNetworkController = mTelephonyComponentFactory.inject(
+ DataNetworkController.class.getName())
+ .makeDataNetworkController(this, getLooper());
mCarrierResolver = mTelephonyComponentFactory.inject(CarrierResolver.class.getName())
.makeCarrierResolver(this);
@@ -366,15 +340,6 @@
mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null);
mSST.registerForVoiceRegStateOrRatChanged(this, EVENT_VRS_OR_RAT_CHANGED, null);
- // TODO: Remove SettingsObserver and provisioning events when DataEnabledSettings is removed
- mSettingsObserver = new SettingsObserver(context, this);
- mSettingsObserver.observe(
- Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
- EVENT_DEVICE_PROVISIONED_CHANGE);
- mSettingsObserver.observe(
- Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED),
- EVENT_DEVICE_PROVISIONING_DATA_SETTING_CHANGE);
-
SubscriptionController.getInstance().registerForUiccAppsEnabled(this,
EVENT_UICC_APPS_ENABLEMENT_SETTING_CHANGED, null, false);
@@ -680,11 +645,6 @@
}
@Override
- public TransportManager getTransportManager() {
- return mTransportManager;
- }
-
- @Override
public AccessNetworksManager getAccessNetworksManager() {
return mAccessNetworksManager;
}
@@ -736,83 +696,8 @@
}
@Override
- public PhoneConstants.DataState getDataConnectionState(String apnType) {
- PhoneConstants.DataState ret = PhoneConstants.DataState.DISCONNECTED;
-
- if (mSST == null) {
- // Radio Technology Change is ongoing, dispose() and removeReferences() have
- // already been called
-
- ret = PhoneConstants.DataState.DISCONNECTED;
- } else if (mSST.getCurrentDataConnectionState() != ServiceState.STATE_IN_SERVICE
- && (isPhoneTypeCdma() || isPhoneTypeCdmaLte() ||
- (isPhoneTypeGsm() && !apnType.equals(ApnSetting.TYPE_EMERGENCY_STRING)))) {
- // If we're out of service, open TCP sockets may still work
- // but no data will flow
-
- // Emergency APN is available even in Out Of Service
- // Pass the actual State of EPDN
-
- ret = PhoneConstants.DataState.DISCONNECTED;
- } else { /* mSST.gprsState == ServiceState.STATE_IN_SERVICE */
- int currentTransport = mAccessNetworksManager.getCurrentTransport(
- ApnSetting.getApnTypesBitmaskFromString(apnType));
- if (getDcTracker(currentTransport) != null) {
- switch (getDcTracker(currentTransport).getState(apnType)) {
- case CONNECTED:
- case DISCONNECTING:
- if (isDataSuspended()) {
- ret = PhoneConstants.DataState.SUSPENDED;
- } else {
- ret = PhoneConstants.DataState.CONNECTED;
- }
- break;
- case CONNECTING:
- ret = PhoneConstants.DataState.CONNECTING;
- break;
- default:
- ret = PhoneConstants.DataState.DISCONNECTED;
- }
- }
- }
-
- logd("getDataConnectionState apnType=" + apnType + " ret=" + ret);
- return ret;
- }
-
- @Override
public @DataActivityType int getDataActivityState() {
- if (isUsingNewDataStack()) {
- return getDataNetworkController().getDataActivity();
- }
- int ret = TelephonyManager.DATA_ACTIVITY_NONE;
-
- if (mSST.getCurrentDataConnectionState() == ServiceState.STATE_IN_SERVICE
- && getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) != null) {
- switch (getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).getActivity()) {
- case DATAIN:
- ret = TelephonyManager.DATA_ACTIVITY_IN;
- break;
-
- case DATAOUT:
- ret = TelephonyManager.DATA_ACTIVITY_OUT;
- break;
-
- case DATAINANDOUT:
- ret = TelephonyManager.DATA_ACTIVITY_INOUT;
- break;
-
- case DORMANT:
- ret = TelephonyManager.DATA_ACTIVITY_DORMANT;
- break;
-
- default:
- ret = TelephonyManager.DATA_ACTIVITY_NONE;
- break;
- }
- }
-
- return ret;
+ return getDataNetworkController().getDataActivity();
}
/**
@@ -2672,25 +2557,12 @@
@Override
public boolean getDataRoamingEnabled() {
- if (isUsingNewDataStack()) {
- return getDataSettingsManager().isDataRoamingEnabled();
- }
- if (getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) != null) {
- return getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).getDataRoamingEnabled();
- }
- return false;
+ return getDataSettingsManager().isDataRoamingEnabled();
}
@Override
public void setDataRoamingEnabled(boolean enable) {
- if (isUsingNewDataStack()) {
- getDataSettingsManager().setDataRoamingEnabled(enable);
- return;
- }
- if (getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) != null) {
- getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
- .setDataRoamingEnabledByUser(enable);
- }
+ getDataSettingsManager().setDataRoamingEnabled(enable);
}
@Override
@@ -2735,21 +2607,12 @@
}
/**
- * Whether data is enabled by user. Unlike isDataEnabled, this only
- * checks user setting stored in {@link android.provider.Settings.Global#MOBILE_DATA}
- * if not provisioning, or isProvisioningDataEnabled if provisioning.
+ * Whether data is enabled by user.
*/
@Override
public boolean isUserDataEnabled() {
- if (isUsingNewDataStack()) {
- return getDataSettingsManager().isDataEnabledForReason(
- TelephonyManager.DATA_ENABLED_REASON_USER);
- }
- if (mDataEnabledSettings.isProvisioning()) {
- return mDataEnabledSettings.isProvisioningDataEnabled();
- } else {
- return mDataEnabledSettings.isUserDataEnabled();
- }
+ return getDataSettingsManager().isDataEnabledForReason(
+ TelephonyManager.DATA_ENABLED_REASON_USER);
}
/**
@@ -3283,24 +3146,9 @@
case EVENT_SET_CARRIER_DATA_ENABLED:
ar = (AsyncResult) msg.obj;
boolean enabled = (boolean) ar.result;
- if (isUsingNewDataStack()) {
- getDataSettingsManager().setDataEnabled(
- TelephonyManager.DATA_ENABLED_REASON_CARRIER, enabled,
- mContext.getOpPackageName());
- return;
- }
- mDataEnabledSettings.setDataEnabled(TelephonyManager.DATA_ENABLED_REASON_CARRIER,
- enabled);
- break;
- case EVENT_DEVICE_PROVISIONED_CHANGE:
- if (!isUsingNewDataStack()) {
- mDataEnabledSettings.updateProvisionedChanged();
- }
- break;
- case EVENT_DEVICE_PROVISIONING_DATA_SETTING_CHANGE:
- if (!isUsingNewDataStack()) {
- mDataEnabledSettings.updateProvisioningDataEnabled();
- }
+ getDataSettingsManager().setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_CARRIER, enabled,
+ mContext.getOpPackageName());
break;
case EVENT_GET_AVAILABLE_NETWORKS_DONE:
ar = (AsyncResult) msg.obj;
@@ -3795,10 +3643,6 @@
// send an Intent
sendEmergencyCallbackModeChange();
- // Re-initiate data connection
- if (!isUsingNewDataStack()) {
- mDataEnabledSettings.setInternalDataEnabled(true);
- }
notifyEmergencyCallRegistrants(false);
}
mIsTestingEmergencyCallbackMode = false;
@@ -4745,24 +4589,7 @@
* @return Currently bound data service package names.
*/
public @NonNull List<String> getDataServicePackages() {
- if (isUsingNewDataStack()) {
- return getDataNetworkController().getDataServicePackages();
- }
- List<String> packages = new ArrayList<>();
- int[] transports = new int[]{AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
- AccessNetworkConstants.TRANSPORT_TYPE_WLAN};
-
- for (int transport : transports) {
- DcTracker dct = getDcTracker(transport);
- if (dct != null) {
- String pkg = dct.getDataServiceManager().getDataServicePackageName();
- if (!TextUtils.isEmpty(pkg)) {
- packages.add(pkg);
- }
- }
- }
-
- return packages;
+ return getDataNetworkController().getDataServicePackages();
}
private void updateBroadcastEmergencyCallStateChangesAfterCarrierConfigChanged(
diff --git a/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java b/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
index a329771..d3e6a0d 100644
--- a/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
+++ b/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
@@ -625,9 +625,9 @@
}
if (Rlog.isLoggable("SMS", Log.VERBOSE)) {
- log("pdu: " + pdu +
- "\n format=" + format +
- "\n receivedIntent=" + receivedIntent);
+ log("pdu: " + IccUtils.bytesToHexString(pdu)
+ + "\n format=" + format
+ + "\n receivedIntent=" + receivedIntent);
}
mDispatchersController.injectSmsPdu(pdu, format, false /* isOverIms */,
result -> {
diff --git a/src/java/com/android/internal/telephony/InboundSmsHandler.java b/src/java/com/android/internal/telephony/InboundSmsHandler.java
index eeda1f9..8f43dce 100644
--- a/src/java/com/android/internal/telephony/InboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/InboundSmsHandler.java
@@ -89,7 +89,6 @@
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
@@ -116,38 +115,6 @@
protected static final boolean DBG = true;
protected static final boolean VDBG = false; // STOPSHIP if true, logs user data
- /** Query projection for checking for duplicate message segments. */
- private static final String[] PDU_DELETED_FLAG_PROJECTION = {
- "pdu",
- "deleted"
- };
-
- /** Mapping from DB COLUMN to PDU_SEQUENCE_PORT PROJECTION index */
- private static final Map<Integer, Integer> PDU_DELETED_FLAG_PROJECTION_INDEX_MAPPING =
- new HashMap<Integer, Integer>() {{
- put(PDU_COLUMN, 0);
- put(DELETED_FLAG_COLUMN, 1);
- }};
-
- /** Query projection for combining concatenated message segments. */
- private static final String[] PDU_SEQUENCE_PORT_PROJECTION = {
- "pdu",
- "sequence",
- "destination_port",
- "display_originating_addr",
- "date"
- };
-
- /** Mapping from DB COLUMN to PDU_SEQUENCE_PORT PROJECTION index */
- private static final Map<Integer, Integer> PDU_SEQUENCE_PORT_PROJECTION_INDEX_MAPPING =
- new HashMap<Integer, Integer>() {{
- put(PDU_COLUMN, 0);
- put(SEQUENCE_COLUMN, 1);
- put(DESTINATION_PORT_COLUMN, 2);
- put(DISPLAY_ADDRESS_COLUMN, 3);
- put(DATE_COLUMN, 4);
- }};
-
public static final int PDU_COLUMN = 0;
public static final int SEQUENCE_COLUMN = 1;
public static final int DESTINATION_PORT_COLUMN = 2;
@@ -161,6 +128,34 @@
public static final int DELETED_FLAG_COLUMN = 10;
public static final int SUBID_COLUMN = 11;
+ /** Query projection for checking for duplicate message segments. */
+ private static final String[] PDU_DELETED_FLAG_PROJECTION = {
+ "pdu",
+ "deleted"
+ };
+
+ /** Mapping from DB COLUMN to PDU_SEQUENCE_PORT PROJECTION index */
+ private static final Map<Integer, Integer> PDU_DELETED_FLAG_PROJECTION_INDEX_MAPPING = Map.of(
+ PDU_COLUMN, 0,
+ DELETED_FLAG_COLUMN, 1);
+
+ /** Query projection for combining concatenated message segments. */
+ private static final String[] PDU_SEQUENCE_PORT_PROJECTION = {
+ "pdu",
+ "sequence",
+ "destination_port",
+ "display_originating_addr",
+ "date"
+ };
+
+ /** Mapping from DB COLUMN to PDU_SEQUENCE_PORT PROJECTION index */
+ private static final Map<Integer, Integer> PDU_SEQUENCE_PORT_PROJECTION_INDEX_MAPPING = Map.of(
+ PDU_COLUMN, 0,
+ SEQUENCE_COLUMN, 1,
+ DESTINATION_PORT_COLUMN, 2,
+ DISPLAY_ADDRESS_COLUMN, 3,
+ DATE_COLUMN, 4);
+
public static final String SELECT_BY_ID = "_id=?";
/** New SMS received as an AsyncResult. */
diff --git a/src/java/com/android/internal/telephony/MultiSimSettingController.java b/src/java/com/android/internal/telephony/MultiSimSettingController.java
index 85053de..f3b91df 100644
--- a/src/java/com/android/internal/telephony/MultiSimSettingController.java
+++ b/src/java/com/android/internal/telephony/MultiSimSettingController.java
@@ -850,14 +850,9 @@
&& phone.isUserDataEnabled()
&& !areSubscriptionsInSameGroup(defaultDataSub, phone.getSubId())) {
log("setting data to false on " + phone.getSubId());
- if (phone.isUsingNewDataStack()) {
- phone.getDataSettingsManager().setDataEnabled(
- TelephonyManager.DATA_ENABLED_REASON_USER, false,
- mContext.getOpPackageName());
- } else {
- phone.getDataEnabledSettings().setDataEnabled(
- TelephonyManager.DATA_ENABLED_REASON_USER, false);
- }
+ phone.getDataSettingsManager().setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_USER, false,
+ mContext.getOpPackageName());
}
}
}
@@ -893,13 +888,9 @@
// If enable is true and it's not opportunistic subscription, we don't enable it,
// as there can't be two
if (phone != null) {
- if (phone.isUsingNewDataStack()) {
- phone.getDataSettingsManager().setDataEnabled(
- TelephonyManager.DATA_ENABLED_REASON_USER, enable,
- mContext.getOpPackageName());
- } else {
- phone.getDataEnabledSettings().setUserDataEnabled(enable, false);
- }
+ phone.getDataSettingsManager().setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_USER, enable,
+ mContext.getOpPackageName());
}
} else {
// For inactive subscription, directly write into global settings.
@@ -1074,10 +1065,8 @@
// existing phone instance.
Phone[] phones = PhoneFactory.getPhones();
for (int i = mCallbacksCount; i < phones.length; i++) {
- if (phones[i].isUsingNewDataStack()) {
- phones[i].getDataSettingsManager().registerCallback(
- new DataSettingsControllerCallback(phones[i], this::post));
- }
+ phones[i].getDataSettingsManager().registerCallback(
+ new DataSettingsControllerCallback(phones[i], this::post));
}
mCallbacksCount = phones.length;
}
diff --git a/src/java/com/android/internal/telephony/NetworkTypeController.java b/src/java/com/android/internal/telephony/NetworkTypeController.java
index 5c9c848..f39c79b 100644
--- a/src/java/com/android/internal/telephony/NetworkTypeController.java
+++ b/src/java/com/android/internal/telephony/NetworkTypeController.java
@@ -16,6 +16,7 @@
package com.android.internal.telephony;
+import android.annotation.Nullable;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -28,20 +29,16 @@
import android.telephony.Annotation;
import android.telephony.CarrierConfigManager;
import android.telephony.NetworkRegistrationInfo;
-import android.telephony.PcoData;
import android.telephony.PhysicalChannelConfig;
import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyDisplayInfo;
import android.telephony.TelephonyManager;
-import android.telephony.data.ApnSetting;
import android.telephony.data.DataCallResponse;
import android.telephony.data.DataCallResponse.LinkStatus;
import android.text.TextUtils;
import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback;
-import com.android.internal.telephony.dataconnection.DataConnection;
-import com.android.internal.telephony.dataconnection.DcTracker;
import com.android.internal.telephony.util.ArrayUtils;
import com.android.internal.util.IState;
import com.android.internal.util.IndentingPrintWriter;
@@ -99,7 +96,6 @@
private static final int EVENT_PREFERRED_NETWORK_MODE_CHANGED = 11;
private static final int EVENT_INITIALIZE = 12;
private static final int EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED = 13;
- private static final int EVENT_PCO_DATA_CHANGED = 14;
private static final int EVENT_BANDWIDTH_CHANGED = 15;
private static final int EVENT_UPDATE_NR_ADVANCED_STATE = 16;
private static final int EVENT_DEVICE_IDLE_MODE_CHANGED = 17;
@@ -121,7 +117,6 @@
sEvents[EVENT_PREFERRED_NETWORK_MODE_CHANGED] = "EVENT_PREFERRED_NETWORK_MODE_CHANGED";
sEvents[EVENT_INITIALIZE] = "EVENT_INITIALIZE";
sEvents[EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED] = "EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED";
- sEvents[EVENT_PCO_DATA_CHANGED] = "EVENT_PCO_DATA_CHANGED";
sEvents[EVENT_BANDWIDTH_CHANGED] = "EVENT_BANDWIDTH_CHANGED";
sEvents[EVENT_UPDATE_NR_ADVANCED_STATE] = "EVENT_UPDATE_NR_ADVANCED_STATE";
sEvents[EVENT_DEVICE_IDLE_MODE_CHANGED] = "EVENT_DEVICE_IDLE_MODE_CHANGED";
@@ -170,6 +165,9 @@
private boolean mEnableNrAdvancedWhileRoaming = true;
private boolean mIsDeviceIdleMode = false;
+ private @Nullable DataNetworkControllerCallback mNrAdvancedCapableByPcoChangedCallback = null;
+ private @Nullable DataNetworkControllerCallback mNrPhysicalLinkStatusChangedCallback = null;
+
/**
* NetworkTypeController constructor.
*
@@ -233,9 +231,6 @@
filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
filter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
- if (!mPhone.isUsingNewDataStack()) {
- mPhone.mCi.registerForPcoData(getHandler(), EVENT_PCO_DATA_CHANGED, null);
- }
}
private void unRegisterForAllEvents() {
@@ -247,9 +242,6 @@
mPhone.getServiceStateTracker().unregisterForNrFrequencyChanged(getHandler());
mPhone.getDeviceStateMonitor().unregisterForPhysicalChannelConfigNotifChanged(getHandler());
mPhone.getContext().unregisterReceiver(mIntentReceiver);
- if (!mPhone.isUsingNewDataStack()) {
- mPhone.mCi.unregisterForPcoData(getHandler());
- }
}
private void parseCarrierConfigs() {
@@ -313,38 +305,47 @@
CarrierConfigManager.KEY_ADDITIONAL_NR_ADVANCED_BANDS_INT_ARRAY);
mNrAdvancedCapablePcoId = b.getInt(
CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT);
- if (mNrAdvancedCapablePcoId > 0 && mPhone.isUsingNewDataStack()) {
- mPhone.getDataNetworkController().registerDataNetworkControllerCallback(
+ if (mNrAdvancedCapablePcoId > 0 && mNrAdvancedCapableByPcoChangedCallback == null) {
+ mNrAdvancedCapableByPcoChangedCallback =
new DataNetworkControllerCallback(getHandler()::post) {
- @Override
- public void onNrAdvancedCapableByPcoChanged(
- boolean nrAdvancedCapable) {
- log("mIsNrAdvancedAllowedByPco=" + nrAdvancedCapable);
- mIsNrAdvancedAllowedByPco = nrAdvancedCapable;
- sendMessage(EVENT_UPDATE_NR_ADVANCED_STATE);
- }
- });
+ @Override
+ public void onNrAdvancedCapableByPcoChanged(
+ boolean nrAdvancedCapable) {
+ log("mIsNrAdvancedAllowedByPco=" + nrAdvancedCapable);
+ mIsNrAdvancedAllowedByPco = nrAdvancedCapable;
+ sendMessage(EVENT_UPDATE_NR_ADVANCED_STATE);
+ }
+ };
+ mPhone.getDataNetworkController().registerDataNetworkControllerCallback(
+ mNrAdvancedCapableByPcoChangedCallback);
+ } else if (mNrAdvancedCapablePcoId == 0
+ && mNrAdvancedCapableByPcoChangedCallback != null) {
+ mPhone.getDataNetworkController().unregisterDataNetworkControllerCallback(
+ mNrAdvancedCapableByPcoChangedCallback);
+ mNrAdvancedCapableByPcoChangedCallback = null;
}
mEnableNrAdvancedWhileRoaming = b.getBoolean(
CarrierConfigManager.KEY_ENABLE_NR_ADVANCED_WHILE_ROAMING_BOOL);
mIsUsingUserDataForRrcDetection = b.getBoolean(
CarrierConfigManager.KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL);
if (!mIsPhysicalChannelConfig16Supported || mIsUsingUserDataForRrcDetection) {
- if (mPhone.isUsingNewDataStack()) {
- mPhone.getDataNetworkController().registerDataNetworkControllerCallback(
+ if (mNrPhysicalLinkStatusChangedCallback == null) {
+ mNrPhysicalLinkStatusChangedCallback =
new DataNetworkControllerCallback(getHandler()::post) {
- @Override
- public void onPhysicalLinkStatusChanged(
- @LinkStatus int status) {
- sendMessage(obtainMessage(
- EVENT_PHYSICAL_LINK_STATUS_CHANGED,
- new AsyncResult(null, status, null)));
- }});
- } else {
- mPhone.getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
- .registerForPhysicalLinkStatusChanged(getHandler(),
- EVENT_PHYSICAL_LINK_STATUS_CHANGED);
+ @Override
+ public void onPhysicalLinkStatusChanged(
+ @LinkStatus int status) {
+ sendMessage(obtainMessage(
+ EVENT_PHYSICAL_LINK_STATUS_CHANGED,
+ new AsyncResult(null, status, null)));
+ }};
+ mPhone.getDataNetworkController().registerDataNetworkControllerCallback(
+ mNrPhysicalLinkStatusChangedCallback);
}
+ } else if (mNrPhysicalLinkStatusChangedCallback != null) {
+ mPhone.getDataNetworkController().unregisterDataNetworkControllerCallback(
+ mNrPhysicalLinkStatusChangedCallback);
+ mNrPhysicalLinkStatusChangedCallback = null;
}
}
}
@@ -562,15 +563,14 @@
break;
case EVENT_INITIALIZE:
// The reason that we do it here is because some of the works below requires
- // other modules (e.g. DcTracker, ServiceStateTracker), which is not created
- // yet when NetworkTypeController is created.
+ // other modules (e.g. DataNetworkController, ServiceStateTracker), which is not
+ // created yet when NetworkTypeController is created.
registerForAllEvents();
parseCarrierConfigs();
break;
case EVENT_DATA_RAT_CHANGED:
case EVENT_NR_STATE_CHANGED:
case EVENT_NR_FREQUENCY_CHANGED:
- case EVENT_PCO_DATA_CHANGED:
case EVENT_UPDATE_NR_ADVANCED_STATE:
// ignored
break;
@@ -948,9 +948,6 @@
transitionWithTimerTo(mLegacyState);
}
break;
- case EVENT_PCO_DATA_CHANGED:
- handlePcoData((AsyncResult) msg.obj);
- break;
case EVENT_UPDATE_NR_ADVANCED_STATE:
updateNrAdvancedState();
break;
@@ -1003,33 +1000,7 @@
}
}
mIsNrAdvanced = isNrAdvanced();
- }
-
- private void handlePcoData(AsyncResult ar) {
- if (ar.exception != null) {
- loge("PCO_DATA exception: " + ar.exception);
- return;
- }
- PcoData pcodata = (PcoData) ar.result;
- if (pcodata == null) {
- return;
- }
- log("EVENT_PCO_DATA_CHANGED: pco data: " + pcodata);
- DcTracker dcTracker = mPhone.getDcTracker(
- AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
- DataConnection dc =
- dcTracker != null ? dcTracker.getDataConnectionByContextId(pcodata.cid) : null;
- ApnSetting apnSettings = dc != null ? dc.getApnSetting() : null;
- if (apnSettings != null && apnSettings.canHandleType(ApnSetting.TYPE_DEFAULT)
- && mNrAdvancedCapablePcoId > 0
- && pcodata.pcoId == mNrAdvancedCapablePcoId
- ) {
- log("EVENT_PCO_DATA_CHANGED: NR_ADVANCED is allowed by PCO. length:"
- + pcodata.contents.length + ",value: " + Arrays.toString(pcodata.contents));
- mIsNrAdvancedAllowedByPco = pcodata.contents.length > 0
- && pcodata.contents[pcodata.contents.length - 1] == 1;
- updateNrAdvancedState();
- }
+ log("mIsNrAdvanced=" + mIsNrAdvanced);
}
}
diff --git a/src/java/com/android/internal/telephony/NitzData.java b/src/java/com/android/internal/telephony/NitzData.java
index 6b19e08..8430585 100644
--- a/src/java/com/android/internal/telephony/NitzData.java
+++ b/src/java/com/android/internal/telephony/NitzData.java
@@ -21,6 +21,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.telephony.Rlog;
+import java.time.DateTimeException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Objects;
@@ -39,9 +40,6 @@
private static final int MS_PER_QUARTER_HOUR = 15 * 60 * 1000;
private static final int MS_PER_HOUR = 60 * 60 * 1000;
- /* Time stamp after 19 January 2038 is not supported under 32 bit */
- private static final int MAX_NITZ_YEAR = 2037;
-
private static final Pattern NITZ_SPLIT_PATTERN = Pattern.compile("[/:,+-]");
// Stored For logging / debugging only.
@@ -77,22 +75,37 @@
try {
String[] nitzSubs = NITZ_SPLIT_PATTERN.split(nitz);
- int year = 2000 + Integer.parseInt(nitzSubs[0]);
- if (year > MAX_NITZ_YEAR) {
- if (ServiceStateTracker.DBG) {
- Rlog.e(LOG_TAG, "NITZ year: " + year + " exceeds limit, skip NITZ time update");
- }
- return null;
+ int year = Integer.parseInt(nitzSubs[0]);
+ if (year < 1 || year > 99) {
+ // 0 > year > 99 imply an invalid string.
+ //
+ // At the time of this comment (year 2023), a zero year is considered invalid and
+ // assumed to be the result of invalid data being converted to zero in the code that
+ // turns the binary NITZ into a string. For the next few decades at least, Android
+ // devices should not need to interpret zero. Hopefully, NITZ will be replaced by
+ // the time that's not true, or folks dealing the Y2K1 issue can handle it.
+ //
+ // DateTimeException is also thrown by LocalDateTime below if the values are out of
+ // range and will be handled in the catch block.
+ throw new DateTimeException("Invalid NITZ year == 0");
}
+ // Values < {current year} could be considered invalid but are used in test code, so no
+ // window is applied to adjust low values < {current year} with "+ 2100" (and would also
+ // need to consider zero as valid). Code that processes the NitzData is in a better
+ // position to log and discard obviously invalid NITZ signals from past years.
+ year += 2000;
+
int month = Integer.parseInt(nitzSubs[1]);
int date = Integer.parseInt(nitzSubs[2]);
int hour = Integer.parseInt(nitzSubs[3]);
int minute = Integer.parseInt(nitzSubs[4]);
int second = Integer.parseInt(nitzSubs[5]);
- /* NITZ time (hour:min:sec) will be in UTC but it supplies the timezone
- * offset as well (which we won't worry about until later) */
+ // NITZ time (hour:min:sec) will be in UTC but it supplies the timezone
+ // offset as well (which we won't worry about until later).
+ // The LocalDateTime.of() will throw DateTimeException for values outside the allowed
+ // range for the Gregorian calendar.
long epochMillis = LocalDateTime.of(year, month, date, hour, minute, second)
.toInstant(ZoneOffset.UTC)
.toEpochMilli();
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index 4afccd1..36cf50c 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -40,7 +40,6 @@
import android.sysprop.TelephonyProperties;
import android.telecom.VideoProfile;
import android.telephony.AccessNetworkConstants;
-import android.telephony.Annotation.ApnType;
import android.telephony.CarrierConfigManager;
import android.telephony.CarrierRestrictionRules;
import android.telephony.CellIdentity;
@@ -60,14 +59,12 @@
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyDisplayInfo;
import android.telephony.TelephonyManager;
-import android.telephony.data.ApnSetting;
import android.telephony.emergency.EmergencyNumber;
import android.telephony.ims.RegistrationManager;
import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.text.TextUtils;
import android.util.LocalLog;
import android.util.Log;
-import android.util.SparseArray;
import android.util.Xml;
import com.android.ims.ImsCall;
@@ -80,10 +77,6 @@
import com.android.internal.telephony.data.DataNetworkController;
import com.android.internal.telephony.data.DataSettingsManager;
import com.android.internal.telephony.data.LinkBandwidthEstimator;
-import com.android.internal.telephony.dataconnection.DataConnectionReasons;
-import com.android.internal.telephony.dataconnection.DataEnabledSettings;
-import com.android.internal.telephony.dataconnection.DcTracker;
-import com.android.internal.telephony.dataconnection.TransportManager;
import com.android.internal.telephony.emergency.EmergencyNumberTracker;
import com.android.internal.telephony.imsphone.ImsPhone;
import com.android.internal.telephony.imsphone.ImsPhoneCall;
@@ -222,11 +215,8 @@
// Radio state change
protected static final int EVENT_RADIO_STATE_CHANGED = 47;
protected static final int EVENT_SET_CARRIER_DATA_ENABLED = 48;
- protected static final int EVENT_DEVICE_PROVISIONED_CHANGE = 49;
- protected static final int EVENT_DEVICE_PROVISIONING_DATA_SETTING_CHANGE = 50;
protected static final int EVENT_GET_AVAILABLE_NETWORKS_DONE = 51;
- private static final int EVENT_ALL_DATA_DISCONNECTED = 52;
protected static final int EVENT_UICC_APPS_ENABLEMENT_STATUS_CHANGED = 53;
protected static final int EVENT_UICC_APPS_ENABLEMENT_SETTING_CHANGED = 54;
protected static final int EVENT_GET_UICC_APPS_ENABLEMENT_DONE = 55;
@@ -303,11 +293,6 @@
public CommandsInterface mCi;
protected int mVmCount = 0;
private boolean mDnsCheckDisabled;
- // Data connection trackers. For each transport type (e.g. WWAN, WLAN), there will be a
- // corresponding DcTracker. The WWAN DcTracker is for cellular data connections while
- // WLAN DcTracker is for IWLAN data connection. For IWLAN legacy mode, only one (WWAN) DcTracker
- // will be created.
- protected final SparseArray<DcTracker> mDcTrackers = new SparseArray<>();
protected DataNetworkController mDataNetworkController;
/* Used for dispatching signals to configured carrier apps */
protected CarrierSignalAgent mCarrierSignalAgent;
@@ -346,9 +331,7 @@
private final String mActionAttached;
protected DeviceStateMonitor mDeviceStateMonitor;
protected DisplayInfoController mDisplayInfoController;
- protected TransportManager mTransportManager;
protected AccessNetworksManager mAccessNetworksManager;
- protected DataEnabledSettings mDataEnabledSettings;
// Used for identify the carrier of current subscription
protected CarrierResolver mCarrierResolver;
protected SignalStrengthController mSignalStrengthController;
@@ -428,8 +411,6 @@
protected final RegistrantList mEmergencyCallToggledRegistrants = new RegistrantList();
- private final RegistrantList mAllDataDisconnectedRegistrants = new RegistrantList();
-
private final RegistrantList mCellInfoRegistrants = new RegistrantList();
private final RegistrantList mRedialRegistrants = new RegistrantList();
@@ -474,10 +455,6 @@
protected LinkBandwidthEstimator mLinkBandwidthEstimator;
- /** The flag indicating using the new data stack or not. */
- // This flag and the old data stack code will be deleted in Android 14.
- private final boolean mNewDataStackEnabled;
-
public IccRecords getIccRecords() {
return mIccRecords.get();
}
@@ -619,9 +596,6 @@
// Initialize SMS stats
mSmsStats = new SmsStats(this);
- mNewDataStackEnabled = !mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_force_disable_telephony_new_data_stack);
-
if (getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) {
return;
}
@@ -814,11 +788,6 @@
break;
}
- case EVENT_ALL_DATA_DISCONNECTED:
- if (areAllDataDisconnected()) {
- mAllDataDisconnectedRegistrants.notifyRegistrants();
- }
- break;
case EVENT_GET_USAGE_SETTING_DONE:
ar = (AsyncResult) msg.obj;
if (ar.exception == null) {
@@ -1951,13 +1920,6 @@
}
/**
- * @return The instance of transport manager.
- */
- public TransportManager getTransportManager() {
- return null;
- }
-
- /**
* @return The instance of access networks manager.
*/
public AccessNetworksManager getAccessNetworksManager() {
@@ -3730,18 +3692,11 @@
* @return true if there is a matching DUN APN.
*/
public boolean hasMatchedTetherApnSetting() {
- if (isUsingNewDataStack()) {
- NetworkRegistrationInfo nrs = getServiceState().getNetworkRegistrationInfo(
- NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
- if (nrs != null) {
- return getDataNetworkController().getDataProfileManager()
- .isTetheringDataProfileExisting(nrs.getAccessNetworkTechnology());
- }
- return false;
- }
- if (getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) != null) {
- return getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
- .hasMatchedTetherApnSetting();
+ NetworkRegistrationInfo nrs = getServiceState().getNetworkRegistrationInfo(
+ NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+ if (nrs != null) {
+ return getDataNetworkController().getDataProfileManager()
+ .isTetheringDataProfileExisting(nrs.getAccessNetworkTechnology());
}
return false;
}
@@ -3752,31 +3707,10 @@
* @return {@code true} if internet data is allowed to be established.
*/
public boolean isDataAllowed() {
- if (isUsingNewDataStack()) {
- return getDataNetworkController().isInternetDataAllowed();
- }
- return isDataAllowed(ApnSetting.TYPE_DEFAULT, null);
+ return getDataNetworkController().isInternetDataAllowed();
}
/**
- * Report on whether data connectivity is allowed.
- *
- * @param apnType APN type
- * @param reasons The reasons that data can/can't be established. This is an output param.
- * @return True if data is allowed to be established
- */
- public boolean isDataAllowed(@ApnType int apnType, DataConnectionReasons reasons) {
- if (mAccessNetworksManager != null) {
- int transport = mAccessNetworksManager.getCurrentTransport(apnType);
- if (getDcTracker(transport) != null) {
- return getDcTracker(transport).isDataAllowed(reasons);
- }
- }
- return false;
- }
-
-
- /**
* Action set from carrier signalling broadcast receivers to enable/disable metered apns.
*/
public void carrierActionSetMeteredApnsEnabled(boolean enabled) {
@@ -3932,16 +3866,6 @@
return null;
}
- /**
- * Get the current for the default apn DataState. No change notification
- * exists at this interface -- use
- * {@link android.telephony.PhoneStateListener} instead.
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public PhoneConstants.DataState getDataConnectionState() {
- return getDataConnectionState(ApnSetting.TYPE_DEFAULT_STRING);
- }
-
public void notifyCallForwardingIndicator() {
}
@@ -4621,42 +4545,6 @@
return false;
}
- /**
- * @return True if all data connections are disconnected.
- */
- public boolean areAllDataDisconnected() {
- if (mAccessNetworksManager != null) {
- for (int transport : mAccessNetworksManager.getAvailableTransports()) {
- if (getDcTracker(transport) != null
- && !getDcTracker(transport).areAllDataDisconnected()) {
- return false;
- }
- }
- }
- return true;
- }
-
- public void registerForAllDataDisconnected(Handler h, int what) {
- mAllDataDisconnectedRegistrants.addUnique(h, what, null);
- if (mAccessNetworksManager != null) {
- for (int transport : mAccessNetworksManager.getAvailableTransports()) {
- if (getDcTracker(transport) != null
- && !getDcTracker(transport).areAllDataDisconnected()) {
- getDcTracker(transport).registerForAllDataDisconnected(
- this, EVENT_ALL_DATA_DISCONNECTED);
- }
- }
- }
- }
-
- public void unregisterForAllDataDisconnected(Handler h) {
- mAllDataDisconnectedRegistrants.remove(h);
- }
-
- public DataEnabledSettings getDataEnabledSettings() {
- return mDataEnabledSettings;
- }
-
@UnsupportedAppUsage
public IccSmsInterfaceManager getIccSmsInterfaceManager(){
return null;
@@ -4787,16 +4675,6 @@
return isEmergencyCallOnly;
}
- /**
- * Get data connection tracker based on the transport type
- *
- * @param transportType Transport type defined in AccessNetworkConstants.TransportType
- * @return The data connection tracker. Null if not found.
- */
- public @Nullable DcTracker getDcTracker(int transportType) {
- return mDcTrackers.get(transportType);
- }
-
// Return true if either CSIM or RUIM app is present. By default it returns false.
public boolean isCdmaSubscriptionAppPresent() {
return false;
@@ -4966,14 +4844,6 @@
return mIsAllowedNetworkTypesLoadedFromDb;
}
- /**
- * @return {@code true} if using the new telephony data stack.
- */
- // This flag and the old data stack code will be deleted in Android 14.
- public boolean isUsingNewDataStack() {
- return mNewDataStackEnabled;
- }
-
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("Phone: subId=" + getSubId());
pw.println(" mPhoneId=" + mPhoneId);
@@ -5009,7 +4879,6 @@
pw.println(" needsOtaServiceProvisioning=" + needsOtaServiceProvisioning());
pw.println(" isInEmergencySmsMode=" + isInEmergencySmsMode());
pw.println(" isEcmCanceledForEmergency=" + isEcmCanceledForEmergency());
- pw.println(" isUsingNewDataStack=" + isUsingNewDataStack());
pw.println(" service state=" + getServiceState());
pw.flush();
pw.println("++++++++++++++++++++++++++++++++");
@@ -5025,16 +4894,6 @@
pw.println("++++++++++++++++++++++++++++++++");
}
- if (mAccessNetworksManager != null) {
- for (int transport : mAccessNetworksManager.getAvailableTransports()) {
- if (getDcTracker(transport) != null) {
- getDcTracker(transport).dump(fd, pw, args);
- pw.flush();
- pw.println("++++++++++++++++++++++++++++++++");
- }
- }
- }
-
if (mDataNetworkController != null) {
try {
mDataNetworkController.dump(fd, pw, args);
diff --git a/src/java/com/android/internal/telephony/ProxyController.java b/src/java/com/android/internal/telephony/ProxyController.java
index 76f0041..498953c 100644
--- a/src/java/com/android/internal/telephony/ProxyController.java
+++ b/src/java/com/android/internal/telephony/ProxyController.java
@@ -28,7 +28,6 @@
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.telephony.RadioAccessFamily;
-import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;
@@ -157,34 +156,6 @@
logd("Constructor - Exit");
}
- public void registerForAllDataDisconnected(int subId, Handler h, int what) {
- int phoneId = SubscriptionController.getInstance().getPhoneId(subId);
-
- if (SubscriptionManager.isValidPhoneId(phoneId)) {
- mPhones[phoneId].registerForAllDataDisconnected(h, what);
- }
- }
-
- public void unregisterForAllDataDisconnected(int subId, Handler h) {
- int phoneId = SubscriptionController.getInstance().getPhoneId(subId);
-
- if (SubscriptionManager.isValidPhoneId(phoneId)) {
- mPhones[phoneId].unregisterForAllDataDisconnected(h);
- }
- }
-
-
- public boolean areAllDataDisconnected(int subId) {
- int phoneId = SubscriptionController.getInstance().getPhoneId(subId);
-
- if (SubscriptionManager.isValidPhoneId(phoneId)) {
- return mPhones[phoneId].areAllDataDisconnected();
- } else {
- // if we can't find a phone for the given subId, it is disconnected.
- return true;
- }
- }
-
/**
* Get phone radio type and access technology.
*
diff --git a/src/java/com/android/internal/telephony/RadioSimProxy.java b/src/java/com/android/internal/telephony/RadioSimProxy.java
index c7e19c4..da5b660 100644
--- a/src/java/com/android/internal/telephony/RadioSimProxy.java
+++ b/src/java/com/android/internal/telephony/RadioSimProxy.java
@@ -576,7 +576,7 @@
halImsiInfo.base.expirationTime = imsiEncryptionInfo.getExpirationTime().getTime();
}
for (byte b : imsiEncryptionInfo.getPublicKey().getEncoded()) {
- halImsiInfo.base.carrierKey.add(new Byte(b));
+ halImsiInfo.base.carrierKey.add(Byte.valueOf(b));
}
halImsiInfo.keyType = (byte) imsiEncryptionInfo.getKeyType();
@@ -592,7 +592,7 @@
halImsiInfo.expirationTime = imsiEncryptionInfo.getExpirationTime().getTime();
}
for (byte b : imsiEncryptionInfo.getPublicKey().getEncoded()) {
- halImsiInfo.carrierKey.add(new Byte(b));
+ halImsiInfo.carrierKey.add(Byte.valueOf(b));
}
((android.hardware.radio.V1_1.IRadio) mRadioProxy).setCarrierInfoForImsiEncryption(
diff --git a/src/java/com/android/internal/telephony/RetryManager.java b/src/java/com/android/internal/telephony/RetryManager.java
deleted file mode 100644
index 83864e4..0000000
--- a/src/java/com/android/internal/telephony/RetryManager.java
+++ /dev/null
@@ -1,723 +0,0 @@
-/**
- * Copyright (C) 2009 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;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.Context;
-import android.os.Build;
-import android.os.PersistableBundle;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.telephony.Annotation.ApnType;
-import android.telephony.CarrierConfigManager;
-import android.telephony.data.ApnSetting;
-import android.telephony.data.DataCallResponse;
-import android.text.TextUtils;
-import android.util.Pair;
-
-import com.android.internal.telephony.dataconnection.DataThrottler;
-import com.android.internal.telephony.util.TelephonyUtils;
-import com.android.telephony.Rlog;
-
-import java.util.ArrayList;
-import java.util.Random;
-
-/**
- * Retry manager allows a simple way to declare a series of
- * retry timeouts. After creating a RetryManager the configure
- * method is used to define the sequence. A simple linear series
- * may be initialized using configure with three integer parameters
- * The other configure method allows a series to be declared using
- * a string.
- *<p>
- * The format of the configuration string is the apn type followed by a series of parameters
- * separated by a comma. There are two name value pair parameters plus a series
- * of delay times. The units of of these delay times is unspecified.
- * The name value pairs which may be specified are:
- *<ul>
- *<li>max_retries=<value>
- *<li>default_randomizationTime=<value>
- *</ul>
- *<p>
- * apn type specifies the APN type that the retry pattern will apply for. "others" is for all other
- * APN types not specified in the config.
- *
- * max_retries is the number of times that incrementRetryCount
- * maybe called before isRetryNeeded will return false. if value
- * is infinite then isRetryNeeded will always return true.
- *
- * default_randomizationTime will be used as the randomizationTime
- * for delay times which have no supplied randomizationTime. If
- * default_randomizationTime is not defined it defaults to 0.
- *<p>
- * The other parameters define The series of delay times and each
- * may have an optional randomization value separated from the
- * delay time by a colon.
- *<p>
- * Examples:
- * <ul>
- * <li>3 retries for mms with no randomization value which means its 0:
- * <ul><li><code>"mms:1000, 2000, 3000"</code></ul>
- *
- * <li>10 retries for default APN with a 500 default randomization value for each and
- * the 4..10 retries all using 3000 as the delay:
- * <ul><li><code>"default:max_retries=10, default_randomization=500, 1000, 2000, 3000"</code></ul>
- *
- * <li>4 retries for supl APN with a 100 as the default randomization value for the first 2 values
- * and the other two having specified values of 500:
- * <ul><li><code>"supl:default_randomization=100, 1000, 2000, 4000:500, 5000:500"</code></ul>
- *
- * <li>Infinite number of retries for all other APNs with the first one at 1000, the second at 2000
- * all others will be at 3000.
- * <ul><li><code>"others:max_retries=infinite,1000,2000,3000</code></ul>
- * </ul>
- *
- * {@hide}
- */
-public class RetryManager {
- public static final String LOG_TAG = "RetryManager";
- public static final boolean DBG = true;
- public static final boolean VDBG = false; // STOPSHIP if true
-
- /**
- * The default retry configuration for APNs. See above for the syntax.
- */
- private static final String DEFAULT_DATA_RETRY_CONFIG = "max_retries=3, 5000, 5000, 5000";
-
- /**
- * The APN type used for all other APNs retry configuration.
- */
- private static final String OTHERS_APN_TYPE = "others";
-
- /**
- * The default value (in milliseconds) for delay between APN trying (mInterApnDelay)
- * within the same round
- */
- private static final long DEFAULT_INTER_APN_DELAY = 20000;
-
- /**
- * The default value (in milliseconds) for delay between APN trying (mFailFastInterApnDelay)
- * within the same round when we are in fail fast mode
- */
- private static final long DEFAULT_INTER_APN_DELAY_FOR_PROVISIONING = 3000;
-
- /**
- * The default value (in milliseconds) for retrying APN after disconnect
- */
- private static final long DEFAULT_APN_RETRY_AFTER_DISCONNECT_DELAY = 10000;
-
- /**
- * The value indicating retry should not occur.
- */
- public static final long NO_RETRY = Long.MAX_VALUE;
-
- /**
- * The value indicating network did not suggest any retry delay
- */
- public static final long NO_SUGGESTED_RETRY_DELAY = DataCallResponse.RETRY_DURATION_UNDEFINED;
-
- /**
- * If the network suggests a retry delay in the data call setup response, we will retry
- * the current APN setting again. The maximum retry count is to prevent that network
- * keeps asking device to retry data setup forever and causes power consumption issue.
- */
- private static final int DEFAULT_MAX_SAME_APN_RETRY = 3;
-
- /**
- * The delay (in milliseconds) between APN trying within the same round
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- private long mInterApnDelay;
-
- /**
- * The delay (in milliseconds) between APN trying within the same round when we are in
- * fail fast mode
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- private long mFailFastInterApnDelay;
-
- /**
- * The delay (in milliseconds) for APN retrying after disconnect (e.g. Modem suddenly reports
- * data call lost)
- */
- private long mApnRetryAfterDisconnectDelay;
-
- /**
- * The counter for same APN retrying. See {@link #DEFAULT_MAX_SAME_APN_RETRY} for the details.
- */
- private int mSameApnRetryCount = 0;
-
- /**
- * The maximum times that frameworks retries data setup with the same APN. This value could be
- * changed via carrier config. See {@link #DEFAULT_MAX_SAME_APN_RETRY} for the details.
- */
- private int mMaxSameApnRetry = DEFAULT_MAX_SAME_APN_RETRY;
-
- /**
- * Retry record with times in milli-seconds
- */
- private static class RetryRec {
- long mDelayTime;
- long mRandomizationTime;
-
- RetryRec(long delayTime, long randomizationTime) {
- mDelayTime = delayTime;
- mRandomizationTime = randomizationTime;
- }
- }
-
- /**
- * The array of retry records
- */
- private ArrayList<RetryRec> mRetryArray = new ArrayList<RetryRec>();
-
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- private Phone mPhone;
-
- private final DataThrottler mDataThrottler;
-
- /**
- * Flag indicating whether retrying forever regardless the maximum retry count mMaxRetryCount
- */
- private boolean mRetryForever = false;
-
- /**
- * The maximum number of retries to attempt
- */
- private int mMaxRetryCount;
-
- /**
- * The current number of retries
- */
- private int mRetryCount = 0;
-
- /**
- * Random number generator. The random delay will be added into retry timer to avoid all devices
- * around retrying the APN at the same time.
- */
- private Random mRng = new Random();
-
- /**
- * Retry manager configuration string. See top of the detailed explanation.
- */
- private String mConfig;
-
- /**
- * The list to store APN setting candidates for data call setup. Most of the carriers only have
- * one APN, but few carriers have more than one.
- */
- private ArrayList<ApnSetting> mWaitingApns = new ArrayList<>();
-
- /**
- * Index pointing to the current trying APN from mWaitingApns
- */
- private int mCurrentApnIndex = -1;
-
- /**
- * Apn context type.
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- private String mApnType;
-
- private final @ApnType int apnType;
-
- /**
- * Retry manager constructor
- * @param phone Phone object
- * @param dataThrottler Data throttler
- * @param apnType APN type
- */
- public RetryManager(@NonNull Phone phone, @NonNull DataThrottler dataThrottler,
- @ApnType int apnType) {
- mPhone = phone;
- mDataThrottler = dataThrottler;
- this.apnType = apnType;
- }
-
- /**
- * Configure for using string which allow arbitrary
- * sequences of times. See class comments for the
- * string format.
- *
- * @return true if successful
- */
- @UnsupportedAppUsage
- private boolean configure(String configStr) {
- // Strip quotes if present.
- if ((configStr.startsWith("\"") && configStr.endsWith("\""))) {
- configStr = configStr.substring(1, configStr.length() - 1);
- }
-
- // Reset the retry manager since delay, max retry count, etc...will be reset.
- reset();
-
- if (DBG) log("configure: '" + configStr + "'");
- mConfig = configStr;
-
- if (!TextUtils.isEmpty(configStr)) {
- long defaultRandomization = 0;
-
- if (VDBG) log("configure: not empty");
-
- String strArray[] = configStr.split(",");
- for (int i = 0; i < strArray.length; i++) {
- if (VDBG) log("configure: strArray[" + i + "]='" + strArray[i] + "'");
- Pair<Boolean, Integer> value;
- String splitStr[] = strArray[i].split("=", 2);
- splitStr[0] = splitStr[0].trim();
- if (VDBG) log("configure: splitStr[0]='" + splitStr[0] + "'");
- if (splitStr.length > 1) {
- splitStr[1] = splitStr[1].trim();
- if (VDBG) log("configure: splitStr[1]='" + splitStr[1] + "'");
- if (TextUtils.equals(splitStr[0], "default_randomization")) {
- value = parseNonNegativeInt(splitStr[0], splitStr[1]);
- if (!value.first) return false;
- defaultRandomization = value.second;
- } else if (TextUtils.equals(splitStr[0], "max_retries")) {
- if (TextUtils.equals("infinite", splitStr[1])) {
- mRetryForever = true;
- } else {
- value = parseNonNegativeInt(splitStr[0], splitStr[1]);
- if (!value.first) return false;
- mMaxRetryCount = value.second;
- }
- } else {
- Rlog.e(LOG_TAG, "Unrecognized configuration name value pair: "
- + strArray[i]);
- return false;
- }
- } else {
- /**
- * Assume a retry time with an optional randomization value
- * following a ":"
- */
- splitStr = strArray[i].split(":", 2);
- splitStr[0] = splitStr[0].trim();
- RetryRec rr = new RetryRec(0, 0);
- value = parseNonNegativeInt("delayTime", splitStr[0]);
- if (!value.first) return false;
- rr.mDelayTime = value.second;
-
- // Check if optional randomization value present
- if (splitStr.length > 1) {
- splitStr[1] = splitStr[1].trim();
- if (VDBG) log("configure: splitStr[1]='" + splitStr[1] + "'");
- value = parseNonNegativeInt("randomizationTime", splitStr[1]);
- if (!value.first) return false;
- rr.mRandomizationTime = value.second;
- } else {
- rr.mRandomizationTime = defaultRandomization;
- }
- mRetryArray.add(rr);
- }
- }
- if (mRetryArray.size() > mMaxRetryCount) {
- mMaxRetryCount = mRetryArray.size();
- if (VDBG) log("configure: setting mMaxRetryCount=" + mMaxRetryCount);
- }
- } else {
- log("configure: cleared");
- }
-
- if (VDBG) log("configure: true");
- return true;
- }
-
- /**
- * Configure the retry manager
- */
- private void configureRetry() {
- String configString = null;
- String otherConfigString = null;
-
- try {
- if (TelephonyUtils.IS_DEBUGGABLE) {
- // Using system properties is easier for testing from command line.
- String config = SystemProperties.get("test.data_retry_config");
- if (!TextUtils.isEmpty(config)) {
- configure(config);
- return;
- }
- }
-
- CarrierConfigManager configManager = (CarrierConfigManager)
- mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
- PersistableBundle b = configManager.getConfigForSubId(mPhone.getSubId());
-
- mInterApnDelay = b.getLong(
- CarrierConfigManager.KEY_CARRIER_DATA_CALL_APN_DELAY_DEFAULT_LONG,
- DEFAULT_INTER_APN_DELAY);
- mFailFastInterApnDelay = b.getLong(
- CarrierConfigManager.KEY_CARRIER_DATA_CALL_APN_DELAY_FASTER_LONG,
- DEFAULT_INTER_APN_DELAY_FOR_PROVISIONING);
- mApnRetryAfterDisconnectDelay = b.getLong(
- CarrierConfigManager.KEY_CARRIER_DATA_CALL_APN_RETRY_AFTER_DISCONNECT_LONG,
- DEFAULT_APN_RETRY_AFTER_DISCONNECT_DELAY);
- mMaxSameApnRetry = b.getInt(
- CarrierConfigManager
- .KEY_CARRIER_DATA_CALL_RETRY_NETWORK_REQUESTED_MAX_COUNT_INT,
- DEFAULT_MAX_SAME_APN_RETRY);
-
- // Load all retry patterns for all different APNs.
- String[] allConfigStrings = b.getStringArray(
- CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS);
- if (allConfigStrings != null) {
- for (String s : allConfigStrings) {
- if (!TextUtils.isEmpty(s)) {
- String splitStr[] = s.split(":", 2);
- if (splitStr.length == 2) {
- String apnTypeStr = splitStr[0].trim();
- // Check if this retry pattern is for the APN we want.
- if (apnTypeStr.equals(ApnSetting.getApnTypeString(apnType))) {
- // Extract the config string. Note that an empty string is valid
- // here, meaning no retry for the specified APN.
- configString = splitStr[1];
- break;
- } else if (apnTypeStr.equals(OTHERS_APN_TYPE)) {
- // Extract the config string. Note that an empty string is valid
- // here, meaning no retry for all other APNs.
- otherConfigString = splitStr[1];
- }
- }
- }
- }
- }
-
- if (configString == null) {
- if (otherConfigString != null) {
- configString = otherConfigString;
- } else {
- // We should never reach here. If we reach here, it must be a configuration
- // error bug.
- log("Invalid APN retry configuration!. Use the default one now.");
- configString = DEFAULT_DATA_RETRY_CONFIG;
- }
- }
- } catch (NullPointerException ex) {
- // We should never reach here unless there is a bug
- log("Failed to read configuration! Use the hardcoded default value.");
-
- mInterApnDelay = DEFAULT_INTER_APN_DELAY;
- mFailFastInterApnDelay = DEFAULT_INTER_APN_DELAY_FOR_PROVISIONING;
- configString = DEFAULT_DATA_RETRY_CONFIG;
- }
-
- if (VDBG) {
- log("mInterApnDelay = " + mInterApnDelay + ", mFailFastInterApnDelay = " +
- mFailFastInterApnDelay);
- }
-
- configure(configString);
- }
-
- /**
- * Return the timer that should be used to trigger the data reconnection
- */
- @UnsupportedAppUsage
- private long getRetryTimer() {
- int index;
- if (mRetryCount < mRetryArray.size()) {
- index = mRetryCount;
- } else {
- index = mRetryArray.size() - 1;
- }
-
- long retVal;
- if ((index >= 0) && (index < mRetryArray.size())) {
- retVal = mRetryArray.get(index).mDelayTime + nextRandomizationTime(index);
- } else {
- retVal = 0;
- }
-
- if (DBG) log("getRetryTimer: " + retVal);
- return retVal;
- }
-
- /**
- * Parse an integer validating the value is not negative.
- * @param name Name
- * @param stringValue Value
- * @return Pair.first == true if stringValue an integer >= 0
- */
- private Pair<Boolean, Integer> parseNonNegativeInt(String name, String stringValue) {
- int value;
- Pair<Boolean, Integer> retVal;
- try {
- value = Integer.parseInt(stringValue);
- retVal = new Pair<>(validateNonNegativeInt(name, value), value);
- } catch (NumberFormatException e) {
- Rlog.e(LOG_TAG, name + " bad value: " + stringValue, e);
- retVal = new Pair<>(false, 0);
- }
- if (VDBG) {
- log("parseNonNegativeInt: " + name + ", " + stringValue + ", "
- + retVal.first + ", " + retVal.second);
- }
- return retVal;
- }
-
- /**
- * Validate an integer is >= 0 and logs an error if not
- * @param name Name
- * @param value Value
- * @return Pair.first
- */
- private boolean validateNonNegativeInt(String name, long value) {
- boolean retVal;
- if (value < 0) {
- Rlog.e(LOG_TAG, name + " bad value: is < 0");
- retVal = false;
- } else {
- retVal = true;
- }
- if (VDBG) log("validateNonNegative: " + name + ", " + value + ", " + retVal);
- return retVal;
- }
-
- /**
- * Return next random number for the index
- * @param index Retry index
- */
- private long nextRandomizationTime(int index) {
- long randomTime = mRetryArray.get(index).mRandomizationTime;
- if (randomTime == 0) {
- return 0;
- } else {
- return mRng.nextInt((int) randomTime);
- }
- }
-
- private long getNetworkSuggestedRetryDelay() {
- long retryElapseTime = mDataThrottler.getRetryTime(apnType);
- if (retryElapseTime == NO_RETRY || retryElapseTime == NO_SUGGESTED_RETRY_DELAY) {
- return retryElapseTime;
- }
-
- // The time from data throttler is system's elapsed time. We need to return the delta. If
- // less than 0, then return 0 (i.e. retry immediately).
- return Math.max(0, retryElapseTime - SystemClock.elapsedRealtime());
- }
-
- /**
- * Get the next APN setting for data call setup.
- * @return APN setting to try. {@code null} if cannot find any APN,
- */
- public @Nullable ApnSetting getNextApnSetting() {
- if (mWaitingApns == null || mWaitingApns.size() == 0) {
- log("Waiting APN list is null or empty.");
- return null;
- }
-
- long networkSuggestedRetryDelay = getNetworkSuggestedRetryDelay();
- if (networkSuggestedRetryDelay == NO_RETRY) {
- log("Network suggested no retry.");
- return null;
- }
-
- // If the network had suggested a retry delay, we should retry the current APN again
- // (up to mMaxSameApnRetry times) instead of getting the next APN setting from
- // our own list. If the APN waiting list has been reset before a setup data responses
- // arrive (i.e. mCurrentApnIndex=-1), then ignore the network suggested retry.
- if (mCurrentApnIndex != -1 && networkSuggestedRetryDelay != NO_SUGGESTED_RETRY_DELAY
- && mSameApnRetryCount < mMaxSameApnRetry) {
- mSameApnRetryCount++;
- return mWaitingApns.get(mCurrentApnIndex);
- }
-
- mSameApnRetryCount = 0;
-
- int index = mCurrentApnIndex;
- // Loop through the APN list to find out the index of next non-permanent failed APN.
- while (true) {
- if (++index == mWaitingApns.size()) index = 0;
-
- // Stop if we find the non-failed APN.
- if (!mWaitingApns.get(index).getPermanentFailed()) {
- break;
- }
-
- // If all APNs have permanently failed, bail out.
- if (mWaitingApns.stream().allMatch(ApnSetting::getPermanentFailed)) {
- return null;
- }
- }
-
- mCurrentApnIndex = index;
- return mWaitingApns.get(mCurrentApnIndex);
- }
-
- /**
- * Get the delay for trying the next waiting APN from the list.
- * @param failFastEnabled True if fail fast mode enabled. In this case we'll use a shorter
- * delay.
- * @return delay in milliseconds
- */
- public long getDelayForNextApn(boolean failFastEnabled) {
-
- if (mWaitingApns == null || mWaitingApns.size() == 0) {
- log("Waiting APN list is null or empty.");
- return NO_RETRY;
- }
-
- long networkSuggestedDelay = getNetworkSuggestedRetryDelay();
- log("Network suggested delay=" + networkSuggestedDelay + "ms");
-
- if (networkSuggestedDelay == NO_RETRY) {
- log("Network suggested not retrying.");
- return NO_RETRY;
- }
-
- if (networkSuggestedDelay != NO_SUGGESTED_RETRY_DELAY
- && mSameApnRetryCount < mMaxSameApnRetry) {
- // If the network explicitly suggests a retry delay, we should use it, even in fail fast
- // mode.
- log("Network suggested retry in " + networkSuggestedDelay + " ms.");
- return networkSuggestedDelay;
- }
-
- // In order to determine the delay to try next APN, we need to peek the next available APN.
- // Case 1 - If we will start the next round of APN trying,
- // we use the exponential-growth delay. (e.g. 5s, 10s, 30s...etc.)
- // Case 2 - If we are still within the same round of APN trying,
- // we use the fixed standard delay between APNs. (e.g. 20s)
-
- int index = mCurrentApnIndex;
- while (true) {
- if (++index >= mWaitingApns.size()) index = 0;
-
- // Stop if we find the non-failed APN.
- if (!mWaitingApns.get(index).getPermanentFailed()) {
- break;
- }
-
- // If all APNs have permanently failed, bail out.
- if (mWaitingApns.stream().allMatch(ApnSetting::getPermanentFailed)) {
- log("All APNs have permanently failed.");
- return NO_RETRY;
- }
- }
-
- long delay;
- if (index <= mCurrentApnIndex) {
- // Case 1, if the next APN is in the next round.
- if (!mRetryForever && mRetryCount + 1 > mMaxRetryCount) {
- log("Reached maximum retry count " + mMaxRetryCount + ".");
- return NO_RETRY;
- }
- delay = getRetryTimer();
- ++mRetryCount;
- } else {
- // Case 2, if the next APN is still in the same round.
- delay = mInterApnDelay;
- }
-
- if (failFastEnabled && delay > mFailFastInterApnDelay) {
- // If we enable fail fast mode, and the delay we got is longer than
- // fail-fast delay (mFailFastInterApnDelay), use the fail-fast delay.
- // If the delay we calculated is already shorter than fail-fast delay,
- // then ignore fail-fast delay.
- delay = mFailFastInterApnDelay;
- }
-
- return delay;
- }
-
- /**
- * Mark the APN setting permanently failed.
- * @param apn APN setting to be marked as permanently failed
- * */
- public void markApnPermanentFailed(ApnSetting apn) {
- if (apn != null) {
- apn.setPermanentFailed(true);
- }
- }
-
- /**
- * Reset the retry manager.
- */
- private void reset() {
- mMaxRetryCount = 0;
- mRetryCount = 0;
- mCurrentApnIndex = -1;
- mSameApnRetryCount = 0;
- mRetryArray.clear();
- }
-
- /**
- * Set waiting APNs for retrying in case needed.
- * @param waitingApns Waiting APN list
- */
- public void setWaitingApns(ArrayList<ApnSetting> waitingApns) {
-
- if (waitingApns == null) {
- log("No waiting APNs provided");
- return;
- }
-
- mWaitingApns = waitingApns;
-
- // Since we replace the entire waiting APN list, we need to re-config this retry manager.
- configureRetry();
-
- for (ApnSetting apn : mWaitingApns) {
- apn.setPermanentFailed(false);
- }
-
- log("Setting " + mWaitingApns.size() + " waiting APNs.");
-
- if (VDBG) {
- for (int i = 0; i < mWaitingApns.size(); i++) {
- log(" [" + i + "]:" + mWaitingApns.get(i));
- }
- }
- }
-
- /**
- * Get the list of waiting APNs.
- * @return the list of waiting APNs
- */
- public @NonNull ArrayList<ApnSetting> getWaitingApns() {
- return mWaitingApns;
- }
-
- /**
- * Get the delay in milliseconds for APN retry after disconnect
- * @return The delay in milliseconds
- */
- public long getRetryAfterDisconnectDelay() {
- return mApnRetryAfterDisconnectDelay;
- }
-
- public String toString() {
- if (mConfig == null) return "";
- return "RetryManager: apnType=" + ApnSetting.getApnTypeString(apnType)
- + " mRetryCount="
- + mRetryCount + " mMaxRetryCount=" + mMaxRetryCount + " mCurrentApnIndex="
- + mCurrentApnIndex + " mSameApnRtryCount=" + mSameApnRetryCount
- + " networkSuggestedDelay=" + getNetworkSuggestedRetryDelay() + " mRetryForever="
- + mRetryForever + " mInterApnDelay=" + mInterApnDelay
- + " mApnRetryAfterDisconnectDelay=" + mApnRetryAfterDisconnectDelay
- + " mConfig={" + mConfig + "}";
- }
-
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- private void log(String s) {
- Rlog.d(LOG_TAG, "[" + ApnSetting.getApnTypeString(apnType) + "] " + s);
- }
-}
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index 3ed4578..0c73169 100755
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -37,7 +37,6 @@
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.hardware.radio.V1_0.CellInfoType;
-import android.net.NetworkCapabilities;
import android.os.AsyncResult;
import android.os.BaseBundle;
import android.os.Build;
@@ -95,7 +94,6 @@
import com.android.internal.telephony.data.AccessNetworksManager;
import com.android.internal.telephony.data.DataNetwork;
import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback;
-import com.android.internal.telephony.dataconnection.DataConnection;
import com.android.internal.telephony.imsphone.ImsPhone;
import com.android.internal.telephony.metrics.ServiceStateStats;
import com.android.internal.telephony.metrics.TelephonyMetrics;
@@ -224,7 +222,6 @@
/* Radio power off pending flag and tag counter */
private boolean mPendingRadioPowerOffAfterDataOff = false;
- private int mPendingRadioPowerOffAfterDataOffTag = 0;
/** Waiting period before recheck gprs and voice registration. */
public static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000;
@@ -721,17 +718,15 @@
registerForImsCapabilityChanged(mCSST,
CarrierServiceStateTracker.CARRIER_EVENT_IMS_CAPABILITIES_CHANGED, null);
- if (mPhone.isUsingNewDataStack()) {
- mDataDisconnectedCallback = new DataNetworkControllerCallback(this::post) {
- @Override
- public void onAnyDataNetworkExistingChanged(boolean anyDataExisting) {
- log("onAnyDataNetworkExistingChanged: anyDataExisting=" + anyDataExisting);
- if (!anyDataExisting) {
- sendEmptyMessage(EVENT_ALL_DATA_DISCONNECTED);
- }
+ mDataDisconnectedCallback = new DataNetworkControllerCallback(this::post) {
+ @Override
+ public void onAnyDataNetworkExistingChanged(boolean anyDataExisting) {
+ log("onAnyDataNetworkExistingChanged: anyDataExisting=" + anyDataExisting);
+ if (!anyDataExisting) {
+ sendEmptyMessage(EVENT_ALL_DATA_DISCONNECTED);
}
- };
- }
+ }
+ };
}
@VisibleForTesting
@@ -1197,22 +1192,9 @@
switch (msg.what) {
case EVENT_SET_RADIO_POWER_OFF:
synchronized(this) {
- if (mPhone.isUsingNewDataStack()) {
- mPendingRadioPowerOffAfterDataOff = false;
- log("Wait for all data networks torn down timed out. Power off now.");
- hangupAndPowerOff();
- return;
- }
- if (mPendingRadioPowerOffAfterDataOff &&
- (msg.arg1 == mPendingRadioPowerOffAfterDataOffTag)) {
- if (DBG) log("EVENT_SET_RADIO_OFF, turn radio off now.");
- hangupAndPowerOff();
- mPendingRadioPowerOffAfterDataOffTag += 1;
- mPendingRadioPowerOffAfterDataOff = false;
- } else {
- log("EVENT_SET_RADIO_OFF is stale arg1=" + msg.arg1 +
- "!= tag=" + mPendingRadioPowerOffAfterDataOffTag);
- }
+ mPendingRadioPowerOffAfterDataOff = false;
+ log("Wait for all data networks torn down timed out. Power off now.");
+ hangupAndPowerOff();
}
break;
@@ -1480,41 +1462,26 @@
break;
case EVENT_ALL_DATA_DISCONNECTED:
- if (mPhone.isUsingNewDataStack()) {
- log("EVENT_ALL_DATA_DISCONNECTED");
- if (!mPendingRadioPowerOffAfterDataOff) return;
- boolean areAllDataDisconnectedOnAllPhones = true;
- for (Phone phone : PhoneFactory.getPhones()) {
- if (phone.getDataNetworkController().areAllDataDisconnected()) {
- phone.getDataNetworkController()
- .unregisterDataNetworkControllerCallback(
- mDataDisconnectedCallback);
- } else {
- log("Still waiting for all data disconnected on phone: "
- + phone.getSubId());
- areAllDataDisconnectedOnAllPhones = false;
- }
- }
- if (areAllDataDisconnectedOnAllPhones) {
- mPendingRadioPowerOffAfterDataOff = false;
- removeMessages(EVENT_SET_RADIO_POWER_OFF);
- if (DBG) log("Data disconnected for all phones, turn radio off now.");
- hangupAndPowerOff();
- }
- return;
- }
- int dds = SubscriptionManager.getDefaultDataSubscriptionId();
- ProxyController.getInstance().unregisterForAllDataDisconnected(dds, this);
- synchronized(this) {
- if (mPendingRadioPowerOffAfterDataOff) {
- if (DBG) log("EVENT_ALL_DATA_DISCONNECTED, turn radio off now.");
- hangupAndPowerOff();
- mPendingRadioPowerOffAfterDataOffTag += 1;
- mPendingRadioPowerOffAfterDataOff = false;
+ log("EVENT_ALL_DATA_DISCONNECTED");
+ if (!mPendingRadioPowerOffAfterDataOff) return;
+ boolean areAllDataDisconnectedOnAllPhones = true;
+ for (Phone phone : PhoneFactory.getPhones()) {
+ if (phone.getDataNetworkController().areAllDataDisconnected()) {
+ phone.getDataNetworkController()
+ .unregisterDataNetworkControllerCallback(
+ mDataDisconnectedCallback);
} else {
- log("EVENT_ALL_DATA_DISCONNECTED is stale");
+ log("Still waiting for all data disconnected on phone: "
+ + phone.getSubId());
+ areAllDataDisconnectedOnAllPhones = false;
}
}
+ if (areAllDataDisconnectedOnAllPhones) {
+ mPendingRadioPowerOffAfterDataOff = false;
+ removeMessages(EVENT_SET_RADIO_POWER_OFF);
+ if (DBG) log("Data disconnected for all phones, turn radio off now.");
+ hangupAndPowerOff();
+ }
break;
case EVENT_CHANGE_IMS_STATE:
@@ -2165,18 +2132,8 @@
private boolean isInternetPhysicalChannelConfig(PhysicalChannelConfig config) {
for (int cid : config.getContextIds()) {
- if (mPhone.isUsingNewDataStack()) {
- if (mPhone.getDataNetworkController().isInternetNetwork(cid)) {
- return true;
- }
- } else {
- DataConnection dc = mPhone.getDcTracker(
- AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
- .getDataConnectionByContextId(cid);
- if (dc != null && dc.getNetworkCapabilities().hasCapability(
- NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
- return true;
- }
+ if (mPhone.getDataNetworkController().isInternetNetwork(cid)) {
+ return true;
}
}
return false;
@@ -3136,17 +3093,8 @@
mCi.setRadioPower(true, forEmergencyCall, isSelectedPhoneForEmergencyCall, null);
} else if ((!mDesiredPowerState || mRadioDisabledByCarrier) && mCi.getRadioState()
== TelephonyManager.RADIO_POWER_ON) {
- // If it's on and available and we want it off gracefully
- if (!mPhone.isUsingNewDataStack() && mImsRegistrationOnOff
- && getRadioPowerOffDelayTimeoutForImsRegistration() > 0) {
- if (DBG) log("setPowerStateToDesired: delaying power off until IMS dereg.");
- startDelayRadioOffWaitingForImsDeregTimeout();
- // Return early here as we do not want to hit the cancel timeout code below.
- return;
- } else {
- if (DBG) log("setPowerStateToDesired: powerOffRadioSafely()");
- powerOffRadioSafely();
- }
+ if (DBG) log("setPowerStateToDesired: powerOffRadioSafely()");
+ powerOffRadioSafely();
} else if (mDeviceShuttingDown
&& (mCi.getRadioState() != TelephonyManager.RADIO_POWER_UNAVAILABLE)) {
// !mDesiredPowerState condition above will happen first if the radio is on, so we will
@@ -3464,14 +3412,15 @@
useDataRegStateForDataOnlyDevices();
processIwlanRegistrationInfo();
+ updateNrFrequencyRangeFromPhysicalChannelConfigs(mLastPhysicalChannelConfigList, mNewSS);
+ updateNrStateFromPhysicalChannelConfigs(mLastPhysicalChannelConfigList, mNewSS);
+
if (TelephonyUtils.IS_DEBUGGABLE && mPhone.mTelephonyTester != null) {
mPhone.mTelephonyTester.overrideServiceState(mNewSS);
}
NetworkRegistrationInfo networkRegState = mNewSS.getNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
- updateNrFrequencyRangeFromPhysicalChannelConfigs(mLastPhysicalChannelConfigList, mNewSS);
- updateNrStateFromPhysicalChannelConfigs(mLastPhysicalChannelConfigList, mNewSS);
setPhyCellInfoFromCellIdentity(mNewSS, networkRegState.getCellIdentity());
if (DBG) {
@@ -3519,11 +3468,6 @@
NetworkRegistrationInfo newNrs = mNewSS.getNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, transport);
- // If the previously it was not in service, and now it's in service, trigger the
- // attached event. Also if airplane mode was just turned on, and data is already in
- // service, we need to trigger the attached event again so that DcTracker can setup
- // data on all connectable APNs again (because we've already torn down all data
- // connections just before airplane mode turned on)
boolean changed = (oldNrs == null || !oldNrs.isInService() || hasAirplaneModeOnChanged)
&& (newNrs != null && newNrs.isInService());
hasDataAttached.put(transport, changed);
@@ -5024,96 +4968,33 @@
public void powerOffRadioSafely() {
synchronized (this) {
if (!mPendingRadioPowerOffAfterDataOff) {
- if (mPhone.isUsingNewDataStack()) {
- // hang up all active voice calls first
- if (mPhone.isPhoneTypeGsm() && mPhone.isInCall()) {
- mPhone.mCT.mRingingCall.hangupIfAlive();
- mPhone.mCT.mBackgroundCall.hangupIfAlive();
- mPhone.mCT.mForegroundCall.hangupIfAlive();
- }
-
- for (Phone phone : PhoneFactory.getPhones()) {
- if (!phone.getDataNetworkController().areAllDataDisconnected()) {
- log("powerOffRadioSafely: Data is active on phone " + phone.getSubId()
- + ". Wait for all data disconnect.");
- mPendingRadioPowerOffAfterDataOff = true;
- phone.getDataNetworkController().registerDataNetworkControllerCallback(
- mDataDisconnectedCallback);
- }
- }
-
- // Tear down outside of the disconnected check to prevent race conditions.
- mPhone.getDataNetworkController().tearDownAllDataNetworks(
- DataNetwork.TEAR_DOWN_REASON_AIRPLANE_MODE_ON);
-
- if (mPendingRadioPowerOffAfterDataOff) {
- sendEmptyMessageDelayed(EVENT_SET_RADIO_POWER_OFF,
- POWER_OFF_ALL_DATA_NETWORKS_DISCONNECTED_TIMEOUT);
- } else {
- log("powerOffRadioSafely: No data is connected, turn off radio now.");
- hangupAndPowerOff();
- }
- return;
+ // hang up all active voice calls first
+ if (mPhone.isPhoneTypeGsm() && mPhone.isInCall()) {
+ mPhone.mCT.mRingingCall.hangupIfAlive();
+ mPhone.mCT.mBackgroundCall.hangupIfAlive();
+ mPhone.mCT.mForegroundCall.hangupIfAlive();
}
- int dds = SubscriptionManager.getDefaultDataSubscriptionId();
- // To minimize race conditions we call cleanUpAllConnections on
- // both if else paths instead of before this isDisconnected test.
- if (mPhone.areAllDataDisconnected()
- && (dds == mPhone.getSubId()
- || (dds != mPhone.getSubId()
- && ProxyController.getInstance().areAllDataDisconnected(dds)))) {
- // To minimize race conditions we do this after isDisconnected
- for (int transport : mAccessNetworksManager.getAvailableTransports()) {
- if (mPhone.getDcTracker(transport) != null) {
- mPhone.getDcTracker(transport).cleanUpAllConnections(
- Phone.REASON_RADIO_TURNED_OFF);
- }
- }
- if (DBG) {
- log("powerOffRadioSafely: Data disconnected, turn off radio now.");
- }
- hangupAndPowerOff();
- } else {
- // hang up all active voice calls first
- if (mPhone.isPhoneTypeGsm() && mPhone.isInCall()) {
- mPhone.mCT.mRingingCall.hangupIfAlive();
- mPhone.mCT.mBackgroundCall.hangupIfAlive();
- mPhone.mCT.mForegroundCall.hangupIfAlive();
- }
- for (int transport : mAccessNetworksManager.getAvailableTransports()) {
- if (mPhone.getDcTracker(transport) != null) {
- mPhone.getDcTracker(transport).cleanUpAllConnections(
- Phone.REASON_RADIO_TURNED_OFF);
- }
- }
- if (dds != mPhone.getSubId()
- && !ProxyController.getInstance().areAllDataDisconnected(dds)) {
- if (DBG) {
- log(String.format("powerOffRadioSafely: Data is active on DDS (%d)."
- + " Wait for all data disconnect", dds));
- }
- // Data is not disconnected on DDS. Wait for the data disconnect complete
- // before sending the RADIO_POWER off.
- ProxyController.getInstance().registerForAllDataDisconnected(dds, this,
- EVENT_ALL_DATA_DISCONNECTED);
+ for (Phone phone : PhoneFactory.getPhones()) {
+ if (!phone.getDataNetworkController().areAllDataDisconnected()) {
+ log("powerOffRadioSafely: Data is active on phone " + phone.getSubId()
+ + ". Wait for all data disconnect.");
mPendingRadioPowerOffAfterDataOff = true;
+ phone.getDataNetworkController().registerDataNetworkControllerCallback(
+ mDataDisconnectedCallback);
}
- Message msg = Message.obtain(this);
- msg.what = EVENT_SET_RADIO_POWER_OFF;
- msg.arg1 = ++mPendingRadioPowerOffAfterDataOffTag;
- if (sendMessageDelayed(msg, 30000)) {
- if (DBG) {
- log("powerOffRadioSafely: Wait up to 30s for data to disconnect, "
- + "then turn off radio.");
- }
- mPendingRadioPowerOffAfterDataOff = true;
- } else {
- log("powerOffRadioSafely: Cannot send delayed Msg, turn off radio right"
- + " away.");
- hangupAndPowerOff();
- mPendingRadioPowerOffAfterDataOff = false;
- }
+ }
+
+ // Tear down outside of the disconnected check to prevent race conditions.
+ mPhone.getDataNetworkController().tearDownAllDataNetworks(
+ DataNetwork.TEAR_DOWN_REASON_AIRPLANE_MODE_ON);
+
+ if (mPendingRadioPowerOffAfterDataOff) {
+ sendEmptyMessageDelayed(EVENT_SET_RADIO_POWER_OFF,
+ POWER_OFF_ALL_DATA_NETWORKS_DISCONNECTED_TIMEOUT);
+ } else {
+ log("powerOffRadioSafely: No data is connected, turn off radio now.");
+ hangupAndPowerOff();
}
}
}
@@ -5129,7 +5010,6 @@
if (mPendingRadioPowerOffAfterDataOff) {
if (DBG) log("Process pending request to turn radio off.");
hangupAndPowerOff();
- mPendingRadioPowerOffAfterDataOffTag += 1;
mPendingRadioPowerOffAfterDataOff = false;
return true;
}
@@ -5358,12 +5238,10 @@
pw.println(" mNewSS=" + mNewSS);
pw.println(" mVoiceCapable=" + mVoiceCapable);
pw.println(" mRestrictedState=" + mRestrictedState);
- pw.println(" mPollingContext=" + mPollingContext + " - " +
- (mPollingContext != null ? mPollingContext[0] : ""));
+ pw.println(" mPollingContext=" + Arrays.toString(mPollingContext));
pw.println(" mDesiredPowerState=" + mDesiredPowerState);
pw.println(" mRestrictedState=" + mRestrictedState);
pw.println(" mPendingRadioPowerOffAfterDataOff=" + mPendingRadioPowerOffAfterDataOff);
- pw.println(" mPendingRadioPowerOffAfterDataOffTag=" + mPendingRadioPowerOffAfterDataOffTag);
pw.println(" mCellIdentity=" + Rlog.pii(VDBG, mCellIdentity));
pw.println(" mLastCellInfoReqTime=" + mLastCellInfoReqTime);
dumpCellInfoList(pw);
@@ -5397,8 +5275,8 @@
pw.println(" mDefaultRoamingIndicator=" + mDefaultRoamingIndicator);
pw.println(" mRegistrationState=" + mRegistrationState);
pw.println(" mMdn=" + mMdn);
- pw.println(" mHomeSystemId=" + mHomeSystemId);
- pw.println(" mHomeNetworkId=" + mHomeNetworkId);
+ pw.println(" mHomeSystemId=" + Arrays.toString(mHomeSystemId));
+ pw.println(" mHomeNetworkId=" + Arrays.toString(mHomeNetworkId));
pw.println(" mMin=" + mMin);
pw.println(" mPrlVersion=" + mPrlVersion);
pw.println(" mIsMinInfoReady=" + mIsMinInfoReady);
diff --git a/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java b/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java
index 7c52a42..f5d9e9e 100644
--- a/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java
+++ b/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java
@@ -16,6 +16,8 @@
package com.android.internal.telephony;
+import static java.util.Map.entry;
+
import android.compat.annotation.UnsupportedAppUsage;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
@@ -72,19 +74,18 @@
/** Mapping from DB COLUMN to PDU_PENDING_MESSAGE_PROJECTION index */
static final Map<Integer, Integer> PDU_PENDING_MESSAGE_PROJECTION_INDEX_MAPPING =
- new HashMap<Integer, Integer>() {{
- put(InboundSmsHandler.PDU_COLUMN, 0);
- put(InboundSmsHandler.SEQUENCE_COLUMN, 1);
- put(InboundSmsHandler.DESTINATION_PORT_COLUMN, 2);
- put(InboundSmsHandler.DATE_COLUMN, 3);
- put(InboundSmsHandler.REFERENCE_NUMBER_COLUMN, 4);
- put(InboundSmsHandler.COUNT_COLUMN, 5);
- put(InboundSmsHandler.ADDRESS_COLUMN, 6);
- put(InboundSmsHandler.ID_COLUMN, 7);
- put(InboundSmsHandler.MESSAGE_BODY_COLUMN, 8);
- put(InboundSmsHandler.DISPLAY_ADDRESS_COLUMN, 9);
- put(InboundSmsHandler.SUBID_COLUMN, 10);
- }};
+ Map.ofEntries(
+ entry(InboundSmsHandler.PDU_COLUMN, 0),
+ entry(InboundSmsHandler.SEQUENCE_COLUMN, 1),
+ entry(InboundSmsHandler.DESTINATION_PORT_COLUMN, 2),
+ entry(InboundSmsHandler.DATE_COLUMN, 3),
+ entry(InboundSmsHandler.REFERENCE_NUMBER_COLUMN, 4),
+ entry(InboundSmsHandler.COUNT_COLUMN, 5),
+ entry(InboundSmsHandler.ADDRESS_COLUMN, 6),
+ entry(InboundSmsHandler.ID_COLUMN, 7),
+ entry(InboundSmsHandler.MESSAGE_BODY_COLUMN, 8),
+ entry(InboundSmsHandler.DISPLAY_ADDRESS_COLUMN, 9),
+ entry(InboundSmsHandler.SUBID_COLUMN, 10));
private static SmsBroadcastUndelivered instance;
diff --git a/src/java/com/android/internal/telephony/SmsStorageMonitor.java b/src/java/com/android/internal/telephony/SmsStorageMonitor.java
index b890a4d..2375c73 100755
--- a/src/java/com/android/internal/telephony/SmsStorageMonitor.java
+++ b/src/java/com/android/internal/telephony/SmsStorageMonitor.java
@@ -29,6 +29,7 @@
import android.provider.Telephony.Sms.Intents;
import android.telephony.SubscriptionManager;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.telephony.Rlog;
/**
@@ -41,14 +42,26 @@
public class SmsStorageMonitor extends Handler {
private static final String TAG = "SmsStorageMonitor";
+ /** Maximum number of times to retry memory status reporting */
+ private static final int MAX_RETRIES = 1;
+
+ /** Delay before next attempt on a failed memory status reporting, in milliseconds. */
+ private static final int RETRY_DELAY = 5000; // 5 seconds
+
/** SIM/RUIM storage is full */
private static final int EVENT_ICC_FULL = 1;
+ /** Report memory status */
+ private static final int EVENT_REPORT_MEMORY_STATUS = 2;
+
/** Memory status reporting is acknowledged by RIL */
- private static final int EVENT_REPORT_MEMORY_STATUS_DONE = 2;
+ private static final int EVENT_REPORT_MEMORY_STATUS_DONE = 3;
+
+ /** Retry memory status reporting */
+ private static final int EVENT_RETRY_MEMORY_STATUS_REPORTING = 4;
/** Radio is ON */
- private static final int EVENT_RADIO_ON = 3;
+ private static final int EVENT_RADIO_ON = 5;
/** Context from phone object passed to constructor. */
private final Context mContext;
@@ -56,14 +69,19 @@
/** Wake lock to ensure device stays awake while dispatching the SMS intent. */
private PowerManager.WakeLock mWakeLock;
- private boolean mReportMemoryStatusPending;
+ private int mMaxRetryCount = MAX_RETRIES;
+ private int mRetryDelay = RETRY_DELAY;
+ private int mRetryCount = 0;
+ private boolean mIsWaitingResponse = false;
+ private boolean mNeedNewReporting = false;
+ private boolean mIsMemoryStatusReportingFailed = false;
/** it is use to put in to extra value for SIM_FULL_ACTION and SMS_REJECTED_ACTION */
Phone mPhone;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- final CommandsInterface mCi; // accessed from inner class
- boolean mStorageAvailable = true; // accessed from inner class
+ final CommandsInterface mCi;
+ boolean mStorageAvailable = true;
/**
* Hold the wake lock for 5 seconds, which should be enough time for
@@ -93,6 +111,16 @@
mContext.registerReceiver(mResultReceiver, filter);
}
+ @VisibleForTesting
+ public void setMaxRetries(int maxCount) {
+ mMaxRetryCount = maxCount;
+ }
+
+ @VisibleForTesting
+ public void setRetryDelayInMillis(int delay) {
+ mRetryDelay = delay;
+ }
+
public void dispose() {
mCi.unSetOnIccSmsFull(this);
mCi.unregisterForOn(this);
@@ -105,35 +133,85 @@
*/
@Override
public void handleMessage(Message msg) {
- AsyncResult ar;
+ boolean isAvailable = mStorageAvailable;
switch (msg.what) {
case EVENT_ICC_FULL:
handleIccFull();
break;
- case EVENT_REPORT_MEMORY_STATUS_DONE:
- ar = (AsyncResult) msg.obj;
- if (ar.exception != null) {
- mReportMemoryStatusPending = true;
- Rlog.v(TAG, "Memory status report to modem pending : mStorageAvailable = "
- + mStorageAvailable);
+ case EVENT_REPORT_MEMORY_STATUS:
+ if (mIsWaitingResponse) {
+ Rlog.v(TAG, "EVENT_REPORT_MEMORY_STATUS - deferred");
+ // Previous reporting is on-going now. New reporting will be issued in
+ // EVENT_REPORT_MEMORY_STATUS_DONE.
+ mNeedNewReporting = true;
} else {
- mReportMemoryStatusPending = false;
+ Rlog.v(TAG, "EVENT_REPORT_MEMORY_STATUS - report sms memory status"
+ + (isAvailable ? "(not full)" : "(full)"));
+ // Clear a delayed EVENT_RETRY_MEMORY_STATUS_REPORTING
+ // and mIsMemoryStatusReportingFailed.
+ removeMessages(EVENT_RETRY_MEMORY_STATUS_REPORTING);
+ mIsMemoryStatusReportingFailed = false;
+ mRetryCount = 0;
+ sendMemoryStatusReport(isAvailable);
}
break;
+ case EVENT_REPORT_MEMORY_STATUS_DONE:
+ AsyncResult ar = (AsyncResult) msg.obj;
+ mIsWaitingResponse = false;
+ Rlog.v(TAG, "EVENT_REPORT_MEMORY_STATUS_DONE - "
+ + (ar.exception == null ? "succeeded" : "failed"));
+ if (mNeedNewReporting) {
+ Rlog.v(TAG, "EVENT_REPORT_MEMORY_STATUS_DONE - report again now"
+ + (isAvailable ? "(not full)" : "(full)"));
+ // New reportings have been requested, report last memory status here.
+ mNeedNewReporting = false;
+ mRetryCount = 0;
+ sendMemoryStatusReport(isAvailable);
+ } else {
+ if (ar.exception != null) {
+ if (mRetryCount++ < mMaxRetryCount) {
+ Rlog.v(TAG, "EVENT_REPORT_MEMORY_STATUS_DONE - retry in "
+ + mRetryDelay + "ms");
+ sendMessageDelayed(
+ obtainMessage(EVENT_RETRY_MEMORY_STATUS_REPORTING),
+ mRetryDelay);
+ } else {
+ Rlog.v(TAG, "EVENT_REPORT_MEMORY_STATUS_DONE - "
+ + "no retry anymore(pended)");
+ mRetryCount = 0;
+ mIsMemoryStatusReportingFailed = true;
+ }
+ } else {
+ mRetryCount = 0;
+ mIsMemoryStatusReportingFailed = false;
+ }
+ }
+ break;
+
+ case EVENT_RETRY_MEMORY_STATUS_REPORTING:
+ Rlog.v(TAG, "EVENT_RETRY_MEMORY_STATUS_REPORTING - retry"
+ + (isAvailable ? "(not full)" : "(full)"));
+ sendMemoryStatusReport(isAvailable);
+ break;
+
case EVENT_RADIO_ON:
- if (mReportMemoryStatusPending) {
- Rlog.v(TAG, "Sending pending memory status report : mStorageAvailable = "
- + mStorageAvailable);
- mCi.reportSmsMemoryStatus(mStorageAvailable,
- obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE));
+ if (mIsMemoryStatusReportingFailed) {
+ Rlog.v(TAG, "EVENT_RADIO_ON - report failed sms memory status"
+ + (isAvailable ? "(not full)" : "(full)"));
+ sendMemoryStatusReport(isAvailable);
}
break;
}
}
+ private void sendMemoryStatusReport(boolean isAvailable) {
+ mIsWaitingResponse = true;
+ mCi.reportSmsMemoryStatus(isAvailable, obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE));
+ }
+
private void createWakelock() {
PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SmsStorageMonitor");
@@ -161,12 +239,12 @@
private final BroadcastReceiver mResultReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_FULL)) {
- mStorageAvailable = false;
- mCi.reportSmsMemoryStatus(false, obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE));
- } else if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_NOT_FULL)) {
- mStorageAvailable = true;
- mCi.reportSmsMemoryStatus(true, obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE));
+ final String action = intent.getAction();
+ if (Intent.ACTION_DEVICE_STORAGE_FULL.equals(action)
+ || Intent.ACTION_DEVICE_STORAGE_NOT_FULL.equals(action)) {
+ mStorageAvailable =
+ Intent.ACTION_DEVICE_STORAGE_FULL.equals(action) ? false : true;
+ sendMessage(obtainMessage(EVENT_REPORT_MEMORY_STATUS));
}
}
};
diff --git a/src/java/com/android/internal/telephony/SubscriptionController.java b/src/java/com/android/internal/telephony/SubscriptionController.java
index 82799be..088cc67 100644
--- a/src/java/com/android/internal/telephony/SubscriptionController.java
+++ b/src/java/com/android/internal/telephony/SubscriptionController.java
@@ -176,15 +176,10 @@
private AppOpsManager mAppOps;
- // Allows test mocks to avoid SELinux failures on invalidate calls.
- private static boolean sCachingEnabled = true;
-
// Each slot can have multiple subs.
private static class WatchedSlotIndexToSubIds {
- private Map<Integer, ArrayList<Integer>> mSlotIndexToSubIds = new ConcurrentHashMap<>();
-
- WatchedSlotIndexToSubIds() {
- }
+ private final Map<Integer, ArrayList<Integer>> mSlotIndexToSubIds =
+ new ConcurrentHashMap<>();
public void clear() {
mSlotIndexToSubIds.clear();
@@ -203,7 +198,7 @@
return null;
}
- return new ArrayList<Integer>(subIdList);
+ return new ArrayList<>(subIdList);
}
public void put(int slotIndex, ArrayList<Integer> value) {
@@ -285,9 +280,9 @@
}
}
- private static WatchedSlotIndexToSubIds sSlotIndexToSubIds = new WatchedSlotIndexToSubIds();
+ private final WatchedSlotIndexToSubIds mSlotIndexToSubIds = new WatchedSlotIndexToSubIds();
- protected static WatchedInt sDefaultFallbackSubId =
+ private final WatchedInt mDefaultFallbackSubId =
new WatchedInt(SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
@Override
public void set(int newValue) {
@@ -628,7 +623,6 @@
+ " publicCardId:" + publicCardId
+ " isOpportunistic:" + isOpportunistic + " groupUUID:" + groupUUID
+ " profileClass:" + profileClass + " subscriptionType: " + subType
- + " carrierConfigAccessRules:" + carrierConfigAccessRules
+ " areUiccApplicationsEnabled: " + areUiccApplicationsEnabled
+ " usageSetting: " + usageSetting);
}
@@ -1492,7 +1486,7 @@
int defaultSubId = getDefaultSubId();
if (DBG) {
logdl("[addSubInfoRecord]"
- + " sSlotIndexToSubIds.size=" + sSlotIndexToSubIds.size()
+ + " mSlotIndexToSubIds.size=" + mSlotIndexToSubIds.size()
+ " slotIndex=" + slotIndex + " subId=" + subId
+ " defaultSubId=" + defaultSubId
+ " simCount=" + subIdCountMax);
@@ -1501,7 +1495,9 @@
// Set the default sub if not set or if single sim device
if (!isSubscriptionForRemoteSim(subscriptionType)) {
if (!SubscriptionManager.isValidSubscriptionId(defaultSubId)
- || subIdCountMax == 1) {
+ || subIdCountMax == 1
+ || mDefaultFallbackSubId.get() ==
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
logdl("setting default fallback subid to " + subId);
setDefaultFallbackSubId(subId, subscriptionType);
}
@@ -1572,7 +1568,7 @@
if (DBG) logdl("[addSubInfoRecord] sim name = " + nameToSet);
}
- if (DBG) logdl("[addSubInfoRecord]- info size=" + sSlotIndexToSubIds.size());
+ if (DBG) logdl("[addSubInfoRecord]- info size=" + mSlotIndexToSubIds.size());
}
} finally {
@@ -1676,7 +1672,7 @@
return -1;
}
refreshCachedActiveSubscriptionInfoList();
- result = sSlotIndexToSubIds.removeFromSubIdList(slotIndex, subId);
+ result = mSlotIndexToSubIds.removeFromSubIdList(slotIndex, subId);
if (result == NO_ENTRY_FOR_SLOT_INDEX) {
loge("sSlotIndexToSubIds has no entry for slotIndex = " + slotIndex);
} else if (result == SUB_ID_NOT_IN_SLOT) {
@@ -1720,7 +1716,26 @@
// Refresh the Cache of Active Subscription Info List
refreshCachedActiveSubscriptionInfoList();
- sSlotIndexToSubIds.remove(slotIndex);
+ boolean isFallBackRefreshRequired = false;
+ if (mDefaultFallbackSubId.get() > SubscriptionManager.INVALID_SUBSCRIPTION_ID &&
+ mSlotIndexToSubIds.getCopy(slotIndex) != null &&
+ mSlotIndexToSubIds.getCopy(slotIndex).contains(mDefaultFallbackSubId.get())) {
+ isFallBackRefreshRequired = true;
+ }
+ mSlotIndexToSubIds.remove(slotIndex);
+ // set mDefaultFallbackSubId to invalid in case mSlotIndexToSubIds do not have any entries
+ if (mSlotIndexToSubIds.size() ==0 ) {
+ mDefaultFallbackSubId.set(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ } else if (isFallBackRefreshRequired) {
+ // set mDefaultFallbackSubId to valid subId from mSlotIndexToSubIds
+ for (int index = 0; index < getActiveSubIdArrayList().size(); index ++) {
+ int subId = getActiveSubIdArrayList().get(index);
+ if (subId > SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ mDefaultFallbackSubId.set(subId);
+ break;
+ }
+ }
+ }
}
/**
@@ -2607,14 +2622,14 @@
return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
}
- int size = sSlotIndexToSubIds.size();
+ int size = mSlotIndexToSubIds.size();
if (size == 0) {
if (DBG) logd("[getSlotIndex]- size == 0, return SIM_NOT_INSERTED instead");
return SubscriptionManager.SIM_NOT_INSERTED;
}
- for (Entry<Integer, ArrayList<Integer>> entry : sSlotIndexToSubIds.entrySet()) {
+ for (Entry<Integer, ArrayList<Integer>> entry : mSlotIndexToSubIds.entrySet()) {
int sim = entry.getKey();
ArrayList<Integer> subs = entry.getValue();
@@ -2657,7 +2672,7 @@
}
// Check if we've got any SubscriptionInfo records using slotIndexToSubId as a surrogate.
- int size = sSlotIndexToSubIds.size();
+ int size = mSlotIndexToSubIds.size();
if (size == 0) {
if (VDBG) {
logd("[getSubId]- sSlotIndexToSubIds.size == 0, return null slotIndex="
@@ -2667,13 +2682,13 @@
}
// Convert ArrayList to array
- ArrayList<Integer> subIds = sSlotIndexToSubIds.getCopy(slotIndex);
+ ArrayList<Integer> subIds = mSlotIndexToSubIds.getCopy(slotIndex);
if (subIds != null && subIds.size() > 0) {
int[] subIdArr = new int[subIds.size()];
for (int i = 0; i < subIds.size(); i++) {
subIdArr[i] = subIds.get(i);
}
- if (VDBG) logd("[getSubId]- subIdArr=" + subIdArr);
+ if (VDBG) logd("[getSubId]- subIdArr=" + Arrays.toString(subIdArr));
return subIdArr;
} else {
if (DBG) logd("[getSubId]- numSubIds == 0, return null slotIndex=" + slotIndex);
@@ -2700,7 +2715,7 @@
return SubscriptionManager.INVALID_PHONE_INDEX;
}
- int size = sSlotIndexToSubIds.size();
+ int size = mSlotIndexToSubIds.size();
if (size == 0) {
phoneId = mDefaultPhoneId;
if (VDBG) logdl("[getPhoneId]- no sims, returning default phoneId=" + phoneId);
@@ -2708,7 +2723,7 @@
}
// FIXME: Assumes phoneId == slotIndex
- for (Entry<Integer, ArrayList<Integer>> entry: sSlotIndexToSubIds.entrySet()) {
+ for (Entry<Integer, ArrayList<Integer>> entry: mSlotIndexToSubIds.entrySet()) {
int sim = entry.getKey();
ArrayList<Integer> subs = entry.getValue();
@@ -2736,14 +2751,14 @@
// Now that all security checks passes, perform the operation as ourselves.
final long identity = Binder.clearCallingIdentity();
try {
- int size = sSlotIndexToSubIds.size();
+ int size = mSlotIndexToSubIds.size();
if (size == 0) {
if (DBG) logdl("[clearSubInfo]- no simInfo size=" + size);
return 0;
}
- sSlotIndexToSubIds.clear();
+ mSlotIndexToSubIds.clear();
if (DBG) logdl("[clearSubInfo]- clear size=" + size);
return size;
} finally {
@@ -2794,7 +2809,7 @@
if (VDBG) logdl("[getDefaultSubId] NOT VoiceCapable subId=" + subId);
}
if (!isActiveSubId(subId)) {
- subId = sDefaultFallbackSubId.get();
+ subId = mDefaultFallbackSubId.get();
if (VDBG) logdl("[getDefaultSubId] NOT active use fall back subId=" + subId);
}
if (VDBG) logv("[getDefaultSubId]- value = " + subId);
@@ -2981,7 +2996,7 @@
}
int previousDefaultSub = getDefaultSubId();
if (isSubscriptionForRemoteSim(subscriptionType)) {
- sDefaultFallbackSubId.set(subId);
+ mDefaultFallbackSubId.set(subId);
return;
}
if (SubscriptionManager.isValidSubscriptionId(subId)) {
@@ -2989,7 +3004,7 @@
if (phoneId >= 0 && (phoneId < mTelephonyManager.getPhoneCount()
|| mTelephonyManager.getSimCount() == 1)) {
if (DBG) logdl("[setDefaultFallbackSubId] set sDefaultFallbackSubId=" + subId);
- sDefaultFallbackSubId.set(subId);
+ mDefaultFallbackSubId.set(subId);
// Update MCC MNC device configuration information
String defaultMccMnc = mTelephonyManager.getSimOperatorNumericForPhone(phoneId);
MccTable.updateMccMncConfiguration(mContext, defaultMccMnc);
@@ -3089,7 +3104,7 @@
private synchronized ArrayList<Integer> getActiveSubIdArrayList() {
// Clone the sub id list so it can't change out from under us while iterating
List<Entry<Integer, ArrayList<Integer>>> simInfoList =
- new ArrayList<>(sSlotIndexToSubIds.entrySet());
+ new ArrayList<>(mSlotIndexToSubIds.entrySet());
// Put the set of sub ids in slot index order
Collections.sort(simInfoList, (x, y) -> x.getKey().compareTo(y.getKey()));
@@ -3419,7 +3434,7 @@
.from(mContext).getDefaultSmsPhoneId());
pw.flush();
- for (Entry<Integer, ArrayList<Integer>> entry : sSlotIndexToSubIds.entrySet()) {
+ for (Entry<Integer, ArrayList<Integer>> entry : mSlotIndexToSubIds.entrySet()) {
pw.println(" sSlotIndexToSubId[" + entry.getKey() + "]: subIds=" + entry);
}
pw.flush();
@@ -3615,7 +3630,7 @@
return SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
}
- return phoneSwitcher.getOpportunisticDataSubscriptionId();
+ return phoneSwitcher.getAutoSelectedDataSubId();
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -3653,7 +3668,7 @@
@Override
public ParcelUuid createSubscriptionGroup(int[] subIdList, String callingPackage) {
if (subIdList == null || subIdList.length == 0) {
- throw new IllegalArgumentException("Invalid subIdList " + subIdList);
+ throw new IllegalArgumentException("Invalid subIdList " + Arrays.toString(subIdList));
}
// Makes sure calling package matches caller UID.
@@ -4434,10 +4449,10 @@
}
private synchronized boolean addToSubIdList(int slotIndex, int subId, int subscriptionType) {
- ArrayList<Integer> subIdsList = sSlotIndexToSubIds.getCopy(slotIndex);
+ ArrayList<Integer> subIdsList = mSlotIndexToSubIds.getCopy(slotIndex);
if (subIdsList == null) {
subIdsList = new ArrayList<>();
- sSlotIndexToSubIds.put(slotIndex, subIdsList);
+ mSlotIndexToSubIds.put(slotIndex, subIdsList);
}
// add the given subId unless it already exists
@@ -4447,20 +4462,20 @@
}
if (isSubscriptionForRemoteSim(subscriptionType)) {
// For Remote SIM subscriptions, a slot can have multiple subscriptions.
- sSlotIndexToSubIds.addToSubIdList(slotIndex, subId);
+ mSlotIndexToSubIds.addToSubIdList(slotIndex, subId);
} else {
// for all other types of subscriptions, a slot can have only one subscription at a time
- sSlotIndexToSubIds.clearSubIdList(slotIndex);
- sSlotIndexToSubIds.addToSubIdList(slotIndex, subId);
+ mSlotIndexToSubIds.clearSubIdList(slotIndex);
+ mSlotIndexToSubIds.addToSubIdList(slotIndex, subId);
}
// Remove the slot from sSlotIndexToSubIds if it has the same sub id with the added slot
- for (Entry<Integer, ArrayList<Integer>> entry : sSlotIndexToSubIds.entrySet()) {
+ for (Entry<Integer, ArrayList<Integer>> entry : mSlotIndexToSubIds.entrySet()) {
if (entry.getKey() != slotIndex && entry.getValue() != null
&& entry.getValue().contains(subId)) {
logdl("addToSubIdList - remove " + entry.getKey());
- sSlotIndexToSubIds.remove(entry.getKey());
+ mSlotIndexToSubIds.remove(entry.getKey());
}
}
@@ -4478,17 +4493,7 @@
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
public Map<Integer, ArrayList<Integer>> getSlotIndexToSubIdsMap() {
- return sSlotIndexToSubIds.getMap();
- }
-
- /**
- * This is only for testing
- * @hide
- */
- @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
- public void resetStaticMembers() {
- sDefaultFallbackSubId.set(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
- mDefaultPhoneId = SubscriptionManager.DEFAULT_PHONE_INDEX;
+ return mSlotIndexToSubIds.getMap();
}
private void notifyOpportunisticSubscriptionInfoChanged() {
@@ -4500,11 +4505,11 @@
}
private void refreshCachedOpportunisticSubscriptionInfoList() {
- List<SubscriptionInfo> subList = getSubInfo(
- SubscriptionManager.IS_OPPORTUNISTIC + "=1 AND ("
- + SubscriptionManager.SIM_SLOT_INDEX + ">=0 OR "
- + SubscriptionManager.IS_EMBEDDED + "=1)", null);
synchronized (mSubInfoListLock) {
+ List<SubscriptionInfo> subList = getSubInfo(
+ SubscriptionManager.IS_OPPORTUNISTIC + "=1 AND ("
+ + SubscriptionManager.SIM_SLOT_INDEX + ">=0 OR "
+ + SubscriptionManager.IS_EMBEDDED + "=1)", null);
List<SubscriptionInfo> oldOpptCachedList = mCacheOpportunisticSubInfoList;
if (subList != null) {
@@ -4780,77 +4785,36 @@
*/
private void setGlobalSetting(String name, int value) {
Settings.Global.putInt(mContext.getContentResolver(), name, value);
- if (name == Settings.Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION) {
+ if (TextUtils.equals(name, Settings.Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION)) {
invalidateDefaultDataSubIdCaches();
invalidateActiveDataSubIdCaches();
invalidateDefaultSubIdCaches();
invalidateSlotIndexCaches();
- } else if (name == Settings.Global.MULTI_SIM_VOICE_CALL_SUBSCRIPTION) {
+ } else if (TextUtils.equals(name, Settings.Global.MULTI_SIM_VOICE_CALL_SUBSCRIPTION)) {
invalidateDefaultSubIdCaches();
invalidateSlotIndexCaches();
- } else if (name == Settings.Global.MULTI_SIM_SMS_SUBSCRIPTION) {
+ } else if (TextUtils.equals(name, Settings.Global.MULTI_SIM_SMS_SUBSCRIPTION)) {
invalidateDefaultSmsSubIdCaches();
}
}
- /**
- * @hide
- */
private static void invalidateDefaultSubIdCaches() {
- if (sCachingEnabled) {
- SubscriptionManager.invalidateDefaultSubIdCaches();
- }
+ SubscriptionManager.invalidateDefaultSubIdCaches();
}
- /**
- * @hide
- */
private static void invalidateDefaultDataSubIdCaches() {
- if (sCachingEnabled) {
- SubscriptionManager.invalidateDefaultDataSubIdCaches();
- }
+ SubscriptionManager.invalidateDefaultDataSubIdCaches();
}
- /**
- * @hide
- */
private static void invalidateDefaultSmsSubIdCaches() {
- if (sCachingEnabled) {
- SubscriptionManager.invalidateDefaultSmsSubIdCaches();
- }
+ SubscriptionManager.invalidateDefaultSmsSubIdCaches();
}
- /**
- * @hide
- */
- public static void invalidateActiveDataSubIdCaches() {
- if (sCachingEnabled) {
- SubscriptionManager.invalidateActiveDataSubIdCaches();
- }
+ private static void invalidateActiveDataSubIdCaches() {
+ SubscriptionManager.invalidateActiveDataSubIdCaches();
}
- /**
- * @hide
- */
- protected static void invalidateSlotIndexCaches() {
- if (sCachingEnabled) {
- SubscriptionManager.invalidateSlotIndexCaches();
- }
- }
-
- /**
- * @hide
- */
- @VisibleForTesting
- public static void disableCaching() {
- sCachingEnabled = false;
- }
-
- /**
- * @hide
- */
- @VisibleForTesting
- public static void enableCaching() {
- sCachingEnabled = true;
+ private static void invalidateSlotIndexCaches() {
+ SubscriptionManager.invalidateSlotIndexCaches();
}
}
diff --git a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
index dcbd2d5..08c02e2 100644
--- a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
+++ b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
@@ -27,7 +27,6 @@
import android.system.Os;
import android.system.OsConstants;
import android.system.StructStatVfs;
-import android.telephony.AccessNetworkConstants.TransportType;
import android.text.TextUtils;
import com.android.ims.ImsManager;
@@ -40,9 +39,6 @@
import com.android.internal.telephony.data.DataSettingsManager;
import com.android.internal.telephony.data.LinkBandwidthEstimator;
import com.android.internal.telephony.data.PhoneSwitcher;
-import com.android.internal.telephony.dataconnection.DataEnabledSettings;
-import com.android.internal.telephony.dataconnection.DcTracker;
-import com.android.internal.telephony.dataconnection.TransportManager;
import com.android.internal.telephony.emergency.EmergencyNumberTracker;
import com.android.internal.telephony.imsphone.ImsExternalCallTracker;
import com.android.internal.telephony.imsphone.ImsPhone;
@@ -313,10 +309,6 @@
return new SimActivationTracker(phone);
}
- public DcTracker makeDcTracker(Phone phone, @TransportType int transportType) {
- return new DcTracker(phone, transportType);
- }
-
public CarrierSignalAgent makeCarrierSignalAgent(Phone phone) {
return new CarrierSignalAgent(phone);
}
@@ -404,10 +396,6 @@
return new DeviceStateMonitor(phone);
}
- public TransportManager makeTransportManager(Phone phone) {
- return new TransportManager(phone);
- }
-
/**
* Make access networks manager
*
@@ -430,10 +418,6 @@
return new LocaleTracker(phone, nitzStateMachine, looper);
}
- public DataEnabledSettings makeDataEnabledSettings(Phone phone) {
- return new DataEnabledSettings(phone);
- }
-
public Phone makePhone(Context context, CommandsInterface ci, PhoneNotifier notifier,
int phoneId, int precisePhoneType,
TelephonyComponentFactory telephonyComponentFactory) {
diff --git a/src/java/com/android/internal/telephony/data/AccessNetworksManager.java b/src/java/com/android/internal/telephony/data/AccessNetworksManager.java
index d3af323..d034abd 100644
--- a/src/java/com/android/internal/telephony/data/AccessNetworksManager.java
+++ b/src/java/com/android/internal/telephony/data/AccessNetworksManager.java
@@ -58,7 +58,6 @@
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.RIL;
import com.android.internal.telephony.SlidingWindowEventCounter;
-import com.android.internal.telephony.dataconnection.DataThrottler;
import com.android.telephony.Rlog;
import java.io.FileDescriptor;
@@ -67,7 +66,6 @@
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -156,8 +154,6 @@
private final RegistrantList mQualifiedNetworksChangedRegistrants = new RegistrantList();
- private final Set<DataThrottler> mDataThrottlers = new HashSet<>();
-
private final BroadcastReceiver mConfigChangedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -175,19 +171,9 @@
};
/**
- * The current transport of the APN type. The key is the APN type, and the value is the
- * transport.
- */
- private final Map<Integer, Integer> mCurrentTransports = new ConcurrentHashMap<>();
-
- /**
* The preferred transport of the APN type. The key is the APN type, and the value is the
- * transport. The preferred transports are updated as soon as QNS changes the preference, while
- * the current transports are updated after handover complete.
+ * transport. The preferred transports are updated as soon as QNS changes the preference.
*/
- // TODO: Deprecate mPreferredTransports. Should expose mAvailableNetworks to
- // DataNetworkController after we support multi preferred access networks (i.e.
- // DataNetworkController might select 2nd preferred access network in some scenarios.)
private final Map<Integer, Integer> mPreferredTransports = new ConcurrentHashMap<>();
/**
@@ -197,21 +183,6 @@
new ArraySet<>();
/**
- * Registers the data throttler in order to receive APN status changes.
- *
- * @param dataThrottler the data throttler to register
- */
- public void registerDataThrottler(DataThrottler dataThrottler) {
- this.post(() -> {
- QualifiedNetworksServiceConnection serviceConnection = mServiceConnection;
- this.mDataThrottlers.add(dataThrottler);
- if (serviceConnection != null) {
- serviceConnection.registerDataThrottler(dataThrottler);
- }
- });
- }
-
- /**
* Represents qualified network types list on a specific APN type.
*/
public static class QualifiedNetworks {
@@ -252,18 +223,6 @@
}
private final class QualifiedNetworksServiceConnection implements ServiceConnection {
-
- /**
- * The APN throttle status callback is attached to the service connection so that they have
- * the same life cycle.
- */
- @NonNull
- private final ThrottleStatusChangedCallback mThrottleStatusCallback;
-
- QualifiedNetworksServiceConnection() {
- mThrottleStatusCallback = new ThrottleStatusChangedCallback();
- }
-
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (DBG) log("onServiceConnected " + name);
@@ -275,9 +234,6 @@
service.linkToDeath(mDeathRecipient, 0 /* flags */);
mIQualifiedNetworksService.createNetworkAvailabilityProvider(mPhone.getPhoneId(),
new QualifiedNetworksServiceCallback());
-
- registerDataThrottlersFirstTime();
-
} catch (RemoteException e) {
loge("Remote exception. " + e);
}
@@ -286,55 +242,9 @@
@Override
public void onServiceDisconnected(ComponentName name) {
if (DBG) log("onServiceDisconnected " + name);
- unregisterForThrottleCallbacks();
mTargetBindingPackageName = null;
}
- /**
- * Runs on all of the data throttlers when the service is connected
- */
- private void registerDataThrottlersFirstTime() {
- post(() -> {
- for (DataThrottler dataThrottler : mDataThrottlers) {
- dataThrottler.registerForThrottleStatusChanges(mThrottleStatusCallback);
- }
- });
- }
-
- private void registerDataThrottler(DataThrottler dataThrottler) {
- post(() -> {
- dataThrottler.registerForThrottleStatusChanges(mThrottleStatusCallback);
- });
- }
-
- private void unregisterForThrottleCallbacks() {
- post(() -> {
- for (DataThrottler dataThrottler : mDataThrottlers) {
- dataThrottler.unregisterForThrottleStatusChanges(mThrottleStatusCallback);
- }
- });
- }
- }
-
- private class ThrottleStatusChangedCallback implements DataThrottler.Callback {
- @Override
- public void onThrottleStatusChanged(List<ThrottleStatus> throttleStatuses) {
- post(() -> {
- try {
- List<ThrottleStatus> throttleStatusesBySlot =
- throttleStatuses
- .stream()
- .filter(x -> x.getSlotIndex() == mPhone.getPhoneId())
- .collect(Collectors.toList());
- if (mIQualifiedNetworksService != null) {
- mIQualifiedNetworksService.reportThrottleStatusChanged(mPhone.getPhoneId(),
- throttleStatusesBySlot);
- }
- } catch (Exception ex) {
- loge("onThrottleStatusChanged", ex);
- }
- });
- }
}
private final class QualifiedNetworksServiceCallback extends
@@ -479,11 +389,10 @@
bindQualifiedNetworksService();
}
- if (phone.isUsingNewDataStack()) {
- // Using post to delay the registering because data retry manager and data config
- // manager instances are created later than access networks manager.
- post(() -> {
- mPhone.getDataNetworkController().getDataRetryManager().registerCallback(
+ // Using post to delay the registering because data retry manager and data config
+ // manager instances are created later than access networks manager.
+ post(() -> {
+ mPhone.getDataNetworkController().getDataRetryManager().registerCallback(
new DataRetryManager.DataRetryManagerCallback(this::post) {
@Override
public void onThrottleStatusChanged(List<ThrottleStatus> throttleStatuses) {
@@ -498,16 +407,15 @@
}
}
});
- mDataConfigManager = mPhone.getDataNetworkController().getDataConfigManager();
- mDataConfigManager.registerCallback(
- new DataConfigManager.DataConfigManagerCallback(this::post) {
- @Override
- public void onDeviceConfigChanged() {
- mApnTypeToQnsChangeNetworkCounter.clear();
- }
- });
- });
- }
+ mDataConfigManager = mPhone.getDataNetworkController().getDataConfigManager();
+ mDataConfigManager.registerCallback(
+ new DataConfigManager.DataConfigManagerCallback(this::post) {
+ @Override
+ public void onDeviceConfigChanged() {
+ mApnTypeToQnsChangeNetworkCounter.clear();
+ }
+ });
+ });
}
/**
@@ -687,60 +595,6 @@
return mAvailableTransports;
}
- /**
- * Get the transport based on the network capability.
- *
- * @param netCap The network capability.
- * @return The transport type.
- */
- public @TransportType int getCurrentTransportByNetworkCapability(@NetCapability int netCap) {
- return getCurrentTransport(DataUtils.networkCapabilityToApnType(netCap));
- }
-
- /**
- * Get the transport based on the APN type.
- *
- * @param apnType APN type
- * @return The transport type
- */
- // TODO: Remove this after TransportManager is removed.
- public @TransportType int getCurrentTransport(@ApnType int apnType) {
- // In legacy mode, always route to cellular.
- if (isInLegacyMode()) {
- return AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
- }
-
- // If we can't find the corresponding transport, always route to cellular.
- return mCurrentTransports.get(apnType) == null
- ? AccessNetworkConstants.TRANSPORT_TYPE_WWAN : mCurrentTransports.get(apnType);
- }
-
- /**
- * Set the current transport of a network capability.
- *
- * @param netCap The network capability.
- * @param transport The transport.
- */
- public void setCurrentTransportByNetworkCapability(@NetCapability int netCap,
- @TransportType int transport) {
- setCurrentTransport(DataUtils.networkCapabilityToApnType(netCap), transport);
- }
-
- /**
- * Set the current transport of apn type.
- *
- * @param apnType The APN type
- * @param transport The transport.
- */
- // TODO: Remove this after TransportManager is removed.
- public void setCurrentTransport(@ApnType int apnType, @TransportType int transport) {
- Integer previousTransport = mCurrentTransports.put(apnType, transport);
- if (previousTransport == null || previousTransport != transport) {
- logl("setCurrentTransport: apnType=" + ApnSetting.getApnTypeString(apnType)
- + ", transport=" + AccessNetworkConstants.transportTypeToString(transport));
- }
- }
-
private static @TransportType int getTransportFromAccessNetwork(int accessNetwork) {
return accessNetwork == AccessNetworkType.IWLAN
? AccessNetworkConstants.TRANSPORT_TYPE_WLAN
@@ -799,20 +653,14 @@
}
/**
- * Check if there is any APN type's current transport is on IWLAN.
+ * Check if there is any APN type preferred on IWLAN.
*
* @return {@code true} if there is any APN is on IWLAN, otherwise {@code false}.
*/
public boolean isAnyApnOnIwlan() {
for (int apnType : AccessNetworksManager.SUPPORTED_APN_TYPES) {
- if (mPhone.isUsingNewDataStack()) {
- if (getPreferredTransport(apnType) == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
- return true;
- }
- } else {
- if (getCurrentTransport(apnType) == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
- return true;
- }
+ if (getPreferredTransport(apnType) == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
+ return true;
}
}
return false;
@@ -876,14 +724,6 @@
IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " ");
pw.println(AccessNetworksManager.class.getSimpleName() + "-" + mPhone.getPhoneId() + ":");
pw.increaseIndent();
- pw.println("current transports=");
- pw.increaseIndent();
- for (int apnType : AccessNetworksManager.SUPPORTED_APN_TYPES) {
- pw.println(ApnSetting.getApnTypeString(apnType)
- + ": " + AccessNetworkConstants.transportTypeToString(
- getCurrentTransport(apnType)));
- }
- pw.decreaseIndent();
pw.println("preferred transports=");
pw.increaseIndent();
for (int apnType : AccessNetworksManager.SUPPORTED_APN_TYPES) {
diff --git a/src/java/com/android/internal/telephony/data/DataConfigManager.java b/src/java/com/android/internal/telephony/data/DataConfigManager.java
index 73f08b9..71dde93 100644
--- a/src/java/com/android/internal/telephony/data/DataConfigManager.java
+++ b/src/java/com/android/internal/telephony/data/DataConfigManager.java
@@ -135,8 +135,7 @@
private static final String DATA_CONFIG_NETWORK_TYPE_IDEN = "iDEN";
/** Network type LTE. Should not be used outside of DataConfigManager. */
- // TODO: Public only for use by DcTracker. This should be private once DcTracker is removed.
- public static final String DATA_CONFIG_NETWORK_TYPE_LTE = "LTE";
+ private static final String DATA_CONFIG_NETWORK_TYPE_LTE = "LTE";
/** Network type HSPA+. Should not be used outside of DataConfigManager. */
private static final String DATA_CONFIG_NETWORK_TYPE_HSPAP = "HSPA+";
@@ -154,12 +153,10 @@
private static final String DATA_CONFIG_NETWORK_TYPE_LTE_CA = "LTE_CA";
/** Network type NR_NSA. Should not be used outside of DataConfigManager. */
- // TODO: Public only for use by DcTracker. This should be private once DcTracker is removed.
- public static final String DATA_CONFIG_NETWORK_TYPE_NR_NSA = "NR_NSA";
+ private static final String DATA_CONFIG_NETWORK_TYPE_NR_NSA = "NR_NSA";
/** Network type NR_NSA_MMWAVE. Should not be used outside of DataConfigManager. */
- // TODO: Public only for use by DcTracker. This should be private once DcTracker is removed.
- public static final String DATA_CONFIG_NETWORK_TYPE_NR_NSA_MMWAVE = "NR_NSA_MMWAVE";
+ private static final String DATA_CONFIG_NETWORK_TYPE_NR_NSA_MMWAVE = "NR_NSA_MMWAVE";
/** Network type NR_SA. Should not be used outside of DataConfigManager. */
private static final String DATA_CONFIG_NETWORK_TYPE_NR_SA = "NR_SA";
@@ -1006,9 +1003,8 @@
* @param displayInfo The {@link TelephonyDisplayInfo} used to determine the type.
* @return The equivalent {@link DataConfigNetworkType}.
*/
- public static @NonNull @DataConfigNetworkType String getDataConfigNetworkType(
+ private static @NonNull @DataConfigNetworkType String getDataConfigNetworkType(
@NonNull TelephonyDisplayInfo displayInfo) {
- // TODO: Make method private once DataConnection is removed
int networkType = displayInfo.getNetworkType();
switch (displayInfo.getOverrideNetworkType()) {
case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED:
diff --git a/src/java/com/android/internal/telephony/data/DataNetwork.java b/src/java/com/android/internal/telephony/data/DataNetwork.java
index 8572891..bb887c9 100644
--- a/src/java/com/android/internal/telephony/data/DataNetwork.java
+++ b/src/java/com/android/internal/telephony/data/DataNetwork.java
@@ -643,6 +643,11 @@
*/
private @TransportType int mTransport;
+ /**
+ * The last known data network type.
+ */
+ private @NetworkType int mLastKnownDataNetworkType;
+
/** The reason that why setting up this data network is allowed. */
private @NonNull DataAllowedReason mDataAllowedReason;
@@ -887,6 +892,7 @@
mTrafficDescriptors.add(dataProfile.getTrafficDescriptor());
}
mTransport = transport;
+ mLastKnownDataNetworkType = getDataNetworkType();
mDataAllowedReason = dataAllowedReason;
dataProfile.setLastSetupTimestamp(SystemClock.elapsedRealtime());
mAttachedNetworkRequestList.addAll(networkRequestList);
@@ -1077,7 +1083,11 @@
onCarrierConfigUpdated();
break;
case EVENT_SERVICE_STATE_CHANGED: {
- mDataCallSessionStats.onDrsOrRatChanged(getDataNetworkType());
+ int networkType = getDataNetworkType();
+ mDataCallSessionStats.onDrsOrRatChanged(networkType);
+ if (networkType != TelephonyManager.NETWORK_TYPE_UNKNOWN) {
+ mLastKnownDataNetworkType = networkType;
+ }
updateSuspendState();
updateNetworkCapabilities();
break;
@@ -2333,7 +2343,7 @@
// If the new link properties is not compatible (e.g. IP changes, interface changes),
// then we should de-register the network agent and re-create a new one.
if ((isConnected() || isHandoverInProgress())
- && !isLinkPropertiesCompatible(linkProperties, mLinkProperties)) {
+ && !isLinkPropertiesCompatible(mLinkProperties, linkProperties)) {
logl("updateDataNetwork: Incompatible link properties detected. Re-create the "
+ "network agent. Changed from " + mLinkProperties + " to "
+ linkProperties);
@@ -3293,8 +3303,14 @@
}
/**
- * @return The PCO data map of the network. The key is the PCO id, the value is the PCO data.
- * An empty map if PCO data is not available (or when the network is on IWLAN).
+ * @return The last known data network type of the data network.
+ */
+ public @NetworkType int getLastKnownDataNetworkType() {
+ return mLastKnownDataNetworkType;
+ }
+
+ /**
+ * @return The PCO data received from the network.
*/
public @NonNull Map<Integer, PcoData> getPcoData() {
if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN
@@ -3543,6 +3559,8 @@
pw.increaseIndent();
pw.println("mSubId=" + mSubId);
pw.println("mTransport=" + AccessNetworkConstants.transportTypeToString(mTransport));
+ pw.println("mLastKnownDataNetworkType=" + TelephonyManager
+ .getNetworkTypeName(mLastKnownDataNetworkType));
pw.println("WWAN cid=" + mCid.get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN));
pw.println("WLAN cid=" + mCid.get(AccessNetworkConstants.TRANSPORT_TYPE_WLAN));
pw.println("mNetworkScore=" + mNetworkScore);
diff --git a/src/java/com/android/internal/telephony/data/DataNetworkController.java b/src/java/com/android/internal/telephony/data/DataNetworkController.java
index d004293..9eee448 100644
--- a/src/java/com/android/internal/telephony/data/DataNetworkController.java
+++ b/src/java/com/android/internal/telephony/data/DataNetworkController.java
@@ -111,6 +111,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
@@ -1125,8 +1126,8 @@
log("Subscription plans changed: " + Arrays.toString(plans));
mSubscriptionPlans.clear();
mSubscriptionPlans.addAll(Arrays.asList(plans));
- mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
- () -> callback.onSubscriptionPlanOverride()));
+ mDataNetworkControllerCallbacks.forEach(cb -> cb.invokeFromExecutor(
+ () -> cb.onSubscriptionPlanOverride()));
break;
case EVENT_SUBSCRIPTION_OVERRIDE:
int overrideMask = msg.arg1;
@@ -1145,8 +1146,8 @@
mUnmeteredOverrideNetworkTypes.remove(networkType);
}
}
- mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
- () -> callback.onSubscriptionPlanOverride()));
+ mDataNetworkControllerCallbacks.forEach(cb -> cb.invokeFromExecutor(
+ () -> cb.onSubscriptionPlanOverride()));
} else if (overrideMask == NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_CONGESTED) {
log("Congested subscription override: override=" + override
+ ", networkTypes=" + Arrays.stream(networkTypes)
@@ -1159,8 +1160,8 @@
mCongestedOverrideNetworkTypes.remove(networkType);
}
}
- mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
- () -> callback.onSubscriptionPlanOverride()));
+ mDataNetworkControllerCallbacks.forEach(cb -> cb.invokeFromExecutor(
+ () -> cb.onSubscriptionPlanOverride()));
} else {
loge("Unknown override mask: " + overrideMask);
}
@@ -1319,7 +1320,7 @@
if (nriRegState == NetworkRegistrationInfo.REGISTRATION_STATE_HOME
|| nriRegState == NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING) return true;
- // If data is OOS on the non-DDS,
+ // If data is OOS as this device slot is not modem preferred(i.e. not active for internet),
// attempt to attach PS on 2G/3G if CS connection is available.
return ss.getVoiceRegState() == ServiceState.STATE_IN_SERVICE
&& mPhone.getPhoneId() != PhoneSwitcher.getInstance().getPreferredDataPhoneId()
@@ -1373,8 +1374,26 @@
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.build(), mPhone);
+ // If one of the existing networks can satisfy the internet request, then internet is
+ // allowed.
+ if (mDataNetworkList.stream().anyMatch(dataNetwork -> internetRequest.canBeSatisfiedBy(
+ dataNetwork.getNetworkCapabilities()))) {
+ return true;
+ }
+
+ // If no existing network can satisfy the request, then check if we can possibly setup
+ // the internet network.
+
DataEvaluation evaluation = evaluateNetworkRequest(internetRequest,
DataEvaluationReason.EXTERNAL_QUERY);
+ if (evaluation.containsOnly(DataDisallowedReason.ONLY_ALLOWED_SINGLE_NETWORK)) {
+ // If the only failed reason is only single network allowed, then check if the request
+ // can trump the current network.
+ return internetRequest.getPriority() > mDataNetworkList.stream()
+ .map(DataNetwork::getPriority)
+ .max(Comparator.comparing(Integer::valueOf))
+ .orElse(0);
+ }
return !evaluation.containsDisallowedReasons();
}
@@ -1576,8 +1595,15 @@
}
// Check if there is any compatible data profile
+ int networkType = getDataNetworkType(transport);
+ if (networkType == TelephonyManager.NETWORK_TYPE_UNKNOWN
+ && transport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
+ // reach here when data is OOS but serviceStateAllowsPSAttach == true, so we adopt the
+ // voice RAT to select data profile
+ networkType = mServiceState.getVoiceNetworkType();
+ }
DataProfile dataProfile = mDataProfileManager
- .getDataProfileForNetworkRequest(networkRequest, getDataNetworkType(transport),
+ .getDataProfileForNetworkRequest(networkRequest, networkType,
// If the evaluation is due to environmental changes, then we should ignore
// the permanent failure reached earlier.
reason.isConditionBased());
@@ -1906,8 +1932,18 @@
if (mDataConfigManager.isIwlanHandoverPolicyEnabled()) {
List<HandoverRule> handoverRules = mDataConfigManager.getHandoverRules();
+ int sourceNetworkType = getDataNetworkType(dataNetwork.getTransport());
+ if (sourceNetworkType == TelephonyManager.NETWORK_TYPE_UNKNOWN) {
+ // Using the data network type stored in the data network. We
+ // cache the last known network type in data network controller
+ // because data network has much shorter life cycle. It can prevent
+ // the obsolete last known network type cached in data network
+ // type controller.
+ sourceNetworkType = dataNetwork.getLastKnownDataNetworkType();
+ }
int sourceAccessNetwork = DataUtils.networkTypeToAccessNetworkType(
- getDataNetworkType(dataNetwork.getTransport()));
+ sourceNetworkType);
+
int targetAccessNetwork = DataUtils.networkTypeToAccessNetworkType(
getDataNetworkType(DataUtils.getTargetTransport(dataNetwork.getTransport())));
NetworkCapabilities capabilities = dataNetwork.getNetworkCapabilities();
diff --git a/src/java/com/android/internal/telephony/data/DataProfileManager.java b/src/java/com/android/internal/telephony/data/DataProfileManager.java
index c7e5433..b4dc698 100644
--- a/src/java/com/android/internal/telephony/data/DataProfileManager.java
+++ b/src/java/com/android/internal/telephony/data/DataProfileManager.java
@@ -106,6 +106,9 @@
/** The preferred data profile used for internet. */
private @Nullable DataProfile mPreferredDataProfile = null;
+ /** The last data profile that's successful for internet connection. */
+ private @Nullable DataProfile mLastInternetDataProfile = null;
+
/** Preferred data profile set id. */
private int mPreferredDataProfileSetId = Telephony.Carriers.NO_APN_SET_ID;
@@ -166,7 +169,12 @@
public void onInternetDataNetworkConnected(
@NonNull List<DataProfile> dataProfiles) {
DataProfileManager.this.onInternetDataNetworkConnected(dataProfiles);
- }});
+ }
+ @Override
+ public void onInternetDataNetworkDisconnected() {
+ DataProfileManager.this.onInternetDataNetworkDisconnected();
+ }
+ });
mDataConfigManager.registerCallback(new DataConfigManagerCallback(this::post) {
@Override
public void onCarrierConfigChanged() {
@@ -285,9 +293,27 @@
}
}
+ DataProfile dataProfile;
+
+ if (!profiles.isEmpty()) { // APN database has been read successfully after SIM loaded
+ // Check if any of the profile already supports IMS, if not, add the default one.
+ dataProfile = profiles.stream()
+ .filter(dp -> dp.canSatisfy(NetworkCapabilities.NET_CAPABILITY_IMS))
+ .findFirst()
+ .orElse(null);
+ if (dataProfile == null) {
+ profiles.add(new DataProfile.Builder()
+ .setApnSetting(buildDefaultApnSetting("DEFAULT IMS", "ims",
+ ApnSetting.TYPE_IMS))
+ .setTrafficDescriptor(new TrafficDescriptor("ims", null))
+ .build());
+ log("Added default IMS data profile.");
+ }
+ }
+
// Check if any of the profile already supports ENTERPRISE, if not, check if DPC has
// configured one and retrieve the same.
- DataProfile dataProfile = profiles.stream()
+ dataProfile = profiles.stream()
.filter(dp -> dp.canSatisfy(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE))
.findFirst()
.orElse(null);
@@ -299,20 +325,6 @@
}
}
- // Check if any of the profile already supports IMS, if not, add the default one.
- dataProfile = profiles.stream()
- .filter(dp -> dp.canSatisfy(NetworkCapabilities.NET_CAPABILITY_IMS))
- .findFirst()
- .orElse(null);
- if (dataProfile == null) {
- profiles.add(new DataProfile.Builder()
- .setApnSetting(buildDefaultApnSetting("DEFAULT IMS", "ims",
- ApnSetting.TYPE_IMS))
- .setTrafficDescriptor(new TrafficDescriptor("ims", null))
- .build());
- log("Added default IMS data profile.");
- }
-
// Check if any of the profile already supports EIMS, if not, add the default one.
dataProfile = profiles.stream()
.filter(dp -> dp.canSatisfy(NetworkCapabilities.NET_CAPABILITY_EIMS))
@@ -410,12 +422,20 @@
DataProfile dataProfile = dataProfiles.stream()
.max(Comparator.comparingLong(DataProfile::getLastSetupTimestamp).reversed())
.orElse(null);
+ mLastInternetDataProfile = dataProfile;
// Save the preferred data profile into database.
setPreferredDataProfile(dataProfile);
updateDataProfiles(ONLY_UPDATE_IA_IF_CHANGED);
}
/**
+ * Called when internet data is disconnected.
+ */
+ private void onInternetDataNetworkDisconnected() {
+ mLastInternetDataProfile = null;
+ }
+
+ /**
* Get the preferred data profile for internet data.
*
* @return The preferred data profile.
@@ -498,12 +518,12 @@
setPreferredDataProfile(preferredDataProfile);
} else {
preferredDataProfile = mAllDataProfiles.stream()
- .filter(dp -> areDataProfilesSharingApn(dp, mPreferredDataProfile))
+ .filter(dp -> areDataProfilesSharingApn(dp, mLastInternetDataProfile))
.findFirst()
.orElse(null);
if (preferredDataProfile != null) {
log("updatePreferredDataProfile: preferredDB is empty and no carrier "
- + "default configured, setting preferred to be prev preferred DP.");
+ + "default configured, setting preferred to be prev internet DP.");
setPreferredDataProfile(preferredDataProfile);
}
}
@@ -946,6 +966,9 @@
? apn1.getMtuV4() : apn2.getMtuV4());
apnBuilder.setMtuV6(apn2.getMtuV6() <= ApnSetting.UNSET_MTU
? apn1.getMtuV6() : apn2.getMtuV6());
+ // legacy properties that don't matter
+ apnBuilder.setMvnoType(apn1.getMvnoType());
+ apnBuilder.setMvnoMatchData(apn1.getMvnoMatchData());
// The following fields in apn1 and apn2 should be the same, otherwise ApnSetting.similar()
// should fail earlier.
@@ -960,8 +983,6 @@
apnBuilder.setMaxConns(apn1.getMaxConns());
apnBuilder.setWaitTime(apn1.getWaitTime());
apnBuilder.setMaxConnsTime(apn1.getMaxConnsTime());
- apnBuilder.setMvnoType(apn1.getMvnoType());
- apnBuilder.setMvnoMatchData(apn1.getMvnoMatchData());
apnBuilder.setApnSetId(apn1.getApnSetId());
apnBuilder.setCarrierId(apn1.getCarrierId());
apnBuilder.setSkip464Xlat(apn1.getSkip464Xlat());
@@ -992,14 +1013,13 @@
return true;
}
- // Only check the APN from the profile is compatible or not.
+ // Check the APN from the profile is compatible and matches preferred data profile set id.
return mAllDataProfiles.stream()
.filter(dp -> dp.getApnSetting() != null
&& (dp.getApnSetting().getApnSetId()
== Telephony.Carriers.MATCH_ALL_APN_SET_ID
|| dp.getApnSetting().getApnSetId() == mPreferredDataProfileSetId))
.anyMatch(dp -> areDataProfilesSharingApn(dataProfile, dp));
-
}
/**
diff --git a/src/java/com/android/internal/telephony/data/DataRetryManager.java b/src/java/com/android/internal/telephony/data/DataRetryManager.java
index 0faad2c..0beea1f 100644
--- a/src/java/com/android/internal/telephony/data/DataRetryManager.java
+++ b/src/java/com/android/internal/telephony/data/DataRetryManager.java
@@ -1009,18 +1009,16 @@
switch (msg.what) {
case EVENT_DATA_SETUP_RETRY:
DataSetupRetryEntry dataSetupRetryEntry = (DataSetupRetryEntry) msg.obj;
- Objects.requireNonNull(dataSetupRetryEntry);
- mDataRetryManagerCallbacks.forEach(callback -> callback.invokeFromExecutor(
- () -> callback.onDataNetworkSetupRetry(dataSetupRetryEntry)));
+ if (!isRetryCancelled(dataSetupRetryEntry)) {
+ mDataRetryManagerCallbacks.forEach(callback -> callback.invokeFromExecutor(
+ () -> callback.onDataNetworkSetupRetry(dataSetupRetryEntry)));
+ }
break;
case EVENT_DATA_HANDOVER_RETRY:
DataHandoverRetryEntry dataHandoverRetryEntry = (DataHandoverRetryEntry) msg.obj;
- Objects.requireNonNull(dataHandoverRetryEntry);
- if (mDataRetryEntries.contains(dataHandoverRetryEntry)) {
+ if (!isRetryCancelled(dataHandoverRetryEntry)) {
mDataRetryManagerCallbacks.forEach(callback -> callback.invokeFromExecutor(
() -> callback.onDataNetworkHandoverRetry(dataHandoverRetryEntry)));
- } else {
- log("Handover was cancelled earlier. " + dataHandoverRetryEntry);
}
break;
case EVENT_RADIO_ON:
@@ -1054,6 +1052,18 @@
}
/**
+ * @param retryEntry The retry entry to check.
+ * @return {@code true} if the retry is null or not in RETRY_STATE_NOT_RETRIED state.
+ */
+ private boolean isRetryCancelled(@Nullable DataRetryEntry retryEntry) {
+ if (retryEntry != null && retryEntry.getState() == DataRetryEntry.RETRY_STATE_NOT_RETRIED) {
+ return false;
+ }
+ log("Retry was removed earlier. " + retryEntry);
+ return true;
+ }
+
+ /**
* Called when carrier config is updated.
*/
private void onCarrierConfigUpdated() {
@@ -1536,6 +1546,11 @@
mDataRetryManagerCallbacks.forEach(callback -> callback.invokeFromExecutor(
() -> callback.onThrottleStatusChanged(throttleStatusList)));
+ if (unthrottledProfile != null) {
+ // cancel pending retries since we will soon schedule an immediate retry
+ cancelRetriesForDataProfile(unthrottledProfile, transport);
+ }
+
logl("onDataProfileUnthrottled: Removing the following throttling entries. "
+ dataUnthrottlingEntries);
if (retry) {
@@ -1563,6 +1578,34 @@
}
/**
+ * Cancel pending retries that uses the specified data profile, with specified target transport.
+ *
+ * @param dataProfile The data profile to cancel.
+ * @param transport The target {@link TransportType} on which the retry to cancel.
+ */
+ private void cancelRetriesForDataProfile(@NonNull DataProfile dataProfile,
+ @TransportType int transport) {
+ logl("cancelRetriesForDataProfile: Canceling pending retries for " + dataProfile);
+ mDataRetryEntries.stream()
+ .filter(entry -> {
+ if (entry.getState() == DataRetryEntry.RETRY_STATE_NOT_RETRIED) {
+ if (entry instanceof DataSetupRetryEntry) {
+ DataSetupRetryEntry retryEntry = (DataSetupRetryEntry) entry;
+ return dataProfile.equals(retryEntry.dataProfile)
+ && transport == retryEntry.transport;
+ } else if (entry instanceof DataHandoverRetryEntry) {
+ DataHandoverRetryEntry retryEntry = (DataHandoverRetryEntry) entry;
+ return dataProfile.equals(retryEntry.dataNetwork.getDataProfile());
+ }
+ }
+ return false;
+ })
+ .forEach(entry -> entry.setState(DataRetryEntry.RETRY_STATE_CANCELLED));
+ }
+
+
+
+ /**
* Check if there is any similar network request scheduled to retry. The definition of similar
* is that network requests have same APN capability and on the same transport.
*
@@ -1646,14 +1689,18 @@
* @param dataNetwork The data network that was originally scheduled for handover retry.
*/
private void onCancelPendingHandoverRetry(@NonNull DataNetwork dataNetwork) {
- mDataRetryEntries.removeIf(entry -> entry instanceof DataHandoverRetryEntry
- && ((DataHandoverRetryEntry) entry).dataNetwork == dataNetwork);
+ mDataRetryEntries.stream()
+ .filter(entry -> entry instanceof DataHandoverRetryEntry
+ && ((DataHandoverRetryEntry) entry).dataNetwork == dataNetwork
+ && entry.getState() == DataRetryEntry.RETRY_STATE_NOT_RETRIED)
+ .forEach(entry -> entry.setState(DataRetryEntry.RETRY_STATE_CANCELLED));
mDataThrottlingEntries.removeIf(entry -> entry.dataNetwork == dataNetwork);
}
/**
* Check if there is any data handover retry scheduled.
*
+ *
* @param dataNetwork The network network to retry handover.
* @return {@code true} if there is retry scheduled for this network capability.
*/
diff --git a/src/java/com/android/internal/telephony/data/LinkBandwidthEstimator.java b/src/java/com/android/internal/telephony/data/LinkBandwidthEstimator.java
index c225b3f..994e8f6 100644
--- a/src/java/com/android/internal/telephony/data/LinkBandwidthEstimator.java
+++ b/src/java/com/android/internal/telephony/data/LinkBandwidthEstimator.java
@@ -32,8 +32,6 @@
import android.os.HandlerExecutor;
import android.os.Message;
import android.os.OutcomeReceiver;
-import android.os.Registrant;
-import android.os.RegistrantList;
import android.preference.PreferenceManager;
import android.telephony.AccessNetworkConstants;
import android.telephony.Annotation.DataActivityType;
@@ -191,7 +189,6 @@
private String mBandwidthUpdatePlmn = UNKNOWN_PLMN;
private BandwidthState mTxState = new BandwidthState(LINK_TX);
private BandwidthState mRxState = new BandwidthState(LINK_RX);
- private RegistrantList mBandwidthChangedRegistrants = new RegistrantList();
private long mLastPlmnOrRatChangeTimeMs;
private long mLastDrsOrRatChangeTimeMs;
@@ -351,33 +348,6 @@
}
/**
- * Registers for bandwidth estimation change. The bandwidth will be returned
- * * {@link AsyncResult#result} as a {@link Pair} Object.
- * * The {@link AsyncResult} will be in the notification {@link Message#obj}.
- * @param h handler to notify
- * @param what what code of message when delivered
- * @param obj placed in Message.obj
- *
- * @deprecated Use {@link #registerCallback(LinkBandwidthEstimatorCallback)}.
- */
- @Deprecated //TODO: Remove once old data stack is removed.
- public void registerForBandwidthChanged(Handler h, int what, Object obj) {
- Registrant r = new Registrant(h, what, obj);
- mBandwidthChangedRegistrants.add(r);
- }
-
- /**
- * Unregisters for bandwidth estimation change.
- * @param h handler to notify
- *
- * @deprecated Use {@link #unregisterCallback(LinkBandwidthEstimatorCallback)}.
- */
- @Deprecated //TODO: Remove once old data stack is removed.
- public void unregisterForBandwidthChanged(Handler h) {
- mBandwidthChangedRegistrants.remove(h);
- }
-
- /**
* Register the callback for receiving information from {@link LinkBandwidthEstimator}.
*
* @param callback The callback.
@@ -441,6 +411,7 @@
return;
}
mIsOnDefaultRoute = isOnDefaultRoute;
+ logd("mIsOnDefaultRoute " + mIsOnDefaultRoute);
handleTrafficStatsPollConditionChanged();
}
@@ -465,6 +436,13 @@
if (mScreenOn && mIsOnDefaultRoute && mIsOnActiveData) {
updateDataRatCellIdentityBandwidth();
handleTrafficStatsPoll();
+ } else {
+ logd("Traffic status poll stopped");
+ if (mDataActivity != TelephonyManager.DATA_ACTIVITY_NONE) {
+ mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
+ mLinkBandwidthEstimatorCallbacks.forEach(callback -> callback.invokeFromExecutor(
+ () -> callback.onDataActivityChanged(mDataActivity)));
+ }
}
}
@@ -930,9 +908,6 @@
private void sendLinkBandwidthToDataConnection(int linkBandwidthTxKps, int linkBandwidthRxKps) {
logv("send to DC tx " + linkBandwidthTxKps + " rx " + linkBandwidthRxKps);
- Pair<Integer, Integer> bandwidthInfo =
- new Pair<Integer, Integer>(linkBandwidthTxKps, linkBandwidthRxKps);
- mBandwidthChangedRegistrants.notifyRegistrants(new AsyncResult(null, bandwidthInfo, null));
mLinkBandwidthEstimatorCallbacks.forEach(callback -> callback.invokeFromExecutor(
() -> callback.onBandwidthChanged(linkBandwidthTxKps, linkBandwidthRxKps)));
}
@@ -1175,8 +1150,7 @@
StringBuilder sb = new StringBuilder();
sb.append("Plmn").append(mPlmn)
.append("Rat").append(mDataRat)
- .append("Tac").append(mTac)
- .toString();
+ .append("Tac").append(mTac);
return sb.toString();
}
}
diff --git a/src/java/com/android/internal/telephony/data/NotifyQosSessionInterface.java b/src/java/com/android/internal/telephony/data/NotifyQosSessionInterface.java
deleted file mode 100644
index 554177a..0000000
--- a/src/java/com/android/internal/telephony/data/NotifyQosSessionInterface.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.data;
-
-import android.annotation.NonNull;
-import android.net.NetworkAgent;
-import android.net.QosSessionAttributes;
-
-/**
- * The temporary interface that is shared by
- * {@link com.android.internal.telephony.dataconnection.DcNetworkAgent} and
- * {@link com.android.internal.telephony.data.TelephonyNetworkAgent} so they can both interact
- * with {@link QosCallbackTracker}.
- */
-// TODO: Remove after DcNetworkAgent is removed.
-public interface NotifyQosSessionInterface {
- /**
- * Sends the attributes of Qos Session back to the Application. This method is create for
- * Mockito to mock since
- * {@link NetworkAgent#sendQosSessionAvailable(int, int, QosSessionAttributes)} is
- * {@code final} that can't be mocked.
- *
- * @param qosCallbackId the callback id that the session belongs to.
- * @param sessionId the unique session id across all Qos Sessions.
- * @param attributes the attributes of the Qos Session.
- */
- void notifyQosSessionAvailable(int qosCallbackId, int sessionId,
- @NonNull QosSessionAttributes attributes);
-
- /**
- * Sends event that the Qos Session was lost. This method is create for Mockito to mock
- * since {@link NetworkAgent#sendQosSessionLost(int, int, int)} is {@code final} that can't be
- * mocked..
- *
- * @param qosCallbackId the callback id that the session belongs to.
- * @param sessionId the unique session id across all Qos Sessions.
- * @param qosSessionType the session type {@code QosSession#QosSessionType}.
- */
- void notifyQosSessionLost(int qosCallbackId, int sessionId, int qosSessionType);
-}
diff --git a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
index cc5f447..ee8d157 100644
--- a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
+++ b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
@@ -31,6 +31,7 @@
import static java.util.Arrays.copyOf;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -53,6 +54,7 @@
import android.os.Registrant;
import android.os.RegistrantList;
import android.os.RemoteException;
+import android.provider.DeviceConfig;
import android.telephony.CarrierConfigManager;
import android.telephony.PhoneCapability;
import android.telephony.PhoneStateListener;
@@ -65,6 +67,7 @@
import android.telephony.ims.ImsRegistrationAttributes;
import android.telephony.ims.RegistrationManager;
import android.telephony.ims.stub.ImsRegistrationImplBase;
+import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.LocalLog;
@@ -83,8 +86,6 @@
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.data.DataNetworkController.NetworkRequestList;
import com.android.internal.telephony.data.DataSettingsManager.DataSettingsManagerCallback;
-import com.android.internal.telephony.dataconnection.ApnConfigTypeRepository;
-import com.android.internal.telephony.dataconnection.DcRequest;
import com.android.internal.telephony.metrics.TelephonyMetrics;
import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent;
import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.DataSwitch;
@@ -96,7 +97,6 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Calendar;
-import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -112,6 +112,9 @@
*/
public class PhoneSwitcher extends Handler {
private static final String LOG_TAG = "PhoneSwitcher";
+ /** DeviceConfig key of the time threshold in ms for defining a network status to be stable. **/
+ private static final String KEY_AUTO_DATA_SWITCH_AVAILABILITY_STABILITY_TIME_THRESHOLD =
+ "auto_data_switch_availability_stability_time_threshold";
protected static final boolean VDBG = false;
private static final int DEFAULT_NETWORK_CHANGE_TIMEOUT_MS = 5000;
@@ -182,7 +185,6 @@
}
}
- protected final List<DcRequest> mPrioritizedDcRequests = new ArrayList<>();
private final @NonNull NetworkRequestList mNetworkRequestList = new NetworkRequestList();
protected final RegistrantList mActivePhoneRegistrants;
protected final SubscriptionController mSubscriptionController;
@@ -194,6 +196,7 @@
@VisibleForTesting
protected final CellularNetworkValidator mValidator;
private int mPendingSwitchSubId = INVALID_SUBSCRIPTION_ID;
+ private int mLastAutoSelectedSwitchReason = -1;
private boolean mPendingSwitchNeedValidation;
@VisibleForTesting
public final CellularNetworkValidator.ValidationCallback mValidationCallback =
@@ -226,9 +229,12 @@
// Internet data if mOpptDataSubId is not set.
protected int mPrimaryDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
- // mOpptDataSubId must be an active subscription. If it's set, it overrides mPrimaryDataSubId
- // to be used for Internet data.
- private int mOpptDataSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
+ // The automatically suggested preferred data subId (by e.g. CBRS or auto data switch), a
+ // candidate for preferred data subId, which is eventually presided by
+ // updatePreferredDataPhoneId().
+ // If CBRS/auto switch feature selects the primary data subId as the preferred data subId,
+ // its value will be DEFAULT_SUBSCRIPTION_ID.
+ private int mAutoSelectedDataSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
// The phone ID that has an active voice call. If set, and its mobile data setting is on,
// it will become the mPreferredDataPhoneId.
@@ -249,7 +255,7 @@
@Override
public void set(int newValue) {
super.set(newValue);
- SubscriptionController.invalidateActiveDataSubIdCaches();
+ SubscriptionManager.invalidateActiveDataSubIdCaches();
}
};
@@ -298,6 +304,7 @@
private static final int EVENT_PROCESS_SIM_STATE_CHANGE = 119;
@VisibleForTesting
public static final int EVENT_IMS_RADIO_TECH_CHANGED = 120;
+ public static final int EVENT_DEVICE_CONFIG_CHANGED = 121;
// List of events triggers re-evaluations
private static final String EVALUATION_REASON_RADIO_ON = "EVENT_RADIO_ON";
@@ -324,6 +331,13 @@
private List<Set<CommandException.Error>> mCurrentDdsSwitchFailure;
+ /**
+ * Time threshold in ms to define a internet connection status to be stable(e.g. out of service,
+ * in service, wifi is the default active network.etc), while -1 indicates auto switch
+ * feature disabled.
+ */
+ private long mAutoDataSwitchAvailabilityStabilityTimeThreshold = -1;
+
/** Data settings manager callback. Key is the phone id. */
private final @NonNull Map<Integer, DataSettingsManagerCallback> mDataSettingsManagerCallbacks =
new ArrayMap<>();
@@ -395,7 +409,7 @@
public static PhoneSwitcher make(int maxDataAttachModemCount, Context context, Looper looper) {
if (sPhoneSwitcher == null) {
sPhoneSwitcher = new PhoneSwitcher(maxDataAttachModemCount, context, looper);
- SubscriptionController.invalidateActiveDataSubIdCaches();
+ SubscriptionManager.invalidateActiveDataSubIdCaches();
}
return sPhoneSwitcher;
@@ -507,21 +521,16 @@
phone.getImsPhone().registerForPreciseCallStateChanged(
this, EVENT_PRECISE_CALL_STATE_CHANGED, null);
}
- if (phone.isUsingNewDataStack()) {
- mDataSettingsManagerCallbacks.computeIfAbsent(phone.getPhoneId(),
- v -> new DataSettingsManagerCallback(this::post) {
- @Override
- public void onDataEnabledChanged(boolean enabled,
- @TelephonyManager.DataEnabledChangedReason int reason,
- @NonNull String callingPackage) {
- evaluateIfDataSwitchIsNeeded("EVENT_DATA_ENABLED_CHANGED");
- }});
- phone.getDataSettingsManager().registerCallback(
- mDataSettingsManagerCallbacks.get(phone.getPhoneId()));
- } else {
- phone.getDataEnabledSettings().registerForDataEnabledChanged(
- this, EVENT_DATA_ENABLED_CHANGED, null);
- }
+ mDataSettingsManagerCallbacks.computeIfAbsent(phone.getPhoneId(),
+ v -> new DataSettingsManagerCallback(this::post) {
+ @Override
+ public void onDataEnabledChanged(boolean enabled,
+ @TelephonyManager.DataEnabledChangedReason int reason,
+ @NonNull String callingPackage) {
+ evaluateIfDataSwitchIsNeeded("EVENT_DATA_ENABLED_CHANGED");
+ }});
+ phone.getDataSettingsManager().registerCallback(
+ mDataSettingsManagerCallbacks.get(phone.getPhoneId()));
registerForImsRadioTechChange(context, i);
}
@@ -578,6 +587,17 @@
// we want to see all requests
networkFactory.registerIgnoringScore();
+ // Register for device config update
+ DeviceConfig.addOnPropertiesChangedListener(
+ DeviceConfig.NAMESPACE_TELEPHONY, this::post,
+ properties -> {
+ if (TextUtils.equals(DeviceConfig.NAMESPACE_TELEPHONY,
+ properties.getNamespace())) {
+ sendEmptyMessage(EVENT_DEVICE_CONFIG_CHANGED);
+ }
+ });
+ updateDeviceConfig();
+
updateHalCommandToUse();
log("PhoneSwitcher started");
@@ -849,9 +869,23 @@
}
break;
}
+ case EVENT_DEVICE_CONFIG_CHANGED: {
+ updateDeviceConfig();
+ break;
+ }
}
}
+ /** Update local properties from {@link DeviceConfig} */
+ private void updateDeviceConfig() {
+ DeviceConfig.Properties properties = //read all telephony properties
+ DeviceConfig.getProperties(DeviceConfig.NAMESPACE_TELEPHONY);
+
+ mAutoDataSwitchAvailabilityStabilityTimeThreshold = properties.getInt(
+ KEY_AUTO_DATA_SWITCH_AVAILABILITY_STABILITY_TIME_THRESHOLD, -1);
+
+ }
+
private synchronized void onMultiSimConfigChanged(int activeModemCount) {
// No change.
if (mActiveModemCount == activeModemCount) return;
@@ -880,22 +914,17 @@
this, EVENT_PRECISE_CALL_STATE_CHANGED, null);
}
- if (phone.isUsingNewDataStack()) {
- mDataSettingsManagerCallbacks.computeIfAbsent(phone.getPhoneId(),
- v -> new DataSettingsManagerCallback(this::post) {
- @Override
- public void onDataEnabledChanged(boolean enabled,
- @TelephonyManager.DataEnabledChangedReason int reason,
- @NonNull String callingPackage) {
- evaluateIfDataSwitchIsNeeded("EVENT_DATA_ENABLED_CHANGED");
- }
- });
- phone.getDataSettingsManager().registerCallback(
- mDataSettingsManagerCallbacks.get(phone.getPhoneId()));
- } else {
- phone.getDataEnabledSettings().registerForDataEnabledChanged(
- this, EVENT_DATA_ENABLED_CHANGED, null);
- }
+ mDataSettingsManagerCallbacks.computeIfAbsent(phone.getPhoneId(),
+ v -> new DataSettingsManagerCallback(this::post) {
+ @Override
+ public void onDataEnabledChanged(boolean enabled,
+ @TelephonyManager.DataEnabledChangedReason int reason,
+ @NonNull String callingPackage) {
+ evaluateIfDataSwitchIsNeeded("EVENT_DATA_ENABLED_CHANGED");
+ }
+ });
+ phone.getDataSettingsManager().registerCallback(
+ mDataSettingsManagerCallbacks.get(phone.getPhoneId()));
Set<CommandException.Error> ddsFailure = new HashSet<CommandException.Error>();
mCurrentDdsSwitchFailure.add(ddsFailure);
@@ -941,62 +970,21 @@
}
private void onRequestNetwork(NetworkRequest networkRequest) {
- if (PhoneFactory.getDefaultPhone().isUsingNewDataStack()) {
- TelephonyNetworkRequest telephonyNetworkRequest = new TelephonyNetworkRequest(
- networkRequest, PhoneFactory.getDefaultPhone());
- if (!mNetworkRequestList.contains(telephonyNetworkRequest)) {
- mNetworkRequestList.add(telephonyNetworkRequest);
- onEvaluate(REQUESTS_CHANGED, "netRequest");
- }
- return;
- }
- final DcRequest dcRequest =
- DcRequest.create(networkRequest, createApnRepository(networkRequest));
- if (dcRequest != null) {
- if (!mPrioritizedDcRequests.contains(dcRequest)) {
- collectRequestNetworkMetrics(networkRequest);
- mPrioritizedDcRequests.add(dcRequest);
- Collections.sort(mPrioritizedDcRequests);
- onEvaluate(REQUESTS_CHANGED, "netRequest");
- if (VDBG) log("Added DcRequest, size: " + mPrioritizedDcRequests.size());
- }
+ TelephonyNetworkRequest telephonyNetworkRequest = new TelephonyNetworkRequest(
+ networkRequest, PhoneFactory.getDefaultPhone());
+ if (!mNetworkRequestList.contains(telephonyNetworkRequest)) {
+ mNetworkRequestList.add(telephonyNetworkRequest);
+ onEvaluate(REQUESTS_CHANGED, "netRequest");
}
}
private void onReleaseNetwork(NetworkRequest networkRequest) {
- if (PhoneFactory.getDefaultPhone().isUsingNewDataStack()) {
- TelephonyNetworkRequest telephonyNetworkRequest = new TelephonyNetworkRequest(
- networkRequest, PhoneFactory.getDefaultPhone());
- if (mNetworkRequestList.remove(telephonyNetworkRequest)) {
- onEvaluate(REQUESTS_CHANGED, "netReleased");
- collectReleaseNetworkMetrics(networkRequest);
- }
- return;
+ TelephonyNetworkRequest telephonyNetworkRequest = new TelephonyNetworkRequest(
+ networkRequest, PhoneFactory.getDefaultPhone());
+ if (mNetworkRequestList.remove(telephonyNetworkRequest)) {
+ onEvaluate(REQUESTS_CHANGED, "netReleased");
+ collectReleaseNetworkMetrics(networkRequest);
}
- final DcRequest dcRequest =
- DcRequest.create(networkRequest, createApnRepository(networkRequest));
- if (dcRequest != null) {
- if (mPrioritizedDcRequests.remove(dcRequest)) {
- onEvaluate(REQUESTS_CHANGED, "netReleased");
- collectReleaseNetworkMetrics(networkRequest);
- if (VDBG) log("Removed DcRequest, size: " + mPrioritizedDcRequests.size());
- }
- }
- }
-
- private ApnConfigTypeRepository createApnRepository(NetworkRequest networkRequest) {
- int phoneIdForRequest = phoneIdForRequest(networkRequest);
- int subId = mSubscriptionController.getSubIdUsingPhoneId(phoneIdForRequest);
- CarrierConfigManager configManager = (CarrierConfigManager) mContext
- .getSystemService(Context.CARRIER_CONFIG_SERVICE);
-
- PersistableBundle carrierConfig;
- if (configManager != null) {
- carrierConfig = configManager.getConfigForSubId(subId);
- } else {
- carrierConfig = null;
- }
- return new ApnConfigTypeRepository(carrierConfig);
}
private void removeDefaultNetworkChangeCallback() {
@@ -1147,22 +1135,12 @@
}
if (newActivePhones.size() < mMaxDataAttachModemCount) {
- if (PhoneFactory.getDefaultPhone().isUsingNewDataStack()) {
- for (TelephonyNetworkRequest networkRequest : mNetworkRequestList) {
- int phoneIdForRequest = phoneIdForRequest(networkRequest);
- if (phoneIdForRequest == INVALID_PHONE_INDEX) continue;
- if (newActivePhones.contains(phoneIdForRequest)) continue;
- newActivePhones.add(phoneIdForRequest);
- if (newActivePhones.size() >= mMaxDataAttachModemCount) break;
- }
- } else {
- for (DcRequest dcRequest : mPrioritizedDcRequests) {
- int phoneIdForRequest = phoneIdForRequest(dcRequest.networkRequest);
- if (phoneIdForRequest == INVALID_PHONE_INDEX) continue;
- if (newActivePhones.contains(phoneIdForRequest)) continue;
- newActivePhones.add(phoneIdForRequest);
- if (newActivePhones.size() >= mMaxDataAttachModemCount) break;
- }
+ for (TelephonyNetworkRequest networkRequest : mNetworkRequestList) {
+ int phoneIdForRequest = phoneIdForRequest(networkRequest);
+ if (phoneIdForRequest == INVALID_PHONE_INDEX) continue;
+ if (newActivePhones.contains(phoneIdForRequest)) continue;
+ newActivePhones.add(phoneIdForRequest);
+ if (newActivePhones.size() >= mMaxDataAttachModemCount) break;
}
}
@@ -1175,7 +1153,7 @@
if (VDBG) {
log("mPrimaryDataSubId = " + mPrimaryDataSubId);
- log("mOpptDataSubId = " + mOpptDataSubId);
+ log("mAutoSelectedDataSubId = " + mAutoSelectedDataSubId);
for (int i = 0; i < mActiveModemCount; i++) {
log(" phone[" + i + "] using sub[" + mPhoneSubscriptions[i] + "]");
}
@@ -1291,13 +1269,8 @@
}
}
- // Merge phoneIdForRequest(NetworkRequest netRequest) after Phone.isUsingNewDataStack() is
- // cleaned up.
private int phoneIdForRequest(TelephonyNetworkRequest networkRequest) {
- return phoneIdForRequest(networkRequest.getNativeNetworkRequest());
- }
-
- private int phoneIdForRequest(NetworkRequest netRequest) {
+ NetworkRequest netRequest = networkRequest.getNativeNetworkRequest();
int subId = getSubIdFromNetworkSpecifier(netRequest.getNetworkSpecifier());
if (subId == DEFAULT_SUBSCRIPTION_ID) return mPreferredDataPhoneId;
@@ -1342,8 +1315,8 @@
}
private int getSubIdForDefaultNetworkRequests() {
- if (mSubscriptionController.isActiveSubId(mOpptDataSubId)) {
- return mOpptDataSubId;
+ if (mSubscriptionController.isActiveSubId(mAutoSelectedDataSubId)) {
+ return mAutoSelectedDataSubId;
} else {
return mPrimaryDataSubId;
}
@@ -1355,13 +1328,8 @@
Phone voicePhone = findPhoneById(mPhoneIdInVoiceCall);
boolean isDataEnabled = false;
if (voicePhone != null) {
- if (voicePhone.isUsingNewDataStack()) {
- isDataEnabled = voicePhone.getDataSettingsManager()
- .isDataEnabled(ApnSetting.TYPE_DEFAULT);
- } else {
- isDataEnabled = voicePhone.getDataEnabledSettings()
- .isDataEnabled(ApnSetting.TYPE_DEFAULT);
- }
+ isDataEnabled = voicePhone.getDataSettingsManager()
+ .isDataEnabled(ApnSetting.TYPE_DEFAULT);
}
if (mEmergencyOverride != null && findPhoneById(mEmergencyOverride.mPhoneId) != null) {
@@ -1488,45 +1456,65 @@
*/
private void setOpportunisticDataSubscription(int subId, boolean needValidation,
ISetOpportunisticDataCallback callback) {
- if (!mSubscriptionController.isActiveSubId(subId)
- && subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
- log("Can't switch data to inactive subId " + subId);
+ validate(subId, needValidation,
+ DataSwitch.Reason.DATA_SWITCH_REASON_CBRS, callback);
+ }
+
+ /**
+ * Try setup a new internet connection on the subId that's pending validation. If the validation
+ * succeeds, this subId will be evaluated for being the preferred data subId; If fails, nothing
+ * happens.
+ * Callback will be updated with the validation result.
+ *
+ * @param subId Sub Id that's pending switch, awaiting validation.
+ * @param needValidation {@code false} if switch to the subId even if validation fails.
+ * @param switchReason The switch reason for this validation
+ * @param callback Optional - specific for external opportunistic sub validation request.
+ */
+ private void validate(int subId, boolean needValidation, int switchReason,
+ @Nullable ISetOpportunisticDataCallback callback) {
+ int subIdToValidate = (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)
+ ? mPrimaryDataSubId : subId;
+ if (!mSubscriptionController.isActiveSubId(subIdToValidate)) {
+ log("Can't switch data to inactive subId " + subIdToValidate);
+ if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
+ // the default data sub is not selected yet, store the intent of switching to
+ // default subId once it becomes available.
+ mAutoSelectedDataSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
+ }
sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION);
return;
}
- // Remove EVENT_NETWORK_VALIDATION_DONE. Don't handle validation result of previously subId
- // if queued.
- removeMessages(EVENT_NETWORK_VALIDATION_DONE);
- removeMessages(EVENT_NETWORK_AVAILABLE);
-
- int subIdToValidate = (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)
- ? mPrimaryDataSubId : subId;
-
- mPendingSwitchSubId = INVALID_SUBSCRIPTION_ID;
-
if (mValidator.isValidating()) {
mValidator.stopValidation();
sendSetOpptCallbackHelper(mSetOpptSubCallback, SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED);
mSetOpptSubCallback = null;
}
- if (subId == mOpptDataSubId) {
+ // Remove EVENT_NETWORK_VALIDATION_DONE. Don't handle validation result of previous subId
+ // if queued.
+ removeMessages(EVENT_NETWORK_VALIDATION_DONE);
+ removeMessages(EVENT_NETWORK_AVAILABLE);
+
+ mPendingSwitchSubId = INVALID_SUBSCRIPTION_ID;
+
+ if (subIdToValidate == mPreferredDataSubId.get()) {
sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_SUCCESS);
return;
}
- logDataSwitchEvent(subId == DEFAULT_SUBSCRIPTION_ID ? mPrimaryDataSubId : subId,
+ mLastAutoSelectedSwitchReason = switchReason;
+ logDataSwitchEvent(subIdToValidate,
TelephonyEvent.EventState.EVENT_STATE_START,
- DataSwitch.Reason.DATA_SWITCH_REASON_CBRS);
- registerDefaultNetworkChangeCallback(
- subId == DEFAULT_SUBSCRIPTION_ID ? mPrimaryDataSubId : subId,
- DataSwitch.Reason.DATA_SWITCH_REASON_CBRS);
+ switchReason);
+ registerDefaultNetworkChangeCallback(subIdToValidate,
+ switchReason);
// If validation feature is not supported, set it directly. Otherwise,
// start validation on the subscription first.
if (!mValidator.isValidationFeatureSupported()) {
- setOpportunisticSubscriptionInternal(subId);
+ setAutoSelectedDataSubIdInternal(subIdToValidate);
sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_SUCCESS);
return;
}
@@ -1568,12 +1556,15 @@
}
/**
- * Set opportunistic data subscription.
+ * Evaluate whether the specified sub Id can be set to be the preferred data sub Id.
+ *
+ * @param subId The subId that we tried to validate: could possibly be unvalidated if validation
+ * feature is not supported.
*/
- private void setOpportunisticSubscriptionInternal(int subId) {
- if (mOpptDataSubId != subId) {
- mOpptDataSubId = subId;
- onEvaluate(REQUESTS_UNCHANGED, "oppt data subId changed");
+ private void setAutoSelectedDataSubIdInternal(int subId) {
+ if (mAutoSelectedDataSubId != subId) {
+ mAutoSelectedDataSubId = subId;
+ onEvaluate(REQUESTS_UNCHANGED, switchReasonToString(mLastAutoSelectedSwitchReason));
}
}
@@ -1586,11 +1577,10 @@
} else if (!confirm) {
resultForCallBack = SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED;
} else {
- if (mSubscriptionController.isOpportunistic(subId)) {
- setOpportunisticSubscriptionInternal(subId);
+ if (subId == mPrimaryDataSubId) {
+ setAutoSelectedDataSubIdInternal(DEFAULT_SUBSCRIPTION_ID);
} else {
- // Switching data back to primary subscription.
- setOpportunisticSubscriptionInternal(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
+ setAutoSelectedDataSubIdInternal(subId);
}
resultForCallBack = SET_OPPORTUNISTIC_SUB_SUCCESS;
}
@@ -1660,10 +1650,6 @@
? HAL_COMMAND_PREFERRED_DATA : HAL_COMMAND_ALLOW_DATA;
}
- public int getOpportunisticDataSubscriptionId() {
- return mOpptDataSubId;
- }
-
public int getPreferredDataPhoneId() {
return mPreferredDataPhoneId;
}
@@ -1745,6 +1731,13 @@
return mPreferredDataSubId.get();
}
+ /**
+ * @return The auto selected data subscription id.
+ */
+ public int getAutoSelectedDataSubId() {
+ return mAutoSelectedDataSubId;
+ }
+
// TODO (b/148396668): add an internal callback method to monitor phone capability change,
// and hook this call to that callback.
private void onPhoneCapabilityChanged(PhoneCapability capability) {
@@ -1769,13 +1762,15 @@
pw.println("DefaultDataPhoneId=" + mSubscriptionController.getPhoneId(
mSubscriptionController.getDefaultDataSubId()));
pw.println("mPrimaryDataSubId=" + mPrimaryDataSubId);
- pw.println("mOpptDataSubId=" + mOpptDataSubId);
+ pw.println("mAutoSelectedDataSubId=" + mAutoSelectedDataSubId);
pw.println("mIsRegisteredForImsRadioTechChange=" + mIsRegisteredForImsRadioTechChange);
pw.println("mPendingSwitchNeedValidation=" + mPendingSwitchNeedValidation);
pw.println("mMaxDataAttachModemCount=" + mMaxDataAttachModemCount);
pw.println("mActiveModemCount=" + mActiveModemCount);
pw.println("mPhoneIdInVoiceCall=" + mPhoneIdInVoiceCall);
pw.println("mCurrentDdsSwitchFailure=" + mCurrentDdsSwitchFailure);
+ pw.println("mAutoDataSwitchAvailabilityStabilityTimeThreshold="
+ + mAutoDataSwitchAvailabilityStabilityTimeThreshold);
pw.println("Local logs:");
pw.increaseIndent();
mLocalLog.dump(fd, pw, args);
@@ -1832,25 +1827,11 @@
if (ddsPhoneId != INVALID_PHONE_INDEX && ddsPhoneId == phoneId) {
return true;
} else {
- if (PhoneFactory.getDefaultPhone().isUsingNewDataStack()) {
- if (mNetworkRequestList.isEmpty()) return false;
- for (TelephonyNetworkRequest networkRequest : mNetworkRequestList) {
- phoneIdForRequest = phoneIdForRequest(networkRequest);
- if (phoneIdForRequest == phoneId) {
- return true;
- }
- }
- } else {
- if (mPrioritizedDcRequests.size() == 0) {
- return false;
- }
- for (DcRequest dcRequest : mPrioritizedDcRequests) {
- if (dcRequest != null) {
- phoneIdForRequest = phoneIdForRequest(dcRequest.networkRequest);
- if (phoneIdForRequest == phoneId) {
- return true;
- }
- }
+ if (mNetworkRequestList.isEmpty()) return false;
+ for (TelephonyNetworkRequest networkRequest : mNetworkRequestList) {
+ phoneIdForRequest = phoneIdForRequest(networkRequest);
+ if (phoneIdForRequest == phoneId) {
+ return true;
}
}
}
diff --git a/src/java/com/android/internal/telephony/data/QosCallbackTracker.java b/src/java/com/android/internal/telephony/data/QosCallbackTracker.java
index b7cecbd..ac04627 100644
--- a/src/java/com/android/internal/telephony/data/QosCallbackTracker.java
+++ b/src/java/com/android/internal/telephony/data/QosCallbackTracker.java
@@ -37,6 +37,7 @@
import java.net.InetAddress;
import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -53,8 +54,7 @@
private static final int DEDICATED_BEARER_EVENT_STATE_DELETED = 3;
private final @NonNull String mLogTag;
- // TODO: Change this to TelephonyNetworkAgent
- private final @NonNull NotifyQosSessionInterface mNetworkAgent;
+ private final @NonNull TelephonyNetworkAgent mNetworkAgent;
private final @NonNull Map<Integer, QosBearerSession> mQosBearerSessions;
private final @NonNull RcsStats mRcsStats;
@@ -80,12 +80,20 @@
/**
* Filter using the remote address.
*
- * @param address The local address.
+ * @param address The remote address.
* @param startPort Starting port.
* @param endPort Ending port.
* @return {@code true} if matches, {@code false} otherwise.
*/
boolean matchesRemoteAddress(InetAddress address, int startPort, int endPort);
+
+ /**
+ * Filter using the protocol
+ *
+ * @param protocol ID
+ * @return {@code true} if matches, {@code false} otherwise.
+ */
+ boolean matchesProtocol(int protocol);
}
/**
@@ -94,8 +102,7 @@
* @param networkAgent The network agent to send events to.
* @param phone The phone instance.
*/
- public QosCallbackTracker(@NonNull NotifyQosSessionInterface networkAgent,
- @NonNull Phone phone) {
+ public QosCallbackTracker(@NonNull TelephonyNetworkAgent networkAgent, @NonNull Phone phone) {
mQosBearerSessions = new HashMap<>();
mCallbacksToFilter = new HashMap<>();
mNetworkAgent = networkAgent;
@@ -103,40 +110,41 @@
mRcsStats = RcsStats.getInstance();
mLogTag = "QOSCT" + "-" + ((NetworkAgent) mNetworkAgent).getNetwork().getNetId();
- if (phone.isUsingNewDataStack()) {
- //TODO: Replace the NetworkAgent in the constructor with TelephonyNetworkAgent
- // after mPhone.isUsingNewDataStack() check is removed.
- ((TelephonyNetworkAgent) networkAgent).registerCallback(
- new TelephonyNetworkAgent.TelephonyNetworkAgentCallback(this::post) {
- @Override
- public void onQosCallbackRegistered(int qosCallbackId,
- @NonNull QosFilter filter) {
- addFilter(qosCallbackId,
- new QosCallbackTracker.IFilter() {
- @Override
- public boolean matchesLocalAddress(
- @NonNull InetAddress address, int startPort,
- int endPort) {
- return filter.matchesLocalAddress(address, startPort,
- endPort);
- }
+ networkAgent.registerCallback(
+ new TelephonyNetworkAgent.TelephonyNetworkAgentCallback(this::post) {
+ @Override
+ public void onQosCallbackRegistered(int qosCallbackId,
+ @NonNull QosFilter filter) {
+ addFilter(qosCallbackId,
+ new QosCallbackTracker.IFilter() {
+ @Override
+ public boolean matchesLocalAddress(
+ @NonNull InetAddress address, int startPort,
+ int endPort) {
+ return filter.matchesLocalAddress(address, startPort,
+ endPort);
+ }
- @Override
- public boolean matchesRemoteAddress(
- @NonNull InetAddress address, int startPort,
- int endPort) {
- return filter.matchesRemoteAddress(address, startPort,
- endPort);
- }
- });
- }
+ @Override
+ public boolean matchesRemoteAddress(
+ @NonNull InetAddress address, int startPort,
+ int endPort) {
+ return filter.matchesRemoteAddress(address, startPort,
+ endPort);
+ }
- @Override
- public void onQosCallbackUnregistered(int qosCallbackId) {
+ @Override
+ public boolean matchesProtocol(int protocol) {
+ return filter.matchesProtocol(protocol);
+ }
+ });
+ }
- }
- });
- }
+ @Override
+ public void onQosCallbackUnregistered(int qosCallbackId) {
+
+ }
+ });
}
/**
@@ -280,41 +288,76 @@
private boolean matchesByLocalAddress(final @NonNull QosBearerFilter sessionFilter,
final @NonNull IFilter filter) {
- if (sessionFilter.getLocalPortRange() == null) return false;
- for (final LinkAddress qosAddress : sessionFilter.getLocalAddresses()) {
- return filter.matchesLocalAddress(qosAddress.getAddress(),
- sessionFilter.getLocalPortRange().getStart(),
- sessionFilter.getLocalPortRange().getEnd());
+ int portStart;
+ int portEnd;
+ if (sessionFilter.getLocalPortRange() == null) {
+ portStart = QosBearerFilter.QOS_MIN_PORT;
+ portEnd = QosBearerFilter.QOS_MAX_PORT;
+ } else if (sessionFilter.getLocalPortRange().isValid()) {
+ portStart = sessionFilter.getLocalPortRange().getStart();
+ portEnd = sessionFilter.getLocalPortRange().getEnd();
+ } else {
+ return false;
+ }
+ if (sessionFilter.getLocalAddresses().isEmpty()) {
+ InetAddress anyAddress;
+ try {
+ anyAddress = InetAddress.getByAddress(new byte[] {0, 0, 0, 0});
+ } catch (UnknownHostException e) {
+ return false;
+ }
+ return filter.matchesLocalAddress(anyAddress, portStart, portEnd);
+ } else {
+ for (final LinkAddress qosAddress : sessionFilter.getLocalAddresses()) {
+ return filter.matchesLocalAddress(qosAddress.getAddress(), portStart, portEnd);
+ }
}
return false;
}
private boolean matchesByRemoteAddress(@NonNull QosBearerFilter sessionFilter,
final @NonNull IFilter filter) {
- if (sessionFilter.getRemotePortRange() == null) return false;
- for (final LinkAddress qosAddress : sessionFilter.getRemoteAddresses()) {
- return filter.matchesRemoteAddress(qosAddress.getAddress(),
- sessionFilter.getRemotePortRange().getStart(),
- sessionFilter.getRemotePortRange().getEnd());
+ int portStart;
+ int portEnd;
+ boolean result = false;
+ if (sessionFilter.getRemotePortRange() == null) {
+ portStart = QosBearerFilter.QOS_MIN_PORT;
+ portEnd = QosBearerFilter.QOS_MAX_PORT;
+ } else if (sessionFilter.getRemotePortRange().isValid()) {
+ portStart = sessionFilter.getRemotePortRange().getStart();
+ portEnd = sessionFilter.getRemotePortRange().getEnd();
+ } else {
+ return false;
}
- return false;
- }
-
- private boolean matchesByRemoteAndLocalAddress(@NonNull QosBearerFilter sessionFilter,
- final @NonNull IFilter filter) {
- if (sessionFilter.getLocalPortRange() == null
- || sessionFilter.getRemotePortRange() == null) return false;
- for (final LinkAddress remoteAddress : sessionFilter.getRemoteAddresses()) {
- for (final LinkAddress localAddress : sessionFilter.getLocalAddresses()) {
- return filter.matchesRemoteAddress(remoteAddress.getAddress(),
- sessionFilter.getRemotePortRange().getStart(),
- sessionFilter.getRemotePortRange().getEnd())
- && filter.matchesLocalAddress(localAddress.getAddress(),
- sessionFilter.getLocalPortRange().getStart(),
- sessionFilter.getLocalPortRange().getEnd());
+ if (sessionFilter.getRemoteAddresses().isEmpty()) {
+ InetAddress anyAddress;
+ try {
+ anyAddress = InetAddress.getByAddress(new byte[] {0, 0, 0, 0});
+ } catch (UnknownHostException e) {
+ return false;
+ }
+ result = filter.matchesRemoteAddress(anyAddress, portStart, portEnd);
+ } else {
+ for (final LinkAddress qosAddress : sessionFilter.getRemoteAddresses()) {
+ result = filter.matchesRemoteAddress(qosAddress.getAddress(), portStart, portEnd);
}
}
- return false;
+ return result;
+ }
+
+ private boolean matchesByProtocol(@NonNull QosBearerFilter sessionFilter,
+ final @NonNull IFilter filter, boolean hasMatchedFilter) {
+ boolean result = false;
+ int protocol = sessionFilter.getProtocol();
+ if (protocol == QosBearerFilter.QOS_PROTOCOL_TCP
+ || protocol == QosBearerFilter.QOS_PROTOCOL_UDP) {
+ result = filter.matchesProtocol(protocol);
+ } else {
+ // FWK currently doesn't support filtering based on protocol ID ESP & AH. We will follow
+ // match results of other filters.
+ result = hasMatchedFilter;
+ }
+ return result;
}
private QosBearerFilter getFilterByPrecedence(
@@ -329,28 +372,36 @@
QosBearerFilter qosFilter = null;
for (final QosBearerFilter sessionFilter : qosBearerSession.getQosBearerFilterList()) {
+ boolean unMatched = false;
+ boolean hasMatchedFilter = false;
if (!sessionFilter.getLocalAddresses().isEmpty()
- && !sessionFilter.getRemoteAddresses().isEmpty()
- && sessionFilter.getLocalPortRange() != null
- && sessionFilter.getLocalPortRange().isValid()
- && sessionFilter.getRemotePortRange() != null
- && sessionFilter.getRemotePortRange().isValid()) {
- if (matchesByRemoteAndLocalAddress(sessionFilter, filter)) {
- qosFilter = getFilterByPrecedence(qosFilter, sessionFilter);
+ || sessionFilter.getLocalPortRange() != null) {
+ if (!matchesByLocalAddress(sessionFilter, filter)) {
+ unMatched = true;
+ } else {
+ hasMatchedFilter = true;
}
- } else if (!sessionFilter.getRemoteAddresses().isEmpty()
- && sessionFilter.getRemotePortRange() != null
- && sessionFilter.getRemotePortRange().isValid()) {
- if (matchesByRemoteAddress(sessionFilter, filter)) {
- qosFilter = getFilterByPrecedence(qosFilter, sessionFilter);
+ }
+ if (!sessionFilter.getRemoteAddresses().isEmpty()
+ || sessionFilter.getRemotePortRange() != null) {
+ if (!matchesByRemoteAddress(sessionFilter, filter)) {
+ unMatched = true;
+ } else {
+ hasMatchedFilter = true;
}
- } else if (!sessionFilter.getLocalAddresses().isEmpty()
- && sessionFilter.getLocalPortRange() != null
- && sessionFilter.getLocalPortRange().isValid()) {
- if (matchesByLocalAddress(sessionFilter, filter)) {
- qosFilter = getFilterByPrecedence(qosFilter, sessionFilter);
+ }
+
+ if (sessionFilter.getProtocol() != QosBearerFilter.QOS_PROTOCOL_UNSPECIFIED) {
+ if (!matchesByProtocol(sessionFilter, filter, hasMatchedFilter)) {
+ unMatched = true;
+ } else {
+ hasMatchedFilter = true;
}
}
+
+ if (!unMatched && hasMatchedFilter) {
+ qosFilter = getFilterByPrecedence(qosFilter, sessionFilter);
+ }
}
return qosFilter;
}
@@ -375,7 +426,7 @@
qos.getDownlinkBandwidth().getGuaranteedBitrateKbps(),
qos.getUplinkBandwidth().getGuaranteedBitrateKbps(),
remoteAddresses);
- mNetworkAgent.notifyQosSessionAvailable(
+ mNetworkAgent.sendQosSessionAvailable(
callbackId, session.getQosBearerSessionId(), epsBearerAttr);
} else {
NrQos qos = (NrQos) session.getQos();
@@ -386,7 +437,7 @@
qos.getDownlinkBandwidth().getGuaranteedBitrateKbps(),
qos.getUplinkBandwidth().getGuaranteedBitrateKbps(),
qos.getAveragingWindow(), remoteAddresses);
- mNetworkAgent.notifyQosSessionAvailable(
+ mNetworkAgent.sendQosSessionAvailable(
callbackId, session.getQosBearerSessionId(), nrQosAttr);
}
@@ -397,7 +448,7 @@
}
private void sendSessionLost(int callbackId, @NonNull QosBearerSession session) {
- mNetworkAgent.notifyQosSessionLost(callbackId, session.getQosBearerSessionId(),
+ mNetworkAgent.sendQosSessionLost(callbackId, session.getQosBearerSessionId(),
session.getQos() instanceof EpsQos
? QosSession.TYPE_EPS_BEARER : QosSession.TYPE_NR_BEARER);
log("sendSessionLost, callbackId=" + callbackId);
diff --git a/src/java/com/android/internal/telephony/data/TelephonyNetworkAgent.java b/src/java/com/android/internal/telephony/data/TelephonyNetworkAgent.java
index b74396b..78c555c 100644
--- a/src/java/com/android/internal/telephony/data/TelephonyNetworkAgent.java
+++ b/src/java/com/android/internal/telephony/data/TelephonyNetworkAgent.java
@@ -26,7 +26,6 @@
import android.net.NetworkProvider;
import android.net.NetworkScore;
import android.net.QosFilter;
-import android.net.QosSessionAttributes;
import android.net.Uri;
import android.os.Looper;
import android.util.ArraySet;
@@ -47,9 +46,8 @@
* for telephony to propagate network related information to the connectivity service. It always
* has an associated parent {@link DataNetwork}.
*/
-public class TelephonyNetworkAgent extends NetworkAgent implements NotifyQosSessionInterface {
+public class TelephonyNetworkAgent extends NetworkAgent {
private final String mLogTag;
- private final Phone mPhone;
private final LocalLog mLocalLog = new LocalLog(128);
/** The parent data network. */
@@ -166,7 +164,6 @@
mDataNetwork = dataNetwork;
mNetworkAgentConfig = config;
mTelephonyNetworkAgentCallbacks.add(callback);
- mPhone = phone;
mId = getNetwork().getNetId();
mLogTag = "TNA-" + mId;
@@ -298,37 +295,6 @@
}
/**
- * Sends the attributes of Qos Session back to the Application. This method is create for
- * Mockito to mock since
- * {@link NetworkAgent#sendQosSessionAvailable(int, int, QosSessionAttributes)} is
- * {@code final} that can't be mocked.
- *
- * @param qosCallbackId the callback id that the session belongs to.
- * @param sessionId the unique session id across all Qos Sessions.
- * @param attributes the attributes of the Qos Session.
- */
- @Override
- public void notifyQosSessionAvailable(final int qosCallbackId, final int sessionId,
- @NonNull final QosSessionAttributes attributes) {
- super.sendQosSessionAvailable(qosCallbackId, sessionId, attributes);
- }
-
- /**
- * Sends event that the Qos Session was lost. This method is create for Mockito to mock
- * since {@link NetworkAgent#sendQosSessionLost(int, int, int)} is {@code final} that can't be
- * mocked..
- *
- * @param qosCallbackId the callback id that the session belongs to.
- * @param sessionId the unique session id across all Qos Sessions.
- * @param qosSessionType the session type {@code QosSession#QosSessionType}.
- */
- @Override
- public void notifyQosSessionLost(final int qosCallbackId,
- final int sessionId, final int qosSessionType) {
- super.sendQosSessionLost(qosCallbackId, sessionId, qosSessionType);
- }
-
- /**
* Abandon the network agent. This is used for telephony to re-create the network agent when
* immutable capabilities got changed, where telephony calls {@link NetworkAgent#unregister()}
* and then create another network agent with new capabilities. Abandon this network agent
diff --git a/src/java/com/android/internal/telephony/data/TelephonyNetworkFactory.java b/src/java/com/android/internal/telephony/data/TelephonyNetworkFactory.java
index 85f0ae1..e64dd9b 100644
--- a/src/java/com/android/internal/telephony/data/TelephonyNetworkFactory.java
+++ b/src/java/com/android/internal/telephony/data/TelephonyNetworkFactory.java
@@ -20,27 +20,16 @@
import android.net.NetworkFactory;
import android.net.NetworkRequest;
import android.net.TelephonyNetworkSpecifier;
-import android.os.AsyncResult;
-import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.telephony.AccessNetworkConstants;
-import android.telephony.Annotation.ApnType;
import android.telephony.SubscriptionManager;
-import android.telephony.data.ApnSetting;
import android.util.LocalLog;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.SubscriptionController;
-import com.android.internal.telephony.dataconnection.ApnContext;
-import com.android.internal.telephony.dataconnection.DataConnection;
-import com.android.internal.telephony.dataconnection.DcTracker;
-import com.android.internal.telephony.dataconnection.DcTracker.ReleaseNetworkType;
-import com.android.internal.telephony.dataconnection.DcTracker.RequestNetworkType;
-import com.android.internal.telephony.dataconnection.TransportManager.HandoverParams;
import com.android.internal.telephony.metrics.NetworkRequestsStats;
import com.android.internal.util.IndentingPrintWriter;
import com.android.telephony.Rlog;
@@ -72,19 +61,15 @@
public static final int EVENT_SUBSCRIPTION_CHANGED = 2;
private static final int EVENT_NETWORK_REQUEST = 3;
private static final int EVENT_NETWORK_RELEASE = 4;
- private static final int EVENT_DATA_HANDOVER_NEEDED = 5;
- private static final int EVENT_DATA_HANDOVER_COMPLETED = 6;
private final PhoneSwitcher mPhoneSwitcher;
private final SubscriptionController mSubscriptionController;
private final LocalLog mLocalLog = new LocalLog(REQUEST_LOG_SIZE);
- // Key: network request. Value: the transport of DcTracker it applies to,
+ // Key: network request. Value: the transport of the network request applies to,
// AccessNetworkConstants.TRANSPORT_TYPE_INVALID if not applied.
private final Map<TelephonyNetworkRequest, Integer> mNetworkRequests = new HashMap<>();
- private final Map<Message, HandoverParams> mPendingHandovers = new HashMap<>();
-
private final Phone mPhone;
private AccessNetworksManager mAccessNetworksManager;
@@ -112,10 +97,6 @@
mPhoneSwitcher.registerForActivePhoneSwitch(mInternalHandler, EVENT_ACTIVE_PHONE_SWITCH,
null);
- if (!phone.isUsingNewDataStack()) {
- mPhone.getTransportManager().registerForHandoverNeededEvent(mInternalHandler,
- EVENT_DATA_HANDOVER_NEEDED);
- }
mSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
SubscriptionManager.from(mPhone.getContext()).addOnSubscriptionsChangedListener(
@@ -201,93 +182,18 @@
onReleaseNetworkFor(msg);
break;
}
- case EVENT_DATA_HANDOVER_NEEDED: {
- AsyncResult ar = (AsyncResult) msg.obj;
- HandoverParams handoverParams = (HandoverParams) ar.result;
- onDataHandoverNeeded(handoverParams.apnType, handoverParams.targetTransport,
- handoverParams);
- break;
- }
- case EVENT_DATA_HANDOVER_COMPLETED: {
- Bundle bundle = msg.getData();
- NetworkRequest nr = bundle.getParcelable(
- DcTracker.DATA_COMPLETE_MSG_EXTRA_NETWORK_REQUEST);
- boolean success = bundle.getBoolean(
- DcTracker.DATA_COMPLETE_MSG_EXTRA_SUCCESS);
- int transport = bundle.getInt(
- DcTracker.DATA_COMPLETE_MSG_EXTRA_TRANSPORT_TYPE);
- boolean fallback = bundle.getBoolean(
- DcTracker.DATA_COMPLETE_MSG_EXTRA_HANDOVER_FAILURE_FALLBACK);
- HandoverParams handoverParams = mPendingHandovers.remove(msg);
- if (handoverParams != null) {
- onDataHandoverSetupCompleted(nr, success, transport, fallback,
- handoverParams);
- } else {
- logl("Handover completed but cannot find handover entry!");
- }
- break;
- }
}
}
}
private int getTransportTypeFromNetworkRequest(TelephonyNetworkRequest networkRequest) {
- if (PhoneFactory.getDefaultPhone().isUsingNewDataStack()) {
- int transport = AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
- int capability = networkRequest.getApnTypeNetworkCapability();
- if (capability >= 0) {
- transport = mAccessNetworksManager
- .getPreferredTransportByNetworkCapability(capability);
- }
- return transport;
- } else {
- int apnType = ApnContext.getApnTypeFromNetworkRequest(
- networkRequest.getNativeNetworkRequest());
- return mAccessNetworksManager.getCurrentTransport(apnType);
+ int transport = AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
+ int capability = networkRequest.getApnTypeNetworkCapability();
+ if (capability >= 0) {
+ transport = mAccessNetworksManager
+ .getPreferredTransportByNetworkCapability(capability);
}
- }
-
- /**
- * Request network
- *
- * @param networkRequest Network request from clients
- * @param requestType The request type
- * @param transport Transport type
- * @param onHandoverCompleteMsg When request type is handover, this message will be sent when
- * handover is completed. For normal request, this should be null.
- */
- private void requestNetworkInternal(TelephonyNetworkRequest networkRequest,
- @RequestNetworkType int requestType, int transport, Message onHandoverCompleteMsg) {
- NetworkRequestsStats.addNetworkRequest(networkRequest.getNativeNetworkRequest(),
- mSubscriptionId);
-
- if (mPhone.isUsingNewDataStack()) {
- mPhone.getDataNetworkController().addNetworkRequest(networkRequest);
- } else {
- if (mPhone.getDcTracker(transport) != null) {
- mPhone.getDcTracker(transport).requestNetwork(
- networkRequest.getNativeNetworkRequest(), requestType,
- onHandoverCompleteMsg);
- }
- }
- }
-
- private void releaseNetworkInternal(TelephonyNetworkRequest networkRequest) {
- mPhone.getDataNetworkController().removeNetworkRequest(networkRequest);
- }
-
- // TODO: Clean this up after old data stack removed.
- private void releaseNetworkInternal(TelephonyNetworkRequest networkRequest,
- @ReleaseNetworkType int releaseType,
- int transport) {
- if (mPhone.isUsingNewDataStack()) {
- mPhone.getDataNetworkController().removeNetworkRequest(networkRequest);
- } else {
- if (mPhone.getDcTracker(transport) != null) {
- mPhone.getDcTracker(transport).releaseNetwork(
- networkRequest.getNativeNetworkRequest(), releaseType);
- }
- }
+ return transport;
}
private static int getAction(boolean wasActive, boolean isActive) {
@@ -317,15 +223,11 @@
? "Requesting" : "Releasing") + " network request " + networkRequest);
int transportType = getTransportTypeFromNetworkRequest(networkRequest);
if (action == ACTION_REQUEST) {
- requestNetworkInternal(networkRequest, DcTracker.REQUEST_TYPE_NORMAL,
- getTransportTypeFromNetworkRequest(networkRequest), null);
+ NetworkRequestsStats.addNetworkRequest(networkRequest.getNativeNetworkRequest(),
+ mSubscriptionId);
+ mPhone.getDataNetworkController().addNetworkRequest(networkRequest);
} else if (action == ACTION_RELEASE) {
- if (mPhone.isUsingNewDataStack()) {
- releaseNetworkInternal(networkRequest);
- } else {
- releaseNetworkInternal(networkRequest, DcTracker.RELEASE_TYPE_DETACH,
- getTransportTypeFromNetworkRequest(networkRequest));
- }
+ mPhone.getDataNetworkController().removeNetworkRequest(networkRequest);
}
mNetworkRequests.put(networkRequest,
@@ -365,8 +267,9 @@
logl("onNeedNetworkFor " + networkRequest + " shouldApply " + shouldApply);
if (shouldApply) {
- requestNetworkInternal(networkRequest, DcTracker.REQUEST_TYPE_NORMAL,
- getTransportTypeFromNetworkRequest(networkRequest), null);
+ NetworkRequestsStats.addNetworkRequest(networkRequest.getNativeNetworkRequest(),
+ mSubscriptionId);
+ mPhone.getDataNetworkController().addNetworkRequest(networkRequest);
}
}
@@ -388,136 +291,10 @@
logl("onReleaseNetworkFor " + networkRequest + " applied " + applied);
if (applied) {
- if (mPhone.isUsingNewDataStack()) {
- releaseNetworkInternal(networkRequest);
- } else {
- // Most of the time, the network request only exists in one of the DcTracker, but in
- // the middle of handover, the network request temporarily exists in both
- // DcTrackers. If connectivity service releases the network request while handover
- // is ongoing, we need to remove network requests from both DcTrackers.
- // Note that this part will be refactored in T, where we won't even have DcTracker
- // at all.
- releaseNetworkInternal(networkRequest, DcTracker.RELEASE_TYPE_NORMAL,
- AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
- releaseNetworkInternal(networkRequest, DcTracker.RELEASE_TYPE_NORMAL,
- AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
- }
+ mPhone.getDataNetworkController().removeNetworkRequest(networkRequest);
}
}
- private void onDataHandoverNeeded(@ApnType int apnType, int targetTransport,
- HandoverParams handoverParams) {
- log("onDataHandoverNeeded: apnType=" + ApnSetting.getApnTypeString(apnType)
- + ", target transport="
- + AccessNetworkConstants.transportTypeToString(targetTransport));
- if (mAccessNetworksManager.getCurrentTransport(apnType) == targetTransport) {
- log("APN type " + ApnSetting.getApnTypeString(apnType) + " is already on "
- + AccessNetworkConstants.transportTypeToString(targetTransport));
- return;
- }
-
- boolean handoverPending = false;
- for (Map.Entry<TelephonyNetworkRequest, Integer> entry : mNetworkRequests.entrySet()) {
- TelephonyNetworkRequest networkRequest = entry.getKey();
- int currentTransport = entry.getValue();
- boolean applied = currentTransport != AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
- if (ApnContext.getApnTypeFromNetworkRequest(
- networkRequest.getNativeNetworkRequest()) == apnType
- && applied
- && currentTransport != targetTransport) {
- DcTracker dcTracker = mPhone.getDcTracker(currentTransport);
- if (dcTracker != null) {
- DataConnection dc = dcTracker.getDataConnectionByApnType(
- ApnSetting.getApnTypeString(apnType));
- if (dc != null && (dc.isActive())) {
- Message onCompleteMsg = mInternalHandler.obtainMessage(
- EVENT_DATA_HANDOVER_COMPLETED);
- onCompleteMsg.getData().putParcelable(
- DcTracker.DATA_COMPLETE_MSG_EXTRA_NETWORK_REQUEST,
- networkRequest.getNativeNetworkRequest());
- mPendingHandovers.put(onCompleteMsg, handoverParams);
- requestNetworkInternal(networkRequest, DcTracker.REQUEST_TYPE_HANDOVER,
- targetTransport, onCompleteMsg);
- log("Requested handover " + ApnSetting.getApnTypeString(apnType)
- + " to "
- + AccessNetworkConstants.transportTypeToString(targetTransport)
- + ". " + networkRequest);
- handoverPending = true;
- } else {
- // Request is there, but no actual data connection. In this case, just move
- // the request to the new transport.
- log("The network request is on transport " + AccessNetworkConstants
- .transportTypeToString(currentTransport) + ", but no live data "
- + "connection. Just move the request to transport "
- + AccessNetworkConstants.transportTypeToString(targetTransport)
- + ", dc=" + dc);
- entry.setValue(targetTransport);
- releaseNetworkInternal(networkRequest, DcTracker.RELEASE_TYPE_NORMAL,
- currentTransport);
- requestNetworkInternal(networkRequest, DcTracker.REQUEST_TYPE_NORMAL,
- targetTransport, null);
- }
- } else {
- log("DcTracker on " + AccessNetworkConstants.transportTypeToString(
- currentTransport) + " is not available.");
- }
- }
- }
-
- if (!handoverPending) {
- log("No handover request pending. Handover process is now completed");
- handoverParams.callback.onCompleted(true, false);
- }
- }
-
- private void onDataHandoverSetupCompleted(NetworkRequest request, boolean success,
- int targetTransport, boolean fallback,
- HandoverParams handoverParams) {
- log("onDataHandoverSetupCompleted: " + request + ", success=" + success
- + ", targetTransport="
- + AccessNetworkConstants.transportTypeToString(targetTransport)
- + ", fallback=" + fallback);
-
- TelephonyNetworkRequest networkRequest = new TelephonyNetworkRequest(request, mPhone);
- // At this point, handover setup has been completed on the target transport.
- // If it succeeded, or it failed without falling back to the original transport,
- // we should release the request from the original transport.
- if (!fallback) {
- int originTransport = DataUtils.getSourceTransport(targetTransport);
- int releaseType = success
- ? DcTracker.RELEASE_TYPE_HANDOVER
- // If handover fails, we need to tear down the existing connection, so the
- // new data connection can be re-established on the new transport. If we leave
- // the existing data connection in current transport, then DCT and qualified
- // network service will be out of sync. Specifying release type to detach
- // the transport is moved to the other transport, but network request is still
- // there, connectivity service will not call unwanted to tear down the network.
- // We need explicitly tear down the data connection here so the new data
- // connection can be re-established on the other transport.
- : DcTracker.RELEASE_TYPE_DETACH;
- releaseNetworkInternal(networkRequest, releaseType, originTransport);
-
- // Before updating the network request with the target transport, make sure the request
- // is still there because it's possible that connectivity service has already released
- // the network while handover is ongoing. If connectivity service already released
- // the network request, we need to tear down the just-handovered data connection on the
- // target transport.
- if (mNetworkRequests.containsKey(networkRequest)) {
- // Update it with the target transport.
- mNetworkRequests.put(networkRequest, targetTransport);
- }
- } else {
- // If handover fails and requires to fallback, the context of target transport needs to
- // be released
- if (!success) {
- releaseNetworkInternal(networkRequest,
- DcTracker.RELEASE_TYPE_NORMAL, targetTransport);
- }
- }
-
- handoverParams.callback.onCompleted(success, fallback);
- }
-
protected void log(String s) {
Rlog.d(LOG_TAG, s);
}
diff --git a/src/java/com/android/internal/telephony/data/TelephonyNetworkRequest.java b/src/java/com/android/internal/telephony/data/TelephonyNetworkRequest.java
index b55304a..b334b89 100644
--- a/src/java/com/android/internal/telephony/data/TelephonyNetworkRequest.java
+++ b/src/java/com/android/internal/telephony/data/TelephonyNetworkRequest.java
@@ -157,8 +157,7 @@
/**
* Data config manager for retrieving data config.
*/
- // TODO: Make this @NonNull after old data stack removed.
- private final @Nullable DataConfigManager mDataConfigManager;
+ private final @NonNull DataConfigManager mDataConfigManager;
/**
* The attached data network. Note that the data network could be in any state. {@code null}
@@ -204,12 +203,8 @@
// to satisfy it.
mState = REQUEST_STATE_UNSATISFIED;
mCreatedTimeMillis = SystemClock.elapsedRealtime();
- if (phone.isUsingNewDataStack()) {
- mDataConfigManager = phone.getDataNetworkController().getDataConfigManager();
- updatePriority();
- } else {
- mDataConfigManager = null;
- }
+ mDataConfigManager = phone.getDataNetworkController().getDataConfigManager();
+ updatePriority();
}
/**
@@ -401,8 +396,7 @@
* @return {@code true} if this network request can result in bringing up a metered network.
*/
public boolean isMeteredRequest() {
- // TODO: Remove null check after old data stack removed.
- return mDataConfigManager != null && mDataConfigManager.isAnyMeteredCapability(
+ return mDataConfigManager.isAnyMeteredCapability(
getCapabilities(), mPhone.getServiceState().getDataRoaming());
}
diff --git a/src/java/com/android/internal/telephony/dataconnection/ApnConfigType.java b/src/java/com/android/internal/telephony/dataconnection/ApnConfigType.java
deleted file mode 100644
index 827dbdd..0000000
--- a/src/java/com/android/internal/telephony/dataconnection/ApnConfigType.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import android.telephony.Annotation;
-
-/**
- * Container of network configuration settings relevant for telephony module.
- *
- */
-public class ApnConfigType {
-
- private final int mType;
- private final int mPriority;
-
- public ApnConfigType(@Annotation.ApnType int type, int priority) {
- mType = type;
- mPriority = priority;
- }
-
- /**
- * Returns the apn type of this config type
- * @return Type of apn.
- */
- public int getType() {
- return mType;
- }
-
- /**
- * Returns the priority of this apn config type.
- * @return The priority of this apn.
- */
- public int getPriority() {
- return mPriority;
- }
-}
diff --git a/src/java/com/android/internal/telephony/dataconnection/ApnConfigTypeRepository.java b/src/java/com/android/internal/telephony/dataconnection/ApnConfigTypeRepository.java
deleted file mode 100644
index 156ac92..0000000
--- a/src/java/com/android/internal/telephony/dataconnection/ApnConfigTypeRepository.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.PersistableBundle;
-import android.telephony.Annotation;
-import android.telephony.CarrierConfigManager;
-import android.telephony.Rlog;
-import android.telephony.data.ApnSetting;
-import android.util.ArrayMap;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Hard coded configuration of specific network types that the telephony module needs.
- * Formerly stored in network attributes within the resources file.
- */
-public class ApnConfigTypeRepository {
-
- private static final String TAG = ApnConfigTypeRepository.class.getSimpleName();
-
- private final Map<Integer, ApnConfigType> mConfigTypeMap;
-
- public ApnConfigTypeRepository(PersistableBundle carrierConfig) {
- mConfigTypeMap = new HashMap<>();
- setup(carrierConfig);
- }
-
- /**
- * Gets list of apn config types.
- * @return All apn config types.
- */
- public Collection<ApnConfigType> getTypes() {
- return mConfigTypeMap.values();
- }
-
- /**
- * Gets the apn config type by apn type.
- * @param type The ApnType to search for.
- * @return The config type matching the given apn type.
- */
- @Nullable
- public ApnConfigType getByType(@Annotation.ApnType int type) {
- return mConfigTypeMap.get(type);
- }
-
- private void setup(PersistableBundle carrierConfig) {
- addApns(getCarrierApnTypeMap(CarrierConfigManager.getDefaultConfig()));
- addApns(getCarrierApnTypeMap(carrierConfig));
- }
-
- private void addApns(Map<Integer, Integer> apnTypeMap) {
- add(ApnSetting.TYPE_DEFAULT, apnTypeMap);
- add(ApnSetting.TYPE_MMS, apnTypeMap);
- add(ApnSetting.TYPE_SUPL, apnTypeMap);
- add(ApnSetting.TYPE_DUN, apnTypeMap);
- add(ApnSetting.TYPE_HIPRI, apnTypeMap);
- add(ApnSetting.TYPE_FOTA, apnTypeMap);
- add(ApnSetting.TYPE_IMS, apnTypeMap);
- add(ApnSetting.TYPE_CBS, apnTypeMap);
- add(ApnSetting.TYPE_IA, apnTypeMap);
- add(ApnSetting.TYPE_EMERGENCY, apnTypeMap);
- add(ApnSetting.TYPE_MCX, apnTypeMap);
- add(ApnSetting.TYPE_XCAP, apnTypeMap);
- add(ApnSetting.TYPE_ENTERPRISE, apnTypeMap);
- }
-
- @NonNull
- private Map<Integer, Integer> getCarrierApnTypeMap(PersistableBundle carrierConfig) {
- if (carrierConfig == null) {
- Rlog.w(TAG, "carrier config is null");
- return new ArrayMap<>();
- }
-
- final String[] apnTypeConfig =
- carrierConfig.getStringArray(CarrierConfigManager.KEY_APN_PRIORITY_STRING_ARRAY);
-
- final Map<Integer, Integer> apnTypeMap = new ArrayMap<>();
- if (apnTypeConfig != null) {
- for (final String entry : apnTypeConfig) {
- try {
- final String[] keyValue = entry.split(":");
- if (keyValue.length != 2) {
- Rlog.e(TAG, "Apn type entry must have exactly one ':'");
- } else if (keyValue[0].contains(",")) {
- //getApnTypesBitmaskFromString parses commas to a list, not valid here.
- Rlog.e(TAG, "Invalid apn type name, entry: " + entry);
- } else {
- int apnTypeBitmask = ApnSetting.getApnTypesBitmaskFromString(keyValue[0]);
- if (apnTypeBitmask > 0) {
- apnTypeMap.put(apnTypeBitmask, Integer.parseInt(keyValue[1]));
- } else {
- Rlog.e(TAG, "Invalid apn type name, entry: " + entry);
- }
- }
-
- } catch (Exception ex) {
- Rlog.e(TAG, "Exception on apn type entry: " + entry + "\n", ex);
- }
- }
- }
- return apnTypeMap;
- }
-
- private void add(@Annotation.ApnType int type, Map<Integer, Integer> apnTypeMap) {
- if (apnTypeMap.containsKey(type)) {
- mConfigTypeMap.put(type, new ApnConfigType(type, apnTypeMap.get(type)));
- }
- }
-}
diff --git a/src/java/com/android/internal/telephony/dataconnection/ApnContext.java b/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
deleted file mode 100644
index 3f487cd..0000000
--- a/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
+++ /dev/null
@@ -1,675 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.os.Message;
-import android.telephony.Annotation.ApnType;
-import android.telephony.data.ApnSetting;
-import android.text.TextUtils;
-import android.util.ArraySet;
-import android.util.LocalLog;
-import android.util.SparseIntArray;
-
-import com.android.internal.R;
-import com.android.internal.telephony.DctConstants;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.RetryManager;
-import com.android.internal.telephony.dataconnection.DcTracker.ReleaseNetworkType;
-import com.android.internal.telephony.dataconnection.DcTracker.RequestNetworkType;
-import com.android.internal.util.IndentingPrintWriter;
-import com.android.telephony.Rlog;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Maintain the Apn context
- */
-public class ApnContext {
-
- public final String LOG_TAG;
- private final static String SLOG_TAG = "ApnContext";
-
- protected static final boolean DBG = false;
-
- private final Phone mPhone;
-
- private final String mApnType;
-
- private DctConstants.State mState;
-
- private int mPriority;
-
- private ApnSetting mApnSetting;
-
- private DataConnection mDataConnection;
-
- private String mReason;
-
- /**
- * user/app requested connection on this APN
- */
- AtomicBoolean mDataEnabled;
-
- private final Object mRefCountLock = new Object();
-
- private final DcTracker mDcTracker;
-
-
- /**
- * Remember this as a change in this value to a more permissive state
- * should cause us to retry even permanent failures
- */
- private boolean mConcurrentVoiceAndDataAllowed;
-
- /**
- * used to track a single connection request so disconnects can get ignored if
- * obsolete.
- */
- private final AtomicInteger mConnectionGeneration = new AtomicInteger(0);
-
- /**
- * Retry manager that handles the APN retry and delays.
- */
- private final RetryManager mRetryManager;
-
- /**
- * ApnContext constructor
- * @param phone phone object
- * @param typeId APN type Id
- * @param logTag Tag for logging
- * @param tracker Data call tracker
- * @param priority Priority of APN type
- */
- public ApnContext(Phone phone, int typeId, String logTag, DcTracker tracker, int priority) {
- this(phone, ApnSetting.getApnTypeString(typeId), logTag, tracker, priority);
- }
-
- /**
- * ApnContext constructor
- * @param phone phone object
- * @param apnType APN type (e.g. default, supl, mms, etc...)
- * @param logTag Tag for logging
- * @param tracker Data call tracker
- * @param priority Priority of APN type
- */
- public ApnContext(Phone phone, String apnType, String logTag, DcTracker tracker, int priority) {
- mPhone = phone;
- mApnType = apnType;
- mState = DctConstants.State.IDLE;
- setReason(Phone.REASON_DATA_ENABLED);
- mDataEnabled = new AtomicBoolean(false);
- mPriority = priority;
- LOG_TAG = logTag;
- mDcTracker = tracker;
- mRetryManager = new RetryManager(phone, tracker.getDataThrottler(),
- ApnSetting.getApnTypesBitmaskFromString(apnType));
- }
-
-
-
- /**
- * Get the APN type
- * @return The APN type
- */
- public String getApnType() {
- return mApnType;
- }
-
- /**
- * Gets the APN type bitmask.
- * @return The APN type bitmask
- */
- public int getApnTypeBitmask() {
- return ApnSetting.getApnTypesBitmaskFromString(mApnType);
- }
-
- /**
- * Get the associated data connection
- * @return The data connection
- */
- public synchronized DataConnection getDataConnection() {
- return mDataConnection;
- }
-
- /**
- * This priority is taken into account when concurrent data connections are not allowed. The
- * APN with the HIGHER priority is given preference.
- * @return The priority of the APN type
- */
- public int getPriority() {
- return mPriority;
- }
-
- /**
- * Updates the priority of this context.
- * @param priority The priority of the APN type
- */
- public void setPriority(int priority) {
- mPriority = priority;
- }
-
- /**
- * Keeping for backwards compatibility and in case it's needed in the future
- * @return true
- */
- public boolean isDependencyMet() {
- return true;
- }
-
- /**
- * Set the associated data connection.
- * @param dc data connection
- */
- public synchronized void setDataConnection(DataConnection dc) {
- log("setDataConnectionAc: old=" + mDataConnection + ",new=" + dc + " this=" + this);
- mDataConnection = dc;
- }
-
- /**
- * Release data connection.
- * @param reason The reason of releasing data connection
- */
- public synchronized void releaseDataConnection(String reason) {
- if (mDataConnection != null) {
- mDataConnection.tearDown(this, reason, null);
- mDataConnection = null;
- }
- setState(DctConstants.State.IDLE);
- }
-
- /**
- * Get the current APN setting.
- * @return APN setting
- */
- public synchronized ApnSetting getApnSetting() {
- log("getApnSetting: apnSetting=" + mApnSetting);
- return mApnSetting;
- }
-
- /**
- * Set the APN setting.
- * @param apnSetting APN setting
- */
- public synchronized void setApnSetting(ApnSetting apnSetting) {
- log("setApnSetting: apnSetting=" + apnSetting);
- mApnSetting = apnSetting;
- }
-
- /**
- * Set the list of APN candidates which will be used for data call setup later.
- * @param waitingApns List of APN candidates
- */
- public synchronized void setWaitingApns(ArrayList<ApnSetting> waitingApns) {
- mRetryManager.setWaitingApns(waitingApns);
- }
-
- /**
- * Get the next available APN to try.
- * @return APN setting which will be used for data call setup.{@code null} if there is no
- * APN can be retried.
- */
- public @Nullable ApnSetting getNextApnSetting() {
- return mRetryManager.getNextApnSetting();
- }
-
- /**
- * Get the delay for trying the next APN setting if the current one failed.
- * @param failFastEnabled True if fail fast mode enabled. In this case we'll use a shorter
- * delay.
- * @return The delay in milliseconds
- */
- public long getDelayForNextApn(boolean failFastEnabled) {
- return mRetryManager.getDelayForNextApn(failFastEnabled || isFastRetryReason());
- }
-
- /**
- * Mark the current APN setting permanently failed, which means it will not be retried anymore.
- * @param apn APN setting
- */
- public void markApnPermanentFailed(ApnSetting apn) {
- mRetryManager.markApnPermanentFailed(apn);
- }
-
- /**
- * Get the list of waiting APNs.
- * @return the list of waiting APNs
- */
- public @NonNull ArrayList<ApnSetting> getWaitingApns() {
- return mRetryManager.getWaitingApns();
- }
-
- /**
- * Save the state indicating concurrent voice/data allowed.
- * @param allowed True if concurrent voice/data is allowed
- */
- public synchronized void setConcurrentVoiceAndDataAllowed(boolean allowed) {
- mConcurrentVoiceAndDataAllowed = allowed;
- }
-
- /**
- * Get the state indicating concurrent voice/data allowed.
- * @return True if concurrent voice/data is allowed
- */
- public synchronized boolean isConcurrentVoiceAndDataAllowed() {
- return mConcurrentVoiceAndDataAllowed;
- }
-
- /**
- * Set the current data call state.
- * @param s Current data call state
- */
- public synchronized void setState(DctConstants.State s) {
- log("setState: " + s + ", previous state:" + mState);
-
- if (mState != s) {
- mStateLocalLog.log("State changed from " + mState + " to " + s);
- mState = s;
- }
-
- if (mState == DctConstants.State.FAILED) {
- // when teardown the connection and set to IDLE
- mRetryManager.getWaitingApns().clear();
- }
- }
-
- /**
- * Get the current data call state.
- * @return The current data call state
- */
- public synchronized DctConstants.State getState() {
- return mState;
- }
-
- /**
- * Check whether the data call is disconnected or not.
- * @return True if the data call is disconnected
- */
- public boolean isDisconnected() {
- DctConstants.State currentState = getState();
- return ((currentState == DctConstants.State.IDLE) ||
- currentState == DctConstants.State.FAILED);
- }
-
- /**
- * Set the reason for data call connection.
- * @param reason Reason for data call connection
- */
- public synchronized void setReason(String reason) {
- log("set reason as " + reason + ",current state " + mState);
- mReason = reason;
- }
-
- /**
- * Get the reason for data call connection.
- * @return The reason for data call connection
- */
- public synchronized String getReason() {
- return mReason;
- }
-
- /**
- * Check if ready for data call connection
- * @return True if ready, otherwise false.
- */
- public boolean isReady() {
- return mDataEnabled.get() && isDependencyMet();
- }
-
- /**
- * Check if the data call is in the state which allow connecting.
- * @return True if allowed, otherwise false.
- */
- public boolean isConnectable() {
- return isReady() && ((mState == DctConstants.State.IDLE)
- || (mState == DctConstants.State.RETRYING)
- || (mState == DctConstants.State.FAILED));
- }
-
- /**
- * Check if apn reason is fast retry reason which should apply shorter delay between apn re-try.
- * @return True if it is fast retry reason, otherwise false.
- */
- private boolean isFastRetryReason() {
- return Phone.REASON_NW_TYPE_CHANGED.equals(mReason) ||
- Phone.REASON_APN_CHANGED.equals(mReason);
- }
-
- /** Check if the data call is in connected or connecting state.
- * @return True if the data call is in connected or connecting state
- */
- public boolean isConnectedOrConnecting() {
- return isReady() && ((mState == DctConstants.State.CONNECTED)
- || (mState == DctConstants.State.CONNECTING)
- || (mState == DctConstants.State.RETRYING));
- }
-
- /**
- * Set data call enabled/disabled state.
- * @param enabled True if data call is enabled
- */
- public void setEnabled(boolean enabled) {
- log("set enabled as " + enabled + ", current state is " + mDataEnabled.get());
- mDataEnabled.set(enabled);
- }
-
- /**
- * Check if the data call is enabled or not.
- * @return True if enabled
- */
- public boolean isEnabled() {
- return mDataEnabled.get();
- }
-
- public boolean isProvisioningApn() {
- String provisioningApn = mPhone.getContext().getResources()
- .getString(R.string.mobile_provisioning_apn);
- if (!TextUtils.isEmpty(provisioningApn) &&
- (mApnSetting != null) && (mApnSetting.getApnName() != null)) {
- return (mApnSetting.getApnName().equals(provisioningApn));
- } else {
- return false;
- }
- }
-
- private final ArraySet<NetworkRequest> mNetworkRequests = new ArraySet<>();
- private final LocalLog mStateLocalLog = new LocalLog(32);
-
- private static final LocalLog sLocalLog = new LocalLog(256);
-
- /** Add a line to the ApnContext local log. */
- public static void requestLog(ApnContext apnContext, String str) {
- if (apnContext != null) {
- String logString = "[ApnContext:" + apnContext.getApnType() + "] " + str;
- if (DBG) {
- Rlog.d(SLOG_TAG, logString);
- }
- synchronized (sLocalLog) {
- sLocalLog.log(logString);
- }
- }
- }
-
- /**
- * Request a network
- *
- * @param networkRequest Network request from clients
- * @param type The request type
- * @param onHandoverCompleteMsg When request type is handover, this message will be sent when
- * handover is completed. For normal request, this should be null.
- */
- public void requestNetwork(NetworkRequest networkRequest, @RequestNetworkType int type,
- Message onHandoverCompleteMsg) {
- synchronized (mRefCountLock) {
- mNetworkRequests.add(networkRequest);
- requestLog(this, "requestNetwork for " + networkRequest + ", type="
- + DcTracker.requestTypeToString(type));
- mDcTracker.enableApn(ApnSetting.getApnTypesBitmaskFromString(mApnType), type,
- onHandoverCompleteMsg);
- if (mDataConnection != null) {
- // New network request added. Should re-evaluate properties of
- // the data connection. For example, the score may change.
- mDataConnection.reevaluateDataConnectionProperties();
- }
- }
- }
-
- public void releaseNetwork(NetworkRequest networkRequest, @ReleaseNetworkType int type) {
- synchronized (mRefCountLock) {
- if (mNetworkRequests.contains(networkRequest)) {
- mNetworkRequests.remove(networkRequest);
- if (mDataConnection != null) {
- // New network request added. Should re-evaluate properties of
- // the data connection. For example, the score may change.
- mDataConnection.reevaluateDataConnectionProperties();
- }
- requestLog(this, "releaseNetwork left with " + mNetworkRequests.size()
- + " requests.");
- if (mNetworkRequests.size() == 0
- || type == DcTracker.RELEASE_TYPE_DETACH
- || type == DcTracker.RELEASE_TYPE_HANDOVER) {
- mDcTracker.disableApn(ApnSetting.getApnTypesBitmaskFromString(mApnType), type);
- }
- }
- }
- }
-
- /**
- * @param excludeDun True if excluding requests that have DUN capability
- * @return True if the attached network requests contain restricted capability.
- */
- public boolean hasRestrictedRequests(boolean excludeDun) {
- synchronized (mRefCountLock) {
- for (NetworkRequest nr : mNetworkRequests) {
- if (excludeDun &&
- nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
- continue;
- }
- if (!nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)) {
- return true;
- }
- }
- }
- return false;
- }
-
- private final SparseIntArray mRetriesLeftPerErrorCode = new SparseIntArray();
-
- public void resetErrorCodeRetries() {
- requestLog(this, "resetErrorCodeRetries");
-
- String[] config = mPhone.getContext().getResources().getStringArray(
- com.android.internal.R.array.config_cell_retries_per_error_code);
- synchronized (mRetriesLeftPerErrorCode) {
- mRetriesLeftPerErrorCode.clear();
-
- for (String c : config) {
- String errorValue[] = c.split(",");
- if (errorValue != null && errorValue.length == 2) {
- int count = 0;
- int errorCode = 0;
- try {
- errorCode = Integer.parseInt(errorValue[0]);
- count = Integer.parseInt(errorValue[1]);
- } catch (NumberFormatException e) {
- log("Exception parsing config_retries_per_error_code: " + e);
- continue;
- }
- if (count > 0 && errorCode > 0) {
- mRetriesLeftPerErrorCode.put(errorCode, count);
- }
- } else {
- log("Exception parsing config_retries_per_error_code: " + c);
- }
- }
- }
- }
-
- public boolean restartOnError(int errorCode) {
- boolean result = false;
- int retriesLeft = 0;
- synchronized(mRetriesLeftPerErrorCode) {
- retriesLeft = mRetriesLeftPerErrorCode.get(errorCode);
- switch (retriesLeft) {
- case 0: {
- // not set, never restart modem
- break;
- }
- case 1: {
- resetErrorCodeRetries();
- result = true;
- break;
- }
- default: {
- mRetriesLeftPerErrorCode.put(errorCode, retriesLeft - 1);
- result = false;
- }
- }
- }
- requestLog(this, "restartOnError(" + errorCode + ") found " + retriesLeft
- + " and returned " + result);
- return result;
- }
-
- public int incAndGetConnectionGeneration() {
- return mConnectionGeneration.incrementAndGet();
- }
-
- public int getConnectionGeneration() {
- return mConnectionGeneration.get();
- }
-
- long getRetryAfterDisconnectDelay() {
- return mRetryManager.getRetryAfterDisconnectDelay();
- }
-
- /**
- * Get APN type from the network request.
- *
- * @param nr The network request.
- * @return The APN type.
- */
- public static @ApnType int getApnTypeFromNetworkRequest(NetworkRequest nr) {
- // For now, ignore the bandwidth stuff
- if (nr.getTransportTypes().length > 0
- && !nr.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
- return ApnSetting.TYPE_NONE;
- }
-
- // in the near term just do 1-1 matches.
- // TODO - actually try to match the set of capabilities
- int apnType = ApnSetting.TYPE_NONE;
- boolean error = false;
-
- if (nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
- apnType = ApnSetting.TYPE_DEFAULT;
- }
- if (nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
- if (apnType != ApnSetting.TYPE_NONE) error = true;
- apnType = ApnSetting.TYPE_MMS;
- }
- if (nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
- if (apnType != ApnSetting.TYPE_NONE) error = true;
- apnType = ApnSetting.TYPE_SUPL;
- }
- if (nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
- if (apnType != ApnSetting.TYPE_NONE) error = true;
- apnType = ApnSetting.TYPE_DUN;
- }
- if (nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
- if (apnType != ApnSetting.TYPE_NONE) error = true;
- apnType = ApnSetting.TYPE_FOTA;
- }
- if (nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
- if (apnType != ApnSetting.TYPE_NONE) error = true;
- apnType = ApnSetting.TYPE_IMS;
- }
- if (nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
- if (apnType != ApnSetting.TYPE_NONE) error = true;
- apnType = ApnSetting.TYPE_CBS;
- }
- if (nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_IA)) {
- if (apnType != ApnSetting.TYPE_NONE) error = true;
- apnType = ApnSetting.TYPE_IA;
- }
- if (nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)) {
- if (apnType != ApnSetting.TYPE_NONE) error = true;
- apnType = ApnSetting.TYPE_EMERGENCY;
- }
- if (nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_MCX)) {
- if (apnType != ApnSetting.TYPE_NONE) error = true;
- apnType = ApnSetting.TYPE_MCX;
- }
- if (nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_XCAP)) {
- if (apnType != ApnSetting.TYPE_NONE) error = true;
- apnType = ApnSetting.TYPE_XCAP;
- }
- if (nr.hasCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)) {
- if (apnType != ApnSetting.TYPE_NONE) error = true;
- apnType = ApnSetting.TYPE_ENTERPRISE;
- }
- if (error) {
- // TODO: If this error condition is removed, the framework's handling of
- // NET_CAPABILITY_NOT_RESTRICTED will need to be updated so requests for
- // say FOTA and INTERNET are marked as restricted. This is not how
- // NetworkCapabilities.maybeMarkCapabilitiesRestricted currently works.
- Rlog.d(SLOG_TAG, "Multiple apn types specified in request - result is unspecified!");
- }
- if (apnType == ApnSetting.TYPE_NONE) {
- Rlog.d(SLOG_TAG, "Unsupported NetworkRequest in Telephony: nr=" + nr);
- }
- return apnType;
- }
-
- public List<NetworkRequest> getNetworkRequests() {
- synchronized (mRefCountLock) {
- return new ArrayList<NetworkRequest>(mNetworkRequests);
- }
- }
-
- @Override
- public synchronized String toString() {
- // We don't print mDataConnection because its recursive.
- return "{mApnType=" + mApnType + " mState=" + getState() + " mWaitingApns={"
- + mRetryManager.getWaitingApns() + " priority=" + mPriority + "}"
- + " mApnSetting={" + mApnSetting
- + "} mReason=" + mReason + " mDataEnabled=" + mDataEnabled + "}";
- }
-
- private void log(String s) {
- if (DBG) {
- Rlog.d(LOG_TAG, "[ApnContext:" + mApnType + "] " + s);
- }
- }
-
- public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
- final IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " ");
- synchronized (mRefCountLock) {
- pw.println(toString());
- if (mNetworkRequests.size() > 0) {
- pw.println("NetworkRequests:");
- pw.increaseIndent();
- for (NetworkRequest nr : mNetworkRequests) {
- pw.println(nr);
- }
- pw.decreaseIndent();
- }
- pw.println("Historical APN state:");
- pw.increaseIndent();
- mStateLocalLog.dump(fd, pw, args);
- pw.decreaseIndent();
- pw.println(mRetryManager);
- pw.println("--------------------------");
- }
- }
-
- /** Dumps the ApnContext local log. */
- public static void dumpLocalLog(FileDescriptor fd, PrintWriter printWriter, String[] args) {
- printWriter.println("Local log:");
- synchronized (sLocalLog) {
- sLocalLog.dump(fd, printWriter, args);
- }
- }
-}
diff --git a/src/java/com/android/internal/telephony/dataconnection/ApnSettingUtils.java b/src/java/com/android/internal/telephony/dataconnection/ApnSettingUtils.java
deleted file mode 100644
index 3c2a6ef..0000000
--- a/src/java/com/android/internal/telephony/dataconnection/ApnSettingUtils.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import android.content.Context;
-import android.os.PersistableBundle;
-import android.telephony.Annotation.ApnType;
-import android.telephony.CarrierConfigManager;
-import android.telephony.data.ApnSetting;
-
-import com.android.internal.telephony.Phone;
-import com.android.telephony.Rlog;
-
-import java.util.Arrays;
-import java.util.HashSet;
-
-/**
- * This class represents a apn setting for create PDP link
- */
-public class ApnSettingUtils {
-
- static final String LOG_TAG = "ApnSetting";
-
- private static final boolean DBG = false;
-
- /**
- * Check if this APN type is metered.
- *
- * @param apnType the APN type
- * @param phone the phone object
- * @return {@code true} if the APN type is metered, {@code false} otherwise.
- */
- public static boolean isMeteredApnType(@ApnType int apnType, Phone phone) {
- if (phone == null) {
- return true;
- }
-
- boolean isRoaming = phone.getServiceState().getDataRoaming();
- int subId = phone.getSubId();
-
- String carrierConfig;
- // First check if the device is roaming. If yes, use the roaming metered APN list.
- // Otherwise use the normal metered APN list.
- if (isRoaming) {
- carrierConfig = CarrierConfigManager.KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS;
- } else {
- carrierConfig = CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS;
- }
-
- if (DBG) {
- Rlog.d(LOG_TAG, "isMeteredApnType: isRoaming=" + isRoaming);
- }
-
- CarrierConfigManager configManager = (CarrierConfigManager)
- phone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
- if (configManager == null) {
- Rlog.e(LOG_TAG, "Carrier config service is not available");
- return true;
- }
-
- PersistableBundle b = configManager.getConfigForSubId(subId);
- if (b == null) {
- Rlog.e(LOG_TAG, "Can't get the config. subId = " + subId);
- return true;
- }
-
- String[] meteredApnTypes = b.getStringArray(carrierConfig);
- if (meteredApnTypes == null) {
- Rlog.e(LOG_TAG, carrierConfig + " is not available. " + "subId = " + subId);
- return true;
- }
-
- HashSet<String> meteredApnSet = new HashSet<>(Arrays.asList(meteredApnTypes));
- if (DBG) {
- Rlog.d(LOG_TAG, "For subId = " + subId + ", metered APN types are "
- + Arrays.toString(meteredApnSet.toArray()));
- }
-
- if (meteredApnSet.contains(ApnSetting.getApnTypeString(apnType))) {
- if (DBG) Rlog.d(LOG_TAG, ApnSetting.getApnTypeString(apnType) + " is metered.");
- return true;
- } else if (apnType == ApnSetting.TYPE_ALL) {
- // Assuming no configuration error, if at least one APN type is
- // metered, then this APN setting is metered.
- if (meteredApnSet.size() > 0) {
- if (DBG) Rlog.d(LOG_TAG, "APN_TYPE_ALL APN is metered.");
- return true;
- }
- }
-
- if (DBG) Rlog.d(LOG_TAG, ApnSetting.getApnTypeString(apnType) + " is not metered.");
- return false;
- }
-
- /**
- * Check if this APN setting is metered.
- *
- * @param apn APN setting
- * @param phone The phone object
- * @return True if this APN setting is metered, otherwise false.
- */
- public static boolean isMetered(ApnSetting apn, Phone phone) {
- if (phone == null || apn == null) {
- return true;
- }
-
- for (int apnType : apn.getApnTypes()) {
- // If one of the APN type is metered, then this APN setting is metered.
- if (isMeteredApnType(apnType, phone)) {
- return true;
- }
- }
- return false;
- }
-}
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
deleted file mode 100644
index 348908a..0000000
--- a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
+++ /dev/null
@@ -1,4088 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import static android.telephony.data.DataCallResponse.PDU_SESSION_ID_NOT_SET;
-
-import static com.android.internal.telephony.dataconnection.DcTracker.REQUEST_TYPE_HANDOVER;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.UserInfo;
-import android.net.ConnectivityManager;
-import android.net.InetAddresses;
-import android.net.KeepalivePacketData;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.NetworkAgentConfig;
-import android.net.NetworkCapabilities;
-import android.net.NetworkFactory;
-import android.net.NetworkProvider;
-import android.net.NetworkRequest;
-import android.net.ProxyInfo;
-import android.net.RouteInfo;
-import android.net.SocketKeepalive;
-import android.net.TelephonyNetworkSpecifier;
-import android.net.vcn.VcnManager;
-import android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener;
-import android.net.vcn.VcnNetworkPolicyResult;
-import android.os.AsyncResult;
-import android.os.HandlerExecutor;
-import android.os.Message;
-import android.os.PersistableBundle;
-import android.os.Process;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.os.UserManager;
-import android.provider.Telephony;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.AccessNetworkConstants.TransportType;
-import android.telephony.Annotation.ApnType;
-import android.telephony.Annotation.DataFailureCause;
-import android.telephony.Annotation.DataState;
-import android.telephony.Annotation.NetworkType;
-import android.telephony.CarrierConfigManager;
-import android.telephony.DataFailCause;
-import android.telephony.LinkCapacityEstimate;
-import android.telephony.NetworkRegistrationInfo;
-import android.telephony.PreciseDataConnectionState;
-import android.telephony.ServiceState;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.telephony.data.ApnSetting;
-import android.telephony.data.DataCallResponse;
-import android.telephony.data.DataCallResponse.HandoverFailureMode;
-import android.telephony.data.DataProfile;
-import android.telephony.data.DataService;
-import android.telephony.data.DataServiceCallback;
-import android.telephony.data.NetworkSliceInfo;
-import android.telephony.data.Qos;
-import android.telephony.data.QosBearerSession;
-import android.telephony.data.TrafficDescriptor;
-import android.text.TextUtils;
-import android.util.LocalLog;
-import android.util.Pair;
-import android.util.TimeUtils;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.CarrierPrivilegesTracker;
-import com.android.internal.telephony.CarrierSignalAgent;
-import com.android.internal.telephony.DctConstants;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.RIL;
-import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.RetryManager;
-import com.android.internal.telephony.TelephonyStatsLog;
-import com.android.internal.telephony.data.DataConfigManager;
-import com.android.internal.telephony.data.KeepaliveStatus;
-import com.android.internal.telephony.dataconnection.DcTracker.ReleaseNetworkType;
-import com.android.internal.telephony.dataconnection.DcTracker.RequestNetworkType;
-import com.android.internal.telephony.metrics.DataCallSessionStats;
-import com.android.internal.telephony.metrics.TelephonyMetrics;
-import com.android.internal.telephony.nano.TelephonyProto.RilDataCall;
-import com.android.internal.telephony.uicc.IccUtils;
-import com.android.internal.telephony.util.ArrayUtils;
-import com.android.internal.util.AsyncChannel;
-import com.android.internal.util.IndentingPrintWriter;
-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;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.nio.ByteBuffer;
-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;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.function.Consumer;
-
-/**
- * {@hide}
- *
- * DataConnection StateMachine.
- *
- * This a class for representing a single data connection, with instances of this
- * class representing a connection via the cellular network. There may be multiple
- * data connections and all of them are managed by the <code>DataConnectionTracker</code>.
- *
- * NOTE: All DataConnection objects must be running on the same looper, which is the default
- * as the coordinator has members which are used without synchronization.
- */
-public class DataConnection extends StateMachine {
- private static final boolean DBG = true;
- private static final boolean VDBG = true;
-
- private static final String NETWORK_TYPE = "MOBILE";
-
- private static final String RAT_NAME_5G = "nr";
- private static final String RAT_NAME_EVDO = "evdo";
-
- /**
- * OSId for "Android", using UUID version 5 with namespace ISO OSI.
- * Prepended to the OsAppId in TrafficDescriptor to use for URSP matching.
- */
- private static final UUID OS_ID = UUID.fromString("97a498e3-fc92-5c94-8986-0333d06e4e47");
-
- /**
- * The data connection is not being or been handovered. Note this is the state for the source
- * data connection, not destination data connection
- */
- private static final int HANDOVER_STATE_IDLE = 1;
-
- /**
- * The data connection is being handovered. Note this is the state for the source
- * data connection, not destination data connection.
- */
- private static final int HANDOVER_STATE_BEING_TRANSFERRED = 2;
-
- /**
- * The data connection is already handovered. Note this is the state for the source
- * data connection, not destination data connection.
- */
- private static final int HANDOVER_STATE_COMPLETED = 3;
-
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"HANDOVER_STATE_"}, value = {
- HANDOVER_STATE_IDLE,
- HANDOVER_STATE_BEING_TRANSFERRED,
- HANDOVER_STATE_COMPLETED})
- public @interface HandoverState {}
-
- // The data connection providing default Internet connection will have a higher score of 50.
- // Other connections will have a slightly lower score of 45. The intention is other connections
- // will not cause ConnectivityService to tear down default internet connection. For example,
- // to validate Internet connection on non-default data SIM, we'll set up a temporary Internet
- // connection on that data SIM. In this case, score of 45 is assigned so ConnectivityService
- // will not replace the default Internet connection with it.
- private static final int DEFAULT_INTERNET_CONNECTION_SCORE = 50;
- private static final int OTHER_CONNECTION_SCORE = 45;
-
- // The score we report to connectivity service
- private int mScore;
-
- // The subscription id associated with this data connection.
- private int mSubId;
-
- // The data connection controller
- private DcController mDcController;
-
- // The Tester for failing all bringup's
- private DcTesterFailBringUpAll mDcTesterFailBringUpAll;
-
- // Whether or not the data connection should allocate its own pdu session id
- private boolean mDoAllocatePduSessionId;
-
- private static AtomicInteger mInstanceNumber = new AtomicInteger(0);
- private AsyncChannel mAc;
-
- // The DCT that's talking to us, we only support one!
- private DcTracker mDct = null;
-
- private String[] mPcscfAddr;
-
- private final String mTagSuffix;
-
- private final LocalLog mHandoverLocalLog = new LocalLog(64);
-
- private int[] mAdministratorUids = new int[0];
-
- // stats per data call
- private DataCallSessionStats mDataCallSessionStats;
-
- /**
- * Used internally for saving connecting parameters.
- */
- public static class ConnectionParams {
- int mTag;
- ApnContext mApnContext;
- int mProfileId;
- int mRilRat;
- Message mOnCompletedMsg;
- final int mConnectionGeneration;
- @RequestNetworkType
- final int mRequestType;
- final int mSubId;
- final boolean mIsPreferredApn;
-
- ConnectionParams(ApnContext apnContext, int profileId, int rilRadioTechnology,
- Message onCompletedMsg, int connectionGeneration,
- @RequestNetworkType int requestType, int subId,
- boolean isPreferredApn) {
- mApnContext = apnContext;
- mProfileId = profileId;
- mRilRat = rilRadioTechnology;
- mOnCompletedMsg = onCompletedMsg;
- mConnectionGeneration = connectionGeneration;
- mRequestType = requestType;
- mSubId = subId;
- mIsPreferredApn = isPreferredApn;
- }
-
- @Override
- public String toString() {
- return "{mTag=" + mTag + " mApnContext=" + mApnContext
- + " mProfileId=" + mProfileId
- + " mRat=" + mRilRat
- + " mOnCompletedMsg=" + msgToString(mOnCompletedMsg)
- + " mRequestType=" + DcTracker.requestTypeToString(mRequestType)
- + " mSubId=" + mSubId
- + " mIsPreferredApn=" + mIsPreferredApn
- + "}";
- }
- }
-
- /**
- * Used internally for saving disconnecting parameters.
- */
- public static class DisconnectParams {
- int mTag;
- public ApnContext mApnContext;
- String mReason;
- @ReleaseNetworkType
- final int mReleaseType;
- Message mOnCompletedMsg;
-
- DisconnectParams(ApnContext apnContext, String reason, @ReleaseNetworkType int releaseType,
- Message onCompletedMsg) {
- mApnContext = apnContext;
- mReason = reason;
- mReleaseType = releaseType;
- mOnCompletedMsg = onCompletedMsg;
- }
-
- @Override
- public String toString() {
- return "{mTag=" + mTag + " mApnContext=" + mApnContext
- + " mReason=" + mReason
- + " mReleaseType=" + DcTracker.releaseTypeToString(mReleaseType)
- + " mOnCompletedMsg=" + msgToString(mOnCompletedMsg) + "}";
- }
- }
-
- private volatile ApnSetting mApnSetting;
- private ConnectionParams mConnectionParams;
- private DisconnectParams mDisconnectParams;
- @DataFailureCause
- private int mDcFailCause;
-
- @HandoverFailureMode
- private int mHandoverFailureMode;
-
- private Phone mPhone;
- private DataServiceManager mDataServiceManager;
- private VcnManager mVcnManager;
- private final int mTransportType;
- private LinkProperties mLinkProperties = new LinkProperties();
- private int mPduSessionId;
- private long mCreateTime;
- private long mLastFailTime;
- @DataFailureCause
- private int mLastFailCause;
- private static final String NULL_IP = "0.0.0.0";
- private Object mUserData;
- private boolean mCongestedOverride;
- private boolean mUnmeteredOverride;
- private int mRilRat = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
- private int mDataRegState = Integer.MAX_VALUE;
- // Indicating data connection is suspended due to temporary reasons, for example, out of
- // service, concurrency voice/data not supported, etc.. Note this flag is only meaningful when
- // data is in active state. When data is in inactive, connecting, or disconnecting, this flag
- // is unmeaningful.
- private boolean mIsSuspended;
- private int mDownlinkBandwidth = 14;
- private int mUplinkBandwidth = 14;
- private Qos mDefaultQos = null;
- private List<QosBearerSession> mQosBearerSessions = new ArrayList<>();
- private NetworkSliceInfo mSliceInfo;
- private List<TrafficDescriptor> mTrafficDescriptors = new ArrayList<>();
-
- /** The corresponding network agent for this data connection. */
- private DcNetworkAgent mNetworkAgent;
-
- /**
- * The network agent from handover source data connection. This is the potential network agent
- * that will be transferred here after handover completed.
- */
- private DcNetworkAgent mHandoverSourceNetworkAgent;
-
- private int mDisabledApnTypeBitMask = 0;
-
- int mTag;
-
- /** Data connection id assigned by the modem. This is unique across transports */
- public int mCid;
-
- @HandoverState
- private int mHandoverState = HANDOVER_STATE_IDLE;
- private final Map<ApnContext, ConnectionParams> mApnContexts = new ConcurrentHashMap<>();
- PendingIntent mReconnectIntent = null;
-
- /** Class used to track VCN-defined Network policies for this DcNetworkAgent. */
- private final VcnNetworkPolicyChangeListener mVcnPolicyChangeListener =
- new DataConnectionVcnNetworkPolicyChangeListener();
-
- // ***** Event codes for driving the state machine, package visible for Dcc
- static final int BASE = Protocol.BASE_DATA_CONNECTION;
- static final int EVENT_CONNECT = BASE + 0;
- static final int EVENT_SETUP_DATA_CONNECTION_DONE = BASE + 1;
- static final int EVENT_DEACTIVATE_DONE = BASE + 3;
- static final int EVENT_DISCONNECT = BASE + 4;
- static final int EVENT_DISCONNECT_ALL = BASE + 6;
- static final int EVENT_DATA_STATE_CHANGED = BASE + 7;
- static final int EVENT_TEAR_DOWN_NOW = BASE + 8;
- static final int EVENT_LOST_CONNECTION = BASE + 9;
- static final int EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED = BASE + 11;
- static final int EVENT_DATA_CONNECTION_ROAM_ON = BASE + 12;
- static final int EVENT_DATA_CONNECTION_ROAM_OFF = BASE + 13;
- static final int EVENT_BW_REFRESH_RESPONSE = BASE + 14;
- static final int EVENT_DATA_CONNECTION_VOICE_CALL_STARTED = BASE + 15;
- static final int EVENT_DATA_CONNECTION_VOICE_CALL_ENDED = BASE + 16;
- static final int EVENT_DATA_CONNECTION_CONGESTEDNESS_CHANGED = BASE + 17;
- static final int EVENT_KEEPALIVE_STATUS = BASE + 18;
- static final int EVENT_KEEPALIVE_STARTED = BASE + 19;
- static final int EVENT_KEEPALIVE_STOPPED = BASE + 20;
- static final int EVENT_KEEPALIVE_START_REQUEST = BASE + 21;
- static final int EVENT_KEEPALIVE_STOP_REQUEST = BASE + 22;
- static final int EVENT_LINK_CAPACITY_CHANGED = BASE + 23;
- static final int EVENT_RESET = BASE + 24;
- static final int EVENT_REEVALUATE_RESTRICTED_STATE = BASE + 25;
- static final int EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES = BASE + 26;
- static final int EVENT_NR_STATE_CHANGED = BASE + 27;
- static final int EVENT_DATA_CONNECTION_METEREDNESS_CHANGED = BASE + 28;
- static final int EVENT_NR_FREQUENCY_CHANGED = BASE + 29;
- static final int EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED = BASE + 30;
- static final int EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED = BASE + 31;
- static final int EVENT_CSS_INDICATOR_CHANGED = BASE + 32;
- static final int EVENT_UPDATE_SUSPENDED_STATE = BASE + 33;
- static final int EVENT_START_HANDOVER = BASE + 34;
- static final int EVENT_CANCEL_HANDOVER = BASE + 35;
- static final int EVENT_START_HANDOVER_ON_TARGET = BASE + 36;
- static final int EVENT_ALLOCATE_PDU_SESSION_ID = BASE + 37;
- static final int EVENT_RELEASE_PDU_SESSION_ID = BASE + 38;
- static final int EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE = BASE + 39;
- private static final int CMD_TO_STRING_COUNT = EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE - BASE + 1;
-
- private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT];
- static {
- sCmdToString[EVENT_CONNECT - BASE] = "EVENT_CONNECT";
- sCmdToString[EVENT_SETUP_DATA_CONNECTION_DONE - BASE] =
- "EVENT_SETUP_DATA_CONNECTION_DONE";
- sCmdToString[EVENT_DEACTIVATE_DONE - BASE] = "EVENT_DEACTIVATE_DONE";
- sCmdToString[EVENT_DISCONNECT - BASE] = "EVENT_DISCONNECT";
- sCmdToString[EVENT_DISCONNECT_ALL - BASE] = "EVENT_DISCONNECT_ALL";
- sCmdToString[EVENT_DATA_STATE_CHANGED - BASE] = "EVENT_DATA_STATE_CHANGED";
- sCmdToString[EVENT_TEAR_DOWN_NOW - BASE] = "EVENT_TEAR_DOWN_NOW";
- sCmdToString[EVENT_LOST_CONNECTION - BASE] = "EVENT_LOST_CONNECTION";
- sCmdToString[EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED - BASE] =
- "EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED";
- sCmdToString[EVENT_DATA_CONNECTION_ROAM_ON - BASE] = "EVENT_DATA_CONNECTION_ROAM_ON";
- sCmdToString[EVENT_DATA_CONNECTION_ROAM_OFF - BASE] = "EVENT_DATA_CONNECTION_ROAM_OFF";
- sCmdToString[EVENT_BW_REFRESH_RESPONSE - BASE] = "EVENT_BW_REFRESH_RESPONSE";
- sCmdToString[EVENT_DATA_CONNECTION_VOICE_CALL_STARTED - BASE] =
- "EVENT_DATA_CONNECTION_VOICE_CALL_STARTED";
- sCmdToString[EVENT_DATA_CONNECTION_VOICE_CALL_ENDED - BASE] =
- "EVENT_DATA_CONNECTION_VOICE_CALL_ENDED";
- sCmdToString[EVENT_DATA_CONNECTION_CONGESTEDNESS_CHANGED - BASE] =
- "EVENT_DATA_CONNECTION_CONGESTEDNESS_CHANGED";
- sCmdToString[EVENT_KEEPALIVE_STATUS - BASE] = "EVENT_KEEPALIVE_STATUS";
- sCmdToString[EVENT_KEEPALIVE_STARTED - BASE] = "EVENT_KEEPALIVE_STARTED";
- sCmdToString[EVENT_KEEPALIVE_STOPPED - BASE] = "EVENT_KEEPALIVE_STOPPED";
- sCmdToString[EVENT_KEEPALIVE_START_REQUEST - BASE] = "EVENT_KEEPALIVE_START_REQUEST";
- sCmdToString[EVENT_KEEPALIVE_STOP_REQUEST - BASE] = "EVENT_KEEPALIVE_STOP_REQUEST";
- sCmdToString[EVENT_LINK_CAPACITY_CHANGED - BASE] = "EVENT_LINK_CAPACITY_CHANGED";
- sCmdToString[EVENT_RESET - BASE] = "EVENT_RESET";
- sCmdToString[EVENT_REEVALUATE_RESTRICTED_STATE - BASE] =
- "EVENT_REEVALUATE_RESTRICTED_STATE";
- sCmdToString[EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES - BASE] =
- "EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES";
- sCmdToString[EVENT_NR_STATE_CHANGED - BASE] = "EVENT_NR_STATE_CHANGED";
- sCmdToString[EVENT_DATA_CONNECTION_METEREDNESS_CHANGED - BASE] =
- "EVENT_DATA_CONNECTION_METEREDNESS_CHANGED";
- sCmdToString[EVENT_NR_FREQUENCY_CHANGED - BASE] = "EVENT_NR_FREQUENCY_CHANGED";
- sCmdToString[EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED - BASE] =
- "EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED";
- sCmdToString[EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED - BASE] =
- "EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED";
- sCmdToString[EVENT_CSS_INDICATOR_CHANGED - BASE] = "EVENT_CSS_INDICATOR_CHANGED";
- sCmdToString[EVENT_UPDATE_SUSPENDED_STATE - BASE] = "EVENT_UPDATE_SUSPENDED_STATE";
- sCmdToString[EVENT_START_HANDOVER - BASE] = "EVENT_START_HANDOVER";
- sCmdToString[EVENT_CANCEL_HANDOVER - BASE] = "EVENT_CANCEL_HANDOVER";
- sCmdToString[EVENT_START_HANDOVER_ON_TARGET - BASE] = "EVENT_START_HANDOVER_ON_TARGET";
- sCmdToString[EVENT_ALLOCATE_PDU_SESSION_ID - BASE] = "EVENT_ALLOCATE_PDU_SESSION_ID";
- sCmdToString[EVENT_RELEASE_PDU_SESSION_ID - BASE] = "EVENT_RELEASE_PDU_SESSION_ID";
- sCmdToString[EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE - BASE] =
- "EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE";
- }
- // Convert cmd to string or null if unknown
- static String cmdToString(int cmd) {
- String value = null;
- cmd -= BASE;
- if ((cmd >= 0) && (cmd < sCmdToString.length)) {
- value = sCmdToString[cmd];
- }
- if (value == null) {
- value = "0x" + Integer.toHexString(cmd + BASE);
- }
- return value;
- }
-
- /**
- * Create the connection object
- *
- * @param phone the Phone
- * @param id the connection id
- * @return DataConnection that was created.
- */
- public static DataConnection makeDataConnection(Phone phone, int id, DcTracker dct,
- DataServiceManager dataServiceManager,
- DcTesterFailBringUpAll failBringUpAll,
- DcController dcc) {
- String transportType = (dataServiceManager.getTransportType()
- == AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
- ? "C" // Cellular
- : "I"; // IWLAN
- DataConnection dc = new DataConnection(phone, transportType + "-"
- + mInstanceNumber.incrementAndGet(), id, dct, dataServiceManager, failBringUpAll,
- dcc);
- dc.start();
- if (DBG) dc.log("Made " + dc.getName());
- return dc;
- }
-
- void dispose() {
- log("dispose: call quiteNow()");
- quitNow();
- }
-
- /* Getter functions */
-
- LinkProperties getLinkProperties() {
- return new LinkProperties(mLinkProperties);
- }
-
- boolean isDisconnecting() {
- return getCurrentState() == mDisconnectingState
- || getCurrentState() == mDisconnectingErrorCreatingConnection;
- }
-
- @VisibleForTesting
- public boolean isActive() {
- return getCurrentState() == mActiveState;
- }
-
- @VisibleForTesting
- public boolean isInactive() {
- return getCurrentState() == mInactiveState;
- }
-
- boolean isActivating() {
- return getCurrentState() == mActivatingState;
- }
-
- boolean hasBeenTransferred() {
- return mHandoverState == HANDOVER_STATE_COMPLETED;
- }
-
- int getCid() {
- return mCid;
- }
-
- /**
- * @return DataConnection's ApnSetting.
- */
- public ApnSetting getApnSetting() {
- return mApnSetting;
- }
-
- /**
- * Update http proxy of link properties based on current apn setting
- */
- private void updateLinkPropertiesHttpProxy() {
- if (mApnSetting == null
- || TextUtils.isEmpty(mApnSetting.getProxyAddressAsString())) {
- return;
- }
- try {
- int port = mApnSetting.getProxyPort();
- if (port == -1) {
- port = 8080;
- }
- ProxyInfo proxy = ProxyInfo.buildDirectProxy(
- mApnSetting.getProxyAddressAsString(), port);
- mLinkProperties.setHttpProxy(proxy);
- } catch (NumberFormatException e) {
- loge("onDataSetupComplete: NumberFormatException making ProxyProperties ("
- + mApnSetting.getProxyPort() + "): " + e);
- }
- }
-
- public static class UpdateLinkPropertyResult {
- public SetupResult setupResult = SetupResult.SUCCESS;
- public LinkProperties oldLp;
- public LinkProperties newLp;
- public UpdateLinkPropertyResult(LinkProperties curLp) {
- oldLp = curLp;
- newLp = curLp;
- }
- }
-
- /**
- * Class returned by onSetupConnectionCompleted.
- */
- public enum SetupResult {
- SUCCESS,
- ERROR_RADIO_NOT_AVAILABLE,
- ERROR_INVALID_ARG,
- ERROR_STALE,
- ERROR_DATA_SERVICE_SPECIFIC_ERROR,
- ERROR_DUPLICATE_CID,
- ERROR_NO_DEFAULT_CONNECTION;
-
- public int mFailCause;
-
- SetupResult() {
- mFailCause = DataFailCause.getFailCause(0);
- }
-
- @Override
- public String toString() {
- return name() + " SetupResult.mFailCause=" + DataFailCause.toString(mFailCause);
- }
- }
-
- public boolean isIpv4Connected() {
- boolean ret = false;
- Collection <InetAddress> addresses = mLinkProperties.getAddresses();
-
- for (InetAddress addr: addresses) {
- if (addr instanceof java.net.Inet4Address) {
- java.net.Inet4Address i4addr = (java.net.Inet4Address) addr;
- if (!i4addr.isAnyLocalAddress() && !i4addr.isLinkLocalAddress() &&
- !i4addr.isLoopbackAddress() && !i4addr.isMulticastAddress()) {
- ret = true;
- break;
- }
- }
- }
- return ret;
- }
-
- public boolean isIpv6Connected() {
- boolean ret = false;
- Collection <InetAddress> addresses = mLinkProperties.getAddresses();
-
- for (InetAddress addr: addresses) {
- if (addr instanceof java.net.Inet6Address) {
- java.net.Inet6Address i6addr = (java.net.Inet6Address) addr;
- if (!i6addr.isAnyLocalAddress() && !i6addr.isLinkLocalAddress() &&
- !i6addr.isLoopbackAddress() && !i6addr.isMulticastAddress()) {
- ret = true;
- break;
- }
- }
- }
- return ret;
- }
-
- public int getPduSessionId() {
- return mPduSessionId;
- }
-
- public NetworkSliceInfo getSliceInfo() {
- return mSliceInfo;
- }
-
- public List<TrafficDescriptor> getTrafficDescriptors() {
- return mTrafficDescriptors;
- }
-
- /**
- * Update DC fields based on a new DataCallResponse
- * @param response the response to use to update DC fields
- */
- public void updateResponseFields(DataCallResponse response) {
- updateQosParameters(response);
- updateSliceInfo(response);
- updateTrafficDescriptors(response);
- }
-
- public void updateQosParameters(final @Nullable DataCallResponse response) {
- if (response == null) {
- mDefaultQos = null;
- mQosBearerSessions.clear();
- return;
- }
-
- mDefaultQos = response.getDefaultQos();
- mQosBearerSessions = response.getQosBearerSessions();
-
- if (mNetworkAgent != null) {
- syncQosToNetworkAgent();
- }
- }
-
- private void syncQosToNetworkAgent() {
- final DcNetworkAgent networkAgent = mNetworkAgent;
- final List<QosBearerSession> qosBearerSessions = mQosBearerSessions;
- if (qosBearerSessions == null) {
- networkAgent.updateQosBearerSessions(new ArrayList<>());
- return;
- }
- networkAgent.updateQosBearerSessions(qosBearerSessions);
- }
-
- /**
- * Update the latest slice info on this data connection with
- * {@link DataCallResponse#getSliceInfo}.
- */
- public void updateSliceInfo(DataCallResponse response) {
- mSliceInfo = response.getSliceInfo();
- }
-
- /**
- * Update the latest traffic descriptor on this data connection with
- * {@link DataCallResponse#getTrafficDescriptors}.
- */
- public void updateTrafficDescriptors(DataCallResponse response) {
- mTrafficDescriptors = response.getTrafficDescriptors();
- mDcController.updateTrafficDescriptorsForCid(response.getId(),
- response.getTrafficDescriptors());
- }
-
- @VisibleForTesting
- public UpdateLinkPropertyResult updateLinkProperty(DataCallResponse newState) {
- UpdateLinkPropertyResult result = new UpdateLinkPropertyResult(mLinkProperties);
-
- if (newState == null) return result;
-
- result.newLp = new LinkProperties();
-
- // set link properties based on data call response
- result.setupResult = setLinkProperties(newState, result.newLp);
- if (result.setupResult != SetupResult.SUCCESS) {
- if (DBG) log("updateLinkProperty failed : " + result.setupResult);
- return result;
- }
- // copy HTTP proxy as it is not part DataCallResponse.
- result.newLp.setHttpProxy(mLinkProperties.getHttpProxy());
-
- checkSetMtu(mApnSetting, result.newLp);
-
- mLinkProperties = result.newLp;
-
- updateTcpBufferSizes(mRilRat);
-
- if (DBG && (! result.oldLp.equals(result.newLp))) {
- log("updateLinkProperty old LP=" + result.oldLp);
- log("updateLinkProperty new LP=" + result.newLp);
- }
-
- if (result.newLp.equals(result.oldLp) == false &&
- mNetworkAgent != null) {
- mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this);
- }
-
- return result;
- }
-
- /**
- * Sets the pdu session id of the data connection
- * @param pduSessionId pdu session id to set
- */
- @VisibleForTesting
- public void setPduSessionId(int pduSessionId) {
- if (mPduSessionId != pduSessionId) {
- logd("Changing pdu session id from: " + mPduSessionId + " to: " + pduSessionId + ", "
- + "Handover state: " + handoverStateToString(this.mHandoverState));
- mPduSessionId = pduSessionId;
- }
- }
-
- /**
- * Read the MTU value from link properties where it can be set from network. In case
- * not set by the network, set it again using the mtu szie value defined in the APN
- * database for the connected APN
- */
- private void checkSetMtu(ApnSetting apn, LinkProperties lp) {
- if (lp == null) return;
-
- if (apn == null || lp == null) return;
-
- if (lp.getMtu() != PhoneConstants.UNSET_MTU) {
- if (DBG) log("MTU set by call response to: " + lp.getMtu());
- return;
- }
-
- if (apn != null && apn.getMtuV4() != PhoneConstants.UNSET_MTU) {
- lp.setMtu(apn.getMtuV4());
- if (DBG) log("MTU set by APN to: " + apn.getMtuV4());
- return;
- }
-
- int mtu = mPhone.getContext().getResources().getInteger(
- com.android.internal.R.integer.config_mobile_mtu);
- if (mtu != PhoneConstants.UNSET_MTU) {
- lp.setMtu(mtu);
- if (DBG) log("MTU set by config resource to: " + mtu);
- }
- }
-
- //***** Constructor (NOTE: uses dcc.getHandler() as its Handler)
- private DataConnection(Phone phone, String tagSuffix, int id,
- DcTracker dct, DataServiceManager dataServiceManager,
- DcTesterFailBringUpAll failBringUpAll, DcController dcc) {
- super("DC-" + tagSuffix, dcc);
- mTagSuffix = tagSuffix;
- setLogRecSize(300);
- setLogOnlyTransitions(true);
- if (DBG) log("DataConnection created");
-
- mPhone = phone;
- mDct = dct;
- mDataServiceManager = dataServiceManager;
- mVcnManager = mPhone.getContext().getSystemService(VcnManager.class);
- mTransportType = dataServiceManager.getTransportType();
- mDcTesterFailBringUpAll = failBringUpAll;
- mDcController = dcc;
- mId = id;
- mCid = -1;
- mDataRegState = mPhone.getServiceState().getDataRegistrationState();
- mIsSuspended = false;
- mDataCallSessionStats = new DataCallSessionStats(mPhone);
- mDoAllocatePduSessionId = false;
-
- int networkType = getNetworkType();
- mRilRat = ServiceState.networkTypeToRilRadioTechnology(networkType);
- updateLinkBandwidthsFromCarrierConfig(mRilRat);
-
- addState(mDefaultState);
- addState(mInactiveState, mDefaultState);
- addState(mActivatingState, mDefaultState);
- addState(mActiveState, mDefaultState);
- addState(mDisconnectingState, mDefaultState);
- addState(mDisconnectingErrorCreatingConnection, mDefaultState);
- setInitialState(mInactiveState);
- }
-
- private @NetworkType int getNetworkType() {
- ServiceState ss = mPhone.getServiceState();
- int networkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
-
- NetworkRegistrationInfo nri = ss.getNetworkRegistrationInfo(
- NetworkRegistrationInfo.DOMAIN_PS, mTransportType);
- if (nri != null) {
- networkType = nri.getAccessNetworkTechnology();
- }
-
- return networkType;
- }
-
- /**
- * Get the source transport for handover. For example, handover from WWAN to WLAN, WWAN is the
- * source transport, and vice versa.
- */
- private @TransportType int getHandoverSourceTransport() {
- return mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN
- ? AccessNetworkConstants.TRANSPORT_TYPE_WLAN
- : AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
- }
-
- /**
- * API to generate the OsAppId for enterprise traffic category.
- * @return byte[] representing OsId + length of OsAppId + OsAppId
- */
- @VisibleForTesting
- public static byte[] getEnterpriseOsAppId() {
- byte[] osAppId = NetworkCapabilities.getCapabilityCarrierName(
- NetworkCapabilities.NET_CAPABILITY_ENTERPRISE).getBytes();
- // 16 bytes for UUID, 1 byte for length of osAppId, and up to 255 bytes for osAppId
- ByteBuffer bb = ByteBuffer.allocate(16 + 1 + osAppId.length);
- bb.putLong(OS_ID.getMostSignificantBits());
- bb.putLong(OS_ID.getLeastSignificantBits());
- bb.put((byte) osAppId.length);
- bb.put(osAppId);
- if (VDBG) {
- Rlog.d("DataConnection", "getEnterpriseOsAppId: "
- + IccUtils.bytesToHexString(bb.array()));
- }
- return bb.array();
- }
-
- /**
- * Begin setting up a data connection, calls setupDataCall
- * and the ConnectionParams will be returned with the
- * EVENT_SETUP_DATA_CONNECTION_DONE
- *
- * @param cp is the connection parameters
- *
- * @return Fail cause if failed to setup data connection. {@link DataFailCause#NONE} if success.
- */
- private @DataFailureCause int connect(ConnectionParams cp) {
- log("connect: carrier='" + mApnSetting.getEntryName()
- + "' APN='" + mApnSetting.getApnName()
- + "' proxy='" + mApnSetting.getProxyAddressAsString()
- + "' port='" + mApnSetting.getProxyPort() + "'");
- ApnContext.requestLog(cp.mApnContext, "DataConnection.connect");
-
- // Check if we should fake an error.
- if (mDcTesterFailBringUpAll.getDcFailBringUp().mCounter > 0) {
- DataCallResponse response = new DataCallResponse.Builder()
- .setCause(mDcTesterFailBringUpAll.getDcFailBringUp().mFailCause)
- .setRetryDurationMillis(
- mDcTesterFailBringUpAll.getDcFailBringUp().mSuggestedRetryTime)
- .setMtuV4(PhoneConstants.UNSET_MTU)
- .setMtuV6(PhoneConstants.UNSET_MTU)
- .build();
-
- Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp);
- AsyncResult.forMessage(msg, response, null);
- sendMessage(msg);
- if (DBG) {
- log("connect: FailBringUpAll=" + mDcTesterFailBringUpAll.getDcFailBringUp()
- + " send error response=" + response);
- }
- mDcTesterFailBringUpAll.getDcFailBringUp().mCounter -= 1;
- return DataFailCause.NONE;
- }
-
- mCreateTime = -1;
- mLastFailTime = -1;
- mLastFailCause = DataFailCause.NONE;
-
- Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp);
- msg.obj = cp;
-
- DataProfile dp = new DataProfile.Builder()
- .setApnSetting(mApnSetting)
- .setPreferred(cp.mIsPreferredApn)
- .build();
-
- // We need to use the actual modem roaming state instead of the framework roaming state
- // here. This flag is only passed down to ril_service for picking the correct protocol (for
- // old modem backward compatibility).
- boolean isModemRoaming = mPhone.getServiceState().getDataRoamingFromRegistration();
-
- // If the apn is NOT metered, we will allow data roaming regardless of the setting.
- boolean isUnmeteredApnType = !ApnSettingUtils.isMeteredApnType(
- cp.mApnContext.getApnTypeBitmask(), mPhone);
-
- // Set this flag to true if the user turns on data roaming. Or if we override the roaming
- // state in framework, we should set this flag to true as well so the modem will not reject
- // the data call setup (because the modem actually thinks the device is roaming).
- boolean allowRoaming = mPhone.getDataRoamingEnabled()
- || (isModemRoaming && (!mPhone.getServiceState().getDataRoaming()
- || isUnmeteredApnType));
-
- String dnn = null;
- byte[] osAppId = null;
- if (cp.mApnContext.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE) {
- osAppId = getEnterpriseOsAppId();
- } else {
- dnn = mApnSetting.getApnName();
- }
- final TrafficDescriptor td = osAppId == null && dnn == null ? null
- : new TrafficDescriptor(dnn, osAppId);
- final boolean matchAllRuleAllowed = td == null || td.getOsAppId() == null;
-
- if (DBG) {
- log("allowRoaming=" + allowRoaming
- + ", mPhone.getDataRoamingEnabled()=" + mPhone.getDataRoamingEnabled()
- + ", isModemRoaming=" + isModemRoaming
- + ", mPhone.getServiceState().getDataRoaming()="
- + mPhone.getServiceState().getDataRoaming()
- + ", isUnmeteredApnType=" + isUnmeteredApnType
- + ", trafficDescriptor=" + td
- + ", matchAllRuleAllowed=" + matchAllRuleAllowed
- );
- }
-
- // Check if this data setup is a handover.
- LinkProperties linkProperties = null;
- int reason = DataService.REQUEST_REASON_NORMAL;
- if (cp.mRequestType == REQUEST_TYPE_HANDOVER) {
- // If this is a data setup for handover, we need to pass the link properties
- // of the existing data connection to the modem.
- DcTracker srcDcTracker = mPhone.getDcTracker(getHandoverSourceTransport());
- if (srcDcTracker == null || cp.mApnContext == null) {
- loge("connect: Handover failed. dcTracker=" + srcDcTracker + ", apnContext="
- + cp.mApnContext);
- return DataFailCause.HANDOVER_FAILED;
- }
-
-
- // srcDc is the source data connection while the current instance is the target
- DataConnection srcDc =
- srcDcTracker.getDataConnectionByApnType(cp.mApnContext.getApnType());
- if (srcDc == null) {
- loge("connect: Can't find data connection for handover.");
- return DataFailCause.HANDOVER_FAILED;
- }
-
- // Helpful for logging purposes
- DataServiceManager srcDsm = srcDc.mDataServiceManager;
- String srcDsmTag = (srcDsm == null ? "(null)" : srcDsm.getTag());
- logd("connect: REQUEST_TYPE_HANDOVER - Request handover from " + srcDc.getName()
- + ", targetDsm=" + mDataServiceManager.getTag()
- + ", sourceDsm=" + srcDsmTag);
-
-
- /* startHandover is called on the source data connection, and if successful,
- we ask the target data connection (which is the current instance) to call
- #setupDataCall with request type handover.
- */
- Consumer<Integer> onCompleted = (dataServiceCallbackResultCode) ->
- /* startHandover is called on the srcDc handler, but the callback needs to
- be called on the current (which is the targetDc) handler which is why we
- call sendRunnableMessage. */
- sendRunnableMessage(EVENT_START_HANDOVER_ON_TARGET,
- (inCorrectState) -> requestHandover(inCorrectState, srcDc,
- dataServiceCallbackResultCode,
- cp, msg, dp, isModemRoaming, allowRoaming));
- srcDc.startHandover(onCompleted);
- return DataFailCause.NONE;
- }
-
- // setup data call for REQUEST_TYPE_NORMAL
- mDoAllocatePduSessionId = mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN;
- allocatePduSessionId(psi -> {
- this.setPduSessionId(psi);
- mDataServiceManager.setupDataCall(
- ServiceState.rilRadioTechnologyToAccessNetworkType(cp.mRilRat),
- dp,
- isModemRoaming,
- allowRoaming,
- reason,
- linkProperties,
- psi,
- null, //slice info is null since this is not a handover
- td,
- matchAllRuleAllowed,
- msg);
- TelephonyMetrics.getInstance().writeSetupDataCall(mPhone.getPhoneId(), cp.mRilRat,
- dp.getProfileId(), dp.getApn(), dp.getProtocolType());
- });
- return DataFailCause.NONE;
- }
-
- private void allocatePduSessionId(Consumer<Integer> allocateCallback) {
- if (mDoAllocatePduSessionId) {
- Message msg = this.obtainMessage(EVENT_ALLOCATE_PDU_SESSION_ID);
- msg.obj = allocateCallback;
- mPhone.mCi.allocatePduSessionId(msg);
- } else {
- allocateCallback.accept(PDU_SESSION_ID_NOT_SET);
- }
- }
-
- private void onRquestHandoverFailed(ConnectionParams cp) {
- sendMessage(obtainMessage(EVENT_CANCEL_HANDOVER));
- notifyConnectCompleted(cp, DataFailCause.UNKNOWN,
- DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN, false);
- }
-
- private void requestHandover(boolean inCorrectState, DataConnection srcDc,
- @DataServiceCallback.ResultCode int resultCode,
- ConnectionParams cp, Message msg, DataProfile dp, boolean isModemRoaming,
- boolean allowRoaming) {
-
- if (!inCorrectState) {
- logd("requestHandover: Not in correct state");
- if (isResultCodeSuccess(resultCode)) {
- if (srcDc != null) {
- logd("requestHandover: Not in correct state - Success result code");
- // We need to cancel the handover on source if we ended up in the wrong state.
- srcDc.cancelHandover();
- } else {
- logd("requestHandover: Not in correct state - Success result code - "
- + "srcdc = null");
- }
- }
- onRquestHandoverFailed(cp);
- return;
- } else if (!isResultCodeSuccess(resultCode)) {
- if (DBG) {
- logd("requestHandover: Non success result code from DataService, "
- + "setupDataCall will not be called, result code = "
- + DataServiceCallback.resultCodeToString(resultCode));
- }
- onRquestHandoverFailed(cp);
- return;
- }
-
- if (srcDc == null) {
- loge("requestHandover: Cannot find source data connection.");
- onRquestHandoverFailed(cp);
- return;
- }
-
- LinkProperties linkProperties;
- int reason;
-
- // Preserve the potential network agent from the source data connection. The ownership
- // is not transferred at this moment.
- mHandoverSourceNetworkAgent = srcDc.getNetworkAgent();
- if (mHandoverSourceNetworkAgent == null) {
- loge("requestHandover: Cannot get network agent from the source dc " + srcDc.getName());
- onRquestHandoverFailed(cp);
- return;
- }
-
- linkProperties = srcDc.getLinkProperties();
- if (linkProperties == null || linkProperties.getLinkAddresses().isEmpty()) {
- loge("requestHandover: Can't find link properties of handover data connection. dc="
- + srcDc);
- onRquestHandoverFailed(cp);
- return;
- }
-
- mHandoverLocalLog.log("Handover started. Preserved the agent.");
- log("Get the handover source network agent: " + mHandoverSourceNetworkAgent);
-
- reason = DataService.REQUEST_REASON_HANDOVER;
-
- TrafficDescriptor td = dp.getApn() == null ? null
- : new TrafficDescriptor(dp.getApn(), null);
- boolean matchAllRuleAllowed = true;
-
- mDataServiceManager.setupDataCall(
- ServiceState.rilRadioTechnologyToAccessNetworkType(cp.mRilRat),
- dp,
- isModemRoaming,
- allowRoaming,
- reason,
- linkProperties,
- srcDc.getPduSessionId(),
- srcDc.getSliceInfo(),
- td,
- matchAllRuleAllowed,
- msg);
- TelephonyMetrics.getInstance().writeSetupDataCall(mPhone.getPhoneId(), cp.mRilRat,
- dp.getProfileId(), dp.getApn(), dp.getProtocolType());
- }
-
- /**
- * Called on the source data connection from the target data connection.
- */
- @VisibleForTesting
- public void startHandover(Consumer<Integer> onTargetDcComplete) {
- logd("startHandover: " + toStringSimple());
- // Set the handover state to being transferred on "this" data connection which is the src.
- setHandoverState(HANDOVER_STATE_BEING_TRANSFERRED);
-
- Consumer<Integer> onSrcDcComplete =
- resultCode -> onHandoverStarted(resultCode, onTargetDcComplete);
- /*
- The flow here is:
- srcDc#startHandover -> dataService#startHandover -> (onHandoverStarted) ->
- onSrcDcComplete -> onTargetDcComplete
- */
- mDataServiceManager.startHandover(mCid,
- this.obtainMessage(EVENT_START_HANDOVER,
- onSrcDcComplete));
- }
-
- /**
- * Called on the source data connection when the async call to start handover is complete
- */
- private void onHandoverStarted(@DataServiceCallback.ResultCode int resultCode,
- Consumer<Integer> onTargetDcComplete) {
- logd("onHandoverStarted: " + toStringSimple());
- if (!isResultCodeSuccess(resultCode)) {
- setHandoverState(HANDOVER_STATE_IDLE);
- }
- onTargetDcComplete.accept(resultCode);
- }
-
- private void cancelHandover() {
- if (mHandoverState != HANDOVER_STATE_BEING_TRANSFERRED) {
- logd("cancelHandover: handover state is " + handoverStateToString(mHandoverState)
- + ", expecting HANDOVER_STATE_BEING_TRANSFERRED");
- }
- mDataServiceManager.cancelHandover(mCid, this.obtainMessage(EVENT_CANCEL_HANDOVER));
- setHandoverState(HANDOVER_STATE_IDLE);
- }
-
- /**
- * Update NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED based on congested override
- * @param isCongested whether this DC should be set to congested or not
- */
- public void onCongestednessChanged(boolean isCongested) {
- sendMessage(obtainMessage(EVENT_DATA_CONNECTION_CONGESTEDNESS_CHANGED, isCongested));
- }
-
- /**
- * Update NetworkCapabilities.NET_CAPABILITY_NOT_METERED based on metered override
- * @param isUnmetered whether this DC should be set to unmetered or not
- */
- public void onMeterednessChanged(boolean isUnmetered) {
- sendMessage(obtainMessage(EVENT_DATA_CONNECTION_METEREDNESS_CHANGED, isUnmetered));
- }
-
- /**
- * TearDown the data connection when the deactivation is complete a Message with
- * msg.what == EVENT_DEACTIVATE_DONE
- *
- * @param o is the object returned in the AsyncResult.obj.
- */
- private void tearDownData(Object o) {
- int discReason = DataService.REQUEST_REASON_NORMAL;
- ApnContext apnContext = null;
- if ((o != null) && (o instanceof DisconnectParams)) {
- DisconnectParams dp = (DisconnectParams) o;
- apnContext = dp.mApnContext;
- if (TextUtils.equals(dp.mReason, Phone.REASON_RADIO_TURNED_OFF)
- || TextUtils.equals(dp.mReason, Phone.REASON_PDP_RESET)) {
- discReason = DataService.REQUEST_REASON_SHUTDOWN;
- } else if (dp.mReleaseType == DcTracker.RELEASE_TYPE_HANDOVER) {
- discReason = DataService.REQUEST_REASON_HANDOVER;
- }
- }
-
- String str = "tearDownData. mCid=" + mCid + ", reason=" + discReason;
- if (DBG) log(str);
- ApnContext.requestLog(apnContext, str);
-
-
- //Needed to be final to work in a closure
- final int fDiscReason = discReason;
- releasePduSessionId(() -> {
- // This is run after release pdu session id is complete
- this.setPduSessionId(PDU_SESSION_ID_NOT_SET);
- mDataServiceManager.deactivateDataCall(mCid, fDiscReason,
- obtainMessage(EVENT_DEACTIVATE_DONE, mTag, 0, o));
- mDataCallSessionStats.setDeactivateDataCallReason(fDiscReason);
- });
- }
-
- private void releasePduSessionId(Runnable releaseCallback) {
- // If the transport is IWLAN, and there is a valid PDU session id, also the data connection
- // is not being handovered, we should release the pdu session id.
- if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN
- && mHandoverState == HANDOVER_STATE_IDLE
- && this.getPduSessionId() != PDU_SESSION_ID_NOT_SET) {
- Message msg = this.obtainMessage(EVENT_RELEASE_PDU_SESSION_ID);
- msg.obj = releaseCallback;
- mPhone.mCi.releasePduSessionId(msg, this.getPduSessionId());
- } else {
- // Just go and run the callback since we either have no pdu session id to release
- // or we are in the middle of a handover
- releaseCallback.run();
- }
- }
-
- private void notifyAllWithEvent(ApnContext alreadySent, int event, String reason) {
- for (ConnectionParams cp : mApnContexts.values()) {
- ApnContext apnContext = cp.mApnContext;
- if (apnContext == alreadySent) continue;
- if (reason != null) apnContext.setReason(reason);
- Pair<ApnContext, Integer> pair = new Pair<>(apnContext, cp.mConnectionGeneration);
- Message msg = mDct.obtainMessage(event, cp.mRequestType,
- DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN, pair);
- AsyncResult.forMessage(msg);
- msg.sendToTarget();
- }
- }
-
- /**
- * Send the connectionCompletedMsg.
- *
- * @param cp is the ConnectionParams
- * @param cause and if no error the cause is DataFailCause.NONE
- * @param handoverFailureMode The action on handover failure
- * @param sendAll is true if all contexts are to be notified
- */
- private void notifyConnectCompleted(ConnectionParams cp, @DataFailureCause int cause,
- @HandoverFailureMode int handoverFailureMode, boolean sendAll) {
- ApnContext alreadySent = null;
-
- if (cp != null && cp.mOnCompletedMsg != null) {
- // Get the completed message but only use it once
- Message connectionCompletedMsg = cp.mOnCompletedMsg;
- cp.mOnCompletedMsg = null;
- alreadySent = cp.mApnContext;
-
- long timeStamp = System.currentTimeMillis();
- connectionCompletedMsg.arg1 = cp.mRequestType;
- connectionCompletedMsg.arg2 = handoverFailureMode;
-
- if (cause == DataFailCause.NONE) {
- mCreateTime = timeStamp;
- AsyncResult.forMessage(connectionCompletedMsg);
- } else {
- mLastFailCause = cause;
- mLastFailTime = timeStamp;
-
- // Return message with a Throwable exception to signify an error.
- if (cause == DataFailCause.NONE) cause = DataFailCause.UNKNOWN;
- AsyncResult.forMessage(connectionCompletedMsg, cause,
- new Throwable(DataFailCause.toString(cause)));
- }
- if (DBG) {
- log("notifyConnectCompleted at " + timeStamp + " cause="
- + DataFailCause.toString(cause) + " connectionCompletedMsg="
- + msgToString(connectionCompletedMsg));
- }
-
- connectionCompletedMsg.sendToTarget();
- }
- if (sendAll) {
- log("Send to all. " + alreadySent + " " + DataFailCause.toString(cause));
- notifyAllWithEvent(alreadySent, DctConstants.EVENT_DATA_SETUP_COMPLETE_ERROR,
- DataFailCause.toString(cause));
- }
- }
-
- /**
- * Send ar.userObj if its a message, which is should be back to originator.
- *
- * @param dp is the DisconnectParams.
- */
- private void notifyDisconnectCompleted(DisconnectParams dp, boolean sendAll) {
- if (VDBG) log("NotifyDisconnectCompleted");
-
- ApnContext alreadySent = null;
- String reason = null;
-
- if (dp != null && dp.mOnCompletedMsg != null) {
- // Get the completed message but only use it once
- Message msg = dp.mOnCompletedMsg;
- dp.mOnCompletedMsg = null;
- if (msg.obj instanceof ApnContext) {
- alreadySent = (ApnContext)msg.obj;
- }
- reason = dp.mReason;
- if (VDBG) {
- log(String.format("msg=%s msg.obj=%s", msg.toString(),
- ((msg.obj instanceof String) ? (String) msg.obj : "<no-reason>")));
- }
- AsyncResult.forMessage(msg);
- msg.sendToTarget();
- }
- if (sendAll) {
- if (reason == null) {
- reason = DataFailCause.toString(DataFailCause.UNKNOWN);
- }
- notifyAllWithEvent(alreadySent, DctConstants.EVENT_DISCONNECT_DONE, reason);
- }
- if (DBG) log("NotifyDisconnectCompleted DisconnectParams=" + dp);
- }
-
- private void sendRunnableMessage(int eventCode, @NonNull final Consumer<Boolean> r) {
- sendMessage(eventCode, r);
- }
-
- /*
- * **************************************************************************
- * Begin Members and methods owned by DataConnectionTracker but stored
- * in a DataConnection because there is one per connection.
- * **************************************************************************
- */
-
- /*
- * The id is owned by DataConnectionTracker.
- */
- private int mId;
-
- /**
- * Get the DataConnection ID
- */
- public int getDataConnectionId() {
- return mId;
- }
-
- /*
- * **************************************************************************
- * End members owned by DataConnectionTracker
- * **************************************************************************
- */
-
- /**
- * Clear all settings called when entering mInactiveState.
- */
- private synchronized void clearSettings() {
- if (DBG) log("clearSettings");
-
- mCreateTime = -1;
- mLastFailTime = -1;
- mLastFailCause = DataFailCause.NONE;
- mCid = -1;
-
- mPcscfAddr = new String[5];
-
- mLinkProperties = new LinkProperties();
- mApnContexts.clear();
- mApnSetting = null;
- mUnmeteredUseOnly = false;
- mMmsUseOnly = false;
- mEnterpriseUse = false;
- mRestrictedNetworkOverride = false;
- mDcFailCause = DataFailCause.NONE;
- mDisabledApnTypeBitMask = 0;
- mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
- mCongestedOverride = false;
- mUnmeteredOverride = false;
- mDownlinkBandwidth = 14;
- mUplinkBandwidth = 14;
- mIsSuspended = false;
- mHandoverState = HANDOVER_STATE_IDLE;
- mHandoverFailureMode = DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN;
- mSliceInfo = null;
- mDefaultQos = null;
- mDoAllocatePduSessionId = false;
- mQosBearerSessions.clear();
- mTrafficDescriptors.clear();
- }
-
- /**
- * Process setup data completion result from data service
- *
- * @param resultCode The result code returned by data service
- * @param response Data call setup response from data service
- * @param cp The original connection params used for data call setup
- * @return Setup result
- */
- private SetupResult onSetupConnectionCompleted(@DataServiceCallback.ResultCode int resultCode,
- DataCallResponse response,
- ConnectionParams cp) {
- SetupResult result;
-
- log("onSetupConnectionCompleted: resultCode=" + resultCode + ", response=" + response);
- if (cp.mTag != mTag) {
- if (DBG) {
- log("onSetupConnectionCompleted stale cp.tag=" + cp.mTag + ", mtag=" + mTag);
- }
- result = SetupResult.ERROR_STALE;
- } else if (resultCode == DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE) {
- result = SetupResult.ERROR_RADIO_NOT_AVAILABLE;
- result.mFailCause = DataFailCause.RADIO_NOT_AVAILABLE;
- } else if (resultCode == DataServiceCallback.RESULT_ERROR_TEMPORARILY_UNAVAILABLE) {
- result = SetupResult.ERROR_DATA_SERVICE_SPECIFIC_ERROR;
- result.mFailCause = DataFailCause.SERVICE_TEMPORARILY_UNAVAILABLE;
- } else if (resultCode == DataServiceCallback.RESULT_ERROR_INVALID_ARG) {
- result = SetupResult.ERROR_INVALID_ARG;
- result.mFailCause = DataFailCause.UNACCEPTABLE_NETWORK_PARAMETER;
- } else if (response.getCause() != 0) {
- if (response.getCause() == DataFailCause.RADIO_NOT_AVAILABLE) {
- result = SetupResult.ERROR_RADIO_NOT_AVAILABLE;
- result.mFailCause = DataFailCause.RADIO_NOT_AVAILABLE;
- } else {
- 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 (!mDcController.getTrafficDescriptorsForCid(response.getId())
- .equals(response.getTrafficDescriptors())) {
- if (DBG) log("Updating traffic descriptors: " + response.getTrafficDescriptors());
- mDcController.getActiveDcByCid(response.getId()).updateTrafficDescriptors(response);
- mDct.obtainMessage(DctConstants.EVENT_TRAFFIC_DESCRIPTORS_UPDATED).sendToTarget();
- }
- if (DBG) log("DataConnection already exists for cid: " + response.getId());
- result = SetupResult.ERROR_DUPLICATE_CID;
- result.mFailCause = DataFailCause.DUPLICATE_CID;
- } else if (cp.mApnContext.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE
- && !mDcController.isDefaultDataActive()) {
- if (DBG) log("No default data connection currently active");
- mCid = response.getId();
- result = SetupResult.ERROR_NO_DEFAULT_CONNECTION;
- result.mFailCause = DataFailCause.NO_DEFAULT_DATA;
- } else {
- if (DBG) log("onSetupConnectionCompleted received successful DataCallResponse");
- mCid = response.getId();
- setPduSessionId(response.getPduSessionId());
- updatePcscfAddr(response);
- updateResponseFields(response);
- result = updateLinkProperty(response).setupResult;
- }
-
- return result;
- }
-
- private static boolean isResultCodeSuccess(int resultCode) {
- return resultCode == DataServiceCallback.RESULT_SUCCESS
- || resultCode == DataServiceCallback.RESULT_ERROR_UNSUPPORTED;
- }
-
- private boolean isDnsOk(String[] domainNameServers) {
- if (NULL_IP.equals(domainNameServers[0]) && NULL_IP.equals(domainNameServers[1])
- && !mPhone.isDnsCheckDisabled()) {
- // Work around a race condition where QMI does not fill in DNS:
- // Deactivate PDP and let DataConnectionTracker retry.
- // Do not apply the race condition workaround for MMS APN
- // if Proxy is an IP-address.
- // Otherwise, the default APN will not be restored anymore.
- if (!isIpAddress(mApnSetting.getMmsProxyAddressAsString())) {
- log(String.format(
- "isDnsOk: return false apn.types=%d APN_TYPE_MMS=%s isIpAddress(%s)=%s",
- mApnSetting.getApnTypeBitmask(), ApnSetting.TYPE_MMS_STRING,
- mApnSetting.getMmsProxyAddressAsString(),
- isIpAddress(mApnSetting.getMmsProxyAddressAsString())));
- return false;
- }
- }
- return true;
- }
-
- /**
- * TCP buffer size config based on the ril technology. There are 6 parameters
- * read_min, read_default, read_max, write_min, write_default, write_max in the TCP buffer
- * config string and they are separated by a comma. The unit of these parameters is byte.
- */
- private static final String TCP_BUFFER_SIZES_GPRS = "4092,8760,48000,4096,8760,48000";
- private static final String TCP_BUFFER_SIZES_EDGE = "4093,26280,70800,4096,16384,70800";
- private static final String TCP_BUFFER_SIZES_UMTS = "58254,349525,1048576,58254,349525,1048576";
- private static final String TCP_BUFFER_SIZES_1XRTT = "16384,32768,131072,4096,16384,102400";
- private static final String TCP_BUFFER_SIZES_EVDO = "4094,87380,262144,4096,16384,262144";
- private static final String TCP_BUFFER_SIZES_EHRPD = "131072,262144,1048576,4096,16384,524288";
- private static final String TCP_BUFFER_SIZES_HSDPA = "61167,367002,1101005,8738,52429,262114";
- private static final String TCP_BUFFER_SIZES_HSPA = "40778,244668,734003,16777,100663,301990";
- private static final String TCP_BUFFER_SIZES_LTE =
- "524288,1048576,2097152,262144,524288,1048576";
- private static final String TCP_BUFFER_SIZES_HSPAP =
- "122334,734003,2202010,32040,192239,576717";
- private static final String TCP_BUFFER_SIZES_NR =
- "2097152,6291456,16777216,512000,2097152,8388608";
- private static final String TCP_BUFFER_SIZES_LTE_CA =
- "4096,6291456,12582912,4096,1048576,2097152";
-
- private void updateTcpBufferSizes(int rilRat) {
- String sizes = null;
- ServiceState ss = mPhone.getServiceState();
- if (rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE &&
- ss.isUsingCarrierAggregation()) {
- rilRat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA;
- }
- String ratName = ServiceState.rilRadioTechnologyToString(rilRat).toLowerCase(Locale.ROOT);
- // ServiceState gives slightly different names for EVDO tech ("evdo-rev.0" for ex)
- // - patch it up:
- if (rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0 ||
- rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A ||
- rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B) {
- ratName = RAT_NAME_EVDO;
- }
-
- // NR 5G Non-Standalone use LTE cell as the primary cell, the ril technology is LTE in this
- // case. We use NR 5G TCP buffer size when connected to NR 5G Non-Standalone network.
- if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN
- && ((rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE ||
- rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA) && isNRConnected())
- && mPhone.getServiceStateTracker().getNrContextIds().contains(mCid)) {
- ratName = RAT_NAME_5G;
- }
-
- log("updateTcpBufferSizes: " + ratName);
-
- // in the form: "ratname:rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max"
- String[] configOverride = mPhone.getContext().getResources().getStringArray(
- com.android.internal.R.array.config_mobile_tcp_buffers);
- for (int i = 0; i < configOverride.length; i++) {
- String[] split = configOverride[i].split(":");
- if (ratName.equals(split[0]) && split.length == 2) {
- sizes = split[1];
- break;
- }
- }
-
- if (sizes == null) {
- // no override - use telephony defaults
- // doing it this way allows device or carrier to just override the types they
- // care about and inherit the defaults for the others.
- switch (rilRat) {
- case ServiceState.RIL_RADIO_TECHNOLOGY_GPRS:
- sizes = TCP_BUFFER_SIZES_GPRS;
- break;
- case ServiceState.RIL_RADIO_TECHNOLOGY_EDGE:
- sizes = TCP_BUFFER_SIZES_EDGE;
- break;
- case ServiceState.RIL_RADIO_TECHNOLOGY_UMTS:
- sizes = TCP_BUFFER_SIZES_UMTS;
- break;
- case ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT:
- sizes = TCP_BUFFER_SIZES_1XRTT;
- break;
- case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0:
- case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A:
- case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B:
- sizes = TCP_BUFFER_SIZES_EVDO;
- break;
- case ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD:
- sizes = TCP_BUFFER_SIZES_EHRPD;
- break;
- case ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA:
- sizes = TCP_BUFFER_SIZES_HSDPA;
- break;
- case ServiceState.RIL_RADIO_TECHNOLOGY_HSPA:
- case ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA:
- sizes = TCP_BUFFER_SIZES_HSPA;
- break;
- case ServiceState.RIL_RADIO_TECHNOLOGY_LTE:
- // Use NR 5G TCP buffer size when connected to NR 5G Non-Standalone network.
- if (RAT_NAME_5G.equals(ratName)) {
- sizes = TCP_BUFFER_SIZES_NR;
- } else {
- sizes = TCP_BUFFER_SIZES_LTE;
- }
- break;
- case ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA:
- // Use NR 5G TCP buffer size when connected to NR 5G Non-Standalone network.
- if (RAT_NAME_5G.equals(ratName)) {
- sizes = TCP_BUFFER_SIZES_NR;
- } else {
- sizes = TCP_BUFFER_SIZES_LTE_CA;
- }
- break;
- case ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP:
- sizes = TCP_BUFFER_SIZES_HSPAP;
- break;
- case ServiceState.RIL_RADIO_TECHNOLOGY_NR:
- sizes = TCP_BUFFER_SIZES_NR;
- break;
- default:
- // Leave empty - this will let ConnectivityService use the system default.
- break;
- }
- }
- mLinkProperties.setTcpBufferSizes(sizes);
- }
-
- private void updateLinkBandwidthsFromCarrierConfig(int rilRat) {
- String ratName = DataConfigManager.getDataConfigNetworkType(
- mPhone.getDisplayInfoController().getTelephonyDisplayInfo());
-
- if (DBG) log("updateLinkBandwidthsFromCarrierConfig: " + ratName);
-
- Pair<Integer, Integer> values = mDct.getLinkBandwidthsFromCarrierConfig(ratName);
- if (values == null) {
- values = new Pair<>(14, 14);
- }
- mDownlinkBandwidth = values.first;
- mUplinkBandwidth = values.second;
- }
-
-
- private void updateLinkBandwidthsFromModem(List<LinkCapacityEstimate> lceList) {
- if (DBG) log("updateLinkBandwidthsFromModem: lceList=" + lceList);
- boolean downlinkUpdated = false;
- boolean uplinkUpdated = false;
- LinkCapacityEstimate lce = lceList.get(0);
- // LCE status deprecated in IRadio 1.2, so only check for IRadio < 1.2
- if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_2)
- || mPhone.getLceStatus() == RILConstants.LCE_ACTIVE) {
- if (lce.getDownlinkCapacityKbps() != LinkCapacityEstimate.INVALID) {
- mDownlinkBandwidth = lce.getDownlinkCapacityKbps();
- downlinkUpdated = true;
- }
- if (lce.getUplinkCapacityKbps() != LinkCapacityEstimate.INVALID) {
- mUplinkBandwidth = lce.getUplinkCapacityKbps();
- uplinkUpdated = true;
- }
- }
-
- if (!downlinkUpdated || !uplinkUpdated) {
- fallBackToCarrierConfigValues(downlinkUpdated, uplinkUpdated);
- }
-
- if (mNetworkAgent != null) {
- mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), DataConnection.this);
- }
- }
-
- private void updateLinkBandwidthsFromBandwidthEstimator(int uplinkBandwidthKbps,
- int downlinkBandwidthKbps) {
- if (DBG) {
- log("updateLinkBandwidthsFromBandwidthEstimator, UL= "
- + uplinkBandwidthKbps + " DL= " + downlinkBandwidthKbps);
- }
- 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);
- }
- }
-
- private void fallBackToCarrierConfigValues(boolean downlinkUpdated, boolean uplinkUpdated) {
- String ratName = ServiceState.rilRadioTechnologyToString(mRilRat);
- if (mRilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE && isNRConnected()) {
- ratName = mPhone.getServiceState().getNrFrequencyRange()
- == ServiceState.FREQUENCY_RANGE_MMWAVE
- ? DctConstants.RAT_NAME_NR_NSA_MMWAVE : DctConstants.RAT_NAME_NR_NSA;
- }
- Pair<Integer, Integer> values = mDct.getLinkBandwidthsFromCarrierConfig(ratName);
- if (values != null) {
- if (!downlinkUpdated) {
- mDownlinkBandwidth = values.first;
- }
- if (!uplinkUpdated) {
- mUplinkBandwidth = values.second;
- }
- mUplinkBandwidth = Math.min(mUplinkBandwidth, mDownlinkBandwidth);
- }
- }
-
- private boolean isBandwidthSourceKey(String source) {
- return source.equals(mPhone.getContext().getResources().getString(
- com.android.internal.R.string.config_bandwidthEstimateSource));
- }
-
- /**
- * Indicates if this data connection was established for unmetered use only. Note that this
- * flag should be populated when data becomes active. And if it is set to true, it can be set to
- * false later when we are reevaluating the data connection. But if it is set to false, it
- * can never become true later because setting it to true will cause this data connection
- * losing some immutable network capabilities, which can cause issues in connectivity service.
- */
- private boolean mUnmeteredUseOnly = false;
-
- /**
- * Indicates if this data connection was established for MMS use only. This is true only when
- * mobile data is disabled but the user allows sending and receiving MMS messages. If the data
- * enabled settings indicate that MMS data is allowed unconditionally, MMS can be sent when data
- * is disabled even if it is a metered APN type.
- */
- private boolean mMmsUseOnly = false;
-
- /**
- * Indicates if when this connection was established we had a restricted/privileged
- * NetworkRequest and needed it to overcome data-enabled limitations.
- *
- * This flag overrides the APN-based restriction capability, restricting the network
- * based on both having a NetworkRequest with restricted AND needing a restricted
- * bit to overcome user-disabled status. This allows us to handle the common case
- * of having both restricted requests and unrestricted requests for the same apn:
- * if conditions require a restricted network to overcome user-disabled then it must
- * be restricted, otherwise it is unrestricted (or restricted based on APN type).
- *
- * This supports a privileged app bringing up a network without general apps having access
- * to it when the network is otherwise unavailable (hipri). The first use case is
- * pre-paid SIM reprovisioning over internet, where the carrier insists on no traffic
- * other than from the privileged carrier-app.
- *
- * Note that the data connection cannot go from unrestricted to restricted because the
- * connectivity service does not support dynamically closing TCP connections at this point.
- */
- 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)
- boolean isAnyRestrictedRequest = false;
- for (ApnContext apnContext : mApnContexts.keySet()) {
- if (apnContext.hasRestrictedRequests(true /* exclude DUN */)) {
- isAnyRestrictedRequest = true;
- break;
- }
- }
-
- // If all of the network requests are non-restricted, then we don't need to restrict
- // the network.
- if (!isAnyRestrictedRequest) {
- return false;
- }
-
- // If the network is unmetered, then we don't need to restrict the network because users
- // won't be charged anyway.
- if (!ApnSettingUtils.isMetered(mApnSetting, mPhone)) {
- return false;
- }
-
- // If the data is disabled, then we need to restrict the network so only privileged apps can
- // use the restricted network while data is disabled.
- if (!mPhone.getDataEnabledSettings().isDataEnabled()) {
- return true;
- }
-
- // If the device is roaming, and the user does not turn on data roaming, then we need to
- // restrict the network so only privileged apps can use it.
- if (!mDct.getDataRoamingEnabled() && mPhone.getServiceState().getDataRoaming()) {
- return true;
- }
-
- // Otherwise we should not restrict the network so anyone who requests can use it.
- return false;
- }
-
- /**
- * @return True if this data connection should only be used for unmetered purposes.
- */
- private boolean isUnmeteredUseOnly() {
- // If this data connection is on IWLAN, then it's unmetered and can be used by everyone.
- // Should not be for unmetered used only.
- if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
- return false;
- }
-
- // If data is enabled, this data connection can't be for unmetered used only because
- // everyone should be able to use it if:
- // 1. Device is not roaming, or
- // 2. Device is roaming and data roaming is turned on
- if (mPhone.getDataEnabledSettings().isDataEnabled()) {
- if (!mPhone.getServiceState().getDataRoaming() || mDct.getDataRoamingEnabled()) {
- return false;
- }
- }
-
- // The data connection can only be unmetered used only if all attached APN contexts
- // attached to this data connection are unmetered.
- for (ApnContext apnContext : mApnContexts.keySet()) {
- if (ApnSettingUtils.isMeteredApnType(apnContext.getApnTypeBitmask(), mPhone)) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * @return True if this data connection should only be used for MMS purposes.
- */
- private boolean isMmsUseOnly() {
- // MMS use only if data is disabled, MMS is allowed unconditionally, and MMS is the only
- // APN type for this data connection.
- DataEnabledSettings des = mPhone.getDataEnabledSettings();
- boolean mmsAllowedUnconditionally = !des.isDataEnabled() && des.isMmsAlwaysAllowed();
- boolean mmsApnOnly = isApnContextAttached(ApnSetting.TYPE_MMS, true);
- return mmsAllowedUnconditionally && mmsApnOnly;
- }
-
- /**
- * 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() {
- return mApnContexts.keySet().stream().anyMatch(
- ac -> ac.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE);
- }
-
- /**
- * Get the network capabilities for this data connection.
- *
- * @return the {@link NetworkCapabilities} of this data connection.
- */
- public NetworkCapabilities getNetworkCapabilities() {
- final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder()
- .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
- boolean unmeteredApns = false;
-
- if (mApnSetting != null && !mEnterpriseUse && !mMmsUseOnly) {
- final int[] types = ApnSetting.getApnTypesFromBitmask(
- mApnSetting.getApnTypeBitmask() & ~mDisabledApnTypeBitMask);
- for (int type : types) {
- if ((!mRestrictedNetworkOverride && mUnmeteredUseOnly)
- && ApnSettingUtils.isMeteredApnType(type, mPhone)) {
- log("Dropped the metered " + ApnSetting.getApnTypeString(type)
- + " type for the unmetered data call.");
- continue;
- }
- switch (type) {
- case ApnSetting.TYPE_ALL: {
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL);
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_FOTA);
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_CBS);
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_IA);
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
- break;
- }
- case ApnSetting.TYPE_DEFAULT: {
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
- break;
- }
- case ApnSetting.TYPE_MMS: {
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
- break;
- }
- case ApnSetting.TYPE_SUPL: {
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL);
- break;
- }
- case ApnSetting.TYPE_DUN: {
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
- break;
- }
- case ApnSetting.TYPE_FOTA: {
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_FOTA);
- break;
- }
- case ApnSetting.TYPE_IMS: {
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
- break;
- }
- case ApnSetting.TYPE_CBS: {
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_CBS);
- break;
- }
- case ApnSetting.TYPE_IA: {
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_IA);
- break;
- }
- case ApnSetting.TYPE_EMERGENCY: {
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS);
- break;
- }
- case ApnSetting.TYPE_MCX: {
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MCX);
- break;
- }
- case ApnSetting.TYPE_XCAP: {
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_XCAP);
- break;
- }
- default:
- }
- }
-
- if (!ApnSettingUtils.isMetered(mApnSetting, mPhone)) {
- unmeteredApns = true;
- }
- }
-
- // 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 (mEnterpriseUse) {
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE);
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
- }
-
- if (NetworkCapabilitiesUtils.inferRestrictedCapability(builder.build())) {
- builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
- }
-
- if (mMmsUseOnly) {
- if (ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_MMS, mPhone)) {
- log("Adding unmetered capability for the unmetered MMS-only data connection");
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
- }
- log("Adding MMS capability for the MMS-only data connection");
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
- }
-
- if (mRestrictedNetworkOverride) {
- builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
- // don't use dun on restriction-overriden networks.
- builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
- }
-
- builder.setLinkDownstreamBandwidthKbps(mDownlinkBandwidth);
- builder.setLinkUpstreamBandwidthKbps(mUplinkBandwidth);
-
- builder.setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
- .setSubscriptionId(mSubId).build());
- builder.setSubscriptionIds(Collections.singleton(mSubId));
-
- if (!mPhone.getServiceState().getDataRoaming()) {
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
- }
-
- if (!mCongestedOverride) {
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED);
- }
-
- if (mUnmeteredOverride) {
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED);
- }
-
- if (!mIsSuspended) {
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED);
- }
-
- final int carrierServicePackageUid = getCarrierServicePackageUid();
-
- // TODO(b/205736323): Owner and Admin UIDs currently come from separate data sources. Unify
- // them, and remove ArrayUtils.contains() check.
- if (carrierServicePackageUid != Process.INVALID_UID
- && ArrayUtils.contains(mAdministratorUids, carrierServicePackageUid)) {
- builder.setOwnerUid(carrierServicePackageUid);
- builder.setAllowedUids(Collections.singleton(carrierServicePackageUid));
- }
- builder.setAdministratorUids(mAdministratorUids);
-
- // Always start with NOT_VCN_MANAGED, then remove if VcnManager indicates this is part of a
- // VCN.
- builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
- final VcnNetworkPolicyResult vcnPolicy = getVcnPolicy(builder.build());
- if (!vcnPolicy.getNetworkCapabilities()
- .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)) {
- builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
- }
- if (!vcnPolicy.getNetworkCapabilities()
- .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)) {
- builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
- }
-
- return builder.build();
- }
-
- // TODO(b/205736323): Once TelephonyManager#getCarrierServicePackageNameForLogicalSlot() is
- // plumbed to CarrierPrivilegesTracker's cache, query the cached UIDs.
- private int getFirstUidForPackage(String pkgName) {
- if (pkgName == null) {
- return Process.INVALID_UID;
- }
-
- List<UserInfo> users = mPhone.getContext().getSystemService(UserManager.class).getUsers();
- for (UserInfo user : users) {
- int userId = user.getUserHandle().getIdentifier();
- try {
- PackageManager pm = mPhone.getContext().getPackageManager();
-
- if (pm != null) {
- return pm.getPackageUidAsUser(pkgName, userId);
- }
- } catch (NameNotFoundException exception) {
- // Didn't find package. Try other users
- Rlog.i(
- "DataConnection",
- "Unable to find uid for package " + pkgName + " and user " + userId);
- }
- }
- return Process.INVALID_UID;
- }
-
- private int getCarrierServicePackageUid() {
- String pkgName =
- mPhone.getContext()
- .getSystemService(TelephonyManager.class)
- .getCarrierServicePackageNameForLogicalSlot(mPhone.getPhoneId());
-
- return getFirstUidForPackage(pkgName);
- }
-
- /**
- * Check if the this data network is VCN-managed.
- *
- * @param networkCapabilities The network capabilities of this data network.
- * @return The VCN's policy for this DataNetwork.
- */
- private VcnNetworkPolicyResult getVcnPolicy(NetworkCapabilities networkCapabilities) {
- return mVcnManager.applyVcnNetworkPolicy(networkCapabilities, getLinkProperties());
- }
-
- /** @return {@code true} if validation is required, {@code false} otherwise. */
- public boolean isValidationRequired() {
- final NetworkCapabilities nc = getNetworkCapabilities();
- return nc != null
- && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
- && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
- && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
- && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN);
- }
-
- /**
- * @return {@code True} if 464xlat should be skipped.
- */
- @VisibleForTesting
- public boolean shouldSkip464Xlat() {
- switch (mApnSetting.getSkip464Xlat()) {
- case Telephony.Carriers.SKIP_464XLAT_ENABLE:
- return true;
- case Telephony.Carriers.SKIP_464XLAT_DISABLE:
- return false;
- case Telephony.Carriers.SKIP_464XLAT_DEFAULT:
- default:
- break;
- }
-
- // As default, return true if ims and no internet
- final NetworkCapabilities nc = getNetworkCapabilities();
- return nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
- && !nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
- }
-
- /**
- * @return {@code} true iff. {@code address} is a literal IPv4 or IPv6 address.
- */
- @VisibleForTesting
- public static boolean isIpAddress(String address) {
- if (address == null) return false;
-
- // Accept IPv6 addresses (only) in square brackets for compatibility.
- if (address.startsWith("[") && address.endsWith("]") && address.indexOf(':') != -1) {
- address = address.substring(1, address.length() - 1);
- }
- return InetAddresses.isNumericAddress(address);
- }
-
- private SetupResult setLinkProperties(DataCallResponse response,
- LinkProperties linkProperties) {
- // Check if system property dns usable
- String propertyPrefix = "net." + response.getInterfaceName() + ".";
- String dnsServers[] = new String[2];
- dnsServers[0] = SystemProperties.get(propertyPrefix + "dns1");
- dnsServers[1] = SystemProperties.get(propertyPrefix + "dns2");
- boolean okToUseSystemPropertyDns = isDnsOk(dnsServers);
-
- SetupResult result;
-
- // Start with clean network properties and if we have
- // a failure we'll clear again at the bottom of this code.
- linkProperties.clear();
-
- if (response.getCause() == DataFailCause.NONE) {
- try {
- // set interface name
- linkProperties.setInterfaceName(response.getInterfaceName());
-
- // set link addresses
- if (response.getAddresses().size() > 0) {
- for (LinkAddress la : response.getAddresses()) {
- if (!la.getAddress().isAnyLocalAddress()) {
- if (DBG) {
- log("addr/pl=" + la.getAddress() + "/"
- + la.getPrefixLength());
- }
- linkProperties.addLinkAddress(la);
- }
- }
- } else {
- throw new UnknownHostException("no address for ifname="
- + response.getInterfaceName());
- }
-
- // set dns servers
- if (response.getDnsAddresses().size() > 0) {
- for (InetAddress dns : response.getDnsAddresses()) {
- if (!dns.isAnyLocalAddress()) {
- linkProperties.addDnsServer(dns);
- }
- }
- } else if (okToUseSystemPropertyDns) {
- for (String dnsAddr : dnsServers) {
- dnsAddr = dnsAddr.trim();
- if (dnsAddr.isEmpty()) continue;
- InetAddress ia;
- try {
- ia = InetAddresses.parseNumericAddress(dnsAddr);
- } catch (IllegalArgumentException e) {
- throw new UnknownHostException("Non-numeric dns addr=" + dnsAddr);
- }
- if (!ia.isAnyLocalAddress()) {
- linkProperties.addDnsServer(ia);
- }
- }
- } else {
- throw new UnknownHostException("Empty dns response and no system default dns");
- }
-
- // set pcscf
- if (response.getPcscfAddresses().size() > 0) {
- for (InetAddress pcscf : response.getPcscfAddresses()) {
- linkProperties.addPcscfServer(pcscf);
- }
- }
-
- for (InetAddress gateway : response.getGatewayAddresses()) {
- int mtu = gateway instanceof java.net.Inet6Address ? response.getMtuV6()
- : response.getMtuV4();
- // Allow 0.0.0.0 or :: as a gateway;
- // this indicates a point-to-point interface.
- linkProperties.addRoute(new RouteInfo(null, gateway, null,
- RouteInfo.RTN_UNICAST, mtu));
- }
-
- // set interface MTU
- // this may clobber the setting read from the APN db, but that's ok
- // TODO: remove once LinkProperties#setMtu is deprecated
- linkProperties.setMtu(response.getMtu());
-
- result = SetupResult.SUCCESS;
- } catch (UnknownHostException e) {
- log("setLinkProperties: UnknownHostException " + e);
- result = SetupResult.ERROR_INVALID_ARG;
- }
- } else {
- result = SetupResult.ERROR_DATA_SERVICE_SPECIFIC_ERROR;
- }
-
- // An error occurred so clear properties
- if (result != SetupResult.SUCCESS) {
- if (DBG) {
- log("setLinkProperties: error clearing LinkProperties status="
- + response.getCause() + " result=" + result);
- }
- linkProperties.clear();
- }
-
- return result;
- }
-
- /**
- * Initialize connection, this will fail if the
- * apnSettings are not compatible.
- *
- * @param cp the Connection parameters
- * @return true if initialization was successful.
- */
- private boolean initConnection(ConnectionParams cp) {
- ApnContext apnContext = cp.mApnContext;
- if (mApnSetting == null) {
- // Only change apn setting if it isn't set, it will
- // only NOT be set only if we're in DcInactiveState.
- mApnSetting = apnContext.getApnSetting();
- }
- if (mApnSetting == null || (!mApnSetting.canHandleType(apnContext.getApnTypeBitmask())
- && apnContext.getApnTypeBitmask() != ApnSetting.TYPE_ENTERPRISE)) {
- if (DBG) {
- log("initConnection: incompatible apnSetting in ConnectionParams cp=" + cp
- + " dc=" + DataConnection.this);
- }
- return false;
- }
- mTag += 1;
- mConnectionParams = cp;
- mConnectionParams.mTag = mTag;
-
- // always update the ConnectionParams with the latest or the
- // connectionGeneration gets stale
- mApnContexts.put(apnContext, cp);
-
- if (DBG) {
- log("initConnection: "
- + " RefCount=" + mApnContexts.size()
- + " mApnList=" + mApnContexts
- + " mConnectionParams=" + mConnectionParams);
- }
- return true;
- }
-
- /**
- * The parent state for all other states.
- */
- private class DcDefaultState extends State {
- @Override
- public void enter() {
- if (DBG) log("DcDefaultState: enter");
-
- // Register for DRS or RAT change
- mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(
- mTransportType, getHandler(),
- DataConnection.EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED, null);
-
- mPhone.getServiceStateTracker().registerForDataRoamingOn(getHandler(),
- DataConnection.EVENT_DATA_CONNECTION_ROAM_ON, null);
- mPhone.getServiceStateTracker().registerForDataRoamingOff(getHandler(),
- DataConnection.EVENT_DATA_CONNECTION_ROAM_OFF, null, true);
- mPhone.getServiceStateTracker().registerForNrStateChanged(getHandler(),
- DataConnection.EVENT_NR_STATE_CHANGED, null);
- mPhone.getServiceStateTracker().registerForNrFrequencyChanged(getHandler(),
- DataConnection.EVENT_NR_FREQUENCY_CHANGED, null);
- mPhone.getServiceStateTracker().registerForCssIndicatorChanged(getHandler(),
- DataConnection.EVENT_CSS_INDICATOR_CHANGED, null);
- if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR_KEY)) {
- mPhone.getLinkBandwidthEstimator().registerForBandwidthChanged(getHandler(),
- DataConnection.EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE, null);
- }
-
- // Add ourselves to the list of data connections
- mDcController.addDc(DataConnection.this);
- }
- @Override
- public void exit() {
- if (DBG) log("DcDefaultState: exit");
-
- // Unregister for DRS or RAT change.
- mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged(
- mTransportType, getHandler());
-
- mPhone.getServiceStateTracker().unregisterForDataRoamingOn(getHandler());
- mPhone.getServiceStateTracker().unregisterForDataRoamingOff(getHandler());
- mPhone.getServiceStateTracker().unregisterForNrStateChanged(getHandler());
- mPhone.getServiceStateTracker().unregisterForNrFrequencyChanged(getHandler());
- mPhone.getServiceStateTracker().unregisterForCssIndicatorChanged(getHandler());
- if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR_KEY)) {
- mPhone.getLinkBandwidthEstimator().unregisterForBandwidthChanged(getHandler());
- }
-
- // Remove ourselves from the DC lists
- mDcController.removeDc(DataConnection.this);
-
- if (mAc != null) {
- mAc.disconnected();
- mAc = null;
- }
- mApnContexts.clear();
- mReconnectIntent = null;
- mDct = null;
- mApnSetting = null;
- mPhone = null;
- mDataServiceManager = null;
- mLinkProperties = null;
- mLastFailCause = DataFailCause.NONE;
- mUserData = null;
- mDcController = null;
- mDcTesterFailBringUpAll = null;
- }
-
- @Override
- public boolean processMessage(Message msg) {
- boolean retVal = HANDLED;
-
- if (VDBG) {
- log("DcDefault msg=" + getWhatToString(msg.what)
- + " RefCount=" + mApnContexts.size());
- }
- switch (msg.what) {
- case EVENT_RESET:
- if (VDBG) log("DcDefaultState: msg.what=REQ_RESET");
- transitionTo(mInactiveState);
- break;
- case EVENT_CONNECT:
- if (DBG) log("DcDefaultState: msg.what=EVENT_CONNECT, fail not expected");
- ConnectionParams cp = (ConnectionParams) msg.obj;
- notifyConnectCompleted(cp, DataFailCause.UNKNOWN,
- DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN, false);
- break;
-
- case EVENT_DISCONNECT:
- case EVENT_DISCONNECT_ALL:
- case EVENT_REEVALUATE_RESTRICTED_STATE:
- if (DBG) {
- log("DcDefaultState deferring msg.what=" + getWhatToString(msg.what)
- + " RefCount=" + mApnContexts.size());
- }
- deferMessage(msg);
- break;
- case EVENT_TEAR_DOWN_NOW:
- if (DBG) log("DcDefaultState EVENT_TEAR_DOWN_NOW");
- mDataServiceManager.deactivateDataCall(mCid, DataService.REQUEST_REASON_NORMAL,
- null);
- mDataCallSessionStats.setDeactivateDataCallReason(
- DataService.REQUEST_REASON_NORMAL);
- break;
- case EVENT_LOST_CONNECTION:
- if (DBG) {
- String s = "DcDefaultState ignore EVENT_LOST_CONNECTION"
- + " tag=" + msg.arg1 + ":mTag=" + mTag;
- logAndAddLogRec(s);
- }
- break;
- case EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED:
- AsyncResult ar = (AsyncResult)msg.obj;
- Pair<Integer, Integer> drsRatPair = (Pair<Integer, Integer>)ar.result;
- mDataRegState = drsRatPair.first;
- updateTcpBufferSizes(drsRatPair.second);
- if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_CARRIER_CONFIG_KEY)) {
- updateLinkBandwidthsFromCarrierConfig(drsRatPair.second);
- }
- mRilRat = drsRatPair.second;
- if (DBG) {
- log("DcDefaultState: EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED"
- + " regState=" + ServiceState.rilServiceStateToString(mDataRegState)
- + " RAT=" + ServiceState.rilRadioTechnologyToString(mRilRat));
- }
- mDataCallSessionStats.onDrsOrRatChanged(
- ServiceState.rilRadioTechnologyToNetworkType(mRilRat));
- break;
-
- case EVENT_START_HANDOVER: //calls startHandover()
- if (DBG) {
- log("DcDefaultState: EVENT_START_HANDOVER not expected.");
- }
- Consumer<Integer> r = (Consumer<Integer>) msg.obj;
- r.accept(DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
- break;
- case EVENT_START_HANDOVER_ON_TARGET:
- if (DBG) {
- log("DcDefaultState: EVENT_START_HANDOVER not expected, but will "
- + "clean up, result code: "
- + DataServiceCallback.resultCodeToString(msg.arg1));
- }
- ((Consumer<Boolean>) msg.obj).accept(false /* is in correct state*/);
- break;
- case EVENT_CANCEL_HANDOVER:
- // We don't need to do anything in this case
- if (DBG) {
- log("DcDefaultState: EVENT_CANCEL_HANDOVER resultCode="
- + DataServiceCallback.resultCodeToString(msg.arg1));
- }
- break;
- case EVENT_RELEASE_PDU_SESSION_ID: {
- // We do the same thing in all state in order to preserve the existing workflow
- final AsyncResult asyncResult = (AsyncResult) msg.obj;
- if (asyncResult == null) {
- loge("EVENT_RELEASE_PDU_SESSION_ID: asyncResult is null!");
- } else {
- if (msg.obj != null) {
- if (DBG) logd("EVENT_RELEASE_PDU_SESSION_ID: id released");
- Runnable runnable = (Runnable) asyncResult.userObj;
- runnable.run();
- } else {
- loge("EVENT_RELEASE_PDU_SESSION_ID: no runnable set");
- }
- }
- retVal = HANDLED;
- break;
- }
- case EVENT_ALLOCATE_PDU_SESSION_ID: {
- // We do the same thing in all state in order to preserve the existing workflow
- final AsyncResult asyncResult = (AsyncResult) msg.obj;
- if (asyncResult == null) {
- loge("EVENT_ALLOCATE_PDU_SESSION_ID: asyncResult is null!");
- } else {
- Consumer<Integer> onAllocated = (Consumer<Integer>) asyncResult.userObj;
- if (asyncResult.exception != null) {
- loge("EVENT_ALLOCATE_PDU_SESSION_ID: exception",
- asyncResult.exception);
- onAllocated.accept(PDU_SESSION_ID_NOT_SET);
- } else if (asyncResult.result == null) {
- loge("EVENT_ALLOCATE_PDU_SESSION_ID: result null, no id");
- onAllocated.accept(PDU_SESSION_ID_NOT_SET);
- } else {
- int psi = (int) asyncResult.result;
- if (DBG) logd("EVENT_ALLOCATE_PDU_SESSION_ID: psi=" + psi);
- onAllocated.accept(psi);
- }
- }
- retVal = HANDLED;
- break;
- }
- default:
- if (DBG) {
- log("DcDefaultState: ignore msg.what=" + getWhatToString(msg.what));
- }
- break;
- }
-
- return retVal;
- }
- }
-
- private void updateSuspendState() {
- if (mNetworkAgent == null) {
- Rlog.d(getName(), "Setting suspend state without a NetworkAgent");
- }
-
- boolean newSuspendedState = false;
- // Data can only be (temporarily) suspended while data is in active state
- if (getCurrentState() == mActiveState) {
- // Never set suspended for emergency apn. Emergency data connection
- // can work while device is not in service.
- if (mApnSetting != null && mApnSetting.isEmergencyApn()) {
- newSuspendedState = false;
- // If we are not in service, change to suspended.
- } else if (mDataRegState != ServiceState.STATE_IN_SERVICE) {
- newSuspendedState = true;
- // Check voice/data concurrency.
- } else if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
- newSuspendedState = mPhone.getCallTracker().getState() != PhoneConstants.State.IDLE;
- }
- }
-
- // Only notify when there is a change.
- if (mIsSuspended != newSuspendedState) {
- mIsSuspended = newSuspendedState;
-
- // If data connection is active, we need to notify the new data connection state
- // changed event reflecting the latest suspended state.
- if (isActive()) {
- notifyDataConnectionState();
- }
- }
- }
-
- private void notifyDataConnectionState() {
- // The receivers of this have no way to differentiate between default and enterprise
- // connections. Do not notify for enterprise.
- if (!isEnterpriseUse()) {
- mPhone.notifyDataConnection(getPreciseDataConnectionState());
- } else {
- log("notifyDataConnectionState: Skipping for enterprise; state=" + getState());
- }
- }
-
- private DcDefaultState mDefaultState = new DcDefaultState();
-
- private int getApnTypeBitmask() {
- return isEnterpriseUse() ? ApnSetting.TYPE_ENTERPRISE :
- mApnSetting != null ? mApnSetting.getApnTypeBitmask() : 0;
- }
-
- private boolean canHandleDefault() {
- return !isEnterpriseUse() && mApnSetting != null
- ? mApnSetting.canHandleType(ApnSetting.TYPE_DEFAULT) : false;
- }
-
- /**
- * The state machine is inactive and expects a EVENT_CONNECT.
- */
- private class DcInactiveState extends State {
- // Inform all contexts we've failed connecting
- public void setEnterNotificationParams(ConnectionParams cp, @DataFailureCause int cause,
- @HandoverFailureMode int handoverFailureMode) {
- if (VDBG) log("DcInactiveState: setEnterNotificationParams cp,cause");
- mConnectionParams = cp;
- mDisconnectParams = null;
- mDcFailCause = cause;
- mHandoverFailureMode = handoverFailureMode;
- }
-
- // Inform all contexts we've failed disconnected
- public void setEnterNotificationParams(DisconnectParams dp) {
- if (VDBG) log("DcInactiveState: setEnterNotificationParams dp");
- mConnectionParams = null;
- mDisconnectParams = dp;
- mDcFailCause = DataFailCause.NONE;
- }
-
- // Inform all contexts of the failure cause
- public void setEnterNotificationParams(@DataFailureCause int cause) {
- mConnectionParams = null;
- mDisconnectParams = null;
- mDcFailCause = cause;
- }
-
- @Override
- public void enter() {
- mTag += 1;
- if (DBG) log("DcInactiveState: enter() mTag=" + mTag);
- TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED,
- TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED__STATE__INACTIVE,
- mPhone.getPhoneId(), mId, getApnTypeBitmask(), canHandleDefault());
- mDataCallSessionStats.onDataCallDisconnected(mDcFailCause);
- if (mHandoverState == HANDOVER_STATE_BEING_TRANSFERRED) {
- // This is from source data connection to set itself's state
- setHandoverState(HANDOVER_STATE_COMPLETED);
- }
-
- // Check for dangling agent. Ideally the handover source agent should be null if
- // handover process is smooth. When it's not null, that means handover failed. The
- // agent was not successfully transferred to the new data connection. We should
- // gracefully notify connectivity service the network was disconnected.
- if (mHandoverSourceNetworkAgent != null) {
- DataConnection sourceDc = mHandoverSourceNetworkAgent.getDataConnection();
- if (sourceDc != null) {
- // If the source data connection still owns this agent, then just reset the
- // handover state back to idle because handover is already failed.
- mHandoverLocalLog.log(
- "Handover failed. Reset the source dc " + sourceDc.getName()
- + " state to idle");
- sourceDc.cancelHandover();
- } else {
- // The agent is now a dangling agent. No data connection owns this agent.
- // Gracefully notify connectivity service disconnected.
- mHandoverLocalLog.log(
- "Handover failed and dangling agent found.");
- mHandoverSourceNetworkAgent.acquireOwnership(
- DataConnection.this, mTransportType);
- log("Cleared dangling network agent. " + mHandoverSourceNetworkAgent);
- mHandoverSourceNetworkAgent.unregister(DataConnection.this);
- mHandoverSourceNetworkAgent.releaseOwnership(DataConnection.this);
- }
- mHandoverSourceNetworkAgent = null;
- }
-
- if (mConnectionParams != null) {
- if (DBG) {
- log("DcInactiveState: enter notifyConnectCompleted +ALL failCause="
- + DataFailCause.toString(mDcFailCause));
- }
- notifyConnectCompleted(mConnectionParams, mDcFailCause, mHandoverFailureMode,
- true);
- }
- if (mDisconnectParams != null) {
- if (DBG) {
- log("DcInactiveState: enter notifyDisconnectCompleted +ALL failCause="
- + DataFailCause.toString(mDcFailCause));
- }
- notifyDisconnectCompleted(mDisconnectParams, true);
- }
- if (mDisconnectParams == null && mConnectionParams == null
- && mDcFailCause != DataFailCause.NONE) {
- if (DBG) {
- log("DcInactiveState: enter notifyAllDisconnectCompleted failCause="
- + DataFailCause.toString(mDcFailCause));
- }
- notifyAllWithEvent(null, DctConstants.EVENT_DISCONNECT_DONE,
- DataFailCause.toString(mDcFailCause));
- }
-
- // Remove ourselves from cid mapping, before clearSettings
- mDcController.removeActiveDcByCid(DataConnection.this);
-
- // For the first time entering here (idle state before setup), do not notify
- // disconnected state. Only notify data connection disconnected for data that is
- // actually moving from disconnecting to disconnected, or setup failed. In both cases,
- // APN setting will not be null.
- if (mApnSetting != null) {
- notifyDataConnectionState();
- }
- clearSettings();
- }
-
- @Override
- public void exit() {
- }
-
- @Override
- public boolean processMessage(Message msg) {
- switch (msg.what) {
- case EVENT_RESET:
- case EVENT_REEVALUATE_RESTRICTED_STATE:
- if (DBG) {
- log("DcInactiveState: msg.what=" + getWhatToString(msg.what)
- + ", ignore we're already done");
- }
- return HANDLED;
- case EVENT_CONNECT:
- if (DBG) log("DcInactiveState: mag.what=EVENT_CONNECT");
- ConnectionParams cp = (ConnectionParams) msg.obj;
-
- if (!initConnection(cp)) {
- log("DcInactiveState: msg.what=EVENT_CONNECT initConnection failed");
- notifyConnectCompleted(cp, DataFailCause.UNACCEPTABLE_NETWORK_PARAMETER,
- DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN, false);
- transitionTo(mInactiveState);
- return HANDLED;
- }
-
- int cause = connect(cp);
- if (cause != DataFailCause.NONE) {
- log("DcInactiveState: msg.what=EVENT_CONNECT connect failed");
- notifyConnectCompleted(cp, cause,
- DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN, false);
- transitionTo(mInactiveState);
- return HANDLED;
- }
-
- if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
- mSubId = cp.mSubId;
- }
-
- transitionTo(mActivatingState);
- return HANDLED;
- case EVENT_DISCONNECT:
- if (DBG) log("DcInactiveState: msg.what=EVENT_DISCONNECT");
- notifyDisconnectCompleted((DisconnectParams)msg.obj, false);
- return HANDLED;
- case EVENT_DISCONNECT_ALL:
- if (DBG) log("DcInactiveState: msg.what=EVENT_DISCONNECT_ALL");
- notifyDisconnectCompleted((DisconnectParams)msg.obj, false);
- return HANDLED;
- default:
- if (VDBG) {
- log("DcInactiveState not handled msg.what=" + getWhatToString(msg.what));
- }
- return NOT_HANDLED;
- }
- }
- }
- private DcInactiveState mInactiveState = new DcInactiveState();
-
- /**
- * The state machine is activating a connection.
- */
- private class DcActivatingState extends State {
- @Override
- public void enter() {
- int apnTypeBitmask = getApnTypeBitmask();
- TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED,
- TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED__STATE__ACTIVATING,
- mPhone.getPhoneId(), mId, apnTypeBitmask, canHandleDefault());
- setHandoverState(HANDOVER_STATE_IDLE);
- // restricted evaluation depends on network requests from apnContext. The evaluation
- // should happen once entering connecting state rather than active state because it's
- // possible that restricted network request can be released during the connecting window
- // and if we wait for connection established, then we might mistakenly
- // consider it as un-restricted. ConnectivityService then will immediately
- // tear down the connection through networkAgent unwanted callback if all requests for
- // this connection are going away.
- mRestrictedNetworkOverride = shouldRestrictNetwork();
-
- CarrierPrivilegesTracker carrierPrivTracker = mPhone.getCarrierPrivilegesTracker();
- if (carrierPrivTracker != null) {
- carrierPrivTracker.registerCarrierPrivilegesListener(
- getHandler(), EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED, null);
- }
- notifyDataConnectionState();
- mDataCallSessionStats.onSetupDataCall(apnTypeBitmask);
- }
- @Override
- public boolean processMessage(Message msg) {
- boolean retVal;
- AsyncResult ar;
- ConnectionParams cp;
-
- if (DBG) log("DcActivatingState: msg=" + msgToString(msg));
- switch (msg.what) {
- case EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED:
- case EVENT_CONNECT:
- // Activating can't process until we're done.
- deferMessage(msg);
- retVal = HANDLED;
- break;
-
- case EVENT_SETUP_DATA_CONNECTION_DONE:
- cp = (ConnectionParams) msg.obj;
-
- DataCallResponse dataCallResponse =
- msg.getData().getParcelable(DataServiceManager.DATA_CALL_RESPONSE);
- SetupResult result = onSetupConnectionCompleted(msg.arg1, dataCallResponse, cp);
- if (result != SetupResult.ERROR_STALE) {
- if (mConnectionParams != cp) {
- loge("DcActivatingState: WEIRD mConnectionsParams:"+ mConnectionParams
- + " != cp:" + cp);
- }
- }
- if (DBG) {
- log("DcActivatingState onSetupConnectionCompleted result=" + result
- + " dc=" + DataConnection.this);
- }
- ApnContext.requestLog(
- cp.mApnContext, "onSetupConnectionCompleted result=" + result);
- switch (result) {
- case SUCCESS:
- // All is well
- mDcFailCause = DataFailCause.NONE;
- transitionTo(mActiveState);
- break;
- case ERROR_RADIO_NOT_AVAILABLE:
- // Vendor ril rejected the command and didn't connect.
- // Transition to inactive but send notifications after
- // we've entered the mInactive state.
- mInactiveState.setEnterNotificationParams(cp, result.mFailCause,
- 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.
- long retry = RetryManager.NO_SUGGESTED_RETRY_DELAY;
- if (cp.mApnContext != null) {
- retry = RetryManager.NO_RETRY;
- mDct.getDataThrottler().setRetryTime(
- cp.mApnContext.getApnTypeBitmask(),
- retry, DcTracker.REQUEST_TYPE_NORMAL);
- }
- String logStr = "DcActivatingState: "
- + DataFailCause.toString(result.mFailCause)
- + " retry=" + retry;
- if (DBG) log(logStr);
- ApnContext.requestLog(cp.mApnContext, logStr);
- mInactiveState.setEnterNotificationParams(cp, result.mFailCause,
- DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN);
- transitionTo(mInactiveState);
- break;
- case ERROR_NO_DEFAULT_CONNECTION:
- // TODO (b/180988471): Properly handle the case when a default data
- // connection doesn't exist (tear down connection and retry).
- // Currently, this just tears down the connection without retry.
- if (DBG) log("DcActivatingState: NO_DEFAULT_DATA");
- case ERROR_INVALID_ARG:
- // The addresses given from the RIL are bad
- tearDownData(cp);
- transitionTo(mDisconnectingErrorCreatingConnection);
- break;
- case ERROR_DATA_SERVICE_SPECIFIC_ERROR:
-
- // Retrieve the suggested retry delay from the modem and save it.
- // If the modem want us to retry the current APN again, it will
- // suggest a positive delay value (in milliseconds). Otherwise we'll get
- // NO_SUGGESTED_RETRY_DELAY here.
-
- long delay = getSuggestedRetryDelay(dataCallResponse);
- long retryTime = RetryManager.NO_SUGGESTED_RETRY_DELAY;
- if (delay == RetryManager.NO_RETRY) {
- retryTime = RetryManager.NO_RETRY;
- } else if (delay >= 0) {
- retryTime = SystemClock.elapsedRealtime() + delay;
- }
- int newRequestType = DcTracker.calculateNewRetryRequestType(
- mHandoverFailureMode, cp.mRequestType, mDcFailCause);
- mDct.getDataThrottler().setRetryTime(getApnTypeBitmask(),
- retryTime, newRequestType);
-
- String str = "DcActivatingState: ERROR_DATA_SERVICE_SPECIFIC_ERROR "
- + " delay=" + delay
- + " result=" + result
- + " result.isRadioRestartFailure="
- + DataFailCause.isRadioRestartFailure(mPhone.getContext(),
- result.mFailCause, mPhone.getSubId())
- + " isPermanentFailure=" +
- mDct.isPermanentFailure(result.mFailCause);
- if (DBG) log(str);
- ApnContext.requestLog(cp.mApnContext, str);
-
- // Save the cause. DcTracker.onDataSetupComplete will check this
- // failure cause and determine if we need to retry this APN later
- // or not.
- mInactiveState.setEnterNotificationParams(cp, result.mFailCause,
- dataCallResponse != null
- ? dataCallResponse.getHandoverFailureMode()
- : DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN);
- transitionTo(mInactiveState);
- break;
- case ERROR_STALE:
- loge("DcActivatingState: stale EVENT_SETUP_DATA_CONNECTION_DONE"
- + " tag:" + cp.mTag + " != mTag:" + mTag);
- break;
- default:
- throw new RuntimeException("Unknown SetupResult, should not happen");
- }
- retVal = HANDLED;
- mDataCallSessionStats
- .onSetupDataCallResponse(dataCallResponse,
- ServiceState.rilRadioTechnologyToNetworkType(cp.mRilRat),
- getApnTypeBitmask(), mApnSetting.getProtocol(),
- result.mFailCause);
- break;
- case EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED:
- AsyncResult asyncResult = (AsyncResult) msg.obj;
- int[] administratorUids = (int[]) asyncResult.result;
- mAdministratorUids = Arrays.copyOf(administratorUids, administratorUids.length);
- retVal = HANDLED;
- break;
- case EVENT_START_HANDOVER_ON_TARGET:
- //called after startHandover on target transport
- ((Consumer<Boolean>) msg.obj).accept(true /* is in correct state*/);
- retVal = HANDLED;
- break;
- case EVENT_CANCEL_HANDOVER:
- transitionTo(mInactiveState);
- retVal = HANDLED;
- break;
- default:
- if (VDBG) {
- log("DcActivatingState not handled msg.what=" +
- getWhatToString(msg.what) + " RefCount=" + mApnContexts.size());
- }
- retVal = NOT_HANDLED;
- break;
- }
- return retVal;
- }
- }
- private DcActivatingState mActivatingState = new DcActivatingState();
-
- /**
- * The state machine is connected, expecting an EVENT_DISCONNECT.
- */
- private class DcActiveState extends State {
-
- @Override public void enter() {
- if (DBG) log("DcActiveState: enter dc=" + DataConnection.this);
- TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED,
- TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED__STATE__ACTIVE,
- mPhone.getPhoneId(), mId, getApnTypeBitmask(), canHandleDefault());
- // If we were retrying there maybe more than one, otherwise they'll only be one.
- notifyAllWithEvent(null, DctConstants.EVENT_DATA_SETUP_COMPLETE,
- Phone.REASON_CONNECTED);
-
- mPhone.getCallTracker().registerForVoiceCallStarted(getHandler(),
- DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_STARTED, null);
- mPhone.getCallTracker().registerForVoiceCallEnded(getHandler(),
- DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_ENDED, null);
-
- // If the EVENT_CONNECT set the current max retry restore it here
- // if it didn't then this is effectively a NOP.
- mDcController.addActiveDcByCid(DataConnection.this);
-
- updateTcpBufferSizes(mRilRat);
- updateLinkBandwidthsFromCarrierConfig(mRilRat);
-
- 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
- .ACTION_CARRIER_SIGNAL_REDIRECTED)) {
- // carrierSignal Receivers will place the carrier-specific provisioning notification
- configBuilder.setProvisioningNotificationEnabled(false);
- }
-
- final String subscriberId = mPhone.getSubscriberId();
- if (!TextUtils.isEmpty(subscriberId)) {
- configBuilder.setSubscriberId(subscriberId);
- }
-
- // set skip464xlat if it is not default otherwise
- if (shouldSkip464Xlat()) {
- configBuilder.setNat64DetectionEnabled(false);
- }
-
- mUnmeteredUseOnly = isUnmeteredUseOnly();
- mMmsUseOnly = isMmsUseOnly();
- mEnterpriseUse = isEnterpriseUse();
-
- if (DBG) {
- log("mRestrictedNetworkOverride = " + mRestrictedNetworkOverride
- + ", mUnmeteredUseOnly = " + mUnmeteredUseOnly
- + ", mMmsUseOnly = " + mMmsUseOnly
- + ", mEnterpriseUse = " + mEnterpriseUse);
- }
-
- // Always register a VcnNetworkPolicyChangeListener, regardless of whether this is a
- // handover
- // or new Network.
- mVcnManager.addVcnNetworkPolicyChangeListener(
- new HandlerExecutor(getHandler()), mVcnPolicyChangeListener);
-
- if (mConnectionParams != null
- && mConnectionParams.mRequestType == REQUEST_TYPE_HANDOVER) {
- // If this is a data setup for handover, we need to reuse the existing network agent
- // instead of creating a new one. This should be transparent to connectivity
- // service.
- DcTracker dcTracker = mPhone.getDcTracker(getHandoverSourceTransport());
- DataConnection dc = dcTracker.getDataConnectionByApnType(
- mConnectionParams.mApnContext.getApnType());
- // It's possible that the source data connection has been disconnected by the modem
- // already. If not, set its handover state to completed.
- if (dc != null) {
- // Transfer network agent from the original data connection as soon as the
- // new handover data connection is connected.
- dc.setHandoverState(HANDOVER_STATE_COMPLETED);
- }
-
- if (mHandoverSourceNetworkAgent != null) {
- String logStr = "Transfer network agent " + mHandoverSourceNetworkAgent.getTag()
- + " successfully.";
- log(logStr);
- mHandoverLocalLog.log(logStr);
- mNetworkAgent = mHandoverSourceNetworkAgent;
- mNetworkAgent.acquireOwnership(DataConnection.this, mTransportType);
-
- // TODO: Should evaluate mDisabledApnTypeBitMask again after handover. We don't
- // do it now because connectivity service does not support dynamically removing
- // immutable capabilities.
-
- mNetworkAgent.updateLegacySubtype(DataConnection.this);
- // Update the capability after handover
- mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
- DataConnection.this);
- mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this);
- mHandoverSourceNetworkAgent = null;
- } else {
- String logStr = "Failed to get network agent from original data connection";
- loge(logStr);
- mHandoverLocalLog.log(logStr);
- return;
- }
- } else {
- mScore = calculateScore();
- final NetworkFactory factory = PhoneFactory.getNetworkFactory(
- mPhone.getPhoneId());
- final NetworkProvider provider = (null == factory) ? null : factory.getProvider();
-
- mDisabledApnTypeBitMask |= getDisallowedApnTypes();
- updateLinkPropertiesHttpProxy();
- mNetworkAgent = new DcNetworkAgent(DataConnection.this, mPhone, mScore,
- configBuilder.build(), provider, mTransportType);
-
- VcnNetworkPolicyResult policyResult =
- mVcnManager.applyVcnNetworkPolicy(
- getNetworkCapabilities(), getLinkProperties());
- if (policyResult.isTeardownRequested()) {
- tearDownAll(
- Phone.REASON_VCN_REQUESTED_TEARDOWN,
- DcTracker.RELEASE_TYPE_DETACH,
- null /* onCompletedMsg */);
- } else {
- // All network agents start out in CONNECTING mode, but DcNetworkAgents are
- // created when the network is already connected. Hence, send the connected
- // notification immediately.
- mNetworkAgent.markConnected();
- }
-
- // The network agent is always created with NOT_SUSPENDED capability, but the
- // network might be already out of service (or voice call is ongoing) just right
- // before data connection is created. Connectivity service would not allow a network
- // created with suspended state, so we create a non-suspended network first, and
- // then immediately evaluate the suspended state.
- sendMessage(obtainMessage(EVENT_UPDATE_SUSPENDED_STATE));
- }
-
- // The qos parameters are set when the call is connected
- syncQosToNetworkAgent();
-
- if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
- mPhone.mCi.registerForNattKeepaliveStatus(
- getHandler(), DataConnection.EVENT_KEEPALIVE_STATUS, null);
- mPhone.mCi.registerForLceInfo(
- getHandler(), DataConnection.EVENT_LINK_CAPACITY_CHANGED, null);
- }
- notifyDataConnectionState();
- TelephonyMetrics.getInstance().writeRilDataCallEvent(mPhone.getPhoneId(),
- mCid, getApnTypeBitmask(), RilDataCall.State.CONNECTED);
- }
-
- @Override
- public void exit() {
- if (DBG) log("DcActiveState: exit dc=" + this);
- mPhone.getCallTracker().unregisterForVoiceCallStarted(getHandler());
- mPhone.getCallTracker().unregisterForVoiceCallEnded(getHandler());
-
- if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
- mPhone.mCi.unregisterForNattKeepaliveStatus(getHandler());
- mPhone.mCi.unregisterForLceInfo(getHandler());
- }
-
- // If we are still owning this agent, then we should inform connectivity service the
- // data connection is disconnected. There is one exception that we shouldn't unregister,
- // which is when IWLAN handover is ongoing. Instead of unregistering, the agent will
- // be transferred to the new data connection on the other transport.
- if (mNetworkAgent != null) {
- syncQosToNetworkAgent();
- if (mHandoverState == HANDOVER_STATE_IDLE) {
- mNetworkAgent.unregister(DataConnection.this);
- }
- mNetworkAgent.releaseOwnership(DataConnection.this);
- }
- mNetworkAgent = null;
-
- TelephonyMetrics.getInstance().writeRilDataCallEvent(mPhone.getPhoneId(),
- mCid, getApnTypeBitmask(), RilDataCall.State.DISCONNECTED);
-
- mVcnManager.removeVcnNetworkPolicyChangeListener(mVcnPolicyChangeListener);
-
- CarrierPrivilegesTracker carrierPrivTracker = mPhone.getCarrierPrivilegesTracker();
- if (carrierPrivTracker != null) {
- carrierPrivTracker.unregisterCarrierPrivilegesListener(getHandler());
- }
- }
-
- @Override
- public boolean processMessage(Message msg) {
- boolean retVal;
-
- switch (msg.what) {
- case EVENT_CONNECT: {
- ConnectionParams cp = (ConnectionParams) msg.obj;
- // either add this new apn context to our set or
- // update the existing cp with the latest connection generation number
- mApnContexts.put(cp.mApnContext, cp);
- // TODO (b/118347948): evaluate if it's still needed after assigning
- // different scores to different Cellular network.
- mDisabledApnTypeBitMask &= ~cp.mApnContext.getApnTypeBitmask();
- mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
- DataConnection.this);
- if (DBG) {
- log("DcActiveState: EVENT_CONNECT cp=" + cp + " dc=" + DataConnection.this);
- }
- notifyConnectCompleted(cp, DataFailCause.NONE,
- DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN, false);
- retVal = HANDLED;
- break;
- }
- case EVENT_DISCONNECT: {
- DisconnectParams dp = (DisconnectParams) msg.obj;
- if (DBG) {
- log("DcActiveState: EVENT_DISCONNECT dp=" + dp
- + " dc=" + DataConnection.this);
- }
- if (mApnContexts.containsKey(dp.mApnContext)) {
- if (DBG) {
- log("DcActiveState msg.what=EVENT_DISCONNECT RefCount="
- + mApnContexts.size());
- }
-
- if (mApnContexts.size() == 1) {
- mApnContexts.clear();
- mDisconnectParams = dp;
- mConnectionParams = null;
- dp.mTag = mTag;
- tearDownData(dp);
- transitionTo(mDisconnectingState);
- } else {
- mApnContexts.remove(dp.mApnContext);
- // TODO (b/118347948): evaluate if it's still needed after assigning
- // different scores to different Cellular network.
- mDisabledApnTypeBitMask |= dp.mApnContext.getApnTypeBitmask();
- mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
- DataConnection.this);
- notifyDisconnectCompleted(dp, false);
- }
- } else {
- log("DcActiveState ERROR no such apnContext=" + dp.mApnContext
- + " in this dc=" + DataConnection.this);
- notifyDisconnectCompleted(dp, false);
- }
- retVal = HANDLED;
- break;
- }
- case EVENT_DISCONNECT_ALL: {
- if (DBG) {
- log("DcActiveState EVENT_DISCONNECT clearing apn contexts,"
- + " dc=" + DataConnection.this);
- }
- DisconnectParams dp = (DisconnectParams) msg.obj;
- mDisconnectParams = dp;
- mConnectionParams = null;
- dp.mTag = mTag;
- tearDownData(dp);
- transitionTo(mDisconnectingState);
- retVal = HANDLED;
- break;
- }
- case EVENT_LOST_CONNECTION: {
- if (DBG) {
- log("DcActiveState EVENT_LOST_CONNECTION dc=" + DataConnection.this);
- }
-
- mInactiveState.setEnterNotificationParams(DataFailCause.LOST_CONNECTION);
- transitionTo(mInactiveState);
- retVal = HANDLED;
- break;
- }
- case EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED: {
- AsyncResult ar = (AsyncResult) msg.obj;
- Pair<Integer, Integer> drsRatPair = (Pair<Integer, Integer>) ar.result;
- mDataRegState = drsRatPair.first;
- updateTcpBufferSizes(drsRatPair.second);
- if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_CARRIER_CONFIG_KEY)) {
- updateLinkBandwidthsFromCarrierConfig(drsRatPair.second);
- }
- mRilRat = drsRatPair.second;
- if (DBG) {
- log("DcActiveState: EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED"
- + " drs=" + mDataRegState
- + " mRilRat=" + mRilRat);
- }
- updateSuspendState();
- if (mNetworkAgent != null) {
- mNetworkAgent.updateLegacySubtype(DataConnection.this);
- // The new suspended state will be passed through connectivity service
- // through NET_CAPABILITY_NOT_SUSPENDED.
- mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
- DataConnection.this);
- mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this);
- }
- retVal = HANDLED;
- mDataCallSessionStats.onDrsOrRatChanged(
- ServiceState.rilRadioTechnologyToNetworkType(mRilRat));
- break;
- }
- case EVENT_NR_FREQUENCY_CHANGED:
- // fallthrough
- case EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED:
- if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_CARRIER_CONFIG_KEY)) {
- updateLinkBandwidthsFromCarrierConfig(mRilRat);
- }
- if (mNetworkAgent != null) {
- mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
- DataConnection.this);
- }
- retVal = HANDLED;
- break;
- case EVENT_DATA_CONNECTION_METEREDNESS_CHANGED:
- boolean isUnmetered = (boolean) msg.obj;
- if (isUnmetered == mUnmeteredOverride) {
- retVal = HANDLED;
- break;
- }
- mUnmeteredOverride = isUnmetered;
- if (mNetworkAgent != null) {
- mNetworkAgent.updateLegacySubtype(DataConnection.this);
- mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
- DataConnection.this);
- }
- retVal = HANDLED;
- break;
- case EVENT_DATA_CONNECTION_CONGESTEDNESS_CHANGED:
- boolean isCongested = (boolean) msg.obj;
- if (isCongested == mCongestedOverride) {
- retVal = HANDLED;
- break;
- }
- mCongestedOverride = isCongested;
- if (mNetworkAgent != null) {
- mNetworkAgent.updateLegacySubtype(DataConnection.this);
- mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
- DataConnection.this);
- }
- retVal = HANDLED;
- break;
- case EVENT_DATA_CONNECTION_ROAM_ON:
- case EVENT_DATA_CONNECTION_ROAM_OFF: {
- if (mNetworkAgent != null) {
- mNetworkAgent.updateLegacySubtype(DataConnection.this);
- mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
- DataConnection.this);
- }
- retVal = HANDLED;
- break;
- }
- case EVENT_DATA_CONNECTION_VOICE_CALL_STARTED:
- case EVENT_DATA_CONNECTION_VOICE_CALL_ENDED:
- case EVENT_CSS_INDICATOR_CHANGED:
- case EVENT_UPDATE_SUSPENDED_STATE: {
- updateSuspendState();
- if (mNetworkAgent != null) {
- mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
- DataConnection.this);
- }
- retVal = HANDLED;
- break;
- }
- case EVENT_BW_REFRESH_RESPONSE: {
- AsyncResult ar = (AsyncResult)msg.obj;
- if (ar.exception != null) {
- log("EVENT_BW_REFRESH_RESPONSE: error ignoring, e=" + ar.exception);
- } else {
- if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_MODEM_KEY)) {
- updateLinkBandwidthsFromModem((List<LinkCapacityEstimate>) ar.result);
- }
- }
- retVal = HANDLED;
- break;
- }
- case EVENT_KEEPALIVE_START_REQUEST: {
- KeepalivePacketData pkt = (KeepalivePacketData) msg.obj;
- int slotId = msg.arg1;
- int intervalMillis = msg.arg2 * 1000;
- if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
- mPhone.mCi.startNattKeepalive(
- DataConnection.this.mCid, pkt, intervalMillis,
- DataConnection.this.obtainMessage(
- EVENT_KEEPALIVE_STARTED, slotId, 0, null));
- } else {
- // We currently do not support NATT Keepalive requests using the
- // DataService API, so unless the request is WWAN (always bound via
- // the CommandsInterface), the request cannot be honored.
- //
- // TODO: b/72331356 to add support for Keepalive to the DataService
- // so that keepalive requests can be handled (if supported) by the
- // underlying transport.
- if (mNetworkAgent != null) {
- mNetworkAgent.sendSocketKeepaliveEvent(
- msg.arg1, SocketKeepalive.ERROR_INVALID_NETWORK);
- }
- }
- retVal = HANDLED;
- break;
- }
- case EVENT_KEEPALIVE_STOP_REQUEST: {
- int slotId = msg.arg1;
- int handle = mNetworkAgent.keepaliveTracker.getHandleForSlot(slotId);
- if (handle < 0) {
- loge("No slot found for stopSocketKeepalive! " + slotId);
- mNetworkAgent.sendSocketKeepaliveEvent(
- slotId, SocketKeepalive.ERROR_NO_SUCH_SLOT);
- retVal = HANDLED;
- break;
- } else {
- logd("Stopping keepalive with handle: " + handle);
- }
-
- mPhone.mCi.stopNattKeepalive(
- handle, DataConnection.this.obtainMessage(
- EVENT_KEEPALIVE_STOPPED, handle, slotId, null));
- retVal = HANDLED;
- break;
- }
- case EVENT_KEEPALIVE_STARTED: {
- AsyncResult ar = (AsyncResult) msg.obj;
- final int slot = msg.arg1;
- if (ar.exception != null || ar.result == null) {
- loge("EVENT_KEEPALIVE_STARTED: error starting keepalive, e="
- + ar.exception);
- mNetworkAgent.sendSocketKeepaliveEvent(
- slot, SocketKeepalive.ERROR_HARDWARE_ERROR);
- } else {
- KeepaliveStatus ks = (KeepaliveStatus) ar.result;
- if (ks == null) {
- loge("Null KeepaliveStatus received!");
- } else {
- mNetworkAgent.keepaliveTracker.handleKeepaliveStarted(slot, ks);
- }
- }
- retVal = HANDLED;
- break;
- }
- case EVENT_KEEPALIVE_STATUS: {
- AsyncResult ar = (AsyncResult) msg.obj;
- if (ar.exception != null) {
- loge("EVENT_KEEPALIVE_STATUS: error in keepalive, e=" + ar.exception);
- // We have no way to notify connectivity in this case.
- }
- if (ar.result != null) {
- KeepaliveStatus ks = (KeepaliveStatus) ar.result;
- mNetworkAgent.keepaliveTracker.handleKeepaliveStatus(ks);
- }
-
- retVal = HANDLED;
- break;
- }
- case EVENT_KEEPALIVE_STOPPED: {
- AsyncResult ar = (AsyncResult) msg.obj;
- final int handle = msg.arg1;
- final int slotId = msg.arg2;
-
- if (ar.exception != null) {
- loge("EVENT_KEEPALIVE_STOPPED: error stopping keepalive for handle="
- + handle + " e=" + ar.exception);
- mNetworkAgent.keepaliveTracker.handleKeepaliveStatus(
- new KeepaliveStatus(KeepaliveStatus.ERROR_UNKNOWN));
- } else {
- log("Keepalive Stop Requested for handle=" + handle);
- mNetworkAgent.keepaliveTracker.handleKeepaliveStatus(
- new KeepaliveStatus(
- handle, KeepaliveStatus.STATUS_INACTIVE));
- }
- retVal = HANDLED;
- break;
- }
- case EVENT_LINK_CAPACITY_CHANGED: {
- AsyncResult ar = (AsyncResult) msg.obj;
- if (ar.exception != null) {
- loge("EVENT_LINK_CAPACITY_CHANGED e=" + ar.exception);
- } else {
- if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_MODEM_KEY)) {
- updateLinkBandwidthsFromModem((List<LinkCapacityEstimate>) ar.result);
- }
- }
- retVal = HANDLED;
- break;
- }
- case EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE: {
- AsyncResult ar = (AsyncResult) msg.obj;
- if (ar.exception != null) {
- loge("EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE e=" + ar.exception);
- } else {
- Pair<Integer, Integer> pair = (Pair<Integer, Integer>) ar.result;
- if (isBandwidthSourceKey(
- DctConstants.BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR_KEY)) {
- updateLinkBandwidthsFromBandwidthEstimator(pair.first, pair.second);
- }
- }
- retVal = HANDLED;
- break;
- }
- case EVENT_REEVALUATE_RESTRICTED_STATE: {
- // If the network was restricted, and now it does not need to be restricted
- // anymore, we should add the NET_CAPABILITY_NOT_RESTRICTED capability.
- if (mRestrictedNetworkOverride && !shouldRestrictNetwork()) {
- if (DBG) {
- log("Data connection becomes not-restricted. dc=" + this);
- }
- // Note we only do this when network becomes non-restricted. When a
- // non-restricted becomes restricted (e.g. users disable data, or turn off
- // data roaming), DCT will explicitly tear down the networks (because
- // connectivity service does not support force-close TCP connections today).
- // Also note that NET_CAPABILITY_NOT_RESTRICTED is an immutable capability
- // (see {@link NetworkCapabilities}) once we add it to the network, we can't
- // remove it through the entire life cycle of the connection.
- mRestrictedNetworkOverride = false;
- mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
- DataConnection.this);
- }
-
- // If the data does need to be unmetered use only (e.g. users turn on data, or
- // device is not roaming anymore assuming data roaming is off), then we can
- // dynamically add those metered APN type capabilities back. (But not the
- // other way around because most of the APN-type capabilities are immutable
- // capabilities.)
- if (mUnmeteredUseOnly && !isUnmeteredUseOnly()) {
- mUnmeteredUseOnly = false;
- mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
- DataConnection.this);
- }
-
- mMmsUseOnly = isMmsUseOnly();
-
- retVal = HANDLED;
- break;
- }
- case EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES: {
- // Update other properties like link properties if needed in future.
- updateScore();
- retVal = HANDLED;
- break;
- }
- case EVENT_NR_STATE_CHANGED: {
- updateTcpBufferSizes(mRilRat);
- if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_CARRIER_CONFIG_KEY)) {
- updateLinkBandwidthsFromCarrierConfig(mRilRat);
- }
- if (mNetworkAgent != null) {
- mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this);
- mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
- DataConnection.this);
- }
- retVal = HANDLED;
- break;
- }
- case EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED:
- AsyncResult asyncResult = (AsyncResult) msg.obj;
- int[] administratorUids = (int[]) asyncResult.result;
- mAdministratorUids = Arrays.copyOf(administratorUids, administratorUids.length);
-
- // Administrator UIDs changed, so update NetworkAgent with new
- // NetworkCapabilities
- if (mNetworkAgent != null) {
- mNetworkAgent.sendNetworkCapabilities(
- getNetworkCapabilities(), DataConnection.this);
- }
- retVal = HANDLED;
- break;
- case EVENT_START_HANDOVER: //calls startHandover()
- Consumer<Integer> r = (Consumer<Integer>) msg.obj;
- r.accept(msg.arg1);
- retVal = HANDLED;
- break;
-
- default:
- if (VDBG) {
- log("DcActiveState not handled msg.what=" + getWhatToString(msg.what));
- }
- retVal = NOT_HANDLED;
- break;
- }
- return retVal;
- }
- }
- private DcActiveState mActiveState = new DcActiveState();
-
- /**
- * The state machine is disconnecting.
- */
- private class DcDisconnectingState extends State {
- @Override
- public void enter() {
- TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED,
- TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED__STATE__DISCONNECTING,
- mPhone.getPhoneId(), mId, getApnTypeBitmask(), canHandleDefault());
- notifyDataConnectionState();
- }
- @Override
- public boolean processMessage(Message msg) {
- boolean retVal;
-
- switch (msg.what) {
- case EVENT_CONNECT:
- if (DBG) log("DcDisconnectingState msg.what=EVENT_CONNECT. Defer. RefCount = "
- + mApnContexts.size());
- deferMessage(msg);
- retVal = HANDLED;
- break;
-
- case EVENT_DEACTIVATE_DONE:
- DisconnectParams dp = (DisconnectParams) msg.obj;
-
- String str = "DcDisconnectingState msg.what=EVENT_DEACTIVATE_DONE RefCount="
- + mApnContexts.size();
-
- if (DBG) log(str);
- ApnContext.requestLog(dp.mApnContext, str);
-
- // Clear out existing qos sessions
- updateQosParameters(null);
-
- if (dp.mTag == mTag) {
- // Transition to inactive but send notifications after
- // we've entered the mInactive state.
- mInactiveState.setEnterNotificationParams(dp);
- transitionTo(mInactiveState);
- } else {
- if (DBG) log("DcDisconnectState stale EVENT_DEACTIVATE_DONE"
- + " dp.tag=" + dp.mTag + " mTag=" + mTag);
- }
- retVal = HANDLED;
- break;
-
- default:
- if (VDBG) {
- log("DcDisconnectingState not handled msg.what="
- + getWhatToString(msg.what));
- }
- retVal = NOT_HANDLED;
- break;
- }
- return retVal;
- }
- }
- private DcDisconnectingState mDisconnectingState = new DcDisconnectingState();
-
- /**
- * The state machine is disconnecting after an creating a connection.
- */
- private class DcDisconnectionErrorCreatingConnection extends State {
- @Override
- public void enter() {
- TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED,
- TelephonyStatsLog
- .MOBILE_CONNECTION_STATE_CHANGED__STATE__DISCONNECTION_ERROR_CREATING_CONNECTION,
- mPhone.getPhoneId(), mId, getApnTypeBitmask(), canHandleDefault());
- notifyDataConnectionState();
- }
- @Override
- public boolean processMessage(Message msg) {
- boolean retVal;
-
- switch (msg.what) {
- case EVENT_DEACTIVATE_DONE:
- ConnectionParams cp = (ConnectionParams) msg.obj;
- if (cp.mTag == mTag) {
- String str = "DcDisconnectionErrorCreatingConnection" +
- " msg.what=EVENT_DEACTIVATE_DONE";
- if (DBG) log(str);
- ApnContext.requestLog(cp.mApnContext, str);
-
- // Transition to inactive but send notifications after
- // we've entered the mInactive state.
- mInactiveState.setEnterNotificationParams(cp,
- DataFailCause.UNACCEPTABLE_NETWORK_PARAMETER,
- DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN);
- transitionTo(mInactiveState);
- } else {
- if (DBG) {
- log("DcDisconnectionErrorCreatingConnection stale EVENT_DEACTIVATE_DONE"
- + " dp.tag=" + cp.mTag + ", mTag=" + mTag);
- }
- }
- retVal = HANDLED;
- break;
-
- default:
- if (VDBG) {
- log("DcDisconnectionErrorCreatingConnection not handled msg.what="
- + getWhatToString(msg.what));
- }
- retVal = NOT_HANDLED;
- break;
- }
- return retVal;
- }
- }
- private DcDisconnectionErrorCreatingConnection mDisconnectingErrorCreatingConnection =
- new DcDisconnectionErrorCreatingConnection();
-
- /**
- * Bring up a connection to the apn and return an AsyncResult in onCompletedMsg.
- * Used for cellular networks that use Access Point Names (APN) such
- * as GSM networks.
- *
- * @param apnContext is the Access Point Name to bring up a connection to
- * @param profileId for the connection
- * @param rilRadioTechnology Radio technology for the data connection
- * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
- * With AsyncResult.userObj set to the original msg.obj,
- * AsyncResult.result = FailCause and AsyncResult.exception = Exception().
- * @param connectionGeneration used to track a single connection request so disconnects can get
- * ignored if obsolete.
- * @param requestType Data request type
- * @param subId the subscription id associated with this data connection.
- * @param isApnPreferred whether or not the apn is preferred.
- */
- public void bringUp(ApnContext apnContext, int profileId, int rilRadioTechnology,
- Message onCompletedMsg, int connectionGeneration,
- @RequestNetworkType int requestType, int subId, boolean isApnPreferred) {
- if (DBG) {
- log("bringUp: apnContext=" + apnContext + " onCompletedMsg=" + onCompletedMsg);
- }
-
- if (mApnSetting == null) {
- mApnSetting = apnContext.getApnSetting();
- }
-
- sendMessage(DataConnection.EVENT_CONNECT,
- new ConnectionParams(apnContext, profileId, rilRadioTechnology, onCompletedMsg,
- connectionGeneration, requestType, subId, isApnPreferred));
- }
-
- /**
- * Tear down the connection through the apn on the network.
- *
- * @param apnContext APN context
- * @param reason reason to tear down
- * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
- * With AsyncResult.userObj set to the original msg.obj.
- */
- public void tearDown(ApnContext apnContext, String reason, Message onCompletedMsg) {
- if (DBG) {
- log("tearDown: apnContext=" + apnContext + " reason=" + reason + " onCompletedMsg="
- + onCompletedMsg);
- }
- sendMessage(DataConnection.EVENT_DISCONNECT,
- new DisconnectParams(apnContext, reason, DcTracker.RELEASE_TYPE_DETACH,
- onCompletedMsg));
- }
-
- // ******* "public" interface
-
- /**
- * Used for testing purposes.
- */
- void tearDownNow() {
- if (DBG) log("tearDownNow()");
- sendMessage(obtainMessage(EVENT_TEAR_DOWN_NOW));
- }
-
- /**
- * Tear down the connection through the apn on the network. Ignores reference count and
- * and always tears down.
- *
- * @param releaseType Data release type
- * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
- * With AsyncResult.userObj set to the original msg.obj.
- */
- public void tearDownAll(String reason, @ReleaseNetworkType int releaseType,
- Message onCompletedMsg) {
- if (DBG) {
- log("tearDownAll: reason=" + reason + ", releaseType="
- + DcTracker.releaseTypeToString(releaseType));
- }
- sendMessage(DataConnection.EVENT_DISCONNECT_ALL,
- new DisconnectParams(null, reason, releaseType, onCompletedMsg));
- }
-
- /**
- * Reset the data connection to inactive state.
- */
- public void reset() {
- sendMessage(EVENT_RESET);
- if (DBG) log("reset");
- }
-
- /**
- * Re-evaluate the restricted state. If the restricted data connection does not need to be
- * restricted anymore, we need to dynamically change the network's capability.
- */
- void reevaluateRestrictedState() {
- sendMessage(EVENT_REEVALUATE_RESTRICTED_STATE);
- if (DBG) log("reevaluate restricted state");
- }
-
- /**
- * Re-evaluate the data connection properties. For example, it will recalculate data connection
- * score and update through network agent it if changed.
- */
- void reevaluateDataConnectionProperties() {
- sendMessage(EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES);
- if (DBG) log("reevaluate data connection properties");
- }
-
- /**
- * @return The parameters used for initiating a data connection.
- */
- public ConnectionParams getConnectionParams() {
- return mConnectionParams;
- }
-
- /**
- * Update PCSCF addresses
- *
- * @param response
- */
- public void updatePcscfAddr(DataCallResponse response) {
- mPcscfAddr = response.getPcscfAddresses().stream()
- .map(InetAddress::getHostAddress).toArray(String[]::new);
- }
-
- /**
- * @return The list of PCSCF addresses
- */
- public String[] getPcscfAddresses() {
- return mPcscfAddr;
- }
-
- /**
- * Using the result of the SETUP_DATA_CALL determine the retry delay.
- *
- * @param response The response from setup data call
- * @return {@link RetryManager#NO_SUGGESTED_RETRY_DELAY} if not suggested.
- * {@link RetryManager#NO_RETRY} if retry should not happen. Otherwise the delay in milliseconds
- * to the next SETUP_DATA_CALL.
- */
- private long getSuggestedRetryDelay(DataCallResponse response) {
- /** According to ril.h
- * The value < 0 means no value is suggested
- * The value 0 means retry should be done ASAP.
- * The value of Long.MAX_VALUE(0x7fffffffffffffff) means no retry.
- */
- if (response == null) {
- return RetryManager.NO_SUGGESTED_RETRY_DELAY;
- }
-
- long suggestedRetryTime = response.getRetryDurationMillis();
-
- // The value < 0 means no value is suggested
- if (suggestedRetryTime < 0) {
- if (DBG) log("No suggested retry delay.");
- return RetryManager.NO_SUGGESTED_RETRY_DELAY;
- } else if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)
- && suggestedRetryTime == Long.MAX_VALUE) {
- if (DBG) log("Network suggested not retrying.");
- return RetryManager.NO_RETRY;
- } else if (mPhone.getHalVersion().less(RIL.RADIO_HAL_VERSION_1_6)
- && suggestedRetryTime == Integer.MAX_VALUE) {
- if (DBG) log("Network suggested not retrying.");
- return RetryManager.NO_RETRY;
- }
-
- return suggestedRetryTime;
- }
-
- public List<ApnContext> getApnContexts() {
- return new ArrayList<>(mApnContexts.keySet());
- }
-
- /**
- * Return whether there is an ApnContext for the given type in this DataConnection.
- * @param type APN type to check
- * @param exclusive true if the given APN type should be the only APN type that exists
- * @return True if there is an ApnContext for the given type
- */
- private boolean isApnContextAttached(@ApnType int type, boolean exclusive) {
- boolean attached = mApnContexts.keySet().stream()
- .map(ApnContext::getApnTypeBitmask)
- .anyMatch(bitmask -> bitmask == type);
- if (exclusive) {
- attached &= mApnContexts.size() == 1;
- }
- return attached;
- }
-
- /** Get the network agent of the data connection */
- @Nullable
- DcNetworkAgent getNetworkAgent() {
- return mNetworkAgent;
- }
-
- void setHandoverState(@HandoverState int state) {
- if (mHandoverState != state) {
- String logStr = "State changed from " + handoverStateToString(mHandoverState)
- + " to " + handoverStateToString(state);
- mHandoverLocalLog.log(logStr);
- logd(logStr);
- mHandoverState = state;
- }
- }
-
- /** Sets the {@link DataCallSessionStats} mock for this data connection during unit testing. */
- @VisibleForTesting
- public void setDataCallSessionStats(DataCallSessionStats dataCallSessionStats) {
- mDataCallSessionStats = dataCallSessionStats;
- }
-
- /**
- * @return the string for msg.what as our info.
- */
- @Override
- protected String getWhatToString(int what) {
- return cmdToString(what);
- }
-
- private static String msgToString(Message msg) {
- String retVal;
- if (msg == null) {
- retVal = "null";
- } else {
- StringBuilder b = new StringBuilder();
-
- b.append("{what=");
- b.append(cmdToString(msg.what));
-
- b.append(" when=");
- TimeUtils.formatDuration(msg.getWhen() - SystemClock.uptimeMillis(), b);
-
- if (msg.arg1 != 0) {
- b.append(" arg1=");
- b.append(msg.arg1);
- }
-
- if (msg.arg2 != 0) {
- b.append(" arg2=");
- b.append(msg.arg2);
- }
-
- if (msg.obj != null) {
- b.append(" obj=");
- b.append(msg.obj);
- }
-
- b.append(" target=");
- b.append(msg.getTarget());
-
- b.append(" replyTo=");
- b.append(msg.replyTo);
-
- b.append("}");
-
- retVal = b.toString();
- }
- return retVal;
- }
-
- static void slog(String s) {
- Rlog.d("DC", s);
- }
-
- /**
- * Log with debug
- *
- * @param s is string log
- */
- @Override
- protected void log(String s) {
- Rlog.d(getName(), s);
- }
-
- /**
- * Log with debug attribute
- *
- * @param s is string log
- */
- @Override
- protected void logd(String s) {
- Rlog.d(getName(), s);
- }
-
- /**
- * Log with verbose attribute
- *
- * @param s is string log
- */
- @Override
- protected void logv(String s) {
- Rlog.v(getName(), s);
- }
-
- /**
- * Log with info attribute
- *
- * @param s is string log
- */
- @Override
- protected void logi(String s) {
- Rlog.i(getName(), s);
- }
-
- /**
- * Log with warning attribute
- *
- * @param s is string log
- */
- @Override
- protected void logw(String s) {
- Rlog.w(getName(), s);
- }
-
- /**
- * Log with error attribute
- *
- * @param s is string log
- */
- @Override
- protected void loge(String s) {
- Rlog.e(getName(), s);
- }
-
- /**
- * Log with error attribute
- *
- * @param s is string log
- * @param e is a Throwable which logs additional information.
- */
- @Override
- protected void loge(String s, Throwable e) {
- Rlog.e(getName(), s, e);
- }
-
- /** Doesn't print mApnList of ApnContext's which would be recursive */
- public synchronized String toStringSimple() {
- return getName() + ": State=" + getCurrentState().getName()
- + " mApnSetting=" + mApnSetting + " RefCount=" + mApnContexts.size()
- + " mCid=" + mCid + " mCreateTime=" + mCreateTime
- + " mLastastFailTime=" + mLastFailTime
- + " mLastFailCause=" + DataFailCause.toString(mLastFailCause)
- + " mTag=" + mTag
- + " mLinkProperties=" + mLinkProperties
- + " linkCapabilities=" + getNetworkCapabilities()
- + " mRestrictedNetworkOverride=" + mRestrictedNetworkOverride;
- }
-
- @Override
- public String toString() {
- return "{" + toStringSimple() + " mApnContexts=" + mApnContexts + "}";
- }
-
- /** Check if the device is connected to NR 5G Non-Standalone network. */
- private boolean isNRConnected() {
- return mPhone.getServiceState().getNrState()
- == NetworkRegistrationInfo.NR_STATE_CONNECTED;
- }
-
- /**
- * @return The disallowed APN types bitmask
- */
- private @ApnType int getDisallowedApnTypes() {
- CarrierConfigManager configManager = (CarrierConfigManager)
- mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
- int apnTypesBitmask = 0;
- if (configManager != null) {
- PersistableBundle bundle = configManager.getConfigForSubId(mSubId);
- if (bundle != null) {
- String key = (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
- ? CarrierConfigManager.KEY_CARRIER_WWAN_DISALLOWED_APN_TYPES_STRING_ARRAY
- : CarrierConfigManager.KEY_CARRIER_WLAN_DISALLOWED_APN_TYPES_STRING_ARRAY;
- if (bundle.getStringArray(key) != null) {
- String disallowedApnTypesString =
- TextUtils.join(",", bundle.getStringArray(key));
- if (!TextUtils.isEmpty(disallowedApnTypesString)) {
- apnTypesBitmask = ApnSetting.getApnTypesBitmaskFromString(
- disallowedApnTypesString);
- }
- }
- }
- }
-
- return apnTypesBitmask;
- }
-
- private void dumpToLog() {
- dump(null, new PrintWriter(new StringWriter(0)) {
- @Override
- public void println(String s) {
- DataConnection.this.logd(s);
- }
-
- @Override
- public void flush() {
- }
- }, null);
- }
-
- /**
- * Re-calculate score and update through network agent if it changes.
- */
- private void updateScore() {
- int oldScore = mScore;
- mScore = calculateScore();
- if (oldScore != mScore && mNetworkAgent != null) {
- log("Updating score from " + oldScore + " to " + mScore);
- mNetworkAgent.sendNetworkScore(mScore, this);
- }
- }
-
- private int calculateScore() {
- int score = OTHER_CONNECTION_SCORE;
-
- // If it's serving a network request that asks NET_CAPABILITY_INTERNET and doesn't have
- // specify a subId, this dataConnection is considered to be default Internet data
- // connection. In this case we assign a slightly higher score of 50. The intention is
- // it will not be replaced by other data connections accidentally in DSDS usecase.
- for (ApnContext apnContext : mApnContexts.keySet()) {
- for (NetworkRequest networkRequest : apnContext.getNetworkRequests()) {
- if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
- && networkRequest.getNetworkSpecifier() == null) {
- score = DEFAULT_INTERNET_CONNECTION_SCORE;
- break;
- }
- }
- }
-
- return score;
- }
-
- private String handoverStateToString(@HandoverState int state) {
- switch (state) {
- case HANDOVER_STATE_IDLE: return "IDLE";
- case HANDOVER_STATE_BEING_TRANSFERRED: return "BEING_TRANSFERRED";
- case HANDOVER_STATE_COMPLETED: return "COMPLETED";
- default: return "UNKNOWN";
- }
- }
-
- private @DataState int getState() {
- if (isInactive()) {
- return TelephonyManager.DATA_DISCONNECTED;
- } else if (isActivating()) {
- return TelephonyManager.DATA_CONNECTING;
- } else if (isActive()) {
- // The data connection can only be suspended when it's in active state.
- if (mIsSuspended) {
- return TelephonyManager.DATA_SUSPENDED;
- }
- return TelephonyManager.DATA_CONNECTED;
- } else if (isDisconnecting()) {
- return TelephonyManager.DATA_DISCONNECTING;
- }
-
- return TelephonyManager.DATA_UNKNOWN;
- }
-
- /**
- * Get precise data connection state
- *
- * @return The {@link PreciseDataConnectionState}
- */
- public PreciseDataConnectionState getPreciseDataConnectionState() {
- return new PreciseDataConnectionState.Builder()
- .setTransportType(mTransportType)
- .setId(mCid)
- .setState(getState())
- .setApnSetting(mApnSetting)
- .setLinkProperties(mLinkProperties)
- .setNetworkType(getNetworkType())
- .setFailCause(mDcFailCause)
- .build();
- }
-
- /**
- * Dump the current state.
- *
- * @param fd
- * @param printWriter
- * @param args
- */
- @Override
- public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
- IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " ");
- pw.print("DataConnection ");
- super.dump(fd, pw, args);
- pw.flush();
- pw.increaseIndent();
- pw.println("transport type="
- + AccessNetworkConstants.transportTypeToString(mTransportType));
- pw.println("mApnContexts.size=" + mApnContexts.size());
- pw.println("mApnContexts=" + mApnContexts);
- pw.println("mApnSetting=" + mApnSetting);
- pw.println("mTag=" + mTag);
- pw.println("mCid=" + mCid);
- pw.println("mConnectionParams=" + mConnectionParams);
- pw.println("mDisconnectParams=" + mDisconnectParams);
- pw.println("mDcFailCause=" + DataFailCause.toString(mDcFailCause));
- pw.println("mPhone=" + mPhone);
- pw.println("mSubId=" + mSubId);
- pw.println("mLinkProperties=" + mLinkProperties);
- pw.flush();
- pw.println("mDataRegState=" + mDataRegState);
- pw.println("mHandoverState=" + handoverStateToString(mHandoverState));
- pw.println("mRilRat=" + mRilRat);
- pw.println("mNetworkCapabilities=" + getNetworkCapabilities());
- pw.println("mCreateTime=" + TimeUtils.logTimeOfDay(mCreateTime));
- pw.println("mLastFailTime=" + TimeUtils.logTimeOfDay(mLastFailTime));
- pw.println("mLastFailCause=" + DataFailCause.toString(mLastFailCause));
- pw.println("mUserData=" + mUserData);
- pw.println("mRestrictedNetworkOverride=" + mRestrictedNetworkOverride);
- pw.println("mUnmeteredUseOnly=" + mUnmeteredUseOnly);
- pw.println("mMmsUseOnly=" + mMmsUseOnly);
- pw.println("mEnterpriseUse=" + mEnterpriseUse);
- pw.println("mUnmeteredOverride=" + mUnmeteredOverride);
- pw.println("mCongestedOverride=" + mCongestedOverride);
- pw.println("mDownlinkBandwidth" + mDownlinkBandwidth);
- pw.println("mUplinkBandwidth=" + mUplinkBandwidth);
- pw.println("mDefaultQos=" + mDefaultQos);
- pw.println("mQosBearerSessions=" + mQosBearerSessions);
- pw.println("disallowedApnTypes="
- + ApnSetting.getApnTypesStringFromBitmask(getDisallowedApnTypes()));
- pw.println("mInstanceNumber=" + mInstanceNumber);
- pw.println("mAc=" + mAc);
- pw.println("mScore=" + mScore);
- if (mNetworkAgent != null) {
- mNetworkAgent.dump(fd, pw, args);
- }
- pw.println("handover local log:");
- pw.increaseIndent();
- mHandoverLocalLog.dump(fd, pw, args);
- pw.decreaseIndent();
- pw.decreaseIndent();
- pw.println();
- pw.flush();
- }
-
- /**
- * Class used to track VCN-defined Network policies for this DataConnection.
- *
- * <p>MUST be registered with the associated DataConnection's Handler.
- */
- private class DataConnectionVcnNetworkPolicyChangeListener
- implements VcnNetworkPolicyChangeListener {
- @Override
- public void onPolicyChanged() {
- // Poll the current underlying Network policy from VcnManager and send to NetworkAgent.
- final NetworkCapabilities networkCapabilities = getNetworkCapabilities();
- VcnNetworkPolicyResult policyResult =
- mVcnManager.applyVcnNetworkPolicy(
- networkCapabilities, getLinkProperties());
- if (policyResult.isTeardownRequested()) {
- tearDownAll(
- Phone.REASON_VCN_REQUESTED_TEARDOWN,
- DcTracker.RELEASE_TYPE_DETACH,
- null /* onCompletedMsg */);
- }
-
- if (mNetworkAgent != null) {
- mNetworkAgent.sendNetworkCapabilities(networkCapabilities, DataConnection.this);
- }
- }
- }
-}
-
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataConnectionReasons.java b/src/java/com/android/internal/telephony/dataconnection/DataConnectionReasons.java
deleted file mode 100644
index 68f2ab3..0000000
--- a/src/java/com/android/internal/telephony/dataconnection/DataConnectionReasons.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.HashSet;
-
-/**
- * The class to describe the reasons of allowing or disallowing to establish a data connection.
- */
-public class DataConnectionReasons {
- private HashSet<DataDisallowedReasonType> mDataDisallowedReasonSet = new HashSet<>();
- private DataAllowedReasonType mDataAllowedReason = DataAllowedReasonType.NONE;
-
- public DataConnectionReasons() {}
-
- void add(DataDisallowedReasonType reason) {
- // Adding a disallowed reason will clean up the allowed reason because they are
- // mutual exclusive.
- mDataAllowedReason = DataAllowedReasonType.NONE;
- mDataDisallowedReasonSet.add(reason);
- }
-
- void add(DataAllowedReasonType reason) {
- // Adding an allowed reason will clean up the disallowed reasons because they are
- // mutual exclusive.
- mDataDisallowedReasonSet.clear();
-
- // Only higher priority allowed reason can overwrite the old one. See
- // DataAllowedReasonType for the oder.
- if (reason.ordinal() > mDataAllowedReason.ordinal()) {
- mDataAllowedReason = reason;
- }
- }
-
- @Override
- public String toString() {
- StringBuilder reasonStr = new StringBuilder();
- if (mDataDisallowedReasonSet.size() > 0) {
- reasonStr.append("Data disallowed reasons:");
- for (DataDisallowedReasonType reason : mDataDisallowedReasonSet) {
- reasonStr.append(" ").append(reason);
- }
- } else {
- reasonStr.append("Data allowed reason:");
- reasonStr.append(" ").append(mDataAllowedReason);
- }
- return reasonStr.toString();
- }
-
- void copyFrom(DataConnectionReasons reasons) {
- this.mDataDisallowedReasonSet = reasons.mDataDisallowedReasonSet;
- this.mDataAllowedReason = reasons.mDataAllowedReason;
- }
-
- boolean allowed() {
- return mDataDisallowedReasonSet.size() == 0;
- }
-
- /**
- * Check if it contains a certain disallowed reason.
- *
- * @param reason The disallowed reason to check.
- * @return {@code true} if the provided reason matches one of the disallowed reasons.
- */
- @VisibleForTesting
- public boolean contains(DataDisallowedReasonType reason) {
- return mDataDisallowedReasonSet.contains(reason);
- }
-
- /**
- * Check if only one disallowed reason prevent data connection.
- *
- * @param reason The given reason to check
- * @return True if the given reason is the only one that prevents data connection
- */
- public boolean containsOnly(DataDisallowedReasonType reason) {
- return mDataDisallowedReasonSet.size() == 1 && contains(reason);
- }
-
- boolean contains(DataAllowedReasonType reason) {
- return reason == mDataAllowedReason;
- }
-
- boolean containsHardDisallowedReasons() {
- for (DataDisallowedReasonType reason : mDataDisallowedReasonSet) {
- if (reason.isHardReason()) {
- return true;
- }
- }
- return false;
- }
-
- // Disallowed reasons. There could be multiple reasons if data connection is not allowed.
- public enum DataDisallowedReasonType {
- // Soft failure reasons. Normally the reasons from users or policy settings.
-
- // Data is disabled by the user or policy.
- DATA_DISABLED(false),
- // Data roaming is disabled by the user.
- ROAMING_DISABLED(false),
- // Default data not selected.
- DEFAULT_DATA_UNSELECTED(false),
-
- // Belows are all hard failure reasons.
- NOT_ATTACHED(true),
- SIM_NOT_READY(true),
- INVALID_PHONE_STATE(true),
- CONCURRENT_VOICE_DATA_NOT_ALLOWED(true),
- PS_RESTRICTED(true),
- UNDESIRED_POWER_STATE(true),
- INTERNAL_DATA_DISABLED(true),
- RADIO_DISABLED_BY_CARRIER(true),
- // Not in the right state for data call setup.
- APN_NOT_CONNECTABLE(true),
- // Data is in connecting state. No need to send another setup request.
- DATA_IS_CONNECTING(true),
- // Data is being disconnected. Telephony will retry after disconnected.
- DATA_IS_DISCONNECTING(true),
- // Data is already connected. No need to setup data again.
- DATA_ALREADY_CONNECTED(true),
- // certain APNs are not allowed on IWLAN in legacy mode.
- ON_IWLAN(true),
- // certain APNs are only allowed when the device is camped on NR.
- NOT_ON_NR(true),
- // Data is not allowed while device is in emergency callback mode.
- IN_ECBM(true),
- // The given APN type's preferred transport has switched.
- ON_OTHER_TRANSPORT(true),
- // Underlying data service is not bound.
- DATA_SERVICE_NOT_READY(true),
- // Qualified networks service does not allow certain types of APN brought up on either
- // cellular or IWLAN.
- DISABLED_BY_QNS(true),
- // Data is throttled. The network explicitly requested device not to establish data
- // connection for a certain period.
- DATA_THROTTLED(true);
-
- private boolean mIsHardReason;
-
- boolean isHardReason() {
- return mIsHardReason;
- }
-
- DataDisallowedReasonType(boolean isHardReason) {
- mIsHardReason = isHardReason;
- }
- }
-
- // Data allowed reasons. There will be only one reason if data is allowed.
- enum DataAllowedReasonType {
- // Note that unlike disallowed reasons, we only have one allowed reason every time
- // when we check data is allowed or not. The order of these allowed reasons is very
- // important. The lower ones take precedence over the upper ones.
- NONE,
- NORMAL,
- UNMETERED_APN,
- RESTRICTED_REQUEST,
- EMERGENCY_APN,
- }
-}
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java b/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java
deleted file mode 100644
index 305b4a8..0000000
--- a/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java
+++ /dev/null
@@ -1,566 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-
-import static android.telephony.PhoneStateListener.LISTEN_CALL_STATE;
-import static android.telephony.PhoneStateListener.LISTEN_NONE;
-
-import android.annotation.IntDef;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.os.Handler;
-import android.os.RegistrantList;
-import android.os.SystemProperties;
-import android.provider.Settings;
-import android.sysprop.TelephonyProperties;
-import android.telephony.Annotation.CallState;
-import android.telephony.CarrierConfigManager;
-import android.telephony.PhoneStateListener;
-import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.telephony.data.ApnSetting;
-import android.util.LocalLog;
-import android.util.Pair;
-
-import com.android.internal.telephony.GlobalSettingsHelper;
-import com.android.internal.telephony.MultiSimSettingController;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.SubscriptionController;
-import com.android.internal.telephony.data.DataEnabledOverride;
-import com.android.telephony.Rlog;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * The class to hold different data enabled/disabled settings. Also it allows clients to register
- * for overall data enabled setting changed event.
- * @hide
- */
-public class DataEnabledSettings {
-
- private static final String LOG_TAG = "DataEnabledSettings";
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"REASON_"},
- value = {
- REASON_REGISTERED,
- REASON_INTERNAL_DATA_ENABLED,
- REASON_USER_DATA_ENABLED,
- REASON_POLICY_DATA_ENABLED,
- REASON_DATA_ENABLED_BY_CARRIER,
- REASON_PROVISIONED_CHANGED,
- REASON_PROVISIONING_DATA_ENABLED_CHANGED,
- REASON_OVERRIDE_RULE_CHANGED,
- REASON_OVERRIDE_CONDITION_CHANGED,
- REASON_THERMAL_DATA_ENABLED
- })
- public @interface DataEnabledChangedReason {}
-
- public static final int REASON_REGISTERED = 0;
-
- public static final int REASON_INTERNAL_DATA_ENABLED = 1;
-
- public static final int REASON_USER_DATA_ENABLED = 2;
-
- public static final int REASON_POLICY_DATA_ENABLED = 3;
-
- public static final int REASON_DATA_ENABLED_BY_CARRIER = 4;
-
- public static final int REASON_PROVISIONED_CHANGED = 5;
-
- public static final int REASON_PROVISIONING_DATA_ENABLED_CHANGED = 6;
-
- public static final int REASON_OVERRIDE_RULE_CHANGED = 7;
-
- public static final int REASON_OVERRIDE_CONDITION_CHANGED = 8;
-
- public static final int REASON_THERMAL_DATA_ENABLED = 9;
-
- /**
- * responds to the setInternalDataEnabled call - used internally to turn off data.
- * For example during emergency calls
- */
- private boolean mInternalDataEnabled = true;
-
- /**
- * Flag indicating data allowed by network policy manager or not.
- */
- private boolean mPolicyDataEnabled = true;
-
- /**
- * Indicate if metered APNs are enabled by the carrier. set false to block all the metered APNs
- * from continuously sending requests, which causes undesired network load.
- */
- private boolean mCarrierDataEnabled = true;
-
- /**
- * Flag indicating data allowed by Thermal service or not.
- */
- private boolean mThermalDataEnabled = true;
-
- /**
- * Flag indicating whether data is allowed or not for the device. It can be disabled by
- * user, carrier, policy or thermal
- */
- private boolean mIsDataEnabled = false;
-
- private final Phone mPhone;
-
- private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-
- private ContentResolver mResolver = null;
-
- private final RegistrantList mOverallDataEnabledChangedRegistrants = new RegistrantList();
-
- // TODO: Merge this with mOverallDataEnabledChangedRegistrants. In the future, notifying data
- // enabled changed with APN types bitmask
- private final RegistrantList mOverallDataEnabledOverrideChangedRegistrants =
- new RegistrantList();
-
- private final LocalLog mSettingChangeLocalLog = new LocalLog(32);
-
- private DataEnabledOverride mDataEnabledOverride;
-
- private TelephonyManager mTelephonyManager;
-
- // for msim, user data enabled setting depends on subId.
- private final SubscriptionManager.OnSubscriptionsChangedListener
- mOnSubscriptionsChangeListener =
- new SubscriptionManager.OnSubscriptionsChangedListener() {
- @Override
- public void onSubscriptionsChanged() {
- synchronized (this) {
- if (mSubId != mPhone.getSubId()) {
- log("onSubscriptionsChanged subId: " + mSubId + " to: "
- + mPhone.getSubId());
- mSubId = mPhone.getSubId();
- mDataEnabledOverride = getDataEnabledOverride();
- updatePhoneStateListener();
- updateDataEnabledAndNotify(REASON_USER_DATA_ENABLED);
- mPhone.notifyUserMobileDataStateChanged(isUserDataEnabled());
- }
- }
- }
- };
-
- private void updatePhoneStateListener() {
- mTelephonyManager.listen(mPhoneStateListener, LISTEN_NONE);
- if (SubscriptionManager.isUsableSubscriptionId(mSubId)) {
- mTelephonyManager = mTelephonyManager.createForSubscriptionId(mSubId);
- }
- mTelephonyManager.listen(mPhoneStateListener, LISTEN_CALL_STATE);
- }
-
- private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
- @Override
- public void onCallStateChanged(@CallState int state, String phoneNumber) {
- updateDataEnabledAndNotify(REASON_OVERRIDE_CONDITION_CHANGED);
- }
- };
-
- @Override
- public String toString() {
- return "[mInternalDataEnabled=" + mInternalDataEnabled
- + ", isUserDataEnabled=" + isUserDataEnabled()
- + ", isProvisioningDataEnabled=" + isProvisioningDataEnabled()
- + ", mPolicyDataEnabled=" + mPolicyDataEnabled
- + ", mCarrierDataEnabled=" + mCarrierDataEnabled
- + ", mIsDataEnabled=" + mIsDataEnabled
- + ", mThermalDataEnabled=" + mThermalDataEnabled
- + ", " + mDataEnabledOverride
- + "]";
- }
-
- public DataEnabledSettings(Phone phone) {
- mPhone = phone;
- mResolver = mPhone.getContext().getContentResolver();
- SubscriptionManager subscriptionManager = (SubscriptionManager) mPhone.getContext()
- .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
- subscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangeListener);
- mTelephonyManager = (TelephonyManager) mPhone.getContext()
- .getSystemService(Context.TELEPHONY_SERVICE);
- mDataEnabledOverride = getDataEnabledOverride();
- updateDataEnabled();
- }
-
- private DataEnabledOverride getDataEnabledOverride() {
- return new DataEnabledOverride(SubscriptionController.getInstance()
- .getDataEnabledOverrideRules(mPhone.getSubId()));
- }
-
- public synchronized void setInternalDataEnabled(boolean enabled) {
- if (mInternalDataEnabled != enabled) {
- localLog("InternalDataEnabled", enabled);
- mInternalDataEnabled = enabled;
- updateDataEnabledAndNotify(REASON_INTERNAL_DATA_ENABLED);
- }
- }
- public synchronized boolean isInternalDataEnabled() {
- return mInternalDataEnabled;
- }
-
- private synchronized void setUserDataEnabled(boolean enabled) {
- // By default the change should propagate to the group.
- setUserDataEnabled(enabled, true);
- }
-
- /**
- * @param notifyMultiSimSettingController if setUserDataEnabled is already from propagating
- * from MultiSimSettingController, don't notify MultiSimSettingController again.
- * For example, if sub1 and sub2 are in the same group and user enables data for sub
- * 1, sub 2 will also be enabled but with propagateToGroup = false.
- */
- public synchronized void setUserDataEnabled(boolean enabled,
- boolean notifyMultiSimSettingController) {
- // Can't disable data for stand alone opportunistic subscription.
- if (isStandAloneOpportunistic(mPhone.getSubId(), mPhone.getContext()) && !enabled) return;
-
- boolean changed = GlobalSettingsHelper.setInt(mPhone.getContext(),
- Settings.Global.MOBILE_DATA, mPhone.getSubId(), (enabled ? 1 : 0));
- if (changed) {
- localLog("UserDataEnabled", enabled);
- mPhone.notifyUserMobileDataStateChanged(enabled);
- updateDataEnabledAndNotify(REASON_USER_DATA_ENABLED);
- if (notifyMultiSimSettingController) {
- MultiSimSettingController.getInstance().notifyUserDataEnabled(
- mPhone.getSubId(), enabled);
- }
- }
- }
-
- /**
- * Policy control of data connection with reason
- * @param reason the reason the data enable change is taking place
- * @param enabled True if enabling the data, otherwise disabling.
- */
- public synchronized void setDataEnabled(@TelephonyManager.DataEnabledReason int reason,
- boolean enabled) {
- switch (reason) {
- case TelephonyManager.DATA_ENABLED_REASON_USER:
- setUserDataEnabled(enabled);
- break;
- case TelephonyManager.DATA_ENABLED_REASON_CARRIER:
- setCarrierDataEnabled(enabled);
- break;
- case TelephonyManager.DATA_ENABLED_REASON_POLICY:
- setPolicyDataEnabled(enabled);
- break;
- case TelephonyManager.DATA_ENABLED_REASON_THERMAL:
- setThermalDataEnabled(enabled);
- break;
- default:
- log("Invalid data enable reason " + reason);
- break;
- }
- }
-
- public synchronized boolean isUserDataEnabled() {
- // User data should always be true for opportunistic subscription.
- if (isStandAloneOpportunistic(mPhone.getSubId(), mPhone.getContext())) return true;
-
- boolean defaultVal = TelephonyProperties.mobile_data().orElse(true);
-
- return GlobalSettingsHelper.getBoolean(mPhone.getContext(),
- Settings.Global.MOBILE_DATA, mPhone.getSubId(), defaultVal);
- }
-
- /**
- * Set whether always allowing MMS data connection.
- *
- * @param alwaysAllow {@code true} if MMS data is always allowed.
- *
- * @return {@code false} if the setting is changed.
- */
- public synchronized boolean setAlwaysAllowMmsData(boolean alwaysAllow) {
- localLog("setAlwaysAllowMmsData", alwaysAllow);
- mDataEnabledOverride.setAlwaysAllowMms(alwaysAllow);
- boolean changed = SubscriptionController.getInstance()
- .setDataEnabledOverrideRules(mPhone.getSubId(), mDataEnabledOverride.getRules());
- if (changed) {
- updateDataEnabledAndNotify(REASON_OVERRIDE_RULE_CHANGED);
- notifyDataEnabledOverrideChanged();
- }
-
- return changed;
- }
-
- /**
- * Set allowing mobile data during voice call. This is used for allowing data on the non-default
- * data SIM. When a voice call is placed on the non-default data SIM on DSDS devices, users will
- * not be able to use mobile data. By calling this API, data will be temporarily enabled on the
- * non-default data SIM during the life cycle of the voice call.
- *
- * @param allow {@code true} if allowing using data during voice call, {@code false} if
- * disallowed
- *
- * @return {@code true} if operation is successful. otherwise {@code false}.
- */
- public synchronized boolean setAllowDataDuringVoiceCall(boolean allow) {
- localLog("setAllowDataDuringVoiceCall", allow);
- if (allow == isDataAllowedInVoiceCall()) {
- return true;
- }
- mDataEnabledOverride.setDataAllowedInVoiceCall(allow);
-
- boolean changed = SubscriptionController.getInstance()
- .setDataEnabledOverrideRules(mPhone.getSubId(), mDataEnabledOverride.getRules());
- if (changed) {
- updateDataEnabledAndNotify(REASON_OVERRIDE_RULE_CHANGED);
- notifyDataEnabledOverrideChanged();
- }
-
- return changed;
- }
-
- /**
- * Check if data is allowed during voice call.
- *
- * @return {@code true} if data is allowed during voice call.
- */
- public synchronized boolean isDataAllowedInVoiceCall() {
- return mDataEnabledOverride.isDataAllowedInVoiceCall();
- }
-
- public synchronized boolean isMmsAlwaysAllowed() {
- return mDataEnabledOverride.isMmsAlwaysAllowed();
- }
-
- private synchronized void setPolicyDataEnabled(boolean enabled) {
- if (mPolicyDataEnabled != enabled) {
- localLog("PolicyDataEnabled", enabled);
- mPolicyDataEnabled = enabled;
- updateDataEnabledAndNotify(REASON_POLICY_DATA_ENABLED);
- }
- }
-
- public synchronized boolean isPolicyDataEnabled() {
- return mPolicyDataEnabled;
- }
-
- private synchronized void setCarrierDataEnabled(boolean enabled) {
- if (mCarrierDataEnabled != enabled) {
- localLog("CarrierDataEnabled", enabled);
- mCarrierDataEnabled = enabled;
- updateDataEnabledAndNotify(REASON_DATA_ENABLED_BY_CARRIER);
- }
- }
-
- public synchronized boolean isCarrierDataEnabled() {
- return mCarrierDataEnabled;
- }
-
- private synchronized void setThermalDataEnabled(boolean enabled) {
- if (mThermalDataEnabled != enabled) {
- localLog("ThermalDataEnabled", enabled);
- mThermalDataEnabled = enabled;
- updateDataEnabledAndNotify(REASON_THERMAL_DATA_ENABLED);
- }
- }
-
- public synchronized boolean isThermalDataEnabled() {
- return mThermalDataEnabled;
- }
-
- public synchronized void updateProvisionedChanged() {
- updateDataEnabledAndNotify(REASON_PROVISIONED_CHANGED);
- }
-
- public synchronized void updateProvisioningDataEnabled() {
- updateDataEnabledAndNotify(REASON_PROVISIONING_DATA_ENABLED_CHANGED);
- }
-
- public synchronized boolean isDataEnabled() {
- return mIsDataEnabled;
- }
-
- /**
- * Check if data is enabled for a specific reason {@@TelephonyManager.DataEnabledReason}
- *
- * @return {@code true} if the overall data is enabled; {@code false} if not.
- */
- public synchronized boolean isDataEnabledForReason(
- @TelephonyManager.DataEnabledReason int reason) {
- switch (reason) {
- case TelephonyManager.DATA_ENABLED_REASON_USER:
- return isUserDataEnabled();
- case TelephonyManager.DATA_ENABLED_REASON_CARRIER:
- return isCarrierDataEnabled();
- case TelephonyManager.DATA_ENABLED_REASON_POLICY:
- return isPolicyDataEnabled();
- case TelephonyManager.DATA_ENABLED_REASON_THERMAL:
- return isThermalDataEnabled();
- default:
- return false;
- }
- }
-
- private synchronized void updateDataEnabledAndNotify(int reason) {
- boolean prevDataEnabled = mIsDataEnabled;
-
- updateDataEnabled();
-
- if (prevDataEnabled != mIsDataEnabled) {
- notifyDataEnabledChanged(!prevDataEnabled, reason);
- }
- }
-
- private synchronized void updateDataEnabled() {
- if (isProvisioning()) {
- mIsDataEnabled = isProvisioningDataEnabled();
- } else {
- mIsDataEnabled = mInternalDataEnabled && (isUserDataEnabled() || mDataEnabledOverride
- .shouldOverrideDataEnabledSettings(mPhone, ApnSetting.TYPE_ALL))
- && mPolicyDataEnabled && mCarrierDataEnabled && mThermalDataEnabled;
- }
- }
-
- public boolean isProvisioning() {
- return Settings.Global.getInt(mResolver, Settings.Global.DEVICE_PROVISIONED, 0) == 0;
- }
- /**
- * In provisioning, we might want to have enable mobile data during provisioning. It depends
- * on value of Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED which is set by
- * setupwizard. It only matters if it's in provisioning stage.
- * @return whether we are enabling userData during provisioning stage.
- */
- public boolean isProvisioningDataEnabled() {
- final String prov_property = SystemProperties.get("ro.com.android.prov_mobiledata",
- "false");
- boolean retVal = "true".equalsIgnoreCase(prov_property);
-
- final int prov_mobile_data = Settings.Global.getInt(mResolver,
- Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED,
- retVal ? 1 : 0);
- retVal = prov_mobile_data != 0;
- log("getDataEnabled during provisioning retVal=" + retVal + " - (" + prov_property
- + ", " + prov_mobile_data + ")");
-
- return retVal;
- }
-
- public synchronized void setDataRoamingEnabled(boolean enabled) {
- // will trigger handleDataOnRoamingChange() through observer
- boolean changed = GlobalSettingsHelper.setBoolean(mPhone.getContext(),
- Settings.Global.DATA_ROAMING, mPhone.getSubId(), enabled);
-
- if (changed) {
- localLog("setDataRoamingEnabled", enabled);
- MultiSimSettingController.getInstance().notifyRoamingDataEnabled(mPhone.getSubId(),
- enabled);
- }
- }
-
- /**
- * Return current {@link android.provider.Settings.Global#DATA_ROAMING} value.
- */
- public synchronized boolean getDataRoamingEnabled() {
- return GlobalSettingsHelper.getBoolean(mPhone.getContext(),
- Settings.Global.DATA_ROAMING, mPhone.getSubId(), getDefaultDataRoamingEnabled());
- }
-
- /**
- * get default values for {@link Settings.Global#DATA_ROAMING}
- * return {@code true} if either
- * {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL} or
- * system property ro.com.android.dataroaming is set to true. otherwise return {@code false}
- */
- public synchronized boolean getDefaultDataRoamingEnabled() {
- final CarrierConfigManager configMgr = (CarrierConfigManager)
- mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
- boolean isDataRoamingEnabled = "true".equalsIgnoreCase(SystemProperties.get(
- "ro.com.android.dataroaming", "false"));
- isDataRoamingEnabled |= configMgr.getConfigForSubId(mPhone.getSubId()).getBoolean(
- CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
- return isDataRoamingEnabled;
- }
-
- private void notifyDataEnabledChanged(boolean enabled, int reason) {
- mOverallDataEnabledChangedRegistrants.notifyResult(new Pair<>(enabled, reason));
- mPhone.notifyDataEnabled(enabled, reason);
- }
-
- public void registerForDataEnabledChanged(Handler h, int what, Object obj) {
- mOverallDataEnabledChangedRegistrants.addUnique(h, what, obj);
- notifyDataEnabledChanged(isDataEnabled(), REASON_REGISTERED);
- }
-
- public void unregisterForDataEnabledChanged(Handler h) {
- mOverallDataEnabledChangedRegistrants.remove(h);
- }
-
- private void notifyDataEnabledOverrideChanged() {
- mOverallDataEnabledOverrideChangedRegistrants.notifyRegistrants();
- }
-
- /**
- * Register for data enabled override changed event.
- *
- * @param h The handler
- * @param what The event
- */
- public void registerForDataEnabledOverrideChanged(Handler h, int what) {
- mOverallDataEnabledOverrideChangedRegistrants.addUnique(h, what, null);
- notifyDataEnabledOverrideChanged();
- }
-
- /**
- * Unregistered for data enabled override changed event.
- *
- * @param h The handler
- */
- public void unregisterForDataEnabledOverrideChanged(Handler h) {
- mOverallDataEnabledOverrideChangedRegistrants.remove(h);
- }
-
- private static boolean isStandAloneOpportunistic(int subId, Context context) {
- SubscriptionInfo info = SubscriptionController.getInstance().getActiveSubscriptionInfo(
- subId, context.getOpPackageName(), context.getAttributionTag());
- return (info != null) && info.isOpportunistic() && info.getGroupUuid() == null;
- }
-
- public synchronized boolean isDataEnabled(int apnType) {
- if (isProvisioning()) {
- return isProvisioningDataEnabled();
- } else {
- boolean userDataEnabled = isUserDataEnabled();
- // Check if we should temporarily enable data in certain conditions.
- boolean isDataEnabledOverridden = mDataEnabledOverride
- .shouldOverrideDataEnabledSettings(mPhone, apnType);
-
- return (mInternalDataEnabled && mPolicyDataEnabled && mCarrierDataEnabled
- && mThermalDataEnabled && (userDataEnabled || isDataEnabledOverridden));
- }
- }
-
- private void log(String s) {
- Rlog.d(LOG_TAG, "[" + mPhone.getPhoneId() + "]" + s);
- }
-
- private void localLog(String name, boolean value) {
- mSettingChangeLocalLog.log(name + " change to " + value);
- }
-
- protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println(" DataEnabledSettings=");
- mSettingChangeLocalLog.dump(fd, pw, args);
- }
-}
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java b/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java
deleted file mode 100644
index d006004..0000000
--- a/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java
+++ /dev/null
@@ -1,978 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
-import static android.text.format.DateUtils.SECOND_IN_MILLIS;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.AppOpsManager;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.ServiceConnection;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.net.LinkProperties;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.PersistableBundle;
-import android.os.RegistrantList;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.permission.LegacyPermissionManager;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.AccessNetworkConstants.TransportType;
-import android.telephony.AnomalyReporter;
-import android.telephony.CarrierConfigManager;
-import android.telephony.SubscriptionManager;
-import android.telephony.data.DataCallResponse;
-import android.telephony.data.DataProfile;
-import android.telephony.data.DataService;
-import android.telephony.data.DataServiceCallback;
-import android.telephony.data.IDataService;
-import android.telephony.data.IDataServiceCallback;
-import android.telephony.data.NetworkSliceInfo;
-import android.telephony.data.TrafficDescriptor;
-import android.text.TextUtils;
-
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConfigurationManager;
-import com.android.internal.telephony.util.TelephonyUtils;
-import com.android.telephony.Rlog;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CountDownLatch;
-
-/**
- * Data service manager manages handling data requests and responses on data services (e.g.
- * Cellular data service, IWLAN data service).
- */
-public class DataServiceManager extends Handler {
- private static final boolean DBG = true;
-
- static final String DATA_CALL_RESPONSE = "data_call_response";
-
- private static final int EVENT_BIND_DATA_SERVICE = 1;
-
- private static final int EVENT_WATCHDOG_TIMEOUT = 2;
-
- private static final long REQUEST_UNRESPONDED_TIMEOUT = 10 * MINUTE_IN_MILLIS; // 10 mins
-
- private static final long CHANGE_PERMISSION_TIMEOUT_MS = 15 * SECOND_IN_MILLIS; // 15 secs
-
- private final Phone mPhone;
-
- private final String mTag;
-
- private final CarrierConfigManager mCarrierConfigManager;
- private final AppOpsManager mAppOps;
- private final LegacyPermissionManager mPermissionManager;
-
- private final int mTransportType;
-
- private boolean mBound;
-
- private IDataService mIDataService;
-
- private DataServiceManagerDeathRecipient mDeathRecipient;
-
- private final RegistrantList mServiceBindingChangedRegistrants = new RegistrantList();
-
- private final Map<IBinder, Message> mMessageMap = new ConcurrentHashMap<>();
-
- private final RegistrantList mDataCallListChangedRegistrants = new RegistrantList();
-
- private final RegistrantList mApnUnthrottledRegistrants = new RegistrantList();
-
- private String mTargetBindingPackageName;
-
- private CellularDataServiceConnection mServiceConnection;
-
- private final UUID mAnomalyUUID = UUID.fromString("fc1956de-c080-45de-8431-a1faab687110");
- private String mLastBoundPackageName;
-
- /**
- * Helpful for logging
- * @return the tag name
- *
- * @hide
- */
- public String getTag() {
- return mTag;
- }
-
- private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
- if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(action)
- && mPhone.getPhoneId() == intent.getIntExtra(
- CarrierConfigManager.EXTRA_SLOT_INDEX, 0)) {
- // We should wait for carrier config changed event because the target binding
- // package name can come from the carrier config. Note that we still get this event
- // even when SIM is absent.
- if (DBG) log("Carrier config changed. Try to bind data service.");
- sendEmptyMessage(EVENT_BIND_DATA_SERVICE);
- }
- }
- };
-
- private class DataServiceManagerDeathRecipient implements IBinder.DeathRecipient {
- @Override
- public void binderDied() {
- // TODO: try to rebind the service.
- String message = "Data service " + mLastBoundPackageName + " for transport type "
- + AccessNetworkConstants.transportTypeToString(mTransportType) + " died.";
- loge(message);
- AnomalyReporter.reportAnomaly(mAnomalyUUID, message, mPhone.getCarrierId());
- }
- }
-
- private void grantPermissionsToService(String packageName) {
- final String[] pkgToGrant = {packageName};
- CountDownLatch latch = new CountDownLatch(1);
- try {
- mPermissionManager.grantDefaultPermissionsToEnabledTelephonyDataServices(
- pkgToGrant, UserHandle.of(UserHandle.myUserId()), Runnable::run,
- isSuccess -> {
- if (isSuccess) {
- latch.countDown();
- } else {
- loge("Failed to grant permissions to service.");
- }
- });
- TelephonyUtils.waitUntilReady(latch, CHANGE_PERMISSION_TIMEOUT_MS);
- mAppOps.setMode(AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS,
- UserHandle.myUserId(), pkgToGrant[0], AppOpsManager.MODE_ALLOWED);
- mAppOps.setMode(AppOpsManager.OPSTR_FINE_LOCATION,
- UserHandle.myUserId(), pkgToGrant[0], AppOpsManager.MODE_ALLOWED);
- } catch (RuntimeException e) {
- loge("Binder to package manager died, permission grant for DataService failed.");
- throw e;
- }
- }
-
- /**
- * Loop through all DataServices installed on the system and revoke permissions from any that
- * are not currently the WWAN or WLAN data service.
- */
- private void revokePermissionsFromUnusedDataServices() {
- // Except the current data services from having their permissions removed.
- Set<String> dataServices = getAllDataServicePackageNames();
- for (int transportType : mPhone.getAccessNetworksManager().getAvailableTransports()) {
- dataServices.remove(getDataServicePackageName(transportType));
- }
-
- CountDownLatch latch = new CountDownLatch(1);
- try {
- String[] dataServicesArray = new String[dataServices.size()];
- dataServices.toArray(dataServicesArray);
- mPermissionManager.revokeDefaultPermissionsFromDisabledTelephonyDataServices(
- dataServicesArray, UserHandle.of(UserHandle.myUserId()), Runnable::run,
- isSuccess -> {
- if (isSuccess) {
- latch.countDown();
- } else {
- loge("Failed to revoke permissions from data services.");
- }
- });
- TelephonyUtils.waitUntilReady(latch, CHANGE_PERMISSION_TIMEOUT_MS);
- for (String pkg : dataServices) {
- mAppOps.setMode(AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS, UserHandle.myUserId(),
- pkg, AppOpsManager.MODE_ERRORED);
- mAppOps.setMode(AppOpsManager.OPSTR_FINE_LOCATION, UserHandle.myUserId(),
- pkg, AppOpsManager.MODE_ERRORED);
- }
- } catch (RuntimeException e) {
- loge("Binder to package manager died; failed to revoke DataService permissions.");
- throw e;
- }
- }
-
- private final class CellularDataServiceConnection implements ServiceConnection {
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- if (DBG) log("onServiceConnected");
- mIDataService = IDataService.Stub.asInterface(service);
- mDeathRecipient = new DataServiceManagerDeathRecipient();
- mBound = true;
- mLastBoundPackageName = getDataServicePackageName();
- removeMessages(EVENT_WATCHDOG_TIMEOUT);
-
- try {
- service.linkToDeath(mDeathRecipient, 0);
- mIDataService.createDataServiceProvider(mPhone.getPhoneId());
- mIDataService.registerForDataCallListChanged(mPhone.getPhoneId(),
- new CellularDataServiceCallback("dataCallListChanged"));
- mIDataService.registerForUnthrottleApn(mPhone.getPhoneId(),
- new CellularDataServiceCallback("unthrottleApn"));
- } catch (RemoteException e) {
- loge("Remote exception. " + e);
- return;
- }
- mServiceBindingChangedRegistrants.notifyResult(true);
- }
- @Override
- public void onServiceDisconnected(ComponentName name) {
- if (DBG) log("onServiceDisconnected");
- removeMessages(EVENT_WATCHDOG_TIMEOUT);
- mIDataService = null;
- mBound = false;
- mServiceBindingChangedRegistrants.notifyResult(false);
- mTargetBindingPackageName = null;
- }
- }
-
- private final class CellularDataServiceCallback extends IDataServiceCallback.Stub {
-
- private final String mTag;
-
- CellularDataServiceCallback(String tag) {
- mTag = tag;
- }
-
- public String getTag() {
- return mTag;
- }
-
- @Override
- public void onSetupDataCallComplete(@DataServiceCallback.ResultCode int resultCode,
- DataCallResponse response) {
- if (DBG) {
- log("onSetupDataCallComplete. resultCode = " + resultCode + ", response = "
- + response);
- }
- removeMessages(EVENT_WATCHDOG_TIMEOUT, CellularDataServiceCallback.this);
- Message msg = mMessageMap.remove(asBinder());
- if (msg != null) {
- msg.getData().putParcelable(DATA_CALL_RESPONSE, response);
- sendCompleteMessage(msg, resultCode);
- } else {
- loge("Unable to find the message for setup call response.");
- }
- }
-
- @Override
- public void onDeactivateDataCallComplete(@DataServiceCallback.ResultCode int resultCode) {
- if (DBG) log("onDeactivateDataCallComplete. resultCode = " + resultCode);
- removeMessages(EVENT_WATCHDOG_TIMEOUT, CellularDataServiceCallback.this);
- Message msg = mMessageMap.remove(asBinder());
- sendCompleteMessage(msg, resultCode);
- }
-
- @Override
- public void onSetInitialAttachApnComplete(@DataServiceCallback.ResultCode int resultCode) {
- if (DBG) log("onSetInitialAttachApnComplete. resultCode = " + resultCode);
- Message msg = mMessageMap.remove(asBinder());
- sendCompleteMessage(msg, resultCode);
- }
-
- @Override
- public void onSetDataProfileComplete(@DataServiceCallback.ResultCode int resultCode) {
- if (DBG) log("onSetDataProfileComplete. resultCode = " + resultCode);
- Message msg = mMessageMap.remove(asBinder());
- sendCompleteMessage(msg, resultCode);
- }
-
- @Override
- public void onRequestDataCallListComplete(@DataServiceCallback.ResultCode int resultCode,
- List<DataCallResponse> dataCallList) {
- if (DBG) log("onRequestDataCallListComplete. resultCode = " + resultCode);
- Message msg = mMessageMap.remove(asBinder());
- sendCompleteMessage(msg, resultCode);
- }
-
- @Override
- public void onDataCallListChanged(List<DataCallResponse> dataCallList) {
- mDataCallListChangedRegistrants.notifyRegistrants(
- new AsyncResult(null, dataCallList, null));
- }
-
- @Override
- public void onHandoverStarted(@DataServiceCallback.ResultCode int resultCode) {
- if (DBG) log("onHandoverStarted. resultCode = " + resultCode);
- removeMessages(EVENT_WATCHDOG_TIMEOUT, CellularDataServiceCallback.this);
- Message msg = mMessageMap.remove(asBinder());
- sendCompleteMessage(msg, resultCode);
- }
-
- @Override
- public void onHandoverCancelled(@DataServiceCallback.ResultCode int resultCode) {
- if (DBG) log("onHandoverCancelled. resultCode = " + resultCode);
- removeMessages(EVENT_WATCHDOG_TIMEOUT, CellularDataServiceCallback.this);
- Message msg = mMessageMap.remove(asBinder());
- sendCompleteMessage(msg, resultCode);
- }
-
- @Override
- public void onApnUnthrottled(String apn) {
- if (apn != null) {
- mApnUnthrottledRegistrants.notifyRegistrants(
- new AsyncResult(null, apn, null));
- } else {
- loge("onApnUnthrottled: apn is null");
- }
- }
-
- @Override
- public void onDataProfileUnthrottled(DataProfile dataProfile) {
- if (dataProfile != null) {
- mApnUnthrottledRegistrants.notifyRegistrants(
- new AsyncResult(null, dataProfile, null));
- } else {
- loge("onDataProfileUnthrottled: dataProfile is null");
- }
- }
- }
-
- /**
- * Constructor
- *
- * @param phone The phone object
- * @param transportType The transport type
- * @param tagSuffix Logging tag suffix
- */
- public DataServiceManager(Phone phone, @TransportType int transportType, String tagSuffix) {
- mPhone = phone;
- mTag = "DSM" + tagSuffix;
- mTransportType = transportType;
- mBound = false;
- mCarrierConfigManager = (CarrierConfigManager) phone.getContext().getSystemService(
- Context.CARRIER_CONFIG_SERVICE);
- // NOTE: Do NOT use AppGlobals to retrieve the permission manager; AppGlobals
- // caches the service instance, but we need to explicitly request a new service
- // so it can be mocked out for tests
- mPermissionManager = (LegacyPermissionManager) phone.getContext().getSystemService(
- Context.LEGACY_PERMISSION_SERVICE);
- mAppOps = (AppOpsManager) phone.getContext().getSystemService(Context.APP_OPS_SERVICE);
-
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
- try {
- Context contextAsUser = phone.getContext().createPackageContextAsUser(
- phone.getContext().getPackageName(), 0, UserHandle.ALL);
- contextAsUser.registerReceiver(mBroadcastReceiver, intentFilter,
- null /* broadcastPermission */, null);
- } catch (PackageManager.NameNotFoundException e) {
- loge("Package name not found: " + e.getMessage());
- }
-
- PhoneConfigurationManager.registerForMultiSimConfigChange(
- this, EVENT_BIND_DATA_SERVICE, null);
-
- sendEmptyMessage(EVENT_BIND_DATA_SERVICE);
- }
-
- /**
- * Handle message events
- *
- * @param msg The message to handle
- */
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case EVENT_BIND_DATA_SERVICE:
- rebindDataService();
- break;
- case EVENT_WATCHDOG_TIMEOUT:
- handleRequestUnresponded((CellularDataServiceCallback) msg.obj);
- break;
- default:
- loge("Unhandled event " + msg.what);
- }
- }
-
- private void handleRequestUnresponded(CellularDataServiceCallback callback) {
- String message = "Request " + callback.getTag() + " unresponded on transport "
- + AccessNetworkConstants.transportTypeToString(mTransportType) + " in "
- + REQUEST_UNRESPONDED_TIMEOUT / 1000 + " seconds.";
- log(message);
- // Using fixed UUID to avoid duplicate bugreport notification
- AnomalyReporter.reportAnomaly(
- UUID.fromString("f5d5cbe6-9bd6-4009-b764-42b1b649b1de"),
- message, mPhone.getCarrierId());
- }
-
- private void unbindDataService() {
- // Start by cleaning up all packages that *shouldn't* have permissions.
- revokePermissionsFromUnusedDataServices();
- if (mIDataService != null && mIDataService.asBinder().isBinderAlive()) {
- log("unbinding service");
- // Remove the network availability updater and then unbind the service.
- try {
- mIDataService.removeDataServiceProvider(mPhone.getPhoneId());
- } catch (RemoteException e) {
- loge("Cannot remove data service provider. " + e);
- }
- }
-
- if (mServiceConnection != null) {
- mPhone.getContext().unbindService(mServiceConnection);
- }
- mIDataService = null;
- mServiceConnection = null;
- mTargetBindingPackageName = null;
- mBound = false;
- }
-
- private void bindDataService(String packageName) {
- if (mPhone == null || !SubscriptionManager.isValidPhoneId(mPhone.getPhoneId())) {
- loge("can't bindDataService with invalid phone or phoneId.");
- return;
- }
-
- if (TextUtils.isEmpty(packageName)) {
- loge("Can't find the binding package");
- return;
- }
-
- Intent intent = null;
- String className = getDataServiceClassName();
- if (TextUtils.isEmpty(className)) {
- intent = new Intent(DataService.SERVICE_INTERFACE);
- intent.setPackage(packageName);
- } else {
- ComponentName cm = new ComponentName(packageName, className);
- intent = new Intent(DataService.SERVICE_INTERFACE).setComponent(cm);
- }
-
- // Then pre-emptively grant the permissions to the package we will bind.
- grantPermissionsToService(packageName);
-
- try {
- mServiceConnection = new CellularDataServiceConnection();
- if (!mPhone.getContext().bindService(
- intent, mServiceConnection, Context.BIND_AUTO_CREATE)) {
- loge("Cannot bind to the data service.");
- return;
- }
- mTargetBindingPackageName = packageName;
- } catch (Exception e) {
- loge("Cannot bind to the data service. Exception: " + e);
- }
- }
-
- private void rebindDataService() {
- String packageName = getDataServicePackageName();
- // Do nothing if no need to rebind.
- if (SubscriptionManager.isValidPhoneId(mPhone.getPhoneId())
- && TextUtils.equals(packageName, mTargetBindingPackageName)) {
- if (DBG) log("Service " + packageName + " already bound or being bound.");
- return;
- }
-
- unbindDataService();
- bindDataService(packageName);
- }
-
- @NonNull
- private Set<String> getAllDataServicePackageNames() {
- // Cowardly using the public PackageManager interface here.
- // Note: This matches only packages that were installed on the system image. If we ever
- // expand the permissions model to allow CarrierPrivileged packages, then this will need
- // to be updated.
- List<ResolveInfo> dataPackages =
- mPhone.getContext().getPackageManager().queryIntentServices(
- new Intent(DataService.SERVICE_INTERFACE),
- PackageManager.MATCH_SYSTEM_ONLY);
- HashSet<String> packageNames = new HashSet<>();
- for (ResolveInfo info : dataPackages) {
- if (info.serviceInfo == null) continue;
- packageNames.add(info.serviceInfo.packageName);
- }
- return packageNames;
- }
-
- /**
- * Get the data service package name for our current transport type.
- *
- * @return package name of the data service package for the the current transportType.
- */
- public String getDataServicePackageName() {
- return getDataServicePackageName(mTransportType);
- }
-
- /**
- * Get the data service package by transport type.
- *
- * When we bind to a DataService package, we need to revoke permissions from stale
- * packages; we need to exclude data packages for all transport types, so we need to
- * to be able to query by transport type.
- *
- * @param transportType The transport type
- * @return package name of the data service package for the specified transportType.
- */
- private String getDataServicePackageName(@TransportType int transportType) {
- String packageName;
- int resourceId;
- String carrierConfig;
-
- switch (transportType) {
- case AccessNetworkConstants.TRANSPORT_TYPE_WWAN:
- resourceId = com.android.internal.R.string.config_wwan_data_service_package;
- carrierConfig = CarrierConfigManager
- .KEY_CARRIER_DATA_SERVICE_WWAN_PACKAGE_OVERRIDE_STRING;
- break;
- case AccessNetworkConstants.TRANSPORT_TYPE_WLAN:
- resourceId = com.android.internal.R.string.config_wlan_data_service_package;
- carrierConfig = CarrierConfigManager
- .KEY_CARRIER_DATA_SERVICE_WLAN_PACKAGE_OVERRIDE_STRING;
- break;
- default:
- throw new IllegalStateException("Transport type not WWAN or WLAN. type="
- + AccessNetworkConstants.transportTypeToString(mTransportType));
- }
-
- // Read package name from resource overlay
- packageName = mPhone.getContext().getResources().getString(resourceId);
-
- PersistableBundle b = mCarrierConfigManager.getConfigForSubId(mPhone.getSubId());
-
- if (b != null && !TextUtils.isEmpty(b.getString(carrierConfig))) {
- // If carrier config overrides it, use the one from carrier config
- packageName = b.getString(carrierConfig, packageName);
- }
-
- return packageName;
- }
-
- /**
- * Get the data service class name for our current transport type.
- *
- * @return class name of the data service package for the the current transportType.
- */
- private String getDataServiceClassName() {
- return getDataServiceClassName(mTransportType);
- }
-
-
- /**
- * Get the data service class by transport type.
- *
- * @param transportType either WWAN or WLAN
- * @return class name of the data service package for the specified transportType.
- */
- private String getDataServiceClassName(int transportType) {
- String className;
- int resourceId;
- String carrierConfig;
- switch (transportType) {
- case AccessNetworkConstants.TRANSPORT_TYPE_WWAN:
- resourceId = com.android.internal.R.string.config_wwan_data_service_class;
- carrierConfig = CarrierConfigManager
- .KEY_CARRIER_DATA_SERVICE_WWAN_CLASS_OVERRIDE_STRING;
- break;
- case AccessNetworkConstants.TRANSPORT_TYPE_WLAN:
- resourceId = com.android.internal.R.string.config_wlan_data_service_class;
- carrierConfig = CarrierConfigManager
- .KEY_CARRIER_DATA_SERVICE_WLAN_CLASS_OVERRIDE_STRING;
- break;
- default:
- throw new IllegalStateException("Transport type not WWAN or WLAN. type="
- + transportType);
- }
-
- // Read package name from resource overlay
- className = mPhone.getContext().getResources().getString(resourceId);
-
- PersistableBundle b = mCarrierConfigManager.getConfigForSubId(mPhone.getSubId());
-
- if (b != null && !TextUtils.isEmpty(b.getString(carrierConfig))) {
- // If carrier config overrides it, use the one from carrier config
- className = b.getString(carrierConfig, className);
- }
-
- return className;
- }
-
- private void sendCompleteMessage(Message msg, @DataServiceCallback.ResultCode int code) {
- if (msg != null) {
- msg.arg1 = code;
- msg.sendToTarget();
- }
- }
-
- /**
- * Setup a data connection. The data service provider must implement this method to support
- * establishing a packet data connection. When completed or error, the service must invoke
- * the provided callback to notify the platform.
- *
- * @param accessNetworkType Access network type that the data call will be established on.
- * Must be one of {@link AccessNetworkConstants.AccessNetworkType}.
- * @param dataProfile Data profile used for data call setup. See {@link DataProfile}
- * @param isRoaming True if the device is data roaming.
- * @param allowRoaming True if data roaming is allowed by the user.
- * @param reason The reason for data setup. Must be {@link DataService#REQUEST_REASON_NORMAL} or
- * {@link DataService#REQUEST_REASON_HANDOVER}.
- * @param linkProperties If {@code reason} is {@link DataService#REQUEST_REASON_HANDOVER}, this
- * is the link properties of the existing data connection, otherwise null.
- * @param pduSessionId The pdu session id to be used for this data call. A value of -1 means
- * no pdu session id was attached to this call.
- * Reference: 3GPP TS 24.007 Section 11.2.3.1b
- * @param sliceInfo The slice that represents S-NSSAI.
- * Reference: 3GPP TS 24.501
- * @param trafficDescriptor The traffic descriptor for this data call, used for URSP matching.
- * Reference: 3GPP TS TS 24.526 Section 5.2
- * @param matchAllRuleAllowed True if using the default match-all URSP rule for this request is
- * allowed.
- * @param onCompleteMessage The result message for this request. Null if the client does not
- * care about the result.
- */
- public void setupDataCall(int accessNetworkType, DataProfile dataProfile, boolean isRoaming,
- boolean allowRoaming, int reason, LinkProperties linkProperties, int pduSessionId,
- @Nullable NetworkSliceInfo sliceInfo, @Nullable TrafficDescriptor trafficDescriptor,
- boolean matchAllRuleAllowed, Message onCompleteMessage) {
- if (DBG) log("setupDataCall");
- if (!mBound) {
- loge("setupDataCall: Data service not bound.");
- sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
- return;
- }
-
- CellularDataServiceCallback callback = new CellularDataServiceCallback("setupDataCall");
- if (onCompleteMessage != null) {
- mMessageMap.put(callback.asBinder(), onCompleteMessage);
- }
- try {
- sendMessageDelayed(obtainMessage(EVENT_WATCHDOG_TIMEOUT, callback),
- REQUEST_UNRESPONDED_TIMEOUT);
- mIDataService.setupDataCall(mPhone.getPhoneId(), accessNetworkType, dataProfile,
- isRoaming, allowRoaming, reason, linkProperties, pduSessionId, sliceInfo,
- trafficDescriptor, matchAllRuleAllowed, callback);
- } catch (RemoteException e) {
- loge("setupDataCall: Cannot invoke setupDataCall on data service.");
- mMessageMap.remove(callback.asBinder());
- sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
- }
- }
-
- /**
- * Deactivate a data connection. The data service provider must implement this method to
- * support data connection tear down. When completed or error, the service must invoke the
- * provided callback to notify the platform.
- *
- * @param cid Call id returned in the callback of {@link #setupDataCall(int, DataProfile,
- * boolean, boolean, int, LinkProperties, Message)}
- * @param reason The reason for data deactivation. Must be
- * {@link DataService#REQUEST_REASON_NORMAL}, {@link DataService#REQUEST_REASON_SHUTDOWN}
- * or {@link DataService#REQUEST_REASON_HANDOVER}.
- * @param onCompleteMessage The result message for this request. Null if the client does not
- * care about the result.
- */
- public void deactivateDataCall(int cid, int reason, Message onCompleteMessage) {
- if (DBG) log("deactivateDataCall");
- if (!mBound) {
- loge("Data service not bound.");
- sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
- return;
- }
-
- CellularDataServiceCallback callback =
- new CellularDataServiceCallback("deactivateDataCall");
- if (onCompleteMessage != null) {
- mMessageMap.put(callback.asBinder(), onCompleteMessage);
- }
- try {
- sendMessageDelayed(obtainMessage(EVENT_WATCHDOG_TIMEOUT, callback),
- REQUEST_UNRESPONDED_TIMEOUT);
- mIDataService.deactivateDataCall(mPhone.getPhoneId(), cid, reason, callback);
- } catch (RemoteException e) {
- loge("Cannot invoke deactivateDataCall on data service.");
- mMessageMap.remove(callback.asBinder());
- sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
- }
- }
-
- /**
- * Indicates that a handover has begun. This is called on the source transport.
- *
- * Any resources being transferred cannot be released while a
- * handover is underway.
- *
- * If a handover was unsuccessful, then the framework calls DataServiceManager#cancelHandover.
- * The target transport retains ownership over any of the resources being transferred.
- *
- * If a handover was successful, the framework calls DataServiceManager#deactivateDataCall with
- * reason HANDOVER. The target transport now owns the transferred resources and is
- * responsible for releasing them.
- *
- * @param cid The identifier of the data call which is provided in DataCallResponse
- * @param onCompleteMessage The result callback for this request.
- */
- public void startHandover(int cid, @NonNull Message onCompleteMessage) {
- CellularDataServiceCallback callback =
- setupCallbackHelper("startHandover", onCompleteMessage);
- if (callback == null) {
- loge("startHandover: callback == null");
- sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
- return;
- }
-
- try {
- sendMessageDelayed(obtainMessage(EVENT_WATCHDOG_TIMEOUT, callback),
- REQUEST_UNRESPONDED_TIMEOUT);
- mIDataService.startHandover(mPhone.getPhoneId(), cid, callback);
- } catch (RemoteException e) {
- loge("Cannot invoke startHandover on data service.");
- mMessageMap.remove(callback.asBinder());
- sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
- }
- }
-
- /**
- * Indicates that a handover was cancelled after a call to DataServiceManager#startHandover.
- * This is called on the source transport.
- *
- * Since the handover was unsuccessful, the source transport retains ownership over any of
- * the resources being transferred and is still responsible for releasing them.
- *
- * @param cid The identifier of the data call which is provided in DataCallResponse
- * @param onCompleteMessage The result callback for this request.
- */
- public void cancelHandover(int cid, @NonNull Message onCompleteMessage) {
- CellularDataServiceCallback callback =
- setupCallbackHelper("cancelHandover", onCompleteMessage);
- if (callback == null) {
- sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
- return;
- }
-
- try {
- sendMessageDelayed(obtainMessage(EVENT_WATCHDOG_TIMEOUT, callback),
- REQUEST_UNRESPONDED_TIMEOUT);
- mIDataService.cancelHandover(mPhone.getPhoneId(), cid, callback);
- } catch (RemoteException e) {
- loge("Cannot invoke cancelHandover on data service.");
- mMessageMap.remove(callback.asBinder());
- sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
- }
- }
-
- @Nullable
- private CellularDataServiceCallback setupCallbackHelper(
- @NonNull final String operationName, @NonNull final Message onCompleteMessage) {
- if (DBG) log(operationName);
- if (!mBound) {
- sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
- return null;
- }
-
- CellularDataServiceCallback callback =
- new CellularDataServiceCallback(operationName);
- if (onCompleteMessage != null) {
- if (DBG) log(operationName + ": onCompleteMessage set");
- mMessageMap.put(callback.asBinder(), onCompleteMessage);
- } else {
- if (DBG) log(operationName + ": onCompleteMessage not set");
- }
- return callback;
- }
-
- /**
- * Set an APN to initial attach network.
- *
- * @param dataProfile Data profile used for data call setup. See {@link DataProfile}.
- * @param isRoaming True if the device is data roaming.
- * @param onCompleteMessage The result message for this request. Null if the client does not
- * care about the result.
- */
- public void setInitialAttachApn(DataProfile dataProfile, boolean isRoaming,
- Message onCompleteMessage) {
- if (DBG) log("setInitialAttachApn");
- if (!mBound) {
- loge("Data service not bound.");
- sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
- return;
- }
-
- CellularDataServiceCallback callback =
- new CellularDataServiceCallback("setInitialAttachApn");
- if (onCompleteMessage != null) {
- mMessageMap.put(callback.asBinder(), onCompleteMessage);
- }
- try {
- mIDataService.setInitialAttachApn(mPhone.getPhoneId(), dataProfile, isRoaming,
- callback);
- } catch (RemoteException e) {
- loge("Cannot invoke setInitialAttachApn on data service.");
- mMessageMap.remove(callback.asBinder());
- sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
- }
- }
-
- /**
- * Send current carrier's data profiles to the data service for data call setup. This is
- * only for CDMA carrier that can change the profile through OTA. The data service should
- * always uses the latest data profile sent by the framework.
- *
- * @param dps A list of data profiles.
- * @param isRoaming True if the device is data roaming.
- * @param onCompleteMessage The result message for this request. Null if the client does not
- * care about the result.
- */
- public void setDataProfile(List<DataProfile> dps, boolean isRoaming,
- Message onCompleteMessage) {
- if (DBG) log("setDataProfile");
- if (!mBound) {
- loge("Data service not bound.");
- sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
- return;
- }
-
- CellularDataServiceCallback callback = new CellularDataServiceCallback("setDataProfile");
- if (onCompleteMessage != null) {
- mMessageMap.put(callback.asBinder(), onCompleteMessage);
- }
- try {
- mIDataService.setDataProfile(mPhone.getPhoneId(), dps, isRoaming, callback);
- } catch (RemoteException e) {
- loge("Cannot invoke setDataProfile on data service.");
- mMessageMap.remove(callback.asBinder());
- sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
- }
- }
-
- /**
- * Get the active data call list.
- *
- * @param onCompleteMessage The result message for this request. Null if the client does not
- * care about the result.
- */
- public void requestDataCallList(Message onCompleteMessage) {
- if (DBG) log("requestDataCallList");
- if (!mBound) {
- loge("Data service not bound.");
- sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
- return;
- }
-
- CellularDataServiceCallback callback =
- new CellularDataServiceCallback("requestDataCallList");
- if (onCompleteMessage != null) {
- mMessageMap.put(callback.asBinder(), onCompleteMessage);
- }
- try {
- mIDataService.requestDataCallList(mPhone.getPhoneId(), callback);
- } catch (RemoteException e) {
- loge("Cannot invoke requestDataCallList on data service.");
- if (callback != null) {
- mMessageMap.remove(callback.asBinder());
- }
- sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
- }
- }
-
- /**
- * Register for data call list changed event.
- *
- * @param h The target to post the event message to.
- * @param what The event.
- */
- public void registerForDataCallListChanged(Handler h, int what) {
- if (h != null) {
- mDataCallListChangedRegistrants.addUnique(h, what, null);
- }
- }
-
- /**
- * Unregister for data call list changed event.
- *
- * @param h The handler
- */
- public void unregisterForDataCallListChanged(Handler h) {
- if (h != null) {
- mDataCallListChangedRegistrants.remove(h);
- }
- }
-
- /**
- * Register apn unthrottled event
- *
- * @param h The target to post the event message to.
- * @param what The event.
- */
- public void registerForApnUnthrottled(Handler h, int what) {
- if (h != null) {
- mApnUnthrottledRegistrants.addUnique(h, what, null);
- }
- }
-
- /**
- * Unregister for apn unthrottled event
- *
- * @param h The handler
- */
- public void unregisterForApnUnthrottled(Handler h) {
- if (h != null) {
- mApnUnthrottledRegistrants.remove(h);
- }
- }
-
- /**
- * Register for data service binding status changed event.
- *
- * @param h The target to post the event message to.
- * @param what The event.
- * @param obj The user object.
- */
- public void registerForServiceBindingChanged(Handler h, int what, Object obj) {
- if (h != null) {
- mServiceBindingChangedRegistrants.addUnique(h, what, obj);
- }
-
- }
-
- /**
- * Unregister for data service binding status changed event.
- *
- * @param h The handler
- */
- public void unregisterForServiceBindingChanged(Handler h) {
- if (h != null) {
- mServiceBindingChangedRegistrants.remove(h);
- }
- }
-
- /**
- * Get the transport type. Must be a {@link TransportType}.
- *
- * @return
- */
- @TransportType
- public int getTransportType() {
- return mTransportType;
- }
-
- private void log(String s) {
- Rlog.d(mTag, s);
- }
-
- private void loge(String s) {
- Rlog.e(mTag, s);
- }
-}
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataThrottler.java b/src/java/com/android/internal/telephony/dataconnection/DataThrottler.java
deleted file mode 100644
index 4a465d2..0000000
--- a/src/java/com/android/internal/telephony/dataconnection/DataThrottler.java
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import android.annotation.ElapsedRealtimeLong;
-import android.annotation.NonNull;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.PersistableBundle;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.Annotation;
-import android.telephony.Annotation.ApnType;
-import android.telephony.CarrierConfigManager;
-import android.telephony.SubscriptionManager;
-import android.telephony.data.ApnSetting;
-import android.telephony.data.ThrottleStatus;
-
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.RetryManager;
-import com.android.telephony.Rlog;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Data throttler tracks the throttling status of the data network and notifies registrants when
- * there are changes. The throttler is per phone and per transport type.
- */
-public class DataThrottler extends Handler {
- private static final String TAG = DataThrottler.class.getSimpleName();
-
- private static final int EVENT_SET_RETRY_TIME = 1;
- private static final int EVENT_CARRIER_CONFIG_CHANGED = 2;
- private static final int EVENT_RESET = 3;
- private static final int EVENT_AIRPLANE_MODE_CHANGED = 4;
- private static final int EVENT_TRACING_AREA_CODE_CHANGED = 5;
-
- private final Phone mPhone;
- private final int mSlotIndex;
- private final @AccessNetworkConstants.TransportType int mTransportType;
- private boolean mResetWhenAreaCodeChanged = false;
-
- /**
- * Callbacks that report the apn throttle status.
- */
- private final List<DataThrottler.Callback> mCallbacks = new ArrayList<>();
-
- /**
- * Keeps track of detailed information of the throttle status that is meant to be
- * reported to other components.
- */
- private final Map<Integer, ThrottleStatus> mThrottleStatus = new ConcurrentHashMap<>();
-
- private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
- if (mPhone.getPhoneId() == intent.getIntExtra(CarrierConfigManager.EXTRA_SLOT_INDEX,
- SubscriptionManager.INVALID_SIM_SLOT_INDEX)) {
- if (intent.getBooleanExtra(
- CarrierConfigManager.EXTRA_REBROADCAST_ON_UNLOCK, false)) {
- // Ignore the rebroadcast one to prevent multiple carrier config changed
- // event during boot up.
- return;
- }
- int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
- SubscriptionManager.INVALID_SUBSCRIPTION_ID);
- if (SubscriptionManager.isValidSubscriptionId(subId)) {
- sendEmptyMessage(EVENT_CARRIER_CONFIG_CHANGED);
- }
- }
- }
- }
- };
-
- public DataThrottler(Phone phone, int transportType) {
- super(null, false);
- mPhone = phone;
- mSlotIndex = phone.getPhoneId();
- mTransportType = transportType;
-
- IntentFilter filter = new IntentFilter();
- filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
- mPhone.getContext().registerReceiver(mBroadcastReceiver, filter, null, mPhone);
-
- mPhone.getServiceStateTracker().registerForAirplaneModeChanged(this,
- EVENT_AIRPLANE_MODE_CHANGED, null);
- mPhone.getServiceStateTracker().registerForAreaCodeChanged(this,
- EVENT_TRACING_AREA_CODE_CHANGED, null);
- }
-
- @Override
- public void handleMessage(Message msg) {
- AsyncResult ar;
- switch (msg.what) {
- case EVENT_SET_RETRY_TIME:
- int apnTypes = msg.arg1;
- int newRequestType = msg.arg2;
- long retryElapsedTime = (long) msg.obj;
- setRetryTimeInternal(apnTypes, retryElapsedTime, newRequestType);
- break;
- case EVENT_CARRIER_CONFIG_CHANGED:
- onCarrierConfigChanged();
- break;
- case EVENT_RESET:
- resetInternal();
- break;
- case EVENT_AIRPLANE_MODE_CHANGED:
- ar = (AsyncResult) msg.obj;
- if (!(Boolean) ar.result) {
- resetInternal();
- }
- break;
- case EVENT_TRACING_AREA_CODE_CHANGED:
- if (mResetWhenAreaCodeChanged) {
- resetInternal();
- }
- break;
- }
- }
-
- @NonNull
- private PersistableBundle getCarrierConfig() {
- CarrierConfigManager configManager = (CarrierConfigManager) mPhone.getContext()
- .getSystemService(Context.CARRIER_CONFIG_SERVICE);
- if (configManager != null) {
- // If an invalid subId is used, this bundle will contain default values.
- PersistableBundle config = configManager.getConfigForSubId(mPhone.getSubId());
- if (config != null) {
- return config;
- }
- }
- // Return static default defined in CarrierConfigManager.
- return CarrierConfigManager.getDefaultConfig();
- }
-
- private void onCarrierConfigChanged() {
- PersistableBundle config = getCarrierConfig();
- mResetWhenAreaCodeChanged = config.getBoolean(
- CarrierConfigManager.KEY_UNTHROTTLE_DATA_RETRY_WHEN_TAC_CHANGES_BOOL, false);
- }
-
- /**
- * Set the retry time and handover failure mode for the give APN types.
- *
- * @param apnTypes APN types
- * @param retryElapsedTime The elapsed time that data connection for APN types should not be
- * retried. {@link RetryManager#NO_SUGGESTED_RETRY_DELAY} indicates throttling does not exist.
- * {@link RetryManager#NO_RETRY} indicates retry should never happen.
- */
- public void setRetryTime(@ApnType int apnTypes, @ElapsedRealtimeLong long retryElapsedTime,
- @DcTracker.RequestNetworkType int newRequestType) {
- sendMessage(obtainMessage(EVENT_SET_RETRY_TIME, apnTypes, newRequestType,
- retryElapsedTime));
- }
-
- /**
- * Set the retry time and handover failure mode for the give APN types. This is running on the
- * handler thread.
- *
- * @param apnTypes APN types
- * @param retryElapsedTime The elapsed time that data connection for APN types should not be
- * retried. {@link RetryManager#NO_SUGGESTED_RETRY_DELAY} indicates throttling does not exist.
- * {@link RetryManager#NO_RETRY} indicates retry should never happen.
- */
- private void setRetryTimeInternal(@ApnType int apnTypes, @ElapsedRealtimeLong
- long retryElapsedTime, @DcTracker.RequestNetworkType int newRequestType) {
- if (retryElapsedTime < 0) {
- retryElapsedTime = RetryManager.NO_SUGGESTED_RETRY_DELAY;
- }
-
- List<ThrottleStatus> changedStatuses = new ArrayList<>();
- while (apnTypes != 0) {
- int apnType;
- // Due to an API mistake of ApnSetting.TYPE_DEFAULT (which combines default and hipri
- // bit), we need to do special handling here.
- if ((apnTypes & ApnSetting.TYPE_DEFAULT) == ApnSetting.TYPE_DEFAULT) {
- apnType = ApnSetting.TYPE_DEFAULT;
- apnTypes &= ~ApnSetting.TYPE_DEFAULT;
- } else {
- //Extract the least significant bit.
- apnType = apnTypes & -apnTypes;
- //Remove the least significant bit.
- apnTypes &= apnTypes - 1;
- }
-
- //Update the apn throttle status
- ThrottleStatus newStatus = createStatus(apnType, retryElapsedTime, newRequestType);
-
- ThrottleStatus oldStatus = mThrottleStatus.get(apnType);
-
- //Check to see if there is a change that needs to be applied
- if (!newStatus.equals(oldStatus)) {
- //Mark as changed status
- changedStatuses.add(newStatus);
-
- //Put the new status in the temp space
- mThrottleStatus.put(apnType, newStatus);
- }
- }
-
- if (changedStatuses.size() > 0) {
- sendThrottleStatusChanged(changedStatuses);
- }
- }
-
- /**
- * Get the earliest retry time for the given APN type. The time is the system's elapse time.
- *
- * Note the DataThrottler is running phone process's main thread, which is most of the telephony
- * components running on. Calling this method from other threads might run into race conditions.
- *
- * @param apnType APN type
- * @return The earliest retry time for APN type. The time is the system's elapse time.
- * {@link RetryManager#NO_SUGGESTED_RETRY_DELAY} indicates there is no throttling for given APN
- * type, {@link RetryManager#NO_RETRY} indicates retry should never happen.
- */
- @ElapsedRealtimeLong
- public long getRetryTime(@ApnType int apnType) {
- ThrottleStatus status = mThrottleStatus.get(apnType);
- if (status != null) {
- if (status.getThrottleType() == ThrottleStatus.THROTTLE_TYPE_NONE) {
- return RetryManager.NO_SUGGESTED_RETRY_DELAY;
- } else {
- return status.getThrottleExpiryTimeMillis();
- }
- }
- return RetryManager.NO_SUGGESTED_RETRY_DELAY;
- }
-
- /**
- * Resets retry times for all APNs to {@link RetryManager.NO_SUGGESTED_RETRY_DELAY}.
- */
- public void reset() {
- sendEmptyMessage(EVENT_RESET);
- }
-
- /**
- * Resets retry times for all APNs to {@link RetryManager.NO_SUGGESTED_RETRY_DELAY}.
- */
- private void resetInternal() {
- final List<Integer> apnTypes = new ArrayList<>();
- for (ThrottleStatus throttleStatus : mThrottleStatus.values()) {
- apnTypes.add(throttleStatus.getApnType());
- }
-
- for (int apnType : apnTypes) {
- setRetryTime(apnType, RetryManager.NO_SUGGESTED_RETRY_DELAY,
- DcTracker.REQUEST_TYPE_NORMAL);
- }
- }
-
- private ThrottleStatus createStatus(@Annotation.ApnType int apnType, long retryElapsedTime,
- @DcTracker.RequestNetworkType int newRequestType) {
- ThrottleStatus.Builder builder = new ThrottleStatus.Builder();
-
- if (retryElapsedTime == RetryManager.NO_SUGGESTED_RETRY_DELAY) {
- builder
- .setNoThrottle()
- .setRetryType(getRetryType(newRequestType));
- } else if (retryElapsedTime == RetryManager.NO_RETRY) {
- builder
- .setThrottleExpiryTimeMillis(RetryManager.NO_RETRY)
- .setRetryType(ThrottleStatus.RETRY_TYPE_NONE);
- } else {
- builder
- .setThrottleExpiryTimeMillis(retryElapsedTime)
- .setRetryType(getRetryType(newRequestType));
- }
- return builder
- .setSlotIndex(mSlotIndex)
- .setTransportType(mTransportType)
- .setApnType(apnType)
- .build();
- }
-
- private static int getRetryType(@DcTracker.RequestNetworkType int newRequestType) {
- if (newRequestType == DcTracker.REQUEST_TYPE_NORMAL) {
- return ThrottleStatus.RETRY_TYPE_NEW_CONNECTION;
- }
-
- if (newRequestType == DcTracker.REQUEST_TYPE_HANDOVER) {
- return ThrottleStatus.RETRY_TYPE_HANDOVER;
- }
-
- loge("createStatus: Unknown requestType=" + newRequestType);
- return ThrottleStatus.RETRY_TYPE_NEW_CONNECTION;
- }
-
- private void sendThrottleStatusChanged(List<ThrottleStatus> statuses) {
- synchronized (mCallbacks) {
- for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).onThrottleStatusChanged(statuses);
- }
- }
- }
-
- private static void loge(String s) {
- Rlog.e(TAG, s);
- }
-
- /**
- * Reports changes to apn throttle statuses.
- *
- * Note: All statuses are sent when first registered.
- *
- * @param callback status changes callback
- */
- public void registerForThrottleStatusChanges(DataThrottler.Callback callback) {
- synchronized (mCallbacks) {
- //Only add if it's not there already
- if (!mCallbacks.contains(callback)) {
- //Report everything the first time
- List<ThrottleStatus> throttleStatuses =
- new ArrayList<>(mThrottleStatus.values());
- callback.onThrottleStatusChanged(throttleStatuses);
- mCallbacks.add(callback);
- }
- }
- }
-
- /**
- * Unregister the callback
- * @param callback the callback to unregister
- */
- public void unregisterForThrottleStatusChanges(DataThrottler.Callback callback) {
- synchronized (mCallbacks) {
- mCallbacks.remove(callback);
- }
- }
-
- /**
- * Callback for when throttle statuses change
- */
- public interface Callback {
- /**
- * Called whenever the throttle status of an APN has changed.
- *
- * Note: Called with all statuses when first registered.
- *
- * @param throttleStatuses the status changes
- */
- void onThrottleStatusChanged(List<ThrottleStatus> throttleStatuses);
- }
-}
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcController.java b/src/java/com/android/internal/telephony/dataconnection/DcController.java
deleted file mode 100644
index c34157e..0000000
--- a/src/java/com/android/internal/telephony/dataconnection/DcController.java
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import android.hardware.radio.V1_4.DataConnActiveStatus;
-import android.net.LinkAddress;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RegistrantList;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.CarrierConfigManager;
-import android.telephony.DataFailCause;
-import android.telephony.data.ApnSetting;
-import android.telephony.data.DataCallResponse;
-import android.telephony.data.TrafficDescriptor;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.DctConstants;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.dataconnection.DataConnection.UpdateLinkPropertyResult;
-import com.android.internal.telephony.util.TelephonyUtils;
-import com.android.net.module.util.LinkPropertiesUtils;
-import com.android.net.module.util.LinkPropertiesUtils.CompareOrUpdateResult;
-import com.android.net.module.util.NetUtils;
-import com.android.telephony.Rlog;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Data Connection Controller which is a package visible class and controls
- * multiple data connections. For instance listening for unsolicited messages
- * and then demultiplexing them to the appropriate DC.
- */
-public class DcController extends Handler {
- private static final boolean DBG = true;
- private static final boolean VDBG = false;
-
- private final Phone mPhone;
- private final DcTracker mDct;
- private final String mTag;
- private final DataServiceManager mDataServiceManager;
- private final DcTesterDeactivateAll mDcTesterDeactivateAll;
-
- // package as its used by Testing code
- // @GuardedBy("mDcListAll")
- final ArrayList<DataConnection> mDcListAll = new ArrayList<>();
- // @GuardedBy("mDcListAll")
- private final HashMap<Integer, DataConnection> mDcListActiveByCid = new HashMap<>();
- // @GuardedBy("mTrafficDescriptorsByCid")
- private final HashMap<Integer, List<TrafficDescriptor>> mTrafficDescriptorsByCid =
- new HashMap<>();
-
- /**
- * Aggregated physical link status from all data connections. This reflects the device's RRC
- * connection state.
- * If {@link CarrierConfigManager#KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL} is true,
- * then This reflects "internet data connection" instead of RRC state.
- */
- private @DataCallResponse.LinkStatus int mPhysicalLinkStatus =
- DataCallResponse.LINK_STATUS_UNKNOWN;
-
- private RegistrantList mPhysicalLinkStatusChangedRegistrants = new RegistrantList();
-
- /**
- * Constructor.
- *
- * @param name to be used for the Controller
- * @param phone the phone associated with Dcc and Dct
- * @param dct the DataConnectionTracker associated with Dcc
- * @param dataServiceManager the data service manager that manages data services
- * @param looper looper for this handler
- */
- private DcController(String name, Phone phone, DcTracker dct,
- DataServiceManager dataServiceManager, Looper looper) {
- super(looper);
- mPhone = phone;
- mDct = dct;
- mTag = name;
- mDataServiceManager = dataServiceManager;
-
- mDcTesterDeactivateAll = (TelephonyUtils.IS_DEBUGGABLE)
- ? new DcTesterDeactivateAll(mPhone, DcController.this, this)
- : null;
- mDataServiceManager.registerForDataCallListChanged(this,
- DataConnection.EVENT_DATA_STATE_CHANGED);
- }
-
- public static DcController makeDcc(Phone phone, DcTracker dct,
- DataServiceManager dataServiceManager, Looper looper,
- String tagSuffix) {
- return new DcController("Dcc" + tagSuffix, phone, dct, dataServiceManager, looper);
- }
-
- void addDc(DataConnection dc) {
- synchronized (mDcListAll) {
- mDcListAll.add(dc);
- }
- }
-
- void removeDc(DataConnection dc) {
- synchronized (mDcListAll) {
- mDcListActiveByCid.remove(dc.mCid);
- mDcListAll.remove(dc);
- }
- synchronized (mTrafficDescriptorsByCid) {
- mTrafficDescriptorsByCid.remove(dc.mCid);
- }
- }
-
- public void addActiveDcByCid(DataConnection dc) {
- if (DBG && dc.mCid < 0) {
- log("addActiveDcByCid dc.mCid < 0 dc=" + dc);
- }
- synchronized (mDcListAll) {
- mDcListActiveByCid.put(dc.mCid, dc);
- }
- updateTrafficDescriptorsForCid(dc.mCid, dc.getTrafficDescriptors());
- }
-
- DataConnection getActiveDcByCid(int cid) {
- synchronized (mDcListAll) {
- return mDcListActiveByCid.get(cid);
- }
- }
-
- void removeActiveDcByCid(DataConnection dc) {
- synchronized (mDcListAll) {
- DataConnection removedDc = mDcListActiveByCid.remove(dc.mCid);
- if (DBG && removedDc == null) {
- log("removeActiveDcByCid removedDc=null dc=" + dc);
- }
- }
- synchronized (mTrafficDescriptorsByCid) {
- mTrafficDescriptorsByCid.remove(dc.mCid);
- }
- }
-
- boolean isDefaultDataActive() {
- synchronized (mDcListAll) {
- return mDcListActiveByCid.values().stream()
- .anyMatch(dc -> dc.getApnContexts().stream()
- .anyMatch(apn -> apn.getApnTypeBitmask() == ApnSetting.TYPE_DEFAULT));
- }
- }
-
- List<TrafficDescriptor> getTrafficDescriptorsForCid(int cid) {
- synchronized (mTrafficDescriptorsByCid) {
- return mTrafficDescriptorsByCid.get(cid);
- }
- }
-
- void updateTrafficDescriptorsForCid(int cid, List<TrafficDescriptor> tds) {
- synchronized (mTrafficDescriptorsByCid) {
- mTrafficDescriptorsByCid.put(cid, tds);
- }
- }
-
- @Override
- public void handleMessage(Message msg) {
- AsyncResult ar;
-
- switch (msg.what) {
- case DataConnection.EVENT_DATA_STATE_CHANGED:
- ar = (AsyncResult) msg.obj;
- if (ar.exception == null) {
- onDataStateChanged((ArrayList<DataCallResponse>) ar.result);
- } else {
- log("EVENT_DATA_STATE_CHANGED: exception; likely radio not available, ignore");
- }
- break;
- default:
- loge("Unexpected event " + msg);
- break;
- }
- }
-
- /**
- * Process the new list of "known" Data Calls
- * @param dcsList as sent by RIL_UNSOL_DATA_CALL_LIST_CHANGED
- */
- private void onDataStateChanged(ArrayList<DataCallResponse> dcsList) {
- final HashMap<Integer, DataConnection> dcListActiveByCid;
- synchronized (mDcListAll) {
- dcListActiveByCid = new HashMap<>(mDcListActiveByCid);
- }
-
- if (DBG) {
- log("onDataStateChanged: dcsList=" + dcsList
- + " dcListActiveByCid=" + dcListActiveByCid);
- }
-
- // Create hashmap of cid to DataCallResponse
- HashMap<Integer, DataCallResponse> dataCallResponseListByCid = new HashMap<>();
- for (DataCallResponse dcs : dcsList) {
- dataCallResponseListByCid.put(dcs.getId(), dcs);
- }
-
- // Add a DC that is active but not in the dcsList to the list of DC's to retry
- ArrayList<DataConnection> dcsToRetry = new ArrayList<>();
- for (DataConnection dc : dcListActiveByCid.values()) {
- DataCallResponse response = dataCallResponseListByCid.get(dc.mCid);
- if (response == null) {
- if (DBG) log("onDataStateChanged: add to retry dc=" + dc);
- dcsToRetry.add(dc);
- } else {
- List<TrafficDescriptor> oldTds = getTrafficDescriptorsForCid(dc.mCid);
- List<TrafficDescriptor> newTds = response.getTrafficDescriptors();
- if (!oldTds.equals(newTds)) {
- if (DBG) {
- log("onDataStateChanged: add to retry due to TD changed dc=" + dc
- + ", oldTds=" + oldTds + ", newTds=" + newTds);
- }
- updateTrafficDescriptorsForCid(dc.mCid, newTds);
- dcsToRetry.add(dc);
- }
- }
- }
- if (DBG) log("onDataStateChanged: dcsToRetry=" + dcsToRetry);
-
- // Find which connections have changed state and send a notification or cleanup
- // and any that are in active need to be retried.
- ArrayList<ApnContext> apnsToCleanup = new ArrayList<ApnContext>();
-
- boolean isAnyDataCallDormant = false;
- boolean isAnyDataCallActive = false;
- boolean isInternetDataCallActive = false;
-
- for (DataCallResponse newState : dcsList) {
-
- DataConnection dc = dcListActiveByCid.get(newState.getId());
- if (dc == null) {
- // UNSOL_DATA_CALL_LIST_CHANGED arrived before SETUP_DATA_CALL completed.
- loge("onDataStateChanged: no associated DC yet, ignore");
- continue;
- }
-
- List<ApnContext> apnContexts = dc.getApnContexts();
- if (apnContexts.size() == 0) {
- if (DBG) loge("onDataStateChanged: no connected apns, ignore");
- } else {
- // Determine if the connection/apnContext should be cleaned up
- // or just a notification should be sent out.
- if (DBG) {
- log("onDataStateChanged: Found ConnId=" + newState.getId()
- + " newState=" + newState.toString());
- }
- if (apnContexts.stream().anyMatch(
- i -> ApnSetting.TYPE_DEFAULT_STRING.equals(i.getApnType()))
- && newState.getLinkStatus() == DataConnActiveStatus.ACTIVE) {
- isInternetDataCallActive = true;
- }
- if (newState.getLinkStatus() == DataConnActiveStatus.INACTIVE) {
- if (mDct.isCleanupRequired.get()) {
- apnsToCleanup.addAll(apnContexts);
- mDct.isCleanupRequired.set(false);
- } else {
- int failCause = DataFailCause.getFailCause(newState.getCause());
- if (DataFailCause.isRadioRestartFailure(mPhone.getContext(), failCause,
- mPhone.getSubId())) {
- if (DBG) {
- log("onDataStateChanged: X restart radio, failCause="
- + failCause);
- }
- mDct.sendRestartRadio();
- } else if (mDct.isPermanentFailure(failCause)) {
- if (DBG) {
- log("onDataStateChanged: inactive, add to cleanup list. "
- + "failCause=" + failCause);
- }
- apnsToCleanup.addAll(apnContexts);
- } else {
- if (DBG) {
- log("onDataStateChanged: inactive, add to retry list. "
- + "failCause=" + failCause);
- }
- dcsToRetry.add(dc);
- }
- }
- } else {
- // Update the pdu session id
- dc.setPduSessionId(newState.getPduSessionId());
-
- dc.updatePcscfAddr(newState);
-
- // Its active so update the DataConnections link properties
- UpdateLinkPropertyResult result = dc.updateLinkProperty(newState);
- dc.updateResponseFields(newState);
- if (result.oldLp.equals(result.newLp)) {
- if (DBG) log("onDataStateChanged: no change");
- } else {
- if (LinkPropertiesUtils.isIdenticalInterfaceName(
- result.oldLp, result.newLp)) {
- if (!LinkPropertiesUtils.isIdenticalDnses(
- result.oldLp, result.newLp)
- || !LinkPropertiesUtils.isIdenticalRoutes(
- result.oldLp, result.newLp)
- || !LinkPropertiesUtils.isIdenticalHttpProxy(
- result.oldLp, result.newLp)
- || !LinkPropertiesUtils.isIdenticalAddresses(
- result.oldLp, result.newLp)) {
- // If the same address type was removed and
- // added we need to cleanup
- CompareOrUpdateResult<Integer, LinkAddress> car
- = new CompareOrUpdateResult(
- result.oldLp != null ?
- result.oldLp.getLinkAddresses() : null,
- result.newLp != null ?
- result.newLp.getLinkAddresses() : null,
- (la) -> Objects.hash(((LinkAddress)la).getAddress(),
- ((LinkAddress)la).getPrefixLength(),
- ((LinkAddress)la).getScope()));
- if (DBG) {
- log("onDataStateChanged: oldLp=" + result.oldLp
- + " newLp=" + result.newLp + " car=" + car);
- }
- boolean needToClean = false;
- for (LinkAddress added : car.added) {
- for (LinkAddress removed : car.removed) {
- if (NetUtils.addressTypeMatches(
- removed.getAddress(),
- added.getAddress())) {
- needToClean = true;
- break;
- }
- }
- }
- if (needToClean) {
- if (DBG) {
- log("onDataStateChanged: addr change,"
- + " cleanup apns=" + apnContexts
- + " oldLp=" + result.oldLp
- + " newLp=" + result.newLp);
- }
- apnsToCleanup.addAll(apnContexts);
- }
- } else {
- if (DBG) {
- log("onDataStateChanged: no changes");
- }
- }
- } else {
- apnsToCleanup.addAll(apnContexts);
- if (DBG) {
- log("onDataStateChanged: interface change, cleanup apns="
- + apnContexts);
- }
- }
- }
- }
- }
-
- if (newState.getLinkStatus() == DataConnActiveStatus.ACTIVE) {
- isAnyDataCallActive = true;
- }
- if (newState.getLinkStatus() == DataConnActiveStatus.DORMANT) {
- isAnyDataCallDormant = true;
- }
- }
-
- if (mDataServiceManager.getTransportType()
- == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
- boolean isPhysicalLinkStatusFocusingOnInternetData =
- mDct.getLteEndcUsingUserDataForIdleDetection();
- int physicalLinkStatus =
- (isPhysicalLinkStatusFocusingOnInternetData
- ? isInternetDataCallActive : isAnyDataCallActive)
- ? DataCallResponse.LINK_STATUS_ACTIVE
- : DataCallResponse.LINK_STATUS_DORMANT;
- if (mPhysicalLinkStatus != physicalLinkStatus) {
- mPhysicalLinkStatus = physicalLinkStatus;
- mPhysicalLinkStatusChangedRegistrants.notifyResult(mPhysicalLinkStatus);
- }
- if (isAnyDataCallDormant && !isAnyDataCallActive) {
- // There is no way to indicate link activity per APN right now. So
- // Link Activity will be considered dormant only when all data calls
- // are dormant.
- // If a single data call is in dormant state and none of the data
- // calls are active broadcast overall link status as dormant.
- if (DBG) {
- log("onDataStateChanged: Data activity DORMANT. stopNetStatePoll");
- }
- mDct.sendStopNetStatPoll(DctConstants.Activity.DORMANT);
- } else {
- if (DBG) {
- log("onDataStateChanged: Data Activity updated to NONE. "
- + "isAnyDataCallActive = " + isAnyDataCallActive
- + " isAnyDataCallDormant = " + isAnyDataCallDormant);
- }
- if (isAnyDataCallActive) {
- mDct.sendStartNetStatPoll(DctConstants.Activity.NONE);
- }
- }
- }
-
- if (DBG) {
- log("onDataStateChanged: dcsToRetry=" + dcsToRetry
- + " apnsToCleanup=" + apnsToCleanup);
- }
-
- // Cleanup connections that have changed
- for (ApnContext apnContext : apnsToCleanup) {
- mDct.cleanUpConnection(apnContext);
- }
-
- // Retry connections that have disappeared
- for (DataConnection dc : dcsToRetry) {
- if (DBG) log("onDataStateChanged: send EVENT_LOST_CONNECTION dc.mTag=" + dc.mTag);
- dc.sendMessage(DataConnection.EVENT_LOST_CONNECTION, dc.mTag);
- }
-
- if (VDBG) log("onDataStateChanged: X");
- }
-
- /**
- * Register for physical link status (i.e. RRC state) changed event.
- * if {@link CarrierConfigManager#KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL} is true,
- * then physical link status is focusing on "internet data connection" instead of RRC state.
- * @param h The handler
- * @param what The event
- */
- @VisibleForTesting
- public void registerForPhysicalLinkStatusChanged(Handler h, int what) {
- mPhysicalLinkStatusChangedRegistrants.addUnique(h, what, null);
- }
-
- /**
- * Unregister from physical link status (i.e. RRC state) changed event.
- *
- * @param h The previously registered handler
- */
- void unregisterForPhysicalLinkStatusChanged(Handler h) {
- mPhysicalLinkStatusChangedRegistrants.remove(h);
- }
-
- private void log(String s) {
- Rlog.d(mTag, s);
- }
-
- private void loge(String s) {
- Rlog.e(mTag, s);
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- synchronized (mDcListAll) {
- sb.append("mDcListAll=").append(mDcListAll)
- .append(" mDcListActiveByCid=").append(mDcListActiveByCid);
- }
- synchronized (mTrafficDescriptorsByCid) {
- sb.append("mTrafficDescriptorsByCid=").append(mTrafficDescriptorsByCid);
- }
- return sb.toString();
- }
-
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println(" mPhone=" + mPhone);
- synchronized (mDcListAll) {
- pw.println(" mDcListAll=" + mDcListAll);
- pw.println(" mDcListActiveByCid=" + mDcListActiveByCid);
- }
- synchronized (mTrafficDescriptorsByCid) {
- pw.println(" mTrafficDescriptorsByCid=" + mTrafficDescriptorsByCid);
- }
- }
-}
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcFailBringUp.java b/src/java/com/android/internal/telephony/dataconnection/DcFailBringUp.java
deleted file mode 100644
index 3cdd209..0000000
--- a/src/java/com/android/internal/telephony/dataconnection/DcFailBringUp.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import android.content.Intent;
-import android.telephony.Annotation.DataFailureCause;
-import android.telephony.DataFailCause;
-
-import com.android.telephony.Rlog;
-
-/**
- * A package visible class for supporting testing failing bringUp commands. This
- * saves the parameters from a action_fail_bringup intent. See
- * {@link DataConnection#doOnConnect} and {@see DcTesterFailBringUpAll} for more info.
- */
-public class DcFailBringUp {
- private static final String LOG_TAG = "DcFailBringUp";
- private static final boolean DBG = true;
-
- static final String INTENT_BASE = DataConnection.class.getPackage().getName();
-
- static final String ACTION_FAIL_BRINGUP = "action_fail_bringup";
-
- // counter with its --ei option name and default value
- static final String COUNTER = "counter";
- static final int DEFAULT_COUNTER = 2;
- int mCounter;
-
- // failCause with its --ei option name and default value
- static final String FAIL_CAUSE = "fail_cause";
- static final int DEFAULT_FAIL_CAUSE = DataFailCause.ERROR_UNSPECIFIED;
- @DataFailureCause
- int mFailCause;
-
- // suggestedRetryTime with its --ei option name and default value
- static final String SUGGESTED_RETRY_TIME = "suggested_retry_time";
- static final long DEFAULT_SUGGESTED_RETRY_TIME = -1;
- long mSuggestedRetryTime;
-
- // Get the Extra Intent parameters
- void saveParameters(Intent intent, String s) {
- if (DBG) log(s + ".saveParameters: action=" + intent.getAction());
- mCounter = intent.getIntExtra(COUNTER, DEFAULT_COUNTER);
- mFailCause = DataFailCause.getFailCause(
- intent.getIntExtra(FAIL_CAUSE, DEFAULT_FAIL_CAUSE));
- mSuggestedRetryTime =
- intent.getLongExtra(SUGGESTED_RETRY_TIME, DEFAULT_SUGGESTED_RETRY_TIME);
- if (DBG) {
- log(s + ".saveParameters: " + this);
- }
- }
-
- public void saveParameters(int counter, @DataFailureCause int failCause,
- long suggestedRetryTime) {
- mCounter = counter;
- mFailCause = DataFailCause.getFailCause(failCause);
- mSuggestedRetryTime = suggestedRetryTime;
- }
-
- @Override
- public String toString() {
- return "{mCounter=" + mCounter +
- " mFailCause=" + mFailCause +
- " mSuggestedRetryTime=" + mSuggestedRetryTime + "}";
-
- }
-
- private static void log(String s) {
- Rlog.d(LOG_TAG, s);
- }
-}
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcNetworkAgent.java b/src/java/com/android/internal/telephony/dataconnection/DcNetworkAgent.java
deleted file mode 100644
index c6def34..0000000
--- a/src/java/com/android/internal/telephony/dataconnection/DcNetworkAgent.java
+++ /dev/null
@@ -1,617 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.KeepalivePacketData;
-import android.net.LinkProperties;
-import android.net.NattKeepalivePacketData;
-import android.net.NetworkAgent;
-import android.net.NetworkAgentConfig;
-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.Handler;
-import android.os.Message;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.AccessNetworkConstants.TransportType;
-import android.telephony.Annotation.NetworkType;
-import android.telephony.AnomalyReporter;
-import android.telephony.NetworkRegistrationInfo;
-import android.telephony.ServiceState;
-import android.telephony.TelephonyManager;
-import android.telephony.data.QosBearerSession;
-import android.util.LocalLog;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.DctConstants;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.SlidingWindowEventCounter;
-import com.android.internal.telephony.data.KeepaliveStatus;
-import com.android.internal.telephony.data.NotifyQosSessionInterface;
-import com.android.internal.telephony.data.QosCallbackTracker;
-import com.android.internal.telephony.metrics.TelephonyMetrics;
-import com.android.internal.util.IndentingPrintWriter;
-import com.android.telephony.Rlog;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.net.InetAddress;
-import java.time.Duration;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
-/**
- * This class represents a network agent which is communication channel between
- * {@link DataConnection} and {@link com.android.server.ConnectivityService}. The agent is
- * created when data connection enters {@link DataConnection.DcActiveState} until it exits that
- * state.
- *
- * Note that in IWLAN handover scenario, this agent could be transferred to the new
- * {@link DataConnection} so for a short window of time this object might be accessed by two
- * different {@link DataConnection}. Thus each method in this class needs to be synchronized.
- */
-public class DcNetworkAgent extends NetworkAgent implements NotifyQosSessionInterface {
- private final String mTag;
-
- private final int mId;
-
- private final Phone mPhone;
-
- private final Handler mHandler;
-
- private int mTransportType;
-
- private NetworkCapabilities mNetworkCapabilities;
-
- public final DcKeepaliveTracker keepaliveTracker = new DcKeepaliveTracker();
-
- private final QosCallbackTracker mQosCallbackTracker;
-
- private final Executor mQosCallbackExecutor = Executors.newSingleThreadExecutor();
-
- private DataConnection mDataConnection;
-
- private final LocalLog mNetCapsLocalLog = new LocalLog(32);
-
- // For interface duplicate detection. Key is the net id, value is the interface name in string.
- private static Map<Integer, String> sInterfaceNames = new ConcurrentHashMap<>();
-
- private static final long NETWORK_UNWANTED_ANOMALY_WINDOW_MS = TimeUnit.MINUTES.toMillis(5);
- private static final int NETWORK_UNWANTED_ANOMALY_NUM_OCCURRENCES = 12;
-
- private static final int EVENT_UNWANTED_TIMEOUT = 1;
-
- @VisibleForTesting
- public DcNetworkAgent(DataConnection dc, Phone phone, int score, NetworkAgentConfig config,
- NetworkProvider networkProvider, int transportType) {
- super(phone.getContext(), dc.getHandler().getLooper(), "DcNetworkAgent",
- dc.getNetworkCapabilities(), dc.getLinkProperties(), score, config,
- networkProvider);
- register();
- mId = getNetwork().getNetId();
- mTag = "DcNetworkAgent" + "-" + mId;
- mPhone = phone;
- mHandler = new Handler(dc.getHandler().getLooper()) {
- @Override
- public void handleMessage(Message msg) {
- if (msg.what == EVENT_UNWANTED_TIMEOUT) {
- loge("onNetworkUnwanted timed out. Perform silent de-register.");
- logd("Unregister from connectivity service. " + sInterfaceNames.get(mId)
- + " removed.");
- sInterfaceNames.remove(mId);
- DcNetworkAgent.this.unregister();
- }
- }
- };
- mNetworkCapabilities = dc.getNetworkCapabilities();
- mTransportType = transportType;
- mDataConnection = dc;
- if (dc.getLinkProperties() != null) {
- checkDuplicateInterface(mId, dc.getLinkProperties().getInterfaceName());
- logd("created for data connection " + dc.getName() + ", "
- + dc.getLinkProperties().getInterfaceName());
- } else {
- loge("The connection does not have a valid link properties.");
- }
- mQosCallbackTracker = new QosCallbackTracker(this, mPhone);
- }
-
- private @NetworkType int getNetworkType() {
- ServiceState ss = mPhone.getServiceState();
- int networkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
-
- NetworkRegistrationInfo nri = ss.getNetworkRegistrationInfo(
- NetworkRegistrationInfo.DOMAIN_PS, mTransportType);
- if (nri != null) {
- networkType = nri.getAccessNetworkTechnology();
- }
-
- return networkType;
- }
-
- private void checkDuplicateInterface(int netId, @Nullable String interfaceName) {
- for (Map.Entry<Integer, String> entry: sInterfaceNames.entrySet()) {
- if (Objects.equals(interfaceName, entry.getValue())) {
- String message = "Duplicate interface " + interfaceName
- + " is detected. DcNetworkAgent-" + entry.getKey()
- + " already used this interface name.";
- loge(message);
- // Using fixed UUID to avoid duplicate bugreport notification
- AnomalyReporter.reportAnomaly(
- UUID.fromString("02f3d3f6-4613-4415-b6cb-8d92c8a938a6"),
- message, mPhone.getCarrierId());
- return;
- }
- }
- sInterfaceNames.put(netId, interfaceName);
- }
-
- /**
- * @return The tag
- */
- String getTag() {
- return mTag;
- }
-
- /**
- * Set the data connection that owns this network agent.
- *
- * @param dc Data connection owning this network agent.
- * @param transportType Transport that this data connection is on.
- */
- public synchronized void acquireOwnership(@NonNull DataConnection dc,
- @TransportType int transportType) {
- mDataConnection = dc;
- mTransportType = transportType;
- logd(dc.getName() + " acquired the ownership of this agent.");
- }
-
- /**
- * Release the ownership of network agent.
- */
- public synchronized void releaseOwnership(DataConnection dc) {
- if (mDataConnection == null) {
- loge("releaseOwnership called on no-owner DcNetworkAgent!");
- return;
- } else if (mDataConnection != dc) {
- loge("releaseOwnership: This agent belongs to "
- + mDataConnection.getName() + ", ignored the request from " + dc.getName());
- return;
- }
- logd("Data connection " + mDataConnection.getName() + " released the ownership.");
- mDataConnection = null;
- }
-
- /**
- * @return The data connection that owns this agent
- */
- public synchronized DataConnection getDataConnection() {
- return mDataConnection;
- }
-
- private static final SlidingWindowEventCounter sNetworkUnwantedCounter =
- new SlidingWindowEventCounter(NETWORK_UNWANTED_ANOMALY_WINDOW_MS,
- NETWORK_UNWANTED_ANOMALY_NUM_OCCURRENCES);
-
- @Override
- public synchronized void onNetworkUnwanted() {
- mHandler.sendEmptyMessageDelayed(EVENT_UNWANTED_TIMEOUT, TimeUnit.SECONDS.toMillis(30));
- trackNetworkUnwanted();
- if (mDataConnection == null) {
- loge("onNetworkUnwanted found called on no-owner DcNetworkAgent!");
- return;
- }
-
- logd("onNetworkUnwanted called. Now tear down the data connection "
- + mDataConnection.getName());
- mDataConnection.tearDownAll(Phone.REASON_RELEASED_BY_CONNECTIVITY_SERVICE,
- DcTracker.RELEASE_TYPE_DETACH, null);
- }
-
- /**
- * There have been several bugs where a RECONNECT loop kicks off where a DataConnection
- * connects to the Network, ConnectivityService indicates that the Network is unwanted,
- * and then the DataConnection reconnects. By the time we get the bug report it's too late
- * because there have already been hundreds of RECONNECTS. This is meant to capture the issue
- * when it first starts.
- *
- * The unwanted counter is configured to only take an anomaly report in extreme cases.
- * This is to avoid having the anomaly message show up on several devices.
- *
- * This is directly related to b/175845538. But, there have been several other occurrences of
- * this issue.
- */
- private void trackNetworkUnwanted() {
- if (sNetworkUnwantedCounter.addOccurrence()) {
- AnomalyReporter.reportAnomaly(
- UUID.fromString("3f578b5c-64e9-11eb-ae93-0242ac130002"),
- "Network Unwanted called 12 times in 5 minutes.", mPhone.getCarrierId());
- }
- }
-
- @Override
- public synchronized void onBandwidthUpdateRequested() {
- if (mDataConnection == null) {
- loge("onBandwidthUpdateRequested called on no-owner DcNetworkAgent!");
- return;
- }
-
- if (mPhone.getLceStatus() == RILConstants.LCE_ACTIVE // active LCE service
- && mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
- mPhone.mCi.pullLceData(mDataConnection.obtainMessage(
- DataConnection.EVENT_BW_REFRESH_RESPONSE));
- }
- }
-
- @Override
- public synchronized void onValidationStatus(int status, Uri redirectUri) {
- if (mDataConnection == null) {
- loge("onValidationStatus called on no-owner DcNetworkAgent!");
- return;
- }
-
- logd("validation status: " + status + " with redirection URL: " + redirectUri);
- DcTracker dct = mPhone.getDcTracker(mTransportType);
- if (dct != null) {
- Message msg = dct.obtainMessage(DctConstants.EVENT_NETWORK_STATUS_CHANGED,
- status, mDataConnection.getCid(), redirectUri.toString());
- msg.sendToTarget();
- }
- }
-
- private synchronized boolean isOwned(DataConnection dc, String reason) {
- if (mDataConnection == null) {
- loge(reason + " called on no-owner DcNetworkAgent!");
- return false;
- } else if (mDataConnection != dc) {
- loge(reason + ": This agent belongs to "
- + mDataConnection.getName() + ", ignored the request from " + dc.getName());
- return false;
- }
- return true;
- }
-
- /**
- * Update the legacy sub type (i.e. data network type).
- *
- * @param dc The data connection that invokes this method.
- */
- public synchronized void updateLegacySubtype(DataConnection dc) {
- if (!isOwned(dc, "updateLegacySubtype")) return;
-
- int networkType = getNetworkType();
- setLegacySubtype(networkType, TelephonyManager.getNetworkTypeName(networkType));
- }
-
- /**
- * Set the network capabilities.
- *
- * @param networkCapabilities The network capabilities.
- * @param dc The data connection that invokes this method.
- */
- public synchronized void sendNetworkCapabilities(NetworkCapabilities networkCapabilities,
- DataConnection dc) {
- if (!isOwned(dc, "sendNetworkCapabilities")) return;
-
- if (!networkCapabilities.equals(mNetworkCapabilities)) {
- String logStr = "Changed from " + mNetworkCapabilities + " to "
- + networkCapabilities + ", Data RAT="
- + mPhone.getServiceState().getRilDataRadioTechnology()
- + ", dc=" + mDataConnection.getName();
- logd(logStr);
- mNetCapsLocalLog.log(logStr);
- if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
- // only log metrics for DataConnection with NET_CAPABILITY_INTERNET
- if (mNetworkCapabilities == null
- || networkCapabilities.hasCapability(
- NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED)
- != mNetworkCapabilities.hasCapability(
- NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED)) {
- TelephonyMetrics.getInstance().writeNetworkCapabilitiesChangedEvent(
- mPhone.getPhoneId(), networkCapabilities);
- }
- }
- mNetworkCapabilities = networkCapabilities;
- }
- sendNetworkCapabilities(networkCapabilities);
- }
-
- /**
- * Set the link properties
- *
- * @param linkProperties The link properties
- * @param dc The data connection that invokes this method.
- */
- public synchronized void sendLinkProperties(@NonNull LinkProperties linkProperties,
- DataConnection dc) {
- if (!isOwned(dc, "sendLinkProperties")) return;
-
- sInterfaceNames.put(mId, dc.getLinkProperties().getInterfaceName());
- sendLinkProperties(linkProperties);
- }
-
- /**
- * Set the network score.
- *
- * @param score The network score.
- * @param dc The data connection that invokes this method.
- */
- public synchronized void sendNetworkScore(int score, DataConnection dc) {
- if (!isOwned(dc, "sendNetworkScore")) return;
- sendNetworkScore(score);
- }
-
- /**
- * Unregister the network agent from connectivity service.
- *
- * @param dc The data connection that invokes this method.
- */
- public synchronized void unregister(DataConnection dc) {
- if (!isOwned(dc, "unregister")) return;
-
- mHandler.removeMessages(EVENT_UNWANTED_TIMEOUT);
- logd("Unregister from connectivity service. " + sInterfaceNames.get(mId) + " removed.");
- sInterfaceNames.remove(mId);
- super.unregister();
- }
-
- @Override
- public synchronized void onStartSocketKeepalive(int slot, @NonNull Duration interval,
- @NonNull KeepalivePacketData packet) {
- if (mDataConnection == null) {
- loge("onStartSocketKeepalive called on no-owner DcNetworkAgent!");
- return;
- }
-
- if (packet instanceof NattKeepalivePacketData) {
- mDataConnection.obtainMessage(DataConnection.EVENT_KEEPALIVE_START_REQUEST,
- slot, (int) interval.getSeconds(), packet).sendToTarget();
- } else {
- sendSocketKeepaliveEvent(slot, SocketKeepalive.ERROR_UNSUPPORTED);
- }
- }
-
- @Override
- public synchronized void onStopSocketKeepalive(int slot) {
- if (mDataConnection == null) {
- loge("onStopSocketKeepalive called on no-owner DcNetworkAgent!");
- return;
- }
-
- mDataConnection.obtainMessage(DataConnection.EVENT_KEEPALIVE_STOP_REQUEST, slot)
- .sendToTarget();
- }
-
- @Override
- public void onQosCallbackRegistered(final int qosCallbackId, final @NonNull QosFilter filter) {
- mQosCallbackExecutor.execute(() -> mQosCallbackTracker.addFilter(qosCallbackId,
- new QosCallbackTracker.IFilter() {
- @Override
- public boolean matchesLocalAddress(
- InetAddress address, int startPort, int endPort) {
- return filter.matchesLocalAddress(address, startPort, endPort);
- }
-
- @Override
- public boolean matchesRemoteAddress(
- InetAddress address, int startPort, int endPort) {
- return filter.matchesRemoteAddress(address, startPort, endPort);
- }
- }));
- }
-
- @Override
- public void onQosCallbackUnregistered(final int qosCallbackId) {
- mQosCallbackExecutor.execute(() -> mQosCallbackTracker.removeFilter(qosCallbackId));
- }
-
- void updateQosBearerSessions(final List<QosBearerSession> qosBearerSessions) {
- mQosCallbackExecutor.execute(() -> mQosCallbackTracker.updateSessions(qosBearerSessions));
- }
-
- @Override
- public void notifyQosSessionAvailable(final int qosCallbackId, final int sessionId,
- @NonNull final QosSessionAttributes attributes) {
- super.sendQosSessionAvailable(qosCallbackId, sessionId, attributes);
- }
-
- @Override
- public void notifyQosSessionLost(final int qosCallbackId,
- final int sessionId, final int qosSessionType) {
- super.sendQosSessionLost(qosCallbackId, sessionId, qosSessionType);
- }
-
- @Override
- public String toString() {
- return "DcNetworkAgent-"
- + mId
- + " mDataConnection="
- + ((mDataConnection != null) ? mDataConnection.getName() : null)
- + " mTransportType="
- + AccessNetworkConstants.transportTypeToString(mTransportType)
- + " " + ((mDataConnection != null) ? mDataConnection.getLinkProperties() : null)
- + " mNetworkCapabilities=" + mNetworkCapabilities;
- }
-
- /**
- * Dump the state of transport manager
- *
- * @param fd File descriptor
- * @param printWriter Print writer
- * @param args Arguments
- */
- public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
- IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " ");
- pw.println(toString());
- pw.increaseIndent();
- pw.println("Net caps logs:");
- mNetCapsLocalLog.dump(fd, pw, args);
- pw.decreaseIndent();
- }
-
- /**
- * Log with debug level
- *
- * @param s is string log
- */
- private void logd(String s) {
- Rlog.d(mTag, s);
- }
-
- /**
- * Log with error level
- *
- * @param s is string log
- */
- private void loge(String s) {
- Rlog.e(mTag, s);
- }
-
- class DcKeepaliveTracker {
- private class KeepaliveRecord {
- public int slotId;
- public int currentStatus;
-
- KeepaliveRecord(int slotId, int status) {
- this.slotId = slotId;
- this.currentStatus = status;
- }
- }
-
- private final SparseArray<KeepaliveRecord> mKeepalives = new SparseArray();
-
- int getHandleForSlot(int slotId) {
- for (int i = 0; i < mKeepalives.size(); i++) {
- KeepaliveRecord kr = mKeepalives.valueAt(i);
- if (kr.slotId == slotId) return mKeepalives.keyAt(i);
- }
- return -1;
- }
-
- int keepaliveStatusErrorToPacketKeepaliveError(int error) {
- switch(error) {
- case KeepaliveStatus.ERROR_NONE:
- return SocketKeepalive.SUCCESS;
- case KeepaliveStatus.ERROR_UNSUPPORTED:
- return SocketKeepalive.ERROR_UNSUPPORTED;
- case KeepaliveStatus.ERROR_NO_RESOURCES:
- return SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES;
- case KeepaliveStatus.ERROR_UNKNOWN:
- default:
- return SocketKeepalive.ERROR_HARDWARE_ERROR;
- }
- }
-
- void handleKeepaliveStarted(final int slot, KeepaliveStatus ks) {
- switch (ks.statusCode) {
- case KeepaliveStatus.STATUS_INACTIVE:
- DcNetworkAgent.this.sendSocketKeepaliveEvent(slot,
- keepaliveStatusErrorToPacketKeepaliveError(ks.errorCode));
- break;
- case KeepaliveStatus.STATUS_ACTIVE:
- DcNetworkAgent.this.sendSocketKeepaliveEvent(
- slot, SocketKeepalive.SUCCESS);
- // fall through to add record
- case KeepaliveStatus.STATUS_PENDING:
- logd("Adding keepalive handle="
- + ks.sessionHandle + " slot = " + slot);
- mKeepalives.put(ks.sessionHandle,
- new KeepaliveRecord(
- slot, ks.statusCode));
- break;
- default:
- logd("Invalid KeepaliveStatus Code: " + ks.statusCode);
- break;
- }
- }
-
- void handleKeepaliveStatus(KeepaliveStatus ks) {
- final KeepaliveRecord kr;
- kr = mKeepalives.get(ks.sessionHandle);
-
- if (kr == null) {
- // If there is no slot for the session handle, we received an event
- // for a different data connection. This is not an error because the
- // keepalive session events are broadcast to all listeners.
- loge("Discarding keepalive event for different data connection:" + ks);
- return;
- }
- // Switch on the current state, to see what we do with the status update
- switch (kr.currentStatus) {
- case KeepaliveStatus.STATUS_INACTIVE:
- logd("Inactive Keepalive received status!");
- DcNetworkAgent.this.sendSocketKeepaliveEvent(
- kr.slotId, SocketKeepalive.ERROR_HARDWARE_ERROR);
- break;
- case KeepaliveStatus.STATUS_PENDING:
- switch (ks.statusCode) {
- case KeepaliveStatus.STATUS_INACTIVE:
- DcNetworkAgent.this.sendSocketKeepaliveEvent(kr.slotId,
- keepaliveStatusErrorToPacketKeepaliveError(ks.errorCode));
- kr.currentStatus = KeepaliveStatus.STATUS_INACTIVE;
- mKeepalives.remove(ks.sessionHandle);
- break;
- case KeepaliveStatus.STATUS_ACTIVE:
- logd("Pending Keepalive received active status!");
- kr.currentStatus = KeepaliveStatus.STATUS_ACTIVE;
- DcNetworkAgent.this.sendSocketKeepaliveEvent(
- kr.slotId, SocketKeepalive.SUCCESS);
- break;
- case KeepaliveStatus.STATUS_PENDING:
- loge("Invalid unsolicied Keepalive Pending Status!");
- break;
- default:
- loge("Invalid Keepalive Status received, " + ks.statusCode);
- }
- break;
- case KeepaliveStatus.STATUS_ACTIVE:
- switch (ks.statusCode) {
- case KeepaliveStatus.STATUS_INACTIVE:
- logd("Keepalive received stopped status!");
- DcNetworkAgent.this.sendSocketKeepaliveEvent(
- kr.slotId, SocketKeepalive.SUCCESS);
-
- kr.currentStatus = KeepaliveStatus.STATUS_INACTIVE;
- mKeepalives.remove(ks.sessionHandle);
- break;
- case KeepaliveStatus.STATUS_PENDING:
- case KeepaliveStatus.STATUS_ACTIVE:
- loge("Active Keepalive received invalid status!");
- break;
- default:
- loge("Invalid Keepalive Status received, " + ks.statusCode);
- }
- break;
- default:
- loge("Invalid Keepalive Status received, " + kr.currentStatus);
- }
- }
- }
-}
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcRequest.java b/src/java/com/android/internal/telephony/dataconnection/DcRequest.java
deleted file mode 100644
index da775e8..0000000
--- a/src/java/com/android/internal/telephony/dataconnection/DcRequest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.telephony.dataconnection;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.NetworkRequest;
-import android.net.NetworkSpecifier;
-import android.net.TelephonyNetworkSpecifier;
-import android.telephony.Annotation.ApnType;
-
-import com.android.telephony.Rlog;
-
-/**
- * Wraps cellular network requests to configured apn types.
- */
-public class DcRequest implements Comparable<DcRequest> {
- private static final String LOG_TAG = "DcRequest";
-
- @NonNull
- public final NetworkRequest networkRequest;
- public final int priority;
- public final @ApnType int apnType;
-
- private DcRequest(@NonNull final NetworkRequest nr, @ApnType final int type,
- int apnPriority) {
- networkRequest = nr;
- priority = apnPriority;
- apnType = type;
- }
-
- /**
- * Create a DcRequest based off of the network request. If the network request is not cellular,
- * then null is returned and a warning is generated.
- * @param networkRequest sets the type of dc request
- * @param apnConfigTypeRepository apn config types to match on the network request
- * @return corresponding DcRequest
- *
- */
- @Nullable
- public static DcRequest create(@NonNull final NetworkRequest networkRequest,
- @NonNull final ApnConfigTypeRepository apnConfigTypeRepository) {
- final int apnType = ApnContext.getApnTypeFromNetworkRequest(networkRequest);
- final ApnConfigType apnConfigType = apnConfigTypeRepository.getByType(apnType);
- if (apnConfigType == null) {
- Rlog.d(LOG_TAG, "Non cellular request ignored: " + networkRequest.toString());
- checkForAnomalousNetworkRequest(networkRequest);
- return null;
- } else {
- Rlog.d(LOG_TAG, "Cellular request confirmed: " + networkRequest.toString());
- return new DcRequest(networkRequest, apnType, apnConfigType.getPriority());
- }
- }
-
- private static void checkForAnomalousNetworkRequest(NetworkRequest networkRequest) {
- NetworkSpecifier specifier = networkRequest.getNetworkSpecifier();
- if (specifier != null) {
- if (specifier instanceof TelephonyNetworkSpecifier) {
- reportAnomalousNetworkRequest(networkRequest);
- }
- }
- }
-
- private static void reportAnomalousNetworkRequest(NetworkRequest networkRequest) {
- //TODO: Report anomaly if this happens
- Rlog.w(LOG_TAG, "A TelephonyNetworkSpecifier for a non-cellular request is invalid: "
- + networkRequest.toString());
-
- }
-
- public String toString() {
- return networkRequest.toString() + ", priority=" + priority + ", apnType=" + apnType;
- }
-
- public int hashCode() {
- return networkRequest.hashCode();
- }
-
- public boolean equals(Object o) {
- if (o instanceof DcRequest) {
- return networkRequest.equals(((DcRequest)o).networkRequest);
- }
- return false;
- }
-
- public int compareTo(DcRequest o) {
- return o.priority - priority;
- }
-}
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTesterDeactivateAll.java b/src/java/com/android/internal/telephony/dataconnection/DcTesterDeactivateAll.java
deleted file mode 100644
index 11a0ae6..0000000
--- a/src/java/com/android/internal/telephony/dataconnection/DcTesterDeactivateAll.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Handler;
-
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.util.TelephonyUtils;
-import com.android.telephony.Rlog;
-
-/**
- * To bring down all DC's send the following intent:
- *
- * adb shell am broadcast -a com.android.internal.telephony.dataconnection.action_deactivate_all
- */
-public class DcTesterDeactivateAll {
- private static final String LOG_TAG = "DcTesterDeacativateAll";
- private static final boolean DBG = true;
-
- private Phone mPhone;
- private DcController mDcc;
-
- public static String sActionDcTesterDeactivateAll =
- "com.android.internal.telephony.dataconnection.action_deactivate_all";
-
-
- // The static intent receiver one for all instances and we assume this
- // is running on the same thread as Dcc.
- protected BroadcastReceiver sIntentReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (DBG) log("sIntentReceiver.onReceive: action=" + action);
- if (action.equals(sActionDcTesterDeactivateAll)
- || action.equals(mPhone.getActionDetached())) {
- log("Send DEACTIVATE to all Dcc's");
- if (mDcc != null) {
- for (DataConnection dc : mDcc.mDcListAll) {
- dc.tearDownNow();
- }
- } else {
- if (DBG) log("onReceive: mDcc is null, ignoring");
- }
- } else {
- if (DBG) log("onReceive: unknown action=" + action);
- }
- }
- };
-
- DcTesterDeactivateAll(Phone phone, DcController dcc, Handler handler) {
- mPhone = phone;
- mDcc = dcc;
-
- if (TelephonyUtils.IS_DEBUGGABLE) {
- IntentFilter filter = new IntentFilter();
-
- filter.addAction(sActionDcTesterDeactivateAll);
- log("register for intent action=" + sActionDcTesterDeactivateAll);
-
- filter.addAction(mPhone.getActionDetached());
- log("register for intent action=" + mPhone.getActionDetached());
-
- phone.getContext().registerReceiver(sIntentReceiver, filter, null, handler,
- Context.RECEIVER_EXPORTED);
- }
- }
-
- void dispose() {
- if (TelephonyUtils.IS_DEBUGGABLE) {
- mPhone.getContext().unregisterReceiver(sIntentReceiver);
- }
- }
-
- private static void log(String s) {
- Rlog.d(LOG_TAG, s);
- }
-}
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTesterFailBringUpAll.java b/src/java/com/android/internal/telephony/dataconnection/DcTesterFailBringUpAll.java
deleted file mode 100644
index 788da29..0000000
--- a/src/java/com/android/internal/telephony/dataconnection/DcTesterFailBringUpAll.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Handler;
-import android.telephony.DataFailCause;
-
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.util.TelephonyUtils;
-import com.android.telephony.Rlog;
-
-/**
- * A package level call that causes all DataConnection bringUp calls to fail a specific
- * number of times. Here is an example that sets counter to 2 and cause to -3 for all instances:
- * adb shell am broadcast -a com.android.internal.telephony.dataconnection.action_fail_bringup \
- * --ei counter 2 --ei fail_cause -3
- *
- * Also you can add a suggested retry time if desired:
- * --ei suggested_retry_time 5000
- *
- * The fail_cause is one of {@link DataFailCause}
- */
-public class DcTesterFailBringUpAll {
- private static final String LOG_TAG = "DcTesterFailBrinupAll";
- private static final boolean DBG = true;
-
- private Phone mPhone;
-
- private String mActionFailBringUp = DcFailBringUp.INTENT_BASE + "."
- + DcFailBringUp.ACTION_FAIL_BRINGUP;
-
- // The saved FailBringUp data from the intent
- private DcFailBringUp mFailBringUp = new DcFailBringUp();
-
- // The static intent receiver one for all instances.
- private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (DBG) log("sIntentReceiver.onReceive: action=" + action);
- if (action.equals(mActionFailBringUp)) {
- mFailBringUp.saveParameters(intent, "sFailBringUp");
- } else if (action.equals(mPhone.getActionDetached())) {
- // Counter is MAX, bringUp/retry will always fail
- log("simulate detaching");
- mFailBringUp.saveParameters(Integer.MAX_VALUE,
- DataFailCause.LOST_CONNECTION,
- DcFailBringUp.DEFAULT_SUGGESTED_RETRY_TIME);
- } else if (action.equals(mPhone.getActionAttached())) {
- // Counter is 0 next bringUp/retry will succeed
- log("simulate attaching");
- mFailBringUp.saveParameters(0, DataFailCause.NONE,
- DcFailBringUp.DEFAULT_SUGGESTED_RETRY_TIME);
- } else {
- if (DBG) log("onReceive: unknown action=" + action);
- }
- }
- };
-
- DcTesterFailBringUpAll(Phone phone, Handler handler) {
- mPhone = phone;
- if (TelephonyUtils.IS_DEBUGGABLE) {
- IntentFilter filter = new IntentFilter();
-
- filter.addAction(mActionFailBringUp);
- log("register for intent action=" + mActionFailBringUp);
-
- filter.addAction(mPhone.getActionDetached());
- log("register for intent action=" + mPhone.getActionDetached());
-
- filter.addAction(mPhone.getActionAttached());
- log("register for intent action=" + mPhone.getActionAttached());
-
- phone.getContext().registerReceiver(mIntentReceiver, filter, null, handler,
- Context.RECEIVER_EXPORTED);
- }
- }
-
- void dispose() {
- if (TelephonyUtils.IS_DEBUGGABLE) {
- mPhone.getContext().unregisterReceiver(mIntentReceiver);
- }
- }
-
- public DcFailBringUp getDcFailBringUp() {
- return mFailBringUp;
- }
-
- private void log(String s) {
- Rlog.d(LOG_TAG, s);
- }
-}
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
deleted file mode 100755
index 28f69dc..0000000
--- a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
+++ /dev/null
@@ -1,5665 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
-import static android.net.NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_CONGESTED;
-import static android.net.NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_UNMETERED;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_LTE;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_NR;
-import static android.telephony.data.DataCallResponse.HANDOVER_FAILURE_MODE_DO_FALLBACK;
-import static android.telephony.data.DataCallResponse.HANDOVER_FAILURE_MODE_LEGACY;
-import static android.telephony.data.DataCallResponse.HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL;
-
-import static com.android.internal.telephony.RILConstants.DATA_PROFILE_DEFAULT;
-import static com.android.internal.telephony.RILConstants.DATA_PROFILE_INVALID;
-
-import android.annotation.IntDef;
-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;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
-import android.content.res.Resources;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.net.ConnectivityManager;
-import android.net.LinkProperties;
-import android.net.NetworkAgent;
-import android.net.NetworkCapabilities;
-import android.net.NetworkPolicyManager;
-import android.net.NetworkRequest;
-import android.net.TrafficStats;
-import android.net.Uri;
-import android.os.AsyncResult;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Message;
-import android.os.PersistableBundle;
-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;
-import android.provider.Telephony;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.AccessNetworkConstants.TransportType;
-import android.telephony.Annotation.ApnType;
-import android.telephony.Annotation.DataFailureCause;
-import android.telephony.Annotation.NetworkType;
-import android.telephony.CarrierConfigManager;
-import android.telephony.CellLocation;
-import android.telephony.DataFailCause;
-import android.telephony.NetworkRegistrationInfo;
-import android.telephony.PcoData;
-import android.telephony.PreciseDataConnectionState;
-import android.telephony.ServiceState;
-import android.telephony.ServiceState.RilRadioTechnology;
-import android.telephony.SubscriptionManager;
-import android.telephony.SubscriptionPlan;
-import android.telephony.TelephonyDisplayInfo;
-import android.telephony.TelephonyFrameworkInitializer;
-import android.telephony.TelephonyManager;
-import android.telephony.TelephonyManager.SimState;
-import android.telephony.cdma.CdmaCellLocation;
-import android.telephony.data.ApnSetting;
-import android.telephony.data.DataCallResponse;
-import android.telephony.data.DataCallResponse.HandoverFailureMode;
-import android.telephony.data.DataProfile;
-import android.telephony.data.ThrottleStatus;
-import android.telephony.gsm.GsmCellLocation;
-import android.text.TextUtils;
-import android.util.EventLog;
-import android.util.LocalLog;
-import android.util.Log;
-import android.util.Pair;
-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;
-import com.android.internal.telephony.GsmCdmaPhone;
-import com.android.internal.telephony.ITelephony;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.RILConstants;
-import com.android.internal.telephony.RetryManager;
-import com.android.internal.telephony.SettingsObserver;
-import com.android.internal.telephony.SubscriptionInfoUpdater;
-import com.android.internal.telephony.data.DataConfigManager;
-import com.android.internal.telephony.data.PhoneSwitcher;
-import com.android.internal.telephony.dataconnection.DataConnectionReasons.DataAllowedReasonType;
-import com.android.internal.telephony.dataconnection.DataConnectionReasons.DataDisallowedReasonType;
-import com.android.internal.telephony.dataconnection.DataEnabledSettings.DataEnabledChangedReason;
-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;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.Collectors;
-
-/**
- * {@hide}
- */
-public class DcTracker extends Handler {
- protected static final boolean DBG = true;
- 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,
- REQUEST_TYPE_HANDOVER,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface RequestNetworkType {}
-
- /**
- * Normal request for {@link #requestNetwork(NetworkRequest, int, Message)}. For request
- * network, this adds the request to the {@link ApnContext}. If there were no network request
- * attached to the {@link ApnContext} earlier, this request setups a data connection.
- */
- public static final int REQUEST_TYPE_NORMAL = 1;
-
- /**
- * Handover request for {@link #requestNetwork(NetworkRequest, int, Message)} or
- * {@link #releaseNetwork(NetworkRequest, int)}. For request network, this
- * initiates the handover data setup process. The existing data connection will be seamlessly
- * handover to the new network. For release network, this performs a data connection softly
- * clean up at the underlying layer (versus normal data release).
- */
- public static final int REQUEST_TYPE_HANDOVER = 2;
-
- @IntDef(value = {
- RELEASE_TYPE_NORMAL,
- RELEASE_TYPE_DETACH,
- RELEASE_TYPE_HANDOVER,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface ReleaseNetworkType {}
-
- /**
- * For release network, this is just removing the network request from the {@link ApnContext}.
- * Note this does not tear down the physical data connection. Normally the data connection is
- * torn down by connectivity service directly calling {@link NetworkAgent#unwanted()}.
- */
- public static final int RELEASE_TYPE_NORMAL = 1;
-
- /**
- * Detach request for {@link #releaseNetwork(NetworkRequest, int)} only. This
- * forces the APN context detach from the data connection. If this {@link ApnContext} is the
- * last one attached to the data connection, the data connection will be torn down, otherwise
- * the data connection remains active.
- */
- public static final int RELEASE_TYPE_DETACH = 2;
-
- /**
- * Handover request for {@link #releaseNetwork(NetworkRequest, int)}. For release
- * network, this performs a data connection softly clean up at the underlying layer (versus
- * normal data release).
- */
- public static final int RELEASE_TYPE_HANDOVER = 3;
-
- /** The extras for handover completion message */
- public static final String DATA_COMPLETE_MSG_EXTRA_NETWORK_REQUEST = "extra_network_request";
- public static final String DATA_COMPLETE_MSG_EXTRA_TRANSPORT_TYPE = "extra_transport_type";
- public static final String DATA_COMPLETE_MSG_EXTRA_SUCCESS = "extra_success";
- /**
- * The flag indicates whether after handover failure, the data connection should remain on the
- * original transport.
- */
- public static final String DATA_COMPLETE_MSG_EXTRA_HANDOVER_FAILURE_FALLBACK =
- "extra_handover_failure_fallback";
-
- private final String mLogTag;
-
- public AtomicBoolean isCleanupRequired = new AtomicBoolean(false);
-
- private final TelephonyManager mTelephonyManager;
-
- private final AlarmManager mAlarmManager;
-
- /* Currently requested APN type (TODO: This should probably be a parameter not a member) */
- private int mRequestedApnType = ApnSetting.TYPE_DEFAULT;
-
- // All data enabling/disabling related settings
- private final DataEnabledSettings mDataEnabledSettings;
-
- /**
- * After detecting a potential connection problem, this is the max number
- * of subsequent polls before attempting recovery.
- */
- // 1 sec. default polling interval when screen is on.
- private static final int POLL_NETSTAT_MILLIS = 1000;
- // 10 min. default polling interval when screen is off.
- private static final int POLL_NETSTAT_SCREEN_OFF_MILLIS = 1000*60*10;
- // Default sent packets without ack which triggers initial recovery steps
- private static final int NUMBER_SENT_PACKETS_OF_HANG = 10;
-
- // Default for the data stall alarm while non-aggressive stall detection
- private static final int DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60 * 6;
- // Default for the data stall alarm for aggressive stall detection
- private static final int DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT = 1000 * 60;
-
- private static final boolean DATA_STALL_SUSPECTED = true;
- protected static final boolean DATA_STALL_NOT_SUSPECTED = false;
-
- private static final String INTENT_DATA_STALL_ALARM =
- "com.android.internal.telephony.data-stall";
- // Tag for tracking stale alarms
- private static final String INTENT_DATA_STALL_ALARM_EXTRA_TAG = "data_stall_alarm_extra_tag";
- 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,
- DctConstants.State.DISCONNECTING,
- DctConstants.State.CONNECTING,
- DctConstants.State.CONNECTED,
- };
-
- private DcTesterFailBringUpAll mDcTesterFailBringUpAll;
- private DcController mDcc;
-
- /** kept in sync with mApnContexts
- * Higher numbers are higher priority and sorted so highest priority is first */
- private ArrayList<ApnContext> mPrioritySortedApnContexts = new ArrayList<>();
-
- /** all APN settings applicable to the current carrier */
- private ArrayList<ApnSetting> mAllApnSettings = new ArrayList<>();
-
- /** preferred apn */
- private ApnSetting mPreferredApn = null;
-
- /** Is packet service restricted by network */
- private boolean mIsPsRestricted = false;
-
- /** emergency apn Setting*/
- private ApnSetting mEmergencyApn = null;
-
- /* Once disposed dont handle any messages */
- private boolean mIsDisposed = false;
-
- private ContentResolver mResolver;
-
- /* Set to true with CMD_ENABLE_MOBILE_PROVISIONING */
- private boolean mIsProvisioning = false;
-
- /* The Url passed as object parameter in CMD_ENABLE_MOBILE_PROVISIONING */
- private String mProvisioningUrl = null;
-
- /* Indicating data service is bound or not */
- private boolean mDataServiceBound = false;
-
- /* Intent to hide/show the sign-in error notification for provisioning */
- private static final String INTENT_PROVISION = "com.android.internal.telephony.PROVISION";
-
- /**
- * Extra containing the phone ID for INTENT_PROVISION
- * Must be kept consistent with NetworkNotificationManager#setProvNotificationVisible.
- * TODO: refactor the deprecated API to prevent hardcoding values.
- */
- private static final String EXTRA_PROVISION_PHONE_ID = "provision.phone.id";
-
- /* Intent for the provisioning apn alarm */
- private static final String INTENT_PROVISIONING_APN_ALARM =
- "com.android.internal.telephony.provisioning_apn_alarm";
-
- /* Tag for tracking stale alarms */
- private static final String PROVISIONING_APN_ALARM_TAG_EXTRA = "provisioning.apn.alarm.tag";
-
- /* Debug property for overriding the PROVISIONING_APN_ALARM_DELAY_IN_MS */
- private static final String DEBUG_PROV_APN_ALARM = "persist.debug.prov_apn_alarm";
-
- /* Default for the provisioning apn alarm timeout */
- private static final int PROVISIONING_APN_ALARM_DELAY_IN_MS_DEFAULT = 1000 * 60 * 15;
-
- /* The provision apn alarm intent used to disable the provisioning apn */
- private PendingIntent mProvisioningApnAlarmIntent = null;
-
- /* Used to track stale provisioning apn alarms */
- private int mProvisioningApnAlarmTag = (int) SystemClock.elapsedRealtime();
-
- private AsyncChannel mReplyAc = new AsyncChannel();
-
- private final LocalLog mDataRoamingLeakageLog = new LocalLog(32);
- private final LocalLog mApnSettingsInitializationLog = new LocalLog(32);
-
- /* 5G connection reevaluation watchdog alarm constants */
- private long mWatchdogTimeMs = 1000 * 60 * 60;
- private boolean mWatchdog = false;
-
- /* Default for whether 5G frequencies are considered unmetered */
- private boolean mNrNsaAllUnmetered = false;
- private boolean mNrNsaMmwaveUnmetered = false;
- private boolean mNrNsaSub6Unmetered = false;
- private boolean mNrSaAllUnmetered = false;
- private boolean mNrSaMmwaveUnmetered = false;
- private boolean mNrSaSub6Unmetered = false;
- private boolean mNrNsaRoamingUnmetered = false;
-
- // it effect the PhysicalLinkStatusChanged
- private boolean mLteEndcUsingUserDataForRrcDetection = false;
-
- /* List of SubscriptionPlans, updated when initialized and when plans are changed. */
- private List<SubscriptionPlan> mSubscriptionPlans = new ArrayList<>();
- /* List of network types an unmetered override applies to, set by onSubscriptionOverride
- * and cleared when the device is rebooted or the override expires. */
- private List<Integer> mUnmeteredNetworkTypes = null;
- /* List of network types a congested override applies to, set by onSubscriptionOverride
- * and cleared when the device is rebooted or the override expires. */
- private List<Integer> mCongestedNetworkTypes = null;
- /* Whether an unmetered override is currently active. */
- private boolean mUnmeteredOverride = false;
- /* Whether a congested override is currently active. */
- private boolean mCongestedOverride = false;
-
- @SimState
- private int mSimState = TelephonyManager.SIM_STATE_UNKNOWN;
-
- private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver () {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
-
- if (action.equals(Intent.ACTION_SCREEN_ON)) {
- // TODO: Evaluate hooking this up with DeviceStateMonitor
- if (DBG) log("screen on");
- mIsScreenOn = true;
- stopNetStatPoll();
- startNetStatPoll();
- restartDataStallAlarm();
- } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
- if (DBG) log("screen off");
- mIsScreenOn = false;
- stopNetStatPoll();
- startNetStatPoll();
- restartDataStallAlarm();
- } else if (action.equals(INTENT_DATA_STALL_ALARM)) {
- onActionIntentDataStallAlarm(intent);
- } else if (action.equals(INTENT_PROVISIONING_APN_ALARM)) {
- if (DBG) log("Provisioning apn alarm");
- onActionIntentProvisioningApnAlarm(intent);
- } else if (action.equals(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED)
- || action.equals(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED)) {
- if (mPhone.getPhoneId() == intent.getIntExtra(SubscriptionManager.EXTRA_SLOT_INDEX,
- SubscriptionManager.INVALID_SIM_SLOT_INDEX)) {
- int simState = intent.getIntExtra(TelephonyManager.EXTRA_SIM_STATE,
- TelephonyManager.SIM_STATE_UNKNOWN);
- sendMessage(obtainMessage(DctConstants.EVENT_SIM_STATE_UPDATED, simState, 0));
- }
- } else if (action.equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
- if (mPhone.getPhoneId() == intent.getIntExtra(CarrierConfigManager.EXTRA_SLOT_INDEX,
- SubscriptionManager.INVALID_SIM_SLOT_INDEX)) {
- if (intent.getBooleanExtra(
- CarrierConfigManager.EXTRA_REBROADCAST_ON_UNLOCK, false)) {
- // Ignore the rebroadcast one to prevent multiple carrier config changed
- // event during boot up.
- return;
- }
- int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
- SubscriptionManager.INVALID_SUBSCRIPTION_ID);
- if (SubscriptionManager.isValidSubscriptionId(subId)) {
- sendEmptyMessage(DctConstants.EVENT_CARRIER_CONFIG_CHANGED);
- }
- }
- } else {
- if (DBG) log("onReceive: Unknown action=" + action);
- }
- }
- };
-
- private final Runnable mPollNetStat = new Runnable() {
- @Override
- public void run() {
- updateDataActivity();
-
- if (mIsScreenOn) {
- mNetStatPollPeriod = Settings.Global.getInt(mResolver,
- Settings.Global.PDP_WATCHDOG_POLL_INTERVAL_MS, POLL_NETSTAT_MILLIS);
- } else {
- mNetStatPollPeriod = Settings.Global.getInt(mResolver,
- Settings.Global.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS,
- POLL_NETSTAT_SCREEN_OFF_MILLIS);
- }
-
- if (mNetStatPollEnabled) {
- mDataConnectionTracker.postDelayed(this, mNetStatPollPeriod);
- }
- }
- };
-
- private class ThrottleStatusChangedCallback implements DataThrottler.Callback {
- @Override
- public void onThrottleStatusChanged(List<ThrottleStatus> throttleStatuses) {
- for (ThrottleStatus status : throttleStatuses) {
- if (status.getThrottleType() == ThrottleStatus.THROTTLE_TYPE_NONE) {
- setupDataOnConnectableApn(mApnContextsByType.get(status.getApnType()),
- Phone.REASON_DATA_UNTHROTTLED,
- RetryFailures.ALWAYS);
- }
- }
- }
- }
-
- private NetworkPolicyManager mNetworkPolicyManager;
- private final NetworkPolicyManager.SubscriptionCallback mSubscriptionCallback =
- new NetworkPolicyManager.SubscriptionCallback() {
- @Override
- public void onSubscriptionOverride(int subId, int overrideMask, int overrideValue,
- int[] networkTypes) {
- if (mPhone == null || mPhone.getSubId() != subId) return;
-
- List<Integer> tempList = new ArrayList<>();
- for (int networkType : networkTypes) {
- tempList.add(networkType);
- }
-
- log("Subscription override: overrideMask=" + overrideMask
- + ", overrideValue=" + overrideValue + ", networkTypes=" + tempList);
-
- if (overrideMask == SUBSCRIPTION_OVERRIDE_UNMETERED) {
- mUnmeteredNetworkTypes = tempList;
- mUnmeteredOverride = overrideValue != 0;
- reevaluateUnmeteredConnections();
- } else if (overrideMask == SUBSCRIPTION_OVERRIDE_CONGESTED) {
- mCongestedNetworkTypes = tempList;
- mCongestedOverride = overrideValue != 0;
- reevaluateCongestedConnections();
- }
- }
-
- @Override
- public void onSubscriptionPlansChanged(int subId, SubscriptionPlan[] plans) {
- if (mPhone == null || mPhone.getSubId() != subId) return;
-
- mSubscriptionPlans = Arrays.asList(plans);
- if (DBG) log("SubscriptionPlans changed: " + mSubscriptionPlans);
- reevaluateUnmeteredConnections();
- }
- };
-
- private final SettingsObserver mSettingsObserver;
-
- private void registerSettingsObserver() {
- mSettingsObserver.unobserve();
- String simSuffix = "";
- if (TelephonyManager.getDefault().getSimCount() > 1) {
- simSuffix = Integer.toString(mPhone.getSubId());
- }
-
- mSettingsObserver.observe(
- Settings.Global.getUriFor(Settings.Global.DATA_ROAMING + simSuffix),
- DctConstants.EVENT_ROAMING_SETTING_CHANGE);
- mSettingsObserver.observe(
- Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
- DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE);
- }
-
- /**
- * Maintain the sum of transmit and receive packets.
- *
- * The packet counts are initialized and reset to -1 and
- * remain -1 until they can be updated.
- */
- public static class TxRxSum {
- public long txPkts;
- public long rxPkts;
-
- public TxRxSum() {
- reset();
- }
-
- public TxRxSum(long txPkts, long rxPkts) {
- this.txPkts = txPkts;
- this.rxPkts = rxPkts;
- }
-
- public TxRxSum(TxRxSum sum) {
- txPkts = sum.txPkts;
- rxPkts = sum.rxPkts;
- }
-
- public void reset() {
- txPkts = -1;
- rxPkts = -1;
- }
-
- @Override
- public String toString() {
- return "{txSum=" + txPkts + " rxSum=" + rxPkts + "}";
- }
-
- /**
- * Get total Tx/Rx packet count from TrafficStats
- */
- public void updateTotalTxRxSum() {
- this.txPkts = TrafficStats.getMobileTxPackets();
- this.rxPkts = TrafficStats.getMobileRxPackets();
- }
- }
-
- private void onDataReconnect(ApnContext apnContextforRetry, int subId,
- @RequestNetworkType int requestType) {
- int phoneSubId = mPhone.getSubId();
- String apnType = apnContextforRetry.getApnType();
- String reason = apnContextforRetry.getReason();
-
- if (!SubscriptionManager.isValidSubscriptionId(subId) || (subId != phoneSubId)) {
- log("onDataReconnect: invalid subId");
- return;
- }
-
- ApnContext apnContext = mApnContexts.get(apnType);
-
- if (DBG) {
- log("onDataReconnect: mState=" + mState + " reason=" + reason + " apnType=" + apnType
- + " apnContext=" + apnContext);
- }
-
- if ((apnContext != null) && (apnContext.isEnabled())) {
- apnContext.setReason(reason);
- DctConstants.State apnContextState = apnContext.getState();
- if (DBG) {
- log("onDataReconnect: apnContext state=" + apnContextState);
- }
- if ((apnContextState == DctConstants.State.FAILED)
- || (apnContextState == DctConstants.State.IDLE)) {
- if (DBG) {
- log("onDataReconnect: state is FAILED|IDLE, disassociate");
- }
- apnContext.releaseDataConnection("");
- } else {
- if (DBG) log("onDataReconnect: keep associated");
- }
- // TODO: IF already associated should we send the EVENT_TRY_SETUP_DATA???
- sendMessage(obtainMessage(DctConstants.EVENT_TRY_SETUP_DATA, requestType,
- 0, apnContext));
- }
- }
-
- private void onActionIntentDataStallAlarm(Intent intent) {
- if (VDBG_STALL) log("onActionIntentDataStallAlarm: action=" + intent.getAction());
-
- int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
- SubscriptionManager.INVALID_SUBSCRIPTION_ID);
- if (!SubscriptionManager.isValidSubscriptionId(subId) || (subId != mPhone.getSubId())) {
- return;
- }
-
- int transportType = intent.getIntExtra(INTENT_DATA_STALL_ALARM_EXTRA_TRANSPORT_TYPE, 0);
- if (transportType != mTransportType) {
- return;
- }
-
- Message msg = obtainMessage(DctConstants.EVENT_DATA_STALL_ALARM,
- intent.getAction());
- msg.arg1 = intent.getIntExtra(INTENT_DATA_STALL_ALARM_EXTRA_TAG, 0);
- sendMessage(msg);
- }
-
- private RegistrantList mAllDataDisconnectedRegistrants = new RegistrantList();
-
- // member variables
- protected final Phone mPhone;
- private DctConstants.Activity mActivity = DctConstants.Activity.NONE;
- private DctConstants.State mState = DctConstants.State.IDLE;
- private final Handler mDataConnectionTracker;
-
- private long mTxPkts;
- private long mRxPkts;
- private int mNetStatPollPeriod;
- private boolean mNetStatPollEnabled = false;
-
- private TxRxSum mDataStallTxRxSum = new TxRxSum(0, 0);
- // Used to track stale data stall alarms.
- private int mDataStallAlarmTag = (int) SystemClock.elapsedRealtime();
- // The current data stall alarm intent
- private PendingIntent mDataStallAlarmIntent = null;
- // Number of packets sent since the last received packet
- private long mSentSinceLastRecv;
- // Controls when a simple recovery attempt it to be tried
- private int mNoRecvPollCount = 0;
- // Reference counter for enabling fail fast
- private static int sEnableFailFastRefCounter = 0;
- // True if data stall detection is enabled
- private volatile boolean mDataStallNoRxEnabled = true;
-
- protected volatile boolean mFailFast = false;
-
- // True when in voice call
- protected boolean mInVoiceCall = false;
-
- /** Intent sent when the reconnect alarm fires. */
- private PendingIntent mReconnectIntent = null;
-
- // When false we will not auto attach and manually attaching is required.
- protected boolean mAutoAttachOnCreationConfig = false;
- private AtomicBoolean mAutoAttachEnabled = new AtomicBoolean(false);
-
- // State of screen
- // (TODO: Reconsider tying directly to screen, maybe this is
- // really a lower power mode")
- private boolean mIsScreenOn = true;
-
- /** Allows the generation of unique Id's for DataConnection objects */
- private AtomicInteger mUniqueIdGenerator = new AtomicInteger(0);
-
- /** The data connections. */
- private HashMap<Integer, DataConnection> mDataConnections =
- new HashMap<Integer, DataConnection>();
-
- /** Convert an ApnType string to Id (TODO: Use "enumeration" instead of String for ApnType) */
- private HashMap<String, Integer> mApnToDataConnectionId = new HashMap<String, Integer>();
-
- /** Phone.APN_TYPE_* ===> ApnContext */
- protected ConcurrentHashMap<String, ApnContext> mApnContexts =
- new ConcurrentHashMap<String, ApnContext>();
-
- private SparseArray<ApnContext> mApnContextsByType = new SparseArray<ApnContext>();
-
- private ArrayList<DataProfile> mLastDataProfileList = new ArrayList<>();
-
- /** RAT name ===> (downstream, upstream) bandwidth values from carrier config. */
- private ConcurrentHashMap<String, Pair<Integer, Integer>> mBandwidths =
- new ConcurrentHashMap<>();
-
- private boolean mConfigReady = false;
-
- /**
- * Handles changes to the APN db.
- */
- private class ApnChangeObserver extends ContentObserver {
- public ApnChangeObserver () {
- super(mDataConnectionTracker);
- }
-
- @Override
- public void onChange(boolean selfChange) {
- sendMessage(obtainMessage(DctConstants.EVENT_APN_CHANGED));
- }
- }
-
- //***** Instance Variables
-
- private boolean mReregisterOnReconnectFailure = false;
-
-
- //***** Constants
-
- private static final int PROVISIONING_SPINNER_TIMEOUT_MILLIS = 120 * 1000;
-
- static final Uri PREFERAPN_NO_UPDATE_URI_USING_SUBID =
- Uri.parse("content://telephony/carriers/preferapn_no_update/subId/");
- static final String APN_ID = "apn_id";
-
- private boolean mCanSetPreferApn = false;
-
- private AtomicBoolean mAttached = new AtomicBoolean(false);
-
- /** Watches for changes to the APN db. */
- private ApnChangeObserver mApnObserver;
-
- private BroadcastReceiver mProvisionBroadcastReceiver;
- private ProgressDialog mProvisioningSpinner;
-
- private final DataServiceManager mDataServiceManager;
-
- @AccessNetworkConstants.TransportType
- private final int mTransportType;
-
- private DataStallRecoveryHandler mDsRecoveryHandler;
- private HandlerThread mHandlerThread;
-
- private final DataThrottler mDataThrottler;
-
- private final ThrottleStatusChangedCallback mThrottleStatusCallback;
-
- /**
- * Request network completion message map. Key is the APN type, value is the list of completion
- * messages to be sent. Using a list because there might be multiple network requests for
- * the same APN type.
- */
- private final Map<Integer, List<Message>> mHandoverCompletionMsgs = new HashMap<>();
-
- //***** Constructor
- public DcTracker(Phone phone, @TransportType int transportType) {
- super();
- mPhone = phone;
- if (DBG) log("DCT.constructor");
- mTelephonyManager = TelephonyManager.from(phone.getContext())
- .createForSubscriptionId(phone.getSubId());
- // The 'C' in tag indicates cellular, and 'I' indicates IWLAN. This is to distinguish
- // between two DcTrackers, one for each.
- String tagSuffix = "-" + ((transportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
- ? "C" : "I");
- tagSuffix += "-" + mPhone.getPhoneId();
- mLogTag = "DCT" + tagSuffix;
-
- mTransportType = transportType;
- mDataServiceManager = new DataServiceManager(phone, transportType, tagSuffix);
- mDataThrottler = new DataThrottler(mPhone, transportType);
-
- mResolver = mPhone.getContext().getContentResolver();
- mAlarmManager =
- (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
-
- mDsRecoveryHandler = new DataStallRecoveryHandler();
-
- IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_SCREEN_ON);
- filter.addAction(Intent.ACTION_SCREEN_OFF);
- filter.addAction(INTENT_DATA_STALL_ALARM);
- filter.addAction(INTENT_PROVISIONING_APN_ALARM);
- filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
- filter.addAction(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED);
- filter.addAction(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED);
-
- mDataEnabledSettings = mPhone.getDataEnabledSettings();
-
- mDataEnabledSettings.registerForDataEnabledChanged(this,
- DctConstants.EVENT_DATA_ENABLED_CHANGED, null);
- mDataEnabledSettings.registerForDataEnabledOverrideChanged(this,
- DctConstants.EVENT_DATA_ENABLED_OVERRIDE_RULES_CHANGED);
-
- mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
-
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
- mAutoAttachEnabled.set(sp.getBoolean(Phone.DATA_DISABLED_ON_BOOT_KEY, false));
-
- mNetworkPolicyManager = (NetworkPolicyManager) mPhone.getContext()
- .getSystemService(Context.NETWORK_POLICY_SERVICE);
- mNetworkPolicyManager.registerSubscriptionCallback(mSubscriptionCallback);
-
- mHandlerThread = new HandlerThread("DcHandlerThread");
- mHandlerThread.start();
- Handler dcHandler = new Handler(mHandlerThread.getLooper());
- mDcc = DcController.makeDcc(mPhone, this, mDataServiceManager, dcHandler.getLooper(),
- tagSuffix);
- mDcTesterFailBringUpAll = new DcTesterFailBringUpAll(mPhone, dcHandler);
-
- mDataConnectionTracker = this;
- registerForAllEvents();
- mApnObserver = new ApnChangeObserver();
- phone.getContext().getContentResolver().registerContentObserver(
- Telephony.Carriers.CONTENT_URI, true, mApnObserver);
-
- initApnContexts();
-
- addDefaultApnSettingsAsNeeded();
-
- mSettingsObserver = new SettingsObserver(mPhone.getContext(), this);
- registerSettingsObserver();
-
- mThrottleStatusCallback = new ThrottleStatusChangedCallback();
- mDataThrottler.registerForThrottleStatusChanges(mThrottleStatusCallback);
- }
-
- @VisibleForTesting
- public DcTracker() {
- mLogTag = "DCT";
- mTelephonyManager = null;
- mAlarmManager = null;
- mPhone = null;
- mDataConnectionTracker = null;
- mSettingsObserver = new SettingsObserver(null, this);
- mDataEnabledSettings = null;
- mTransportType = 0;
- mDataServiceManager = null;
- mDataThrottler = null;
- mThrottleStatusCallback = null;
- }
-
- public void registerServiceStateTrackerEvents() {
- mPhone.getServiceStateTracker().registerForDataConnectionAttached(mTransportType, this,
- DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null);
- mPhone.getServiceStateTracker().registerForDataConnectionDetached(mTransportType, this,
- DctConstants.EVENT_DATA_CONNECTION_DETACHED, null);
- mPhone.getServiceStateTracker().registerForDataRoamingOn(this,
- DctConstants.EVENT_ROAMING_ON, null);
- mPhone.getServiceStateTracker().registerForDataRoamingOff(this,
- DctConstants.EVENT_ROAMING_OFF, null, true);
- mPhone.getServiceStateTracker().registerForPsRestrictedEnabled(this,
- DctConstants.EVENT_PS_RESTRICT_ENABLED, null);
- mPhone.getServiceStateTracker().registerForPsRestrictedDisabled(this,
- DctConstants.EVENT_PS_RESTRICT_DISABLED, null);
- mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(mTransportType, this,
- DctConstants.EVENT_DATA_RAT_CHANGED, null);
- }
-
- public void unregisterServiceStateTrackerEvents() {
- mPhone.getServiceStateTracker().unregisterForDataConnectionAttached(mTransportType, this);
- mPhone.getServiceStateTracker().unregisterForDataConnectionDetached(mTransportType, this);
- mPhone.getServiceStateTracker().unregisterForDataRoamingOn(this);
- mPhone.getServiceStateTracker().unregisterForDataRoamingOff(this);
- mPhone.getServiceStateTracker().unregisterForPsRestrictedEnabled(this);
- mPhone.getServiceStateTracker().unregisterForPsRestrictedDisabled(this);
- mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged(mTransportType, this);
- mPhone.getServiceStateTracker().unregisterForAirplaneModeChanged(this);
- }
-
- private void registerForAllEvents() {
- if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
- mPhone.mCi.registerForAvailable(this, DctConstants.EVENT_RADIO_AVAILABLE, null);
- mPhone.mCi.registerForOffOrNotAvailable(this,
- DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
- mPhone.mCi.registerForPcoData(this, DctConstants.EVENT_PCO_DATA_RECEIVED, null);
- }
-
- // Note, this is fragile - the Phone is now presenting a merged picture
- // of PS (volte) & CS and by diving into its internals you're just seeing
- // the CS data. This works well for the purposes this is currently used for
- // but that may not always be the case. Should probably be redesigned to
- // accurately reflect what we're really interested in (registerForCSVoiceCallEnded).
- mPhone.getCallTracker().registerForVoiceCallEnded(this,
- DctConstants.EVENT_VOICE_CALL_ENDED, null);
- mPhone.getCallTracker().registerForVoiceCallStarted(this,
- DctConstants.EVENT_VOICE_CALL_STARTED, null);
- mPhone.getDisplayInfoController().registerForTelephonyDisplayInfoChanged(this,
- DctConstants.EVENT_TELEPHONY_DISPLAY_INFO_CHANGED, null);
- registerServiceStateTrackerEvents();
- mDataServiceManager.registerForServiceBindingChanged(this,
- DctConstants.EVENT_DATA_SERVICE_BINDING_CHANGED, null);
- mDataServiceManager.registerForApnUnthrottled(this, DctConstants.EVENT_APN_UNTHROTTLED);
- }
-
- public void dispose() {
- if (DBG) log("DCT.dispose");
-
- if (mProvisionBroadcastReceiver != null) {
- mPhone.getContext().unregisterReceiver(mProvisionBroadcastReceiver);
- mProvisionBroadcastReceiver = null;
- }
- if (mProvisioningSpinner != null) {
- mProvisioningSpinner.dismiss();
- mProvisioningSpinner = null;
- }
-
- cleanUpAllConnectionsInternal(true, null);
-
- mIsDisposed = true;
- mPhone.getContext().unregisterReceiver(mIntentReceiver);
- mSettingsObserver.unobserve();
-
- mNetworkPolicyManager.unregisterSubscriptionCallback(mSubscriptionCallback);
- mDcTesterFailBringUpAll.dispose();
-
- mPhone.getContext().getContentResolver().unregisterContentObserver(mApnObserver);
- mApnContexts.clear();
- mApnContextsByType.clear();
- mPrioritySortedApnContexts.clear();
- unregisterForAllEvents();
-
- destroyDataConnections();
- }
-
- /**
- * Stop the internal handler thread
- *
- * TESTING ONLY
- */
- @VisibleForTesting
- public void stopHandlerThread() {
- mHandlerThread.quit();
- }
-
- private void unregisterForAllEvents() {
- //Unregister for all events
- if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
- mPhone.mCi.unregisterForAvailable(this);
- mPhone.mCi.unregisterForOffOrNotAvailable(this);
- mPhone.mCi.unregisterForPcoData(this);
- }
-
- mPhone.getCallTracker().unregisterForVoiceCallEnded(this);
- mPhone.getCallTracker().unregisterForVoiceCallStarted(this);
- mPhone.getDisplayInfoController().unregisterForTelephonyDisplayInfoChanged(this);
- unregisterServiceStateTrackerEvents();
- mDataServiceManager.unregisterForServiceBindingChanged(this);
- mDataEnabledSettings.unregisterForDataEnabledChanged(this);
- mDataEnabledSettings.unregisterForDataEnabledOverrideChanged(this);
- mDataServiceManager.unregisterForApnUnthrottled(this);
- }
-
- /**
- * Reevaluate existing data connections when conditions change.
- *
- * For example, handle reverting restricted networks back to unrestricted. If we're changing
- * user data to enabled and this makes data truly enabled (not disabled by other factors) we
- * need to reevaluate and possibly add NET_CAPABILITY_NOT_RESTRICTED capability to the data
- * connection. This allows non-privilege apps to use the network.
- *
- * Or when we brought up a unmetered data connection while data is off, we only limit this
- * data connection for unmetered use only. When data is turned back on, we need to tear that
- * down so a full capable data connection can be re-established.
- */
- private void reevaluateDataConnections() {
- for (DataConnection dataConnection : mDataConnections.values()) {
- dataConnection.reevaluateRestrictedState();
- }
- }
-
- public long getSubId() {
- return mPhone.getSubId();
- }
-
- public DctConstants.Activity getActivity() {
- return mActivity;
- }
-
- private void setActivity(DctConstants.Activity activity) {
- log("setActivity = " + activity);
- mActivity = activity;
- mPhone.notifyDataActivity();
- }
-
- /**
- * Request a network
- *
- * @param networkRequest Network request from clients
- * @param type The request type
- * @param onHandoverCompleteMsg When request type is handover, this message will be sent when
- * handover is completed. For normal request, this should be null.
- */
- public void requestNetwork(NetworkRequest networkRequest, @RequestNetworkType int type,
- Message onHandoverCompleteMsg) {
- if (type != REQUEST_TYPE_HANDOVER && onHandoverCompleteMsg != null) {
- throw new RuntimeException("request network with normal type request type but passing "
- + "handover complete message.");
- }
- final int apnType = ApnContext.getApnTypeFromNetworkRequest(networkRequest);
- final ApnContext apnContext = mApnContextsByType.get(apnType);
- if (apnContext != null) {
- apnContext.requestNetwork(networkRequest, type, onHandoverCompleteMsg);
- }
- }
-
- public void releaseNetwork(NetworkRequest networkRequest, @ReleaseNetworkType int type) {
- final int apnType = ApnContext.getApnTypeFromNetworkRequest(networkRequest);
- final ApnContext apnContext = mApnContextsByType.get(apnType);
- if (apnContext != null) {
- apnContext.releaseNetwork(networkRequest, type);
- }
- }
-
- // Turn telephony radio on or off.
- private void setRadio(boolean on) {
- final ITelephony phone = ITelephony.Stub.asInterface(
- TelephonyFrameworkInitializer
- .getTelephonyServiceManager()
- .getTelephonyServiceRegisterer()
- .get());
- try {
- phone.setRadio(on);
- } catch (Exception e) {
- // Ignore.
- }
- }
-
- // Class to handle Intent dispatched with user selects the "Sign-in to network"
- // notification.
- private class ProvisionNotificationBroadcastReceiver extends BroadcastReceiver {
- private final String mNetworkOperator;
- // Mobile provisioning URL. Valid while provisioning notification is up.
- // Set prior to notification being posted as URL contains ICCID which
- // disappears when radio is off (which is the case when notification is up).
- private final String mProvisionUrl;
-
- public ProvisionNotificationBroadcastReceiver(String provisionUrl, String networkOperator) {
- mNetworkOperator = networkOperator;
- mProvisionUrl = provisionUrl;
- }
-
- private void setEnableFailFastMobileData(int enabled) {
- sendMessage(obtainMessage(DctConstants.CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA, enabled, 0));
- }
-
- private void enableMobileProvisioning() {
- final Message msg = obtainMessage(DctConstants.CMD_ENABLE_MOBILE_PROVISIONING);
- Bundle bundle = new Bundle(1);
- bundle.putString(DctConstants.PROVISIONING_URL_KEY, mProvisionUrl);
- msg.setData(bundle);
- sendMessage(msg);
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
- if (mPhone.getPhoneId() != intent.getIntExtra(EXTRA_PROVISION_PHONE_ID,
- SubscriptionManager.INVALID_PHONE_INDEX)) {
- return;
- }
- // Turning back on the radio can take time on the order of a minute, so show user a
- // spinner so they know something is going on.
- log("onReceive : ProvisionNotificationBroadcastReceiver");
- mProvisioningSpinner = new ProgressDialog(context);
- mProvisioningSpinner.setTitle(mNetworkOperator);
- mProvisioningSpinner.setMessage(
- // TODO: Don't borrow "Connecting..." i18n string; give Telephony a version.
- context.getText(com.android.internal.R.string.media_route_status_connecting));
- mProvisioningSpinner.setIndeterminate(true);
- mProvisioningSpinner.setCancelable(true);
- // Allow non-Activity Service Context to create a View.
- mProvisioningSpinner.getWindow().setType(
- WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
- mProvisioningSpinner.show();
- // After timeout, hide spinner so user can at least use their device.
- // TODO: Indicate to user that it is taking an unusually long time to connect?
- sendMessageDelayed(obtainMessage(DctConstants.CMD_CLEAR_PROVISIONING_SPINNER,
- mProvisioningSpinner), PROVISIONING_SPINNER_TIMEOUT_MILLIS);
- // This code is almost identical to the old
- // ConnectivityService.handleMobileProvisioningAction code.
- setRadio(true);
- setEnableFailFastMobileData(DctConstants.ENABLED);
- enableMobileProvisioning();
- }
- }
-
- @Override
- protected void finalize() {
- if(DBG && mPhone != null) log("finalize");
- }
-
- private void initApnContexts() {
- PersistableBundle carrierConfig;
- CarrierConfigManager configManager = (CarrierConfigManager) mPhone.getContext()
- .getSystemService(Context.CARRIER_CONFIG_SERVICE);
- if (configManager != null) {
- carrierConfig = configManager.getConfigForSubId(mPhone.getSubId());
- } else {
- carrierConfig = null;
- }
- initApnContexts(carrierConfig);
- }
-
- //Blows away any existing apncontexts that may exist, only use in ctor.
- private void initApnContexts(PersistableBundle carrierConfig) {
- if (!mTelephonyManager.isDataCapable()) {
- log("initApnContexts: isDataCapable == false. No Apn Contexts loaded");
- return;
- }
-
- log("initApnContexts: E");
- // Load device network attributes from resources
- final Collection<ApnConfigType> types =
- new ApnConfigTypeRepository(carrierConfig).getTypes();
-
- for (ApnConfigType apnConfigType : types) {
- ApnContext apnContext = new ApnContext(mPhone, apnConfigType.getType(), mLogTag, this,
- apnConfigType.getPriority());
- int bitmask = ApnSetting.getApnTypesBitmaskFromString(apnContext.getApnType());
- mPrioritySortedApnContexts.add(apnContext);
- mApnContexts.put(apnContext.getApnType(), apnContext);
- mApnContextsByType.put(bitmask, apnContext);
- // Notify listeners that all data is disconnected when DCT is initialized.
- // Once connections are established, DC will then notify that data is connected.
- // This is to prevent the case where the phone process crashed but we don't notify
- // listeners that data was disconnected, so they may be stuck in a connected state.
- mPhone.notifyDataConnection(new PreciseDataConnectionState.Builder()
- .setTransportType(mTransportType)
- .setState(TelephonyManager.DATA_DISCONNECTED)
- .setApnSetting(new ApnSetting.Builder()
- .setApnTypeBitmask(bitmask).buildWithoutCheck())
- .setNetworkType(getDataRat())
- .build());
- log("initApnContexts: apnContext=" + ApnSetting.getApnTypeString(
- apnConfigType.getType()));
- }
- mPrioritySortedApnContexts.sort((c1, c2) -> c2.getPriority() - c1.getPriority());
- logSortedApnContexts();
- }
-
- private void sortApnContextByPriority() {
- if (!mTelephonyManager.isDataCapable()) {
- log("sortApnContextByPriority: isDataCapable == false. No Apn Contexts loaded");
- return;
- }
-
- PersistableBundle carrierConfig;
- CarrierConfigManager configManager = (CarrierConfigManager) mPhone.getContext()
- .getSystemService(Context.CARRIER_CONFIG_SERVICE);
- if (configManager != null) {
- carrierConfig = configManager.getConfigForSubId(mPhone.getSubId());
- } else {
- carrierConfig = null;
- }
-
- log("sortApnContextByPriority: E");
- // Load device network attributes from resources
- final Collection<ApnConfigType> types =
- new ApnConfigTypeRepository(carrierConfig).getTypes();
- for (ApnConfigType apnConfigType : types) {
- if (mApnContextsByType.contains(apnConfigType.getType())) {
- ApnContext apnContext = mApnContextsByType.get(apnConfigType.getType());
- apnContext.setPriority(apnConfigType.getPriority());
- }
- }
-
- //Doing sorted in a different list to keep thread safety
- ArrayList<ApnContext> prioritySortedApnContexts =
- new ArrayList<>(mPrioritySortedApnContexts);
- prioritySortedApnContexts.sort((c1, c2) -> c2.getPriority() - c1.getPriority());
- mPrioritySortedApnContexts = prioritySortedApnContexts;
- logSortedApnContexts();
- }
-
- public LinkProperties getLinkProperties(String apnType) {
- ApnContext apnContext = mApnContexts.get(apnType);
- if (apnContext != null) {
- DataConnection dataConnection = apnContext.getDataConnection();
- if (dataConnection != null) {
- if (DBG) log("return link properties for " + apnType);
- return dataConnection.getLinkProperties();
- }
- }
- if (DBG) log("return new LinkProperties");
- return new LinkProperties();
- }
-
- public NetworkCapabilities getNetworkCapabilities(String apnType) {
- ApnContext apnContext = mApnContexts.get(apnType);
- if (apnContext!=null) {
- DataConnection dataConnection = apnContext.getDataConnection();
- if (dataConnection != null) {
- if (DBG) {
- log("get active pdp is not null, return NetworkCapabilities for " + apnType);
- }
- return dataConnection.getNetworkCapabilities();
- }
- }
- if (DBG) log("return new NetworkCapabilities");
- return new NetworkCapabilities();
- }
-
- // Return all active apn types
- public String[] getActiveApnTypes() {
- if (DBG) log("get all active apn types");
- ArrayList<String> result = new ArrayList<String>();
-
- for (ApnContext apnContext : mApnContexts.values()) {
- if (mAttached.get() && apnContext.isReady()) {
- result.add(apnContext.getApnType());
- }
- }
-
- return result.toArray(new String[0]);
- }
-
- /**
- * Get ApnTypes with connected data connections. This is different than getActiveApnTypes()
- * which returns apn types that with active apn contexts.
- * @return apn types
- */
- public String[] getConnectedApnTypes() {
- return mApnContexts.values().stream()
- .filter(ac -> ac.getState() == DctConstants.State.CONNECTED)
- .map(ApnContext::getApnType)
- .toArray(String[]::new);
- }
-
- @VisibleForTesting
- public Collection<ApnContext> getApnContexts() {
- return mPrioritySortedApnContexts;
- }
-
- /** Return active ApnSetting of a specific apnType */
- public ApnSetting getActiveApnSetting(String apnType) {
- if (VDBG) log("get active ApnSetting for type:" + apnType);
- ApnContext apnContext = mApnContexts.get(apnType);
- return (apnContext != null) ? apnContext.getApnSetting() : null;
- }
-
- // Return active apn of specific apn type
- public String getActiveApnString(String apnType) {
- if (VDBG) log( "get active apn string for type:" + apnType);
- ApnSetting setting = getActiveApnSetting(apnType);
- return (setting != null) ? setting.getApnName() : null;
- }
-
- /**
- * Returns {@link DctConstants.State} based on the state of the {@link DataConnection} that
- * contains a {@link ApnSetting} that supported the given apn type {@code anpType}.
- *
- * <p>
- * Assumes there is less than one {@link ApnSetting} can support the given apn type.
- */
- // TODO: for enterprise this always returns IDLE, which is ok for now since it is never called
- // for enterprise
- public DctConstants.State getState(String apnType) {
- DctConstants.State state = DctConstants.State.IDLE;
- final int apnTypeBitmask = ApnSetting.getApnTypesBitmaskFromString(apnType);
- for (DataConnection dc : mDataConnections.values()) {
- ApnSetting apnSetting = dc.getApnSetting();
- if (apnSetting != null && apnSetting.canHandleType(apnTypeBitmask)) {
- if (dc.isActive()) {
- state = getBetterConnectionState(state, DctConstants.State.CONNECTED);
- } else if (dc.isActivating()) {
- state = getBetterConnectionState(state, DctConstants.State.CONNECTING);
- } else if (dc.isInactive()) {
- state = getBetterConnectionState(state, DctConstants.State.IDLE);
- } else if (dc.isDisconnecting()) {
- state = getBetterConnectionState(state, DctConstants.State.DISCONNECTING);
- }
- }
- }
- return state;
- }
-
- /**
- * Return a better connection state between {@code stateA} and {@code stateB}. Check
- * {@link #DATA_CONNECTION_STATE_PRIORITIES} for the details.
- * @return the better connection state between {@code stateA} and {@code stateB}.
- */
- private static DctConstants.State getBetterConnectionState(
- DctConstants.State stateA, DctConstants.State stateB) {
- int idxA = ArrayUtils.indexOf(DATA_CONNECTION_STATE_PRIORITIES, stateA);
- int idxB = ArrayUtils.indexOf(DATA_CONNECTION_STATE_PRIORITIES, stateB);
- return idxA >= idxB ? stateA : stateB;
- }
-
- // Return if apn type is a provisioning apn.
- private boolean isProvisioningApn(String apnType) {
- ApnContext apnContext = mApnContexts.get(apnType);
- if (apnContext != null) {
- return apnContext.isProvisioningApn();
- }
- return false;
- }
-
- //****** Called from ServiceStateTracker
- /**
- * Invoked when ServiceStateTracker observes a transition from GPRS
- * attach to detach.
- */
- private void onDataConnectionDetached() {
- /*
- * We presently believe it is unnecessary to tear down the PDP context
- * when GPRS detaches, but we should stop the network polling.
- */
- if (DBG) log ("onDataConnectionDetached: stop polling and notify detached");
- stopNetStatPoll();
- stopDataStallAlarm();
- mAttached.set(false);
- }
-
- private void onDataConnectionAttached() {
- if (DBG) log("onDataConnectionAttached");
- mAttached.set(true);
- if (isAnyDataConnected()) {
- if (DBG) log("onDataConnectionAttached: start polling notify attached");
- startNetStatPoll();
- startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
- }
- if (mAutoAttachOnCreationConfig) {
- mAutoAttachEnabled.set(true);
- }
- setupDataOnAllConnectableApns(Phone.REASON_DATA_ATTACHED, RetryFailures.ALWAYS);
- }
-
- /**
- * Check if it is allowed to make a data connection (without checking APN context specific
- * conditions).
- *
- * @param dataConnectionReasons Data connection allowed or disallowed reasons as the output
- * param. It's okay to pass null here and no reasons will be
- * provided.
- * @return True if data connection is allowed, otherwise false.
- */
- public boolean isDataAllowed(DataConnectionReasons dataConnectionReasons) {
- return isDataAllowed(null, REQUEST_TYPE_NORMAL, dataConnectionReasons);
- }
-
- /**
- * Check if it is allowed to make a data connection for a given APN type.
- *
- * @param apnContext APN context. If passing null, then will only check general but not APN
- * specific conditions (e.g. APN state, metered/unmetered APN).
- * @param requestType Setup data request type.
- * @param dataConnectionReasons Data connection allowed or disallowed reasons as the output
- * param. It's okay to pass null here and no reasons will be
- * provided.
- * @return True if data connection is allowed, otherwise false.
- */
- public boolean isDataAllowed(ApnContext apnContext, @RequestNetworkType int requestType,
- DataConnectionReasons dataConnectionReasons) {
- // Step 1: Get all environment conditions.
- // Step 2: Special handling for emergency APN.
- // Step 3. Build disallowed reasons.
- // Step 4: Determine if data should be allowed in some special conditions.
-
- DataConnectionReasons reasons = new DataConnectionReasons();
-
- int requestApnType = 0;
- if (apnContext != null) {
- requestApnType = apnContext.getApnTypeBitmask();
- }
-
- // Step 1: Get all environment conditions.
- final boolean internalDataEnabled = mDataEnabledSettings.isInternalDataEnabled();
- boolean attachedState = mAttached.get();
- boolean desiredPowerState = mPhone.getServiceStateTracker().getDesiredPowerState();
- boolean radioStateFromCarrier = mPhone.getServiceStateTracker().getPowerStateFromCarrier();
- // TODO: Remove this hack added by ag/641832.
- int dataRat = getDataRat();
- if (dataRat == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN) {
- desiredPowerState = true;
- radioStateFromCarrier = true;
- }
-
- boolean defaultDataSelected = SubscriptionManager.isValidSubscriptionId(
- SubscriptionManager.getDefaultDataSubscriptionId());
-
- boolean isMeteredApnType = apnContext == null
- || ApnSettingUtils.isMeteredApnType(requestApnType, mPhone);
-
- PhoneConstants.State phoneState = PhoneConstants.State.IDLE;
- // Note this is explicitly not using mPhone.getState. See b/19090488.
- // mPhone.getState reports the merge of CS and PS (volte) voice call state
- // but we only care about CS calls here for data/voice concurrency issues.
- // Calling getCallTracker currently gives you just the CS side where the
- // ImsCallTracker is held internally where applicable.
- // This should be redesigned to ask explicitly what we want:
- // voiceCallStateAllowDataCall, or dataCallAllowed or something similar.
- if (mPhone.getCallTracker() != null) {
- phoneState = mPhone.getCallTracker().getState();
- }
-
- // Step 2: Special handling for emergency APN.
- if (apnContext != null
- && requestApnType == ApnSetting.TYPE_EMERGENCY
- && apnContext.isConnectable()) {
- // If this is an emergency APN, as long as the APN is connectable, we
- // should allow it.
- if (dataConnectionReasons != null) {
- dataConnectionReasons.add(DataAllowedReasonType.EMERGENCY_APN);
- }
- // Bail out without further checks.
- return true;
- }
-
- // Step 3. Build disallowed reasons.
- if (apnContext != null && !apnContext.isConnectable()) {
- DctConstants.State state = apnContext.getState();
- if (state == DctConstants.State.CONNECTED) {
- reasons.add(DataDisallowedReasonType.DATA_ALREADY_CONNECTED);
- } else if (state == DctConstants.State.DISCONNECTING) {
- reasons.add(DataDisallowedReasonType.DATA_IS_DISCONNECTING);
- } else if (state == DctConstants.State.CONNECTING) {
- reasons.add(DataDisallowedReasonType.DATA_IS_CONNECTING);
- } else {
- reasons.add(DataDisallowedReasonType.APN_NOT_CONNECTABLE);
- }
- }
-
- // In legacy mode, if RAT is IWLAN then don't allow default/IA PDP at all.
- // Rest of APN types can be evaluated for remaining conditions.
- if ((apnContext != null && requestApnType == ApnSetting.TYPE_DEFAULT
- || requestApnType == ApnSetting.TYPE_ENTERPRISE
- || requestApnType == ApnSetting.TYPE_IA)
- && mPhone.getAccessNetworksManager().isInLegacyMode()
- && dataRat == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN) {
- reasons.add(DataDisallowedReasonType.ON_IWLAN);
- }
-
- // If device is not on NR, don't allow enterprise
- if (apnContext != null && requestApnType == ApnSetting.TYPE_ENTERPRISE
- && dataRat != ServiceState.RIL_RADIO_TECHNOLOGY_NR) {
- reasons.add(DataDisallowedReasonType.NOT_ON_NR);
- }
-
- if (shouldRestrictDataForEcbm() || mPhone.isInEmergencyCall()) {
- reasons.add(DataDisallowedReasonType.IN_ECBM);
- }
-
- if (!attachedState && !shouldAutoAttach() && requestType != REQUEST_TYPE_HANDOVER) {
- reasons.add(DataDisallowedReasonType.NOT_ATTACHED);
- }
- if (mPhone.getSubId() == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
- reasons.add(DataDisallowedReasonType.SIM_NOT_READY);
- }
- if (phoneState != PhoneConstants.State.IDLE
- && !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
- reasons.add(DataDisallowedReasonType.INVALID_PHONE_STATE);
- reasons.add(DataDisallowedReasonType.CONCURRENT_VOICE_DATA_NOT_ALLOWED);
- }
- if (!internalDataEnabled) {
- reasons.add(DataDisallowedReasonType.INTERNAL_DATA_DISABLED);
- }
- if (!defaultDataSelected) {
- reasons.add(DataDisallowedReasonType.DEFAULT_DATA_UNSELECTED);
- }
- if (mPhone.getServiceState().getDataRoaming() && !getDataRoamingEnabled()) {
- reasons.add(DataDisallowedReasonType.ROAMING_DISABLED);
- }
- if (mIsPsRestricted) {
- reasons.add(DataDisallowedReasonType.PS_RESTRICTED);
- }
- if (!desiredPowerState) {
- reasons.add(DataDisallowedReasonType.UNDESIRED_POWER_STATE);
- }
- if (!radioStateFromCarrier) {
- reasons.add(DataDisallowedReasonType.RADIO_DISABLED_BY_CARRIER);
- }
- if (!mDataServiceBound) {
- reasons.add(DataDisallowedReasonType.DATA_SERVICE_NOT_READY);
- }
-
- if (apnContext != null) {
- if (mPhone.getAccessNetworksManager().getPreferredTransport(
- apnContext.getApnTypeBitmask())
- == AccessNetworkConstants.TRANSPORT_TYPE_INVALID) {
- // If QNS explicitly specified this APN type is not allowed on either cellular or
- // IWLAN, we should not allow data setup.
- reasons.add(DataDisallowedReasonType.DISABLED_BY_QNS);
- } else if (mTransportType != mPhone.getAccessNetworksManager().getPreferredTransport(
- apnContext.getApnTypeBitmask())) {
- // If the latest preference has already switched to other transport, we should not
- // allow data setup.
- reasons.add(DataDisallowedReasonType.ON_OTHER_TRANSPORT);
- }
-
- // If the transport has been already switched to the other transport, we should not
- // allow the data setup. The only exception is the handover case, where we setup
- // handover data connection before switching the transport.
- if (mTransportType != mPhone.getAccessNetworksManager().getCurrentTransport(
- apnContext.getApnTypeBitmask()) && requestType != REQUEST_TYPE_HANDOVER) {
- reasons.add(DataDisallowedReasonType.ON_OTHER_TRANSPORT);
- }
-
- // Check if the device is under data throttling.
- long retryTime = mDataThrottler.getRetryTime(apnContext.getApnTypeBitmask());
- if (retryTime > SystemClock.elapsedRealtime()) {
- reasons.add(DataDisallowedReasonType.DATA_THROTTLED);
- }
- }
-
- boolean isDataEnabled = apnContext == null ? mDataEnabledSettings.isDataEnabled()
- : mDataEnabledSettings.isDataEnabled(requestApnType);
-
- if (!isDataEnabled) {
- reasons.add(DataDisallowedReasonType.DATA_DISABLED);
- }
-
- // If there are hard disallowed reasons, we should not allow data connection no matter what.
- if (reasons.containsHardDisallowedReasons()) {
- if (dataConnectionReasons != null) {
- dataConnectionReasons.copyFrom(reasons);
- }
- return false;
- }
-
- // Step 4: Determine if data should be allowed in some special conditions.
-
- // At this point, if data is not allowed, it must be because of the soft reasons. We
- // should start to check some special conditions that data will be allowed.
- if (!reasons.allowed()) {
- // Check if the transport is WLAN ie wifi (for AP-assisted mode devices)
- if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
- reasons.add(DataAllowedReasonType.UNMETERED_APN);
- // Or if the data is on cellular, and the APN type is determined unmetered by the
- // configuration.
- } else if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN
- && !isMeteredApnType && requestApnType != ApnSetting.TYPE_DEFAULT
- && requestApnType != ApnSetting.TYPE_ENTERPRISE) {
- reasons.add(DataAllowedReasonType.UNMETERED_APN);
- }
-
- // If the request is restricted and there are only soft disallowed reasons (e.g. data
- // disabled, data roaming disabled) existing, we should allow the data. ENTERPRISE is
- // an exception and should not be treated as restricted for this purpose; it should be
- // treated same as DEFAULT.
- if (apnContext != null
- && apnContext.hasRestrictedRequests(true)
- && !apnContext.getApnType().equals(ApnSetting.TYPE_ENTERPRISE_STRING)
- && !reasons.allowed()) {
- reasons.add(DataAllowedReasonType.RESTRICTED_REQUEST);
- }
- } else {
- // If there is no disallowed reasons, then we should allow the data request with
- // normal reason.
- reasons.add(DataAllowedReasonType.NORMAL);
- }
-
- if (dataConnectionReasons != null) {
- dataConnectionReasons.copyFrom(reasons);
- }
-
- return reasons.allowed();
- }
-
- // arg for setupDataOnAllConnectableApns
- protected enum RetryFailures {
- // retry failed networks always (the old default)
- ALWAYS,
- // retry only when a substantial change has occurred. Either:
- // 1) we were restricted by voice/data concurrency and aren't anymore
- // 2) our apn list has change
- ONLY_ON_CHANGE
- };
-
- protected void setupDataOnAllConnectableApns(String reason, RetryFailures retryFailures) {
- if (VDBG) log("setupDataOnAllConnectableApns: " + reason);
-
- if (DBG && !VDBG) {
- StringBuilder sb = new StringBuilder(120);
- for (ApnContext apnContext : mPrioritySortedApnContexts) {
- sb.append(apnContext.getApnType());
- sb.append(":[state=");
- sb.append(apnContext.getState());
- sb.append(",enabled=");
- sb.append(apnContext.isEnabled());
- sb.append("] ");
- }
- log("setupDataOnAllConnectableApns: " + reason + " " + sb);
- }
-
- for (ApnContext apnContext : mPrioritySortedApnContexts) {
- setupDataOnConnectableApn(apnContext, reason, retryFailures);
- }
- }
-
- protected void setupDataOnConnectableApn(ApnContext apnContext, String reason,
- RetryFailures retryFailures) {
- if (VDBG) log("setupDataOnAllConnectableApns: apnContext " + apnContext);
-
- if (apnContext.getState() == DctConstants.State.FAILED
- || apnContext.getState() == DctConstants.State.RETRYING) {
- if (retryFailures == RetryFailures.ALWAYS) {
- apnContext.releaseDataConnection(reason);
- } else if (!apnContext.isConcurrentVoiceAndDataAllowed()
- && mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
- // RetryFailures.ONLY_ON_CHANGE - check if voice concurrency has changed
- apnContext.releaseDataConnection(reason);
- }
- }
- if (apnContext.isConnectable()) {
- log("isConnectable() call trySetupData");
- apnContext.setReason(reason);
- trySetupData(apnContext, REQUEST_TYPE_NORMAL, null);
- }
- }
-
- private boolean shouldRestrictDataForEcbm() {
- boolean isInEcm = mPhone.isInEcm();
- boolean isInImsEcm = mPhone.getImsPhone() != null && mPhone.getImsPhone().isInImsEcm();
- log("shouldRestrictDataForEcbm: isInEcm=" + isInEcm + " isInImsEcm=" + isInImsEcm);
- return isInEcm && !isInImsEcm;
- }
-
- private boolean isHandoverPending(@ApnType int apnType) {
- List<Message> messageList = mHandoverCompletionMsgs.get(apnType);
- return messageList != null && messageList.size() > 0;
- }
-
- private void trySetupData(ApnContext apnContext, @RequestNetworkType int requestType,
- @Nullable Message onHandoverCompleteMsg) {
- if (onHandoverCompleteMsg != null) {
- addHandoverCompleteMsg(onHandoverCompleteMsg, apnContext.getApnTypeBitmask());
- }
-
- if (mPhone.getSimulatedRadioControl() != null) {
- // Assume data is connected on the simulator
- log("trySetupData: X We're on the simulator; assuming connected retValue=true");
- return;
- }
-
- DataConnectionReasons dataConnectionReasons = new DataConnectionReasons();
- boolean isDataAllowed = isDataAllowed(apnContext, requestType, dataConnectionReasons);
- String logStr = "trySetupData for APN type " + apnContext.getApnType() + ", reason: "
- + apnContext.getReason() + ", requestType=" + requestTypeToString(requestType)
- + ". " + dataConnectionReasons.toString();
- if (dataConnectionReasons.contains(DataDisallowedReasonType.DISABLED_BY_QNS)
- || dataConnectionReasons.contains(DataDisallowedReasonType.ON_OTHER_TRANSPORT)) {
- logStr += ", current transport=" + AccessNetworkConstants.transportTypeToString(
- mPhone.getAccessNetworksManager().getCurrentTransport(
- apnContext.getApnTypeBitmask()));
- logStr += ", preferred transport=" + AccessNetworkConstants.transportTypeToString(
- mPhone.getAccessNetworksManager().getPreferredTransport(
- apnContext.getApnTypeBitmask()));
- }
- if (DBG) log(logStr);
- ApnContext.requestLog(apnContext, logStr);
- if (!isDataAllowed) {
- StringBuilder str = new StringBuilder();
-
- str.append("trySetupData failed. apnContext = [type=" + apnContext.getApnType()
- + ", mState=" + apnContext.getState() + ", apnEnabled="
- + apnContext.isEnabled() + ", mDependencyMet="
- + apnContext.isDependencyMet() + "] ");
-
- if (!mDataEnabledSettings.isDataEnabled()) {
- str.append("isDataEnabled() = false. " + mDataEnabledSettings);
- }
-
- // Check if it fails because of the existing data is still disconnecting.
- if (dataConnectionReasons.contains(DataDisallowedReasonType.DATA_IS_DISCONNECTING)
- && isHandoverPending(apnContext.getApnTypeBitmask())) {
- // Normally we don't retry when isDataAllow() returns false, because that's consider
- // pre-condition not met, for example, data not enabled by the user, or airplane
- // mode is on. If we retry in those cases, there will be significant power impact.
- // DATA_IS_DISCONNECTING is a special case we want to retry, and for the handover
- // case only.
- log("Data is disconnecting. Will retry handover later.");
- return;
- }
-
- // If this is a data retry, we should set the APN state to FAILED so it won't stay
- // in RETRYING forever.
- if (apnContext.getState() == DctConstants.State.RETRYING) {
- apnContext.setState(DctConstants.State.FAILED);
- str.append(" Stop retrying.");
- }
-
- if (DBG) log(str.toString());
- ApnContext.requestLog(apnContext, str.toString());
- if (requestType == REQUEST_TYPE_HANDOVER) {
- // If fails due to latest preference already changed back to source transport, then
- // just fallback (will not attempt handover anymore, and will not tear down the
- // data connection on source transport.
- boolean fallback = dataConnectionReasons.contains(
- DataDisallowedReasonType.ON_OTHER_TRANSPORT);
- sendHandoverCompleteMessages(apnContext.getApnTypeBitmask(), false, fallback);
- }
- return;
- }
-
- if (apnContext.getState() == DctConstants.State.FAILED) {
- String str = "trySetupData: make a FAILED ApnContext IDLE so its reusable";
- if (DBG) log(str);
- ApnContext.requestLog(apnContext, str);
- apnContext.setState(DctConstants.State.IDLE);
- }
- int radioTech = getDataRat();
- if (radioTech == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN && mPhone.getServiceState()
- .getState() == ServiceState.STATE_IN_SERVICE) {
- radioTech = getVoiceRat();
- }
- log("service state=" + mPhone.getServiceState());
- apnContext.setConcurrentVoiceAndDataAllowed(mPhone.getServiceStateTracker()
- .isConcurrentVoiceAndDataAllowed());
- if (apnContext.getState() == DctConstants.State.IDLE) {
- ArrayList<ApnSetting> waitingApns =
- buildWaitingApns(apnContext.getApnType(), radioTech);
- if (waitingApns.isEmpty()) {
- String str = "trySetupData: X No APN found retValue=false";
- if (DBG) log(str);
- ApnContext.requestLog(apnContext, str);
- if (requestType == REQUEST_TYPE_HANDOVER) {
- sendHandoverCompleteMessages(apnContext.getApnTypeBitmask(), false,
- false);
- }
- return;
- } else {
- apnContext.setWaitingApns(waitingApns);
- if (DBG) {
- log("trySetupData: Create from mAllApnSettings : "
- + apnListToString(mAllApnSettings));
- }
- }
- }
-
- if (!setupData(apnContext, radioTech, requestType)
- && requestType == REQUEST_TYPE_HANDOVER) {
- sendHandoverCompleteMessages(apnContext.getApnTypeBitmask(), false, false);
- }
- }
-
- /**
- * Clean up all data connections. Note this is just detach the APN context from the data
- * connection. After all APN contexts are detached from the data connection, the data
- * connection will be torn down.
- *
- * @param reason Reason for the clean up.
- */
- public void cleanUpAllConnections(String reason) {
- log("cleanUpAllConnections");
- Message msg = obtainMessage(DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS);
- msg.obj = reason;
- sendMessage(msg);
- }
-
- /**
- * Clean up all data connections by detaching the APN contexts from the data connections, which
- * eventually tearing down all data connections after all APN contexts are detached from the
- * data connections.
- *
- * @param detach {@code true} if detaching APN context from the underlying data connection (when
- * no other APN context is attached to the data connection, the data connection will be torn
- * down.) {@code false} to only reset the data connection's state machine.
- *
- * @param reason reason for the clean up.
- * @return boolean - true if we did cleanup any connections, false if they
- * were already all disconnected.
- */
- private boolean cleanUpAllConnectionsInternal(boolean detach, String reason) {
- if (DBG) log("cleanUpAllConnectionsInternal: detach=" + detach + " reason=" + reason);
- boolean didDisconnect = false;
- boolean disableMeteredOnly = false;
-
- // reasons that only metered apn will be torn down
- if (!TextUtils.isEmpty(reason)) {
- disableMeteredOnly = reason.equals(Phone.REASON_DATA_SPECIFIC_DISABLED) ||
- reason.equals(Phone.REASON_ROAMING_ON) ||
- reason.equals(Phone.REASON_CARRIER_ACTION_DISABLE_METERED_APN);
- }
-
- for (ApnContext apnContext : mApnContexts.values()) {
- // Exclude the IMS APN from single data connection case.
- if (reason.equals(Phone.REASON_SINGLE_PDN_ARBITRATION)
- && apnContext.getApnType().equals(ApnSetting.TYPE_IMS_STRING)) {
- continue;
- }
-
- if (shouldCleanUpConnection(apnContext, disableMeteredOnly,
- reason.equals(Phone.REASON_SINGLE_PDN_ARBITRATION))) {
- // TODO - only do cleanup if not disconnected
- if (apnContext.isDisconnected() == false) didDisconnect = true;
- apnContext.setReason(reason);
- cleanUpConnectionInternal(detach, RELEASE_TYPE_DETACH, apnContext);
- } else if (DBG) {
- log("cleanUpAllConnectionsInternal: APN type " + apnContext.getApnType()
- + " shouldn't be cleaned up.");
- }
- }
-
- stopNetStatPoll();
- stopDataStallAlarm();
-
- // TODO: Do we need mRequestedApnType?
- mRequestedApnType = ApnSetting.TYPE_DEFAULT;
-
- if (areAllDataDisconnected()) {
- notifyAllDataDisconnected();
- }
-
- return didDisconnect;
- }
-
- boolean shouldCleanUpConnection(ApnContext apnContext, boolean disableMeteredOnly,
- boolean singlePdn) {
- if (apnContext == null) return false;
-
- // If APN setting is not null and the reason is single PDN arbitration, clean up connection.
- ApnSetting apnSetting = apnContext.getApnSetting();
- if (apnSetting != null && singlePdn) return true;
-
- // If meteredOnly is false, clean up all connections.
- if (!disableMeteredOnly) return true;
-
- // If meteredOnly is true, and apnSetting is null or it's un-metered, no need to clean up.
- if (apnSetting == null || !ApnSettingUtils.isMetered(apnSetting, mPhone)) return false;
-
- boolean isRoaming = mPhone.getServiceState().getDataRoaming();
- boolean isDataRoamingDisabled = !getDataRoamingEnabled();
- boolean isDataDisabled = !mDataEnabledSettings.isDataEnabled(
- apnSetting.getApnTypeBitmask());
-
- // Should clean up if its data is disabled, or data roaming is disabled while roaming.
- return isDataDisabled || (isRoaming && isDataRoamingDisabled);
- }
-
- /**
- * Detach the APN context from the associated data connection. This data connection might be
- * torn down if no other APN context is attached to it.
- *
- * @param apnContext The APN context to be detached
- */
- void cleanUpConnection(ApnContext apnContext) {
- if (DBG) log("cleanUpConnection: apnContext=" + apnContext);
- Message msg = obtainMessage(DctConstants.EVENT_CLEAN_UP_CONNECTION);
- msg.arg2 = 0;
- msg.obj = apnContext;
- sendMessage(msg);
- }
-
- /**
- * Detach the APN context from the associated data connection. This data connection will be
- * torn down if no other APN context is attached to it.
- *
- * @param detach {@code true} if detaching APN context from the underlying data connection (when
- * no other APN context is attached to the data connection, the data connection will be torn
- * down.) {@code false} to only reset the data connection's state machine.
- * @param releaseType Data release type.
- * @param apnContext The APN context to be detached.
- */
- private void cleanUpConnectionInternal(boolean detach, @ReleaseNetworkType int releaseType,
- ApnContext apnContext) {
- if (apnContext == null) {
- if (DBG) log("cleanUpConnectionInternal: apn context is null");
- return;
- }
-
- DataConnection dataConnection = apnContext.getDataConnection();
- String str = "cleanUpConnectionInternal: detach=" + detach + " reason="
- + apnContext.getReason();
- if (VDBG) log(str + " apnContext=" + apnContext);
- ApnContext.requestLog(apnContext, str);
- if (detach) {
- if (apnContext.isDisconnected()) {
- // The request is detach and but ApnContext is not connected.
- // If apnContext is not enabled anymore, break the linkage to the data connection.
- apnContext.releaseDataConnection("");
- } else {
- // Connection is still there. Try to clean up.
- if (dataConnection != null) {
- if (apnContext.getState() != DctConstants.State.DISCONNECTING) {
- boolean disconnectAll = false;
- if (ApnSetting.TYPE_DUN_STRING.equals(apnContext.getApnType())
- && ServiceState.isCdma(getDataRat())) {
- if (DBG) {
- log("cleanUpConnectionInternal: disconnectAll DUN connection");
- }
- // For CDMA DUN, we need to tear it down immediately. A new data
- // connection will be reestablished with correct profile id.
- disconnectAll = true;
- }
- final int generation = apnContext.getConnectionGeneration();
- str = "cleanUpConnectionInternal: tearing down"
- + (disconnectAll ? " all" : "") + " using gen#" + generation;
- if (DBG) log(str + "apnContext=" + apnContext);
- ApnContext.requestLog(apnContext, str);
- Pair<ApnContext, Integer> pair = new Pair<>(apnContext, generation);
- Message msg = obtainMessage(DctConstants.EVENT_DISCONNECT_DONE, pair);
-
- if (disconnectAll || releaseType == RELEASE_TYPE_HANDOVER) {
- dataConnection.tearDownAll(apnContext.getReason(), releaseType, msg);
- } else {
- dataConnection.tearDown(apnContext, apnContext.getReason(), msg);
- }
-
- apnContext.setState(DctConstants.State.DISCONNECTING);
- }
- } else {
- // apn is connected but no reference to the data connection.
- // Should not be happen, but reset the state in case.
- apnContext.setState(DctConstants.State.IDLE);
- ApnContext.requestLog(
- apnContext, "cleanUpConnectionInternal: connected, bug no dc");
- }
- }
- } else {
- // force clean up the data connection.
- if (dataConnection != null) dataConnection.reset();
- apnContext.setState(DctConstants.State.IDLE);
- apnContext.setDataConnection(null);
- }
-
- // If there is any outstanding handover request, we need to respond it.
- sendHandoverCompleteMessages(apnContext.getApnTypeBitmask(), false, false);
-
- // Make sure reconnection alarm is cleaned up if there is no ApnContext
- // associated to the connection.
- if (dataConnection != null) {
- cancelReconnect(apnContext);
- }
- str = "cleanUpConnectionInternal: X detach=" + detach + " reason="
- + apnContext.getReason();
- if (DBG) log(str + " apnContext=" + apnContext + " dc=" + apnContext.getDataConnection());
- }
-
- private Cursor getPreferredApnCursor(int subId) {
- Cursor cursor = null;
- if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
- cursor = mPhone.getContext().getContentResolver().query(
- Uri.withAppendedPath(PREFERAPN_NO_UPDATE_URI_USING_SUBID,
- String.valueOf(subId)), null, null, null,
- Telephony.Carriers.DEFAULT_SORT_ORDER);
- }
- return cursor;
- }
-
- private ApnSetting getPreferredApnFromDB() {
- ApnSetting preferredApn = null;
- Cursor cursor = getPreferredApnCursor(mPhone.getSubId());
- if (cursor != null) {
- if (cursor.getCount() > 0) {
- cursor.moveToFirst();
- preferredApn = ApnSetting.makeApnSetting(cursor);
- }
- cursor.close();
- }
- if (VDBG) log("getPreferredApnFromDB: preferredApn=" + preferredApn);
- return preferredApn;
- }
-
- private void setDefaultPreferredApnIfNeeded() {
- ApnSetting defaultPreferredApn = null;
- PersistableBundle bundle = getCarrierConfig();
- String defaultPreferredApnName = bundle.getString(CarrierConfigManager
- .KEY_DEFAULT_PREFERRED_APN_NAME_STRING);
-
- if (TextUtils.isEmpty(defaultPreferredApnName) || getPreferredApnFromDB() != null) {
- return;
- }
-
- String selection = Telephony.Carriers.APN + " = \"" + defaultPreferredApnName + "\" AND "
- + Telephony.Carriers.EDITED_STATUS + " = " + Telephony.Carriers.UNEDITED;
- Cursor cursor = mPhone.getContext().getContentResolver().query(
- Uri.withAppendedPath(Telephony.Carriers.SIM_APN_URI,
- "filtered/subId/" + mPhone.getSubId()),
- null, selection, null, Telephony.Carriers._ID);
-
- if (cursor != null) {
- if (cursor.getCount() > 0) {
- if (cursor.moveToFirst()) {
- defaultPreferredApn = ApnSetting.makeApnSetting(cursor);
- }
- }
- cursor.close();
- }
-
- if (defaultPreferredApn != null
- && defaultPreferredApn.canHandleType(mRequestedApnType)) {
- log("setDefaultPreferredApnIfNeeded: For APN type "
- + ApnSetting.getApnTypeString(mRequestedApnType)
- + " found default apnSetting "
- + defaultPreferredApn);
-
- setPreferredApn(defaultPreferredApn.getId(), true);
- }
-
- return;
- }
-
- /**
- * Check if preferred apn is allowed to edit by user.
- * @return {@code true} if it is allowed to edit.
- */
- @VisibleForTesting
- public boolean isPreferredApnUserEdited() {
- boolean isUserEdited = false;
- Cursor cursor = getPreferredApnCursor(mPhone.getSubId());
- if (cursor != null) {
- if (cursor.getCount() > 0) {
- if (cursor.moveToFirst()) {
- isUserEdited = cursor.getInt(
- cursor.getColumnIndexOrThrow(Telephony.Carriers.EDITED_STATUS))
- == Telephony.Carriers.USER_EDITED;
- }
- }
- cursor.close();
- }
- if (VDBG) log("isPreferredApnUserEdited: isUserEdited=" + isUserEdited);
- return isUserEdited;
- }
-
- /**
- * Fetch the DUN apns
- * @return a list of DUN ApnSetting objects
- */
- @VisibleForTesting
- public @NonNull ArrayList<ApnSetting> fetchDunApns() {
- if (mPhone.getServiceState().getRoaming() && !isPreferredApnUserEdited()
- && getCarrierConfig().getBoolean(CarrierConfigManager
- .KEY_DISABLE_DUN_APN_WHILE_ROAMING_WITH_PRESET_APN_BOOL)) {
- if (VDBG) log("fetchDunApns: Dun apn is not used in roaming network");
- return new ArrayList<ApnSetting>(0);
- }
-
- int bearer = getDataRat();
- ArrayList<ApnSetting> dunCandidates = new ArrayList<ApnSetting>();
- ArrayList<ApnSetting> retDunSettings = new ArrayList<ApnSetting>();
-
- if (dunCandidates.isEmpty()) {
- if (!ArrayUtils.isEmpty(mAllApnSettings)) {
- for (ApnSetting apn : mAllApnSettings) {
- if (apn.canHandleType(ApnSetting.TYPE_DUN)) {
- dunCandidates.add(apn);
- }
- }
- if (VDBG) log("fetchDunApns: dunCandidates from database: " + dunCandidates);
- }
- }
-
- int preferredApnSetId = getPreferredApnSetId();
- ApnSetting preferredApn = getPreferredApnFromDB();
- for (ApnSetting dunSetting : dunCandidates) {
- if (dunSetting.canSupportNetworkType(
- ServiceState.rilRadioTechnologyToNetworkType(bearer))) {
- if (preferredApnSetId == dunSetting.getApnSetId()) {
- if (preferredApn != null && preferredApn.equals(dunSetting)) {
- // If there is a preferred APN can handled DUN type, prepend it to list to
- // use it preferred.
- retDunSettings.add(0, dunSetting);
- } else {
- retDunSettings.add(dunSetting);
- }
- }
- }
- }
-
- if (VDBG) log("fetchDunApns: dunSettings=" + retDunSettings);
- return retDunSettings;
- }
-
- private int getPreferredApnSetId() {
- // preferapnset uri returns all APNs for the current carrier which have an apn_set_id
- // equal to the preferred APN (if no preferred APN, or if the preferred APN has no set id,
- // the query will return null)
- Cursor c = mPhone.getContext().getContentResolver()
- .query(Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI,
- "preferapnset/subId/" + mPhone.getSubId()),
- new String[] {Telephony.Carriers.APN_SET_ID}, null, null, null);
- if (c == null) {
- loge("getPreferredApnSetId: cursor is null");
- return Telephony.Carriers.NO_APN_SET_ID;
- }
-
- int setId;
- if (c.getCount() < 1) {
- loge("getPreferredApnSetId: no APNs found");
- setId = Telephony.Carriers.NO_APN_SET_ID;
- } else {
- c.moveToFirst();
- setId = c.getInt(0 /* index of Telephony.Carriers.APN_SET_ID */);
- }
-
- if (!c.isClosed()) {
- c.close();
- }
- return setId;
- }
-
- public boolean hasMatchedTetherApnSetting() {
- ArrayList<ApnSetting> matches = fetchDunApns();
- log("hasMatchedTetherApnSetting: APNs=" + matches);
- return matches.size() > 0;
- }
-
- /**
- * @return the {@link DataConnection} with the given context id {@code cid}.
- */
- public DataConnection getDataConnectionByContextId(int cid) {
- return mDcc.getActiveDcByCid(cid);
- }
-
- /**
- * @return the {@link DataConnection} with the given APN context. Null if no data connection
- * is found.
- */
- public @Nullable DataConnection getDataConnectionByApnType(String apnType) {
- // TODO: Clean up all APN type in string usage
- ApnContext apnContext = mApnContexts.get(apnType);
- if (apnContext != null) {
- return apnContext.getDataConnection();
- }
- return null;
- }
-
- /**
- * Check if the data fail cause is a permanent failure (i.e. Frameworks will not retry data
- * setup).
- *
- * @param dcFailCause The data fail cause
- * @return {@code true} if the data fail cause is a permanent failure.
- */
- @VisibleForTesting
- public boolean isPermanentFailure(@DataFailureCause int dcFailCause) {
- return (DataFailCause.isPermanentFailure(mPhone.getContext(), dcFailCause,
- mPhone.getSubId())
- && (mAttached.get() == false || dcFailCause != DataFailCause.SIGNAL_LOST));
- }
-
- private DataConnection findFreeDataConnection() {
- for (DataConnection dataConnection : mDataConnections.values()) {
- boolean inUse = false;
- for (ApnContext apnContext : mApnContexts.values()) {
- if (apnContext.getDataConnection() == dataConnection) {
- inUse = true;
- break;
- }
- }
- if (!inUse) {
- if (DBG) {
- log("findFreeDataConnection: found free DataConnection=" + dataConnection);
- }
- return dataConnection;
- }
- }
- log("findFreeDataConnection: NO free DataConnection");
- return null;
- }
-
- /**
- * Setup a data connection based on given APN type.
- *
- * @param apnContext APN context
- * @param radioTech RAT of the data connection
- * @param requestType Data request type
- * @return True if successful, otherwise false.
- */
- private boolean setupData(ApnContext apnContext, int radioTech,
- @RequestNetworkType int requestType) {
- if (DBG) {
- log("setupData: apnContext=" + apnContext + ", requestType="
- + requestTypeToString(requestType));
- }
- ApnContext.requestLog(
- apnContext, "setupData. requestType=" + requestTypeToString(requestType));
- ApnSetting apnSetting;
- DataConnection dataConnection = null;
-
- apnSetting = apnContext.getNextApnSetting();
-
- if (apnSetting == null) {
- if (DBG) log("setupData: return for no apn found!");
- return false;
- }
-
- // profile id is only meaningful when the profile is persistent on the modem.
- int profileId = DATA_PROFILE_INVALID;
- if (apnSetting.isPersistent()) {
- profileId = apnSetting.getProfileId();
- if (profileId == DATA_PROFILE_DEFAULT) {
- profileId = getApnProfileID(apnContext.getApnType());
- }
- }
-
- // On CDMA, if we're explicitly asking for DUN, we need have
- // a dun-profiled connection so we can't share an existing one
- // On GSM/LTE we can share existing apn connections provided they support
- // this type.
- // If asking for ENTERPRISE, there are no compatible data connections, so skip this check
- if ((apnContext.getApnTypeBitmask() != ApnSetting.TYPE_DUN
- || ServiceState.isGsm(getDataRat()))
- && apnContext.getApnTypeBitmask() != ApnSetting.TYPE_ENTERPRISE) {
- dataConnection = checkForCompatibleDataConnection(apnContext, apnSetting);
- if (dataConnection != null) {
- // Get the apn setting used by the data connection
- ApnSetting dataConnectionApnSetting = dataConnection.getApnSetting();
- if (dataConnectionApnSetting != null) {
- // Setting is good, so use it.
- apnSetting = dataConnectionApnSetting;
- }
- }
- }
- if (dataConnection == null) {
- if (isOnlySingleDcAllowed(radioTech)) {
- if (isHigherPriorityApnContextActive(apnContext)) {
- if (DBG) {
- log("setupData: Higher priority ApnContext active. Ignoring call");
- }
- return false;
- }
-
- // Should not start cleanUp if the setupData is for IMS APN
- // or retry of same APN(State==RETRYING).
- if (!apnContext.getApnType().equals(ApnSetting.TYPE_IMS_STRING)
- && (apnContext.getState() != DctConstants.State.RETRYING)) {
- // Only lower priority calls left. Disconnect them all in this single PDP case
- // so that we can bring up the requested higher priority call (once we receive
- // response for deactivate request for the calls we are about to disconnect
- if (cleanUpAllConnectionsInternal(true, Phone.REASON_SINGLE_PDN_ARBITRATION)) {
- // If any call actually requested to be disconnected, means we can't
- // bring up this connection yet as we need to wait for those data calls
- // to be disconnected.
- if (DBG) log("setupData: Some calls are disconnecting first."
- + " Wait and retry");
- return false;
- }
- }
-
- // No other calls are active, so proceed
- if (DBG) log("setupData: Single pdp. Continue setting up data call.");
- }
-
- dataConnection = findFreeDataConnection();
-
- if (dataConnection == null) {
- dataConnection = createDataConnection();
- }
-
- if (dataConnection == null) {
- if (DBG) log("setupData: No free DataConnection and couldn't create one, WEIRD");
- return false;
- }
- }
- final int generation = apnContext.incAndGetConnectionGeneration();
- if (DBG) {
- log("setupData: dc=" + dataConnection + " apnSetting=" + apnSetting + " gen#="
- + generation);
- }
-
- apnContext.setDataConnection(dataConnection);
- apnContext.setApnSetting(apnSetting);
- apnContext.setState(DctConstants.State.CONNECTING);
-
- Message msg = obtainMessage();
- msg.what = DctConstants.EVENT_DATA_SETUP_COMPLETE;
- msg.obj = new Pair<ApnContext, Integer>(apnContext, generation);
-
- ApnSetting preferredApn = getPreferredApn();
- boolean isPreferredApn = apnSetting.equals(preferredApn);
- dataConnection.bringUp(apnContext, profileId, radioTech, msg, generation, requestType,
- mPhone.getSubId(), isPreferredApn);
-
- if (DBG) {
- if (isPreferredApn) {
- log("setupData: initing! isPreferredApn=" + isPreferredApn
- + ", apnSetting={" + apnSetting.toString() + "}");
- } else {
- String preferredApnStr = preferredApn == null ? "null" : preferredApn.toString();
- log("setupData: initing! isPreferredApn=" + isPreferredApn
- + ", apnSetting={" + apnSetting + "}"
- + ", preferredApn={" + preferredApnStr + "}");
- }
- }
- return true;
- }
-
- // Get the allowed APN types for initial attach. The order in the returned list represent
- // the order of APN types that should be used for initial attach.
- private @NonNull @ApnType List<Integer> getAllowedInitialAttachApnTypes() {
- PersistableBundle bundle = getCarrierConfig();
- if (bundle != null) {
- String[] apnTypesArray = bundle.getStringArray(
- CarrierConfigManager.KEY_ALLOWED_INITIAL_ATTACH_APN_TYPES_STRING_ARRAY);
- if (apnTypesArray != null) {
- return Arrays.stream(apnTypesArray)
- .map(ApnSetting::getApnTypesBitmaskFromString)
- .collect(Collectors.toList());
- }
- }
-
- return Collections.emptyList();
- }
-
- protected void setInitialAttachApn() {
- ApnSetting apnSetting = null;
- int preferredApnSetId = getPreferredApnSetId();
- ArrayList<ApnSetting> allApnSettings = new ArrayList<>();
- if (mPreferredApn != null) {
- // Put the preferred apn at the beginning of the list. It's okay to have a duplicate
- // when later on mAllApnSettings get added. That would not change the selection result.
- allApnSettings.add(mPreferredApn);
- }
- allApnSettings.addAll(mAllApnSettings);
-
- // Get the allowed APN types for initial attach. Note that if none of the APNs has the
- // allowed APN types, then the initial attach will not be performed.
- List<Integer> allowedApnTypes = getAllowedInitialAttachApnTypes();
- for (int allowedApnType : allowedApnTypes) {
- apnSetting = allApnSettings.stream()
- .filter(apn -> apn.canHandleType(allowedApnType))
- .filter(apn -> (apn.getApnSetId() == preferredApnSetId
- || apn.getApnSetId() == Telephony.Carriers.MATCH_ALL_APN_SET_ID))
- .findFirst()
- .orElse(null);
- if (apnSetting != null) break;
- }
-
- if (DBG) {
- log("setInitialAttachApn: Allowed APN types=" + allowedApnTypes.stream()
- .map(ApnSetting::getApnTypeString)
- .collect(Collectors.joining(",")));
- }
-
- if (apnSetting == null) {
- if (DBG) log("setInitialAttachApn: X There in no available apn.");
- } else {
- if (DBG) log("setInitialAttachApn: X selected APN=" + apnSetting);
- mDataServiceManager.setInitialAttachApn(new DataProfile.Builder()
- .setApnSetting(apnSetting)
- .setPreferred(apnSetting.equals(getPreferredApn()))
- .build(),
- mPhone.getServiceState().getDataRoamingFromRegistration(), null);
- }
- }
-
- /**
- * Handles changes to the APN database.
- */
- private void onApnChanged() {
- if (mPhone instanceof GsmCdmaPhone) {
- // The "current" may no longer be valid. MMS depends on this to send properly. TBD
- ((GsmCdmaPhone)mPhone).updateCurrentCarrierInProvider();
- }
-
- // TODO: It'd be nice to only do this if the changed entrie(s)
- // match the current operator.
- if (DBG) log("onApnChanged: createAllApnList and cleanUpAllConnections");
- mDataThrottler.reset();
- setDefaultPreferredApnIfNeeded();
- createAllApnList();
- setDataProfilesAsNeeded();
- setInitialAttachApn();
- cleanUpConnectionsOnUpdatedApns(isAnyDataConnected(), Phone.REASON_APN_CHANGED);
-
- // FIXME: See bug 17426028 maybe no conditional is needed.
- if (mPhone.getSubId() == SubscriptionManager.getDefaultDataSubscriptionId()) {
- setupDataOnAllConnectableApns(Phone.REASON_APN_CHANGED, RetryFailures.ALWAYS);
- }
- }
-
- /**
- * "Active" here means ApnContext isEnabled() and not in FAILED state
- * @param apnContext to compare with
- * @return true if higher priority active apn found
- */
- private boolean isHigherPriorityApnContextActive(ApnContext apnContext) {
- if (apnContext.getApnType().equals(ApnSetting.TYPE_IMS_STRING)) {
- return false;
- }
-
- for (ApnContext otherContext : mPrioritySortedApnContexts) {
- if (otherContext.getApnType().equals(ApnSetting.TYPE_IMS_STRING)) {
- continue;
- }
- if (apnContext.getApnType().equalsIgnoreCase(otherContext.getApnType())) return false;
- if (otherContext.isEnabled() && otherContext.getState() != DctConstants.State.FAILED) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Reports if we support multiple connections or not.
- * This is a combination of factors, based on carrier and RAT.
- * @param rilRadioTech the RIL Radio Tech currently in use
- * @return true if only single DataConnection is allowed
- */
- private boolean isOnlySingleDcAllowed(int rilRadioTech) {
- int networkType = ServiceState.rilRadioTechnologyToNetworkType(rilRadioTech);
- // Default single dc rats with no knowledge of carrier
- int[] singleDcRats = null;
- // get the carrier specific value, if it exists, from CarrierConfigManager.
- // generally configManager and bundle should not be null, but if they are it should be okay
- // to leave singleDcRats null as well
- CarrierConfigManager configManager = (CarrierConfigManager)
- mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
- if (configManager != null) {
- PersistableBundle bundle = configManager.getConfigForSubId(mPhone.getSubId());
- if (bundle != null) {
- singleDcRats = bundle.getIntArray(
- CarrierConfigManager.KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY);
- }
- }
- boolean onlySingleDcAllowed = false;
- if (TelephonyUtils.IS_DEBUGGABLE
- && SystemProperties.getBoolean("persist.telephony.test.singleDc", false)) {
- onlySingleDcAllowed = true;
- }
- if (singleDcRats != null) {
- for (int i = 0; i < singleDcRats.length && !onlySingleDcAllowed; i++) {
- if (networkType == singleDcRats[i]) {
- onlySingleDcAllowed = true;
- }
- }
- }
-
- if (DBG) {
- log("isOnlySingleDcAllowed(" + TelephonyManager.getNetworkTypeName(networkType) + "): "
- + onlySingleDcAllowed);
- }
- return onlySingleDcAllowed;
- }
-
- void sendRestartRadio() {
- if (DBG)log("sendRestartRadio:");
- Message msg = obtainMessage(DctConstants.EVENT_RESTART_RADIO);
- sendMessage(msg);
- }
-
- private void restartRadio() {
- if (DBG) log("restartRadio: ************TURN OFF RADIO**************");
- cleanUpAllConnectionsInternal(true, Phone.REASON_RADIO_TURNED_OFF);
- mPhone.getServiceStateTracker().powerOffRadioSafely();
- /* Note: no need to call setRadioPower(true). Assuming the desired
- * radio power state is still ON (as tracked by ServiceStateTracker),
- * ServiceStateTracker will call setRadioPower when it receives the
- * RADIO_STATE_CHANGED notification for the power off. And if the
- * desired power state has changed in the interim, we don't want to
- * override it with an unconditional power on.
- */
- }
-
- /**
- * Return true if data connection need to be setup after disconnected due to
- * reason.
- *
- * @param apnContext APN context
- * @return true if try setup data connection is need for this reason
- */
- private boolean retryAfterDisconnected(ApnContext apnContext) {
- boolean retry = true;
- String reason = apnContext.getReason();
-
- if (Phone.REASON_RADIO_TURNED_OFF.equals(reason) || (isOnlySingleDcAllowed(getDataRat())
- && isHigherPriorityApnContextActive(apnContext))) {
- retry = false;
- }
- return retry;
- }
-
- 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) {
- log("startReconnect: delay=" + delay + ", apn="
- + apnContext + ", reason=" + apnContext.getReason()
- + ", subId=" + mPhone.getSubId() + ", request type="
- + requestTypeToString(requestType));
- }
- }
-
- /**
- * Cancels the alarm associated with apnContext.
- *
- * @param apnContext on which the alarm should be stopped.
- */
- protected void cancelReconnect(ApnContext apnContext) {
- if (apnContext == null) return;
-
- if (DBG) {
- log("cancelReconnect: apn=" + apnContext);
- }
- removeMessages(DctConstants.EVENT_DATA_RECONNECT, apnContext);
- }
-
- /**
- * Read configuration. Note this must be called after carrier config is ready.
- */
- private void readConfiguration() {
- log("readConfiguration");
- if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
- // Auto attach is for cellular only.
- mAutoAttachOnCreationConfig = mPhone.getContext().getResources()
- .getBoolean(com.android.internal.R.bool.config_auto_attach_data_on_creation);
- }
-
- mAutoAttachEnabled.set(false);
- setDefaultPreferredApnIfNeeded();
- read5GConfiguration();
- registerSettingsObserver();
- SubscriptionPlan[] plans = mNetworkPolicyManager.getSubscriptionPlans(
- mPhone.getSubId(), mPhone.getContext().getOpPackageName());
- mSubscriptionPlans = plans == null ? Collections.emptyList() : Arrays.asList(plans);
- if (DBG) log("SubscriptionPlans initialized: " + mSubscriptionPlans);
- reevaluateUnmeteredConnections();
- mConfigReady = true;
- }
-
- /**
- * @return {@code true} if carrier config has been applied.
- */
- private boolean isCarrierConfigApplied() {
- CarrierConfigManager configManager = (CarrierConfigManager) mPhone.getContext()
- .getSystemService(Context.CARRIER_CONFIG_SERVICE);
- if (configManager != null) {
- PersistableBundle b = configManager.getConfigForSubId(mPhone.getSubId());
- if (b != null) {
- return CarrierConfigManager.isConfigForIdentifiedCarrier(b);
- }
- }
- return false;
- }
-
- private void onCarrierConfigChanged() {
- if (DBG) log("onCarrierConfigChanged");
-
- if (!isCarrierConfigApplied()) {
- log("onCarrierConfigChanged: Carrier config is not ready yet.");
- return;
- }
-
- readConfiguration();
-
- if (mSimState == TelephonyManager.SIM_STATE_LOADED) {
- setDefaultDataRoamingEnabled();
- createAllApnList();
- setDataProfilesAsNeeded();
- setInitialAttachApn();
- sortApnContextByPriority();
- cleanUpConnectionsOnUpdatedApns(true, Phone.REASON_CARRIER_CHANGE);
- setupDataOnAllConnectableApns(Phone.REASON_CARRIER_CHANGE, RetryFailures.ALWAYS);
- } else {
- log("onCarrierConfigChanged: SIM is not loaded yet.");
- }
- }
-
- private void onSimAbsent() {
- if (DBG) log("onSimAbsent");
-
- mConfigReady = false;
- cleanUpAllConnectionsInternal(true, Phone.REASON_SIM_NOT_READY);
- mAllApnSettings.clear();
- mAutoAttachOnCreationConfig = false;
- // Clear auto attach as modem is expected to do a new attach once SIM is ready
- mAutoAttachEnabled.set(false);
- // In no-sim case, we should still send the emergency APN to the modem, if there is any.
- createAllApnList();
- setDataProfilesAsNeeded();
- }
-
- private void onSimStateUpdated(@SimState int simState) {
- mSimState = simState;
-
- if (DBG) {
- log("onSimStateUpdated: state=" + SubscriptionInfoUpdater.simStateString(mSimState));
- }
-
- if (mSimState == TelephonyManager.SIM_STATE_ABSENT) {
- onSimAbsent();
- } else if (mSimState == TelephonyManager.SIM_STATE_LOADED) {
- mDataThrottler.reset();
- if (mConfigReady) {
- createAllApnList();
- setDataProfilesAsNeeded();
- setInitialAttachApn();
- setupDataOnAllConnectableApns(Phone.REASON_SIM_LOADED, RetryFailures.ALWAYS);
- } else {
- log("onSimStateUpdated: config not ready yet.");
- }
- }
- }
-
- private void onApnUnthrottled(String apn) {
- if (apn != null) {
- ApnSetting apnSetting = mAllApnSettings.stream()
- .filter(as -> apn.equals(as.getApnName()))
- .findFirst()
- .orElse(null);
- if (apnSetting != null) {
- @ApnType int apnTypes = apnSetting.getApnTypeBitmask();
- mDataThrottler.setRetryTime(apnTypes, RetryManager.NO_SUGGESTED_RETRY_DELAY,
- REQUEST_TYPE_NORMAL);
- } else {
- loge("EVENT_APN_UNTHROTTLED: Invalid APN passed: " + apn);
- }
- } else {
- loge("EVENT_APN_UNTHROTTLED: apn is null");
- }
- }
-
- private void onTrafficDescriptorsUpdated() {
- for (ApnContext apnContext : mPrioritySortedApnContexts) {
- if (apnContext.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE
- && apnContext.getApnSetting().getPermanentFailed()) {
- setupDataOnConnectableApn(
- apnContext, Phone.REASON_TRAFFIC_DESCRIPTORS_UPDATED, RetryFailures.ALWAYS);
- }
- }
- }
-
- private DataConnection checkForCompatibleDataConnection(ApnContext apnContext,
- ApnSetting nextApn) {
- int apnType = apnContext.getApnTypeBitmask();
- ArrayList<ApnSetting> dunSettings = null;
-
- if (ApnSetting.TYPE_DUN == apnType) {
- dunSettings = fetchDunApns();
- }
- if (DBG) {
- log("checkForCompatibleDataConnection: apnContext=" + apnContext);
- }
-
- DataConnection potentialDc = null;
- for (DataConnection curDc : mDataConnections.values()) {
- if (curDc != null) {
- ApnSetting apnSetting = curDc.getApnSetting();
- log("apnSetting: " + apnSetting);
- if (dunSettings != null && dunSettings.size() > 0) {
- for (ApnSetting dunSetting : dunSettings) {
- //This ignore network type as a check which is ok because that's checked
- //when calculating dun candidates.
- if (areCompatible(dunSetting, apnSetting)) {
- if (curDc.isActive()) {
- if (DBG) {
- log("checkForCompatibleDataConnection:"
- + " found dun conn=" + curDc);
- }
- return curDc;
- } else if (curDc.isActivating()) {
- potentialDc = curDc;
- }
- }
- }
- } else if (isApnSettingCompatible(curDc, apnType)) {
- if (curDc.isActive()) {
- if (DBG) {
- log("checkForCompatibleDataConnection:"
- + " found canHandle conn=" + curDc);
- }
- return curDc;
- } else if (curDc.isActivating()
- || (apnSetting != null && apnSetting.equals(nextApn))) {
- potentialDc = curDc;
- }
- }
- }
- }
-
- if (DBG) {
- log("checkForCompatibleDataConnection: potential dc=" + potentialDc);
- }
- return potentialDc;
- }
-
- private boolean isApnSettingCompatible(DataConnection dc, int apnType) {
- ApnSetting apnSetting = dc.getApnSetting();
- if (apnSetting == null) return false;
-
- // Nothing can be compatible with type ENTERPRISE
- for (ApnContext apnContext : dc.getApnContexts()) {
- if (apnContext.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE) {
- return false;
- }
- }
-
- return apnSetting.canHandleType(apnType);
- }
-
- private void addHandoverCompleteMsg(Message onCompleteMsg,
- @ApnType int apnType) {
- if (onCompleteMsg != null) {
- List<Message> messageList = mHandoverCompletionMsgs.get(apnType);
- if (messageList == null) messageList = new ArrayList<>();
- messageList.add(onCompleteMsg);
- mHandoverCompletionMsgs.put(apnType, messageList);
- }
- }
-
- private void sendHandoverCompleteMessages(@ApnType int apnType, boolean success,
- boolean fallbackOnFailedHandover) {
- List<Message> messageList = mHandoverCompletionMsgs.get(apnType);
- if (messageList != null) {
- for (Message msg : messageList) {
- sendHandoverCompleteMsg(msg, success, mTransportType, fallbackOnFailedHandover);
- }
- messageList.clear();
- }
- }
-
- private void sendHandoverCompleteMsg(Message message, boolean success,
- @TransportType int transport, boolean doFallbackOnFailedHandover) {
- if (message == null) return;
-
- Bundle b = message.getData();
- b.putBoolean(DATA_COMPLETE_MSG_EXTRA_SUCCESS, success);
- b.putInt(DATA_COMPLETE_MSG_EXTRA_TRANSPORT_TYPE, transport);
- b.putBoolean(DATA_COMPLETE_MSG_EXTRA_HANDOVER_FAILURE_FALLBACK, doFallbackOnFailedHandover);
- message.sendToTarget();
- }
-
- private static boolean shouldFallbackOnFailedHandover(
- @HandoverFailureMode int handoverFailureMode,
- @RequestNetworkType int requestType,
- @DataFailureCause int cause) {
- if (requestType != REQUEST_TYPE_HANDOVER) {
- //The fallback is only relevant if the request is a handover
- return false;
- } else if (handoverFailureMode == HANDOVER_FAILURE_MODE_DO_FALLBACK) {
- return true;
- } else if (handoverFailureMode == HANDOVER_FAILURE_MODE_LEGACY) {
- return cause == DataFailCause.HANDOFF_PREFERENCE_CHANGED;
- } else {
- return false;
- }
- }
-
- /**
- * Calculates the new request type that will be used the next time a data connection retries
- * after a failed data call attempt.
- */
- @RequestNetworkType
- public static int calculateNewRetryRequestType(@HandoverFailureMode int handoverFailureMode,
- @RequestNetworkType int requestType,
- @DataFailureCause int cause) {
- boolean fallbackOnFailedHandover =
- shouldFallbackOnFailedHandover(handoverFailureMode, requestType, cause);
- if (requestType != REQUEST_TYPE_HANDOVER) {
- //The fallback is only relevant if the request is a handover
- return requestType;
- }
-
- if (fallbackOnFailedHandover) {
- // Since fallback is happening, the request type is really "NONE".
- return REQUEST_TYPE_NORMAL;
- }
-
- if (handoverFailureMode == HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL) {
- return REQUEST_TYPE_NORMAL;
- }
-
- return REQUEST_TYPE_HANDOVER;
- }
-
- public void enableApn(@ApnType int apnType, @RequestNetworkType int requestType,
- Message onHandoverCompleteMsg) {
- sendMessage(obtainMessage(DctConstants.EVENT_ENABLE_APN, apnType, requestType,
- onHandoverCompleteMsg));
- }
-
- private void onEnableApn(@ApnType int apnType, @RequestNetworkType int requestType,
- Message onHandoverCompleteMsg) {
- ApnContext apnContext = mApnContextsByType.get(apnType);
- if (apnContext == null) {
- loge("onEnableApn(" + apnType + "): NO ApnContext");
- if (onHandoverCompleteMsg != null) {
- sendHandoverCompleteMsg(onHandoverCompleteMsg, false, mTransportType, false);
- }
- return;
- }
-
- String str = "onEnableApn: apnType=" + ApnSetting.getApnTypeString(apnType)
- + ", request type=" + requestTypeToString(requestType);
- if (DBG) log(str);
- ApnContext.requestLog(apnContext, str);
-
- if (!apnContext.isDependencyMet()) {
- apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_UNMET);
- apnContext.setEnabled(true);
- str = "onEnableApn: dependency is not met.";
- if (DBG) log(str);
- ApnContext.requestLog(apnContext, str);
- if (onHandoverCompleteMsg != null) {
- sendHandoverCompleteMsg(onHandoverCompleteMsg, false, mTransportType, false);
- }
- return;
- }
-
- if (apnContext.isReady()) {
- DctConstants.State state = apnContext.getState();
- switch(state) {
- case CONNECTING:
- if (onHandoverCompleteMsg != null) {
- if (DBG) {
- log("onEnableApn: already in CONNECTING state. Handover request "
- + "will be responded after connected.");
- }
- addHandoverCompleteMsg(onHandoverCompleteMsg, apnType);
- } else {
- if (DBG) log("onEnableApn: in CONNECTING state. Exit now.");
- }
- return;
- case CONNECTED:
- if (onHandoverCompleteMsg != null) {
- sendHandoverCompleteMsg(onHandoverCompleteMsg, true, mTransportType,
- false);
- if (DBG) {
- log("onEnableApn: already in CONNECTED state. Consider as handover "
- + "succeeded");
- }
- } else {
- if (DBG) log("onEnableApn: APN in CONNECTED state. Exit now.");
- }
- return;
- case IDLE:
- case FAILED:
- case RETRYING:
- // We're "READY" but not active so disconnect (cleanup = true) and
- // connect (trySetup = true) to be sure we retry the connection.
- apnContext.setReason(Phone.REASON_DATA_ENABLED);
- break;
- }
- } else {
- if (apnContext.isEnabled()) {
- apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_MET);
- } else {
- apnContext.setReason(Phone.REASON_DATA_ENABLED);
- }
- if (apnContext.getState() == DctConstants.State.FAILED) {
- apnContext.setState(DctConstants.State.IDLE);
- }
- }
- apnContext.setEnabled(true);
- apnContext.resetErrorCodeRetries();
-
- if (mConfigReady || apnContext.getApnTypeBitmask() == ApnSetting.TYPE_EMERGENCY) {
- trySetupData(apnContext, requestType, onHandoverCompleteMsg);
- } else {
- log("onEnableApn: config not ready yet.");
- }
- }
-
- public void disableApn(@ApnType int apnType, @ReleaseNetworkType int releaseType) {
- sendMessage(obtainMessage(DctConstants.EVENT_DISABLE_APN, apnType, releaseType));
- }
-
- private void onDisableApn(@ApnType int apnType,
- @ReleaseNetworkType int releaseType) {
- ApnContext apnContext = mApnContextsByType.get(apnType);
- if (apnContext == null) {
- loge("disableApn(" + apnType + "): NO ApnContext");
- return;
- }
-
- boolean cleanup = false;
- String str = "onDisableApn: apnType=" + ApnSetting.getApnTypeString(apnType)
- + ", release type=" + releaseTypeToString(releaseType);
- if (DBG) log(str);
- ApnContext.requestLog(apnContext, str);
-
- if (apnContext.isReady()) {
- cleanup = (releaseType == RELEASE_TYPE_DETACH
- || releaseType == RELEASE_TYPE_HANDOVER);
- if (apnContext.isDependencyMet()) {
- apnContext.setReason(Phone.REASON_DATA_DISABLED_INTERNAL);
- // If ConnectivityService has disabled this network, stop trying to bring
- // it up, but do not tear it down - ConnectivityService will do that
- // directly by talking with the DataConnection.
- //
- // This doesn't apply to DUN. When the user disable tethering, we would like to
- // detach the APN context from the data connection so the data connection can be
- // torn down if no other APN context attached to it.
- if (ApnSetting.TYPE_DUN_STRING.equals(apnContext.getApnType())
- || apnContext.getState() != DctConstants.State.CONNECTED) {
- str = "Clean up the connection. Apn type = " + apnContext.getApnType()
- + ", state = " + apnContext.getState();
- if (DBG) log(str);
- ApnContext.requestLog(apnContext, str);
- cleanup = true;
- }
- } else {
- apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_UNMET);
- }
- }
-
- apnContext.setEnabled(false);
- if (cleanup) {
- cleanUpConnectionInternal(true, releaseType, apnContext);
- }
-
- if (isOnlySingleDcAllowed(getDataRat()) && !isHigherPriorityApnContextActive(apnContext)) {
- if (DBG) log("disableApn:isOnlySingleDcAllowed true & higher priority APN disabled");
- // If the highest priority APN is disabled and only single
- // data call is allowed, try to setup data call on other connectable APN.
- setupDataOnAllConnectableApns(Phone.REASON_SINGLE_PDN_ARBITRATION,
- RetryFailures.ALWAYS);
- }
- }
-
- /**
- * Modify {@link android.provider.Settings.Global#DATA_ROAMING} value for user modification only
- */
- public void setDataRoamingEnabledByUser(boolean enabled) {
- mDataEnabledSettings.setDataRoamingEnabled(enabled);
- setDataRoamingFromUserAction(true);
- if (DBG) {
- log("setDataRoamingEnabledByUser: set phoneSubId=" + mPhone.getSubId()
- + " isRoaming=" + enabled);
- }
- }
-
- /**
- * Return current {@link android.provider.Settings.Global#DATA_ROAMING} value.
- */
- public boolean getDataRoamingEnabled() {
- boolean isDataRoamingEnabled = mDataEnabledSettings.getDataRoamingEnabled();
-
- if (VDBG) {
- log("getDataRoamingEnabled: phoneSubId=" + mPhone.getSubId()
- + " isDataRoamingEnabled=" + isDataRoamingEnabled);
- }
- return isDataRoamingEnabled;
- }
-
- /**
- * Set default value for {@link android.provider.Settings.Global#DATA_ROAMING}
- * if the setting is not from user actions. default value is based on carrier config and system
- * properties.
- */
- private void setDefaultDataRoamingEnabled() {
- // For single SIM phones, this is a per phone property.
- String setting = Settings.Global.DATA_ROAMING;
- boolean useCarrierSpecificDefault = false;
- if (mTelephonyManager.getSimCount() != 1) {
- setting = setting + mPhone.getSubId();
- try {
- Settings.Global.getInt(mResolver, setting);
- } catch (SettingNotFoundException ex) {
- // For msim, update to carrier default if uninitialized.
- useCarrierSpecificDefault = true;
- }
- } else if (!isDataRoamingFromUserAction()) {
- // for single sim device, update to carrier default if user action is not set
- useCarrierSpecificDefault = true;
- }
- log("setDefaultDataRoamingEnabled: useCarrierSpecificDefault "
- + useCarrierSpecificDefault);
- if (useCarrierSpecificDefault) {
- boolean defaultVal = mDataEnabledSettings.getDefaultDataRoamingEnabled();
- mDataEnabledSettings.setDataRoamingEnabled(defaultVal);
- }
- }
-
- private boolean isDataRoamingFromUserAction() {
- final SharedPreferences sp = PreferenceManager
- .getDefaultSharedPreferences(mPhone.getContext());
- // since we don't want to unset user preference from system update, pass true as the default
- // value if shared pref does not exist and set shared pref to false explicitly from factory
- // reset.
- if (!sp.contains(Phone.DATA_ROAMING_IS_USER_SETTING_KEY)) {
- sp.edit().putBoolean(Phone.DATA_ROAMING_IS_USER_SETTING_KEY, false).commit();
- }
- return sp.getBoolean(Phone.DATA_ROAMING_IS_USER_SETTING_KEY, true);
- }
-
- private void setDataRoamingFromUserAction(boolean isUserAction) {
- final SharedPreferences.Editor sp = PreferenceManager
- .getDefaultSharedPreferences(mPhone.getContext()).edit();
- sp.putBoolean(Phone.DATA_ROAMING_IS_USER_SETTING_KEY, isUserAction).commit();
- }
-
- // When the data roaming status changes from roaming to non-roaming.
- private void onDataRoamingOff() {
- if (DBG) log("onDataRoamingOff");
-
- reevaluateDataConnections();
-
- if (!getDataRoamingEnabled()) {
- // TODO: Remove this once all old vendor RILs are gone. We don't need to set initial apn
- // attach and send the data profile again as the modem should have both roaming and
- // non-roaming protocol in place. Modem should choose the right protocol based on the
- // roaming condition.
- setDataProfilesAsNeeded();
- setInitialAttachApn();
-
- // If the user did not enable data roaming, now when we transit from roaming to
- // non-roaming, we should try to reestablish the data connection.
-
- setupDataOnAllConnectableApns(Phone.REASON_ROAMING_OFF, RetryFailures.ALWAYS);
- }
- }
-
- // This method is called
- // 1. When the data roaming status changes from non-roaming to roaming.
- // 2. When allowed data roaming settings is changed by the user.
- private void onDataRoamingOnOrSettingsChanged(int messageType) {
- if (DBG) log("onDataRoamingOnOrSettingsChanged");
- // Used to differentiate data roaming turned on vs settings changed.
- boolean settingChanged = (messageType == DctConstants.EVENT_ROAMING_SETTING_CHANGE);
-
- // Check if the device is actually data roaming
- if (!mPhone.getServiceState().getDataRoaming()) {
- if (DBG) log("device is not roaming. ignored the request.");
- return;
- }
-
- checkDataRoamingStatus(settingChanged);
-
- if (getDataRoamingEnabled()) {
- // If the restricted data was brought up when data roaming is disabled, and now users
- // enable data roaming, we need to re-evaluate the conditions and possibly change the
- // network's capability.
- if (settingChanged) {
- reevaluateDataConnections();
- }
-
- if (DBG) log("onDataRoamingOnOrSettingsChanged: setup data on roaming");
-
- setupDataOnAllConnectableApns(Phone.REASON_ROAMING_ON, RetryFailures.ALWAYS);
- } else {
- // If the user does not turn on data roaming, when we transit from non-roaming to
- // roaming, we need to tear down the data connection otherwise the user might be
- // charged for data roaming usage.
- if (DBG) log("onDataRoamingOnOrSettingsChanged: Tear down data connection on roaming.");
- cleanUpAllConnectionsInternal(true, Phone.REASON_ROAMING_ON);
- }
- }
-
- // We want to track possible roaming data leakage. Which is, if roaming setting
- // is disabled, yet we still setup a roaming data connection or have a connected ApnContext
- // switched to roaming. When this happens, we log it in a local log.
- private void checkDataRoamingStatus(boolean settingChanged) {
- if (!settingChanged && !getDataRoamingEnabled()
- && mPhone.getServiceState().getDataRoaming()) {
- for (ApnContext apnContext : mApnContexts.values()) {
- if (apnContext.getState() == DctConstants.State.CONNECTED) {
- mDataRoamingLeakageLog.log("PossibleRoamingLeakage "
- + " connection params: " + (apnContext.getDataConnection() != null
- ? apnContext.getDataConnection().getConnectionParams() : ""));
- }
- }
- }
- }
-
- private void onRadioAvailable() {
- if (DBG) log("onRadioAvailable");
- if (!areAllDataDisconnected()) {
- cleanUpConnectionInternal(true, RELEASE_TYPE_DETACH, null);
- }
- }
-
- private void onRadioOffOrNotAvailable() {
- // Make sure our reconnect delay starts at the initial value
- // next time the radio comes on
-
- mReregisterOnReconnectFailure = false;
-
- // Clear auto attach as modem is expected to do a new attach
- mAutoAttachEnabled.set(false);
-
- if (mPhone.getSimulatedRadioControl() != null) {
- // Assume data is connected on the simulator
- // FIXME this can be improved
- log("We're on the simulator; assuming radio off is meaningless");
- } else {
- if (DBG) log("onRadioOffOrNotAvailable: is off and clean up all connections");
- cleanUpAllConnectionsInternal(false, Phone.REASON_RADIO_TURNED_OFF);
- }
- }
-
- private void completeConnection(ApnContext apnContext, @RequestNetworkType int type) {
-
- if (DBG) log("completeConnection: successful, notify the world apnContext=" + apnContext);
-
- if (mIsProvisioning && !TextUtils.isEmpty(mProvisioningUrl)) {
- if (DBG) {
- log("completeConnection: MOBILE_PROVISIONING_ACTION url="
- + mProvisioningUrl);
- }
- Intent newIntent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN,
- Intent.CATEGORY_APP_BROWSER);
- newIntent.setData(Uri.parse(mProvisioningUrl));
- newIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
- Intent.FLAG_ACTIVITY_NEW_TASK);
- try {
- mPhone.getContext().startActivity(newIntent);
- } catch (ActivityNotFoundException e) {
- loge("completeConnection: startActivityAsUser failed" + e);
- }
- }
- mIsProvisioning = false;
- mProvisioningUrl = null;
- if (mProvisioningSpinner != null) {
- sendMessage(obtainMessage(DctConstants.CMD_CLEAR_PROVISIONING_SPINNER,
- mProvisioningSpinner));
- }
-
- 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);
- }
- }
-
- /**
- * A SETUP (aka bringUp) has completed, possibly with an error. If
- * there is an error this method will call {@link #onDataSetupCompleteError}.
- */
- protected void onDataSetupComplete(ApnContext apnContext, boolean success,
- @DataFailureCause int cause, @RequestNetworkType int requestType,
- @HandoverFailureMode int handoverFailureMode) {
- boolean fallbackOnFailedHandover = shouldFallbackOnFailedHandover(
- handoverFailureMode, requestType, cause);
-
- if (success && (handoverFailureMode != DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN
- && handoverFailureMode != DataCallResponse.HANDOVER_FAILURE_MODE_LEGACY)) {
- Log.wtf(mLogTag, "bad failure mode: "
- + DataCallResponse.failureModeToString(handoverFailureMode));
- } else if (handoverFailureMode
- != DataCallResponse.HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_HANDOVER
- && cause != DataFailCause.SERVICE_TEMPORARILY_UNAVAILABLE) {
- sendHandoverCompleteMessages(apnContext.getApnTypeBitmask(), success,
- fallbackOnFailedHandover);
- }
-
- if (success) {
- DataConnection dataConnection = apnContext.getDataConnection();
-
- if (RADIO_TESTS) {
- // Note: To change radio.test.onDSC.null.dcac from command line you need to
- // adb root and adb remount and from the command line you can only change the
- // value to 1 once. To change it a second time you can reboot or execute
- // adb shell stop and then adb shell start. The command line to set the value is:
- // adb shell sqlite3 /data/data/com.android.providers.settings/databases/settings.db "insert into system (name,value) values ('radio.test.onDSC.null.dcac', '1');"
- ContentResolver cr = mPhone.getContext().getContentResolver();
- String radioTestProperty = "radio.test.onDSC.null.dcac";
- if (Settings.System.getInt(cr, radioTestProperty, 0) == 1) {
- log("onDataSetupComplete: " + radioTestProperty +
- " is true, set dcac to null and reset property to false");
- dataConnection = null;
- Settings.System.putInt(cr, radioTestProperty, 0);
- log("onDataSetupComplete: " + radioTestProperty + "=" +
- Settings.System.getInt(mPhone.getContext().getContentResolver(),
- radioTestProperty, -1));
- }
- }
- if (dataConnection == null) {
- log("onDataSetupComplete: no connection to DC, handle as error");
- onDataSetupCompleteError(apnContext, requestType, false);
- } else {
- ApnSetting apn = apnContext.getApnSetting();
- if (DBG) {
- log("onDataSetupComplete: success apn=" + (apn == null ? "unknown"
- : apn.getApnName()));
- }
-
- // everything is setup
- if (TextUtils.equals(apnContext.getApnType(), ApnSetting.TYPE_DEFAULT_STRING)
- && mCanSetPreferApn && mPreferredApn == null) {
- if (DBG) log("onDataSetupComplete: PREFERRED APN is null");
- mPreferredApn = apn;
- if (mPreferredApn != null) {
- setPreferredApn(mPreferredApn.getId());
- }
- }
-
- // A connection is setup
- apnContext.setState(DctConstants.State.CONNECTED);
-
- checkDataRoamingStatus(false);
-
- boolean isProvApn = apnContext.isProvisioningApn();
- final ConnectivityManager cm = (ConnectivityManager) mPhone.getContext()
- .getSystemService(Context.CONNECTIVITY_SERVICE);
- if (mProvisionBroadcastReceiver != null) {
- mPhone.getContext().unregisterReceiver(mProvisionBroadcastReceiver);
- mProvisionBroadcastReceiver = null;
- }
-
- if ((!isProvApn) || mIsProvisioning) {
- 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.
- completeConnection(apnContext, requestType);
- } else {
- // This is a provisioning APN that we're reporting as connected. Later
- // when the user desires to upgrade this to a "default" connection,
- // mIsProvisioning == true, we'll go through the code path above.
- // mIsProvisioning becomes true when CMD_ENABLE_MOBILE_PROVISIONING
- // is sent to the DCT.
- if (DBG) {
- log("onDataSetupComplete: successful, BUT send connected to prov apn as"
- + " mIsProvisioning:" + mIsProvisioning + " == false"
- + " && (isProvisioningApn:" + isProvApn + " == true");
- }
-
- // While radio is up, grab provisioning URL. The URL contains ICCID which
- // disappears when radio is off.
- mProvisionBroadcastReceiver = new ProvisionNotificationBroadcastReceiver(
- mPhone.getMobileProvisioningUrl(),
- mTelephonyManager.getNetworkOperatorName());
- mPhone.getContext().registerReceiver(mProvisionBroadcastReceiver,
- new IntentFilter(INTENT_PROVISION));
-
- // Put up user notification that sign-in is required.
- 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);
- }
- if (DBG) {
- log("onDataSetupComplete: SETUP complete type=" + apnContext.getApnType());
- }
- if (TelephonyUtils.IS_DEBUGGABLE) {
- // adb shell setprop persist.radio.test.pco [pco_val]
- String radioTestProperty = "persist.radio.test.pco";
- int pcoVal = SystemProperties.getInt(radioTestProperty, -1);
- if (pcoVal != -1) {
- log("PCO testing: read pco value from persist.radio.test.pco " + pcoVal);
- final byte[] value = new byte[1];
- value[0] = (byte) pcoVal;
- final Intent intent =
- new Intent(TelephonyManager.ACTION_CARRIER_SIGNAL_PCO_VALUE);
- intent.putExtra(TelephonyManager.EXTRA_APN_TYPE, ApnSetting.TYPE_DEFAULT);
- intent.putExtra(TelephonyManager.EXTRA_APN_PROTOCOL,
- ApnSetting.PROTOCOL_IPV4V6);
- intent.putExtra(TelephonyManager.EXTRA_PCO_ID, 0xFF00);
- intent.putExtra(TelephonyManager.EXTRA_PCO_VALUE, value);
- mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
- }
- }
- }
- } else {
- if (DBG) {
- ApnSetting apn = apnContext.getApnSetting();
- log("onDataSetupComplete: error apn=" + apn.getApnName() + ", cause="
- + DataFailCause.toString(cause) + ", requestType="
- + requestTypeToString(requestType));
- }
- if (DataFailCause.isEventLoggable(cause)) {
- // Log this failure to the Event Logs.
- int cid = getCellLocationId();
- EventLog.writeEvent(EventLogTags.PDP_SETUP_FAIL,
- cause, cid, mTelephonyManager.getNetworkType());
- }
- ApnSetting apn = apnContext.getApnSetting();
-
- // Compose broadcast intent send to the specific carrier signaling receivers
- Intent intent = new Intent(TelephonyManager
- .ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED);
- intent.putExtra(TelephonyManager.EXTRA_DATA_FAIL_CAUSE, cause);
- intent.putExtra(TelephonyManager.EXTRA_APN_TYPE,
- ApnSetting.getApnTypesBitmaskFromString(apnContext.getApnType()));
- mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
-
- if (DataFailCause.isRadioRestartFailure(mPhone.getContext(), cause, mPhone.getSubId())
- || apnContext.restartOnError(cause)) {
- if (DBG) log("Modem restarted.");
- sendRestartRadio();
- }
-
- // If the data call failure cause is a permanent failure, we mark the APN as permanent
- // failed.
- if (isPermanentFailure(cause)) {
- 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,
- cause);
- onDataSetupCompleteError(apnContext, newRequestType, fallbackOnFailedHandover);
- }
- }
-
-
-
- /**
- * Error has occurred during the SETUP {aka bringUP} request and the DCT
- * should either try the next waiting APN or start over from the
- * beginning if the list is empty. Between each SETUP request there will
- * be a delay defined by {@link ApnContext#getDelayForNextApn(boolean)}.
- */
- protected void onDataSetupCompleteError(ApnContext apnContext,
- @RequestNetworkType int requestType, boolean fallbackOnFailedHandover) {
- long delay = apnContext.getDelayForNextApn(mFailFast);
- // Check if we need to retry or not.
- if (delay >= 0 && delay != RetryManager.NO_RETRY && !fallbackOnFailedHandover) {
- if (DBG) {
- log("onDataSetupCompleteError: APN type=" + apnContext.getApnType()
- + ". Request type=" + requestTypeToString(requestType) + ", Retry in "
- + delay + "ms.");
- }
- startReconnect(delay, apnContext, requestType);
- } else {
- // If we are not going to retry any APN, set this APN context to failed state.
- // This would be the final state of a data connection.
- apnContext.setState(DctConstants.State.FAILED);
- apnContext.setDataConnection(null);
- log("onDataSetupCompleteError: Stop retrying APNs. delay=" + delay
- + ", requestType=" + requestTypeToString(requestType));
- //send request network complete messages as needed
- sendHandoverCompleteMessages(apnContext.getApnTypeBitmask(), false,
- fallbackOnFailedHandover);
- }
- }
-
- /**
- * Called when EVENT_NETWORK_STATUS_CHANGED is received.
- *
- * @param status One of {@code NetworkAgent.VALID_NETWORK} or
- * {@code NetworkAgent.INVALID_NETWORK}.
- * @param cid context id {@code cid}
- * @param redirectUrl If the Internet probe was redirected, this
- * is the destination it was redirected to, otherwise {@code null}
- */
- private void onNetworkStatusChanged(int status, int cid, String redirectUrl) {
- if (!TextUtils.isEmpty(redirectUrl)) {
- Intent intent = new Intent(TelephonyManager.ACTION_CARRIER_SIGNAL_REDIRECTED);
- intent.putExtra(TelephonyManager.EXTRA_REDIRECTION_URL, redirectUrl);
- mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
- log("Notify carrier signal receivers with redirectUrl: " + redirectUrl);
- } else {
- final boolean isValid = status == NetworkAgent.VALIDATION_STATUS_VALID;
- final DataConnection dc = getDataConnectionByContextId(cid);
- if (!mDsRecoveryHandler.isRecoveryOnBadNetworkEnabled()) {
- if (DBG) log("Skip data stall recovery on network status change with in threshold");
- return;
- }
- if (mTransportType != AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
- if (DBG) log("Skip data stall recovery on non WWAN");
- return;
- }
- if (dc != null && dc.isValidationRequired()) {
- mDsRecoveryHandler.processNetworkStatusChanged(isValid);
- }
- }
- }
-
- /**
- * Called when EVENT_DISCONNECT_DONE is received.
- */
- private void onDisconnectDone(ApnContext apnContext) {
- if(DBG) log("onDisconnectDone: EVENT_DISCONNECT_DONE apnContext=" + apnContext);
- apnContext.setState(DctConstants.State.IDLE);
- // If all data connection are gone, check whether Airplane mode request was pending.
- if (areAllDataDisconnected()
- && mPhone.getServiceStateTracker().processPendingRadioPowerOffAfterDataOff()) {
- if (DBG) log("onDisconnectDone: radio will be turned off, no retries");
- // Radio will be turned off. No need to retry data setup
- apnContext.setApnSetting(null);
- apnContext.setDataConnection(null);
-
- // Need to notify disconnect as well, in the case of switching Airplane mode.
- // Otherwise, it would cause 30s delayed to turn on Airplane mode.
- notifyAllDataDisconnected();
- return;
- }
- // If APN is still enabled, try to bring it back up automatically
- if (mAttached.get() && apnContext.isReady() && retryAfterDisconnected(apnContext)) {
- // Wait a bit before trying the next APN, so that
- // we're not tying up the RIL command channel.
- // This also helps in any external dependency to turn off the context.
- if (DBG) log("onDisconnectDone: attached, ready and retry after disconnect");
-
- // See if there are still handover request pending that we need to retry handover
- // after previous data gets disconnected.
- if (isHandoverPending(apnContext.getApnTypeBitmask())) {
- if (DBG) log("Handover request pending. Retry handover immediately.");
- startReconnect(0, apnContext, REQUEST_TYPE_HANDOVER);
- } else {
- long delay = apnContext.getRetryAfterDisconnectDelay();
- if (delay > 0) {
- // Data connection is in IDLE state, so when we reconnect later, we'll rebuild
- // the waiting APN list, which will also reset/reconfigure the retry manager.
- startReconnect(delay, apnContext, REQUEST_TYPE_NORMAL);
- }
- }
- } else {
- boolean restartRadioAfterProvisioning = mPhone.getContext().getResources().getBoolean(
- com.android.internal.R.bool.config_restartRadioAfterProvisioning);
-
- if (apnContext.isProvisioningApn() && restartRadioAfterProvisioning) {
- log("onDisconnectDone: restartRadio after provisioning");
- restartRadio();
- }
- apnContext.setApnSetting(null);
- apnContext.setDataConnection(null);
- if (isOnlySingleDcAllowed(getDataRat())) {
- if(DBG) log("onDisconnectDone: isOnlySigneDcAllowed true so setup single apn");
- setupDataOnAllConnectableApns(Phone.REASON_SINGLE_PDN_ARBITRATION,
- RetryFailures.ALWAYS);
- } else {
- if(DBG) log("onDisconnectDone: not retrying");
- }
- }
-
- if (areAllDataDisconnected()) {
- apnContext.setConcurrentVoiceAndDataAllowed(
- mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed());
- notifyAllDataDisconnected();
- }
-
- }
-
- private void onVoiceCallStarted() {
- if (DBG) log("onVoiceCallStarted");
- mInVoiceCall = true;
- if (isAnyDataConnected()
- && !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
- if (DBG) log("onVoiceCallStarted stop polling");
- stopNetStatPoll();
- stopDataStallAlarm();
- }
- }
-
- protected void onVoiceCallEnded() {
- if (DBG) log("onVoiceCallEnded");
- mInVoiceCall = false;
- if (isAnyDataConnected()) {
- if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
- startNetStatPoll();
- startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
- } else {
- // clean slate after call end.
- resetPollStats();
- }
- }
- // reset reconnect timer
- setupDataOnAllConnectableApns(Phone.REASON_VOICE_CALL_ENDED, RetryFailures.ALWAYS);
- }
- /**
- * @return {@code true} if there is any data in connected state.
- */
- @VisibleForTesting
- public boolean isAnyDataConnected() {
- for (DataConnection dc : mDataConnections.values()) {
- if (dc.isActive()) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * @return {@code true} if all data connections are in disconnected state.
- */
- public boolean areAllDataDisconnected() {
- for (DataConnection dc : mDataConnections.values()) {
- if (!dc.isInactive()) {
- if (DBG) log("areAllDataDisconnected false due to DC: " + dc.getName());
- return false;
- }
- }
- return true;
- }
-
- protected void setDataProfilesAsNeeded() {
- if (DBG) log("setDataProfilesAsNeeded");
-
- ArrayList<DataProfile> dataProfileList = new ArrayList<>();
-
- int preferredApnSetId = getPreferredApnSetId();
- for (ApnSetting apn : mAllApnSettings) {
- if (apn.getApnSetId() == Telephony.Carriers.MATCH_ALL_APN_SET_ID
- || preferredApnSetId == apn.getApnSetId()) {
- DataProfile dp = new DataProfile.Builder()
- .setApnSetting(apn)
- .setPreferred(apn.equals(getPreferredApn()))
- .build();
- if (!dataProfileList.contains(dp)) {
- dataProfileList.add(dp);
- }
- } else {
- if (VDBG) {
- log("setDataProfilesAsNeeded: APN set id " + apn.getApnSetId()
- + " does not match the preferred set id " + preferredApnSetId);
- }
- }
- }
-
- // Check if the data profiles we are sending are same as we did last time. We don't want to
- // send the redundant profiles to the modem. Also if there the list is empty, we don't
- // send it to the modem.
- if (!dataProfileList.isEmpty()
- && (dataProfileList.size() != mLastDataProfileList.size()
- || !mLastDataProfileList.containsAll(dataProfileList))) {
- mDataServiceManager.setDataProfile(dataProfileList,
- mPhone.getServiceState().getDataRoamingFromRegistration(), null);
- }
- }
-
- /**
- * Based on the sim operator numeric, create a list for all possible
- * Data Connections and setup the preferredApn.
- */
- protected void createAllApnList() {
- mAllApnSettings.clear();
- String operator = mPhone.getOperatorNumeric();
-
- // ORDER BY Telephony.Carriers._ID ("_id")
- Cursor cursor = mPhone.getContext().getContentResolver().query(
- Uri.withAppendedPath(Telephony.Carriers.SIM_APN_URI, "filtered/subId/"
- + mPhone.getSubId()), null, null, null, Telephony.Carriers._ID);
-
- if (cursor != null) {
- while (cursor.moveToNext()) {
- ApnSetting apn = ApnSetting.makeApnSetting(cursor);
- if (apn == null) {
- continue;
- }
- mAllApnSettings.add(apn);
- }
- cursor.close();
- } else {
- if (DBG) log("createAllApnList: cursor is null");
- mApnSettingsInitializationLog.log("cursor is null for carrier, operator: "
- + operator);
- }
-
- dedupeApnSettings();
-
- if (mAllApnSettings.isEmpty()) {
- log("createAllApnList: No APN found for carrier, operator: " + operator);
- mApnSettingsInitializationLog.log("no APN found for carrier, operator: "
- + operator);
- mPreferredApn = null;
- } else {
- mPreferredApn = getPreferredApn();
- if (DBG) log("createAllApnList: mPreferredApn=" + mPreferredApn);
- }
-
- addDefaultApnSettingsAsNeeded();
- if (DBG) log("createAllApnList: X mAllApnSettings=" + mAllApnSettings);
- }
-
- private void dedupeApnSettings() {
- ArrayList<ApnSetting> resultApns = new ArrayList<ApnSetting>();
-
- // coalesce APNs if they are similar enough to prevent
- // us from bringing up two data calls with the same interface
- int i = 0;
- while (i < mAllApnSettings.size() - 1) {
- ApnSetting first = mAllApnSettings.get(i);
- ApnSetting second = null;
- int j = i + 1;
- while (j < mAllApnSettings.size()) {
- second = mAllApnSettings.get(j);
- if (first.similar(second)) {
- ApnSetting newApn = mergeApns(first, second);
- mAllApnSettings.set(i, newApn);
- first = newApn;
- mAllApnSettings.remove(j);
- } else {
- j++;
- }
- }
- i++;
- }
- }
-
- private ApnSetting mergeApns(ApnSetting dest, ApnSetting src) {
- int id = dest.getId();
- if ((src.getApnTypeBitmask() & ApnSetting.TYPE_DEFAULT) == ApnSetting.TYPE_DEFAULT) {
- id = src.getId();
- }
- final int resultApnType = src.getApnTypeBitmask() | dest.getApnTypeBitmask();
- Uri mmsc = (dest.getMmsc() == null ? src.getMmsc() : dest.getMmsc());
- String mmsProxy = TextUtils.isEmpty(dest.getMmsProxyAddressAsString())
- ? src.getMmsProxyAddressAsString() : dest.getMmsProxyAddressAsString();
- int mmsPort = dest.getMmsProxyPort() == -1 ? src.getMmsProxyPort() : dest.getMmsProxyPort();
- String proxy = TextUtils.isEmpty(dest.getProxyAddressAsString())
- ? src.getProxyAddressAsString() : dest.getProxyAddressAsString();
- int port = dest.getProxyPort() == -1 ? src.getProxyPort() : dest.getProxyPort();
- int protocol = src.getProtocol() == ApnSetting.PROTOCOL_IPV4V6 ? src.getProtocol()
- : dest.getProtocol();
- int roamingProtocol = src.getRoamingProtocol() == ApnSetting.PROTOCOL_IPV4V6
- ? src.getRoamingProtocol() : dest.getRoamingProtocol();
- int networkTypeBitmask = (dest.getNetworkTypeBitmask() == 0
- || src.getNetworkTypeBitmask() == 0)
- ? 0 : (dest.getNetworkTypeBitmask() | src.getNetworkTypeBitmask());
- return new ApnSetting.Builder()
- .setId(id)
- .setOperatorNumeric(dest.getOperatorNumeric())
- .setEntryName(dest.getEntryName())
- .setApnName(dest.getApnName())
- .setProxyAddress(proxy)
- .setProxyPort(port)
- .setMmsc(mmsc)
- .setMmsProxyAddress(mmsProxy)
- .setMmsProxyPort(mmsPort)
- .setUser(dest.getUser())
- .setPassword(dest.getPassword())
- .setAuthType(dest.getAuthType())
- .setApnTypeBitmask(resultApnType)
- .setProtocol(protocol)
- .setRoamingProtocol(roamingProtocol)
- .setCarrierEnabled(dest.isEnabled())
- .setNetworkTypeBitmask(networkTypeBitmask)
- .setProfileId(dest.getProfileId())
- .setModemCognitive(dest.isPersistent() || src.isPersistent())
- .setMaxConns(dest.getMaxConns())
- .setWaitTime(dest.getWaitTime())
- .setMaxConnsTime(dest.getMaxConnsTime())
- .setMtuV4(dest.getMtuV4())
- .setMtuV6(dest.getMtuV6())
- .setMvnoType(dest.getMvnoType())
- .setMvnoMatchData(dest.getMvnoMatchData())
- .setApnSetId(dest.getApnSetId())
- .setCarrierId(dest.getCarrierId())
- .setSkip464Xlat(dest.getSkip464Xlat())
- .build();
- }
-
- private DataConnection createDataConnection() {
- if (DBG) log("createDataConnection E");
-
- int id = mUniqueIdGenerator.getAndIncrement();
- DataConnection dataConnection = DataConnection.makeDataConnection(mPhone, id, this,
- mDataServiceManager, mDcTesterFailBringUpAll, mDcc);
- mDataConnections.put(id, dataConnection);
- if (DBG) log("createDataConnection() X id=" + id + " dc=" + dataConnection);
- return dataConnection;
- }
-
- private void destroyDataConnections() {
- if(mDataConnections != null) {
- if (DBG) log("destroyDataConnections: clear mDataConnectionList");
- mDataConnections.clear();
- } else {
- if (DBG) log("destroyDataConnections: mDataConnecitonList is empty, ignore");
- }
- }
-
- /**
- * Build a list of APNs to be used to create PDP's.
- *
- * @param requestedApnType
- * @return waitingApns list to be used to create PDP
- * error when waitingApns.isEmpty()
- */
- private @NonNull ArrayList<ApnSetting> buildWaitingApns(String requestedApnType,
- int radioTech) {
- if (DBG) log("buildWaitingApns: E requestedApnType=" + requestedApnType);
- ArrayList<ApnSetting> apnList = new ArrayList<ApnSetting>();
-
- int requestedApnTypeBitmask = ApnSetting.getApnTypesBitmaskFromString(requestedApnType);
- if (requestedApnTypeBitmask == ApnSetting.TYPE_ENTERPRISE) {
- requestedApnTypeBitmask = ApnSetting.TYPE_DEFAULT;
- }
- if (requestedApnTypeBitmask == ApnSetting.TYPE_DUN) {
- ArrayList<ApnSetting> dunApns = fetchDunApns();
- if (dunApns.size() > 0) {
- for (ApnSetting dun : dunApns) {
- apnList.add(dun);
- if (DBG) log("buildWaitingApns: X added APN_TYPE_DUN apnList=" + apnList);
- }
- return apnList;
- }
- }
-
- String operator = mPhone.getOperatorNumeric();
-
- // This is a workaround for a bug (7305641) where we don't failover to other
- // suitable APNs if our preferred APN fails. On prepaid ATT sims we need to
- // failover to a provisioning APN, but once we've used their default data
- // connection we are locked to it for life. This change allows ATT devices
- // to say they don't want to use preferred at all.
- boolean usePreferred = true;
- try {
- usePreferred = !mPhone.getContext().getResources().getBoolean(com.android
- .internal.R.bool.config_dontPreferApn);
- } catch (Resources.NotFoundException e) {
- if (DBG) log("buildWaitingApns: usePreferred NotFoundException set to true");
- usePreferred = true;
- }
- if (usePreferred) {
- mPreferredApn = getPreferredApn();
- }
- if (DBG) {
- log("buildWaitingApns: usePreferred=" + usePreferred
- + " canSetPreferApn=" + mCanSetPreferApn
- + " mPreferredApn=" + mPreferredApn
- + " operator=" + operator + " radioTech=" + radioTech);
- }
-
- if (usePreferred && mCanSetPreferApn && mPreferredApn != null &&
- mPreferredApn.canHandleType(requestedApnTypeBitmask)) {
- if (DBG) {
- log("buildWaitingApns: Preferred APN:" + operator + ":"
- + mPreferredApn.getOperatorNumeric() + ":" + mPreferredApn);
- }
-
- if (TextUtils.equals(mPreferredApn.getOperatorNumeric(), operator)
- || mPreferredApn.getCarrierId() == mPhone.getCarrierId()) {
- if (mPreferredApn.canSupportNetworkType(
- ServiceState.rilRadioTechnologyToNetworkType(radioTech))) {
- // Create a new instance of ApnSetting for ENTERPRISE because each
- // DataConnection should have its own ApnSetting. ENTERPRISE uses the same
- // APN as DEFAULT but is a separate DataConnection
- if (ApnSetting.getApnTypesBitmaskFromString(requestedApnType)
- == ApnSetting.TYPE_ENTERPRISE) {
- apnList.add(ApnSetting.makeApnSetting(mPreferredApn));
- } else {
- apnList.add(mPreferredApn);
- }
- if (DBG) log("buildWaitingApns: X added preferred apnList=" + apnList);
- return apnList;
- }
- }
- if (DBG) log("buildWaitingApns: no preferred APN");
- setPreferredApn(-1);
- mPreferredApn = null;
- }
-
- if (DBG) log("buildWaitingApns: mAllApnSettings=" + mAllApnSettings);
- int preferredApnSetId = getPreferredApnSetId();
- for (ApnSetting apn : mAllApnSettings) {
- if (apn.canHandleType(requestedApnTypeBitmask)) {
- if (apn.canSupportNetworkType(
- ServiceState.rilRadioTechnologyToNetworkType(radioTech))) {
- if (apn.getApnSetId() == Telephony.Carriers.MATCH_ALL_APN_SET_ID
- || preferredApnSetId == apn.getApnSetId()) {
- if (VDBG) log("buildWaitingApns: adding apn=" + apn);
- // Create a new instance of ApnSetting for ENTERPRISE because each
- // DataConnection should have its own ApnSetting. ENTERPRISE uses the same
- // APN as DEFAULT but is a separate DataConnection
- if (ApnSetting.getApnTypesBitmaskFromString(requestedApnType)
- == ApnSetting.TYPE_ENTERPRISE) {
- apnList.add(ApnSetting.makeApnSetting(apn));
- } else {
- apnList.add(apn);
- }
- } else {
- log("buildWaitingApns: APN set id " + apn.getApnSetId()
- + " does not match the preferred set id " + preferredApnSetId);
- }
- } else {
- if (DBG) {
- log("buildWaitingApns: networkTypeBitmask:"
- + apn.getNetworkTypeBitmask()
- + " does not include radioTech:"
- + ServiceState.rilRadioTechnologyToString(radioTech));
- }
- }
- } else if (VDBG) {
- log("buildWaitingApns: couldn't handle requested ApnType="
- + requestedApnType);
- }
- }
-
- if (DBG) log("buildWaitingApns: " + apnList.size() + " APNs in the list: " + apnList);
- return apnList;
- }
-
- private String apnListToString (ArrayList<ApnSetting> apns) {
- StringBuilder result = new StringBuilder();
- for (int i = 0, size = apns.size(); i < size; i++) {
- result.append('[')
- .append(apns.get(i).toString())
- .append(']');
- }
- return result.toString();
- }
-
- private void setPreferredApn(int pos) {
- setPreferredApn(pos, false);
- }
-
- private void setPreferredApn(int pos, boolean force) {
- if (!force && !mCanSetPreferApn) {
- log("setPreferredApn: X !canSEtPreferApn");
- return;
- }
-
- String subId = Long.toString(mPhone.getSubId());
- Uri uri = Uri.withAppendedPath(PREFERAPN_NO_UPDATE_URI_USING_SUBID, subId);
- log("setPreferredApn: delete");
- ContentResolver resolver = mPhone.getContext().getContentResolver();
- resolver.delete(uri, null, null);
-
- if (pos >= 0) {
- log("setPreferredApn: insert");
- ContentValues values = new ContentValues();
- values.put(APN_ID, pos);
- resolver.insert(uri, values);
- }
- }
-
- @Nullable
- ApnSetting getPreferredApn() {
- //Only call this method from main thread
- if (mAllApnSettings == null || mAllApnSettings.isEmpty()) {
- log("getPreferredApn: mAllApnSettings is empty");
- return null;
- }
-
- String subId = Long.toString(mPhone.getSubId());
- Uri uri = Uri.withAppendedPath(PREFERAPN_NO_UPDATE_URI_USING_SUBID, subId);
- Cursor cursor = mPhone.getContext().getContentResolver().query(
- uri, new String[] { "_id", "name", "apn" },
- null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
-
- if (cursor != null) {
- mCanSetPreferApn = true;
- } else {
- mCanSetPreferApn = false;
- }
-
- if (VDBG) {
- log("getPreferredApn: mRequestedApnType=" + mRequestedApnType + " cursor=" + cursor
- + " cursor.count=" + ((cursor != null) ? cursor.getCount() : 0));
- }
-
- if (mCanSetPreferApn && cursor.getCount() > 0) {
- int pos;
- cursor.moveToFirst();
- pos = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID));
- for(ApnSetting p : mAllApnSettings) {
- if (p.getId() == pos && p.canHandleType(mRequestedApnType)) {
- log("getPreferredApn: For APN type "
- + ApnSetting.getApnTypeString(mRequestedApnType)
- + " found apnSetting " + p);
- cursor.close();
- return p;
- }
- }
- }
-
- if (cursor != null) {
- cursor.close();
- }
-
- log("getPreferredApn: X not found");
- return null;
- }
-
- @Override
- public void handleMessage (Message msg) {
- if (VDBG) log("handleMessage msg=" + msg);
-
- AsyncResult ar;
- Pair<ApnContext, Integer> pair;
- ApnContext apnContext;
- int generation;
- int requestType;
- int handoverFailureMode;
- switch (msg.what) {
- case DctConstants.EVENT_DATA_CONNECTION_DETACHED:
- onDataConnectionDetached();
- break;
-
- case DctConstants.EVENT_DATA_CONNECTION_ATTACHED:
- onDataConnectionAttached();
- break;
-
- case DctConstants.EVENT_DO_RECOVERY:
- mDsRecoveryHandler.doRecovery();
- break;
-
- case DctConstants.EVENT_APN_CHANGED:
- onApnChanged();
- break;
-
- case DctConstants.EVENT_PS_RESTRICT_ENABLED:
- /**
- * We don't need to explicitly to tear down the PDP context
- * when PS restricted is enabled. The base band will deactive
- * PDP context and notify us with PDP_CONTEXT_CHANGED.
- * But we should stop the network polling and prevent reset PDP.
- */
- if (DBG) log("EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted);
- stopNetStatPoll();
- stopDataStallAlarm();
- mIsPsRestricted = true;
- break;
-
- case DctConstants.EVENT_PS_RESTRICT_DISABLED:
- /**
- * When PS restrict is removed, we need setup PDP connection if
- * PDP connection is down.
- */
- if (DBG) log("EVENT_PS_RESTRICT_DISABLED " + mIsPsRestricted);
- mIsPsRestricted = false;
- if (isAnyDataConnected()) {
- startNetStatPoll();
- startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
- } else {
- // TODO: Should all PDN states be checked to fail?
- if (mState == DctConstants.State.FAILED) {
- cleanUpAllConnectionsInternal(false, Phone.REASON_PS_RESTRICT_ENABLED);
- mReregisterOnReconnectFailure = false;
- }
- apnContext = mApnContextsByType.get(ApnSetting.TYPE_DEFAULT);
- if (apnContext != null) {
- apnContext.setReason(Phone.REASON_PS_RESTRICT_ENABLED);
- trySetupData(apnContext, REQUEST_TYPE_NORMAL, null);
- } else {
- loge("**** Default ApnContext not found ****");
- if (TelephonyUtils.IS_DEBUGGABLE) {
- throw new RuntimeException("Default ApnContext not found");
- }
- }
- }
- break;
-
- case DctConstants.EVENT_TRY_SETUP_DATA:
- apnContext = (ApnContext) msg.obj;
- requestType = msg.arg1;
- trySetupData(apnContext, requestType, null);
- break;
- case DctConstants.EVENT_CLEAN_UP_CONNECTION:
- if (DBG) log("EVENT_CLEAN_UP_CONNECTION");
- cleanUpConnectionInternal(true, RELEASE_TYPE_DETACH, (ApnContext) msg.obj);
- break;
- case DctConstants.EVENT_CLEAN_UP_ALL_CONNECTIONS:
- if ((msg.obj != null) && (msg.obj instanceof String == false)) {
- msg.obj = null;
- }
- cleanUpAllConnectionsInternal(true, (String) msg.obj);
- break;
-
- case DctConstants.EVENT_DATA_RAT_CHANGED:
- if (getDataRat() == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
- // unknown rat is an exception for data rat change. It's only received when out
- // of service and is not applicable for apn bearer bitmask. We should bypass the
- // check of waiting apn list and keep the data connection on, and no need to
- // setup a new one.
- break;
- }
- cleanUpConnectionsOnUpdatedApns(false, Phone.REASON_NW_TYPE_CHANGED);
- //May new Network allow setupData, so try it here
- setupDataOnAllConnectableApns(Phone.REASON_NW_TYPE_CHANGED,
- RetryFailures.ONLY_ON_CHANGE);
- break;
-
- case DctConstants.CMD_CLEAR_PROVISIONING_SPINNER:
- // Check message sender intended to clear the current spinner.
- if (mProvisioningSpinner == msg.obj) {
- mProvisioningSpinner.dismiss();
- mProvisioningSpinner = null;
- }
- break;
-
- case DctConstants.EVENT_ENABLE_APN:
- onEnableApn(msg.arg1, msg.arg2, (Message) msg.obj);
- break;
-
- case DctConstants.EVENT_DISABLE_APN:
- onDisableApn(msg.arg1, msg.arg2);
- break;
-
- case DctConstants.EVENT_DATA_STALL_ALARM:
- onDataStallAlarm(msg.arg1);
- break;
-
- case DctConstants.EVENT_ROAMING_OFF:
- onDataRoamingOff();
- break;
-
- case DctConstants.EVENT_ROAMING_ON:
- case DctConstants.EVENT_ROAMING_SETTING_CHANGE:
- onDataRoamingOnOrSettingsChanged(msg.what);
- break;
-
- case DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE:
- // Update sharedPreference to false when exits new device provisioning, indicating
- // no users modifications on the settings for new devices. Thus carrier specific
- // default roaming settings can be applied for new devices till user modification.
- final SharedPreferences sp = PreferenceManager
- .getDefaultSharedPreferences(mPhone.getContext());
- if (!sp.contains(Phone.DATA_ROAMING_IS_USER_SETTING_KEY)) {
- sp.edit().putBoolean(Phone.DATA_ROAMING_IS_USER_SETTING_KEY, false).commit();
- }
- break;
-
- case DctConstants.EVENT_NETWORK_STATUS_CHANGED:
- int status = msg.arg1;
- int cid = msg.arg2;
- String url = (String) msg.obj;
- onNetworkStatusChanged(status, cid, url);
- break;
-
- case DctConstants.EVENT_RADIO_AVAILABLE:
- onRadioAvailable();
- break;
-
- case DctConstants.EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
- onRadioOffOrNotAvailable();
- break;
-
- case DctConstants.EVENT_DATA_SETUP_COMPLETE:
- ar = (AsyncResult) msg.obj;
- pair = (Pair<ApnContext, Integer>) ar.userObj;
- apnContext = pair.first;
- generation = pair.second;
- requestType = msg.arg1;
- handoverFailureMode = msg.arg2;
- if (apnContext.getConnectionGeneration() == generation) {
- boolean success = true;
- int cause = DataFailCause.UNKNOWN;
- if (ar.exception != null) {
- success = false;
- cause = (int) ar.result;
- }
- onDataSetupComplete(apnContext, success, cause, requestType,
- handoverFailureMode);
- } else {
- loge("EVENT_DATA_SETUP_COMPLETE: Dropped the event because generation "
- + "did not match.");
- }
- break;
-
- case DctConstants.EVENT_DATA_SETUP_COMPLETE_ERROR:
- ar = (AsyncResult) msg.obj;
- pair = (Pair<ApnContext, Integer>) ar.userObj;
- apnContext = pair.first;
- generation = pair.second;
- handoverFailureMode = msg.arg2;
- if (apnContext.getConnectionGeneration() == generation) {
- onDataSetupCompleteError(apnContext, handoverFailureMode, false);
- } else {
- loge("EVENT_DATA_SETUP_COMPLETE_ERROR: Dropped the event because generation "
- + "did not match.");
- }
- break;
-
- case DctConstants.EVENT_DISCONNECT_DONE:
- log("EVENT_DISCONNECT_DONE msg=" + msg);
- ar = (AsyncResult) msg.obj;
- pair = (Pair<ApnContext, Integer>) ar.userObj;
- apnContext = pair.first;
- generation = pair.second;
- if (apnContext.getConnectionGeneration() == generation) {
- onDisconnectDone(apnContext);
- } else {
- loge("EVENT_DISCONNECT_DONE: Dropped the event because generation "
- + "did not match.");
- }
- break;
-
- case DctConstants.EVENT_VOICE_CALL_STARTED:
- onVoiceCallStarted();
- break;
-
- case DctConstants.EVENT_VOICE_CALL_ENDED:
- onVoiceCallEnded();
- break;
- case DctConstants.CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: {
- sEnableFailFastRefCounter += (msg.arg1 == DctConstants.ENABLED) ? 1 : -1;
- if (DBG) {
- log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: "
- + " sEnableFailFastRefCounter=" + sEnableFailFastRefCounter);
- }
- if (sEnableFailFastRefCounter < 0) {
- final String s = "CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: "
- + "sEnableFailFastRefCounter:" + sEnableFailFastRefCounter + " < 0";
- loge(s);
- sEnableFailFastRefCounter = 0;
- }
- final boolean enabled = sEnableFailFastRefCounter > 0;
- if (DBG) {
- log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: enabled=" + enabled
- + " sEnableFailFastRefCounter=" + sEnableFailFastRefCounter);
- }
- if (mFailFast != enabled) {
- mFailFast = enabled;
-
- mDataStallNoRxEnabled = !enabled;
- if (mDsRecoveryHandler.isNoRxDataStallDetectionEnabled()
- && isAnyDataConnected()
- && (!mInVoiceCall ||
- mPhone.getServiceStateTracker()
- .isConcurrentVoiceAndDataAllowed())) {
- if (DBG) log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: start data stall");
- stopDataStallAlarm();
- startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
- } else {
- if (DBG) log("CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA: stop data stall");
- stopDataStallAlarm();
- }
- }
-
- break;
- }
- case DctConstants.CMD_ENABLE_MOBILE_PROVISIONING: {
- Bundle bundle = msg.getData();
- if (bundle != null) {
- try {
- mProvisioningUrl = (String)bundle.get(DctConstants.PROVISIONING_URL_KEY);
- } catch(ClassCastException e) {
- loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioning url not a string" + e);
- mProvisioningUrl = null;
- }
- }
- if (TextUtils.isEmpty(mProvisioningUrl)) {
- loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioning url is empty, ignoring");
- mIsProvisioning = false;
- mProvisioningUrl = null;
- } else {
- loge("CMD_ENABLE_MOBILE_PROVISIONING: provisioningUrl=" + mProvisioningUrl);
- mIsProvisioning = true;
- startProvisioningApnAlarm();
- }
- break;
- }
- case DctConstants.EVENT_PROVISIONING_APN_ALARM: {
- if (DBG) log("EVENT_PROVISIONING_APN_ALARM");
- ApnContext apnCtx = mApnContextsByType.get(ApnSetting.TYPE_DEFAULT);
- if (apnCtx.isProvisioningApn() && apnCtx.isConnectedOrConnecting()) {
- if (mProvisioningApnAlarmTag == msg.arg1) {
- if (DBG) log("EVENT_PROVISIONING_APN_ALARM: Disconnecting");
- mIsProvisioning = false;
- mProvisioningUrl = null;
- stopProvisioningApnAlarm();
- cleanUpConnectionInternal(true, RELEASE_TYPE_DETACH, apnCtx);
- } else {
- if (DBG) {
- log("EVENT_PROVISIONING_APN_ALARM: ignore stale tag,"
- + " mProvisioningApnAlarmTag:" + mProvisioningApnAlarmTag
- + " != arg1:" + msg.arg1);
- }
- }
- } else {
- if (DBG) log("EVENT_PROVISIONING_APN_ALARM: Not connected ignore");
- }
- break;
- }
- case DctConstants.CMD_IS_PROVISIONING_APN: {
- if (DBG) log("CMD_IS_PROVISIONING_APN");
- boolean isProvApn;
- try {
- String apnType = null;
- Bundle bundle = msg.getData();
- if (bundle != null) {
- apnType = (String)bundle.get(DctConstants.APN_TYPE_KEY);
- }
- if (TextUtils.isEmpty(apnType)) {
- loge("CMD_IS_PROVISIONING_APN: apnType is empty");
- isProvApn = false;
- } else {
- isProvApn = isProvisioningApn(apnType);
- }
- } catch (ClassCastException e) {
- loge("CMD_IS_PROVISIONING_APN: NO provisioning url ignoring");
- isProvApn = false;
- }
- if (DBG) log("CMD_IS_PROVISIONING_APN: ret=" + isProvApn);
- mReplyAc.replyToMessage(msg, DctConstants.CMD_IS_PROVISIONING_APN,
- isProvApn ? DctConstants.ENABLED : DctConstants.DISABLED);
- break;
- }
- case DctConstants.EVENT_RESTART_RADIO: {
- restartRadio();
- break;
- }
- case DctConstants.CMD_NET_STAT_POLL: {
- if (msg.arg1 == DctConstants.ENABLED) {
- handleStartNetStatPoll((DctConstants.Activity)msg.obj);
- } else if (msg.arg1 == DctConstants.DISABLED) {
- handleStopNetStatPoll((DctConstants.Activity)msg.obj);
- }
- break;
- }
- case DctConstants.EVENT_PCO_DATA_RECEIVED: {
- handlePcoData((AsyncResult)msg.obj);
- break;
- }
- case DctConstants.EVENT_DATA_RECONNECT:
- if (DBG) {
- log("EVENT_DATA_RECONNECT: subId=" + msg.arg1 + ", type="
- + requestTypeToString(msg.arg2));
- }
- onDataReconnect((ApnContext) msg.obj, msg.arg1, msg.arg2);
- break;
- case DctConstants.EVENT_DATA_SERVICE_BINDING_CHANGED:
- onDataServiceBindingChanged((Boolean) ((AsyncResult) msg.obj).result);
- break;
- case DctConstants.EVENT_DATA_ENABLED_CHANGED:
- ar = (AsyncResult) msg.obj;
- if (ar.result instanceof Pair) {
- Pair<Boolean, Integer> p = (Pair<Boolean, Integer>) ar.result;
- boolean enabled = p.first;
- int reason = p.second;
- onDataEnabledChanged(enabled, reason);
- }
- break;
- case DctConstants.EVENT_DATA_ENABLED_OVERRIDE_RULES_CHANGED:
- onDataEnabledOverrideRulesChanged();
- break;
- case DctConstants.EVENT_NR_TIMER_WATCHDOG:
- mWatchdog = false;
- reevaluateUnmeteredConnections();
- break;
- case DctConstants.EVENT_TELEPHONY_DISPLAY_INFO_CHANGED:
- reevaluateCongestedConnections();
- reevaluateUnmeteredConnections();
- break;
- case DctConstants.EVENT_CARRIER_CONFIG_CHANGED:
- onCarrierConfigChanged();
- break;
- case DctConstants.EVENT_SIM_STATE_UPDATED:
- int simState = msg.arg1;
- onSimStateUpdated(simState);
- break;
- case DctConstants.EVENT_APN_UNTHROTTLED:
- ar = (AsyncResult) msg.obj;
- String apn = (String) ar.result;
- onApnUnthrottled(apn);
- break;
- case DctConstants.EVENT_TRAFFIC_DESCRIPTORS_UPDATED:
- onTrafficDescriptorsUpdated();
- break;
- default:
- Rlog.e("DcTracker", "Unhandled event=" + msg);
- break;
-
- }
- }
-
- private int getApnProfileID(String apnType) {
- if (TextUtils.equals(apnType, ApnSetting.TYPE_IMS_STRING)) {
- return RILConstants.DATA_PROFILE_IMS;
- } else if (TextUtils.equals(apnType, ApnSetting.TYPE_FOTA_STRING)) {
- return RILConstants.DATA_PROFILE_FOTA;
- } else if (TextUtils.equals(apnType, ApnSetting.TYPE_CBS_STRING)) {
- return RILConstants.DATA_PROFILE_CBS;
- } else if (TextUtils.equals(apnType, ApnSetting.TYPE_IA_STRING)) {
- return RILConstants.DATA_PROFILE_DEFAULT; // DEFAULT for now
- } else if (TextUtils.equals(apnType, ApnSetting.TYPE_DUN_STRING)) {
- return RILConstants.DATA_PROFILE_TETHERED;
- } else {
- return RILConstants.DATA_PROFILE_DEFAULT;
- }
- }
-
- private int getCellLocationId() {
- int cid = -1;
- CellLocation loc = mPhone.getCurrentCellIdentity().asCellLocation();
-
- if (loc != null) {
- if (loc instanceof GsmCellLocation) {
- cid = ((GsmCellLocation)loc).getCid();
- } else if (loc instanceof CdmaCellLocation) {
- cid = ((CdmaCellLocation)loc).getBaseStationId();
- }
- }
- return cid;
- }
-
- /**
- * Update link bandwidth estimate default values from carrier config.
- * @param bandwidths String array of "RAT:upstream,downstream" for each RAT
- * @param useLte For NR NSA, whether to use LTE value for upstream or not
- */
- private void updateLinkBandwidths(String[] bandwidths, boolean useLte) {
- ConcurrentHashMap<String, Pair<Integer, Integer>> temp = new ConcurrentHashMap<>();
- for (String config : bandwidths) {
- int downstream = 14;
- int upstream = 14;
- String[] kv = config.split(":");
- if (kv.length == 2) {
- String[] split = kv[1].split(",");
- if (split.length == 2) {
- try {
- downstream = Integer.parseInt(split[0]);
- upstream = Integer.parseInt(split[1]);
- } catch (NumberFormatException ignored) {
- }
- }
- temp.put(kv[0], new Pair<>(downstream, upstream));
- }
- }
- if (useLte) {
- Pair<Integer, Integer> ltePair =
- temp.get(DataConfigManager.DATA_CONFIG_NETWORK_TYPE_LTE);
- if (ltePair != null) {
- if (temp.containsKey(DataConfigManager.DATA_CONFIG_NETWORK_TYPE_NR_NSA)) {
- temp.put(DataConfigManager.DATA_CONFIG_NETWORK_TYPE_NR_NSA, new Pair<>(
- temp.get(DataConfigManager.DATA_CONFIG_NETWORK_TYPE_NR_NSA).first,
- ltePair.second));
- }
- if (temp.containsKey(DataConfigManager.DATA_CONFIG_NETWORK_TYPE_NR_NSA_MMWAVE)) {
- temp.put(DataConfigManager.DATA_CONFIG_NETWORK_TYPE_NR_NSA_MMWAVE, new Pair<>(
- temp.get(DataConfigManager.DATA_CONFIG_NETWORK_TYPE_NR_NSA_MMWAVE)
- .first, ltePair.second));
- }
- }
- }
- mBandwidths = temp;
- for (DataConnection dc : mDataConnections.values()) {
- dc.sendMessage(DataConnection.EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED);
- }
- }
-
- /**
- * Return the link upstream/downstream values from CarrierConfig for the given RAT name.
- * @param ratName RAT name from ServiceState#rilRadioTechnologyToString.
- * @return pair of downstream/upstream values (kbps), or null if the config is not defined.
- */
- public Pair<Integer, Integer> getLinkBandwidthsFromCarrierConfig(String ratName) {
- return mBandwidths.get(ratName);
- }
-
- @VisibleForTesting
- public boolean shouldAutoAttach() {
- if (mAutoAttachEnabled.get()) return true;
-
- PhoneSwitcher phoneSwitcher = PhoneSwitcher.getInstance();
- ServiceState serviceState = mPhone.getServiceState();
-
- if (phoneSwitcher == null || serviceState == null) return false;
-
- // If voice is also not in service, don't auto attach.
- if (serviceState.getState() != ServiceState.STATE_IN_SERVICE) return false;
-
- // If voice is on LTE or NR, don't auto attach as for LTE / NR data would be attached.
- if (serviceState.getVoiceNetworkType() == NETWORK_TYPE_LTE
- || serviceState.getVoiceNetworkType() == NETWORK_TYPE_NR) return false;
-
- // If phone is non default phone, modem may have detached from data for optimization.
- // If phone is in voice call, for DSDS case DDS switch may be limited so we do try our
- // best to setup data connection and allow auto-attach.
- return (mPhone.getPhoneId() != phoneSwitcher.getPreferredDataPhoneId()
- || mPhone.getState() != PhoneConstants.State.IDLE);
- }
-
- private void notifyAllDataDisconnected() {
- sEnableFailFastRefCounter = 0;
- mFailFast = false;
- log("notify all data disconnected");
- mAllDataDisconnectedRegistrants.notifyRegistrants();
- }
-
- public void registerForAllDataDisconnected(Handler h, int what) {
- mAllDataDisconnectedRegistrants.addUnique(h, what, null);
-
- if (areAllDataDisconnected()) {
- notifyAllDataDisconnected();
- }
- }
-
- public void unregisterForAllDataDisconnected(Handler h) {
- mAllDataDisconnectedRegistrants.remove(h);
- }
-
- private void onDataEnabledChanged(boolean enable,
- @DataEnabledChangedReason int enabledChangedReason) {
- if (DBG) {
- log("onDataEnabledChanged: enable=" + enable + ", enabledChangedReason="
- + enabledChangedReason);
- }
-
- if (enable) {
- reevaluateDataConnections();
- setupDataOnAllConnectableApns(Phone.REASON_DATA_ENABLED, RetryFailures.ALWAYS);
- } else {
- String cleanupReason;
- switch (enabledChangedReason) {
- case DataEnabledSettings.REASON_INTERNAL_DATA_ENABLED:
- cleanupReason = Phone.REASON_DATA_DISABLED_INTERNAL;
- break;
- case DataEnabledSettings.REASON_DATA_ENABLED_BY_CARRIER:
- cleanupReason = Phone.REASON_CARRIER_ACTION_DISABLE_METERED_APN;
- break;
- case DataEnabledSettings.REASON_USER_DATA_ENABLED:
- case DataEnabledSettings.REASON_POLICY_DATA_ENABLED:
- case DataEnabledSettings.REASON_PROVISIONED_CHANGED:
- case DataEnabledSettings.REASON_PROVISIONING_DATA_ENABLED_CHANGED:
- default:
- cleanupReason = Phone.REASON_DATA_SPECIFIC_DISABLED;
- break;
-
- }
- cleanUpAllConnectionsInternal(true, cleanupReason);
- }
- }
-
- private void reevaluateCongestedConnections() {
- log("reevaluateCongestedConnections");
- int rat = mPhone.getDisplayInfoController().getTelephonyDisplayInfo().getNetworkType();
- // congested override and either network is specified or unknown and all networks specified
- boolean isCongested = mCongestedOverride && (mCongestedNetworkTypes.contains(rat)
- || mCongestedNetworkTypes.containsAll(Arrays.stream(
- TelephonyManager.getAllNetworkTypes()).boxed().collect(Collectors.toSet())));
- for (DataConnection dataConnection : mDataConnections.values()) {
- dataConnection.onCongestednessChanged(isCongested);
- }
- }
-
- private void reevaluateUnmeteredConnections() {
- log("reevaluateUnmeteredConnections");
- int rat = mPhone.getDisplayInfoController().getTelephonyDisplayInfo().getNetworkType();
- if (isNrUnmetered() && (!mPhone.getServiceState().getRoaming() || mNrNsaRoamingUnmetered)) {
- setDataConnectionUnmetered(true);
- if (!mWatchdog) {
- startWatchdogAlarm();
- }
- } else {
- stopWatchdogAlarm();
- setDataConnectionUnmetered(isNetworkTypeUnmetered(rat));
- }
- }
-
- private void setDataConnectionUnmetered(boolean isUnmetered) {
- if (!isUnmetered || isTempNotMeteredSupportedByCarrier()) {
- for (DataConnection dataConnection : mDataConnections.values()) {
- dataConnection.onMeterednessChanged(isUnmetered);
- }
- }
- }
-
- private boolean isNetworkTypeUnmetered(@NetworkType int networkType) {
- boolean isUnmetered;
- if (mUnmeteredNetworkTypes == null || !mUnmeteredOverride) {
- // check SubscriptionPlans if override is not defined
- isUnmetered = isNetworkTypeUnmeteredViaSubscriptionPlan(networkType);
- log("isNetworkTypeUnmeteredViaSubscriptionPlan: networkType=" + networkType
- + ", isUnmetered=" + isUnmetered);
- return isUnmetered;
- }
- // unmetered override and either network is specified or unknown and all networks specified
- isUnmetered = mUnmeteredNetworkTypes.contains(networkType)
- || mUnmeteredNetworkTypes.containsAll(Arrays.stream(
- TelephonyManager.getAllNetworkTypes()).boxed().collect(Collectors.toSet()));
- if (DBG) {
- log("isNetworkTypeUnmetered: networkType=" + networkType
- + ", isUnmetered=" + isUnmetered);
- }
- return isUnmetered;
- }
-
- private boolean isNetworkTypeUnmeteredViaSubscriptionPlan(@NetworkType int networkType) {
- if (mSubscriptionPlans.isEmpty()) {
- // safe return false if unable to get subscription plans or plans don't exist
- return false;
- }
-
- boolean isGeneralUnmetered = true;
- Set<Integer> allNetworkTypes = Arrays.stream(TelephonyManager.getAllNetworkTypes())
- .boxed().collect(Collectors.toSet());
- for (SubscriptionPlan plan : mSubscriptionPlans) {
- // check plan is general (applies to all network types) or specific
- if (Arrays.stream(plan.getNetworkTypes()).boxed().collect(Collectors.toSet())
- .containsAll(allNetworkTypes)) {
- if (!isPlanUnmetered(plan)) {
- // metered takes precedence over unmetered for safety
- isGeneralUnmetered = false;
- }
- } else {
- // check plan applies to given network type
- if (networkType != TelephonyManager.NETWORK_TYPE_UNKNOWN) {
- for (int planNetworkType : plan.getNetworkTypes()) {
- if (planNetworkType == networkType) {
- return isPlanUnmetered(plan);
- }
- }
- }
- }
- }
- return isGeneralUnmetered;
- }
-
- private boolean isPlanUnmetered(SubscriptionPlan plan) {
- return plan.getDataLimitBytes() == SubscriptionPlan.BYTES_UNLIMITED;
- }
-
- private boolean isNrUnmetered() {
- int rat = mPhone.getDisplayInfoController().getTelephonyDisplayInfo().getNetworkType();
- int override = mPhone.getDisplayInfoController().getTelephonyDisplayInfo()
- .getOverrideNetworkType();
-
- if (isNetworkTypeUnmetered(NETWORK_TYPE_NR)) {
- if (mNrNsaMmwaveUnmetered) {
- if (override == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED) {
- if (DBG) log("NR unmetered for mmwave only");
- return true;
- }
- return false;
- } else if (mNrNsaSub6Unmetered) {
- if (override == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA) {
- if (DBG) log("NR unmetered for sub6 only");
- return true;
- }
- return false;
- }
- if (override == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED
- || override == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA
- || rat == NETWORK_TYPE_NR) {
- if (DBG) log("NR unmetered for all frequencies");
- return true;
- }
- return false;
- }
-
- if (mNrNsaAllUnmetered) {
- if (mNrNsaMmwaveUnmetered) {
- if (override == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED) {
- if (DBG) log("NR NSA unmetered for mmwave only via carrier configs");
- return true;
- }
- return false;
- } else if (mNrNsaSub6Unmetered) {
- if (override == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA) {
- if (DBG) log("NR NSA unmetered for sub6 only via carrier configs");
- return true;
- }
- return false;
- }
- if (override == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED
- || override == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA) {
- if (DBG) log("NR NSA unmetered for all frequencies via carrier configs");
- return true;
- }
- return false;
- }
-
- if (mNrSaAllUnmetered) {
- // TODO: add logic for mNrSaMmwaveUnmetered and mNrSaSub6Unmetered once it's defined
- // in TelephonyDisplayInfo
- if (rat == NETWORK_TYPE_NR) {
- if (DBG) log("NR SA unmetered for all frequencies via carrier configs");
- return true;
- }
- return false;
- }
-
- return false;
- }
-
- private boolean isTempNotMeteredSupportedByCarrier() {
- CarrierConfigManager configManager =
- mPhone.getContext().getSystemService(CarrierConfigManager.class);
- if (configManager != null) {
- PersistableBundle bundle = configManager.getConfigForSubId(mPhone.getSubId());
- if (bundle != null) {
- return bundle.getBoolean(
- CarrierConfigManager.KEY_NETWORK_TEMP_NOT_METERED_SUPPORTED_BOOL);
- }
- }
-
- return false;
- }
-
- protected void log(String s) {
- Rlog.d(mLogTag, s);
- }
-
- private void loge(String s) {
- Rlog.e(mLogTag, s);
- }
-
- private void logSortedApnContexts() {
- if (VDBG) {
- log("initApnContexts: X mApnContexts=" + mApnContexts);
-
- StringBuilder sb = new StringBuilder();
- sb.append("sorted apncontexts -> [");
- for (ApnContext apnContext : mPrioritySortedApnContexts) {
- sb.append(apnContext);
- sb.append(", ");
-
- log("sorted list");
- }
- sb.append("]");
- log(sb.toString());
- }
- }
-
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("DcTracker:");
- pw.println(" RADIO_TESTS=" + RADIO_TESTS);
- pw.println(" mDataEnabledSettings=" + mDataEnabledSettings);
- pw.println(" isDataAllowed=" + isDataAllowed(null));
- pw.flush();
- pw.println(" mRequestedApnType=" + mRequestedApnType);
- pw.println(" mPhone=" + mPhone.getPhoneName());
- pw.println(" mConfigReady=" + mConfigReady);
- pw.println(" mSimState=" + SubscriptionInfoUpdater.simStateString(mSimState));
- pw.println(" mActivity=" + mActivity);
- pw.println(" mState=" + mState);
- pw.println(" mTxPkts=" + mTxPkts);
- pw.println(" mRxPkts=" + mRxPkts);
- pw.println(" mNetStatPollPeriod=" + mNetStatPollPeriod);
- pw.println(" mNetStatPollEnabled=" + mNetStatPollEnabled);
- pw.println(" mDataStallTxRxSum=" + mDataStallTxRxSum);
- pw.println(" mDataStallAlarmTag=" + mDataStallAlarmTag);
- pw.println(" mDataStallNoRxEnabled=" + mDataStallNoRxEnabled);
- pw.println(" mEmergencyApn=" + mEmergencyApn);
- pw.println(" mSentSinceLastRecv=" + mSentSinceLastRecv);
- pw.println(" mNoRecvPollCount=" + mNoRecvPollCount);
- pw.println(" mResolver=" + mResolver);
- pw.println(" mReconnectIntent=" + mReconnectIntent);
- pw.println(" mAutoAttachEnabled=" + mAutoAttachEnabled.get());
- pw.println(" mIsScreenOn=" + mIsScreenOn);
- pw.println(" mUniqueIdGenerator=" + mUniqueIdGenerator);
- pw.println(" mDataServiceBound=" + mDataServiceBound);
- pw.println(" mDataRoamingLeakageLog= ");
- mDataRoamingLeakageLog.dump(fd, pw, args);
- pw.println(" mApnSettingsInitializationLog= ");
- mApnSettingsInitializationLog.dump(fd, pw, args);
- pw.flush();
- pw.println(" ***************************************");
- DcController dcc = mDcc;
- if (dcc != null) {
- if (mDataServiceBound) {
- dcc.dump(fd, pw, args);
- } else {
- pw.println(" Can't dump mDcc because data service is not bound.");
- }
- } else {
- pw.println(" mDcc=null");
- }
- pw.println(" ***************************************");
- HashMap<Integer, DataConnection> dcs = mDataConnections;
- if (dcs != null) {
- Set<Entry<Integer, DataConnection> > mDcSet = mDataConnections.entrySet();
- pw.println(" mDataConnections: count=" + mDcSet.size());
- for (Entry<Integer, DataConnection> entry : mDcSet) {
- pw.printf(" *** mDataConnection[%d] \n", entry.getKey());
- entry.getValue().dump(fd, pw, args);
- }
- } else {
- pw.println("mDataConnections=null");
- }
- pw.println(" ***************************************");
- pw.flush();
- HashMap<String, Integer> apnToDcId = mApnToDataConnectionId;
- if (apnToDcId != null) {
- Set<Entry<String, Integer>> apnToDcIdSet = apnToDcId.entrySet();
- pw.println(" mApnToDataConnectonId size=" + apnToDcIdSet.size());
- for (Entry<String, Integer> entry : apnToDcIdSet) {
- pw.printf(" mApnToDataConnectonId[%s]=%d\n", entry.getKey(), entry.getValue());
- }
- } else {
- pw.println("mApnToDataConnectionId=null");
- }
- pw.println(" ***************************************");
- pw.flush();
- ConcurrentHashMap<String, ApnContext> apnCtxs = mApnContexts;
- if (apnCtxs != null) {
- Set<Entry<String, ApnContext>> apnCtxsSet = apnCtxs.entrySet();
- pw.println(" mApnContexts size=" + apnCtxsSet.size());
- for (Entry<String, ApnContext> entry : apnCtxsSet) {
- entry.getValue().dump(fd, pw, args);
- }
- ApnContext.dumpLocalLog(fd, pw, args);
- pw.println(" ***************************************");
- } else {
- pw.println(" mApnContexts=null");
- }
- pw.flush();
-
- pw.println(" mAllApnSettings size=" + mAllApnSettings.size());
- for (int i = 0; i < mAllApnSettings.size(); i++) {
- pw.printf(" mAllApnSettings[%d]: %s\n", i, mAllApnSettings.get(i));
- }
- pw.flush();
-
- pw.println(" mPreferredApn=" + mPreferredApn);
- pw.println(" mIsPsRestricted=" + mIsPsRestricted);
- pw.println(" mIsDisposed=" + mIsDisposed);
- pw.println(" mIntentReceiver=" + mIntentReceiver);
- pw.println(" mReregisterOnReconnectFailure=" + mReregisterOnReconnectFailure);
- pw.println(" canSetPreferApn=" + mCanSetPreferApn);
- pw.println(" mApnObserver=" + mApnObserver);
- pw.println(" isAnyDataConnected=" + isAnyDataConnected());
- pw.println(" mAttached=" + mAttached.get());
- mDataEnabledSettings.dump(fd, pw, args);
- pw.flush();
- }
-
- public String[] getPcscfAddress(String apnType) {
- log("getPcscfAddress()");
- ApnContext apnContext = null;
-
- if(apnType == null){
- log("apnType is null, return null");
- return null;
- }
-
- if (TextUtils.equals(apnType, ApnSetting.TYPE_EMERGENCY_STRING)) {
- apnContext = mApnContextsByType.get(ApnSetting.TYPE_EMERGENCY);
- } else if (TextUtils.equals(apnType, ApnSetting.TYPE_IMS_STRING)) {
- apnContext = mApnContextsByType.get(ApnSetting.TYPE_IMS);
- } else {
- log("apnType is invalid, return null");
- return null;
- }
-
- if (apnContext == null) {
- log("apnContext is null, return null");
- return null;
- }
-
- DataConnection dataConnection = apnContext.getDataConnection();
- String[] result = null;
-
- if (dataConnection != null) {
- result = dataConnection.getPcscfAddresses();
-
- if (result != null) {
- for (int i = 0; i < result.length; i++) {
- log("Pcscf[" + i + "]: " + result[i]);
- }
- }
- return result;
- }
- return null;
- }
-
- /**
- * Create default apn settings for the apn type like emergency, and ims
- */
- private ApnSetting buildDefaultApnSetting(@NonNull String entry,
- @NonNull String apn, @ApnType int apnTypeBitmask) {
- return new ApnSetting.Builder()
- .setEntryName(entry)
- .setProtocol(ApnSetting.PROTOCOL_IPV4V6)
- .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6)
- .setApnName(apn)
- .setApnTypeBitmask(apnTypeBitmask)
- .setCarrierEnabled(true)
- .setApnSetId(Telephony.Carriers.MATCH_ALL_APN_SET_ID)
- .build();
- }
-
- /**
- * Add default APN settings to APN settings list as needed
- */
- private void addDefaultApnSettingsAsNeeded() {
- boolean isEmergencyApnConfigured = false;
- boolean isImsApnConfigured = false;
-
- for (ApnSetting apn : mAllApnSettings) {
- if (apn.canHandleType(ApnSetting.TYPE_EMERGENCY)) {
- isEmergencyApnConfigured = true;
- }
- if (apn.canHandleType(ApnSetting.TYPE_IMS)) {
- isImsApnConfigured = true;
- }
- if (isEmergencyApnConfigured && isImsApnConfigured) {
- log("Both emergency and ims apn setting are already present");
- return;
- }
- }
-
- // Add default apn setting for emergency service if it is not present
- if (!isEmergencyApnConfigured) {
- mAllApnSettings.add(buildDefaultApnSetting(
- "DEFAULT EIMS", "sos", ApnSetting.TYPE_EMERGENCY));
- log("default emergency apn is created");
- }
-
- // Only add default apn setting for ims when it is not present and sim is loaded
- if (!isImsApnConfigured && mSimState == TelephonyManager.SIM_STATE_LOADED) {
- mAllApnSettings.add(buildDefaultApnSetting(
- "DEFAULT IMS", "ims", ApnSetting.TYPE_IMS));
- log("default ims apn is created");
- }
- }
-
- private void cleanUpConnectionsOnUpdatedApns(boolean detach, String reason) {
- if (DBG) log("cleanUpConnectionsOnUpdatedApns: detach=" + detach);
- if (mAllApnSettings.isEmpty()) {
- cleanUpAllConnectionsInternal(detach, Phone.REASON_APN_CHANGED);
- } else {
- if (getDataRat() == ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN) {
- // unknown rat is an exception for data rat change. Its only received when out of
- // service and is not applicable for apn bearer bitmask. We should bypass the check
- // of waiting apn list and keep the data connection on.
- return;
- }
- for (ApnContext apnContext : mApnContexts.values()) {
- boolean cleanupRequired = true;
- if (!apnContext.isDisconnected()) {
- ArrayList<ApnSetting> waitingApns = buildWaitingApns(
- apnContext.getApnType(), getDataRat());
- if (apnContext.getWaitingApns().size() != waitingApns.size()
- || !apnContext.getWaitingApns().containsAll(waitingApns)) {
- apnContext.setWaitingApns(waitingApns);
- }
- for (ApnSetting apnSetting : waitingApns) {
- if (areCompatible(apnSetting, apnContext.getApnSetting())) {
- cleanupRequired = false;
- break;
- }
- }
-
- if (cleanupRequired) {
- if (DBG) {
- log("cleanUpConnectionsOnUpdatedApns: APN type "
- + apnContext.getApnType() + " clean up is required. The new "
- + "waiting APN list " + waitingApns + " does not cover "
- + apnContext.getApnSetting());
- }
- apnContext.setReason(reason);
- cleanUpConnectionInternal(true, RELEASE_TYPE_DETACH, apnContext);
- }
- }
- }
- }
-
- if (!isAnyDataConnected()) {
- stopNetStatPoll();
- stopDataStallAlarm();
- }
-
- mRequestedApnType = ApnSetting.TYPE_DEFAULT;
-
- if (areAllDataDisconnected()) {
- notifyAllDataDisconnected();
- }
- }
-
- /**
- * Polling stuff
- */
- protected void resetPollStats() {
- mTxPkts = -1;
- mRxPkts = -1;
- mNetStatPollPeriod = POLL_NETSTAT_MILLIS;
- }
-
- protected void startNetStatPoll() {
- if (isAnyDataConnected() && !mNetStatPollEnabled) {
- if (DBG) {
- log("startNetStatPoll");
- }
- resetPollStats();
- mNetStatPollEnabled = true;
- mPollNetStat.run();
- }
- if (mPhone != null) {
- mPhone.notifyDataActivity();
- }
- }
-
- protected void stopNetStatPoll() {
- mNetStatPollEnabled = false;
- removeCallbacks(mPollNetStat);
- if (DBG) {
- log("stopNetStatPoll");
- }
-
- // To sync data activity icon in the case of switching data connection to send MMS.
- if (mPhone != null) {
- mPhone.notifyDataActivity();
- }
- }
-
- public void sendStartNetStatPoll(DctConstants.Activity activity) {
- Message msg = obtainMessage(DctConstants.CMD_NET_STAT_POLL);
- msg.arg1 = DctConstants.ENABLED;
- msg.obj = activity;
- sendMessage(msg);
- }
-
- private void handleStartNetStatPoll(DctConstants.Activity activity) {
- startNetStatPoll();
- startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
- setActivity(activity);
- }
-
- public void sendStopNetStatPoll(DctConstants.Activity activity) {
- Message msg = obtainMessage(DctConstants.CMD_NET_STAT_POLL);
- msg.arg1 = DctConstants.DISABLED;
- msg.obj = activity;
- sendMessage(msg);
- }
-
- private void handleStopNetStatPoll(DctConstants.Activity activity) {
- stopNetStatPoll();
- stopDataStallAlarm();
- setActivity(activity);
- }
-
- private void onDataEnabledOverrideRulesChanged() {
- if (DBG) {
- log("onDataEnabledOverrideRulesChanged");
- }
-
- for (ApnContext apnContext : mPrioritySortedApnContexts) {
- if (isDataAllowed(apnContext, REQUEST_TYPE_NORMAL, null)) {
- if (apnContext.getDataConnection() != null) {
- apnContext.getDataConnection().reevaluateRestrictedState();
- }
- setupDataOnConnectableApn(apnContext, Phone.REASON_DATA_ENABLED_OVERRIDE,
- RetryFailures.ALWAYS);
- } else if (shouldCleanUpConnection(apnContext, true, false)) {
- apnContext.setReason(Phone.REASON_DATA_ENABLED_OVERRIDE);
- cleanUpConnectionInternal(true, RELEASE_TYPE_DETACH, apnContext);
- }
- }
- }
-
- private void updateDataActivity() {
- long sent, received;
-
- DctConstants.Activity newActivity;
-
- TxRxSum preTxRxSum = new TxRxSum(mTxPkts, mRxPkts);
- TxRxSum curTxRxSum = new TxRxSum();
- curTxRxSum.updateTotalTxRxSum();
- mTxPkts = curTxRxSum.txPkts;
- mRxPkts = curTxRxSum.rxPkts;
-
- if (VDBG) {
- log("updateDataActivity: curTxRxSum=" + curTxRxSum + " preTxRxSum=" + preTxRxSum);
- }
-
- if (mNetStatPollEnabled && (preTxRxSum.txPkts > 0 || preTxRxSum.rxPkts > 0)) {
- sent = mTxPkts - preTxRxSum.txPkts;
- received = mRxPkts - preTxRxSum.rxPkts;
-
- if (VDBG)
- log("updateDataActivity: sent=" + sent + " received=" + received);
- if (sent > 0 && received > 0) {
- newActivity = DctConstants.Activity.DATAINANDOUT;
- } else if (sent > 0 && received == 0) {
- newActivity = DctConstants.Activity.DATAOUT;
- } else if (sent == 0 && received > 0) {
- newActivity = DctConstants.Activity.DATAIN;
- } else {
- newActivity = (mActivity == DctConstants.Activity.DORMANT) ?
- mActivity : DctConstants.Activity.NONE;
- }
-
- if (mActivity != newActivity && mIsScreenOn) {
- if (VDBG)
- log("updateDataActivity: newActivity=" + newActivity);
- mActivity = newActivity;
- mPhone.notifyDataActivity();
- }
- }
- }
-
- private void handlePcoData(AsyncResult ar) {
- if (ar.exception != null) {
- loge("PCO_DATA exception: " + ar.exception);
- return;
- }
- PcoData pcoData = (PcoData)(ar.result);
- ArrayList<DataConnection> dcList = new ArrayList<>();
- DataConnection temp = mDcc.getActiveDcByCid(pcoData.cid);
- if (temp != null) {
- dcList.add(temp);
- }
- if (dcList.size() == 0) {
- loge("PCO_DATA for unknown cid: " + pcoData.cid + ", inferring");
- for (DataConnection dc : mDataConnections.values()) {
- final int cid = dc.getCid();
- if (cid == pcoData.cid) {
- if (VDBG) log(" found " + dc);
- dcList.clear();
- dcList.add(dc);
- break;
- }
- // check if this dc is still connecting
- if (cid == -1) {
- for (ApnContext apnContext : dc.getApnContexts()) {
- if (apnContext.getState() == DctConstants.State.CONNECTING) {
- if (VDBG) log(" found potential " + dc);
- dcList.add(dc);
- break;
- }
- }
- }
- }
- }
- if (dcList.size() == 0) {
- loge("PCO_DATA - couldn't infer cid");
- return;
- }
- for (DataConnection dc : dcList) {
- List<ApnContext> apnContextList = dc.getApnContexts();
- if (apnContextList.size() == 0) {
- break;
- }
- // send one out for each apn type in play
- for (ApnContext apnContext : apnContextList) {
- String apnType = apnContext.getApnType();
-
- final Intent intent = new Intent(TelephonyManager.ACTION_CARRIER_SIGNAL_PCO_VALUE);
- intent.putExtra(TelephonyManager.EXTRA_APN_TYPE,
- ApnSetting.getApnTypesBitmaskFromString(apnType));
- intent.putExtra(TelephonyManager.EXTRA_APN_PROTOCOL,
- ApnSetting.getProtocolIntFromString(pcoData.bearerProto));
- intent.putExtra(TelephonyManager.EXTRA_PCO_ID, pcoData.pcoId);
- intent.putExtra(TelephonyManager.EXTRA_PCO_VALUE, pcoData.contents);
- mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
- }
- }
- }
-
- /**
- * Data-Stall
- */
-
- // Recovery action taken in case of data stall
- @IntDef(
- value = {
- RECOVERY_ACTION_GET_DATA_CALL_LIST,
- RECOVERY_ACTION_CLEANUP,
- RECOVERY_ACTION_REREGISTER,
- RECOVERY_ACTION_RADIO_RESTART
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface RecoveryAction {};
- private static final int RECOVERY_ACTION_GET_DATA_CALL_LIST = 0;
- private static final int RECOVERY_ACTION_CLEANUP = 1;
- private static final int RECOVERY_ACTION_REREGISTER = 2;
- private static final int RECOVERY_ACTION_RADIO_RESTART = 3;
-
- // Recovery handler class for cellular data stall
- private class DataStallRecoveryHandler {
- // Default minimum duration between each recovery steps
- private static final int
- DEFAULT_MIN_DURATION_BETWEEN_RECOVERY_STEPS_IN_MS = (3 * 60 * 1000); // 3 mins
-
- // The elapsed real time of last recovery attempted
- private long mTimeLastRecoveryStartMs;
- // Whether current network good or not
- private boolean mIsValidNetwork;
- // Whether data stall happened or not.
- private boolean mWasDataStall;
- // Whether the result of last action(RADIO_RESTART) reported.
- private boolean mLastActionReported;
- // The real time for data stall start.
- private long mDataStallStartMs;
- // Last data stall action.
- private @RecoveryAction int mLastAction;
-
- public DataStallRecoveryHandler() {
- reset();
- }
-
- public void reset() {
- mTimeLastRecoveryStartMs = 0;
- putRecoveryAction(RECOVERY_ACTION_GET_DATA_CALL_LIST);
- }
-
- private void setNetworkValidationState(boolean isValid) {
- // Validation status is true and was not data stall.
- if (isValid && !mWasDataStall) {
- return;
- }
-
- if (!mWasDataStall) {
- mWasDataStall = true;
- mDataStallStartMs = SystemClock.elapsedRealtime();
- if (DBG) log("data stall: start time = " + mDataStallStartMs);
- return;
- }
-
- if (!mLastActionReported) {
- int timeDuration = (int) (SystemClock.elapsedRealtime() - mDataStallStartMs);
- if (DBG) {
- log("data stall: lastaction = " + mLastAction + ", isRecovered = "
- + isValid + ", mTimeDuration = " + timeDuration);
- }
- DataStallRecoveryStats.onDataStallEvent(mLastAction, mPhone, isValid,
- timeDuration);
- mLastActionReported = true;
- }
-
- if (isValid) {
- mLastActionReported = false;
- mWasDataStall = false;
- }
- }
-
- public boolean isAggressiveRecovery() {
- @RecoveryAction int action = getRecoveryAction();
-
- return ((action == RECOVERY_ACTION_CLEANUP)
- || (action == RECOVERY_ACTION_REREGISTER)
- || (action == RECOVERY_ACTION_RADIO_RESTART));
- }
-
- private long getMinDurationBetweenRecovery() {
- return Settings.Global.getLong(mResolver,
- Settings.Global.MIN_DURATION_BETWEEN_RECOVERY_STEPS_IN_MS,
- DEFAULT_MIN_DURATION_BETWEEN_RECOVERY_STEPS_IN_MS);
- }
-
- private long getElapsedTimeSinceRecoveryMs() {
- return (SystemClock.elapsedRealtime() - mTimeLastRecoveryStartMs);
- }
-
- @RecoveryAction
- private int getRecoveryAction() {
- @RecoveryAction int action = Settings.System.getInt(mResolver,
- "radio.data.stall.recovery.action", RECOVERY_ACTION_GET_DATA_CALL_LIST);
- if (VDBG_STALL) log("getRecoveryAction: " + action);
- return action;
- }
-
- private void putRecoveryAction(@RecoveryAction int action) {
- Settings.System.putInt(mResolver, "radio.data.stall.recovery.action", action);
- if (VDBG_STALL) log("putRecoveryAction: " + action);
- }
-
- private void broadcastDataStallDetected(@RecoveryAction int recoveryAction) {
- Intent intent = new Intent(TelephonyManager.ACTION_DATA_STALL_DETECTED);
- SubscriptionManager.putPhoneIdAndSubIdExtra(intent, mPhone.getPhoneId());
- intent.putExtra(TelephonyManager.EXTRA_RECOVERY_ACTION, recoveryAction);
- mPhone.getContext().sendBroadcast(intent, READ_PRIVILEGED_PHONE_STATE);
- }
-
- private boolean isRecoveryAlreadyStarted() {
- return getRecoveryAction() != RECOVERY_ACTION_GET_DATA_CALL_LIST;
- }
-
- private boolean checkRecovery() {
- // To avoid back to back recovery wait for a grace period
- if (getElapsedTimeSinceRecoveryMs() < getMinDurationBetweenRecovery()) {
- if (VDBG_STALL) log("skip back to back data stall recovery");
- return false;
- }
-
- // Skip recovery if it can cause a call to drop
- if (mPhone.getState() != PhoneConstants.State.IDLE
- && getRecoveryAction() > RECOVERY_ACTION_CLEANUP) {
- if (VDBG_STALL) log("skip data stall recovery as there is an active call");
- return false;
- }
-
- // Allow recovery if data is expected to work
- return mAttached.get() && isDataAllowed(null);
- }
-
- private void triggerRecovery() {
- // Updating the recovery start time early to avoid race when
- // the message is being processed in the Queue
- mTimeLastRecoveryStartMs = SystemClock.elapsedRealtime();
- sendMessage(obtainMessage(DctConstants.EVENT_DO_RECOVERY));
- }
-
- public void doRecovery() {
- if (isAnyDataConnected()) {
- // Go through a series of recovery steps, each action transitions to the next action
- @RecoveryAction final int recoveryAction = getRecoveryAction();
- final int signalStrength = mPhone.getSignalStrength().getLevel();
- TelephonyMetrics.getInstance().writeSignalStrengthEvent(
- mPhone.getPhoneId(), signalStrength);
- TelephonyMetrics.getInstance().writeDataStallEvent(
- mPhone.getPhoneId(), recoveryAction);
- mLastAction = recoveryAction;
- mLastActionReported = false;
- broadcastDataStallDetected(recoveryAction);
-
- switch (recoveryAction) {
- case RECOVERY_ACTION_GET_DATA_CALL_LIST:
- EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_GET_DATA_CALL_LIST,
- mSentSinceLastRecv);
- if (DBG) log("doRecovery() get data call list");
- mDataServiceManager.requestDataCallList(obtainMessage());
- putRecoveryAction(RECOVERY_ACTION_CLEANUP);
- break;
- case RECOVERY_ACTION_CLEANUP:
- EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_CLEANUP,
- mSentSinceLastRecv);
- if (DBG) log("doRecovery() cleanup all connections");
- cleanUpConnection(mApnContexts.get(ApnSetting.getApnTypeString(
- ApnSetting.TYPE_DEFAULT)));
- cleanUpConnection(mApnContexts.get(ApnSetting.getApnTypeString(
- ApnSetting.TYPE_ENTERPRISE)));
- putRecoveryAction(RECOVERY_ACTION_REREGISTER);
- break;
- case RECOVERY_ACTION_REREGISTER:
- EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_REREGISTER,
- mSentSinceLastRecv);
- if (DBG) log("doRecovery() re-register");
- mPhone.getServiceStateTracker().reRegisterNetwork(null);
- putRecoveryAction(RECOVERY_ACTION_RADIO_RESTART);
- break;
- case RECOVERY_ACTION_RADIO_RESTART:
- EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART,
- mSentSinceLastRecv);
- if (DBG) log("restarting radio");
- restartRadio();
- reset();
- break;
- default:
- throw new RuntimeException("doRecovery: Invalid recoveryAction="
- + recoveryAction);
- }
- mSentSinceLastRecv = 0;
- }
- }
-
- public void processNetworkStatusChanged(boolean isValid) {
- setNetworkValidationState(isValid);
- if (isValid) {
- mIsValidNetwork = true;
- reset();
- } else {
- if (mIsValidNetwork || isRecoveryAlreadyStarted()) {
- mIsValidNetwork = false;
- // Check and trigger a recovery if network switched from good
- // to bad or recovery is already started before.
- if (checkRecovery()) {
- if (DBG) log("trigger data stall recovery");
- triggerRecovery();
- }
- }
- }
- }
-
- public boolean isRecoveryOnBadNetworkEnabled() {
- return Settings.Global.getInt(mResolver,
- Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 1) == 1;
- }
-
- public boolean isNoRxDataStallDetectionEnabled() {
- return mDataStallNoRxEnabled && !isRecoveryOnBadNetworkEnabled();
- }
- }
-
- private void updateDataStallInfo() {
- long sent, received;
-
- TxRxSum preTxRxSum = new TxRxSum(mDataStallTxRxSum);
- mDataStallTxRxSum.updateTotalTxRxSum();
-
- if (VDBG_STALL) {
- log("updateDataStallInfo: mDataStallTxRxSum=" + mDataStallTxRxSum +
- " preTxRxSum=" + preTxRxSum);
- }
-
- sent = mDataStallTxRxSum.txPkts - preTxRxSum.txPkts;
- received = mDataStallTxRxSum.rxPkts - preTxRxSum.rxPkts;
-
- if (RADIO_TESTS) {
- if (SystemProperties.getBoolean("radio.test.data.stall", false)) {
- log("updateDataStallInfo: radio.test.data.stall true received = 0;");
- received = 0;
- }
- }
- if ( sent > 0 && received > 0 ) {
- if (VDBG_STALL) log("updateDataStallInfo: IN/OUT");
- mSentSinceLastRecv = 0;
- mDsRecoveryHandler.reset();
- } else if (sent > 0 && received == 0) {
- if (isPhoneStateIdle()) {
- mSentSinceLastRecv += sent;
- } else {
- mSentSinceLastRecv = 0;
- }
- if (DBG) {
- log("updateDataStallInfo: OUT sent=" + sent +
- " mSentSinceLastRecv=" + mSentSinceLastRecv);
- }
- } else if (sent == 0 && received > 0) {
- if (VDBG_STALL) log("updateDataStallInfo: IN");
- mSentSinceLastRecv = 0;
- mDsRecoveryHandler.reset();
- } else {
- if (VDBG_STALL) log("updateDataStallInfo: NONE");
- }
- }
-
- private boolean isPhoneStateIdle() {
- for (int i = 0; i < mTelephonyManager.getPhoneCount(); i++) {
- Phone phone = PhoneFactory.getPhone(i);
- if (phone != null && phone.getState() != PhoneConstants.State.IDLE) {
- log("isPhoneStateIdle false: Voice call active on phone " + i);
- return false;
- }
- }
- return true;
- }
-
- private void onDataStallAlarm(int tag) {
- if (mDataStallAlarmTag != tag) {
- if (DBG) {
- log("onDataStallAlarm: ignore, tag=" + tag + " expecting " + mDataStallAlarmTag);
- }
- return;
- }
-
- if (DBG) log("Data stall alarm");
- updateDataStallInfo();
-
- int hangWatchdogTrigger = Settings.Global.getInt(mResolver,
- Settings.Global.PDP_WATCHDOG_TRIGGER_PACKET_COUNT,
- NUMBER_SENT_PACKETS_OF_HANG);
-
- boolean suspectedStall = DATA_STALL_NOT_SUSPECTED;
- if (mSentSinceLastRecv >= hangWatchdogTrigger) {
- if (DBG) {
- log("onDataStallAlarm: tag=" + tag + " do recovery action="
- + mDsRecoveryHandler.getRecoveryAction());
- }
- suspectedStall = DATA_STALL_SUSPECTED;
- sendMessage(obtainMessage(DctConstants.EVENT_DO_RECOVERY));
- } else {
- if (VDBG_STALL) {
- log("onDataStallAlarm: tag=" + tag + " Sent " + String.valueOf(mSentSinceLastRecv) +
- " pkts since last received, < watchdogTrigger=" + hangWatchdogTrigger);
- }
- }
- startDataStallAlarm(suspectedStall);
- }
-
- protected void startDataStallAlarm(boolean suspectedStall) {
- int delayInMs;
-
- if (mDsRecoveryHandler.isNoRxDataStallDetectionEnabled() && isAnyDataConnected()) {
- // If screen is on or data stall is currently suspected, set the alarm
- // with an aggressive timeout.
- if (mIsScreenOn || suspectedStall || mDsRecoveryHandler.isAggressiveRecovery()) {
- delayInMs = Settings.Global.getInt(mResolver,
- Settings.Global.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS,
- DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
- } else {
- delayInMs = Settings.Global.getInt(mResolver,
- Settings.Global.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS,
- DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT);
- }
-
- mDataStallAlarmTag += 1;
- if (VDBG_STALL) {
- log("startDataStallAlarm: tag=" + mDataStallAlarmTag +
- " delay=" + (delayInMs / 1000) + "s");
- }
- Intent intent = new Intent(INTENT_DATA_STALL_ALARM);
- intent.putExtra(INTENT_DATA_STALL_ALARM_EXTRA_TAG, mDataStallAlarmTag);
- intent.putExtra(INTENT_DATA_STALL_ALARM_EXTRA_TRANSPORT_TYPE, mTransportType);
- SubscriptionManager.putPhoneIdAndSubIdExtra(intent, mPhone.getPhoneId());
- mDataStallAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
- PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
- mAlarmManager.set(AlarmManager.ELAPSED_REALTIME,
- SystemClock.elapsedRealtime() + delayInMs, mDataStallAlarmIntent);
- } else {
- if (VDBG_STALL) {
- log("startDataStallAlarm: NOT started, no connection tag=" + mDataStallAlarmTag);
- }
- }
- }
-
- private void stopDataStallAlarm() {
- if (VDBG_STALL) {
- log("stopDataStallAlarm: current tag=" + mDataStallAlarmTag +
- " mDataStallAlarmIntent=" + mDataStallAlarmIntent);
- }
- mDataStallAlarmTag += 1;
- if (mDataStallAlarmIntent != null) {
- mAlarmManager.cancel(mDataStallAlarmIntent);
- mDataStallAlarmIntent = null;
- }
- }
-
- private void restartDataStallAlarm() {
- if (!isAnyDataConnected()) return;
- // To be called on screen status change.
- // Do not cancel the alarm if it is set with aggressive timeout.
- if (mDsRecoveryHandler.isAggressiveRecovery()) {
- if (DBG) log("restartDataStallAlarm: action is pending. not resetting the alarm.");
- return;
- }
- if (VDBG_STALL) log("restartDataStallAlarm: stop then start.");
- stopDataStallAlarm();
- startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
- }
-
- /**
- * Provisioning APN
- */
- private void onActionIntentProvisioningApnAlarm(Intent intent) {
- if (DBG) log("onActionIntentProvisioningApnAlarm: action=" + intent.getAction());
- Message msg = obtainMessage(DctConstants.EVENT_PROVISIONING_APN_ALARM,
- intent.getAction());
- msg.arg1 = intent.getIntExtra(PROVISIONING_APN_ALARM_TAG_EXTRA, 0);
- sendMessage(msg);
- }
-
- private void startProvisioningApnAlarm() {
- int delayInMs = Settings.Global.getInt(mResolver,
- Settings.Global.PROVISIONING_APN_ALARM_DELAY_IN_MS,
- PROVISIONING_APN_ALARM_DELAY_IN_MS_DEFAULT);
- if (TelephonyUtils.IS_DEBUGGABLE) {
- // Allow debug code to use a system property to provide another value
- String delayInMsStrg = Integer.toString(delayInMs);
- delayInMsStrg = System.getProperty(DEBUG_PROV_APN_ALARM, delayInMsStrg);
- try {
- delayInMs = Integer.parseInt(delayInMsStrg);
- } catch (NumberFormatException e) {
- loge("startProvisioningApnAlarm: e=" + e);
- }
- }
- mProvisioningApnAlarmTag += 1;
- if (DBG) {
- log("startProvisioningApnAlarm: tag=" + mProvisioningApnAlarmTag +
- " delay=" + (delayInMs / 1000) + "s");
- }
- Intent intent = new Intent(INTENT_PROVISIONING_APN_ALARM);
- intent.putExtra(PROVISIONING_APN_ALARM_TAG_EXTRA, mProvisioningApnAlarmTag);
- mProvisioningApnAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent,
- PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
- mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
- SystemClock.elapsedRealtime() + delayInMs, mProvisioningApnAlarmIntent);
- }
-
- private void stopProvisioningApnAlarm() {
- if (DBG) {
- log("stopProvisioningApnAlarm: current tag=" + mProvisioningApnAlarmTag +
- " mProvsioningApnAlarmIntent=" + mProvisioningApnAlarmIntent);
- }
- mProvisioningApnAlarmTag += 1;
- if (mProvisioningApnAlarmIntent != null) {
- mAlarmManager.cancel(mProvisioningApnAlarmIntent);
- mProvisioningApnAlarmIntent = null;
- }
- }
-
- /**
- * 5G connection reevaluation alarm
- */
- private void startWatchdogAlarm() {
- sendMessageDelayed(obtainMessage(DctConstants.EVENT_NR_TIMER_WATCHDOG), mWatchdogTimeMs);
- mWatchdog = true;
- }
-
- private void stopWatchdogAlarm() {
- removeMessages(DctConstants.EVENT_NR_TIMER_WATCHDOG);
- mWatchdog = false;
- }
-
- private void onDataServiceBindingChanged(boolean bound) {
- if (!bound) {
- if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
- boolean connPersistenceOnRestart = mPhone.getContext().getResources()
- .getBoolean(com.android
- .internal.R.bool.config_wlan_data_service_conn_persistence_on_restart);
- if (!connPersistenceOnRestart) {
- cleanUpAllConnectionsInternal(false, Phone.REASON_IWLAN_DATA_SERVICE_DIED);
- }
- }
- } else {
- //reset throttling after binding to data service
- mDataThrottler.reset();
- }
- mDataServiceBound = bound;
- }
-
- public static String requestTypeToString(@RequestNetworkType int type) {
- switch (type) {
- case REQUEST_TYPE_NORMAL: return "NORMAL";
- case REQUEST_TYPE_HANDOVER: return "HANDOVER";
- }
- return "UNKNOWN";
- }
-
- public static String releaseTypeToString(@ReleaseNetworkType int type) {
- switch (type) {
- case RELEASE_TYPE_NORMAL: return "NORMAL";
- case RELEASE_TYPE_DETACH: return "DETACH";
- case RELEASE_TYPE_HANDOVER: return "HANDOVER";
- }
- return "UNKNOWN";
- }
-
- @RilRadioTechnology
- protected int getDataRat() {
- ServiceState ss = mPhone.getServiceState();
- NetworkRegistrationInfo nrs = ss.getNetworkRegistrationInfo(
- NetworkRegistrationInfo.DOMAIN_PS, mTransportType);
- if (nrs != null) {
- return ServiceState.networkTypeToRilRadioTechnology(nrs.getAccessNetworkTechnology());
- }
- return ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
- }
-
- @RilRadioTechnology
- private int getVoiceRat() {
- ServiceState ss = mPhone.getServiceState();
- NetworkRegistrationInfo nrs = ss.getNetworkRegistrationInfo(
- NetworkRegistrationInfo.DOMAIN_CS, mTransportType);
- if (nrs != null) {
- return ServiceState.networkTypeToRilRadioTechnology(nrs.getAccessNetworkTechnology());
- }
- return ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
- }
-
- private void read5GConfiguration() {
- if (DBG) log("read5GConfiguration");
- String[] bandwidths = CarrierConfigManager.getDefaultConfig().getStringArray(
- CarrierConfigManager.KEY_BANDWIDTH_STRING_ARRAY);
- boolean useLte = false;
- CarrierConfigManager configManager = (CarrierConfigManager) mPhone.getContext()
- .getSystemService(Context.CARRIER_CONFIG_SERVICE);
- if (configManager != null) {
- PersistableBundle b = configManager.getConfigForSubId(mPhone.getSubId());
- if (b != null) {
- if (b.getStringArray(CarrierConfigManager.KEY_BANDWIDTH_STRING_ARRAY) != null) {
- bandwidths = b.getStringArray(CarrierConfigManager.KEY_BANDWIDTH_STRING_ARRAY);
- }
- useLte = b.getBoolean(CarrierConfigManager
- .KEY_BANDWIDTH_NR_NSA_USE_LTE_VALUE_FOR_UPLINK_BOOL);
- mWatchdogTimeMs = b.getLong(CarrierConfigManager.KEY_5G_WATCHDOG_TIME_MS_LONG);
- mNrNsaAllUnmetered = b.getBoolean(CarrierConfigManager.KEY_UNMETERED_NR_NSA_BOOL);
- mNrNsaMmwaveUnmetered = b.getBoolean(
- CarrierConfigManager.KEY_UNMETERED_NR_NSA_MMWAVE_BOOL);
- mNrNsaSub6Unmetered = b.getBoolean(
- CarrierConfigManager.KEY_UNMETERED_NR_NSA_SUB6_BOOL);
- mNrSaAllUnmetered = b.getBoolean(CarrierConfigManager.KEY_UNMETERED_NR_SA_BOOL);
- mNrSaMmwaveUnmetered = b.getBoolean(
- CarrierConfigManager.KEY_UNMETERED_NR_SA_MMWAVE_BOOL);
- mNrSaSub6Unmetered = b.getBoolean(
- CarrierConfigManager.KEY_UNMETERED_NR_SA_SUB6_BOOL);
- mNrNsaRoamingUnmetered = b.getBoolean(
- CarrierConfigManager.KEY_UNMETERED_NR_NSA_WHEN_ROAMING_BOOL);
- mLteEndcUsingUserDataForRrcDetection = b.getBoolean(
- CarrierConfigManager.KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL);
- }
- }
- updateLinkBandwidths(bandwidths, useLte);
- }
-
- public boolean getLteEndcUsingUserDataForIdleDetection() {
- return mLteEndcUsingUserDataForRrcDetection;
- }
-
- /**
- * Register for physical link status (i.e. RRC state) changed event.
- * if {@link CarrierConfigManager.KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL} is true,
- * then physical link state is focusing on "internet data connection" instead of RRC state.
- *
- * @param h The handler
- * @param what The event
- */
- public void registerForPhysicalLinkStatusChanged(Handler h, int what) {
- mDcc.registerForPhysicalLinkStatusChanged(h, what);
- }
-
- /**
- * Unregister from physical link status (i.e. RRC state) changed event.
- *
- * @param h The previously registered handler
- */
- public void unregisterForPhysicalLinkStatusChanged(Handler h) {
- mDcc.unregisterForPhysicalLinkStatusChanged(h);
- }
-
- // We use a specialized equals function in Apn setting when checking if an active
- // data connection is still legitimate to use against a different apn setting.
- // This method is extracted to a function to ensure that any future changes to this check will
- // be applied to both cleanUpConnectionsOnUpdatedApns and checkForCompatibleDataConnection.
- // Fix for b/158908392.
- private boolean areCompatible(ApnSetting apnSetting1, ApnSetting apnSetting2) {
- return apnSetting1.equals(apnSetting2,
- mPhone.getServiceState().getDataRoamingFromRegistration());
- }
-
- @NonNull
- private PersistableBundle getCarrierConfig() {
- CarrierConfigManager configManager = (CarrierConfigManager) mPhone.getContext()
- .getSystemService(Context.CARRIER_CONFIG_SERVICE);
- if (configManager != null) {
- // If an invalid subId is used, this bundle will contain default values.
- PersistableBundle config = configManager.getConfigForSubId(mPhone.getSubId());
- if (config != null) {
- return config;
- }
- }
- // Return static default defined in CarrierConfigManager.
- return CarrierConfigManager.getDefaultConfig();
- }
-
- /**
- * @return The data service manager.
- */
- public @NonNull DataServiceManager getDataServiceManager() {
- return mDataServiceManager;
- }
-
- /**
- * @return The data throttler
- */
- 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/README.txt b/src/java/com/android/internal/telephony/dataconnection/README.txt
deleted file mode 100644
index e613a00..0000000
--- a/src/java/com/android/internal/telephony/dataconnection/README.txt
+++ /dev/null
@@ -1,71 +0,0 @@
-This package contains classes used to manage a DataConnection.
-
-A criticial aspect of this class is that most objects in this
-package run on the same thread except DataConnectionTracker
-This makes processing efficient as it minimizes context
-switching and it eliminates issues with multi-threading.
-
-This can be done because all actions are either asynchronous
-or are known to be non-blocking and fast. At this time only
-DcTesterDeactivateAll takes specific advantage of this
-single threading knowledge by using Dcc#mDcListAll so be
-very careful when making changes that break this assumption.
-
-A related change was in DataConnectionAc I added code that
-checks to see if the caller is on a different thread. If
-it is then the AsyncChannel#sendMessageSynchronously is
-used. If the caller is on the same thread then a getter
-is used. This allows the DCAC to be used from any thread
-and was required to fix a bug when Dcc called
-PhoneBase#notifyDataConnection which calls DCT#getLinkProperties
-and DCT#getLinkCapabilities which call Dcc all on the same
-thread. Without this change there was a dead lock when
-sendMessageSynchronously blocks.
-
-
-== Testing ==
-
-The following are Intents that can be sent for testing pruproses on
-DEBUGGABLE builds (userdebug, eng)
-
-*) Causes bringUp and retry requests to fail for all DC's
-
- adb shell am broadcast -a com.android.internal.telephony.dataconnection.action_fail_bringup --ei counter 2 --ei fail_cause -3
-
-*) Causes all DC's to get torn down, simulating a temporary network outage:
-
- adb shell am broadcast -a com.android.internal.telephony.dataconnection.action_deactivate_all
-
-*) To simplify testing we also have detach and attach simulations below where {x} is gsm, cdma or sip
-
- adb shell am broadcast -a com.android.internal.telephony.{x}.action_detached
- adb shell am broadcast -a com.android.internal.telephony.{x}.action_attached
-
-
-== System properties for Testing ==
-
-On debuggable builds (userdebug, eng) you can change additional
-settings through system properties. These properties can be set with
-"setprop" for the current boot, or added to local.prop to persist
-across boots.
-
-device# setprop key value
-
-device# echo "key=value" >> /data/local.prop
-device# chmod 644 /data/local.prop
-
-
--- Retry configuration --
-
-You can replace the connection retry configuration. For example, you
-could change it to perform 4 retries at 5 second intervals:
-
-device# setprop test.data_retry_config "5000,5000,5000"
-
-
--- Roaming --
-
-You can force the telephony stack to always assume that it's roaming
-to verify higher-level framework functionality:
-
-device# setprop telephony.test.forceRoaming true
diff --git a/src/java/com/android/internal/telephony/dataconnection/TransportManager.java b/src/java/com/android/internal/telephony/dataconnection/TransportManager.java
deleted file mode 100644
index 63358f4..0000000
--- a/src/java/com/android/internal/telephony/dataconnection/TransportManager.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import android.annotation.Nullable;
-import android.os.Handler;
-import android.os.Message;
-import android.os.RegistrantList;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.Annotation.ApnType;
-import android.telephony.CarrierConfigManager;
-import android.telephony.data.ApnSetting;
-import android.util.LocalLog;
-import android.util.SparseIntArray;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.data.AccessNetworksManager;
-import com.android.internal.telephony.data.TelephonyNetworkFactory;
-import com.android.telephony.Rlog;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * This class represents the transport manager which manages available transports (i.e. WWAN or
- * WLAN) and determine the correct transport for {@link TelephonyNetworkFactory} to handle the data
- * requests.
- *
- * The device can operate in the following modes, which is stored in the system properties
- * ro.telephony.iwlan_operation_mode. If the system properties is missing, then it's tied to
- * IRadio version. For 1.4 or above, it's AP-assisted mdoe. For 1.3 or below, it's legacy mode.
- *
- * Legacy mode:
- * Frameworks send all data requests to the default data service, which is the cellular data
- * service. IWLAN should be still reported as a RAT on cellular network service.
- *
- * AP-assisted mode:
- * IWLAN is handled by IWLAN data service extending {@link android.telephony.data.DataService},
- * IWLAN network service extending {@link android.telephony.NetworkService}, and qualified
- * network service extending {@link android.telephony.data.QualifiedNetworksService}.
- *
- * The following settings for service package name need to be configured properly for
- * frameworks to bind.
- *
- * Package name of data service:
- * The resource overlay 'config_wlan_data_service_package' or,
- * the carrier config
- * {@link CarrierConfigManager#KEY_CARRIER_DATA_SERVICE_WLAN_PACKAGE_OVERRIDE_STRING}.
- * The carrier config takes precedence over the resource overlay if both exist.
- *
- * Package name of network service
- * The resource overlay 'config_wlan_network_service_package' or
- * the carrier config
- * {@link CarrierConfigManager#KEY_CARRIER_NETWORK_SERVICE_WLAN_PACKAGE_OVERRIDE_STRING}.
- * The carrier config takes precedence over the resource overlay if both exist.
- *
- * Package name of qualified network service
- * The resource overlay 'config_qualified_networks_service_package' or
- * the carrier config
- * {@link CarrierConfigManager#
- * KEY_CARRIER_QUALIFIED_NETWORKS_SERVICE_PACKAGE_OVERRIDE_STRING}.
- * The carrier config takes precedence over the resource overlay if both exist.
- */
-public class TransportManager extends Handler {
- private final String mLogTag;
-
- private static final int EVENT_QUALIFIED_NETWORKS_CHANGED = 1;
-
- private static final int EVENT_EVALUATE_TRANSPORT_PREFERENCE = 2;
-
- // Delay the re-evaluation if transport fall back. QNS will need to quickly change the
- // preference back to the original transport to avoid another handover request.
- private static final long FALL_BACK_REEVALUATE_DELAY_MILLIS = TimeUnit.SECONDS.toMillis(3);
-
- private final Phone mPhone;
-
- private final LocalLog mLocalLog = new LocalLog(64);
-
- @Nullable
- private AccessNetworksManager mAccessNetworksManager;
-
- /**
- * The pending handover list. This is a list of APNs that are being handover to the new
- * transport. The entry will be removed once handover is completed. The key
- * is the APN type, and the value is the target transport that the APN is handovered to.
- */
- private final SparseIntArray mPendingHandoverApns;
-
- /**
- * The registrants for listening data handover needed events.
- */
- private final RegistrantList mHandoverNeededEventRegistrants;
-
- /**
- * Handover parameters
- */
- @VisibleForTesting
- public static final class HandoverParams {
- /**
- * The callback for handover complete.
- */
- public interface HandoverCallback {
- /**
- * Called when handover is completed.
- *
- * @param success {@true} if handover succeeded, otherwise failed.
- * @param fallback {@true} if handover failed, the data connection fallback to the
- * original transport
- */
- void onCompleted(boolean success, boolean fallback);
- }
-
- public final @ApnType int apnType;
- public final int targetTransport;
- public final HandoverCallback callback;
-
- @VisibleForTesting
- public HandoverParams(int apnType, int targetTransport, HandoverCallback callback) {
- this.apnType = apnType;
- this.targetTransport = targetTransport;
- this.callback = callback;
- }
- }
-
- public TransportManager(Phone phone) {
- mPhone = phone;
- mPendingHandoverApns = new SparseIntArray();
- mHandoverNeededEventRegistrants = new RegistrantList();
- mLogTag = TransportManager.class.getSimpleName() + "-" + mPhone.getPhoneId();
- mAccessNetworksManager = mPhone.getAccessNetworksManager();
- mAccessNetworksManager.registerForQualifiedNetworksChanged(this,
- EVENT_QUALIFIED_NETWORKS_CHANGED);
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case EVENT_QUALIFIED_NETWORKS_CHANGED:
- if (!hasMessages(EVENT_EVALUATE_TRANSPORT_PREFERENCE)) {
- sendEmptyMessage(EVENT_EVALUATE_TRANSPORT_PREFERENCE);
- }
- break;
- case EVENT_EVALUATE_TRANSPORT_PREFERENCE:
- evaluateTransportPreference();
- break;
- default:
- loge("Unexpected event " + msg.what);
- break;
- }
- }
-
- /**
- * Set the current transport of apn type.
- *
- * @param apnType The APN type
- * @param transport The transport. Must be WWAN or WLAN.
- */
- private synchronized void setCurrentTransport(@ApnType int apnType, int transport) {
- mAccessNetworksManager.setCurrentTransport(apnType, transport);
- }
-
- private boolean isHandoverPending() {
- return mPendingHandoverApns.size() > 0;
- }
-
- /**
- * Evaluate the preferred transport for each APN type to see if handover is needed.
- */
- private void evaluateTransportPreference() {
- // Simultaneously handover is not supported today. Preference will be re-evaluated after
- // handover completed.
- if (isHandoverPending()) return;
- logl("evaluateTransportPreference");
- for (int apnType : AccessNetworksManager.SUPPORTED_APN_TYPES) {
- int targetTransport = mAccessNetworksManager.getPreferredTransport(apnType);
- if (targetTransport != mAccessNetworksManager.getCurrentTransport(apnType)) {
- logl("Handover started for APN type: "
- + ApnSetting.getApnTypeString(apnType)
- + ", target transport: "
- + AccessNetworkConstants.transportTypeToString(targetTransport));
- mPendingHandoverApns.put(apnType, targetTransport);
- mHandoverNeededEventRegistrants.notifyResult(
- new HandoverParams(apnType, targetTransport,
- (success, fallback) -> {
- // The callback for handover completed.
- if (success) {
- logl("Handover succeeded for APN type "
- + ApnSetting.getApnTypeString(apnType));
- } else {
- logl("APN type "
- + ApnSetting.getApnTypeString(apnType)
- + " handover to "
- + AccessNetworkConstants.transportTypeToString(
- targetTransport) + " failed"
- + ", fallback=" + fallback);
- }
-
- long delay = 0;
- if (fallback) {
- // No need to change the preference because we should
- // fallback. Re-evaluate after few seconds to give QNS
- // some time to change the preference back to the original
- // transport.
- delay = FALL_BACK_REEVALUATE_DELAY_MILLIS;
- } else {
- // If handover succeeds or failed without falling back
- // to the original transport, we should move to the new
- // transport (even if it is failed).
- setCurrentTransport(apnType, targetTransport);
- }
- mPendingHandoverApns.delete(apnType);
- sendEmptyMessageDelayed(EVENT_EVALUATE_TRANSPORT_PREFERENCE,
- delay);
- }));
-
- // Return here instead of processing the next APN type. The next APN type for
- // handover will be evaluate again once current handover is completed.
- return;
- }
- }
- }
-
- /**
- * Register for data handover needed event
- *
- * @param h The handler of the event
- * @param what The id of the event
- */
- public void registerForHandoverNeededEvent(Handler h, int what) {
- if (h != null) {
- mHandoverNeededEventRegistrants.addUnique(h, what, null);
- }
- }
-
- /**
- * Unregister for data handover needed event
- *
- * @param h The handler
- */
- public void unregisterForHandoverNeededEvent(Handler h) {
- mHandoverNeededEventRegistrants.remove(h);
- }
-
- /**
- * Registers the data throttler with DcTracker.
- */
- public void registerDataThrottler(DataThrottler dataThrottler) {
- if (mAccessNetworksManager != null) {
- mAccessNetworksManager.registerDataThrottler(dataThrottler);
- }
- }
-
- private void logl(String s) {
- log(s);
- mLocalLog.log(s);
- }
-
- private void log(String s) {
- Rlog.d(mLogTag, s);
- }
-
- private void loge(String s) {
- Rlog.e(mLogTag, s);
- }
-}
diff --git a/src/java/com/android/internal/telephony/gsm/SuppServiceNotification.java b/src/java/com/android/internal/telephony/gsm/SuppServiceNotification.java
index 41e76ae..396e94c 100644
--- a/src/java/com/android/internal/telephony/gsm/SuppServiceNotification.java
+++ b/src/java/com/android/internal/telephony/gsm/SuppServiceNotification.java
@@ -18,6 +18,8 @@
import android.telephony.PhoneNumberUtils;
+import java.util.Arrays;
+
/**
* Represents a Supplementary Service Notification received from the network.
*
@@ -200,7 +202,7 @@
+ (notificationType == 0 ? " originated " : " terminated ")
+ " code: " + code
+ " index: " + index
- + " history: " + history
+ + " history: " + Arrays.toString(history)
+ " \""
+ PhoneNumberUtils.stringFromStringAndTOA(number, type) + "\" ";
}
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java
index d19b8d3..b5c7da1 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java
@@ -41,7 +41,6 @@
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.PhoneNotifier;
-import com.android.internal.telephony.dataconnection.DataConnection;
import com.android.internal.telephony.uicc.IccFileHandler;
import com.android.telephony.Rlog;
@@ -174,11 +173,6 @@
}
@Override
- public PhoneConstants.DataState getDataConnectionState() {
- return PhoneConstants.DataState.DISCONNECTED;
- }
-
- @Override
public @DataActivityType int getDataActivityState() {
return TelephonyManager.DATA_ACTIVITY_NONE;
}
@@ -434,10 +428,6 @@
Message response) {
}
- public List<DataConnection> getCurrentDataConnectionList () {
- return null;
- }
-
@Override
public void updateServiceLocation() {
}
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
index 5968ba6..9b69cc9 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
@@ -65,6 +65,7 @@
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyLocalConnection;
import android.telephony.TelephonyManager;
+import android.telephony.TelephonyManager.DataEnabledChangedReason;
import android.telephony.emergency.EmergencyNumber;
import android.telephony.ims.ImsCallProfile;
import android.telephony.ims.ImsCallSession;
@@ -116,8 +117,6 @@
import com.android.internal.telephony.SubscriptionController;
import com.android.internal.telephony.d2d.RtpTransport;
import com.android.internal.telephony.data.DataSettingsManager;
-import com.android.internal.telephony.dataconnection.DataEnabledSettings;
-import com.android.internal.telephony.dataconnection.DataEnabledSettings.DataEnabledChangedReason;
import com.android.internal.telephony.emergency.EmergencyNumberTracker;
import com.android.internal.telephony.gsm.SuppServiceNotification;
import com.android.internal.telephony.imsphone.ImsPhone.ImsDialArgs;
@@ -965,8 +964,7 @@
}
};
- // TODO: make @NonNull after removing DataEnabledSettings
- private DataSettingsManager.DataSettingsManagerCallback mSettingsCallback;
+ private @NonNull DataSettingsManager.DataSettingsManagerCallback mSettingsCallback;
/**
* Allows the FeatureConnector used to be swapped for easier testing.
@@ -1060,39 +1058,14 @@
mPhone.getContext().registerReceiver(mReceiver, intentfilter);
updateCarrierConfiguration(mPhone.getSubId(), getCarrierConfigBundle(mPhone.getSubId()));
- if (mPhone.getDefaultPhone().isUsingNewDataStack()) {
- mSettingsCallback = new DataSettingsManager.DataSettingsManagerCallback(this::post) {
- @Override
- public void onDataEnabledChanged(boolean enabled,
- @TelephonyManager.DataEnabledChangedReason int reason,
- @NonNull String callingPackage) {
- int internalReason;
- switch (reason) {
- case TelephonyManager.DATA_ENABLED_REASON_USER:
- internalReason = DataEnabledSettings.REASON_USER_DATA_ENABLED;
- break;
- case TelephonyManager.DATA_ENABLED_REASON_POLICY:
- internalReason = DataEnabledSettings.REASON_POLICY_DATA_ENABLED;
- break;
- case TelephonyManager.DATA_ENABLED_REASON_CARRIER:
- internalReason = DataEnabledSettings.REASON_DATA_ENABLED_BY_CARRIER;
- break;
- case TelephonyManager.DATA_ENABLED_REASON_THERMAL:
- internalReason = DataEnabledSettings.REASON_THERMAL_DATA_ENABLED;
- break;
- case TelephonyManager.DATA_ENABLED_REASON_OVERRIDE:
- internalReason = DataEnabledSettings.REASON_OVERRIDE_RULE_CHANGED;
- break;
- default:
- internalReason = DataEnabledSettings.REASON_INTERNAL_DATA_ENABLED;
- }
- ImsPhoneCallTracker.this.onDataEnabledChanged(enabled, internalReason);
- }};
- mPhone.getDefaultPhone().getDataSettingsManager().registerCallback(mSettingsCallback);
- } else {
- mPhone.getDefaultPhone().getDataEnabledSettings().registerForDataEnabledChanged(
- this, EVENT_DATA_ENABLED_CHANGED, null);
- }
+ mSettingsCallback = new DataSettingsManager.DataSettingsManagerCallback(this::post) {
+ @Override
+ public void onDataEnabledChanged(boolean enabled,
+ @DataEnabledChangedReason int reason,
+ @NonNull String callingPackage) {
+ ImsPhoneCallTracker.this.onDataEnabledChanged(enabled, reason);
+ }};
+ mPhone.getDefaultPhone().getDataSettingsManager().registerCallback(mSettingsCallback);
final TelecomManager telecomManager =
(TelecomManager) mPhone.getContext().getSystemService(Context.TELECOM_SERVICE);
@@ -1335,11 +1308,7 @@
clearDisconnected();
mPhone.getContext().unregisterReceiver(mReceiver);
- if (mPhone.getDefaultPhone().isUsingNewDataStack()) {
- mPhone.getDefaultPhone().getDataSettingsManager().unregisterCallback(mSettingsCallback);
- } else {
- mPhone.getDefaultPhone().getDataEnabledSettings().unregisterForDataEnabledChanged(this);
- }
+ mPhone.getDefaultPhone().getDataSettingsManager().unregisterCallback(mSettingsCallback);
mImsManagerConnector.disconnect();
final NetworkStatsManager statsManager =
@@ -2735,6 +2704,9 @@
mPendingMO.finalize();
mPendingMO = null;
}
+ // Ensure aggregate state for this tracker is also updated to reflect the new state.
+ updatePhoneState();
+ mPhone.notifyPreciseCallStateChanged();
}
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -2858,7 +2830,7 @@
private void maybeSetVideoCallProvider(ImsPhoneConnection conn, ImsCall imsCall) {
android.telecom.Connection.VideoProvider connVideoProvider = conn.getVideoProvider();
- ImsCallSession callSession = imsCall.getCallSession();
+ ImsCallSession callSession = imsCall.getCallSession();
if (connVideoProvider != null || callSession == null
|| callSession.getVideoCallProvider() == null) {
return;
@@ -3889,15 +3861,11 @@
@Override
public void onCallHandover(ImsCall imsCall, int srcAccessTech, int targetAccessTech,
ImsReasonInfo reasonInfo) {
- // Check with the DCTracker to see if data is enabled; there may be a case when
+ // Check if data is enabled; there may be a case when
// ImsPhoneCallTracker isn't being informed of the right data enabled state via its
// registration, so we'll refresh now.
boolean isDataEnabled;
- if (mPhone.getDefaultPhone().isUsingNewDataStack()) {
- isDataEnabled = mPhone.getDefaultPhone().getDataSettingsManager().isDataEnabled();
- } else {
- isDataEnabled = mPhone.getDefaultPhone().getDataEnabledSettings().isDataEnabled();
- }
+ isDataEnabled = mPhone.getDefaultPhone().getDataSettingsManager().isDataEnabled();
if (DBG) {
log("onCallHandover :: srcAccessTech=" + srcAccessTech + ", targetAccessTech="
@@ -5076,10 +5044,9 @@
/**
* Handler of data enabled changed event
* @param enabled True if data is enabled, otherwise disabled.
- * @param reason Reason for data enabled/disabled. See {@link DataEnabledChangedReason}.
+ * @param reason Reason for data enabled/disabled.
*/
private void onDataEnabledChanged(boolean enabled, @DataEnabledChangedReason int reason) {
- // TODO: TelephonyManager.DataEnabledChangedReason instead once DataEnabledSettings is gone
log("onDataEnabledChanged: enabled=" + enabled + ", reason=" + reason);
mIsDataEnabled = enabled;
@@ -5099,9 +5066,9 @@
}
int reasonCode;
- if (reason == DataEnabledSettings.REASON_POLICY_DATA_ENABLED) {
+ if (reason == TelephonyManager.DATA_ENABLED_REASON_POLICY) {
reasonCode = ImsReasonInfo.CODE_DATA_LIMIT_REACHED;
- } else if (reason == DataEnabledSettings.REASON_USER_DATA_ENABLED) {
+ } else if (reason == TelephonyManager.DATA_ENABLED_REASON_USER) {
reasonCode = ImsReasonInfo.CODE_DATA_DISABLED;
} else {
// Unexpected code, default to data disabled.
@@ -5114,10 +5081,10 @@
// Handle video state changes required as a result of data being enabled/disabled.
handleDataEnabledChange(enabled, reasonCode);
- // We do not want to update the ImsConfig for REASON_REGISTERED, since it can happen before
+ // We do not want to update the ImsConfig for REASON_UNKNOWN, since it can happen before
// the carrier config has loaded and will deregister IMS.
if (!mShouldUpdateImsConfigOnDisconnect
- && reason != DataEnabledSettings.REASON_REGISTERED
+ && reason != TelephonyManager.DATA_ENABLED_REASON_UNKNOWN
&& mCarrierConfigLoadedForSubscription) {
// This will call into updateVideoCallFeatureValue and eventually all clients will be
// asynchronously notified that the availability of VT over LTE has changed.
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
index c60a4db..68de4a3 100755
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
@@ -1166,17 +1166,24 @@
*/
public void startRtt(android.telecom.Connection.RttTextStream textStream) {
ImsCall imsCall = getImsCall();
- if (imsCall != null) {
- getImsCall().sendRttModifyRequest(true);
- setCurrentRttTextStream(textStream);
+ if (imsCall == null) {
+ Rlog.w(LOG_TAG, "startRtt failed, imsCall is null");
+ return;
}
+ imsCall.sendRttModifyRequest(true);
+ setCurrentRttTextStream(textStream);
}
/**
* Terminate the current RTT session.
*/
public void stopRtt() {
- getImsCall().sendRttModifyRequest(false);
+ ImsCall imsCall = getImsCall();
+ if (imsCall == null) {
+ Rlog.w(LOG_TAG, "stopRtt failed, imsCall is null");
+ return;
+ }
+ imsCall.sendRttModifyRequest(false);
}
/**
@@ -1188,14 +1195,15 @@
public void sendRttModifyResponse(android.telecom.Connection.RttTextStream textStream) {
boolean accept = textStream != null;
ImsCall imsCall = getImsCall();
-
- if (imsCall != null) {
- imsCall.sendRttModifyResponse(accept);
- if (accept) {
- setCurrentRttTextStream(textStream);
- } else {
- Rlog.e(LOG_TAG, "sendRttModifyResponse: foreground call has no connections");
- }
+ if (imsCall == null) {
+ Rlog.w(LOG_TAG, "sendRttModifyResponse failed, imsCall is null");
+ return;
+ }
+ imsCall.sendRttModifyResponse(accept);
+ if (accept) {
+ setCurrentRttTextStream(textStream);
+ } else {
+ Rlog.e(LOG_TAG, "sendRttModifyResponse: foreground call has no connections");
}
}
@@ -1276,6 +1284,8 @@
ImsCall imsCall = getImsCall();
if (imsCall != null) {
imsCall.sendRttMessage(message);
+ } else {
+ Rlog.w(LOG_TAG, "createRttTextHandler: imsCall is null");
}
});
mRttTextHandler.initialize(mRttTextStream);
diff --git a/src/java/com/android/internal/telephony/metrics/DataStallRecoveryStats.java b/src/java/com/android/internal/telephony/metrics/DataStallRecoveryStats.java
index 5ade0bb..77e758b 100644
--- a/src/java/com/android/internal/telephony/metrics/DataStallRecoveryStats.java
+++ b/src/java/com/android/internal/telephony/metrics/DataStallRecoveryStats.java
@@ -26,7 +26,6 @@
import com.android.internal.telephony.SubscriptionController;
import com.android.internal.telephony.TelephonyStatsLog;
import com.android.internal.telephony.data.DataStallRecoveryManager;
-import com.android.internal.telephony.dataconnection.DcTracker;
/** Generates metrics related to data stall recovery events per phone ID for the pushed atom. */
public class DataStallRecoveryStats {
@@ -41,42 +40,6 @@
private static final int RECOVERY_ACTION_RADIO_RESTART_MAPPING = 3;
private static final int RECOVERY_ACTION_RESET_MODEM_MAPPING = 4;
-
- /** TODO: b/214044479 : Remove this function when new data design(Android T) start. */
- public static void onDataStallEvent(
- @DcTracker.RecoveryAction int recoveryAction,
- Phone phone,
- boolean isRecovered,
- int durationMillis) {
- if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) {
- phone = phone.getDefaultPhone();
- }
-
- int carrierId = phone.getCarrierId();
- int rat = getRat(phone);
- int band =
- (rat == TelephonyManager.NETWORK_TYPE_IWLAN) ? 0 : ServiceStateStats.getBand(phone);
- // the number returned here matches the SignalStrength enum we have
- int signalStrength = phone.getSignalStrength().getLevel();
- boolean isOpportunistic = getIsOpportunistic(phone);
- boolean isMultiSim = SimSlotState.getCurrentState().numActiveSims > 1;
-
- // Not use this field in Android S, so we send RECOVERED_REASON_NONE for default value.
- int recoveryReason = 0;
- TelephonyStatsLog.write(
- TelephonyStatsLog.DATA_STALL_RECOVERY_REPORTED,
- carrierId,
- rat,
- signalStrength,
- recoveryAction,
- isOpportunistic,
- isMultiSim,
- band,
- isRecovered,
- durationMillis,
- recoveryReason);
- }
-
/**
* Called when data stall happened.
*
diff --git a/src/java/com/android/internal/telephony/metrics/MetricsCollector.java b/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
index a44cf19..2b4019c 100644
--- a/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
+++ b/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
@@ -48,6 +48,7 @@
import static com.android.internal.telephony.TelephonyStatsLog.UCE_EVENT_STATS;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_RAT_USAGE;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION;
+import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN;
import android.app.StatsManager;
import android.content.Context;
@@ -474,8 +475,7 @@
return StatsManager.PULL_SKIP;
}
- data.add(TelephonyStatsLog.buildStatsEvent(DEVICE_TELEPHONY_PROPERTIES,
- phones[0].isUsingNewDataStack()));
+ data.add(TelephonyStatsLog.buildStatsEvent(DEVICE_TELEPHONY_PROPERTIES, true));
return StatsManager.PULL_SUCCESS;
}
@@ -731,7 +731,8 @@
session.bearerAtStart,
session.bearerAtEnd,
session.direction,
- session.setupDuration,
+ // deprecated and replaced by setupDurationMillis
+ VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN,
session.setupFailed,
session.disconnectReasonCode,
session.disconnectExtraCode,
diff --git a/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java b/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
index d700831..7d68ae1 100644
--- a/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
+++ b/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
@@ -33,16 +33,6 @@
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_SUPER_WIDEBAND;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_UNKNOWN;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_WIDEBAND;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_SLOW;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_FAST;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_NORMAL;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_SLOW;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_ULTRA_FAST;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_ULTRA_SLOW;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_UNKNOWN;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_VERY_FAST;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_VERY_SLOW;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SIGNAL_STRENGTH_AT_END__SIGNAL_STRENGTH_GREAT;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SIGNAL_STRENGTH_AT_END__SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
@@ -127,9 +117,6 @@
/** Holds the audio codec value for IMS calls. */
private static final SparseIntArray IMS_CODEC_MAP = buildImsCodecMap();
- /** Holds setup duration buckets with values as their upper bounds in milliseconds. */
- private static final SparseIntArray CALL_SETUP_DURATION_MAP = buildCallSetupDurationMap();
-
/** Holds call duration buckets with values as their upper bounds in milliseconds. */
private static final SparseIntArray CALL_DURATION_MAP = buildCallDurationMap();
@@ -414,7 +401,6 @@
logd("acceptCall: resetting setup info, connectionId=%d", id);
VoiceCallSession proto = mCallProtos.get(id);
proto.setupBeginMillis = getTimeMillis();
- proto.setupDuration = VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_UNKNOWN;
} else {
loge("acceptCall: untracked connection, connectionId=%d", id);
}
@@ -443,7 +429,6 @@
proto.bearerAtStart = bearer;
proto.bearerAtEnd = bearer;
proto.direction = getDirection(conn);
- proto.setupDuration = VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_UNKNOWN;
proto.setupFailed = true;
proto.disconnectReasonCode = conn.getDisconnectCause();
proto.disconnectExtraCode = conn.getPreciseDisconnectCause();
@@ -588,7 +573,6 @@
private void checkCallSetup(Connection conn, VoiceCallSession proto) {
if (proto.setupBeginMillis != 0L && isSetupFinished(conn.getCall())) {
proto.setupDurationMillis = (int) (getTimeMillis() - proto.setupBeginMillis);
- proto.setupDuration = classifySetupDuration(proto.setupDurationMillis);
proto.setupBeginMillis = 0L;
}
// Clear setupFailed if call now active, but otherwise leave it unchanged
@@ -800,16 +784,6 @@
}
}
- private static int classifySetupDuration(int durationMillis) {
- // keys in CALL_SETUP_DURATION_MAP are upper bounds in ascending order
- for (int i = 0; i < CALL_SETUP_DURATION_MAP.size(); i++) {
- if (durationMillis < CALL_SETUP_DURATION_MAP.keyAt(i)) {
- return CALL_SETUP_DURATION_MAP.valueAt(i);
- }
- }
- return VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_SLOW;
- }
-
private static int classifyCallDuration(long durationMillis) {
if (durationMillis == 0L) {
return VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN;
@@ -888,41 +862,6 @@
return map;
}
- private static SparseIntArray buildCallSetupDurationMap() {
- SparseIntArray map = new SparseIntArray();
-
- map.put(
- CALL_SETUP_DURATION_UNKNOWN,
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_UNKNOWN);
- map.put(
- CALL_SETUP_DURATION_EXTREMELY_FAST,
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST);
- map.put(
- CALL_SETUP_DURATION_ULTRA_FAST,
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_ULTRA_FAST);
- map.put(
- CALL_SETUP_DURATION_VERY_FAST,
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_VERY_FAST);
- map.put(
- CALL_SETUP_DURATION_FAST,
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_FAST);
- map.put(
- CALL_SETUP_DURATION_NORMAL,
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_NORMAL);
- map.put(
- CALL_SETUP_DURATION_SLOW,
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_SLOW);
- map.put(
- CALL_SETUP_DURATION_VERY_SLOW,
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_VERY_SLOW);
- map.put(
- CALL_SETUP_DURATION_ULTRA_SLOW,
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_ULTRA_SLOW);
- // anything above would be CALL_SETUP_DURATION_EXTREMELY_SLOW
-
- return map;
- }
-
private static SparseIntArray buildCallDurationMap() {
SparseIntArray map = new SparseIntArray();
diff --git a/src/java/com/android/internal/telephony/nitz/OWNERS b/src/java/com/android/internal/telephony/nitz/OWNERS
new file mode 100644
index 0000000..be0513d
--- /dev/null
+++ b/src/java/com/android/internal/telephony/nitz/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 847766
+include platform/frameworks/base:/services/core/java/com/android/server/timezonedetector/OWNERS
diff --git a/src/java/com/android/internal/telephony/uicc/AdnCapacity.java b/src/java/com/android/internal/telephony/uicc/AdnCapacity.java
index 479786c..f2cab4f 100644
--- a/src/java/com/android/internal/telephony/uicc/AdnCapacity.java
+++ b/src/java/com/android/internal/telephony/uicc/AdnCapacity.java
@@ -110,6 +110,21 @@
return mMaxAdnCount > 0;
}
+ @Override
+ public String toString() {
+ String capacity = "getAdnRecordsCapacity : max adn=" + mMaxAdnCount
+ + ", used adn=" + mUsedAdnCount
+ + ", max email=" + mMaxEmailCount
+ + ", used email=" + mUsedEmailCount
+ + ", max anr=" + mMaxAnrCount
+ + ", used anr=" + mUsedAnrCount
+ + ", max name length=" + mMaxNameLength
+ + ", max number length =" + mMaxNumberLength
+ + ", max email length =" + mMaxEmailLength
+ + ", max anr length =" + mMaxAnrLength;
+ return capacity;
+ }
+
public static final Parcelable.Creator<AdnCapacity> CREATOR
= new Parcelable.Creator<AdnCapacity>() {
@Override
diff --git a/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java b/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java
index 1fe6223..12284af 100644
--- a/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java
@@ -67,9 +67,9 @@
return "IsimUiccRecords: " + super.toString()
+ (DUMP_RECORDS ? (" mIsimImpi=" + mIsimImpi
+ " mIsimDomain=" + mIsimDomain
- + " mIsimImpu=" + mIsimImpu
+ + " mIsimImpu=" + Arrays.toString(mIsimImpu)
+ " mIsimIst=" + mIsimIst
- + " mIsimPcscf=" + mIsimPcscf) : "");
+ + " mIsimPcscf=" + Arrays.toString(mIsimPcscf)) : "");
}
public IsimUiccRecords(UiccCardApplication app, Context c, CommandsInterface ci) {
@@ -437,7 +437,7 @@
pw.println(" mIsimDomain=" + mIsimDomain);
pw.println(" mIsimImpu[]=" + Arrays.toString(mIsimImpu));
pw.println(" mIsimIst" + mIsimIst);
- pw.println(" mIsimPcscf" + mIsimPcscf);
+ pw.println(" mIsimPcscf" + Arrays.toString(mIsimPcscf));
}
pw.flush();
}
diff --git a/src/java/com/android/internal/telephony/uicc/RuimRecords.java b/src/java/com/android/internal/telephony/uicc/RuimRecords.java
index f905bdc..08c1573 100755
--- a/src/java/com/android/internal/telephony/uicc/RuimRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/RuimRecords.java
@@ -81,8 +81,8 @@
+ " mMyMobileNumber=" + "xxxx"
+ " mMin2Min1=" + mMin2Min1
+ " mPrlVersion=" + mPrlVersion
- + " mEFpl=" + mEFpl
- + " mEFli=" + mEFli
+ + " mEFpl=" + IccUtils.bytesToHexString(mEFpl)
+ + " mEFli=" + IccUtils.bytesToHexString(mEFli)
+ " mCsimSpnDisplayCondition=" + mCsimSpnDisplayCondition
+ " mMdn=" + mMdn
+ " mMin=" + mMin
diff --git a/src/java/com/android/internal/telephony/uicc/SIMRecords.java b/src/java/com/android/internal/telephony/uicc/SIMRecords.java
index 9958bfb..b6032ec 100644
--- a/src/java/com/android/internal/telephony/uicc/SIMRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/SIMRecords.java
@@ -102,12 +102,12 @@
+ " mVmConfig" + mVmConfig
+ " callForwardingEnabled=" + mCallForwardingStatus
+ " spnState=" + mSpnState
- + " mCphsInfo=" + mCphsInfo
+ + " mCphsInfo=" + IccUtils.bytesToHexString(mCphsInfo)
+ " mCspPlmnEnabled=" + mCspPlmnEnabled
- + " efMWIS=" + mEfMWIS
- + " efCPHS_MWI=" + mEfCPHS_MWI
- + " mEfCff=" + mEfCff
- + " mEfCfis=" + mEfCfis
+ + " efMWIS=" + IccUtils.bytesToHexString(mEfMWIS)
+ + " efCPHS_MWI=" + IccUtils.bytesToHexString(mEfCPHS_MWI)
+ + " mEfCff=" + IccUtils.bytesToHexString(mEfCff)
+ + " mEfCfis=" + IccUtils.bytesToHexString(mEfCfis)
+ " getOperatorNumeric=" + getOperatorNumeric();
}
@@ -1970,7 +1970,7 @@
// Byte 5 and 6 are for lacTacEnd.
// Byte 7 is for PNN Record Identifier.
if (data.length != 8) {
- loge("Invalid length for OPL record " + data);
+ loge("Invalid length for OPL record " + IccUtils.bytesToHexString(data));
continue;
}
@@ -2118,14 +2118,14 @@
pw.println(" mVmConfig=" + mVmConfig);
pw.println(" mCallForwardingStatus=" + mCallForwardingStatus);
pw.println(" mSpnState=" + mSpnState);
- pw.println(" mCphsInfo=" + mCphsInfo);
+ pw.println(" mCphsInfo=" + IccUtils.bytesToHexString(mCphsInfo));
pw.println(" mCspPlmnEnabled=" + mCspPlmnEnabled);
pw.println(" mEfMWIS[]=" + Arrays.toString(mEfMWIS));
pw.println(" mEfCPHS_MWI[]=" + Arrays.toString(mEfCPHS_MWI));
pw.println(" mEfCff[]=" + Arrays.toString(mEfCff));
pw.println(" mEfCfis[]=" + Arrays.toString(mEfCfis));
pw.println(" mCarrierNameDisplayCondition=" + mCarrierNameDisplayCondition);
- pw.println(" mSpdi[]=" + mSpdi);
+ pw.println(" mSpdi[]=" + Arrays.toString(mSpdi));
pw.println(" mUsimServiceTable=" + mUsimServiceTable);
pw.println(" mGid1=" + mGid1);
if (mCarrierTestOverride.isInTestMode()) {
diff --git a/src/java/com/android/internal/telephony/uicc/SimPhonebookRecordCache.java b/src/java/com/android/internal/telephony/uicc/SimPhonebookRecordCache.java
index e06e008..149e605 100644
--- a/src/java/com/android/internal/telephony/uicc/SimPhonebookRecordCache.java
+++ b/src/java/com/android/internal/telephony/uicc/SimPhonebookRecordCache.java
@@ -442,17 +442,20 @@
if (!newCapacity.isSimEmpty()){
mIsCacheInvalidated.set(true);
fillCacheWithoutWaiting();
- } else {
+ } else if (newCapacity.isSimValid()) {
notifyAdnLoadingWaiters();
+ tryFireUpdatePendingList();
+ } else {
+ logd("ADN capacity is invalid");
}
mIsInitialized.set(true); // Let's say the whole process is ready
} else {
// There is nothing from PB, so notify waiters directly if any
- if (newCapacity.isSimEmpty()
- || !newCapacity.isSimValid()) {
+ if (newCapacity.isSimValid() && newCapacity.isSimEmpty()) {
mIsCacheInvalidated.set(false);
notifyAdnLoadingWaiters();
- } else if (!mIsUpdateDone) {
+ tryFireUpdatePendingList();
+ } else if (!mIsUpdateDone && !newCapacity.isSimEmpty()) {
invalidateSimPbCache();
fillCacheWithoutWaiting();
}
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
index 08521e6..7d87e5f 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
@@ -495,7 +495,8 @@
}
} else {
if (mAIDInUse == ARAM) {
- String errorMsg = "Invalid response: payload=" + response.payload
+ String errorMsg = "Invalid response: payload="
+ + IccUtils.bytesToHexString(response.payload)
+ " sw1=" + response.sw1 + " sw2=" + response.sw2;
updateState(STATE_ERROR, errorMsg);
}
diff --git a/src/java/com/android/internal/telephony/uicc/euicc/EuiccPort.java b/src/java/com/android/internal/telephony/uicc/euicc/EuiccPort.java
index 45bc06d..639915a 100644
--- a/src/java/com/android/internal/telephony/uicc/euicc/EuiccPort.java
+++ b/src/java/com/android/internal/telephony/uicc/euicc/EuiccPort.java
@@ -995,15 +995,17 @@
}
String devCap = split[0].trim();
- Integer version;
+ String[] fullVer = (split[1].trim()).split("\\.");
+ Integer version, subVersion = 0;
try {
- version = Integer.parseInt(split[1].trim());
+ version = Integer.parseInt(fullVer[0]);
+ if (fullVer.length > 1) subVersion = Integer.parseInt(fullVer[1]);
} catch (NumberFormatException e) {
loge("Invalid device capability version number.", e);
return;
}
- byte[] versionBytes = new byte[] { version.byteValue(), 0, 0 };
+ byte[] versionBytes = new byte[] { version.byteValue(), subVersion.byteValue(), 0 };
switch (devCap) {
case DEV_CAP_GSM:
devCapBuilder.addChildAsBytes(Tags.TAG_CTX_0, versionBytes);
diff --git a/tests/telephonytests/Android.bp b/tests/telephonytests/Android.bp
index f197101..2aa446d 100644
--- a/tests/telephonytests/Android.bp
+++ b/tests/telephonytests/Android.bp
@@ -48,6 +48,7 @@
test_suites: [
"device-tests",
],
+ min_sdk_version: "29",
}
genrule {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierActionAgentTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierActionAgentTest.java
index 7727e79..4f91994 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierActionAgentTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierActionAgentTest.java
@@ -92,6 +92,7 @@
final Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE,
IccCardConstants.INTENT_VALUE_ICC_LOADED);
+ intent.putExtra(PhoneConstants.PHONE_KEY, mPhone.getPhoneId());
mContext.sendBroadcast(intent);
processAllMessages();
@@ -134,6 +135,7 @@
final Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE,
IccCardConstants.INTENT_VALUE_ICC_LOADED);
+ intent.putExtra(PhoneConstants.PHONE_KEY, mPhone.getPhoneId());
mContext.sendBroadcast(intent);
processAllMessages();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java
index 33a8e62..f0c43be 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java
@@ -42,6 +42,9 @@
import com.android.internal.telephony.PhoneInternalInterface.DialArgs;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@@ -109,7 +112,9 @@
processAllMessages();
} catch(Exception ex) {
ex.printStackTrace();
- Assert.fail("unexpected exception thrown"+ex.getMessage()+ex.getStackTrace());
+ StringWriter exString = new StringWriter();
+ ex.printStackTrace(new PrintWriter(exString));
+ Assert.fail("unexpected exception thrown" + exString);
}
assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState());
diff --git a/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
index 5af1c1f..fb7b64d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
@@ -55,7 +55,7 @@
import androidx.test.InstrumentationRegistry;
-import com.android.internal.telephony.dataconnection.DataEnabledSettings;
+import com.android.internal.telephony.data.DataSettingsManager;
import org.junit.After;
import org.junit.Assert;
@@ -75,8 +75,8 @@
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class MultiSimSettingControllerTest extends TelephonyTest {
- private static final int SINGLE_SIM = 1;
private static final int DUAL_SIM = 2;
+ private static final String PHONE_PACKAGE = "com.android.internal.telephony";
private MultiSimSettingController mMultiSimSettingControllerUT;
private Phone[] mPhones;
private ParcelUuid mGroupUuid1 = new ParcelUuid(UUID.randomUUID());
@@ -85,8 +85,8 @@
private SubscriptionController mSubControllerMock;
private Phone mPhoneMock1;
private Phone mPhoneMock2;
- private DataEnabledSettings mDataEnabledSettingsMock1;
- private DataEnabledSettings mDataEnabledSettingsMock2;
+ private DataSettingsManager mDataSettingsManagerMock1;
+ private DataSettingsManager mDataSettingsManagerMock2;
private CommandsInterface mMockCi;
@@ -118,8 +118,8 @@
mSubControllerMock = mock(SubscriptionController.class);
mPhoneMock1 = mock(Phone.class);
mPhoneMock2 = mock(Phone.class);
- mDataEnabledSettingsMock1 = mock(DataEnabledSettings.class);
- mDataEnabledSettingsMock2 = mock(DataEnabledSettings.class);
+ mDataSettingsManagerMock1 = mock(DataSettingsManager.class);
+ mDataSettingsManagerMock2 = mock(DataSettingsManager.class);
mMockCi = mock(CommandsInterface.class);
// Default configuration:
// DSDS device.
@@ -145,8 +145,8 @@
doReturn(new int[]{1, 2}).when(mSubControllerMock).getActiveSubIdList(anyBoolean());
mPhones = new Phone[] {mPhoneMock1, mPhoneMock2};
- doReturn(mDataEnabledSettingsMock1).when(mPhoneMock1).getDataEnabledSettings();
- doReturn(mDataEnabledSettingsMock2).when(mPhoneMock2).getDataEnabledSettings();
+ doReturn(mDataSettingsManagerMock1).when(mPhoneMock1).getDataSettingsManager();
+ doReturn(mDataSettingsManagerMock2).when(mPhoneMock2).getDataSettingsManager();
doReturn(Arrays.asList(mSubInfo1)).when(mSubControllerMock).getSubInfo(
eq(SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID + "=" + 1), any());
@@ -385,8 +385,8 @@
mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0, 1);
mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 2);
processAllMessages();
- verify(mDataEnabledSettingsMock2).setDataEnabled(
- TelephonyManager.DATA_ENABLED_REASON_USER, false);
+ verify(mDataSettingsManagerMock2).setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE);
// Enable on non-default sub should trigger setDefaultDataSubId.
mMultiSimSettingControllerUT.notifyUserDataEnabled(2, true);
@@ -397,8 +397,8 @@
doReturn(2).when(mSubControllerMock).getDefaultDataSubId();
mMultiSimSettingControllerUT.notifyDefaultDataSubChanged();
processAllMessages();
- verify(mDataEnabledSettingsMock1).setDataEnabled(
- TelephonyManager.DATA_ENABLED_REASON_USER, false);
+ verify(mDataSettingsManagerMock1).setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE);
doReturn(1).when(mSubControllerMock).getDefaultDataSubId();
doReturn(1).when(mSubControllerMock).getDefaultSmsSubId();
@@ -440,10 +440,10 @@
mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0, 1);
mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 2);
processAllMessages();
- verify(mDataEnabledSettingsMock1).setDataEnabled(
- TelephonyManager.DATA_ENABLED_REASON_USER, false);
- verify(mDataEnabledSettingsMock2).setDataEnabled(
- TelephonyManager.DATA_ENABLED_REASON_USER, false);
+ verify(mDataSettingsManagerMock1).setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE);
+ verify(mDataSettingsManagerMock2).setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE);
// as a result of the above calls, update new values to be returned
doReturn(false).when(mPhoneMock1).isUserDataEnabled();
@@ -458,8 +458,10 @@
doReturn(2).when(mSubControllerMock).getDefaultDataSubId();
mMultiSimSettingControllerUT.notifyDefaultDataSubChanged();
processAllMessages();
- verify(mDataEnabledSettingsMock1, times(1)).setDataEnabled(anyInt(), anyBoolean());
- verify(mDataEnabledSettingsMock2, times(1)).setDataEnabled(anyInt(), anyBoolean());
+ verify(mDataSettingsManagerMock1, times(1))
+ .setDataEnabled(anyInt(), anyBoolean(), anyString());
+ verify(mDataSettingsManagerMock2, times(1))
+ .setDataEnabled(anyInt(), anyBoolean(), anyString());
}
@Test
@@ -478,10 +480,10 @@
mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0, 1);
mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 2);
processAllMessages();
- verify(mDataEnabledSettingsMock1).setDataEnabled(
- TelephonyManager.DATA_ENABLED_REASON_USER, false);
- verify(mDataEnabledSettingsMock2).setDataEnabled(
- TelephonyManager.DATA_ENABLED_REASON_USER, false);
+ verify(mDataSettingsManagerMock1).setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE);
+ verify(mDataSettingsManagerMock2).setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE);
// as a result of the above calls, update new values to be returned
doReturn(false).when(mPhoneMock1).isUserDataEnabled();
@@ -529,8 +531,8 @@
doReturn(1).when(mSubControllerMock).getDefaultDataSubId();
mMultiSimSettingControllerUT.notifyDefaultDataSubChanged();
processAllMessages();
- verify(mDataEnabledSettingsMock2).setDataEnabled(
- TelephonyManager.DATA_ENABLED_REASON_USER, false);
+ verify(mDataSettingsManagerMock2).setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE);
mMultiSimSettingControllerUT.notifyUserDataEnabled(2, false);
processAllMessages();
assertFalse(GlobalSettingsHelper.getBoolean(
@@ -578,13 +580,13 @@
mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 2);
processAllMessages();
verify(mSubControllerMock).setDefaultDataSubId(2);
- verify(mDataEnabledSettingsMock1, never()).setDataEnabled(
- anyInt(), anyBoolean());
+ verify(mDataSettingsManagerMock1, never()).setDataEnabled(
+ anyInt(), anyBoolean(), anyString());
verifyDismissIntentSent();
clearInvocations(mSubControllerMock);
- clearInvocations(mDataEnabledSettingsMock1);
- clearInvocations(mDataEnabledSettingsMock2);
+ clearInvocations(mDataSettingsManagerMock1);
+ clearInvocations(mDataSettingsManagerMock2);
doReturn(2).when(mSubControllerMock).getDefaultDataSubId();
// Toggle data on sub 1 or sub 2. Nothing should happen as they are independent.
mMultiSimSettingControllerUT.notifyUserDataEnabled(1, false);
@@ -595,10 +597,10 @@
mMultiSimSettingControllerUT.notifyUserDataEnabled(2, true);
processAllMessages();
verify(mSubControllerMock, never()).setDefaultDataSubId(anyInt());
- verify(mDataEnabledSettingsMock1, never()).setDataEnabled(
- eq(TelephonyManager.DATA_ENABLED_REASON_USER), anyBoolean());
- verify(mDataEnabledSettingsMock2, never()).setDataEnabled(
- TelephonyManager.DATA_ENABLED_REASON_USER, false);
+ verify(mDataSettingsManagerMock1, never()).setDataEnabled(
+ eq(TelephonyManager.DATA_ENABLED_REASON_USER), anyBoolean(), anyString());
+ verify(mDataSettingsManagerMock2, never()).setDataEnabled(
+ eq(TelephonyManager.DATA_ENABLED_REASON_USER), eq(false), anyString());
}
private void verifyDismissIntentSent() {
@@ -636,7 +638,8 @@
mMultiSimSettingControllerUT.notifySubscriptionGroupChanged(mGroupUuid1);
processAllMessages();
// This should result in setting sync.
- verify(mDataEnabledSettingsMock1).setUserDataEnabled(false, false);
+ verify(mDataSettingsManagerMock1).setDataEnabled(TelephonyManager.DATA_ENABLED_REASON_USER,
+ false, PHONE_PACKAGE);
assertFalse(GlobalSettingsHelper.getBoolean(
mContext, Settings.Global.DATA_ROAMING, 1, true));
@@ -645,7 +648,8 @@
// Turning data on on sub 2. Sub 1 should also be turned on.
mMultiSimSettingControllerUT.notifyUserDataEnabled(2, true);
processAllMessages();
- verify(mDataEnabledSettingsMock1).setUserDataEnabled(true, false);
+ verify(mDataSettingsManagerMock1).setDataEnabled(TelephonyManager.DATA_ENABLED_REASON_USER,
+ true, PHONE_PACKAGE);
verifyDismissIntentSent();
}
@@ -715,7 +719,8 @@
mMultiSimSettingControllerUT.notifySubscriptionGroupChanged(mGroupUuid1);
processAllMessages();
// This should result in setting sync.
- verify(mDataEnabledSettingsMock2).setUserDataEnabled(true, false);
+ verify(mDataSettingsManagerMock2).setDataEnabled(TelephonyManager.DATA_ENABLED_REASON_USER,
+ true, PHONE_PACKAGE);
assertFalse(GlobalSettingsHelper.getBoolean(
mContext, Settings.Global.DATA_ROAMING, 2, true));
verify(mSubControllerMock).setDataRoaming(/*enable*/0, /*subId*/1);
@@ -724,7 +729,8 @@
doReturn(false).when(mPhoneMock1).isUserDataEnabled();
mMultiSimSettingControllerUT.notifyUserDataEnabled(1, false);
processAllMessages();
- verify(mDataEnabledSettingsMock2).setUserDataEnabled(false, false);
+ verify(mDataSettingsManagerMock2).setDataEnabled(TelephonyManager.DATA_ENABLED_REASON_USER,
+ false, PHONE_PACKAGE);
}
@Test
@@ -736,16 +742,16 @@
// loaded on both subscriptions.
mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
processAllMessages();
- verify(mDataEnabledSettingsMock2, never()).setDataEnabled(
- TelephonyManager.DATA_ENABLED_REASON_USER, false);
+ verify(mDataSettingsManagerMock2, never()).setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE);
mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0, 1);
processAllMessages();
- verify(mDataEnabledSettingsMock2, never()).setDataEnabled(
- TelephonyManager.DATA_ENABLED_REASON_USER, false);
+ verify(mDataSettingsManagerMock2, never()).setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE);
mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 2);
processAllMessages();
- verify(mDataEnabledSettingsMock2).setDataEnabled(
- TelephonyManager.DATA_ENABLED_REASON_USER, false);
+ verify(mDataSettingsManagerMock2).setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE);
// Switch from sub 2 to sub 3 in phone[1].
clearInvocations(mSubControllerMock);
@@ -827,8 +833,8 @@
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
processAllMessages();
// Nothing should happen as carrier config is not ready for sub 2.
- verify(mDataEnabledSettingsMock2, never()).setDataEnabled(
- TelephonyManager.DATA_ENABLED_REASON_USER, false);
+ verify(mDataSettingsManagerMock2, never()).setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE);
// Still notify carrier config without specifying subId2, but this time subController
// and CarrierConfigManager have subId 2 active and ready.
@@ -840,8 +846,8 @@
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
processAllMessages();
// This time user data should be disabled on phone1.
- verify(mDataEnabledSettingsMock2).setDataEnabled(
- TelephonyManager.DATA_ENABLED_REASON_USER, false);
+ verify(mDataSettingsManagerMock2).setDataEnabled(
+ TelephonyManager.DATA_ENABLED_REASON_USER, false, PHONE_PACKAGE);
}
@Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java
index 359010e..20c5d87 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java
@@ -22,6 +22,7 @@
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
import android.content.Context;
import android.content.Intent;
@@ -34,25 +35,25 @@
import android.os.PowerManager;
import android.telephony.CarrierConfigManager;
import android.telephony.NetworkRegistrationInfo;
-import android.telephony.PcoData;
import android.telephony.PhysicalChannelConfig;
import android.telephony.RadioAccessFamily;
import android.telephony.ServiceState;
import android.telephony.TelephonyDisplayInfo;
import android.telephony.TelephonyManager;
-import android.telephony.data.ApnSetting;
import android.telephony.data.DataCallResponse;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
-import com.android.internal.telephony.dataconnection.DataConnection;
+import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback;
import com.android.internal.util.IState;
import com.android.internal.util.StateMachine;
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -60,6 +61,7 @@
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
+@Ignore("b/240911460")
public class NetworkTypeControllerTest extends TelephonyTest {
// private constants copied over from NetworkTypeController
private static final int EVENT_DATA_RAT_CHANGED = 2;
@@ -67,21 +69,13 @@
private static final int EVENT_NR_FREQUENCY_CHANGED = 4;
private static final int EVENT_PHYSICAL_LINK_STATUS_CHANGED = 5;
private static final int EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED = 6;
- private static final int EVENT_CARRIER_CONFIG_CHANGED = 7;
- private static final int EVENT_PRIMARY_TIMER_EXPIRED = 8;
- private static final int EVENT_SECONDARY_TIMER_EXPIRED = 9;
private static final int EVENT_RADIO_OFF_OR_UNAVAILABLE = 10;
private static final int EVENT_PREFERRED_NETWORK_MODE_CHANGED = 11;
- private static final int EVENT_INITIALIZE = 12;
private static final int EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED = 13;
- private static final int EVENT_PCO_DATA_CHANGED = 14;
private NetworkTypeController mNetworkTypeController;
private PersistableBundle mBundle;
-
- // Mocked classes
- DataConnection mDataConnection;
- ApnSetting mApnSetting;
+ private DataNetworkControllerCallback mDataNetworkControllerCallback;
private IState getCurrentState() throws Exception {
Method method = StateMachine.class.getDeclaredMethod("getCurrentState");
@@ -106,23 +100,28 @@
@Before
public void setUp() throws Exception {
super.setUp(getClass().getSimpleName());
- mDataConnection = mock(DataConnection.class);
- mApnSetting = mock(ApnSetting.class);
mBundle = mContextFixture.getCarrierConfigBundle();
mBundle.putString(CarrierConfigManager.KEY_5G_ICON_CONFIGURATION_STRING,
"connected_mmwave:5G_Plus,connected:5G,not_restricted_rrc_idle:5G,"
+ "not_restricted_rrc_con:5G");
+ mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0xFF03);
broadcastCarrierConfigs();
replaceInstance(Handler.class, "mLooper", mDisplayInfoController, Looper.myLooper());
doReturn(RadioAccessFamily.getRafFromNetworkType(
TelephonyManager.NETWORK_MODE_NR_LTE_CDMA_EVDO_GSM_WCDMA)).when(
mPhone).getCachedAllowedNetworkTypesBitmask();
- doReturn(false).when(mTelephonyManager).isRadioInterfaceCapabilitySupported(
+ doReturn(true).when(mTelephonyManager).isRadioInterfaceCapabilitySupported(
TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED);
doReturn(new int[] {0}).when(mServiceState).getCellBandwidths();
mNetworkTypeController = new NetworkTypeController(mPhone, mDisplayInfoController);
processAllMessages();
+
+ ArgumentCaptor<DataNetworkControllerCallback> dataNetworkControllerCallbackCaptor =
+ ArgumentCaptor.forClass(DataNetworkControllerCallback.class);
+ verify(mDataNetworkController).registerDataNetworkControllerCallback(
+ dataNetworkControllerCallbackCaptor.capture());
+ mDataNetworkControllerCallback = dataNetworkControllerCallbackCaptor.getValue();
}
@After
@@ -474,42 +473,7 @@
doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0xFF03);
broadcastCarrierConfigs();
- int cid = 1;
- byte[] contents = new byte[]{0};
- doReturn(mDataConnection).when(mDcTracker).getDataConnectionByContextId(cid);
- doReturn(mApnSetting).when(mDataConnection).getApnSetting();
- doReturn(true).when(mApnSetting).canHandleType(ApnSetting.TYPE_DEFAULT);
- mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0xFF03);
- broadcastCarrierConfigs();
-
-
- mNetworkTypeController.sendMessage(EVENT_PCO_DATA_CHANGED,
- new AsyncResult(null, new PcoData(cid, "", 0xff03, contents), null));
- mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
- processAllMessages();
- assertEquals("connected", getCurrentState().getName());
- }
-
- @Test
- public void testTransitionToCurrentStateNrConnectedWithPcoLength4AndNoNrAdvancedCapable()
- throws Exception {
- assertEquals("DefaultState", getCurrentState().getName());
- doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
- doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
- doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
- mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0xFF03);
- broadcastCarrierConfigs();
- int cid = 1;
- byte[] contents = new byte[]{31, 1, 84, 0};
- doReturn(mDataConnection).when(mDcTracker).getDataConnectionByContextId(cid);
- doReturn(mApnSetting).when(mDataConnection).getApnSetting();
- doReturn(true).when(mApnSetting).canHandleType(ApnSetting.TYPE_DEFAULT);
- mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0xFF03);
- broadcastCarrierConfigs();
-
-
- mNetworkTypeController.sendMessage(EVENT_PCO_DATA_CHANGED,
- new AsyncResult(null, new PcoData(cid, "", 0xff03, contents), null));
+ mDataNetworkControllerCallback.onNrAdvancedCapableByPcoChanged(false);
mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
processAllMessages();
assertEquals("connected", getCurrentState().getName());
@@ -522,19 +486,10 @@
doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
- mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0xFF03);
- broadcastCarrierConfigs();
- int cid = 1;
- byte[] contents = new byte[]{1};
- doReturn(mDataConnection).when(mDcTracker).getDataConnectionByContextId(cid);
- doReturn(mApnSetting).when(mDataConnection).getApnSetting();
- doReturn(true).when(mApnSetting).canHandleType(ApnSetting.TYPE_DEFAULT);
mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0xFF00);
broadcastCarrierConfigs();
-
- mNetworkTypeController.sendMessage(EVENT_PCO_DATA_CHANGED,
- new AsyncResult(null, new PcoData(cid, "", 0xff03, contents), null));
+ mDataNetworkControllerCallback.onNrAdvancedCapableByPcoChanged(false);
mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
processAllMessages();
assertEquals("connected", getCurrentState().getName());
@@ -547,39 +502,12 @@
doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
- int cid = 1;
- byte[] contents = new byte[]{1};
- doReturn(mDataConnection).when(mDcTracker).getDataConnectionByContextId(cid);
- doReturn(mApnSetting).when(mDataConnection).getApnSetting();
- doReturn(true).when(mApnSetting).canHandleType(ApnSetting.TYPE_DEFAULT);
mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0xFF03);
broadcastCarrierConfigs();
- mNetworkTypeController.sendMessage(EVENT_PCO_DATA_CHANGED,
- new AsyncResult(null, new PcoData(cid, "", 0xff03, contents), null));
mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
processAllMessages();
- assertEquals("connected_mmwave", getCurrentState().getName());
- }
-
- @Test
- public void testTransitionToCurrentStateNrConnectedWithNrAdvancedCapableAndPcoLength4()
- throws Exception {
- assertEquals("DefaultState", getCurrentState().getName());
- doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
- doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
- doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
- int cid = 1;
- byte[] contents = new byte[]{31, 1, 84, 1};
- doReturn(mDataConnection).when(mDcTracker).getDataConnectionByContextId(cid);
- doReturn(mApnSetting).when(mDataConnection).getApnSetting();
- doReturn(true).when(mApnSetting).canHandleType(ApnSetting.TYPE_DEFAULT);
- mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0xFF03);
- broadcastCarrierConfigs();
-
- mNetworkTypeController.sendMessage(EVENT_PCO_DATA_CHANGED,
- new AsyncResult(null, new PcoData(cid, "", 0xff03, contents), null));
- mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
+ mDataNetworkControllerCallback.onNrAdvancedCapableByPcoChanged(true);
processAllMessages();
assertEquals("connected_mmwave", getCurrentState().getName());
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/NitzDataTest.java b/tests/telephonytests/src/com/android/internal/telephony/NitzDataTest.java
index 2460dba..05bcc5f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/NitzDataTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/NitzDataTest.java
@@ -29,8 +29,17 @@
public class NitzDataTest {
@Test
- public void testParse_dateOutsideAllowedRange() {
- assertNull(NitzData.parse("38/06/20,00:00:00+0"));
+ public void testParse_invalidYear() {
+ assertNull(NitzData.parse("00/06/20,00:00:00+0,0"));
+ }
+
+ @Test
+ public void testParse_beyond2038() {
+ NitzData nitz = NitzData.parse("40/06/20,01:02:03+4,1");
+ assertEquals(createUnixEpochTime(2040, 6, 20, 1, 2, 3), nitz.getCurrentTimeInMillis());
+ assertEquals(TimeUnit.MINUTES.toMillis(4 * 15), nitz.getLocalOffsetMillis());
+ assertEquals(TimeUnit.MINUTES.toMillis(60), nitz.getDstAdjustmentMillis().longValue());
+ assertNull(nitz.getEmulatorHostTimeZone());
}
@Test
@@ -38,7 +47,7 @@
// "yy/mm/dd,hh:mm:ss(+/-)tz[,dt[,tzid]]"
// No tz field.
- assertNull(NitzData.parse("38/06/20,00:00:00"));
+ assertNull(NitzData.parse("22/06/20,00:00:00"));
}
@Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SMSDispatcherTest.java.broken b/tests/telephonytests/src/com/android/internal/telephony/SMSDispatcherTest.java.broken
deleted file mode 100644
index 80cd9f1..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/SMSDispatcherTest.java.broken
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2007 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;
-
-import android.test.suitebuilder.annotation.MediumTest;
-import com.android.internal.telephony.TestPhoneNotifier;
-import com.android.internal.telephony.gsm.SmsMessage;
-import com.android.internal.telephony.test.SimulatedCommands;
-import com.android.internal.telephony.test.SimulatedRadioControl;
-import com.android.internal.telephony.uicc.IccUtils;
-
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.Suppress;
-
-import java.util.Iterator;
-
-/**
- * {@hide}
- */
-public class SMSDispatcherTest extends AndroidTestCase {
- @MediumTest
- public void testCMT1() throws Exception {
- SmsMessage sms;
- SmsHeader header;
-
- String[] lines = new String[2];
-
- lines[0] = "+CMT: ,158";
- lines[1] = "07914140279510F6440A8111110301003BF56080426101748A8C0B05040B"
- + "8423F000035502010106276170706C69636174696F6E2F766E642E776170"
- + "2E6D6D732D6D65737361676500AF848D0185B4848C8298524F347839776F"
- + "7547514D4141424C3641414141536741415A4B554141414141008D908918"
- + "802B31363530323438363137392F545950453D504C4D4E008A808E028000"
- + "88058103093A8083687474703A2F2F36";
-
- sms = SmsMessage.newFromCMT(lines);
- header = sms.getUserDataHeader();
- assertNotNull(header);
- assertNotNull(sms.getUserData());
- assertNotNull(header.concatRef);
- assertEquals(header.concatRef.refNumber, 85);
- assertEquals(header.concatRef.msgCount, 2);
- assertEquals(header.concatRef.seqNumber, 1);
- assertEquals(header.concatRef.isEightBits, true);
- assertNotNull(header.portAddrs);
- assertEquals(header.portAddrs.destPort, 2948);
- assertEquals(header.portAddrs.origPort, 9200);
- assertEquals(header.portAddrs.areEightBits, false);
- }
-
- @MediumTest
- public void testCMT2() throws Exception {
- SmsMessage sms;
- SmsHeader header;
-
- String[] lines = new String[2];
-
- lines[0] = "+CMT: ,77";
- lines[1] = "07914140279510F6440A8111110301003BF56080426101848A3B0B05040B8423F"
- + "00003550202362E3130322E3137312E3135302F524F347839776F7547514D4141"
- + "424C3641414141536741415A4B55414141414100";
-
- sms = SmsMessage.newFromCMT(lines);
- header = sms.getUserDataHeader();
- assertNotNull(header);
- assertNotNull(sms.getUserData());
- assertNotNull(header.concatRef);
- assertEquals(header.concatRef.refNumber, 85);
- assertEquals(header.concatRef.msgCount, 2);
- assertEquals(header.concatRef.seqNumber, 2);
- assertEquals(header.concatRef.isEightBits, true);
- assertNotNull(header.portAddrs);
- assertEquals(header.portAddrs.destPort, 2948);
- assertEquals(header.portAddrs.origPort, 9200);
- assertEquals(header.portAddrs.areEightBits, false);
- }
-
- @MediumTest
- public void testEfRecord() throws Exception {
- SmsMessage sms;
-
- String s = "03029111000c9194981492631000f269206190022000a053e4534a05358bd3"
- + "69f05804259da0219418a40641536a110a0aea408080604028180e888462c1"
- + "50341c0f484432a1542c174c46b3e1743c9f9068442a994ea8946ac56ab95e"
- + "b0986c46abd96eb89c6ec7ebf97ec0a070482c1a8fc8a472c96c3a9fd0a874"
- + "4aad5aafd8ac76cbed7abfe0b0784c2e9bcfe8b47acd6ebbdff0b87c4eafdb"
- + "eff8bc7ecfeffbffffffffffffffffffffffffffff";
- byte[] data = IccUtils.hexStringToBytes(s);
-
- sms = SmsMessage.createFromEfRecord(1, data);
- assertNotNull(sms.getMessageBody());
- }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
index ce2a260..3833f7d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
@@ -235,7 +235,6 @@
doReturn(mIwlanNetworkServiceStub).when(mIwlanNetworkServiceStub).asBinder();
addNetworkService();
- doReturn(true).when(mDcTracker).areAllDataDisconnected();
doReturn(true).when(mDataNetworkController).areAllDataDisconnected();
doReturn(new ServiceState()).when(mPhone).getServiceState();
@@ -261,7 +260,6 @@
int dds = SubscriptionManager.getDefaultDataSubscriptionId();
doReturn(dds).when(mPhone).getSubId();
- doReturn(true).when(mPhone).areAllDataDisconnected();
doReturn(true).when(mPackageManager)
.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CDMA);
@@ -391,7 +389,6 @@
replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
doReturn(dataNetworkController_phone2).when(phone2).getDataNetworkController();
doReturn(mSST).when(phone2).getServiceStateTracker();
- doReturn(true).when(phone2).isUsingNewDataStack();
doReturn(false).when(mDataNetworkController).areAllDataDisconnected();
doReturn(false).when(dataNetworkController_phone2).areAllDataDisconnected();
doReturn(1).when(mPhone).getSubId();
@@ -1771,29 +1768,6 @@
assertEquals(TelephonyManager.RADIO_POWER_UNAVAILABLE, mSimulatedCommands.getRadioState());
}
- @Test
- @SmallTest
- public void testImsRegisteredDelayShutDown() throws Exception {
- doReturn(false).when(mPhone).isUsingNewDataStack();
- doReturn(true).when(mPhone).isPhoneTypeGsm();
- mContextFixture.putIntResource(
- com.android.internal.R.integer.config_delay_for_ims_dereg_millis, 1000 /*ms*/);
- sst.setImsRegistrationState(true);
- mSimulatedCommands.setRadioPowerFailResponse(false);
- sst.setRadioPower(true);
- waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
-
- // Turn off the radio and ensure radio power is still on
- assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
- sst.setRadioPower(false);
- waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
- assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
-
- // Now set IMS reg state to false and ensure we see the modem move to power off.
- sst.setImsRegistrationState(false);
- waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
- assertEquals(TelephonyManager.RADIO_POWER_OFF, mSimulatedCommands.getRadioState());
- }
@Test
@SmallTest
@@ -1814,33 +1788,6 @@
@Test
@SmallTest
- public void testImsRegisteredDelayShutDownTimeout() throws Exception {
- doReturn(false).when(mPhone).isUsingNewDataStack();
- doReturn(true).when(mPhone).isPhoneTypeGsm();
- mContextFixture.putIntResource(
- com.android.internal.R.integer.config_delay_for_ims_dereg_millis, 1000 /*ms*/);
- sst.setImsRegistrationState(true);
- mSimulatedCommands.setRadioPowerFailResponse(false);
- sst.setRadioPower(true);
- waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
-
- // Turn off the radio and ensure radio power is still on
- assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
- sst.setRadioPower(false);
- waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
- assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
-
- // Ensure that if we never turn deregister for IMS, we still eventually see radio state
- // move to off.
- // Timeout for IMS reg + some extra time to remove race conditions
- waitForDelayedHandlerAction(mSSTTestHandler.getThreadHandler(),
- sst.getRadioPowerOffDelayTimeoutForImsRegistration() + 1000, 1000);
- waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
- assertEquals(TelephonyManager.RADIO_POWER_OFF, mSimulatedCommands.getRadioState());
- }
-
- @Test
- @SmallTest
public void testImsRegisteredAPMOnOffToggle() throws Exception {
doReturn(true).when(mPhone).isPhoneTypeGsm();
mContextFixture.putIntResource(
@@ -1869,12 +1816,6 @@
@SmallTest
public void testSetTimeFromNITZStr_withoutAge() throws Exception {
{
- // Mock sending incorrect nitz str from RIL
- mSimulatedCommands.triggerNITZupdate("38/06/20,00:00:00+0");
- waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
- verify(mNitzStateMachine, times(0)).handleNitzReceived(any());
- }
- {
// Mock sending correct nitz str from RIL with a zero ageMs
String nitzStr = "15/06/20,00:00:00+0";
NitzData expectedNitzData = NitzData.parse(nitzStr);
@@ -1899,13 +1840,6 @@
@SmallTest
public void testSetTimeFromNITZStr_withAge() throws Exception {
{
- // Mock sending incorrect nitz str from RIL with a non-zero ageMs
- long ageMs = 60 * 1000;
- mSimulatedCommands.triggerNITZupdate("38/06/20,00:00:00+0", ageMs);
- waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
- verify(mNitzStateMachine, times(0)).handleNitzReceived(any());
- }
- {
// Mock sending correct nitz str from RIL with a non-zero ageMs
String nitzStr = "21/08/15,00:00:00+0";
long ageMs = 60 * 1000;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SimSmsTest.java b/tests/telephonytests/src/com/android/internal/telephony/SimSmsTest.java
index 0bacc1d..48406de 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SimSmsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SimSmsTest.java
@@ -42,7 +42,6 @@
List<SmsRawData> records = sms.getAllMessagesFromIccEfForSubscriber(
preferredSmsSubscription, ActivityThread.currentPackageName());
assertNotNull(records);
- assertTrue(records.size() >= 0);
int firstNullIndex = -1;
int firstValidIndex = -1;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
index 1a2952c..6a075da 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
@@ -181,6 +181,7 @@
private boolean mDcSuccess = true;
private SetupDataCallResult mSetupDataCallResult;
private boolean mIsRadioPowerFailResponse = false;
+ private boolean mIsReportSmsMemoryStatusFailResponse = false;
public boolean mSetRadioPowerForEmergencyCall;
public boolean mSetRadioPowerAsSelectedPhoneForEmergencyCall;
@@ -1298,10 +1299,19 @@
@Override
public void reportSmsMemoryStatus(boolean available, Message result) {
- resultSuccess(result, null);
+ if (!mIsReportSmsMemoryStatusFailResponse) {
+ resultSuccess(result, null);
+ } else {
+ CommandException ex = new CommandException(CommandException.Error.GENERIC_FAILURE);
+ resultFail(result, null, ex);
+ }
SimulatedCommandsVerifier.getInstance().reportSmsMemoryStatus(available, result);
}
+ public void setReportSmsMemoryStatusFailResponse(boolean fail) {
+ mIsReportSmsMemoryStatusFailResponse = fail;
+ }
+
@Override
public void reportStkServiceIsRunning(Message result) {
resultSuccess(result, null);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SmsStorageMonitorTest.java b/tests/telephonytests/src/com/android/internal/telephony/SmsStorageMonitorTest.java
index 4b22f5f..3eace63 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SmsStorageMonitorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SmsStorageMonitorTest.java
@@ -16,12 +16,15 @@
package com.android.internal.telephony;
+import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
+
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import android.content.Intent;
import android.os.Message;
import android.provider.Telephony;
+import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -36,12 +39,17 @@
@TestableLooper.RunWithLooper
public class SmsStorageMonitorTest extends TelephonyTest {
+ private static final int MAX_RETRIES = 1;
+ private static final int RETRY_DELAY = 200; // 200 millis
+
private SmsStorageMonitor mSmsStorageMonitor;
@Before
public void setUp() throws Exception {
super.setUp(getClass().getSimpleName());
mSmsStorageMonitor = new SmsStorageMonitor(mPhone);
+ mSmsStorageMonitor.setMaxRetries(MAX_RETRIES);
+ mSmsStorageMonitor.setRetryDelayInMillis(RETRY_DELAY);
processAllMessages();
}
@@ -99,4 +107,54 @@
verify(mSimulatedCommandsVerifier).reportSmsMemoryStatus(eq(true), any(Message.class));
}
-}
\ No newline at end of file
+
+ @Test @MediumTest
+ public void testRetrySmsMemoryStatus() {
+ mSimulatedCommands.setReportSmsMemoryStatusFailResponse(true);
+
+ // Send DEVICE_STORAGE_FULL
+ mContextFixture.getTestDouble().sendBroadcast(
+ new Intent(Intent.ACTION_DEVICE_STORAGE_FULL));
+ processAllMessages();
+
+ // Wait until retrying is done.
+ for (int i = 0; i < MAX_RETRIES; i++) {
+ waitForMs(RETRY_DELAY);
+ processAllMessages();
+ }
+
+ verify(mSimulatedCommandsVerifier, times(1 + MAX_RETRIES))
+ .reportSmsMemoryStatus(eq(false), any(Message.class));
+ assertFalse(mSmsStorageMonitor.isStorageAvailable());
+
+ mSimulatedCommands.setReportSmsMemoryStatusFailResponse(false);
+
+ // Notify radio on
+ mSimulatedCommands.notifyRadioOn();
+ processAllMessages();
+
+ verify(mSimulatedCommandsVerifier, times(2 + MAX_RETRIES))
+ .reportSmsMemoryStatus(eq(false), any(Message.class));
+ }
+
+ @Test @SmallTest
+ public void testReportSmsMemoryStatusDuringRetry() {
+ mSimulatedCommands.setReportSmsMemoryStatusFailResponse(true);
+
+ // Send DEVICE_STORAGE_FULL
+ mContextFixture.getTestDouble().sendBroadcast(
+ new Intent(Intent.ACTION_DEVICE_STORAGE_FULL));
+ processAllMessages();
+
+ mSimulatedCommands.setReportSmsMemoryStatusFailResponse(false);
+
+ // Send DEVICE_STORAGE_NOT_FULL
+ mContextFixture.getTestDouble().sendBroadcast(
+ new Intent(Intent.ACTION_DEVICE_STORAGE_NOT_FULL));
+ processAllMessages();
+
+ verify(mSimulatedCommandsVerifier).reportSmsMemoryStatus(eq(false), any(Message.class));
+ verify(mSimulatedCommandsVerifier).reportSmsMemoryStatus(eq(true), any(Message.class));
+ assertTrue(mSmsStorageMonitor.isStorageAvailable());
+ }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
index ea02a4d..38a2454 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
@@ -166,7 +166,6 @@
* between each test case. */
if (mSubscriptionControllerUT != null) {
mSubscriptionControllerUT.clearSubInfo();
- mSubscriptionControllerUT.resetStaticMembers();
mSubscriptionControllerUT = null;
}
@@ -1384,7 +1383,8 @@
int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
// Make sure the return sub ids are sorted by slot index
- assertTrue("active sub ids = " + subIds, Arrays.equals(subIds, new int[]{2, 1}));
+ assertTrue("active sub ids = " + Arrays.toString(subIds),
+ Arrays.equals(subIds, new int[]{2, 1}));
}
@Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
index dbb371b..cf7cadb 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
@@ -43,8 +43,12 @@
import android.os.UserHandle;
import android.telephony.AccessNetworkConstants;
import android.telephony.Annotation;
+import android.telephony.BarringInfo;
import android.telephony.CellIdentity;
import android.telephony.CellIdentityGsm;
+import android.telephony.CellIdentityLte;
+import android.telephony.CellInfo;
+import android.telephony.CellInfoLte;
import android.telephony.CellLocation;
import android.telephony.LinkCapacityEstimate;
import android.telephony.NetworkRegistrationInfo;
@@ -62,6 +66,7 @@
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.text.TextUtils;
+import android.util.SparseArray;
import androidx.annotation.NonNull;
@@ -73,6 +78,7 @@
import org.junit.runner.RunWith;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@@ -100,6 +106,8 @@
private int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
private List<PhysicalChannelConfig> mPhysicalChannelConfigs;
private CellLocation mCellLocation;
+ private List<CellInfo> mCellInfo;
+ private BarringInfo mBarringInfo = null;
// All events contribute to TelephonyRegistry#isPhoneStatePermissionRequired
private static final Set<Integer> READ_PHONE_STATE_EVENTS;
@@ -166,7 +174,9 @@
TelephonyCallback.LinkCapacityEstimateChangedListener,
TelephonyCallback.PhysicalChannelConfigListener,
TelephonyCallback.CellLocationListener,
- TelephonyCallback.ServiceStateListener {
+ TelephonyCallback.ServiceStateListener,
+ TelephonyCallback.CellInfoListener,
+ TelephonyCallback.BarringInfoListener {
// 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);
@@ -228,6 +238,18 @@
public void onPhysicalChannelConfigChanged(@NonNull List<PhysicalChannelConfig> configs) {
mPhysicalChannelConfigs = configs;
}
+
+ @Override
+ public void onCellInfoChanged(List<CellInfo> cellInfo) {
+ invocationCount.incrementAndGet();
+ mCellInfo = cellInfo;
+ }
+
+ @Override
+ public void onBarringInfoChanged(BarringInfo barringInfo) {
+ invocationCount.incrementAndGet();
+ mBarringInfo = barringInfo;
+ }
}
private void addTelephonyRegistryService() {
@@ -874,6 +896,43 @@
assertEquals(PHYSICAL_CELL_ID_UNKNOWN, mPhysicalChannelConfigs.get(0).getPhysicalCellId());
}
+ @Test
+ public void testBarringInfoChanged() {
+ // Return a slotIndex / phoneId of 0 for all sub ids given.
+ doReturn(mMockSubInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
+ doReturn(0/*slotIndex*/).when(mMockSubInfo).getSimSlotIndex();
+ doReturn(true).when(mLocationManager).isLocationEnabledForUser(any(UserHandle.class));
+
+ final int subId = 1;
+ int[] events = {TelephonyCallback.EVENT_BARRING_INFO_CHANGED};
+ SparseArray<BarringInfo.BarringServiceInfo> bsi = new SparseArray(1);
+ bsi.set(BarringInfo.BARRING_SERVICE_TYPE_MO_DATA,
+ new BarringInfo.BarringServiceInfo(
+ BarringInfo.BarringServiceInfo.BARRING_TYPE_CONDITIONAL,
+ false /*isConditionallyBarred*/,
+ 30 /*conditionalBarringFactor*/,
+ 10 /*conditionalBarringTimeSeconds*/));
+ BarringInfo info = new BarringInfo(new CellIdentityLte(), bsi);
+
+ // Registering for info causes Barring Info to be sent to caller
+ mTelephonyRegistry.listenWithEventList(false, false, subId, mContext.getOpPackageName(),
+ mContext.getAttributionTag(), mTelephonyCallback.callback, events, true);
+ processAllMessages();
+ assertEquals(1, mTelephonyCallback.invocationCount.get());
+ assertNotNull(mBarringInfo);
+
+ // Updating the barring info causes Barring Info to be updated
+ mTelephonyRegistry.notifyBarringInfoChanged(0, subId, info);
+ processAllMessages();
+ assertEquals(2, mTelephonyCallback.invocationCount.get());
+ assertEquals(mBarringInfo, info);
+
+ // Duplicate BarringInfo notifications do not trigger callback
+ mTelephonyRegistry.notifyBarringInfoChanged(0, subId, info);
+ processAllMessages();
+ assertEquals(2, mTelephonyCallback.invocationCount.get());
+ }
+
/**
* Test listen to events that require READ_PHONE_STATE permission.
*/
@@ -1260,4 +1319,28 @@
assertEquals(1, mTelephonyCallback.invocationCount.get());
}
+
+ @Test @SmallTest
+ public void testCellInfoChanged() {
+ final int subId = 1;
+ final int[] events = {TelephonyCallback.EVENT_CELL_INFO_CHANGED};
+ final List<CellInfo> dummyCellInfo = Arrays.asList(new CellInfoLte());
+
+ mCellInfo = null; // null is an invalid value since the API is NonNull;
+
+ doReturn(mMockSubInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
+ doReturn(0 /*slotIndex*/).when(mMockSubInfo).getSimSlotIndex();
+ doReturn(true).when(mLocationManager).isLocationEnabledForUser(any(UserHandle.class));
+
+ mTelephonyRegistry.listenWithEventList(false, false, subId, mContext.getOpPackageName(),
+ mContext.getAttributionTag(), mTelephonyCallback.callback, events, true);
+ processAllMessages();
+ assertEquals(1, mTelephonyCallback.invocationCount.get());
+ assertNotNull(mCellInfo);
+
+ mTelephonyRegistry.notifyCellInfoForSubscriber(subId, dummyCellInfo);
+ processAllMessages();
+ assertEquals(2, mTelephonyCallback.invocationCount.get());
+ assertEquals(mCellInfo, dummyCellInfo);
+ }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
index 9b54b19..109a983 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
@@ -33,6 +33,7 @@
import android.app.AppOpsManager;
import android.app.IActivityManager;
import android.app.KeyguardManager;
+import android.app.PropertyInvalidatedCache;
import android.app.usage.NetworkStatsManager;
import android.content.ContentProvider;
import android.content.ContentResolver;
@@ -103,9 +104,6 @@
import com.android.internal.telephony.data.DataServiceManager;
import com.android.internal.telephony.data.DataSettingsManager;
import com.android.internal.telephony.data.LinkBandwidthEstimator;
-import com.android.internal.telephony.dataconnection.DataEnabledSettings;
-import com.android.internal.telephony.dataconnection.DataThrottler;
-import com.android.internal.telephony.dataconnection.DcTracker;
import com.android.internal.telephony.emergency.EmergencyNumberTracker;
import com.android.internal.telephony.imsphone.ImsExternalCallTracker;
import com.android.internal.telephony.imsphone.ImsPhone;
@@ -192,7 +190,6 @@
protected RegistrantList mRegistrantList;
protected IccPhoneBookInterfaceManager mIccPhoneBookIntManager;
protected ImsManager mImsManager;
- protected DcTracker mDcTracker;
protected DataNetworkController mDataNetworkController;
protected DataRetryManager mDataRetryManager;
protected DataSettingsManager mDataSettingsManager;
@@ -240,7 +237,6 @@
protected SubscriptionInfoUpdater mSubInfoRecordUpdater;
protected LocaleTracker mLocaleTracker;
protected RestrictedState mRestrictedState;
- protected DataEnabledSettings mDataEnabledSettings;
protected DataEnabledOverride mDataEnabledOverride;
protected PhoneConfigurationManager mPhoneConfigurationManager;
protected CellularNetworkValidator mCellularNetworkValidator;
@@ -254,7 +250,6 @@
protected PersistAtomsStorage mPersistAtomsStorage;
protected MetricsCollector mMetricsCollector;
protected SmsStats mSmsStats;
- protected DataThrottler mDataThrottler;
protected SignalStrength mSignalStrength;
protected WifiManager mWifiManager;
protected WifiInfo mWifiInfo;
@@ -425,7 +420,6 @@
mRegistrantList = Mockito.mock(RegistrantList.class);
mIccPhoneBookIntManager = Mockito.mock(IccPhoneBookInterfaceManager.class);
mImsManager = Mockito.mock(ImsManager.class);
- mDcTracker = Mockito.mock(DcTracker.class);
mDataNetworkController = Mockito.mock(DataNetworkController.class);
mDataRetryManager = Mockito.mock(DataRetryManager.class);
mDataSettingsManager = Mockito.mock(DataSettingsManager.class);
@@ -473,7 +467,6 @@
mSubInfoRecordUpdater = Mockito.mock(SubscriptionInfoUpdater.class);
mLocaleTracker = Mockito.mock(LocaleTracker.class);
mRestrictedState = Mockito.mock(RestrictedState.class);
- mDataEnabledSettings = Mockito.mock(DataEnabledSettings.class);
mDataEnabledOverride = Mockito.mock(DataEnabledOverride.class);
mPhoneConfigurationManager = Mockito.mock(PhoneConfigurationManager.class);
mCellularNetworkValidator = Mockito.mock(CellularNetworkValidator.class);
@@ -487,7 +480,6 @@
mPersistAtomsStorage = Mockito.mock(PersistAtomsStorage.class);
mMetricsCollector = Mockito.mock(MetricsCollector.class);
mSmsStats = Mockito.mock(SmsStats.class);
- mDataThrottler = Mockito.mock(DataThrottler.class);
mSignalStrength = Mockito.mock(SignalStrength.class);
mWifiManager = Mockito.mock(WifiManager.class);
mWifiInfo = Mockito.mock(WifiInfo.class);
@@ -501,7 +493,7 @@
mMockedWlanDataServiceManager = Mockito.mock(DataServiceManager.class);
TelephonyManager.disableServiceHandleCaching();
- SubscriptionController.disableCaching();
+ PropertyInvalidatedCache.disableForTestMode();
// For testing do not allow Log.WTF as it can cause test process to crash
Log.setWtfHandler((tagString, what, system) -> Log.d(TAG, "WTF captured, ignoring. Tag: "
+ tagString + ", exception: " + what));
@@ -567,8 +559,6 @@
.makeGsmCdmaCallTracker(nullable(GsmCdmaPhone.class));
doReturn(mIccPhoneBookIntManager).when(mTelephonyComponentFactory)
.makeIccPhoneBookInterfaceManager(nullable(Phone.class));
- doReturn(mDcTracker).when(mTelephonyComponentFactory)
- .makeDcTracker(nullable(Phone.class), anyInt());
doReturn(mDisplayInfoController).when(mTelephonyComponentFactory)
.makeDisplayInfoController(nullable(Phone.class));
doReturn(mWspTypeDecoder).when(mTelephonyComponentFactory)
@@ -596,8 +586,6 @@
doReturn(mLocaleTracker).when(mTelephonyComponentFactory)
.makeLocaleTracker(nullable(Phone.class), nullable(NitzStateMachine.class),
nullable(Looper.class));
- doReturn(mDataEnabledSettings).when(mTelephonyComponentFactory)
- .makeDataEnabledSettings(nullable(Phone.class));
doReturn(mEriManager).when(mTelephonyComponentFactory)
.makeEriManager(nullable(Phone.class), anyInt());
doReturn(mLinkBandwidthEstimator).when(mTelephonyComponentFactory)
@@ -627,8 +615,6 @@
doReturn(mAppSmsManager).when(mPhone).getAppSmsManager();
doReturn(mIccSmsInterfaceManager).when(mPhone).getIccSmsInterfaceManager();
doReturn(mAccessNetworksManager).when(mPhone).getAccessNetworksManager();
- doReturn(mDataEnabledSettings).when(mPhone).getDataEnabledSettings();
- doReturn(mDcTracker).when(mPhone).getDcTracker(anyInt());
doReturn(mDataSettingsManager).when(mDataNetworkController).getDataSettingsManager();
doReturn(mDataNetworkController).when(mPhone).getDataNetworkController();
doReturn(mDataSettingsManager).when(mPhone).getDataSettingsManager();
@@ -646,7 +632,6 @@
doReturn(mDataProfileManager).when(mDataNetworkController).getDataProfileManager();
doReturn(mDataRetryManager).when(mDataNetworkController).getDataRetryManager();
doReturn(mCarrierPrivilegesTracker).when(mPhone).getCarrierPrivilegesTracker();
- doReturn(true).when(mPhone).isUsingNewDataStack();
doReturn(0).when(mPhone).getPhoneId();
//mUiccController
@@ -737,11 +722,6 @@
doReturn(new int[]{AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
AccessNetworkConstants.TRANSPORT_TYPE_WLAN})
.when(mAccessNetworksManager).getAvailableTransports();
- doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).when(mAccessNetworksManager)
- .getCurrentTransport(anyInt());
- doReturn(true).when(mDataEnabledSettings).isDataEnabled();
- doReturn(true).when(mDataEnabledSettings).isDataEnabled(anyInt());
- doReturn(true).when(mDataEnabledSettings).isInternalDataEnabled();
doReturn(true).when(mDataSettingsManager).isDataEnabled();
doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
anyInt(), anyInt());
@@ -777,8 +757,6 @@
Settings.Global.putInt(resolver,
Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED, 1);
Settings.Global.putInt(resolver, Settings.Global.DATA_ROAMING, 0);
- doReturn(mDataThrottler).when(mDcTracker).getDataThrottler();
- doReturn(-1L).when(mDataThrottler).getRetryTime(anyInt());
doReturn(90).when(mDataConfigManager).getNetworkCapabilityPriority(
eq(NetworkCapabilities.NET_CAPABILITY_EIMS));
@@ -898,7 +876,6 @@
}
restoreInstances();
TelephonyManager.enableServiceHandleCaching();
- SubscriptionController.enableCaching();
mNetworkRegistrationInfo = null;
mActivityManager = null;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java.broken b/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java.broken
deleted file mode 100644
index 761dfc7..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/TestPhoneNotifier.java.broken
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2006 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;
-
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-import android.telephony.CellInfo;
-
-import java.util.List;
-
-/**
- * Stub class used for unit tests
- */
-
-public class TestPhoneNotifier implements PhoneNotifier {
- public TestPhoneNotifier() {
- }
-
- public void notifyPhoneState(Phone sender) {
- }
-
- public void notifyServiceState(Phone sender) {
- }
-
- public void notifyCellLocation(Phone sender) {
- }
-
- public void notifySignalStrength(Phone sender) {
- }
-
- public void notifyMessageWaitingChanged(Phone sender) {
- }
-
- public void notifyCallForwardingChanged(Phone sender) {
- }
-
- public void notifyDataConnection(Phone sender, String reason, String apnType) {
- }
-
- public void notifyDataConnection(Phone sender, String reason, String apnType,
- PhoneConstants.DataState state) {
- }
-
- public void notifyDataConnectionFailed(Phone sender, String reason, String apnType) {
- }
-
- public void notifyDataActivity(Phone sender) {
- }
-
- public void notifyOtaspChanged(Phone sender, int otaspMode) {
- }
-
- public void notifyCellInfo(Phone sender, List<CellInfo> cellInfo) {
- }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java
index f86dd4b..5df94e5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java
@@ -57,6 +57,11 @@
import com.android.internal.util.IState;
import com.android.internal.util.StateMachine;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
@@ -64,9 +69,6 @@
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class CdmaInboundSmsHandlerTest extends TelephonyTest {
@@ -111,7 +113,9 @@
try {
doReturn(new int[]{UserHandle.USER_SYSTEM}).when(mIActivityManager).getRunningUserIds();
} catch (RemoteException re) {
- fail("Unexpected RemoteException: " + re.getStackTrace());
+ StringWriter reString = new StringWriter();
+ re.printStackTrace(new PrintWriter(reString));
+ fail("Unexpected RemoteException: " + reString);
}
mSmsMessage.mWrappedSmsMessage = mCdmaSmsMessage;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnSettingTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/ApnSettingTest.java
similarity index 62%
rename from tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnSettingTest.java
rename to tests/telephonytests/src/com/android/internal/telephony/data/ApnSettingTest.java
index 1812fa0..b6d77e9 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnSettingTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/ApnSettingTest.java
@@ -14,23 +14,20 @@
* limitations under the License.
*/
-package com.android.internal.telephony.dataconnection;
+package com.android.internal.telephony.data;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;
import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.doReturn;
import android.net.Uri;
import android.os.Parcel;
import android.os.PersistableBundle;
-import android.telephony.CarrierConfigManager;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
-import android.test.suitebuilder.annotation.SmallTest;
import com.android.internal.telephony.TelephonyTest;
@@ -118,213 +115,7 @@
}
@Test
- @SmallTest
- public void testIsMetered() {
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_DEFAULT_STRING, ApnSetting.TYPE_MMS_STRING});
-
- doReturn(false).when(mServiceState).getDataRoaming();
- doReturn(1).when(mPhone).getSubId();
-
- assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_DEFAULT), mPhone));
-
- assertTrue(ApnSettingUtils.isMetered(
- createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS), mPhone));
-
- assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_MMS), mPhone));
-
- assertTrue(ApnSettingUtils.isMetered(
- createApnSetting(ApnSetting.TYPE_SUPL | ApnSetting.TYPE_MMS), mPhone));
-
- assertTrue(ApnSettingUtils.isMetered(
- createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_DUN), mPhone));
-
- assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_ALL), mPhone));
-
- assertFalse(ApnSettingUtils.isMetered(
- createApnSetting(ApnSetting.TYPE_SUPL | ApnSetting.TYPE_FOTA), mPhone));
-
- assertFalse(ApnSettingUtils.isMetered(
- createApnSetting(ApnSetting.TYPE_IA | ApnSetting.TYPE_CBS), mPhone));
-
- assertTrue(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_DEFAULT, mPhone));
- assertTrue(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_MMS, mPhone));
- assertFalse(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_SUPL, mPhone));
- assertFalse(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_CBS, mPhone));
- assertFalse(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_DUN, mPhone));
- assertFalse(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_FOTA, mPhone));
- assertFalse(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_IA, mPhone));
- assertFalse(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_HIPRI, mPhone));
- assertFalse(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_XCAP, mPhone));
- assertFalse(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_ENTERPRISE, mPhone));
-
- // Carrier config settings changes.
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_DEFAULT_STRING});
-
- assertTrue(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_DEFAULT, mPhone));
- assertFalse(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_MMS, mPhone));
- }
-
- @Test
- @SmallTest
- public void testIsRoamingMetered() {
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_DEFAULT_STRING, ApnSetting.TYPE_MMS_STRING});
- doReturn(true).when(mServiceState).getDataRoaming();
- doReturn(1).when(mPhone).getSubId();
-
- assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_DEFAULT), mPhone));
-
- assertTrue(ApnSettingUtils.isMetered(
- createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS), mPhone));
-
- assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_MMS), mPhone));
-
- assertTrue(ApnSettingUtils.isMetered(
- createApnSetting(ApnSetting.TYPE_SUPL | ApnSetting.TYPE_MMS), mPhone));
-
- assertTrue(ApnSettingUtils.isMetered(
- createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_DUN), mPhone));
-
- assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_ALL), mPhone));
-
- assertFalse(ApnSettingUtils.isMetered(
- createApnSetting(ApnSetting.TYPE_SUPL | ApnSetting.TYPE_FOTA), mPhone));
-
- assertFalse(ApnSettingUtils.isMetered(
- createApnSetting(ApnSetting.TYPE_IA | ApnSetting.TYPE_CBS), mPhone));
-
- // Carrier config settings changes.
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_FOTA_STRING});
-
- assertFalse(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_DEFAULT, mPhone));
- assertFalse(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_MMS, mPhone));
- assertTrue(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_FOTA, mPhone));
- assertFalse(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_XCAP, mPhone));
- assertFalse(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_ENTERPRISE, mPhone));
- }
-
- @Test
- @SmallTest
- public void testIsMeteredAnother() {
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_SUPL_STRING, ApnSetting.TYPE_CBS_STRING});
-
- doReturn(false).when(mServiceState).getDataRoaming();
- doReturn(1).when(mPhone).getSubId();
-
- assertTrue(ApnSettingUtils.isMetered(
- createApnSetting(ApnSetting.TYPE_SUPL | ApnSetting.TYPE_CBS), mPhone));
-
- assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_SUPL), mPhone));
-
- assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_CBS), mPhone));
-
- assertTrue(ApnSettingUtils.isMetered(
- createApnSetting(ApnSetting.TYPE_FOTA | ApnSetting.TYPE_CBS), mPhone));
-
- assertTrue(ApnSettingUtils.isMetered(
- createApnSetting(ApnSetting.TYPE_SUPL | ApnSetting.TYPE_IA), mPhone));
-
- assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_ALL), mPhone));
-
- assertFalse(ApnSettingUtils.isMetered(
- createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_IMS), mPhone));
-
- assertFalse(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_IMS), mPhone));
- assertFalse(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_XCAP), mPhone));
- assertFalse(ApnSettingUtils.isMetered(
- createApnSetting(ApnSetting.TYPE_ENTERPRISE), mPhone));
- }
-
- @Test
- @SmallTest
- public void testIsRoamingMeteredAnother() {
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_SUPL_STRING, ApnSetting.TYPE_CBS_STRING});
- doReturn(true).when(mServiceState).getDataRoaming();
- doReturn(2).when(mPhone).getSubId();
-
- assertTrue(ApnSettingUtils.isMetered(
- createApnSetting(ApnSetting.TYPE_SUPL | ApnSetting.TYPE_CBS), mPhone));
-
- assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_SUPL), mPhone));
-
- assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_CBS), mPhone));
-
- assertTrue(ApnSettingUtils.isMetered(
- createApnSetting(ApnSetting.TYPE_FOTA | ApnSetting.TYPE_CBS), mPhone));
-
- assertTrue(ApnSettingUtils.isMetered(
- createApnSetting(ApnSetting.TYPE_SUPL | ApnSetting.TYPE_IA), mPhone));
-
- assertTrue(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_ALL), mPhone));
-
- assertFalse(ApnSettingUtils.isMetered(
- createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_IMS), mPhone));
-
- assertFalse(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_IMS), mPhone));
-
- assertTrue(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_SUPL, mPhone));
- assertTrue(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_CBS, mPhone));
- assertFalse(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_DEFAULT, mPhone));
- assertFalse(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_MMS, mPhone));
- assertFalse(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_DUN, mPhone));
- assertFalse(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_FOTA, mPhone));
- assertFalse(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_IA, mPhone));
- assertFalse(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_HIPRI, mPhone));
- assertFalse(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_XCAP, mPhone));
- assertFalse(ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_ENTERPRISE, mPhone));
- }
-
- @Test
- @SmallTest
- public void testIsMeteredNothingCharged() {
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{});
-
- doReturn(false).when(mServiceState).getDataRoaming();
- doReturn(3).when(mPhone).getSubId();
-
- assertFalse(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_IMS), mPhone));
-
- assertFalse(ApnSettingUtils.isMetered(
- createApnSetting(ApnSetting.TYPE_IMS | ApnSetting.TYPE_MMS), mPhone));
-
- assertFalse(ApnSettingUtils.isMetered(
- createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_FOTA), mPhone));
-
- assertFalse(ApnSettingUtils.isMetered(
- createApnSetting(ApnSetting.TYPE_ALL), mPhone));
- }
-
- @Test
- @SmallTest
- public void testIsRoamingMeteredNothingCharged() {
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS,
- new String[]{});
- doReturn(true).when(mServiceState).getDataRoaming();
- doReturn(3).when(mPhone).getSubId();
-
- assertFalse(ApnSettingUtils.isMetered(createApnSetting(ApnSetting.TYPE_IMS), mPhone));
-
- assertFalse(ApnSettingUtils.isMetered(
- createApnSetting(ApnSetting.TYPE_IMS | ApnSetting.TYPE_MMS), mPhone));
-
- assertFalse(ApnSettingUtils.isMetered(
- createApnSetting(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_FOTA), mPhone));
-
- assertFalse(ApnSettingUtils.isMetered(
- createApnSetting(ApnSetting.TYPE_ALL), mPhone));
- }
-
- @Test
- @SmallTest
public void testCanHandleType() {
- String types[] = {"mms"};
-
assertTrue(createApnSetting(ApnSetting.TYPE_ALL)
.canHandleType(ApnSetting.TYPE_MMS));
@@ -402,7 +193,6 @@
}
@Test
- @SmallTest
public void testEquals() throws Exception {
final int dummyInt = 1;
final int dummyLong = 1;
@@ -451,7 +241,6 @@
}
@Test
- @SmallTest
public void testEqualsRoamingProtocol() {
ApnSetting apn1 = new ApnSetting.Builder()
.setId(1234)
@@ -485,7 +274,6 @@
}
@Test
- @SmallTest
public void testCanHandleNetwork() {
ApnSetting apn1 = new ApnSetting.Builder()
.setId(1234)
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataCallResponseTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataCallResponseTest.java
index 7ee5e23..4b5189a 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataCallResponseTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataCallResponseTest.java
@@ -16,12 +16,6 @@
package com.android.internal.telephony.data;
-import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_ADDRESS;
-import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_DNS;
-import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_GATEWAY;
-import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_IFNAME;
-import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_PCSCF_ADDRESS;
-
import android.net.InetAddresses;
import android.net.LinkAddress;
import android.os.Parcel;
@@ -37,16 +31,21 @@
import java.util.Arrays;
public class DataCallResponseTest extends AndroidTestCase {
- public static final String FAKE_DNN = "FAKE_DNN";
- public static final String FAKE_DNN_2 = "FAKE_DNN_2";
+ private static final String FAKE_ADDRESS = "99.88.77.66";
+ private static final String FAKE_DNS = "55.66.77.88";
+ private static final String FAKE_DNN = "FAKE_DNN";
+ private static final String FAKE_DNN_2 = "FAKE_DNN_2";
+ private static final String FAKE_GATEWAY = "11.22.33.44";
+ private static final String FAKE_IFNAME = "FAKE IFNAME";
+ private static final String FAKE_PCSCF_ADDRESS = "22.33.44.55";
// 97a498e3fc925c9489860333d06e4e470a454e5445525052495345.
// [OsAppId.ANDROID_OS_ID, "ENTERPRISE", 1]
- public static final byte[] FAKE_OS_APP_ID = {-105, -92, -104, -29, -4, -110, 92,
+ private static final byte[] FAKE_OS_APP_ID = {-105, -92, -104, -29, -4, -110, 92,
-108, -119, -122, 3, 51, -48, 110, 78, 71, 10, 69, 78, 84, 69,
82, 80, 82, 73, 83, 69};
// 97a498e3fc925c9489860333d06e4e470a454e544552505249534532.
// [OsAppId.ANDROID_OS_ID, "ENTERPRISE", 2]
- public static final byte[] FAKE_OS_APP_ID_2 = {-105, -92, -104, -29, -4, -110, 92,
+ private static final byte[] FAKE_OS_APP_ID_2 = {-105, -92, -104, -29, -4, -110, 92,
-108, -119, -122, 3, 51, -48, 110, 78, 71, 10, 69, 78, 84, 69,
82, 80, 82, 73, 83, 69, 50};
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
index 399fd9f..d5abf0f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
@@ -76,7 +76,6 @@
import android.telephony.SubscriptionPlan;
import android.telephony.TelephonyDisplayInfo;
import android.telephony.TelephonyManager;
-import android.telephony.TelephonyProtoEnums;
import android.telephony.data.ApnSetting;
import android.telephony.data.DataCallResponse;
import android.telephony.data.DataCallResponse.LinkStatus;
@@ -524,6 +523,20 @@
private void serviceStateChanged(@NetworkType int networkType,
@RegistrationState int dataRegState, @RegistrationState int voiceRegState,
@RegistrationState int iwlanRegState, DataSpecificRegistrationInfo dsri) {
+ ServiceState ss = createSS(networkType, networkType, dataRegState, voiceRegState,
+ iwlanRegState, dsri);
+
+ doReturn(ss).when(mSST).getServiceState();
+ doReturn(ss).when(mPhone).getServiceState();
+
+ mDataNetworkControllerUT.obtainMessage(17/*EVENT_SERVICE_STATE_CHANGED*/).sendToTarget();
+ processAllMessages();
+ }
+
+ private ServiceState createSS(@NetworkType int dataNetworkType,
+ @NetworkType int voiceNetworkType,
+ @RegistrationState int dataRegState, @RegistrationState int voiceRegState,
+ @RegistrationState int iwlanRegState, DataSpecificRegistrationInfo dsri) {
if (dsri == null) {
dsri = new DataSpecificRegistrationInfo(8, false, true, true,
new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
@@ -534,7 +547,7 @@
ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
- .setAccessNetworkTechnology(networkType)
+ .setAccessNetworkTechnology(dataNetworkType)
.setRegistrationState(dataRegState)
.setDomain(NetworkRegistrationInfo.DOMAIN_PS)
.setDataSpecificInfo(dsri)
@@ -549,19 +562,15 @@
ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
- .setAccessNetworkTechnology(networkType)
+ .setAccessNetworkTechnology(voiceNetworkType)
.setRegistrationState(voiceRegState)
.setDomain(NetworkRegistrationInfo.DOMAIN_CS)
.build());
+
ss.setDataRoamingFromRegistration(dataRegState
== NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
processServiceStateRegStateForTest(ss);
-
- doReturn(ss).when(mSST).getServiceState();
- doReturn(ss).when(mPhone).getServiceState();
-
- mDataNetworkControllerUT.obtainMessage(17/*EVENT_SERVICE_STATE_CHANGED*/).sendToTarget();
- processAllMessages();
+ return ss;
}
// set SS reg state base on SST impl, where WLAN overrides WWAN's data reg.
@@ -3373,6 +3382,38 @@
}
@Test
+ public void testHandoverDataNetworkSourceOosNoUnknownRule() throws Exception {
+ testSetupImsDataNetwork();
+ // Configured handover is allowed from OOS to 4G/5G/IWLAN.
+ mCarrierConfig.putStringArray(
+ CarrierConfigManager.KEY_IWLAN_HANDOVER_POLICY_STRING_ARRAY,
+ new String[]{
+ "source=EUTRAN|NGRAN|IWLAN, target=EUTRAN|NGRAN|IWLAN, "
+ + "type=disallowed, capabilities=IMS|EIMS|MMS|XCAP|CBS"
+ });
+ carrierConfigChanged();
+ serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+ NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING);
+
+ updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,
+ AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
+
+ // Verify IMS network was torn down on source first.
+ verify(mMockedWwanDataServiceManager).deactivateDataCall(anyInt(),
+ eq(DataService.REQUEST_REASON_NORMAL), any(Message.class));
+
+ // Verify that IWLAN is brought up again on IWLAN.
+ verify(mMockedWlanDataServiceManager).setupDataCall(anyInt(),
+ any(DataProfile.class), anyBoolean(), anyBoolean(),
+ eq(DataService.REQUEST_REASON_NORMAL), any(), anyInt(), any(), any(), anyBoolean(),
+ any(Message.class));
+
+ DataNetwork dataNetwork = getDataNetworks().get(0);
+ assertThat(dataNetwork.getTransport()).isEqualTo(
+ AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
+ }
+
+ @Test
public void testHandoverDataNetworkNonVops() throws Exception {
ServiceState ss = new ServiceState();
@@ -3792,7 +3833,7 @@
mDataNetworkControllerUT.addNetworkRequest(request);
processAllMessages();
- // Now DDS temporarily switched to phone 1
+ // this slot is 0, modem preferred on slot 1
doReturn(1).when(mMockedPhoneSwitcher).getPreferredDataPhoneId();
// Simulate telephony network factory remove request due to switch.
@@ -3805,13 +3846,13 @@
@Test
public void testSetupDataOnNonDds() throws Exception {
- // Now DDS switched to phone 1
+ // this slot is 0, modem preferred on slot 1
doReturn(1).when(mMockedPhoneSwitcher).getPreferredDataPhoneId();
TelephonyNetworkRequest request = createNetworkRequest(
NetworkCapabilities.NET_CAPABILITY_MMS);
// Test Don't allow setup if both data and voice OOS
- serviceStateChanged(TelephonyProtoEnums.NETWORK_TYPE_1XRTT,
+ serviceStateChanged(TelephonyManager.NETWORK_TYPE_1xRTT,
// data, voice, Iwlan reg state
NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING,
NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING,
@@ -3822,18 +3863,24 @@
verifyAllDataDisconnected();
// Test Don't allow setup if CS is in service, but current RAT is already PS(e.g. LTE)
- serviceStateChanged(TelephonyProtoEnums.NETWORK_TYPE_LTE,
+ serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING,
NetworkRegistrationInfo.REGISTRATION_STATE_HOME,
NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING, null);
verifyAllDataDisconnected();
- // Test Allow if voice is in service if RAT is 2g/3g
- serviceStateChanged(TelephonyProtoEnums.NETWORK_TYPE_1XRTT,
- NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING,
+ // Test Allow if voice is in service if RAT is 2g/3g, use voice RAT to select data profile
+ ServiceState ss = createSS(TelephonyManager.NETWORK_TYPE_UNKNOWN /* data RAT */,
+ TelephonyManager.NETWORK_TYPE_1xRTT /* voice RAT */,
+ NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING ,
NetworkRegistrationInfo.REGISTRATION_STATE_HOME,
NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING, null);
+ doReturn(ss).when(mSST).getServiceState();
+ mDataNetworkControllerUT.obtainMessage(17/*EVENT_SERVICE_STATE_CHANGED*/).sendToTarget();
+ mDataNetworkControllerUT.removeNetworkRequest(request);
+ mDataNetworkControllerUT.addNetworkRequest(request);
+ processAllMessages();
verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_MMS);
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
index 7bab74d..bf5a42d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
@@ -1044,8 +1044,6 @@
verify(mDataNetworkCallback).onHandoverFailed(eq(mDataNetworkUT),
eq(DataFailCause.SERVICE_TEMPORARILY_UNAVAILABLE), eq(-1L),
eq(DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN));
- verify(mLinkBandwidthEstimator, never()).unregisterForBandwidthChanged(
- eq(mDataNetworkUT.getHandler()));
assertThat(mDataNetworkUT.getTransport())
.isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
assertThat(mDataNetworkUT.getId()).isEqualTo(123);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java
index 806ebdc..6a238cb 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java
@@ -78,7 +78,13 @@
private static final String GENERAL_PURPOSE_APN1 = "GP_APN1";
private static final String IMS_APN = "IMS_APN";
private static final String TETHERING_APN = "DUN_APN";
+ private static final String APN_SET_ID_1_APN = "APN_SET_ID_1_APN";
+ private static final String APN_SET_ID_1_TETHERING_APN = "APN_SET_ID_1_TETHERING_APN";
+ private static final String MATCH_ALL_APN_SET_ID_IMS_APN = "MATCH_ALL_APN_SET_ID_IMS_APN";
private static final String PLMN = "330123";
+ private static final int DEFAULT_APN_SET_ID = Telephony.Carriers.NO_APN_SET_ID;
+ private static final int APN_SET_ID_1 = 1;
+ private static final int MATCH_ALL_APN_SET_ID = Telephony.Carriers.MATCH_ALL_APN_SET_ID;
// Mocked classes
private DataProfileManagerCallback mDataProfileManagerCallback;
@@ -159,7 +165,7 @@
TelephonyManager.NETWORK_TYPE_BITMASK_LTE
| TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask
0, // lingering_network_type_bitmask
- 0, // apn_set_id
+ DEFAULT_APN_SET_ID, // apn_set_id
-1, // carrier_id
-1, // skip_464xlat
0 // always_on
@@ -193,7 +199,7 @@
"", // mnvo_match_data
TelephonyManager.NETWORK_TYPE_BITMASK_LTE, // network_type_bitmask
0, // lingering_network_type_bitmask
- 0, // apn_set_id
+ DEFAULT_APN_SET_ID, // apn_set_id
-1, // carrier_id
-1, // skip_464xlat
0 // always_on
@@ -227,7 +233,7 @@
"", // mnvo_match_data
TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask
0, // lingering_network_type_bitmask
- 0, // apn_set_id
+ DEFAULT_APN_SET_ID, // apn_set_id
-1, // carrier_id
-1, // skip_464xlat
0 // alwys_on
@@ -262,7 +268,7 @@
TelephonyManager.NETWORK_TYPE_BITMASK_LTE
| TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask
0, // lingering_network_type_bitmask
- 0, // apn_set_id
+ DEFAULT_APN_SET_ID, // apn_set_id
-1, // carrier_id
-1, // skip_464xlat
0 // always_on
@@ -298,7 +304,112 @@
TelephonyManager.NETWORK_TYPE_BITMASK_LTE
| TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask
0, // lingering_network_type_bitmask
- 0, // apn_set_id
+ DEFAULT_APN_SET_ID, // apn_set_id
+ -1, // carrier_id
+ -1, // skip_464xlat
+ 0 // always_on
+ },
+ new Object[]{
+ 6, // id
+ PLMN, // numeric
+ APN_SET_ID_1_APN, // name
+ APN_SET_ID_1_APN, // apn
+ "", // proxy
+ "", // port
+ "", // mmsc
+ "", // mmsproxy
+ "", // mmsport
+ "", // user
+ "", // password
+ -1, // authtype
+ "default,supl,mms,ia", // types
+ "IPV4V6", // protocol
+ "IPV4V6", // roaming_protocol
+ 1, // carrier_enabled
+ 0, // profile_id
+ 1, // modem_cognitive
+ 0, // max_conns
+ 0, // wait_time
+ 0, // max_conns_time
+ 0, // mtu
+ 1280, // mtu_v4
+ 1280, // mtu_v6
+ "", // mvno_type
+ "", // mnvo_match_data
+ TelephonyManager.NETWORK_TYPE_BITMASK_LTE
+ | TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask
+ 0, // lingering_network_type_bitmask
+ APN_SET_ID_1, // apn_set_id
+ -1, // carrier_id
+ -1, // skip_464xlat
+ 0 // always_on
+ },
+ new Object[]{
+ 7, // id
+ PLMN, // numeric
+ APN_SET_ID_1_TETHERING_APN, // name
+ APN_SET_ID_1_TETHERING_APN, // apn
+ "", // proxy
+ "", // port
+ "", // mmsc
+ "", // mmsproxy
+ "", // mmsport
+ "", // user
+ "", // password
+ -1, // authtype
+ "dun", // types
+ "IPV4V6", // protocol
+ "IPV4V6", // roaming_protocol
+ 1, // carrier_enabled
+ 0, // profile_id
+ 1, // modem_cognitive
+ 0, // max_conns
+ 0, // wait_time
+ 0, // max_conns_time
+ 0, // mtu
+ 1280, // mtu_v4
+ 1280, // mtu_v6
+ "", // mvno_type
+ "", // mnvo_match_data
+ TelephonyManager.NETWORK_TYPE_BITMASK_LTE
+ | TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask
+ 0, // lingering_network_type_bitmask
+ APN_SET_ID_1, // apn_set_id
+ -1, // carrier_id
+ -1, // skip_464xlat
+ 0 // always_on
+ },
+ new Object[]{
+ 8, // id
+ PLMN, // numeric
+ MATCH_ALL_APN_SET_ID_IMS_APN, // name
+ MATCH_ALL_APN_SET_ID_IMS_APN, // apn
+ "", // proxy
+ "", // port
+ "", // mmsc
+ "", // mmsproxy
+ "", // mmsport
+ "", // user
+ "", // password
+ -1, // authtype
+ "ims", // types
+ "IPV4V6", // protocol
+ "IPV4V6", // roaming_protocol
+ 1, // carrier_enabled
+ 0, // profile_id
+ 1, // modem_cognitive
+ 0, // max_conns
+ 0, // wait_time
+ 0, // max_conns_time
+ 0, // mtu
+ 1280, // mtu_v4
+ 1280, // mtu_v6
+ "", // mvno_type
+ "", // mnvo_match_data
+ TelephonyManager.NETWORK_TYPE_BITMASK_LTE
+ | TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask
+ 0, // lingering_network_type_bitmask
+ MATCH_ALL_APN_SET_ID, // apn_set_id
-1, // carrier_id
-1, // skip_464xlat
0 // always_on
@@ -416,6 +527,17 @@
}
}
}
+
+ public int getCountApnSpecifyType(String type) {
+ int count = 0;
+ for (Object apnSetting : mAllApnSettings) {
+ String apnTypes = (String) ((Object[]) apnSetting)[12];
+ if (apnTypes.contains(type)) {
+ count++;
+ }
+ }
+ return count;
+ }
}
/**
@@ -730,6 +852,7 @@
tnr, TelephonyManager.NETWORK_TYPE_LTE, false);
assertThat(dataProfile).isNull();
+ // expect default EIMS when SIM absent
tnr = new TelephonyNetworkRequest(
new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)
@@ -738,13 +861,14 @@
tnr, TelephonyManager.NETWORK_TYPE_LTE, false);
assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo("sos");
+ // expect no default IMS when SIM absent
tnr = new TelephonyNetworkRequest(
new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
.build(), mPhone);
dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
tnr, TelephonyManager.NETWORK_TYPE_LTE, false);
- assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo("ims");
+ assertThat(dataProfile).isEqualTo(null);
}
@Test
@@ -807,6 +931,8 @@
.setProtocol(ApnSetting.PROTOCOL_IPV4V6)
.setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6)
.setCarrierEnabled(true)
+ .setMvnoMatchData("1")
+ .setMvnoType(1)
.build())
.build();
@@ -821,6 +947,8 @@
.setProtocol(ApnSetting.PROTOCOL_IPV4V6)
.setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6)
.setCarrierEnabled(true)
+ .setMvnoMatchData("2")
+ .setMvnoType(2)
.build())
.build();
@@ -950,10 +1078,22 @@
mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget();
processAllMessages();
- // preferred APN should set to be the prev preferred
+ // preferred APN should set to be the last data profile that succeeded for internet setup
assertThat(mDataProfileManagerUT.isAnyPreferredDataProfileExisting()).isTrue();
assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isTrue();
+ // no active internet, expect no preferred APN after reset
+ mDataNetworkControllerCallback.onInternetDataNetworkDisconnected();
+ mPreferredApnId = -1;
+ mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget();
+ processAllMessages();
+
+ assertThat(mDataProfileManagerUT.isAnyPreferredDataProfileExisting()).isFalse();
+ assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isFalse();
+
+ // setup internet again
+ mDataNetworkControllerCallback.onInternetDataNetworkConnected(List.of(dataProfile));
+ processAllMessages();
//APN reset and removed GENERAL_PURPOSE_APN(as if user created) from APN DB
mPreferredApnId = -1;
mApnSettingContentProvider.removeApnByApnId(1);
@@ -1035,12 +1175,13 @@
@Test
public void testNoDefaultIms() throws Exception {
List<DataProfile> dataProfiles = getAllDataProfiles();
+ int countIms = mApnSettingContentProvider.getCountApnSpecifyType("ims");
// Since the database already had IMS, there should not be default IMS created in the
// database.
assertThat(dataProfiles.stream()
.filter(dp -> dp.canSatisfy(NetworkCapabilities.NET_CAPABILITY_IMS))
- .collect(Collectors.toList())).hasSize(1);
+ .collect(Collectors.toList())).hasSize(countIms);
}
@Test
@@ -1076,6 +1217,7 @@
.setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE
| TelephonyManager.NETWORK_TYPE_BITMASK_NR))
.setMvnoMatchData("")
+ .setApnSetId(DEFAULT_APN_SET_ID)
.build())
.build();
@@ -1083,6 +1225,188 @@
}
@Test
+ public void testDataProfileCompatibility_FilteringWithPreferredApnSetIdAsDefault() {
+ mApnSettingContentProvider.setPreferredApn(GENERAL_PURPOSE_APN);
+ mSimInserted = true;
+ mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget();
+ processAllMessages();
+
+ // Test DataProfile's apn_set_id is default so it match with current preferred apn_set_id.
+ DataProfile dataProfile1 = new DataProfile.Builder()
+ .setApnSetting(new ApnSetting.Builder()
+ .setEntryName(TETHERING_APN)
+ .setOperatorNumeric(PLMN)
+ .setApnName(TETHERING_APN)
+ .setProxyAddress("")
+ .setMmsProxyAddress("")
+ .setApnTypeBitmask(ApnSetting.TYPE_DUN)
+ .setUser("")
+ .setPassword("")
+ .setAuthType(ApnSetting.AUTH_TYPE_UNKNOWN)
+ .setProtocol(ApnSetting.PROTOCOL_IPV4V6)
+ .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6)
+ .setCarrierEnabled(true)
+ .setProfileId(2)
+ .setPersistent(true)
+ .setMtuV4(0)
+ .setMtuV6(0)
+ .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_NR))
+ .setMvnoMatchData("")
+ .setApnSetId(DEFAULT_APN_SET_ID)
+ .build())
+ .build();
+
+ assertThat(mDataProfileManagerUT.isDataProfileCompatible(dataProfile1)).isTrue();
+
+ // Test DataProfile's apn_set_id is specified(1) so it not match with current
+ // preferred apn_set_id.
+ DataProfile dataProfile2 = new DataProfile.Builder()
+ .setApnSetting(new ApnSetting.Builder()
+ .setEntryName(APN_SET_ID_1_TETHERING_APN)
+ .setOperatorNumeric(PLMN)
+ .setApnName(APN_SET_ID_1_TETHERING_APN)
+ .setProxyAddress("")
+ .setMmsProxyAddress("")
+ .setApnTypeBitmask(ApnSetting.TYPE_DUN)
+ .setUser("")
+ .setPassword("")
+ .setAuthType(ApnSetting.AUTH_TYPE_UNKNOWN)
+ .setProtocol(ApnSetting.PROTOCOL_IPV4V6)
+ .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6)
+ .setCarrierEnabled(true)
+ .setPersistent(true)
+ .setMtuV4(1280)
+ .setMtuV6(1280)
+ .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE
+ | TelephonyManager.NETWORK_TYPE_BITMASK_NR))
+ .setMvnoMatchData("")
+ .setApnSetId(APN_SET_ID_1)
+ .build())
+ .build();
+
+ assertThat(mDataProfileManagerUT.isDataProfileCompatible(dataProfile2)).isFalse();
+
+ // Test DataProfile has Telephony.Carriers.MATCH_ALL_APN_SET_ID so it matches any preferred
+ // apn_set_id.
+ DataProfile dataProfile3 = new DataProfile.Builder()
+ .setApnSetting(new ApnSetting.Builder()
+ .setEntryName(MATCH_ALL_APN_SET_ID_IMS_APN)
+ .setOperatorNumeric(PLMN)
+ .setApnName(MATCH_ALL_APN_SET_ID_IMS_APN)
+ .setProxyAddress("")
+ .setMmsProxyAddress("")
+ .setApnTypeBitmask(ApnSetting.TYPE_IMS)
+ .setUser("")
+ .setPassword("")
+ .setAuthType(ApnSetting.AUTH_TYPE_UNKNOWN)
+ .setProtocol(ApnSetting.PROTOCOL_IPV4V6)
+ .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6)
+ .setCarrierEnabled(true)
+ .setPersistent(true)
+ .setMtuV4(1280)
+ .setMtuV6(1280)
+ .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE
+ | TelephonyManager.NETWORK_TYPE_BITMASK_NR))
+ .setMvnoMatchData("")
+ .setApnSetId(MATCH_ALL_APN_SET_ID)
+ .build())
+ .build();
+
+ assertThat(mDataProfileManagerUT.isDataProfileCompatible(dataProfile3)).isTrue();
+ }
+
+ @Test
+ public void testDataProfileCompatibility_FilteringWithPreferredApnSetIdAs1() {
+ mApnSettingContentProvider.setPreferredApn(APN_SET_ID_1_APN);
+ mSimInserted = true;
+ mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget();
+ processAllMessages();
+
+ // Test DataProfile's apn_set_id is same as preferred apn_set_id.
+ DataProfile dataProfile1 = new DataProfile.Builder()
+ .setApnSetting(new ApnSetting.Builder()
+ .setEntryName(APN_SET_ID_1_TETHERING_APN)
+ .setOperatorNumeric(PLMN)
+ .setApnName(APN_SET_ID_1_TETHERING_APN)
+ .setProxyAddress("")
+ .setMmsProxyAddress("")
+ .setApnTypeBitmask(ApnSetting.TYPE_DUN)
+ .setUser("")
+ .setPassword("")
+ .setAuthType(ApnSetting.AUTH_TYPE_UNKNOWN)
+ .setProtocol(ApnSetting.PROTOCOL_IPV4V6)
+ .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6)
+ .setCarrierEnabled(true)
+ .setPersistent(true)
+ .setMtuV4(1280)
+ .setMtuV6(1280)
+ .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE
+ | TelephonyManager.NETWORK_TYPE_BITMASK_NR))
+ .setMvnoMatchData("")
+ .setApnSetId(APN_SET_ID_1)
+ .build())
+ .build();
+
+ assertThat(mDataProfileManagerUT.isDataProfileCompatible(dataProfile1)).isTrue();
+
+ // Test DataProfile's apn_set_id is default. so it not match with current preferred
+ // apn_set_id(1).
+ DataProfile dataProfile2 = new DataProfile.Builder()
+ .setApnSetting(new ApnSetting.Builder()
+ .setEntryName(TETHERING_APN)
+ .setOperatorNumeric(PLMN)
+ .setApnName(TETHERING_APN)
+ .setProxyAddress("")
+ .setMmsProxyAddress("")
+ .setApnTypeBitmask(ApnSetting.TYPE_DUN)
+ .setUser("")
+ .setPassword("")
+ .setAuthType(ApnSetting.AUTH_TYPE_UNKNOWN)
+ .setProtocol(ApnSetting.PROTOCOL_IPV4V6)
+ .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6)
+ .setCarrierEnabled(true)
+ .setProfileId(2)
+ .setPersistent(true)
+ .setMtuV4(0)
+ .setMtuV6(0)
+ .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_NR))
+ .setMvnoMatchData("")
+ .setApnSetId(DEFAULT_APN_SET_ID)
+ .build())
+ .build();
+
+ assertThat(mDataProfileManagerUT.isDataProfileCompatible(dataProfile2)).isFalse();
+
+ // Test DataProfile has Telephony.Carriers.MATCH_ALL_APN_SET_ID so it matches any preferred
+ // apn_set_id.
+ DataProfile dataProfile3 = new DataProfile.Builder()
+ .setApnSetting(new ApnSetting.Builder()
+ .setEntryName(MATCH_ALL_APN_SET_ID_IMS_APN)
+ .setOperatorNumeric(PLMN)
+ .setApnName(MATCH_ALL_APN_SET_ID_IMS_APN)
+ .setProxyAddress("")
+ .setMmsProxyAddress("")
+ .setApnTypeBitmask(ApnSetting.TYPE_IMS)
+ .setUser("")
+ .setPassword("")
+ .setAuthType(ApnSetting.AUTH_TYPE_UNKNOWN)
+ .setProtocol(ApnSetting.PROTOCOL_IPV4V6)
+ .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6)
+ .setCarrierEnabled(true)
+ .setPersistent(true)
+ .setMtuV4(1280)
+ .setMtuV6(1280)
+ .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE
+ | TelephonyManager.NETWORK_TYPE_BITMASK_NR))
+ .setMvnoMatchData("")
+ .setApnSetId(MATCH_ALL_APN_SET_ID)
+ .build())
+ .build();
+
+ assertThat(mDataProfileManagerUT.isDataProfileCompatible(dataProfile3)).isTrue();
+ }
+
+ @Test
public void testPermanentFailureWithNoPreferredDataProfile() {
// No preferred APN is set
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java
index 348d96f..769a920 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java
@@ -16,6 +16,8 @@
package com.android.internal.telephony.data;
+import static com.android.internal.telephony.data.DataRetryManager.DataHandoverRetryEntry;
+import static com.android.internal.telephony.data.DataRetryManager.DataRetryEntry;
import static com.android.internal.telephony.data.DataRetryManager.DataSetupRetryEntry;
import static com.google.common.truth.Truth.assertThat;
@@ -25,6 +27,7 @@
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.net.NetworkCapabilities;
@@ -55,6 +58,7 @@
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
+import java.lang.reflect.Field;
import java.util.Collections;
import java.util.List;
@@ -328,15 +332,38 @@
}
@Test
- public void testDataSetupUnthrottling() {
+ public void testDataSetupUnthrottling() throws Exception {
testDataSetupRetryNetworkSuggestedNeverRetry();
Mockito.clearInvocations(mDataRetryManagerCallbackMock);
+ DataNetworkController.NetworkRequestList mockNrl = Mockito.mock(
+ DataNetworkController.NetworkRequestList.class);
+ Field field = DataRetryManager.class.getDeclaredField("mDataRetryEntries");
+ field.setAccessible(true);
+ List<DataRetryEntry> mDataRetryEntries =
+ (List<DataRetryEntry>) field.get(mDataRetryManagerUT);
+ // schedule 2 setup retries
+ DataSetupRetryEntry scheduledRetry1 = new DataSetupRetryEntry.Builder<>()
+ .setDataProfile(mDataProfile3)
+ .setNetworkRequestList(mockNrl)
+ .setTransport(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+ .setSetupRetryType(1)
+ .build();
+ DataSetupRetryEntry scheduledRetry2 = new DataSetupRetryEntry.Builder<>()
+ .setNetworkRequestList(mockNrl)
+ .setDataProfile(mDataProfile3)
+ .setTransport(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
+ .setSetupRetryType(1)
+ .build();
+ mDataRetryEntries.addAll(List.of(scheduledRetry1, scheduledRetry2));
+
+ // unthrottle the data profile, expect previous retries of the same transport is cancelled
mDataRetryManagerUT.obtainMessage(6/*EVENT_DATA_PROFILE_UNTHROTTLED*/,
new AsyncResult(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, mDataProfile3, null))
.sendToTarget();
processAllMessages();
+ // check unthrottle
ArgumentCaptor<List<ThrottleStatus>> throttleStatusCaptor =
ArgumentCaptor.forClass(List.class);
verify(mDataRetryManagerCallbackMock).onThrottleStatusChanged(
@@ -358,6 +385,10 @@
assertThat(entry.dataProfile).isEqualTo(mDataProfile3);
assertThat(entry.retryDelayMillis).isEqualTo(0);
assertThat(entry.transport).isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+
+ // check mDataProfile3-WWAN retry is cancelled, but not the WLAN
+ assertThat(scheduledRetry1.getState()).isEqualTo(DataRetryEntry.RETRY_STATE_CANCELLED);
+ assertThat(scheduledRetry2.getState()).isEqualTo(DataRetryEntry.RETRY_STATE_NOT_RETRIED);
}
@Test
@@ -396,6 +427,66 @@
}
@Test
+ public void testCancellingRetries() throws Exception {
+ DataNetworkController.NetworkRequestList mockNrl = Mockito.mock(
+ DataNetworkController.NetworkRequestList.class);
+
+ // Test: setup retry
+ DataRetryEntry retry = new DataSetupRetryEntry.Builder<>()
+ .setSetupRetryType(1)
+ .setNetworkRequestList(mockNrl)
+ .setTransport(1)
+ .build();
+ retry.setState(DataRetryEntry.RETRY_STATE_CANCELLED);
+
+ mDataRetryManagerUT.obtainMessage(3/*EVENT_DATA_SETUP_RETRY*/, retry).sendToTarget();
+ processAllMessages();
+ verify(mDataRetryManagerCallbackMock, never()).onDataNetworkSetupRetry(any());
+
+ mDataRetryManagerUT.obtainMessage(3/*EVENT_DATA_SETUP_RETRY*/, null).sendToTarget();
+ processAllMessages();
+ verify(mDataRetryManagerCallbackMock, never()).onDataNetworkSetupRetry(any());
+
+ retry.setState(DataRetryEntry.RETRY_STATE_NOT_RETRIED);
+ mDataRetryManagerUT.obtainMessage(3/*EVENT_DATA_SETUP_RETRY*/, retry).sendToTarget();
+ processAllMessages();
+ verify(mDataRetryManagerCallbackMock, times(1)).onDataNetworkSetupRetry(any());
+
+ // Test: handover retry
+ retry = new DataHandoverRetryEntry.Builder<>().build();
+ retry.setState(DataRetryEntry.RETRY_STATE_CANCELLED);
+ mDataRetryManagerUT.obtainMessage(4/*EVENT_DATA_HANDOVER_RETRY*/, retry).sendToTarget();
+ processAllMessages();
+ verify(mDataRetryManagerCallbackMock, never()).onDataNetworkHandoverRetry(any());
+
+ mDataRetryManagerUT.obtainMessage(4/*EVENT_DATA_HANDOVER_RETRY*/, null).sendToTarget();
+ processAllMessages();
+ verify(mDataRetryManagerCallbackMock, never()).onDataNetworkHandoverRetry(any());
+
+ retry.setState(DataRetryEntry.RETRY_STATE_NOT_RETRIED);
+ mDataRetryManagerUT.obtainMessage(4/*EVENT_DATA_HANDOVER_RETRY*/, retry).sendToTarget();
+ processAllMessages();
+ verify(mDataRetryManagerCallbackMock, times(1))
+ .onDataNetworkHandoverRetry(any());
+
+ // Test: cancelPendingHandoverRetry
+ DataNetwork mockDn = Mockito.mock(DataNetwork.class);
+ Field field = DataRetryManager.class.getDeclaredField("mDataRetryEntries");
+ field.setAccessible(true);
+ List<DataRetryEntry> mDataRetryEntries =
+ (List<DataRetryEntry>) field.get(mDataRetryManagerUT);
+ retry = new DataHandoverRetryEntry.Builder<>()
+ .setDataNetwork(mockDn)
+ .build();
+ mDataRetryEntries.add(retry);
+ mDataRetryManagerUT.cancelPendingHandoverRetry(mockDn);
+ processAllMessages();
+
+ assertThat(mDataRetryManagerUT.isAnyHandoverRetryScheduled(mockDn)).isFalse();
+ assertThat(retry.getState()).isEqualTo(DataRetryEntry.RETRY_STATE_CANCELLED);
+ }
+
+ @Test
public void testDataSetupRetryPermanentFailure() {
DataSetupRetryRule retryRule = new DataSetupRetryRule(
"permanent_fail_causes=8|27|28|29|30|32|33|35|50|51|111|-5|-6|65537|65538|-3|65543|"
@@ -598,7 +689,7 @@
assertThat(entry.networkRequestList).isEqualTo(networkRequestList);
assertThat(entry.appliedDataRetryRule).isEqualTo(retryRule3);
- entry.setState(DataRetryManager.DataRetryEntry.RETRY_STATE_FAILED);
+ entry.setState(DataRetryEntry.RETRY_STATE_FAILED);
}
// The last fail should not trigger any retry.
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/LinkBandwidthEstimatorTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/LinkBandwidthEstimatorTest.java
index ba001f2..d41be7d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/LinkBandwidthEstimatorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/LinkBandwidthEstimatorTest.java
@@ -32,7 +32,6 @@
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.eq;
@@ -43,9 +42,7 @@
import static org.mockito.Mockito.when;
import android.net.NetworkCapabilities;
-import android.os.AsyncResult;
import android.os.Handler;
-import android.os.Message;
import android.telephony.CellIdentityLte;
import android.telephony.ModemActivityInfo;
import android.telephony.NetworkRegistrationInfo;
@@ -63,7 +60,6 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
@RunWith(AndroidTestingRunner.class)
@@ -80,7 +76,6 @@
new ModemActivityInfo(100L, 0, 0, TX_TIME_2_MS, RX_TIME_2_MS);
private static final ModemActivityInfo MAI_RX_TIME_HIGH =
new ModemActivityInfo(100L, 0, 0, TX_TIME_1_MS, RX_TIME_2_MS);
- private static final int EVENT_BANDWIDTH_ESTIMATOR_UPDATE = 1;
private NetworkCapabilities mNetworkCapabilities;
private CellIdentityLte mCellIdentity;
private long mElapsedTimeMs = 0;
@@ -89,14 +84,20 @@
private NetworkRegistrationInfo mNri;
// Mocked classes
- TelephonyFacade mTelephonyFacade;
+ private TelephonyFacade mTelephonyFacade;
private Handler mTestHandler;
+ private LinkBandwidthEstimatorCallback mLinkBandwidthEstimatorCallback;
@Before
public void setUp() throws Exception {
super.setUp(getClass().getSimpleName());
mTelephonyFacade = mock(TelephonyFacade.class);
mTestHandler = mock(Handler.class);
+ mLinkBandwidthEstimatorCallback = Mockito.mock(LinkBandwidthEstimatorCallback.class);
+ doAnswer(invocation -> {
+ ((Runnable) invocation.getArguments()[0]).run();
+ return null;
+ }).when(mLinkBandwidthEstimatorCallback).invokeFromExecutor(any(Runnable.class));
mNetworkCapabilities = new NetworkCapabilities.Builder()
.addTransportType(TRANSPORT_CELLULAR)
.build();
@@ -116,10 +117,10 @@
when(mSignalStrength.getDbm()).thenReturn(-100);
when(mSignalStrength.getLevel()).thenReturn(1);
mLBE = new LinkBandwidthEstimator(mPhone, mTelephonyFacade);
- mLBE.registerForBandwidthChanged(mTestHandler, EVENT_BANDWIDTH_ESTIMATOR_UPDATE, null);
mLBE.obtainMessage(MSG_DEFAULT_NETWORK_CHANGED, mNetworkCapabilities).sendToTarget();
mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, false).sendToTarget();
mLBE.obtainMessage(MSG_ACTIVE_PHONE_CHANGED, 1).sendToTarget();
+ mLBE.registerCallback(mLinkBandwidthEstimatorCallback);
processAllMessages();
}
@@ -184,12 +185,8 @@
}
private void verifyUpdateBandwidth(int txKbps, int rxKbps) {
- ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
- verify(mTestHandler, atLeast(1))
- .sendMessageAtTime(messageArgumentCaptor.capture(), anyLong());
- assertEquals(EVENT_BANDWIDTH_ESTIMATOR_UPDATE, messageArgumentCaptor.getValue().what);
- assertEquals(new Pair<Integer, Integer>(txKbps, rxKbps),
- ((AsyncResult) messageArgumentCaptor.getValue().obj).result);
+ verify(mLinkBandwidthEstimatorCallback, atLeast(1))
+ .onBandwidthChanged(eq(txKbps), eq(rxKbps));
}
@Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
index d50cb72..6465705 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
@@ -79,7 +79,6 @@
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.TelephonyTest;
-import com.android.internal.telephony.dataconnection.DataEnabledSettings;
import org.junit.After;
import org.junit.Before;
@@ -104,7 +103,7 @@
private Phone mPhone2; // mPhone as phone 1 is already defined in TelephonyTest.
private Phone mImsPhone;
// TODO: Add logic for DataSettingsManager
- private DataEnabledSettings mDataEnabledSettings2;
+ private DataSettingsManager mDataSettingsManager2;
private Handler mActivePhoneSwitchHandler;
private GsmCdmaCall mActiveCall;
private GsmCdmaCall mHoldingCall;
@@ -136,7 +135,7 @@
mCommandsInterface1 = mock(CommandsInterface.class);
mPhone2 = mock(Phone.class); // mPhone as phone 1 is already defined in TelephonyTest.
mImsPhone = mock(Phone.class);
- mDataEnabledSettings2 = mock(DataEnabledSettings.class);
+ mDataSettingsManager2 = mock(DataSettingsManager.class);
mActivePhoneSwitchHandler = mock(Handler.class);
mActiveCall = mock(GsmCdmaCall.class);
mHoldingCall = mock(GsmCdmaCall.class);
@@ -478,6 +477,65 @@
assertFalse(mDataAllowed[1]);
}
+ /**
+ * TestSetPreferredData in the event of different priorities.
+ * The following events can set preferred data subId with priority in the order of
+ * 1. Emergency call
+ * 2. Voice call (when data during call feature is enabled).
+ * 3. CBRS requests
+ */
+ @Test
+ @SmallTest
+ public void testSetPreferredDataCasePriority() throws Exception {
+ initialize();
+ setAllPhonesInactive();
+
+ // Phone 0 has sub 1, phone 1 has sub 2.
+ // Sub 1 is default data sub.
+ // Both are active subscriptions are active sub, as they are in both active slots.
+ setSlotIndexToSubId(0, 1);
+ setSlotIndexToSubId(1, 2);
+ setDefaultDataSubId(1);
+
+ // Notify phoneSwitcher about default data sub and default network request.
+ NetworkRequest internetRequest = addInternetNetworkRequest(null, 50);
+ // Phone 0 (sub 1) should be activated as it has default data sub.
+ assertEquals(1, mPhoneSwitcher.getActiveDataSubId());
+ assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(
+ new TelephonyNetworkRequest(internetRequest, mPhone), 0));
+ assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(
+ new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+
+ // Set sub 2 as preferred sub should make phone 1 activated and phone 0 deactivated.
+ mPhoneSwitcher.trySetOpportunisticDataSubscription(2, false, null);
+ processAllMessages();
+ mPhoneSwitcher.mValidationCallback.onNetworkAvailable(null, 2);
+ // A higher priority event occurring E.g. Phone1 has active IMS call on LTE.
+ doReturn(mImsPhone).when(mPhone).getImsPhone();
+ doReturn(true).when(mDataSettingsManager).isDataEnabled(ApnSetting.TYPE_DEFAULT);
+ mockImsRegTech(1, REGISTRATION_TECH_LTE);
+ notifyPhoneAsInCall(mPhone);
+
+ // switch shouldn't occur due to the higher priority event
+ assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(
+ new TelephonyNetworkRequest(internetRequest, mPhone), 0));
+ assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(
+ new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+ assertEquals(1, mPhoneSwitcher.getActiveDataSubId());
+ assertEquals(2, mPhoneSwitcher.getAutoSelectedDataSubId());
+
+ // The higher priority event ends, time to switch to auto selected subId.
+ notifyPhoneAsInactive(mPhone);
+
+ assertEquals(2, mPhoneSwitcher.getActiveDataSubId());
+ assertEquals(2, mPhoneSwitcher.getAutoSelectedDataSubId());
+ assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(
+ new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+ assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(
+ new TelephonyNetworkRequest(internetRequest, mPhone), 0));
+
+ }
+
@Test
@SmallTest
public void testSetPreferredDataModemCommand() throws Exception {
@@ -648,7 +706,7 @@
// Phone2 has active IMS call on LTE. And data of DEFAULT apn is enabled. This should
// trigger data switch.
doReturn(mImsPhone).when(mPhone2).getImsPhone();
- doReturn(true).when(mDataEnabledSettings2).isDataEnabled(ApnSetting.TYPE_DEFAULT);
+ doReturn(true).when(mDataSettingsManager2).isDataEnabled(ApnSetting.TYPE_DEFAULT);
mockImsRegTech(1, REGISTRATION_TECH_LTE);
notifyPhoneAsInCall(mImsPhone);
@@ -677,7 +735,7 @@
// Phone2 has active IMS call on LTE. And data of DEFAULT apn is enabled. This should
// trigger data switch.
doReturn(mImsPhone).when(mPhone2).getImsPhone();
- doReturn(true).when(mDataEnabledSettings2).isDataEnabled(ApnSetting.TYPE_DEFAULT);
+ doReturn(true).when(mDataSettingsManager2).isDataEnabled(ApnSetting.TYPE_DEFAULT);
mockImsRegTech(1, REGISTRATION_TECH_LTE);
notifyPhoneAsInDial(mImsPhone);
@@ -705,7 +763,7 @@
// Phone2 has active IMS call on LTE. And data of DEFAULT apn is enabled. This should
// trigger data switch.
doReturn(mImsPhone).when(mPhone2).getImsPhone();
- doReturn(true).when(mDataEnabledSettings2).isDataEnabled(ApnSetting.TYPE_DEFAULT);
+ doReturn(true).when(mDataSettingsManager2).isDataEnabled(ApnSetting.TYPE_DEFAULT);
mockImsRegTech(1, REGISTRATION_TECH_LTE);
notifyPhoneAsInIncomingCall(mImsPhone);
@@ -732,7 +790,7 @@
// Phone2 has active call, but data is turned off. So no data switching should happen.
doReturn(mImsPhone).when(mPhone2).getImsPhone();
- doReturn(true).when(mDataEnabledSettings2).isDataEnabled(ApnSetting.TYPE_DEFAULT);
+ doReturn(true).when(mDataSettingsManager2).isDataEnabled(ApnSetting.TYPE_DEFAULT);
mockImsRegTech(1, REGISTRATION_TECH_IWLAN);
notifyPhoneAsInCall(mImsPhone);
@@ -760,7 +818,7 @@
// Phone 1 has active IMS call on CROSS_SIM. And data of DEFAULT apn is enabled. This should
// not trigger data switch.
doReturn(mImsPhone).when(mPhone2).getImsPhone();
- doReturn(true).when(mDataEnabledSettings2).isDataEnabled(ApnSetting.TYPE_DEFAULT);
+ doReturn(true).when(mDataSettingsManager2).isDataEnabled(ApnSetting.TYPE_DEFAULT);
mockImsRegTech(1, REGISTRATION_TECH_CROSS_SIM);
notifyPhoneAsInCall(mImsPhone);
@@ -1085,7 +1143,23 @@
setSlotIndexToSubId(1, 2);
setDefaultDataSubId(1);
+ // Switch to primary before a primary is selected/inactive.
+ setDefaultDataSubId(-1);
+ mPhoneSwitcher.trySetOpportunisticDataSubscription(
+ SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, mSetOpptDataCallback1);
+ processAllMessages();
+
+ assertEquals(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
+ mPhoneSwitcher.getAutoSelectedDataSubId());
+ verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION);
+
+ // once the primary is selected, it becomes the active sub.
+ setDefaultDataSubId(2);
+ assertEquals(2, mPhoneSwitcher.getActiveDataSubId());
+
+ setDefaultDataSubId(1);
// Validating on sub 10 which is inactive.
+ clearInvocations(mSetOpptDataCallback1);
mPhoneSwitcher.trySetOpportunisticDataSubscription(10, true, mSetOpptDataCallback1);
processAllMessages();
verify(mSetOpptDataCallback1).onComplete(SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION);
@@ -1193,7 +1267,6 @@
verify(mPhone2).registerForEmergencyCallToggle(any(), anyInt(), any());
verify(mPhone2).registerForPreciseCallStateChanged(any(), anyInt(), any());
- verify(mDataEnabledSettings2).registerForDataEnabledChanged(any(), anyInt(), any());
clearInvocations(mMockRadioConfig);
setSlotIndexToSubId(1, 2);
@@ -1375,8 +1448,8 @@
}
private void notifyDataEnabled(boolean dataEnabled) {
- doReturn(dataEnabled).when(mDataEnabledSettings).isDataEnabled(anyInt());
- doReturn(dataEnabled).when(mDataEnabledSettings2).isDataEnabled(anyInt());
+ doReturn(dataEnabled).when(mDataSettingsManager).isDataEnabled(anyInt());
+ doReturn(dataEnabled).when(mDataSettingsManager2).isDataEnabled(anyInt());
mPhoneSwitcher.sendEmptyMessage(EVENT_DATA_ENABLED_CHANGED);
processAllMessages();
}
@@ -1470,7 +1543,7 @@
doReturn(0).when(mPhone).getPhoneId();
doReturn(1).when(mPhone2).getPhoneId();
doReturn(true).when(mPhone2).isUserDataEnabled();
- doReturn(mDataEnabledSettings2).when(mPhone2).getDataEnabledSettings();
+ doReturn(mDataSettingsManager2).when(mPhone2).getDataSettingsManager();
for (int i = 0; i < supportedModemCount; i++) {
mSlotIndexToSubId[i] = new int[1];
mSlotIndexToSubId[i][0] = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/QosCallbackTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/QosCallbackTrackerTest.java
index 00bca4d..d528d85 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/QosCallbackTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/QosCallbackTrackerTest.java
@@ -27,15 +27,17 @@
import static org.mockito.Mockito.verify;
import android.annotation.NonNull;
+import android.net.INetworkAgentRegistry;
import android.net.InetAddresses;
import android.net.LinkAddress;
import android.net.Network;
+import android.net.NetworkAgent;
+import android.net.QosSession;
import android.telephony.data.EpsBearerQosSessionAttributes;
import android.telephony.data.EpsQos;
import android.telephony.data.Qos;
import android.telephony.data.QosBearerFilter;
import android.telephony.data.QosBearerSession;
-import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -51,7 +53,6 @@
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.ArrayList;
-import java.util.Arrays;
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@@ -60,6 +61,7 @@
class Filter implements QosCallbackTracker.IFilter {
InetSocketAddress mLocalAddress;
InetSocketAddress mRemoteAddress;
+ int mProtocol = QosBearerFilter.QOS_PROTOCOL_TCP;
Filter(@NonNull final InetSocketAddress localAddress) {
this.mLocalAddress = localAddress;
@@ -76,7 +78,7 @@
final int startPort, final int endPort) {
return startPort <= mLocalAddress.getPort()
&& endPort >= mLocalAddress.getPort()
- && mLocalAddress.getAddress().equals(address);
+ && (address.isAnyLocalAddress() || mLocalAddress.getAddress().equals(address));
}
public boolean matchesRemoteAddress(final @NonNull InetAddress address,
@@ -84,13 +86,18 @@
return mRemoteAddress != null
&& startPort <= mRemoteAddress.getPort()
&& endPort >= mRemoteAddress.getPort()
- && mRemoteAddress.getAddress().equals(address);
+ && (address.isAnyLocalAddress() || mRemoteAddress.getAddress().equals(address));
+ }
+
+ public boolean matchesProtocol(int protocol) {
+ return mProtocol == protocol;
}
}
// Mocked classes
private Phone mPhone;
private TelephonyNetworkAgent mNetworkAgent;
+ private INetworkAgentRegistry mINetworkAgentRegistry;
private Network mNetwork;
private RcsStats mRcsStats;
@@ -101,6 +108,9 @@
super.setUp(getClass().getSimpleName());
mPhone = mock(Phone.class);
mNetworkAgent = mock(TelephonyNetworkAgent.class);
+ mINetworkAgentRegistry = mock(INetworkAgentRegistry.class);
+ replaceInstance(NetworkAgent.class, "mRegistry", mNetworkAgent, mINetworkAgentRegistry);
+ replaceInstance(NetworkAgent.class, "mPreConnectedQueue", mNetworkAgent, new ArrayList());
mNetwork = mock(Network.class);
mRcsStats = mock(RcsStats.class);
doReturn(mNetwork).when(mNetworkAgent).getNetwork();
@@ -132,28 +142,44 @@
public static QosBearerFilter createIpv4QosFilter(String localAddress,
QosBearerFilter.PortRange localPort, int precedence) {
+ ArrayList<LinkAddress> localAddresses = new ArrayList<>();
+ if (localAddress != null) {
+ localAddresses.add(
+ new LinkAddress(InetAddresses.parseNumericAddress(localAddress), 32));
+ }
return new QosBearerFilter(
- Arrays.asList(
- new LinkAddress(InetAddresses.parseNumericAddress(localAddress), 32)),
- new ArrayList<>(), localPort, null, QosBearerFilter.QOS_PROTOCOL_TCP,
- 7, 987, 678, QosBearerFilter.QOS_FILTER_DIRECTION_BIDIRECTIONAL, precedence);
+ localAddresses, new ArrayList<>(), localPort, null,
+ QosBearerFilter.QOS_PROTOCOL_TCP, 7, 987, 678,
+ QosBearerFilter.QOS_FILTER_DIRECTION_BIDIRECTIONAL, precedence);
}
private static QosBearerFilter createIpv4QosFilter(String localAddress, String remoteAddress,
QosBearerFilter.PortRange localPort, QosBearerFilter.PortRange remotePort,
int precedence) {
+ return createIpv4QosFilter(localAddress, remoteAddress, localPort, remotePort,
+ QosBearerFilter.QOS_PROTOCOL_TCP, precedence);
+ }
+
+ private static QosBearerFilter createIpv4QosFilter(String localAddress, String remoteAddress,
+ QosBearerFilter.PortRange localPort, QosBearerFilter.PortRange remotePort, int protocol,
+ int precedence) {
+ ArrayList<LinkAddress> localAddresses = new ArrayList<>();
+ if (localAddress != null) {
+ localAddresses.add(
+ new LinkAddress(InetAddresses.parseNumericAddress(localAddress), 32));
+ }
+ ArrayList<LinkAddress> remoteAddresses = new ArrayList<>();
+ if (localAddress != null) {
+ remoteAddresses.add(
+ new LinkAddress(InetAddresses.parseNumericAddress(remoteAddress), 32));
+ }
return new QosBearerFilter(
- Arrays.asList(
- new LinkAddress(InetAddresses.parseNumericAddress(localAddress), 32)),
- Arrays.asList(
- new LinkAddress(InetAddresses.parseNumericAddress(remoteAddress), 32)),
- localPort, remotePort,
- QosBearerFilter.QOS_PROTOCOL_TCP, 7, 987, 678,
+ localAddresses, remoteAddresses, localPort, remotePort,
+ protocol, 7, 987, 678,
QosBearerFilter.QOS_FILTER_DIRECTION_BIDIRECTIONAL, precedence);
}
@Test
- @SmallTest
public void testAddFilterBeforeUpdateSessions() throws Exception {
Filter filter = new Filter(new InetSocketAddress(
InetAddresses.parseNumericAddress("122.22.22.22"), 2222));
@@ -170,8 +196,8 @@
mQosCallbackTracker.updateSessions(qosSessions);
processAllMessages();
- verify(mNetworkAgent, never()).notifyQosSessionAvailable(eq(1),
- eq(1234), any(EpsBearerQosSessionAttributes.class));
+ verify(mINetworkAgentRegistry, never()).sendEpsQosSessionAvailable(eq(1),
+ any(QosSession.class), any(EpsBearerQosSessionAttributes.class));
// Matching QosBearerFilter
ArrayList<QosBearerFilter> qosFilters2 = new ArrayList<>();
@@ -182,14 +208,12 @@
mQosCallbackTracker.updateSessions(qosSessions);
processAllMessages();
- verify(mNetworkAgent, times(1)).notifyQosSessionAvailable(eq(1),
- eq(1235), any(EpsBearerQosSessionAttributes.class));
-
+ verify(mINetworkAgentRegistry, times(1)).sendEpsQosSessionAvailable(eq(1),
+ any(QosSession.class), any(EpsBearerQosSessionAttributes.class));
}
@Test
- @SmallTest
public void testAddFilterAfterUpdateSessions() throws Exception {
// Non-matching QosBearerFilter
ArrayList<QosBearerFilter> qosFilters1 = new ArrayList<>();
@@ -213,13 +237,11 @@
mQosCallbackTracker.addFilter(1, filter);
processAllMessages();
- verify(mNetworkAgent, times(1)).notifyQosSessionAvailable(eq(1),
- eq(1235), any(EpsBearerQosSessionAttributes.class));
-
+ verify(mINetworkAgentRegistry, times(1)).sendEpsQosSessionAvailable(eq(1),
+ any(QosSession.class), any(EpsBearerQosSessionAttributes.class));
}
@Test
- @SmallTest
public void testRemoveFilter() throws Exception {
// Add filter
Filter filter = new Filter(new InetSocketAddress(
@@ -237,8 +259,8 @@
mQosCallbackTracker.updateSessions(qosSessions);
processAllMessages();
- verify(mNetworkAgent, never()).notifyQosSessionAvailable(eq(1),
- eq(1234), any(EpsBearerQosSessionAttributes.class));
+ verify(mINetworkAgentRegistry, never()).sendEpsQosSessionAvailable(eq(1),
+ any(QosSession.class), any(EpsBearerQosSessionAttributes.class));
// Remove the filter
mQosCallbackTracker.removeFilter(1);
@@ -253,13 +275,11 @@
processAllMessages();
// Verify that notifyQosSessionAvailable is not invoked as the filter is already removed
- verify(mNetworkAgent, never()).notifyQosSessionAvailable(eq(1),
- eq(1235), any(EpsBearerQosSessionAttributes.class));
-
+ verify(mINetworkAgentRegistry, never()).sendEpsQosSessionAvailable(eq(1),
+ any(QosSession.class), any(EpsBearerQosSessionAttributes.class));
}
@Test
- @SmallTest
public void testSessionLost() throws Exception {
// Non-matching QosBearerFilter
ArrayList<QosBearerFilter> qosFilters1 = new ArrayList<>();
@@ -287,19 +307,18 @@
mQosCallbackTracker.addFilter(1, filter);
processAllMessages();
- verify(mNetworkAgent, times(1)).notifyQosSessionAvailable(eq(1),
- eq(1235), any(EpsBearerQosSessionAttributes.class));
+ verify(mINetworkAgentRegistry, times(1)).sendEpsQosSessionAvailable(eq(1),
+ any(QosSession.class), any(EpsBearerQosSessionAttributes.class));
// Remove the matching QosBearerFilter
qosSessions.remove(1);
mQosCallbackTracker.updateSessions(qosSessions);
processAllMessages();
- verify(mNetworkAgent, times(1)).notifyQosSessionLost(eq(1), eq(1235), eq(1));
+ verify(mINetworkAgentRegistry, times(1)).sendQosSessionLost(eq(1), any(QosSession.class));
}
@Test
- @SmallTest
public void testModifiedQos() throws Exception {
// Non-matching QosBearerFilter
ArrayList<QosBearerFilter> qosFilters1 = new ArrayList<>();
@@ -326,10 +345,10 @@
mQosCallbackTracker.addFilter(1, filter);
processAllMessages();
- verify(mNetworkAgent, times(1)).notifyQosSessionAvailable(eq(1),
- eq(1235), any(EpsBearerQosSessionAttributes.class));
+ verify(mINetworkAgentRegistry, times(1)).sendEpsQosSessionAvailable(eq(1),
+ any(QosSession.class), any(EpsBearerQosSessionAttributes.class));
- reset(mNetworkAgent);
+ reset(mINetworkAgentRegistry);
// Update the QOS
qosSessions.remove(1);
@@ -337,12 +356,11 @@
mQosCallbackTracker.updateSessions(qosSessions);
processAllMessages();
- verify(mNetworkAgent, times(1)).notifyQosSessionAvailable(eq(1),
- eq(1235), any(EpsBearerQosSessionAttributes.class));
+ verify(mINetworkAgentRegistry, times(1)).sendEpsQosSessionAvailable(eq(1),
+ any(QosSession.class), any(EpsBearerQosSessionAttributes.class));
}
@Test
- @SmallTest
public void testUnmodifiedQos() throws Exception {
// Non-matching QosBearerFilter
ArrayList<QosBearerFilter> qosFilters1 = new ArrayList<>();
@@ -369,8 +387,8 @@
mQosCallbackTracker.addFilter(1, filter);
processAllMessages();
- verify(mNetworkAgent, times(1)).notifyQosSessionAvailable(eq(1),
- eq(1235), any(EpsBearerQosSessionAttributes.class));
+ verify(mINetworkAgentRegistry, times(1)).sendEpsQosSessionAvailable(eq(1),
+ any(QosSession.class), any(EpsBearerQosSessionAttributes.class));
reset(mNetworkAgent);
@@ -380,12 +398,11 @@
mQosCallbackTracker.updateSessions(qosSessions);
processAllMessages();
- verify(mNetworkAgent, never()).notifyQosSessionAvailable(eq(1),
- eq(1235), any(EpsBearerQosSessionAttributes.class));
+ verify(mINetworkAgentRegistry, times(1)).sendEpsQosSessionAvailable(eq(1),
+ any(QosSession.class), any(EpsBearerQosSessionAttributes.class));
}
@Test
- @SmallTest
public void testEmptyQosSessions() throws Exception {
// Add filter
Filter filter = new Filter(new InetSocketAddress(
@@ -418,21 +435,21 @@
mQosCallbackTracker.addFilter(2, filter2);
processAllMessages();
- verify(mNetworkAgent, times(1)).notifyQosSessionAvailable(eq(1),
- eq(1234), any(EpsBearerQosSessionAttributes.class));
- verify(mNetworkAgent, times(1)).notifyQosSessionAvailable(eq(2),
- eq(1235), any(EpsBearerQosSessionAttributes.class));
+ verify(mINetworkAgentRegistry, times(1)).sendEpsQosSessionAvailable(eq(1),
+ any(QosSession.class), any(EpsBearerQosSessionAttributes.class));
+ verify(mINetworkAgentRegistry, times(1)).sendEpsQosSessionAvailable(eq(2),
+ any(QosSession.class), any(EpsBearerQosSessionAttributes.class));
+
// Update empty QOS sessions list
mQosCallbackTracker.updateSessions(new ArrayList<>());
processAllMessages();
- verify(mNetworkAgent, times(1)).notifyQosSessionLost(eq(1), eq(1234), eq(1));
- verify(mNetworkAgent, times(1)).notifyQosSessionLost(eq(2), eq(1235), eq(1));
+ verify(mINetworkAgentRegistry, times(1)).sendQosSessionLost(eq(1), any(QosSession.class));
+ verify(mINetworkAgentRegistry, times(1)).sendQosSessionLost(eq(2), any(QosSession.class));
}
@Test
- @SmallTest
public void testMultipleQosSessions() throws Exception {
// Add filter 1
Filter filter1 = new Filter(new InetSocketAddress(
@@ -465,21 +482,20 @@
mQosCallbackTracker.updateSessions(qosSessions);
processAllMessages();
- verify(mNetworkAgent, times(1)).notifyQosSessionAvailable(eq(1),
- eq(1234), any(EpsBearerQosSessionAttributes.class));
- verify(mNetworkAgent, times(1)).notifyQosSessionAvailable(eq(2),
- eq(1235), any(EpsBearerQosSessionAttributes.class));
+ verify(mINetworkAgentRegistry, times(1)).sendEpsQosSessionAvailable(eq(1),
+ any(QosSession.class), any(EpsBearerQosSessionAttributes.class));
+ verify(mINetworkAgentRegistry, times(1)).sendEpsQosSessionAvailable(eq(2),
+ any(QosSession.class), any(EpsBearerQosSessionAttributes.class));
// Update empty QOS sessions list
mQosCallbackTracker.updateSessions(new ArrayList<>());
processAllMessages();
- verify(mNetworkAgent, times(1)).notifyQosSessionLost(eq(1), eq(1234), eq(1));
- verify(mNetworkAgent, times(1)).notifyQosSessionLost(eq(2), eq(1235), eq(1));
+ verify(mINetworkAgentRegistry, times(1)).sendQosSessionLost(eq(1), any(QosSession.class));
+ verify(mINetworkAgentRegistry, times(1)).sendQosSessionLost(eq(2), any(QosSession.class));
}
@Test
- @SmallTest
public void testQosSessionWithInvalidPortRange() throws Exception {
// Non-matching QosBearerFilter
ArrayList<QosBearerFilter> qosFilters1 = new ArrayList<>();
@@ -503,14 +519,110 @@
mQosCallbackTracker.addFilter(1, filter);
processAllMessages();
- verify(mNetworkAgent, never()).notifyQosSessionAvailable(eq(1),
- eq(1235), any(EpsBearerQosSessionAttributes.class));
-
+ verify(mINetworkAgentRegistry, never()).sendEpsQosSessionAvailable(eq(1),
+ any(QosSession.class), any(EpsBearerQosSessionAttributes.class));
}
@Test
- @SmallTest
- public void testQosMetrics() throws Exception {
+ public void testQosSessionFilterPortRangeWithoutAddress() throws Exception {
+ // QosBearerFilter including remote port range without remote address
+ ArrayList<QosBearerFilter> qosFilters1 = new ArrayList<>();
+ qosFilters1.add(createIpv4QosFilter(null, null, null,
+ new QosBearerFilter.PortRange(3200, 3220), 45));
+
+ ArrayList<QosBearerSession> qosSessions = new ArrayList<>();
+ qosSessions.add(new QosBearerSession(1234, createEpsQos(5, 6, 7, 8), qosFilters1));
+
+ mQosCallbackTracker.updateSessions(qosSessions);
+
+ // Add filter after updateSessions
+ Filter filter = new Filter(new InetSocketAddress(
+ InetAddresses.parseNumericAddress("122.22.22.22"), 1357),
+ new InetSocketAddress(InetAddresses.parseNumericAddress("177.77.77.77"), 3202));
+ mQosCallbackTracker.addFilter(1, filter);
+ processAllMessages();
+
+ verify(mINetworkAgentRegistry, times(1)).sendEpsQosSessionAvailable(eq(1),
+ any(QosSession.class), any(EpsBearerQosSessionAttributes.class));
+
+ // Remove the matching QosBearerFilter
+ qosSessions.remove(0);
+ mQosCallbackTracker.updateSessions(qosSessions);
+ processAllMessages();
+
+ verify(mINetworkAgentRegistry, times(1)).sendQosSessionLost(eq(1), any(QosSession.class));
+ }
+
+ @Test
+ public void testQosSessionFilterProtocol() throws Exception {
+ // QosBearerFilter including protocol
+ ArrayList<QosBearerFilter> qosFilters1 = new ArrayList<>();
+ qosFilters1.add(createIpv4QosFilter(null, null, null,
+ new QosBearerFilter.PortRange(3200, 3220), QosBearerFilter.QOS_PROTOCOL_UDP, 45));
+ ArrayList<QosBearerSession> qosSessions = new ArrayList<>();
+ qosSessions.add(new QosBearerSession(1234, createEpsQos(5, 6, 7, 8), qosFilters1));
+
+ mQosCallbackTracker.updateSessions(qosSessions);
+
+ // Add filter after updateSessions
+ Filter filter = new Filter(new InetSocketAddress(
+ InetAddresses.parseNumericAddress("122.22.22.22"), 1357),
+ new InetSocketAddress(InetAddresses.parseNumericAddress("177.77.77.77"), 3207));
+ mQosCallbackTracker.addFilter(1, filter);
+ processAllMessages();
+ verify(mINetworkAgentRegistry, never()).sendEpsQosSessionAvailable(eq(1),
+ any(QosSession.class), any(EpsBearerQosSessionAttributes.class));
+
+ // Remove the matching QosBearerFilter
+ qosSessions.remove(0);
+ mQosCallbackTracker.updateSessions(qosSessions);
+ processAllMessages();
+ verify(mINetworkAgentRegistry, never()).sendQosSessionLost(eq(1), any(QosSession.class));
+
+ qosFilters1.clear();
+ qosFilters1.add(createIpv4QosFilter(null, null, null,
+ new QosBearerFilter.PortRange(3200, 3220), QosBearerFilter.QOS_PROTOCOL_TCP, 45));
+ qosSessions.clear();
+ qosSessions.add(new QosBearerSession(1234, createEpsQos(5, 6, 7, 8), qosFilters1));
+ mQosCallbackTracker.updateSessions(qosSessions);
+ processAllMessages();
+ verify(mINetworkAgentRegistry, times(1)).sendEpsQosSessionAvailable(eq(1),
+ any(QosSession.class), any(EpsBearerQosSessionAttributes.class));
+ qosSessions.remove(0);
+ mQosCallbackTracker.updateSessions(qosSessions);
+ processAllMessages();
+ verify(mINetworkAgentRegistry, times(1)).sendQosSessionLost(eq(1), any(QosSession.class));
+ }
+
+ @Test
+ public void testQosSessionFilterProtocolEsp() throws Exception {
+ // QosBearerFilter including protocol
+ ArrayList<QosBearerFilter> qosFilters1 = new ArrayList<>();
+ qosFilters1.add(createIpv4QosFilter(null, null, null,
+ new QosBearerFilter.PortRange(3200, 3220), QosBearerFilter.QOS_PROTOCOL_ESP, 45));
+ ArrayList<QosBearerSession> qosSessions = new ArrayList<>();
+ qosSessions.add(new QosBearerSession(1234, createEpsQos(5, 6, 7, 8), qosFilters1));
+
+ mQosCallbackTracker.updateSessions(qosSessions);
+
+ // Add filter after updateSessions
+ Filter filter = new Filter(new InetSocketAddress(
+ InetAddresses.parseNumericAddress("122.22.22.22"), 1357),
+ new InetSocketAddress(InetAddresses.parseNumericAddress("177.77.77.77"), 3211));
+ mQosCallbackTracker.addFilter(1, filter);
+ processAllMessages();
+ verify(mINetworkAgentRegistry, times(1)).sendEpsQosSessionAvailable(eq(1),
+ any(QosSession.class), any(EpsBearerQosSessionAttributes.class));
+
+ // Remove the matching QosBearerFilter
+ qosSessions.remove(0);
+ mQosCallbackTracker.updateSessions(qosSessions);
+ processAllMessages();
+ verify(mINetworkAgentRegistry, times(1)).sendQosSessionLost(eq(1), any(QosSession.class));
+ }
+
+ @Test
+ public void testQosMetrics() {
final int callbackId = 1;
final int slotId = mPhone.getPhoneId();
// Add filter before update session
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkFactoryTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkFactoryTest.java
index f03194f..bcc63f3 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkFactoryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkFactoryTest.java
@@ -22,24 +22,18 @@
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.net.NetworkCapabilities;
import android.net.NetworkProvider;
import android.net.NetworkRequest;
import android.net.TelephonyNetworkSpecifier;
-import android.os.AsyncResult;
-import android.os.Handler;
import android.os.Looper;
import android.os.Message;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.data.ApnSetting;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -49,9 +43,6 @@
import com.android.internal.telephony.RadioConfig;
import com.android.internal.telephony.TelephonyTest;
-import com.android.internal.telephony.dataconnection.DataConnection;
-import com.android.internal.telephony.dataconnection.TransportManager.HandoverParams;
-import com.android.internal.telephony.dataconnection.TransportManager.HandoverParams.HandoverCallback;
import com.android.telephony.Rlog;
import org.junit.After;
@@ -60,9 +51,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
-import org.mockito.Mockito;
-import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
@@ -75,13 +64,12 @@
// Mocked classes
PhoneSwitcher mPhoneSwitcher;
private RadioConfig mMockRadioConfig;
- private DataConnection mDataConnection;
private String mTestName = "";
// List of all requests filed by a test
private final ArraySet<TelephonyNetworkRequest> mAllNetworkRequestSet = new ArraySet<>();
- // List of requests active in DcTracker
+ // List of requests active
private final ArrayList<TelephonyNetworkRequest> mNetworkRequestList = new ArrayList<>();
// List of complete messages associated with the network requests
private final Map<TelephonyNetworkRequest, Message> mNetworkRequestMessageMap = new HashMap<>();
@@ -157,7 +145,6 @@
super.setUp(getClass().getSimpleName());
mPhoneSwitcher = mock(PhoneSwitcher.class);
mMockRadioConfig = mock(RadioConfig.class);
- mDataConnection = mock(DataConnection.class);
replaceInstance(RadioConfig.class, "sRadioConfig", null, mMockRadioConfig);
mContextFixture.putStringArrayResource(com.android.internal.R.array.networkAttributes,
@@ -231,7 +218,7 @@
}
/**
- * Test that phone active changes cause the DcTracker to get poked.
+ * Test that phone active changes
*/
@FlakyTest
@Test
@@ -302,7 +289,7 @@
}
/**
- * Test that network request changes cause the DcTracker to get poked.
+ * Test that network request changes
*/
@Test
@SmallTest
@@ -366,81 +353,4 @@
processAllMessages();
assertEquals(3, mNetworkRequestList.size());
}
-
- /**
- * Test handover when there is no live data connection
- */
- @Test
- @SmallTest
- @Ignore("b/256052233")
- public void testHandoverNoLiveData() throws Exception {
- createMockedTelephonyComponents();
- doReturn(0).when(mSubscriptionController).getSubIdUsingPhoneId(0);
- mTelephonyNetworkFactoryUT.mInternalHandler.sendEmptyMessage(
- TelephonyNetworkFactory.EVENT_SUBSCRIPTION_CHANGED);
-
- activatePhoneInPhoneSwitcher(0, true);
- makeDefaultInternetRequest();
-
- makeSubSpecificMmsRequest(0);
- processAllMessages();
-
- Field f = TelephonyNetworkFactory.class.getDeclaredField("mInternalHandler");
- f.setAccessible(true);
- Handler h = (Handler) f.get(mTelephonyNetworkFactoryUT);
-
- HandoverCallback handoverCallback = mock(HandoverCallback.class);
-
- HandoverParams hp = new HandoverParams(ApnSetting.TYPE_MMS,
- AccessNetworkConstants.TRANSPORT_TYPE_WLAN, handoverCallback);
- AsyncResult ar = new AsyncResult(null, hp, null);
- h.sendMessage(h.obtainMessage(5, ar));
- processAllMessages();
-
- doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WLAN).when(mAccessNetworksManager)
- .getCurrentTransport(anyInt());
-
- hp = new HandoverParams(ApnSetting.TYPE_MMS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
- handoverCallback);
- ar = new AsyncResult(null, hp, null);
- h.sendMessage(h.obtainMessage(5, ar));
- processAllMessages();
- }
-
- /**
- * Test handover when the data connection is being connected.
- */
- @Test
- @SmallTest
- @Ignore("b/256052233")
- public void testHandoverActivatingData() throws Exception {
- createMockedTelephonyComponents();
- doReturn(0).when(mSubscriptionController).getSubIdUsingPhoneId(0);
- mTelephonyNetworkFactoryUT.mInternalHandler.sendEmptyMessage(
- TelephonyNetworkFactory.EVENT_SUBSCRIPTION_CHANGED);
-
- activatePhoneInPhoneSwitcher(0, true);
- makeDefaultInternetRequest();
-
- makeSubSpecificMmsRequest(0);
- processAllMessages();
-
- Field f = TelephonyNetworkFactory.class.getDeclaredField("mInternalHandler");
- f.setAccessible(true);
- Handler h = (Handler) f.get(mTelephonyNetworkFactoryUT);
-
- HandoverCallback handoverCallback = mock(HandoverCallback.class);
- Mockito.reset(mDataNetworkController);
- doReturn(mDataConnection).when(mDcTracker).getDataConnectionByApnType(anyString());
- doReturn(false).when(mDataConnection).isActive();
-
- HandoverParams hp = new HandoverParams(ApnSetting.TYPE_MMS,
- AccessNetworkConstants.TRANSPORT_TYPE_WLAN, handoverCallback);
- AsyncResult ar = new AsyncResult(null, hp, null);
- h.sendMessage(h.obtainMessage(5, ar));
- processAllMessages();
-
- verify(mDataNetworkController, times(1)).removeNetworkRequest(any());
- verify(mDataNetworkController, times(1)).addNetworkRequest(any());
- }
}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnConfigTypeRepositoryTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnConfigTypeRepositoryTest.java
deleted file mode 100644
index f2d694f..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnConfigTypeRepositoryTest.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import static junit.framework.Assert.assertEquals;
-
-import android.os.PersistableBundle;
-import android.telephony.CarrierConfigManager;
-import android.telephony.data.ApnSetting;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class ApnConfigTypeRepositoryTest {
-
- PersistableBundle mCarrierConfig;
-
- @Before
- public void setUp() throws Exception {
- mCarrierConfig = new PersistableBundle();
- }
-
- @After
- public void tearDown() {
- mCarrierConfig = null;
- }
-
- @Test
- public void testReturnsDefaultsWhenCarrierConfigNull() {
- ApnConfigTypeRepository repository = new ApnConfigTypeRepository(null);
- checkDefaults(repository);
- }
-
- @Test
- public void testReturnsDefaultsWhenCarrierConfigApnContextKeyReturnsNull() {
- mCarrierConfig.putStringArray(CarrierConfigManager.KEY_APN_PRIORITY_STRING_ARRAY,
- null);
-
- ApnConfigTypeRepository repository = new ApnConfigTypeRepository(mCarrierConfig);
- checkDefaults(repository);
- }
-
- @Test
- public void testReturnsDefaultsWhenCarrierConfigHasInvalidTypes() {
-
- List<String> apnConfigStringArray = new ArrayList<>();
- apnConfigStringArray.add("xcap,cbs:3");
- apnConfigStringArray.add("default:0a");
-
- mCarrierConfig.putStringArray(CarrierConfigManager.KEY_APN_PRIORITY_STRING_ARRAY,
- apnConfigStringArray.toArray(new String[0]));
-
- ApnConfigTypeRepository repository = new ApnConfigTypeRepository(mCarrierConfig);
- checkDefaults(repository);
- }
-
- @Test
- public void testReturnsCarrierConfigOverride() {
- List<String> apnConfigStringArray = new ArrayList<>();
- //Shouldn't match or override any keys
- apnConfigStringArray.add("xcap,cbs:3");
-
- //Priorities must be integers
- apnConfigStringArray.add("default:10a");
-
- //Key isn't case sensitive, which means that this priority should be taken
- apnConfigStringArray.add("fotA:10");
-
- mCarrierConfig.putStringArray(CarrierConfigManager.KEY_APN_PRIORITY_STRING_ARRAY,
- apnConfigStringArray.toArray(new String[0]));
-
- ApnConfigTypeRepository repository = new ApnConfigTypeRepository(mCarrierConfig);
- assertEquals(10, repository.getByType(ApnSetting.TYPE_FOTA).getPriority());
- checkDefaults(repository);
- }
-
- private void checkDefaults(ApnConfigTypeRepository repository) {
- assertEquals(0, repository.getByType(ApnSetting.TYPE_ENTERPRISE).getPriority());
- assertEquals(1, repository.getByType(ApnSetting.TYPE_DEFAULT).getPriority());
- assertEquals(2, repository.getByType(ApnSetting.TYPE_MMS).getPriority());
- assertEquals(2, repository.getByType(ApnSetting.TYPE_SUPL).getPriority());
- assertEquals(2, repository.getByType(ApnSetting.TYPE_DUN).getPriority());
- assertEquals(3, repository.getByType(ApnSetting.TYPE_HIPRI).getPriority());
- assertEquals(2, repository.getByType(ApnSetting.TYPE_IMS).getPriority());
- assertEquals(2, repository.getByType(ApnSetting.TYPE_CBS).getPriority());
- assertEquals(2, repository.getByType(ApnSetting.TYPE_IA).getPriority());
- assertEquals(2, repository.getByType(ApnSetting.TYPE_EMERGENCY).getPriority());
- assertEquals(3, repository.getByType(ApnSetting.TYPE_MCX).getPriority());
- assertEquals(3, repository.getByType(ApnSetting.TYPE_XCAP).getPriority());
- }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnContextTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnContextTest.java
deleted file mode 100644
index b270548..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnContextTest.java
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.telephony.data.ApnSetting;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.internal.R;
-import com.android.internal.telephony.DctConstants;
-import com.android.internal.telephony.TelephonyTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class ApnContextTest extends TelephonyTest {
- // Mocked classes
- ApnSetting mApnSetting;
-
- private ApnContext mApnContext;
-
- @Before
- public void setUp() throws Exception {
- super.setUp(getClass().getSimpleName());
- mApnSetting = mock(ApnSetting.class);
- mApnContext = new ApnContext(mPhone, ApnSetting.TYPE_DEFAULT, TAG, mDcTracker, 1);
- }
-
- @After
- public void tearDown() throws Exception {
- mApnContext = null;
- super.tearDown();
- }
-
- @Test
- @SmallTest
- public void testSetGetApnSetting() throws Exception {
- mApnContext.setApnSetting(mApnSetting);
- assertEquals(mApnSetting, mApnContext.getApnSetting());
- }
-
- @Test
- @SmallTest
- public void testGetApnType() {
- assertEquals(ApnSetting.TYPE_DEFAULT_STRING, mApnContext.getApnType());
- }
-
- @Test
- @SmallTest
- public void testConnectionGeneration() throws Exception {
- for (int i = 0; i < 100; i++) {
- mApnContext.incAndGetConnectionGeneration();
- assertEquals(i + 1, mApnContext.getConnectionGeneration());
- }
- }
-
- @Test
- @SmallTest
- public void testReason() throws Exception {
- mApnContext.setReason("dataEnabled");
- assertEquals("dataEnabled", mApnContext.getReason());
- mApnContext.setReason("simLoaded");
- assertEquals("simLoaded", mApnContext.getReason());
- }
-
- @Test
- @SmallTest
- public void testState() throws Exception {
- mApnContext.setState(DctConstants.State.DISCONNECTING);
- assertEquals(DctConstants.State.DISCONNECTING, mApnContext.getState());
- mApnContext.setEnabled(true);
- assertFalse(mApnContext.isConnectable());
-
- mApnContext.setState(DctConstants.State.RETRYING);
- assertTrue(mApnContext.isConnectable());
- assertTrue(mApnContext.isConnectedOrConnecting());
-
- mApnContext.setState(DctConstants.State.FAILED);
- assertTrue(mApnContext.isDisconnected());
- mApnContext.setState(DctConstants.State.IDLE);
- assertTrue(mApnContext.isDisconnected());
- }
-
- @Test
- @SmallTest
- public void testNetworkRequestNormal() throws Exception {
- NetworkRequest nr1 = new NetworkRequest.Builder().build();
- mApnContext.requestNetwork(nr1, DcTracker.REQUEST_TYPE_NORMAL, null);
-
- verify(mDcTracker, times(1)).enableApn(eq(ApnSetting.TYPE_DEFAULT),
- eq(DcTracker.REQUEST_TYPE_NORMAL), eq(null));
-
- NetworkRequest nr2 = new NetworkRequest.Builder()
- .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
- .build();
-
- mApnContext.requestNetwork(nr2, DcTracker.REQUEST_TYPE_NORMAL, null);
- verify(mDcTracker, times(2)).enableApn(eq(ApnSetting.TYPE_DEFAULT),
- eq(DcTracker.REQUEST_TYPE_NORMAL), eq(null));
-
- mApnContext.releaseNetwork(nr1, DcTracker.RELEASE_TYPE_NORMAL);
- verify(mDcTracker, never()).disableApn(eq(ApnSetting.TYPE_DEFAULT),
- eq(DcTracker.RELEASE_TYPE_NORMAL));
-
- mApnContext.releaseNetwork(nr2, DcTracker.RELEASE_TYPE_NORMAL);
- verify(mDcTracker, times(1)).disableApn(eq(ApnSetting.TYPE_DEFAULT),
- eq(DcTracker.RELEASE_TYPE_NORMAL));
- }
-
- @Test
- @SmallTest
- public void testNetworkRequestDetach() throws Exception {
- NetworkRequest nr1 = new NetworkRequest.Builder().build();
- mApnContext.requestNetwork(nr1, DcTracker.REQUEST_TYPE_NORMAL, null);
- verify(mDcTracker, times(1)).enableApn(eq(ApnSetting.TYPE_DEFAULT),
- eq(DcTracker.REQUEST_TYPE_NORMAL), eq(null));
-
- NetworkRequest nr2 = new NetworkRequest.Builder()
- .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
- .build();
-
- mApnContext.requestNetwork(nr2, DcTracker.REQUEST_TYPE_NORMAL, null);
- verify(mDcTracker, times(2)).enableApn(eq(ApnSetting.TYPE_DEFAULT),
- eq(DcTracker.REQUEST_TYPE_NORMAL), eq(null));
-
- mApnContext.releaseNetwork(nr1, DcTracker.RELEASE_TYPE_DETACH);
- verify(mDcTracker, times(1)).disableApn(eq(ApnSetting.TYPE_DEFAULT),
- eq(DcTracker.RELEASE_TYPE_DETACH));
-
- mApnContext.releaseNetwork(nr2, DcTracker.RELEASE_TYPE_NORMAL);
- verify(mDcTracker, times(1)).disableApn(eq(ApnSetting.TYPE_DEFAULT),
- eq(DcTracker.RELEASE_TYPE_NORMAL));
- }
-
- @Test
- @SmallTest
- public void testNetworkRequestHandover() throws Exception {
- NetworkRequest nr1 = new NetworkRequest.Builder().build();
- mApnContext.requestNetwork(nr1, DcTracker.REQUEST_TYPE_HANDOVER, null);
- verify(mDcTracker, times(1)).enableApn(eq(ApnSetting.TYPE_DEFAULT),
- eq(DcTracker.REQUEST_TYPE_HANDOVER), eq(null));
-
- mApnContext.releaseNetwork(nr1, DcTracker.RELEASE_TYPE_HANDOVER);
- verify(mDcTracker, times(1)).disableApn(eq(ApnSetting.TYPE_DEFAULT),
- eq(DcTracker.RELEASE_TYPE_HANDOVER));
- }
-
- @Test
- @SmallTest
- public void testConcurrentVoiceAndDataAllowed() throws Exception {
- mApnContext.setConcurrentVoiceAndDataAllowed(true);
- assertTrue(mApnContext.isConcurrentVoiceAndDataAllowed());
- mApnContext.setConcurrentVoiceAndDataAllowed(false);
- assertFalse(mApnContext.isConcurrentVoiceAndDataAllowed());
- }
-
- @Test
- @SmallTest
- public void testEnableDisable() throws Exception {
- mApnContext.setEnabled(true);
- assertTrue(mApnContext.isEnabled());
- mApnContext.setEnabled(false);
- assertFalse(mApnContext.isEnabled());
- }
-
- @Test
- @SmallTest
- public void testProvisionApn() throws Exception {
- mContextFixture.putResource(R.string.mobile_provisioning_apn, "fake_apn");
-
- ApnSetting myApn = new ApnSetting.Builder()
- .setId(2163)
- .setOperatorNumeric("44010")
- .setEntryName("sp-mode")
- .setApnName("fake_apn")
- .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL)
- .setProtocol(ApnSetting.PROTOCOL_IP)
- .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
- .setCarrierEnabled(true)
- .build();
-
- mApnContext.setApnSetting(myApn);
- assertTrue(mApnContext.isProvisioningApn());
- mApnContext.setApnSetting(mApnSetting);
- assertFalse(mApnContext.isProvisioningApn());
- }
-
- @Test
- @SmallTest
- public void testIsReady() throws Exception {
- mApnContext.setEnabled(true);
- assertTrue(mApnContext.isReady());
-
- mApnContext.setEnabled(false);
- assertFalse(mApnContext.isReady());
- }
-
- @Test
- @SmallTest
- public void testErrorCodeRetry() throws Exception {
- mContextFixture.putStringArrayResource(
- com.android.internal.R.array.config_cell_retries_per_error_code,
- new String[]{"36,2"});
- mApnContext.resetErrorCodeRetries();
-
- assertFalse(mApnContext.restartOnError(36));
- assertTrue(mApnContext.restartOnError(36));
- assertFalse(mApnContext.restartOnError(37));
- }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
deleted file mode 100644
index dcaa2a0..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
+++ /dev/null
@@ -1,1479 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED;
-
-import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
-import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_ADDRESS;
-import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_DNS;
-import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_GATEWAY;
-import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_IFNAME;
-import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_PCSCF_ADDRESS;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyBoolean;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
-import android.net.InetAddresses;
-import android.net.KeepalivePacketData;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.NattKeepalivePacketData;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.vcn.VcnNetworkPolicyResult;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Message;
-import android.os.UserManager;
-import android.provider.Telephony;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.AccessNetworkConstants.AccessNetworkType;
-import android.telephony.CarrierConfigManager;
-import android.telephony.ServiceState;
-import android.telephony.ServiceState.RegState;
-import android.telephony.ServiceState.RilRadioTechnology;
-import android.telephony.TelephonyManager;
-import android.telephony.data.ApnSetting;
-import android.telephony.data.DataCallResponse;
-import android.telephony.data.DataProfile;
-import android.telephony.data.DataService;
-import android.telephony.data.DataServiceCallback;
-import android.telephony.data.TrafficDescriptor;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Pair;
-
-import com.android.internal.R;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.RetryManager;
-import com.android.internal.telephony.TelephonyTest;
-import com.android.internal.telephony.data.KeepaliveStatus;
-import com.android.internal.telephony.dataconnection.DataConnection.ConnectionParams;
-import com.android.internal.telephony.dataconnection.DataConnection.DisconnectParams;
-import com.android.internal.telephony.dataconnection.DataConnection.SetupResult;
-import com.android.internal.telephony.metrics.DataCallSessionStats;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.function.Consumer;
-
-public class DataConnectionTest extends TelephonyTest {
- private static final int DEFAULT_DC_CID = 10;
- private static final ArrayList<TrafficDescriptor> DEFAULT_TD_LIST = new ArrayList<>();
-
- // Mocked classes
- DcTesterFailBringUpAll mDcTesterFailBringUpAll;
- ConnectionParams mCp;
- DisconnectParams mDcp;
- ApnContext mApnContext;
- ApnContext mEnterpriseApnContext;
- DcFailBringUp mDcFailBringUp;
- DataCallSessionStats mDataCallSessionStats;
- DataConnection mDefaultDc;
- DataServiceManager mDataServiceManager;
-
- private DataConnection mDc;
- private DataConnectionTestHandler mDataConnectionTestHandler;
- private DcController mDcc;
-
- private final ApnSetting mApn1 = new ApnSetting.Builder()
- .setId(2163)
- .setOperatorNumeric("44010")
- .setEntryName("sp-mode")
- .setApnName("spmode.ne.jp")
- .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL)
- .setProtocol(ApnSetting.PROTOCOL_IP)
- .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
- .setCarrierEnabled(true)
- .build();
-
- private final ApnSetting mApn2 = new ApnSetting.Builder()
- .setId(2164)
- .setOperatorNumeric("44010")
- .setEntryName("sp-mode")
- .setApnName("spmode.ne.jp")
- .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_DUN)
- .setProtocol(ApnSetting.PROTOCOL_IP)
- .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
- .setCarrierEnabled(true)
- .build();
-
- private final ApnSetting mApn3 = new ApnSetting.Builder()
- .setId(2165)
- .setOperatorNumeric("44010")
- .setEntryName("sp-mode")
- .setApnName("spmode.ne.jp")
- .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT)
- .setProtocol(ApnSetting.PROTOCOL_IPV6)
- .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
- .setNetworkTypeBitmask(0)
- .setCarrierEnabled(true)
- .setCarrierId(1)
- .setSkip464Xlat(1)
- .build();
-
- private final ApnSetting mApn4 = new ApnSetting.Builder()
- .setId(2166)
- .setOperatorNumeric("44010")
- .setEntryName("sp-mode")
- .setApnName("spmode.ne.jp")
- .setApnTypeBitmask(ApnSetting.TYPE_IMS)
- .setProtocol(ApnSetting.PROTOCOL_IPV6)
- .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
- .setCarrierEnabled(true)
- .build();
-
- private final ApnSetting mApn5 = new ApnSetting.Builder()
- .setId(2167)
- .setOperatorNumeric("44010")
- .setEntryName("sp-mode")
- .setApnName("spmode.ne.jp")
- .setApnTypeBitmask(ApnSetting.TYPE_IMS)
- .setProtocol(ApnSetting.PROTOCOL_IPV6)
- .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
- .setCarrierEnabled(true)
- .setSkip464Xlat(Telephony.Carriers.SKIP_464XLAT_DISABLE)
- .build();
-
- private final ApnSetting mApn6 = new ApnSetting.Builder()
- .setId(2168)
- .setOperatorNumeric("44010")
- .setEntryName("sp-mode")
- .setApnName("spmode.ne.jp")
- .setApnTypeBitmask(ApnSetting.TYPE_EMERGENCY)
- .setProtocol(ApnSetting.PROTOCOL_IP)
- .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
- .setCarrierEnabled(true)
- .build();
-
- private class DataConnectionTestHandler extends HandlerThread {
-
- private DataConnectionTestHandler(String name) {
- super(name);
- }
-
- @Override
- public void onLooperPrepared() {
- Handler h = new Handler();
- mDcc = DcController.makeDcc(mPhone, mDcTracker, mDataServiceManager, h.getLooper(), "");
- mDc = DataConnection.makeDataConnection(mPhone, 0, mDcTracker, mDataServiceManager,
- mDcTesterFailBringUpAll, mDcc);
- }
- }
-
- private void setSuccessfulSetupDataResponse(int cid, ArrayList<TrafficDescriptor> tds) {
- doAnswer(invocation -> {
- final Message msg = (Message) invocation.getArguments()[10];
-
- DataCallResponse response = new DataCallResponse.Builder()
- .setCause(0)
- .setRetryDurationMillis(-1L)
- .setId(cid)
- .setLinkStatus(2)
- .setProtocolType(ApnSetting.PROTOCOL_IPV4V6)
- .setInterfaceName("ifname")
- .setAddresses(Arrays.asList(
- new LinkAddress(InetAddresses.parseNumericAddress("10.0.2.15"), 32),
- new LinkAddress("2607:fb90:a620:651d:eabe:f8da:c107:44be/64")))
- .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress("10.0.2.3"),
- InetAddresses.parseNumericAddress("fd00:976a::9")))
- .setGatewayAddresses(Arrays.asList(
- InetAddresses.parseNumericAddress("10.0.2.15"),
- InetAddresses.parseNumericAddress("fe80::2")))
- .setPcscfAddresses(Arrays.asList(
- InetAddresses.parseNumericAddress("fd00:976a:c305:1d::8"),
- InetAddresses.parseNumericAddress("fd00:976a:c202:1d::7"),
- InetAddresses.parseNumericAddress("fd00:976a:c305:1d::5")))
- .setMtu(1500)
- .setMtuV4(1500)
- .setMtuV6(1500)
- .setPduSessionId(1)
- .setQosBearerSessions(new ArrayList<>())
- .setTrafficDescriptors(tds)
- .build();
- msg.getData().putParcelable("data_call_response", response);
- msg.arg1 = DataServiceCallback.RESULT_SUCCESS;
- msg.sendToTarget();
- return null;
- }).when(mDataServiceManager).setupDataCall(anyInt(), any(DataProfile.class), anyBoolean(),
- anyBoolean(), anyInt(), any(), anyInt(), any(), any(), anyBoolean(),
- any(Message.class));
- }
-
- private void setFailedSetupDataResponse(@DataServiceCallback.ResultCode int resultCode) {
- doAnswer(invocation -> {
- final Message msg = (Message) invocation.getArguments()[10];
- msg.arg1 = resultCode;
- msg.sendToTarget();
- return null;
- }).when(mDataServiceManager).setupDataCall(anyInt(), any(DataProfile.class), anyBoolean(),
- anyBoolean(), anyInt(), any(), anyInt(), any(), any(), anyBoolean(),
- any(Message.class));
- }
-
- @Before
- public void setUp() throws Exception {
- super.setUp(getClass().getSimpleName());
- mDcTesterFailBringUpAll = mock(DcTesterFailBringUpAll.class);
- mCp = mock(ConnectionParams.class);
- mDcp = mock(DisconnectParams.class);
- mApnContext = mock(ApnContext.class);
- mEnterpriseApnContext = mock(ApnContext.class);
- mDcFailBringUp = mock(DcFailBringUp.class);
- mDataCallSessionStats = mock(DataCallSessionStats.class);
- mDefaultDc = mock(DataConnection.class);
- mDataServiceManager = mock(DataServiceManager.class);
- logd("+Setup!");
- doReturn("fake.action_detached").when(mPhone).getActionDetached();
- doReturn(false).when(mPhone).isUsingNewDataStack();
- replaceInstance(ConnectionParams.class, "mApnContext", mCp, mApnContext);
- replaceInstance(ConnectionParams.class, "mRilRat", mCp,
- 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();
-
- mContextFixture.putStringArrayResource(com.android.internal.R.array
- .config_mobile_tcp_buffers, new String[]{
- "umts:131072,262144,1452032,4096,16384,399360",
- "hspa:131072,262144,2441216,4096,16384,399360",
- "hsupa:131072,262144,2441216,4096,16384,399360",
- "hsdpa:131072,262144,2441216,4096,16384,399360",
- "hspap:131072,262144,2441216,4096,16384,399360",
- "edge:16384,32768,131072,4096,16384,65536",
- "gprs:4096,8192,24576,4096,8192,24576",
- "1xrtt:16384,32768,131070,4096,16384,102400",
- "evdo:131072,262144,1048576,4096,16384,524288",
- "lte:524288,1048576,8388608,262144,524288,4194304"});
-
- mContextFixture.putResource(R.string.config_wwan_data_service_package,
- "com.android.phone");
-
- mDcp.mApnContext = mApnContext;
-
- setSuccessfulSetupDataResponse(DEFAULT_DC_CID, DEFAULT_TD_LIST);
-
- doAnswer(invocation -> {
- final Message msg = (Message) invocation.getArguments()[2];
- msg.arg1 = DataServiceCallback.RESULT_SUCCESS;
- msg.sendToTarget();
- return null;
- }).when(mDataServiceManager).deactivateDataCall(anyInt(), anyInt(), any(Message.class));
-
- doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).when(mDataServiceManager)
- .getTransportType();
-
- mDataConnectionTestHandler = new DataConnectionTestHandler(getClass().getSimpleName());
- mDataConnectionTestHandler.start();
-
- waitForMs(200);
- mDc.setDataCallSessionStats(mDataCallSessionStats);
-
- logd("-Setup!");
- }
-
- @After
- public void tearDown() throws Exception {
- logd("tearDown");
- mDc.quitNow();
- mDc = null;
- mDataConnectionTestHandler.quit();
- mDataConnectionTestHandler.join();
- mDataConnectionTestHandler = null;
- mDcc.removeCallbacksAndMessages(null);
- mDcc = null;
- DEFAULT_TD_LIST.clear();
- waitForMs(100);
- super.tearDown();
- }
-
- private long getSuggestedRetryDelay(DataCallResponse response) throws Exception {
- Class[] cArgs = new Class[1];
- cArgs[0] = DataCallResponse.class;
- Method method = DataConnection.class.getDeclaredMethod("getSuggestedRetryDelay", cArgs);
- method.setAccessible(true);
- return (long) method.invoke(mDc, response);
- }
-
- private boolean isUnmeteredUseOnly() throws Exception {
- Method method = DataConnection.class.getDeclaredMethod("isUnmeteredUseOnly");
- method.setAccessible(true);
- return (boolean) method.invoke(mDc);
- }
-
- private boolean isEnterpriseUse() throws Exception {
- Method method = DataConnection.class.getDeclaredMethod("isEnterpriseUse");
- method.setAccessible(true);
- return (boolean) method.invoke(mDc);
- }
-
- private boolean isSuspended() throws Exception {
- Field field = DataConnection.class.getDeclaredField("mIsSuspended");
- field.setAccessible(true);
- return field.getBoolean(mDc);
- }
-
- private SetupResult setLinkProperties(DataCallResponse response, LinkProperties linkProperties)
- throws Exception {
- Class[] cArgs = new Class[2];
- cArgs[0] = DataCallResponse.class;
- cArgs[1] = LinkProperties.class;
- Method method = DataConnection.class.getDeclaredMethod("setLinkProperties", cArgs);
- method.setAccessible(true);
- return (SetupResult) method.invoke(mDc, response, linkProperties);
- }
-
- @Test
- @SmallTest
- public void testConnectEvent() {
- assertTrue(mDc.isInactive());
- connectEvent(true);
-
- verify(mCT, times(1)).registerForVoiceCallStarted(any(Handler.class),
- eq(DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_STARTED), eq(null));
- verify(mCT, times(1)).registerForVoiceCallEnded(any(Handler.class),
- eq(DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_ENDED), eq(null));
- verify(mSimulatedCommandsVerifier, times(1))
- .registerForNattKeepaliveStatus(any(Handler.class),
- eq(DataConnection.EVENT_KEEPALIVE_STATUS), eq(null));
- verify(mSimulatedCommandsVerifier, times(1))
- .registerForLceInfo(any(Handler.class),
- eq(DataConnection.EVENT_LINK_CAPACITY_CHANGED), eq(null));
- verify(mVcnManager, atLeastOnce())
- .applyVcnNetworkPolicy(
- argThat(caps ->
- caps.hasCapability(
- NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)),
- any());
-
- ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
- ArgumentCaptor<TrafficDescriptor> tdCaptor =
- ArgumentCaptor.forClass(TrafficDescriptor.class);
- verify(mDataServiceManager, times(1)).setupDataCall(
- eq(AccessNetworkType.UTRAN), dpCaptor.capture(), eq(false),
- eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), tdCaptor.capture(), anyBoolean(), any(Message.class));
-
- verify(mSimulatedCommandsVerifier, times(0))
- .allocatePduSessionId(any());
-
- assertEquals("spmode.ne.jp", dpCaptor.getValue().getApn());
- if (tdCaptor.getValue() != null) {
- if (mApnContext.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE) {
- assertEquals(null, tdCaptor.getValue().getDataNetworkName());
- assertTrue(Arrays.equals(DataConnection.getEnterpriseOsAppId(),
- tdCaptor.getValue().getOsAppId()));
- } else {
- assertEquals("spmode.ne.jp", tdCaptor.getValue().getDataNetworkName());
- assertEquals(null, tdCaptor.getValue().getOsAppId());
- }
- }
- assertTrue(mDc.isActive());
-
- assertEquals(1, mDc.getPduSessionId());
- assertEquals(3, mDc.getPcscfAddresses().length);
- assertTrue(Arrays.stream(mDc.getPcscfAddresses()).anyMatch("fd00:976a:c305:1d::8"::equals));
- assertTrue(Arrays.stream(mDc.getPcscfAddresses()).anyMatch("fd00:976a:c202:1d::7"::equals));
- assertTrue(Arrays.stream(mDc.getPcscfAddresses()).anyMatch("fd00:976a:c305:1d::5"::equals));
- }
-
- @Test
- @SmallTest
- public void testConnectOnIwlan() throws Exception {
- assertTrue(mDc.isInactive());
- Field field = DataConnection.class.getDeclaredField("mTransportType");
- field.setAccessible(true);
- field.setInt(mDc, AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
- connectEvent(true);
-
- verify(mCT, times(1)).registerForVoiceCallStarted(any(Handler.class),
- eq(DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_STARTED), eq(null));
- verify(mCT, times(1)).registerForVoiceCallEnded(any(Handler.class),
- eq(DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_ENDED), eq(null));
- verify(mSimulatedCommandsVerifier, times(0))
- .registerForNattKeepaliveStatus(any(Handler.class),
- eq(DataConnection.EVENT_KEEPALIVE_STATUS), eq(null));
- verify(mSimulatedCommandsVerifier, times(0))
- .registerForLceInfo(any(Handler.class),
- eq(DataConnection.EVENT_LINK_CAPACITY_CHANGED), eq(null));
- verify(mVcnManager, atLeastOnce())
- .applyVcnNetworkPolicy(
- argThat(caps ->
- caps.hasCapability(
- NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)),
- any());
-
- ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
- ArgumentCaptor<TrafficDescriptor> tdCaptor =
- ArgumentCaptor.forClass(TrafficDescriptor.class);
- verify(mDataServiceManager, times(1)).setupDataCall(
- eq(AccessNetworkType.UTRAN), dpCaptor.capture(), eq(false),
- eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), tdCaptor.capture(), anyBoolean(), any(Message.class));
-
- verify(mSimulatedCommandsVerifier, times(1))
- .allocatePduSessionId(any());
-
- assertEquals("spmode.ne.jp", dpCaptor.getValue().getApn());
- if (tdCaptor.getValue() != null) {
- if (mApnContext.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE) {
- assertEquals(null, tdCaptor.getValue().getDataNetworkName());
- assertTrue(Arrays.equals(DataConnection.getEnterpriseOsAppId(),
- tdCaptor.getValue().getOsAppId()));
- } else {
- assertEquals("spmode.ne.jp", tdCaptor.getValue().getDataNetworkName());
- assertEquals(null, tdCaptor.getValue().getOsAppId());
- }
- }
- assertTrue(mDc.isActive());
-
- assertEquals(1, mDc.getPduSessionId());
- assertEquals(3, mDc.getPcscfAddresses().length);
- assertTrue(Arrays.stream(mDc.getPcscfAddresses()).anyMatch("fd00:976a:c305:1d::8"::equals));
- assertTrue(Arrays.stream(mDc.getPcscfAddresses()).anyMatch("fd00:976a:c202:1d::7"::equals));
- assertTrue(Arrays.stream(mDc.getPcscfAddresses()).anyMatch("fd00:976a:c305:1d::5"::equals));
- }
-
- @Test
- public void testConnectEventDuplicateContextIds() throws Exception {
- setUpDefaultData(DEFAULT_DC_CID);
-
- // 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);
- assertTrue(mDc.isInactive());
-
- // Change the CID
- setSuccessfulSetupDataResponse(DEFAULT_DC_CID + 1, DEFAULT_TD_LIST);
-
- // Verify that ENTERPRISE was set up
- connectEvent(true);
- assertTrue(mDc.getNetworkCapabilities().hasCapability(
- NetworkCapabilities.NET_CAPABILITY_ENTERPRISE));
- }
-
- @Test
- public void testConnectEventDuplicateContextIdsDifferentTDs() throws Exception {
- setUpDefaultData(DEFAULT_DC_CID);
-
- // Try to connect ENTERPRISE with the same CID as default but different TrafficDescriptors
- 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();
- ArrayList<TrafficDescriptor> tdList = new ArrayList<>();
- tdList.add(new TrafficDescriptor("dnn", DataConnection.getEnterpriseOsAppId()));
- setSuccessfulSetupDataResponse(DEFAULT_DC_CID, tdList);
-
- // Verify that ENTERPRISE wasn't set up but the TD list was updated
- connectEvent(false);
- assertTrue(mDc.isInactive());
- ArgumentCaptor<DataCallResponse> captor = ArgumentCaptor.forClass(DataCallResponse.class);
- verify(mDefaultDc).updateTrafficDescriptors(captor.capture());
- assertEquals(tdList, captor.getValue().getTrafficDescriptors());
- }
-
- @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);
- assertTrue(mDc.isInactive());
-
- // Set up default data
- replaceInstance(ConnectionParams.class, "mApnContext", mCp, mApnContext);
- setUpDefaultData(1);
-
- // 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(int cid) throws Exception {
- replaceInstance(DataConnection.class, "mCid", mDefaultDc, 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() {
- testConnectEvent();
-
- mDc.setPduSessionId(5);
- disconnectEvent();
-
- verify(mSimulatedCommandsVerifier, times(1)).unregisterForLceInfo(any(Handler.class));
- verify(mSimulatedCommandsVerifier, times(1))
- .unregisterForNattKeepaliveStatus(any(Handler.class));
- verify(mDataServiceManager, times(1)).deactivateDataCall(eq(DEFAULT_DC_CID),
- eq(DataService.REQUEST_REASON_NORMAL), any(Message.class));
- verify(mSimulatedCommandsVerifier, times(0))
- .releasePduSessionId(any(), eq(5));
-
- assertTrue(mDc.isInactive());
- }
-
- @Test
- @SmallTest
- public void testDisconnectOnIwlan() throws Exception {
- testConnectEvent();
-
- Field field = DataConnection.class.getDeclaredField("mTransportType");
- field.setAccessible(true);
- field.setInt(mDc, AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
- mDc.setPduSessionId(5);
- disconnectEvent();
-
- verify(mSimulatedCommandsVerifier, times(0)).unregisterForLceInfo(any(Handler.class));
- verify(mSimulatedCommandsVerifier, times(0))
- .unregisterForNattKeepaliveStatus(any(Handler.class));
- verify(mDataServiceManager, times(1)).deactivateDataCall(eq(DEFAULT_DC_CID),
- eq(DataService.REQUEST_REASON_NORMAL), any(Message.class));
- verify(mSimulatedCommandsVerifier, times(1))
- .releasePduSessionId(any(), eq(5));
-
- assertTrue(mDc.isInactive());
- }
-
- @Test
- @SmallTest
- public void testModemSuggestRetry() throws Exception {
- DataCallResponse response = new DataCallResponse.Builder()
- .setCause(0)
- .setRetryDurationMillis(0)
- .setId(1)
- .setLinkStatus(2)
- .setProtocolType(ApnSetting.PROTOCOL_IP)
- .setInterfaceName(FAKE_IFNAME)
- .setAddresses(Arrays.asList(
- new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0)))
- .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS)))
- .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY)))
- .setPcscfAddresses(
- Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS)))
- .setMtuV4(1440)
- .setMtuV6(1440)
- .build();
- assertEquals(response.getSuggestedRetryTime(), getSuggestedRetryDelay(response));
-
- response = new DataCallResponse.Builder()
- .setCause(0)
- .setRetryDurationMillis(1000)
- .setId(1)
- .setLinkStatus(2)
- .setProtocolType(ApnSetting.PROTOCOL_IP)
- .setInterfaceName(FAKE_IFNAME)
- .setAddresses(Arrays.asList(
- new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0)))
- .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS)))
- .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY)))
- .setPcscfAddresses(
- Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS)))
- .setMtuV4(1440)
- .setMtuV6(1440)
- .build();
- assertEquals(response.getSuggestedRetryTime(), getSuggestedRetryDelay(response));
-
- response = new DataCallResponse.Builder()
- .setCause(0)
- .setRetryDurationMillis(9999)
- .setId(1)
- .setLinkStatus(2)
- .setProtocolType(ApnSetting.PROTOCOL_IP)
- .setInterfaceName(FAKE_IFNAME)
- .setAddresses(Arrays.asList(
- new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0)))
- .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS)))
- .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY)))
- .setPcscfAddresses(
- Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS)))
- .setMtuV4(1440)
- .setMtuV6(1440)
- .build();
- assertEquals(response.getSuggestedRetryTime(), getSuggestedRetryDelay(response));
- }
-
- @Test
- @SmallTest
- public void testModemNotSuggestRetry() throws Exception {
- DataCallResponse response = new DataCallResponse.Builder()
- .setCause(0)
- .setRetryDurationMillis(-1)
- .setId(1)
- .setLinkStatus(2)
- .setProtocolType(ApnSetting.PROTOCOL_IP)
- .setInterfaceName(FAKE_IFNAME)
- .setAddresses(Arrays.asList(
- new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0)))
- .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS)))
- .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY)))
- .setPcscfAddresses(
- Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS)))
- .setMtuV4(1440)
- .setMtuV6(1440)
- .build();
- assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY, getSuggestedRetryDelay(response));
-
- response = new DataCallResponse.Builder()
- .setCause(0)
- .setRetryDurationMillis(-5)
- .setId(1)
- .setLinkStatus(2)
- .setProtocolType(ApnSetting.PROTOCOL_IP)
- .setInterfaceName(FAKE_IFNAME)
- .setAddresses(Arrays.asList(
- new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0)))
- .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS)))
- .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY)))
- .setPcscfAddresses(
- Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS)))
- .setMtuV4(1440)
- .setMtuV6(1440)
- .build();
- assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY, getSuggestedRetryDelay(response));
-
- response = new DataCallResponse.Builder()
- .setCause(0)
- .setRetryDurationMillis(Long.MIN_VALUE)
- .setId(1)
- .setLinkStatus(2)
- .setProtocolType(ApnSetting.PROTOCOL_IP)
- .setInterfaceName(FAKE_IFNAME)
- .setAddresses(Arrays.asList(
- new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0)))
- .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS)))
- .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY)))
- .setPcscfAddresses(
- Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS)))
- .setMtuV4(1440)
- .setMtuV6(1440)
- .build();
- assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY, getSuggestedRetryDelay(response));
- }
-
- @Test
- @SmallTest
- public void testModemSuggestNoRetry() throws Exception {
- DataCallResponse response = new DataCallResponse.Builder()
- .setCause(0)
- .setRetryDurationMillis(Long.MAX_VALUE)
- .setId(1)
- .setLinkStatus(2)
- .setProtocolType(ApnSetting.PROTOCOL_IP)
- .setInterfaceName(FAKE_IFNAME)
- .setAddresses(Arrays.asList(
- new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0)))
- .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS)))
- .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY)))
- .setPcscfAddresses(
- Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS)))
- .setMtuV4(1440)
- .setMtuV6(1440)
- .build();
- assertEquals(RetryManager.NO_RETRY, getSuggestedRetryDelay(response));
- }
-
- private NetworkCapabilities getNetworkCapabilities() throws Exception {
- Method method = DataConnection.class.getDeclaredMethod("getNetworkCapabilities");
- method.setAccessible(true);
- return (NetworkCapabilities) method.invoke(mDc);
- }
-
- private int getDisallowedApnTypes() throws Exception {
- Method method = DataConnection.class.getDeclaredMethod("getDisallowedApnTypes");
- method.setAccessible(true);
- return (int) method.invoke(mDc);
- }
-
- @Test
- @SmallTest
- public void testNetworkCapability() 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));
-
- mContextFixture.getCarrierConfigBundle().putStringArray(
- CarrierConfigManager.KEY_CARRIER_WWAN_DISALLOWED_APN_TYPES_STRING_ARRAY,
- new String[] {"supl"});
-
- disconnectEvent();
- doReturn(mApn1).when(mApnContext).getApnSetting();
- connectEvent(true);
-
- assertFalse("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_SUPL));
- assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
- .hasCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE));
- }
-
- @Test
- @SmallTest
- public void testVcnNetworkCapability() throws Exception {
- mContextFixture.getCarrierConfigBundle().putStringArray(
- CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[] { "default" });
- doReturn(mApn2).when(mApnContext).getApnSetting();
-
- doAnswer(invocation -> {
- NetworkCapabilities nc = invocation.getArgument(0);
- NetworkCapabilities policyNc = new NetworkCapabilities.Builder(nc)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
- .build();
-
- return new VcnNetworkPolicyResult(
- false /* isTearDownRequested */, policyNc);
- }).when(mVcnManager).applyVcnNetworkPolicy(any(), any());
- connectEvent(true);
-
- assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
- .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED));
- assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
- .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED));
-
- disconnectEvent();
-
- doAnswer(invocation -> {
- NetworkCapabilities nc = invocation.getArgument(0);
- NetworkCapabilities policyNc = new NetworkCapabilities.Builder(nc)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
- .build();
-
- return new VcnNetworkPolicyResult(
- false /* isTearDownRequested */, policyNc);
- }).when(mVcnManager).applyVcnNetworkPolicy(any(), any());
- connectEvent(true);
-
- assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
- .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED));
- assertTrue("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
- .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED));
- }
-
- @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(1);
- 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));
- assertTrue("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));
- }
-
- @Test
- @SmallTest
- public void testMeteredCapability() throws Exception {
-
- mContextFixture.getCarrierConfigBundle().
- putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[] {"default"});
-
- testConnectEvent();
-
- assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED));
- }
-
- @Test
- @SmallTest
- public void testNonMeteredCapability() throws Exception {
-
- doReturn(2819).when(mPhone).getSubId();
- mContextFixture.getCarrierConfigBundle().
- putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[] {"mms"});
-
- testConnectEvent();
-
- assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED));
- }
-
- @Test
- public void testOverrideUnmetered() throws Exception {
- mContextFixture.getCarrierConfigBundle().putStringArray(
- CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[] { "default" });
- testConnectEvent();
-
- assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED));
- assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
- 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));
- assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_CONGESTED));
- }
-
- @Test
- public void testOverrideCongested() throws Exception {
- mContextFixture.getCarrierConfigBundle().putStringArray(
- CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[] { "default" });
- testConnectEvent();
-
- assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_METERED));
- assertFalse(getNetworkCapabilities().hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED));
- 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));
- assertTrue(getNetworkCapabilities().hasCapability(NET_CAPABILITY_NOT_CONGESTED));
- }
-
- @Test
- public void testOwnerUid() throws Exception {
- Context mockContext = mContextFixture.getTestDouble();
- doReturn(mockContext).when(mPhone).getContext();
-
- String testPkg = "com.android.telephony.test";
- TelephonyManager telMgr = mockContext.getSystemService(TelephonyManager.class);
- doReturn(testPkg).when(telMgr).getCarrierServicePackageNameForLogicalSlot(anyInt());
-
- UserInfo info = new UserInfo(0 /* id */, "TEST_USER", 0 /* flags */);
- UserManager userMgr = mockContext.getSystemService(UserManager.class);
- doReturn(Collections.singletonList(info)).when(userMgr).getUsers();
-
- int carrierConfigPkgUid = 12345;
- PackageManager pkgMgr = mockContext.getPackageManager();
- doReturn(carrierConfigPkgUid).when(pkgMgr).getPackageUidAsUser(eq(testPkg), anyInt());
-
- mContextFixture
- .getCarrierConfigBundle()
- .putStringArray(
- CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[] {"default"});
- testConnectEvent();
- AsyncResult adminUidsResult = new AsyncResult(null, new int[] {carrierConfigPkgUid}, null);
- mDc.sendMessage(DataConnection.EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED, adminUidsResult);
- // Wait for carirer privilege UIDs to be updated
- waitForMs(100);
-
- assertEquals(carrierConfigPkgUid, getNetworkCapabilities().getOwnerUid());
- assertEquals(
- Collections.singleton(carrierConfigPkgUid),
- getNetworkCapabilities().getAllowedUids());
- }
-
- @Test
- public void testSubscriptionIds() throws Exception {
- mContextFixture.getCarrierConfigBundle().putStringArray(
- CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[] { "default" });
- testConnectEvent();
-
- assertEquals(Collections.singleton(0), getNetworkCapabilities().getSubscriptionIds());
- }
-
- @Test
- public void testShouldSkip464Xlat() throws Exception {
- assertFalse(testShouldSkip464XlatEvent(mApn1));
- disconnectEvent();
-
- assertTrue(testShouldSkip464XlatEvent(mApn3));
- disconnectEvent();
-
- assertTrue(testShouldSkip464XlatEvent(mApn4));
- disconnectEvent();
-
- assertFalse(testShouldSkip464XlatEvent(mApn5));
- disconnectEvent();
- }
-
- private boolean testShouldSkip464XlatEvent(ApnSetting apn) throws Exception {
- Method method = DataConnection.class.getDeclaredMethod("shouldSkip464Xlat");
- method.setAccessible(true);
-
- doReturn(apn).when(mApnContext).getApnSetting();
- doReturn(apn.getApnTypeBitmask()).when(mApnContext).getApnTypeBitmask();
- connectEvent(true);
- logd(getNetworkCapabilities().toString());
-
- return (Boolean) method.invoke(mDc);
- }
-
- private void connectEvent(boolean validate) {
- mDc.sendMessage(DataConnection.EVENT_CONNECT, mCp);
- waitForMs(200);
- if (validate) {
- assertTrue(mDc.isActive());
- }
- }
-
- private void disconnectEvent() {
- mDc.sendMessage(DataConnection.EVENT_DISCONNECT, mDcp);
- waitForMs(100);
- assertTrue(mDc.isInactive());
- }
-
- private void serviceStateChangedEvent(@RegState int dataRegState, @RilRadioTechnology int rat) {
- mDc.obtainMessage(DataConnection.EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED,
- new AsyncResult(null, new Pair<>(dataRegState, rat), null)).sendToTarget();
- waitForMs(100);
- }
-
- @Test
- @SmallTest
- public void testIsIpAddress() {
- // IPv4
- assertTrue(DataConnection.isIpAddress("1.2.3.4"));
- assertTrue(DataConnection.isIpAddress("127.0.0.1"));
-
- // IPv6
- assertTrue(DataConnection.isIpAddress("::1"));
- assertTrue(DataConnection.isIpAddress("2001:4860:800d::68"));
- }
-
- @Test
- @SmallTest
- public void testSetLinkProperties() throws Exception {
- DataCallResponse response = new DataCallResponse.Builder()
- .setCause(0)
- .setRetryDurationMillis(-1)
- .setId(1)
- .setLinkStatus(2)
- .setProtocolType(ApnSetting.PROTOCOL_IP)
- .setInterfaceName(FAKE_IFNAME)
- .setAddresses(Arrays.asList(
- new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0)))
- .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS)))
- .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY)))
- .setPcscfAddresses(
- Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS)))
- .setMtuV4(1440)
- .setMtuV6(1440)
- .build();
-
- LinkProperties linkProperties = new LinkProperties();
- assertEquals(SetupResult.SUCCESS, setLinkProperties(response, linkProperties));
- logd(linkProperties.toString());
- assertEquals(response.getInterfaceName(), linkProperties.getInterfaceName());
- assertEquals(response.getAddresses().size(), linkProperties.getAddresses().size());
- for (int i = 0; i < response.getAddresses().size(); ++i) {
- assertEquals(response.getAddresses().get(i).getAddress(),
- InetAddresses.parseNumericAddress(linkProperties.getLinkAddresses().get(i)
- .getAddress().getHostAddress()));
- }
-
- assertEquals(response.getDnsAddresses().size(), linkProperties.getDnsServers().size());
- for (int i = 0; i < response.getDnsAddresses().size(); ++i) {
- assertEquals("i = " + i, response.getDnsAddresses().get(i),
- InetAddresses.parseNumericAddress(
- linkProperties.getDnsServers().get(i).getHostAddress()));
- }
-
- assertEquals(response.getGatewayAddresses().size(), linkProperties.getRoutes().size());
- for (int i = 0; i < response.getGatewayAddresses().size(); ++i) {
- assertEquals("i = " + i, response.getGatewayAddresses().get(i),
- InetAddresses.parseNumericAddress(linkProperties.getRoutes().get(i)
- .getGateway().getHostAddress()));
- }
-
- assertEquals(response.getPcscfAddresses().size(), linkProperties.getPcscfServers().size());
- for (int i = 0; i < response.getPcscfAddresses().size(); ++i) {
- assertEquals("i = " + i, response.getPcscfAddresses().get(i),
- InetAddresses.parseNumericAddress(linkProperties.getPcscfServers().get(i)
- .getHostAddress()));
- }
-
- assertEquals(response.getMtu(), linkProperties.getMtu());
- }
-
- @Test
- @SmallTest
- public void testSetLinkPropertiesEmptyAddress() throws Exception {
- // 224.224.224.224 is an invalid address.
- DataCallResponse response = new DataCallResponse.Builder()
- .setCause(0)
- .setRetryDurationMillis(-1)
- .setId(1)
- .setLinkStatus(2)
- .setProtocolType(ApnSetting.PROTOCOL_IP)
- .setInterfaceName(FAKE_IFNAME)
- .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS)))
- .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY)))
- .setPcscfAddresses(
- Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS)))
- .setMtuV4(1440)
- .setMtuV6(1440)
- .build();
-
- LinkProperties linkProperties = new LinkProperties();
- assertEquals(SetupResult.ERROR_INVALID_ARG, setLinkProperties(response, linkProperties));
- }
-
- @Test
- @SmallTest
- public void testSetLinkPropertiesEmptyDns() throws Exception {
- // Empty dns entry.
- DataCallResponse response = new DataCallResponse.Builder()
- .setCause(0)
- .setRetryDurationMillis(-1)
- .setId(1)
- .setLinkStatus(2)
- .setProtocolType(ApnSetting.PROTOCOL_IP)
- .setInterfaceName(FAKE_IFNAME)
- .setAddresses(Arrays.asList(
- new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0)))
- .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY)))
- .setPcscfAddresses(
- Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS)))
- .setMtuV4(1440)
- .setMtuV6(1440)
- .build();
-
- // Make sure no exception was thrown
- LinkProperties linkProperties = new LinkProperties();
- assertEquals(SetupResult.SUCCESS, setLinkProperties(response, linkProperties));
- }
-
- @Test
- @SmallTest
- public void testStartKeepaliveWLAN() throws Exception {
- testConnectEvent();
- waitForMs(200);
-
- Field field = DataConnection.class.getDeclaredField("mTransportType");
- field.setAccessible(true);
- field.setInt(mDc, AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-
- final int sessionHandle = 0xF00;
- final int slotId = 3;
- final int interval = 10; // seconds
- // Construct a new KeepalivePacketData request as we would receive from a Network Agent,
- // and check that the packet is sent to the RIL.
- KeepalivePacketData kd = NattKeepalivePacketData.nattKeepalivePacket(
- InetAddresses.parseNumericAddress("1.2.3.4"),
- 1234,
- InetAddresses.parseNumericAddress("8.8.8.8"),
- 4500);
- mDc.obtainMessage(
- DataConnection.EVENT_KEEPALIVE_START_REQUEST, slotId, interval, kd).sendToTarget();
- waitForMs(100);
- // testStartStopNattKeepalive() verifies that this request is passed with WWAN.
- // Thus, even though we can't see the response in NetworkAgent, we can verify that the
- // CommandsInterface never receives a request and infer that it was dropped due to WLAN.
- verify(mSimulatedCommandsVerifier, times(0))
- .startNattKeepalive(anyInt(), eq(kd), eq(interval * 1000), any(Message.class));
- }
-
- public void checkStartStopNattKeepalive(boolean useCondensedFlow) throws Exception {
- testConnectEvent();
- waitForMs(200);
-
- final int sessionHandle = 0xF00;
- final int slotId = 3;
- final int interval = 10; // seconds
- // Construct a new KeepalivePacketData request as we would receive from a Network Agent,
- // and check that the packet is sent to the RIL.
- KeepalivePacketData kd = NattKeepalivePacketData.nattKeepalivePacket(
- InetAddresses.parseNumericAddress("1.2.3.4"),
- 1234,
- InetAddresses.parseNumericAddress("8.8.8.8"),
- 4500);
- mDc.obtainMessage(
- DataConnection.EVENT_KEEPALIVE_START_REQUEST, slotId, interval, kd).sendToTarget();
- waitForMs(100);
- verify(mSimulatedCommandsVerifier, times(1))
- .startNattKeepalive(anyInt(), eq(kd), eq(interval * 1000), any(Message.class));
-
- Message kaStarted = mDc.obtainMessage(DataConnection.EVENT_KEEPALIVE_STARTED, slotId, 0);
- if (useCondensedFlow) {
- // Send a singled condensed response that a keepalive have been requested and the
- // activation is completed. This flow should be used if the keepalive offload request
- // is handled by a high-priority signalling path.
- AsyncResult.forMessage(
- kaStarted, new KeepaliveStatus(
- sessionHandle, KeepaliveStatus.STATUS_ACTIVE), null);
- kaStarted.sendToTarget();
- } else {
- // Send the sequential responses indicating first that the request was received and
- // then that the keepalive is running. This should create an active record of the
- // keepalive in DataConnection while permitting the status from a low priority or other
- // high-latency handler to activate the keepalive without blocking a request.
- AsyncResult.forMessage(
- kaStarted, new KeepaliveStatus(
- sessionHandle, KeepaliveStatus.STATUS_PENDING), null);
- kaStarted.sendToTarget();
- Message kaRunning = mDc.obtainMessage(DataConnection.EVENT_KEEPALIVE_STATUS);
- AsyncResult.forMessage(
- kaRunning, new KeepaliveStatus(
- sessionHandle, KeepaliveStatus.STATUS_ACTIVE), null);
- kaRunning.sendToTarget();
- }
- waitForMs(100);
-
- // Verify that we can stop the connection, which checks that the record in DataConnection
- // has a valid mapping between slotId (from network agent) to sessionHandle (from Radio).
- mDc.obtainMessage(DataConnection.EVENT_KEEPALIVE_STOP_REQUEST, slotId).sendToTarget();
- waitForMs(100);
- verify(mSimulatedCommandsVerifier, times(1))
- .stopNattKeepalive(eq(sessionHandle), any(Message.class));
-
- Message kaStopped = mDc.obtainMessage(
- DataConnection.EVENT_KEEPALIVE_STOPPED, sessionHandle, slotId);
- AsyncResult.forMessage(kaStopped);
- kaStopped.sendToTarget();
- // Verify that after the connection is stopped, the mapping for a Keepalive Session is
- // removed. Thus, subsequent calls to stop the same keepalive are ignored.
- mDc.obtainMessage(DataConnection.EVENT_KEEPALIVE_STOP_REQUEST, slotId).sendToTarget();
- waitForMs(100);
- // Check that the mock has not been called subsequent to the previous invocation
- // while avoiding the use of reset()
- verify(mSimulatedCommandsVerifier, times(1))
- .stopNattKeepalive(anyInt(), any(Message.class));
- }
-
- @Test
- @MediumTest
- public void testStartStopNattKeepalive() throws Exception {
- checkStartStopNattKeepalive(false);
- }
-
- @Test
- @MediumTest
- public void testStartStopNattKeepaliveCondensed() throws Exception {
- checkStartStopNattKeepalive(true);
- }
-
- public void checkStartNattKeepaliveFail(boolean useCondensedFlow) throws Exception {
- testConnectEvent();
- waitForMs(200);
-
- final int sessionHandle = 0xF00;
- final int slotId = 3;
- final int interval = 10; // seconds
- // Construct a new KeepalivePacketData request as we would receive from a Network Agent,
- // and check that the packet is sent to the RIL.
- KeepalivePacketData kd = NattKeepalivePacketData.nattKeepalivePacket(
- InetAddresses.parseNumericAddress("1.2.3.4"),
- 1234,
- InetAddresses.parseNumericAddress("8.8.8.8"),
- 4500);
- mDc.obtainMessage(
- DataConnection.EVENT_KEEPALIVE_START_REQUEST, slotId, interval, kd).sendToTarget();
- waitForMs(100);
- verify(mSimulatedCommandsVerifier, times(1))
- .startNattKeepalive(anyInt(), eq(kd), eq(interval * 1000), any(Message.class));
-
- Message kaStarted = mDc.obtainMessage(DataConnection.EVENT_KEEPALIVE_STARTED, slotId, 0);
- if (useCondensedFlow) {
- // Indicate in the response that the keepalive has failed.
- AsyncResult.forMessage(
- kaStarted, new KeepaliveStatus(KeepaliveStatus.ERROR_UNSUPPORTED),
- null);
- kaStarted.sendToTarget();
- } else {
- // Indicate that the keepalive is queued, and then signal a failure from the modem
- // such that a pending keepalive fails to activate.
- AsyncResult.forMessage(
- kaStarted, new KeepaliveStatus(
- sessionHandle, KeepaliveStatus.STATUS_PENDING), null);
- kaStarted.sendToTarget();
- Message kaRunning = mDc.obtainMessage(DataConnection.EVENT_KEEPALIVE_STATUS);
- AsyncResult.forMessage(
- kaRunning, new KeepaliveStatus(
- sessionHandle, KeepaliveStatus.STATUS_INACTIVE), null);
- kaRunning.sendToTarget();
- }
- waitForMs(100);
- // Verify that a failed connection request cannot be stopped due to no record in
- // the DataConnection.
- mDc.obtainMessage(DataConnection.EVENT_KEEPALIVE_STOP_REQUEST, slotId).sendToTarget();
- waitForMs(100);
- verify(mSimulatedCommandsVerifier, times(0))
- .stopNattKeepalive(anyInt(), any(Message.class));
- }
-
- @Test
- @SmallTest
- public void testStartNattKeepaliveFail() throws Exception {
- checkStartNattKeepaliveFail(false);
- }
-
- @Test
- @SmallTest
- public void testStartNattKeepaliveFailCondensed() throws Exception {
- checkStartNattKeepaliveFail(true);
- }
-
- @Test
- @SmallTest
- public void testIsUnmeteredUseOnly() throws Exception {
- Field field = DataConnection.class.getDeclaredField("mTransportType");
- field.setAccessible(true);
- field.setInt(mDc, AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-
- assertFalse(isUnmeteredUseOnly());
-
- field = DataConnection.class.getDeclaredField("mTransportType");
- field.setAccessible(true);
- field.setInt(mDc, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-
- doReturn(false).when(mDataEnabledSettings).isDataEnabled();
- doReturn(false).when(mServiceState).getDataRoaming();
- doReturn(ApnSetting.TYPE_MMS).when(mApnContext).getApnTypeBitmask();
-
- mContextFixture.getCarrierConfigBundle().putStringArray(
- CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[] { "default" });
-
- assertTrue(isUnmeteredUseOnly());
- }
-
- @Test
- public void testIsEnterpriseUse() throws Exception {
- assertFalse(isEnterpriseUse());
- assertFalse(mDc.getNetworkCapabilities().hasCapability(
- NetworkCapabilities.NET_CAPABILITY_ENTERPRISE));
-
- setUpDefaultData(1);
- 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(
- CarrierConfigManager.KEY_CARRIER_WWAN_DISALLOWED_APN_TYPES_STRING_ARRAY,
- new String[] { "mms", "supl", "fota" });
- testConnectEvent();
-
- assertEquals(ApnSetting.TYPE_MMS | ApnSetting.TYPE_SUPL | ApnSetting.TYPE_FOTA,
- getDisallowedApnTypes());
- }
-
- @Test
- public void testIsSuspended() throws Exception {
- // Return false if not active state
- assertTrue(mDc.isInactive());
- assertFalse(isSuspended());
-
- // Return false for emergency APN
- doReturn(mApn6).when(mApnContext).getApnSetting();
- doReturn(ApnSetting.TYPE_EMERGENCY).when(mApnContext).getApnTypeBitmask();
- connectEvent(true);
- assertFalse(isSuspended());
-
- // Back to DEFAULT APN
- disconnectEvent();
- assertTrue(mDc.isInactive());
- doReturn(mApn1).when(mApnContext).getApnSetting();
- doReturn(ApnSetting.TYPE_DEFAULT).when(mApnContext).getApnTypeBitmask();
- doReturn(true).when(mSST).isConcurrentVoiceAndDataAllowed();
- connectEvent(true);
-
- // Before getting any service state event, the connection should not be suspended.
- assertFalse(isSuspended());
-
- // Return true if combined reg state is not in service
- serviceStateChangedEvent(ServiceState.STATE_OUT_OF_SERVICE,
- ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN);
- assertTrue(isSuspended());
-
- // Return false if in service and concurrent voice and data is allowed
- serviceStateChangedEvent(ServiceState.STATE_IN_SERVICE,
- ServiceState.RIL_RADIO_TECHNOLOGY_LTE);
- assertFalse(isSuspended());
-
- // Return false if in service and concurrent voice/data not allowed but call state is idle
- doReturn(false).when(mSST).isConcurrentVoiceAndDataAllowed();
- doReturn(PhoneConstants.State.IDLE).when(mCT).getState();
- mDc.sendMessage(DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_STARTED);
- waitForMs(100);
- assertFalse(isSuspended());
-
- // Return true if in service, concurrent voice/data not allowed, and call state not idle
- doReturn(PhoneConstants.State.RINGING).when(mCT).getState();
- mDc.sendMessage(DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_STARTED);
- waitForMs(100);
- assertTrue(isSuspended());
- }
-
- @Test
- public void testDataCreatedWhenOutOfService() throws Exception {
- serviceStateChangedEvent(ServiceState.STATE_OUT_OF_SERVICE,
- ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN);
- ArgumentCaptor<NetworkCapabilities> ncCaptor =
- ArgumentCaptor.forClass(NetworkCapabilities.class);
- doReturn(mock(Network.class)).when(mConnectivityManager).registerNetworkAgent(
- any(), any(), any(), ncCaptor.capture(), any(), any(), anyInt());
-
- doReturn(mApn1).when(mApnContext).getApnSetting();
- doReturn(ApnSetting.TYPE_DEFAULT).when(mApnContext).getApnTypeBitmask();
- doReturn(true).when(mSST).isConcurrentVoiceAndDataAllowed();
- connectEvent(true);
- waitForMs(100);
-
- NetworkCapabilities nc = ncCaptor.getValue();
- // The network must be created with NOT_SUSPENDED capability.
- assertTrue(nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED));
-
- // But it's final state must be suspended.
- assertTrue(isSuspended());
- }
-
- @Test
- public void testDataServiceTempUnavailable() throws Exception {
- setFailedSetupDataResponse(DataServiceCallback.RESULT_ERROR_TEMPORARILY_UNAVAILABLE);
- replaceInstance(ConnectionParams.class, "mRequestType", mCp,
- DcTracker.REQUEST_TYPE_NORMAL);
- // Verify that no data was setup
- connectEvent(false);
- assertTrue(mDc.isInactive());
-
- // Verify that data service did not suggest any retry (i.e. Frameworks uses configured
- // retry timer).
- verify(mDataThrottler).setRetryTime(eq(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL),
- eq(RetryManager.NO_SUGGESTED_RETRY_DELAY), eq(DcTracker.REQUEST_TYPE_NORMAL));
- }
-
- @Test
- public void testDataHandoverFailed() throws Exception {
- doReturn(mDefaultDc).when(mDcTracker).getDataConnectionByApnType(anyString());
-
- doAnswer(invocation -> {
- final Consumer<Integer> consumer = (Consumer<Integer>) invocation.getArguments()[0];
- consumer.accept(DataServiceCallback.RESULT_SUCCESS);
- return null;
- }).when(mDefaultDc).startHandover(any(Consumer.class));
-
- replaceInstance(ConnectionParams.class, "mRequestType", mCp,
- DcTracker.REQUEST_TYPE_HANDOVER);
- assertTrue(mDc.isInactive());
- connectEvent(false);
-
- // Make sure the data connection is still in inactive state
- assertTrue(mDc.isInactive());
- }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataEnabledSettingsTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataEnabledSettingsTest.java
deleted file mode 100644
index ffe4542..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataEnabledSettingsTest.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.verify;
-
-import android.os.HandlerThread;
-import android.telephony.TelephonyManager;
-import android.telephony.data.ApnSetting;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.internal.telephony.TelephonyTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-
-import java.util.Objects;
-
-public class DataEnabledSettingsTest extends TelephonyTest {
-
- private DataEnabledSettings mDataEnabledSettingsUT;
-
- private DataEnabledSettingsTestHandler mDataEnabledSettingsTestHandler;
-
- private String mRules = "";
-
- private class DataEnabledSettingsTestHandler extends HandlerThread {
-
- private DataEnabledSettingsTestHandler(String name) {
- super(name);
- }
-
- @Override
- public void onLooperPrepared() {
- mDataEnabledSettingsUT = new DataEnabledSettings(mPhone);
- setReady(true);
- }
- }
-
- @Before
- public void setUp() throws Exception {
- super.setUp(getClass().getSimpleName());
- doReturn(false).when(mPhone).isUsingNewDataStack();
- doReturn(mRules).when(mSubscriptionController).getDataEnabledOverrideRules(anyInt());
-
- doAnswer(invocation -> {
- String rules = (String) invocation.getArguments()[1];
- boolean changed = !Objects.equals(mRules, rules);
- mRules = rules;
- return changed;
- }).when(mSubscriptionController).setDataEnabledOverrideRules(anyInt(), anyString());
-
- mDataEnabledSettingsTestHandler = new DataEnabledSettingsTestHandler(
- getClass().getSimpleName());
- mDataEnabledSettingsTestHandler.start();
- waitUntilReady();
- }
-
- @After
- public void tearDown() throws Exception {
- mDataEnabledSettingsTestHandler.quit();
- mDataEnabledSettingsTestHandler.join();
- mDataEnabledSettingsTestHandler = null;
- mDataEnabledSettingsUT = null;
- super.tearDown();
- }
-
- @Test
- @SmallTest
- public void testSetDataAllowedInVoiceCall() throws Exception {
- mDataEnabledSettingsUT.setAllowDataDuringVoiceCall(true);
- ArgumentCaptor<String> stringCaptor = ArgumentCaptor.forClass(String.class);
- verify(mSubscriptionController).setDataEnabledOverrideRules(anyInt(),
- stringCaptor.capture());
- assertEquals("*=nonDefault&inVoiceCall&DefaultDataOn&dsdsEnabled", stringCaptor.getValue());
-
- clearInvocations(mSubscriptionController);
-
- mDataEnabledSettingsUT.setAllowDataDuringVoiceCall(false);
- verify(mSubscriptionController).setDataEnabledOverrideRules(anyInt(),
- stringCaptor.capture());
- assertEquals("", stringCaptor.getValue());
- }
-
- @Test
- @SmallTest
- public void testSetAlwaysAllowMmsData() throws Exception {
- mDataEnabledSettingsUT.setDataEnabled(TelephonyManager.DATA_ENABLED_REASON_USER, false);
- assertTrue(mDataEnabledSettingsUT.setAlwaysAllowMmsData(true));
- ArgumentCaptor<String> stringCaptor = ArgumentCaptor.forClass(String.class);
- verify(mSubscriptionController).setDataEnabledOverrideRules(anyInt(),
- stringCaptor.capture());
- assertEquals("mms=unconditionally", stringCaptor.getValue());
- assertTrue(mDataEnabledSettingsUT.isDataEnabled(ApnSetting.TYPE_MMS));
-
- clearInvocations(mSubscriptionController);
-
- assertTrue(mDataEnabledSettingsUT.setAlwaysAllowMmsData(false));
- verify(mSubscriptionController).setDataEnabledOverrideRules(anyInt(),
- stringCaptor.capture());
- assertEquals("", stringCaptor.getValue());
- assertFalse(mDataEnabledSettingsUT.isDataEnabled(ApnSetting.TYPE_MMS));
-
- mDataEnabledSettingsUT.setDataEnabled(TelephonyManager.DATA_ENABLED_REASON_USER, true);
- assertTrue(mDataEnabledSettingsUT.isDataEnabled(ApnSetting.TYPE_MMS));
- }
-
- @Test
- @SmallTest
- public void testSetThermalDataEnabled() throws Exception {
- mDataEnabledSettingsUT.setDataEnabled(TelephonyManager.DATA_ENABLED_REASON_THERMAL,
- false);
- assertFalse(mDataEnabledSettingsUT.isDataEnabledForReason(
- TelephonyManager.DATA_ENABLED_REASON_THERMAL));
- assertFalse(mDataEnabledSettingsUT.isDataEnabled());
-
- mDataEnabledSettingsUT.setDataEnabled(TelephonyManager.DATA_ENABLED_REASON_THERMAL,
- true);
- assertTrue(mDataEnabledSettingsUT.isDataEnabledForReason(
- TelephonyManager.DATA_ENABLED_REASON_THERMAL));
- assertTrue(mDataEnabledSettingsUT.isDataEnabled());
- }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataThrottlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataThrottlerTest.java
deleted file mode 100644
index d03bc8c..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataThrottlerTest.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/**
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import static com.android.internal.telephony.dataconnection.DcTracker.REQUEST_TYPE_HANDOVER;
-import static com.android.internal.telephony.dataconnection.DcTracker.REQUEST_TYPE_NORMAL;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.telephony.AccessNetworkConstants;
-import android.telephony.data.ApnSetting;
-import android.telephony.data.ThrottleStatus;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import com.android.internal.telephony.RetryManager;
-import com.android.internal.telephony.TelephonyTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-
-/**
- * Data throttler tests
- */
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class DataThrottlerTest extends TelephonyTest {
-
- private static final boolean DBG = true;
- private DataThrottler mDataThrottler;
-
- // Mocked classes
- private DataThrottler.Callback mMockChangedCallback1;
- private DataThrottler.Callback mMockChangedCallback2;
-
- @Before
- public void setUp() throws Exception {
- super.setUp(getClass().getSimpleName());
- mMockChangedCallback1 = mock(DataThrottler.Callback.class);
- mMockChangedCallback2 = mock(DataThrottler.Callback.class);
- mDataThrottler = new DataThrottler(mPhone, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
- mDataThrottler.registerForThrottleStatusChanges(mMockChangedCallback1);
- doReturn(false).when(mPhone).isUsingNewDataStack();
- }
-
- @After
- public void tearDown() throws Exception {
- mDataThrottler = null;
- super.tearDown();
- }
-
- /**
- * Test the behavior of a retry manager with no waiting APNs set.
- */
- @Test
- @SmallTest
- public void testSetRetryTime() throws Exception {
- final ArgumentCaptor<List<ThrottleStatus>> statusCaptor =
- ArgumentCaptor.forClass((Class) List.class);
-
- List<List<ThrottleStatus>> expectedStatuses = new ArrayList<>();
- processAllMessages();
- expectedStatuses.add(List.of());
-
- mDataThrottler.setRetryTime(ApnSetting.TYPE_DEFAULT, 1234567890L,
- REQUEST_TYPE_NORMAL);
- processAllMessages();
- assertEquals(1234567890L, mDataThrottler.getRetryTime(ApnSetting.TYPE_DEFAULT));
- assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY,
- mDataThrottler.getRetryTime(ApnSetting.TYPE_MMS));
-
- processAllMessages();
- expectedStatuses.add(List.of(
- new ThrottleStatus.Builder()
- .setSlotIndex(0)
- .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
- .setApnType(ApnSetting.TYPE_DEFAULT)
- .setThrottleExpiryTimeMillis(1234567890L)
- .setRetryType(ThrottleStatus.RETRY_TYPE_NEW_CONNECTION)
- .build())
- );
-
-
- mDataThrottler.setRetryTime(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_DUN, 13579L,
- REQUEST_TYPE_HANDOVER);
- processAllMessages();
- assertEquals(13579L, mDataThrottler.getRetryTime(ApnSetting.TYPE_DEFAULT));
- assertEquals(13579L, mDataThrottler.getRetryTime(ApnSetting.TYPE_DUN));
-
- processAllMessages();
- expectedStatuses.add(List.of(
- new ThrottleStatus.Builder()
- .setSlotIndex(0)
- .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
- .setApnType(ApnSetting.TYPE_DUN)
- .setThrottleExpiryTimeMillis(13579L)
- .setRetryType(ThrottleStatus.RETRY_TYPE_HANDOVER)
- .build(),
- new ThrottleStatus.Builder()
- .setSlotIndex(0)
- .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
- .setApnType(ApnSetting.TYPE_DEFAULT)
- .setThrottleExpiryTimeMillis(13579L)
- .setRetryType(ThrottleStatus.RETRY_TYPE_HANDOVER)
- .build())
- );
-
-
- mDataThrottler.setRetryTime(ApnSetting.TYPE_MMS, -10,
- REQUEST_TYPE_NORMAL);
- processAllMessages();
- assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY,
- mDataThrottler.getRetryTime(ApnSetting.TYPE_MMS));
- processAllMessages();
- expectedStatuses.add(List.of(
- new ThrottleStatus.Builder()
- .setSlotIndex(0)
- .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
- .setNoThrottle()
- .setApnType(ApnSetting.TYPE_MMS)
- .setRetryType(ThrottleStatus.RETRY_TYPE_NEW_CONNECTION)
- .build()
- ));
-
- mDataThrottler.setRetryTime(ApnSetting.TYPE_FOTA | ApnSetting.TYPE_EMERGENCY,
- RetryManager.NO_RETRY, REQUEST_TYPE_HANDOVER);
-
- processAllMessages();
- expectedStatuses.add(List.of(
- new ThrottleStatus.Builder()
- .setSlotIndex(0)
- .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
- .setApnType(ApnSetting.TYPE_EMERGENCY)
- .setThrottleExpiryTimeMillis(RetryManager.NO_RETRY)
- .setRetryType(ThrottleStatus.RETRY_TYPE_NONE)
- .build(),
- new ThrottleStatus.Builder()
- .setSlotIndex(0)
- .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
- .setApnType(ApnSetting.TYPE_FOTA)
- .setThrottleExpiryTimeMillis(RetryManager.NO_RETRY)
- .setRetryType(ThrottleStatus.RETRY_TYPE_NONE)
- .build()
- ));
-
- assertEquals(RetryManager.NO_RETRY, mDataThrottler.getRetryTime(ApnSetting.TYPE_FOTA));
- assertEquals(RetryManager.NO_RETRY, mDataThrottler.getRetryTime(ApnSetting.TYPE_EMERGENCY));
-
-
- // Loop through statuses and test everything
- verify(mMockChangedCallback1, times(expectedStatuses.size()))
- .onThrottleStatusChanged(statusCaptor.capture());
-
- // Check actual statuses
- List<List<ThrottleStatus>> actualStatuses =
- (List<List<ThrottleStatus>>) statusCaptor.getAllValues();
- assertEquals(expectedStatuses.size(), actualStatuses.size());
-
- if (DBG) {
- logd("expectedStatuses.size() = " + expectedStatuses.size());
- logd("actualStatuses.size() = " + actualStatuses.size());
- }
-
- Comparator<ThrottleStatus> comparator = (o1, o2) ->
- Integer.compare(o1.getApnType(), o2.getApnType());
-
- for (int i = 0; i < expectedStatuses.size(); i++) {
- List<ThrottleStatus> atsExpected = new ArrayList<>(expectedStatuses.get(i));
- List<ThrottleStatus> atsActual = new ArrayList<>(actualStatuses.get(i));
-
- atsExpected.sort(comparator);
- atsActual.sort(comparator);
- assertEquals("Lists at index " + i + " don't match",
- atsExpected, atsActual);
- }
-
- this.mDataThrottler.registerForThrottleStatusChanges(mMockChangedCallback2);
- }
-
- /**
- * Test the behavior of a retry manager with no waiting APNs set.
- */
- @Test
- @SmallTest
- public void testUnthrottle() throws Exception {
- mDataThrottler.setRetryTime(ApnSetting.TYPE_DEFAULT, 1234567890L,
- REQUEST_TYPE_NORMAL);
- processAllMessages();
- assertEquals(1234567890L, mDataThrottler.getRetryTime(ApnSetting.TYPE_DEFAULT));
-
- mDataThrottler.reset();
- processAllMessages();
- assertEquals(RetryManager.NO_SUGGESTED_RETRY_DELAY,
- mDataThrottler.getRetryTime(ApnSetting.TYPE_DEFAULT));
- }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcControllerTest.java
deleted file mode 100644
index bddfdb4..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcControllerTest.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_ADDRESS;
-import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_DNS;
-import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_GATEWAY;
-import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_IFNAME;
-import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_PCSCF_ADDRESS;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.net.InetAddresses;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.data.ApnSetting;
-import android.telephony.data.DataCallResponse;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import com.android.internal.telephony.DctConstants;
-import com.android.internal.telephony.TelephonyTest;
-import com.android.internal.telephony.dataconnection.DataConnection.UpdateLinkPropertyResult;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class DcControllerTest extends TelephonyTest {
-
- private static final int DATA_CONNECTION_ACTIVE_PH_LINK_DORMANT = 1;
- private static final int DATA_CONNECTION_ACTIVE_PH_LINK_ACTIVE = 2;
-
- private static final int EVENT_DATA_STATE_CHANGED = 0x00040007;
- private static final int EVENT_PHYSICAL_LINK_STATUS_CHANGED = 1;
-
- // Mocked classes
- private List<ApnContext> mApnContexts;
- private DataConnection mDc;
- private DataServiceManager mDataServiceManager;
- private Handler mTestHandler;
-
- UpdateLinkPropertyResult mResult;
-
- private DcController mDcc;
-
- @Before
- public void setUp() throws Exception {
- super.setUp(getClass().getSimpleName());
- mApnContexts = mock(List.class);
- mDc = mock(DataConnection.class);
- mDataServiceManager = mock(DataServiceManager.class);
- mTestHandler = mock(Handler.class);
-
- doReturn("fake.action_detached").when(mPhone).getActionDetached();
- doReturn(1).when(mApnContexts).size();
- doReturn(mApnContexts).when(mDc).getApnContexts();
- doReturn(false).when(mPhone).isUsingNewDataStack();
-
- LinkProperties lp = new LinkProperties();
- mResult = new UpdateLinkPropertyResult(lp);
- doReturn(mResult).when(mDc).updateLinkProperty(any(DataCallResponse.class));
- doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
- .when(mDataServiceManager).getTransportType();
-
- mDcc = DcController.makeDcc(mPhone, mDcTracker, mDataServiceManager, Looper.myLooper(),
- "");
- processAllMessages();
- }
-
- @After
- public void tearDown() throws Exception {
- mDcc.removeCallbacksAndMessages(null);
- mDcc = null;
- mResult = null;
- super.tearDown();
- }
-
- @Test
- @SmallTest
- public void testDataDormant() throws Exception {
- ArrayList<DataCallResponse> l = new ArrayList<>();
- DataCallResponse dcResponse = new DataCallResponse.Builder()
- .setCause(0)
- .setRetryDurationMillis(-1)
- .setId(1)
- .setLinkStatus(DATA_CONNECTION_ACTIVE_PH_LINK_DORMANT)
- .setProtocolType(ApnSetting.PROTOCOL_IP)
- .setInterfaceName(FAKE_IFNAME)
- .setAddresses(Arrays.asList(
- new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0)))
- .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS)))
- .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY)))
- .setPcscfAddresses(
- Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS)))
- .setMtuV4(1440)
- .setMtuV6(1440)
- .build();
- l.add(dcResponse);
-
- mDc.mCid = 1;
- mDcc.addActiveDcByCid(mDc);
-
- mDcc.sendMessage(mDcc.obtainMessage(EVENT_DATA_STATE_CHANGED,
- new AsyncResult(null, l, null)));
- processAllMessages();
-
- verify(mDcTracker, times(1)).sendStopNetStatPoll(eq(DctConstants.Activity.DORMANT));
- }
-
- @Test
- @SmallTest
- public void testPhysicalLinkStatusChanged_defaultApnTypeAndDormant_registrantNotifyResult()
- throws Exception {
- ArrayList<DataCallResponse> l = new ArrayList<>();
- DataCallResponse dcResponse = new DataCallResponse.Builder()
- .setCause(0)
- .setRetryDurationMillis(-1)
- .setId(1)
- .setLinkStatus(DATA_CONNECTION_ACTIVE_PH_LINK_DORMANT)
- .setProtocolType(ApnSetting.PROTOCOL_IP)
- .setInterfaceName(FAKE_IFNAME)
- .setAddresses(Arrays.asList(
- new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0)))
- .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS)))
- .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY)))
- .setPcscfAddresses(
- Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS)))
- .setMtuV4(1440)
- .setMtuV6(1440)
- .build();
- l.add(dcResponse);
- mDc.mCid = 1;
- mDcc.addActiveDcByCid(mDc);
- ApnContext apnContext = new ApnContext(mPhone, ApnSetting.TYPE_DEFAULT, TAG, mDcTracker, 1);
- List<ApnContext> apnContextList = new ArrayList<>();
- apnContextList.add(apnContext);
- doReturn(apnContextList).when(mDc).getApnContexts();
- doReturn(true).when(mDcTracker).getLteEndcUsingUserDataForIdleDetection();
- mDcc.registerForPhysicalLinkStatusChanged(mTestHandler, EVENT_PHYSICAL_LINK_STATUS_CHANGED);
-
- mDcc.sendMessage(mDcc.obtainMessage(EVENT_DATA_STATE_CHANGED,
- new AsyncResult(null, l, null)));
- processAllMessages();
-
- ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
- verify(mTestHandler, times(1)).sendMessageDelayed(messageCaptor.capture(), anyLong());
- Message message = messageCaptor.getValue();
- assertEquals(EVENT_PHYSICAL_LINK_STATUS_CHANGED, message.what);
- AsyncResult ar = (AsyncResult) message.obj;
- assertEquals(DataCallResponse.LINK_STATUS_DORMANT, (int) ar.result);
- }
-
- @Test
- @SmallTest
- public void testPhysicalLinkStatusChanged_imsApnTypeAndDormant_NoNotifyResult()
- throws Exception {
- testPhysicalLinkStatusChanged_defaultApnTypeAndDormant_registrantNotifyResult();
-
- ArrayList<DataCallResponse> l = new ArrayList<>();
- DataCallResponse dcResponse = new DataCallResponse.Builder()
- .setCause(0)
- .setRetryDurationMillis(-1)
- .setId(1)
- .setLinkStatus(DATA_CONNECTION_ACTIVE_PH_LINK_ACTIVE)
- .setProtocolType(ApnSetting.PROTOCOL_IP)
- .setInterfaceName(FAKE_IFNAME)
- .setAddresses(Arrays.asList(
- new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0)))
- .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS)))
- .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY)))
- .setPcscfAddresses(
- Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS)))
- .setMtuV4(1440)
- .setMtuV6(1440)
- .build();
- l.add(dcResponse);
- mDc.mCid = 1;
- mDcc.addActiveDcByCid(mDc);
- ApnContext apnContext = new ApnContext(mPhone, ApnSetting.TYPE_IMS, TAG, mDcTracker, 1);
- List<ApnContext> apnContextList = new ArrayList<>();
- apnContextList.add(apnContext);
- doReturn(apnContextList).when(mDc).getApnContexts();
- doReturn(true).when(mDcTracker).getLteEndcUsingUserDataForIdleDetection();
-
- mDcc.sendMessage(mDcc.obtainMessage(EVENT_DATA_STATE_CHANGED,
- new AsyncResult(null, l, null)));
- processAllMessages();
-
- ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
- verify(mTestHandler, times(1)).sendMessageDelayed(messageCaptor.capture(), anyLong());
- }
-
- @Test
- @SmallTest
- public void testPhysicalLinkStatusChanged_defaultApnTypeAndStateChanged_registrantNotifyResult()
- throws Exception {
- testPhysicalLinkStatusChanged_imsApnTypeAndDormant_NoNotifyResult();
-
- ArrayList<DataCallResponse> l = new ArrayList<>();
- DataCallResponse dcResponse = new DataCallResponse.Builder()
- .setCause(0)
- .setRetryDurationMillis(-1)
- .setId(1)
- .setLinkStatus(DATA_CONNECTION_ACTIVE_PH_LINK_ACTIVE)
- .setProtocolType(ApnSetting.PROTOCOL_IP)
- .setInterfaceName(FAKE_IFNAME)
- .setAddresses(Arrays.asList(
- new LinkAddress(InetAddresses.parseNumericAddress(FAKE_ADDRESS), 0)))
- .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_DNS)))
- .setGatewayAddresses(Arrays.asList(InetAddresses.parseNumericAddress(FAKE_GATEWAY)))
- .setPcscfAddresses(
- Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS)))
- .setMtuV4(1440)
- .setMtuV6(1440)
- .build();
- l.add(dcResponse);
- mDc.mCid = 1;
- mDcc.addActiveDcByCid(mDc);
- ApnContext apnContext = new ApnContext(mPhone, ApnSetting.TYPE_DEFAULT, TAG, mDcTracker, 1);
- List<ApnContext> apnContextList = new ArrayList<>();
- apnContextList.add(apnContext);
- doReturn(apnContextList).when(mDc).getApnContexts();
- doReturn(true).when(mDcTracker).getLteEndcUsingUserDataForIdleDetection();
-
- mDcc.sendMessage(mDcc.obtainMessage(EVENT_DATA_STATE_CHANGED,
- new AsyncResult(null, l, null)));
- processAllMessages();
-
- ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
- verify(mTestHandler, times(2)).sendMessageDelayed(messageCaptor.capture(), anyLong());
- Message message = messageCaptor.getValue();
- assertEquals(EVENT_PHYSICAL_LINK_STATUS_CHANGED, message.what);
- AsyncResult ar = (AsyncResult) message.obj;
- assertEquals(DataCallResponse.LINK_STATUS_ACTIVE, (int) ar.result);
- }
-}
\ No newline at end of file
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcNetworkAgentTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcNetworkAgentTest.java
deleted file mode 100644
index 78438e4..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcNetworkAgentTest.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import static junit.framework.Assert.assertEquals;
-
-import static org.mockito.Mockito.doReturn;
-
-import android.net.ConnectivityManager;
-import android.net.LinkProperties;
-import android.net.NetworkAgent;
-import android.net.NetworkAgentConfig;
-import android.net.NetworkInfo;
-import android.net.NetworkProvider;
-import android.os.Looper;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.TelephonyManager;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import com.android.internal.telephony.TelephonyTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-
-import java.lang.reflect.Field;
-
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class DcNetworkAgentTest extends TelephonyTest {
-
- private DcNetworkAgent mDcNetworkAgent;
- private DataConnection mDc;
- private DcController mDcc;
- private DcFailBringUp mDcFailBringUp;
-
- private DataServiceManager mDataServiceManager;
- private DcTesterFailBringUpAll mDcTesterFailBringUpAll;
- private NetworkProvider mNetworkProvider;
-
- @Before
- public void setUp() throws Exception {
- super.setUp(getClass().getSimpleName());
- logd("+Setup!");
- if (Looper.myLooper() == null) {
- Looper.prepare();
- }
-
- doReturn(false).when(mPhone).isUsingNewDataStack();
- mDataServiceManager = Mockito.mock(DataServiceManager.class);
- mDcTesterFailBringUpAll = Mockito.mock(DcTesterFailBringUpAll.class);
- mNetworkProvider = Mockito.mock(NetworkProvider.class);
-
- final NetworkAgentConfig.Builder configBuilder = new NetworkAgentConfig.Builder();
- configBuilder.setLegacyType(ConnectivityManager.TYPE_MOBILE);
- configBuilder.setLegacyTypeName("MOBILE");
- configBuilder.setLegacySubType(TelephonyManager.NETWORK_TYPE_LTE);
- configBuilder.setLegacySubTypeName("LTE");
- configBuilder.setLegacyExtraInfo("apn");
-
- doReturn("fake.action_detached").when(mPhone).getActionDetached();
- mDcFailBringUp = new DcFailBringUp();
- mDcFailBringUp.saveParameters(0, 0, -2);
- doReturn(mDcFailBringUp).when(mDcTesterFailBringUpAll).getDcFailBringUp();
-
- mDcc = DcController.makeDcc(mPhone, mDcTracker, mDataServiceManager, Looper.myLooper(),
- "");
- mDc = DataConnection.makeDataConnection(mPhone, 0, mDcTracker, mDataServiceManager,
- mDcTesterFailBringUpAll, mDcc);
-
- LinkProperties linkProperties = new LinkProperties();
- linkProperties.setInterfaceName("fake_iface");
- Field field = DataConnection.class.getDeclaredField("mLinkProperties");
- field.setAccessible(true);
- field.set(mDc, linkProperties);
-
- mDcNetworkAgent = new DcNetworkAgent(mDc, mPhone, 45, configBuilder.build(),
- mNetworkProvider, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
- logd("-Setup!");
- }
-
- @After
- public void tearDown() throws Exception {
- super.tearDown();
- }
-
- private void verifyDisconnected() throws Exception {
- Field field = NetworkAgent.class.getDeclaredField("mNetworkInfo");
- field.setAccessible(true);
- NetworkInfo networkInfo = (NetworkInfo) field.get(mDcNetworkAgent);
- assertEquals(NetworkInfo.DetailedState.DISCONNECTED, networkInfo.getDetailedState());
- }
-
- @Test
- public void testUnwantedTimeout() throws Exception {
- mDcNetworkAgent.markConnected();
- mDcNetworkAgent.onNetworkUnwanted();
- processAllFutureMessages();
- verifyDisconnected();
- }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcRequestTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcRequestTest.java
deleted file mode 100644
index b08a680..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcRequestTest.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.net.TelephonyNetworkSpecifier;
-import android.telephony.data.ApnSetting;
-
-import com.android.internal.telephony.TelephonyTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class DcRequestTest extends TelephonyTest {
- NetworkRequest mNetworkRequest;
-
- // Mocked classes
- ApnConfigTypeRepository mApnConfigTypeRepo;
-
- @Before
- public void setUp() throws Exception {
- mApnConfigTypeRepo = mock(ApnConfigTypeRepository.class);
- super.setUp(getClass().getSimpleName());
- doReturn(false).when(mPhone).isUsingNewDataStack();
- }
-
- @After
- public void tearDown() throws Exception {
- mNetworkRequest = null;
- super.tearDown();
- }
-
- @Test
- public void whenNetworkRequestInternetThenPriorityZero() {
- mNetworkRequest = new NetworkRequest.Builder()
- .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
- .build();
-
- when(mApnConfigTypeRepo.getByType(ApnSetting.TYPE_DEFAULT))
- .thenReturn(new ApnConfigType(ApnSetting.TYPE_DEFAULT, 0));
- DcRequest dcRequest = DcRequest.create(mNetworkRequest, mApnConfigTypeRepo);
-
- assertEquals(0, dcRequest.priority);
- }
-
- @Test
- public void whenNetworkRequestMcxThenApnConfigTypeMcxPriorityReturned() {
- mNetworkRequest = new NetworkRequest.Builder()
- .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
- //Testing out multiple transport types here
- .addTransportType(NetworkCapabilities.TRANSPORT_BLUETOOTH)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_MCX)
- .build();
-
- when(mApnConfigTypeRepo.getByType(ApnSetting.TYPE_MCX))
- .thenReturn(new ApnConfigType(ApnSetting.TYPE_MCX, 21));
- DcRequest dcRequest = DcRequest.create(mNetworkRequest, mApnConfigTypeRepo);
- assertEquals(21, dcRequest.priority);
- }
-
- @Test
- public void whenNetworkRequestNotCellularThenDcRequestIsNull() {
- mNetworkRequest = new NetworkRequest.Builder()
- .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_MCX)
- .build();
- when(mApnConfigTypeRepo.getByType(ApnSetting.TYPE_NONE)).thenReturn(null);
- DcRequest dcRequest = DcRequest.create(mNetworkRequest, mApnConfigTypeRepo);
- assertNull(dcRequest);
- }
-
- @Test
- public void whenNetworkRequestHasNoTransportThenPriorityStays() {
- //This seems like an invalid case that should be handled differently.
- mNetworkRequest = new NetworkRequest.Builder()
- .addCapability(NetworkCapabilities.NET_CAPABILITY_MCX)
- .build();
-
- when(mApnConfigTypeRepo.getByType(ApnSetting.TYPE_MCX))
- .thenReturn(new ApnConfigType(ApnSetting.TYPE_MCX, 11));
- DcRequest dcRequest = DcRequest.create(mNetworkRequest, mApnConfigTypeRepo);
- assertEquals(11, dcRequest.priority);
- }
-
- @Test
- public void whenNetworkRequestNotCellularWithTelephonySpecifierThenDcRequestIsNull() {
- TelephonyNetworkSpecifier telephonyNetworkSpecifier =
- new TelephonyNetworkSpecifier.Builder().setSubscriptionId(5).build();
-
- //This seems like an invalid case that should be handled differently.
- mNetworkRequest = new NetworkRequest.Builder()
- .addTransportType(NetworkCapabilities.TRANSPORT_BLUETOOTH)
- .setNetworkSpecifier(telephonyNetworkSpecifier)
- .build();
-
- when(mApnConfigTypeRepo.getByType(ApnSetting.TYPE_NONE)).thenReturn(null);
-
- DcRequest dcRequest = DcRequest.create(mNetworkRequest, mApnConfigTypeRepo);
-
- assertNull(dcRequest);
- }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
deleted file mode 100644
index 549c587..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
+++ /dev/null
@@ -1,2983 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
-import static com.android.internal.telephony.dataconnection.ApnSettingTest.createApnSetting;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ServiceInfo;
-import android.database.Cursor;
-import android.database.MatrixCursor;
-import android.hardware.radio.V1_0.SetupDataCallResult;
-import android.net.LinkProperties;
-import android.net.NetworkAgent;
-import android.net.NetworkCapabilities;
-import android.net.NetworkPolicyManager;
-import android.net.NetworkRequest;
-import android.net.Uri;
-import android.os.AsyncResult;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.PersistableBundle;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.provider.Telephony;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.AccessNetworkConstants.AccessNetworkType;
-import android.telephony.Annotation;
-import android.telephony.CarrierConfigManager;
-import android.telephony.DataFailCause;
-import android.telephony.NetworkRegistrationInfo;
-import android.telephony.PreciseDataConnectionState;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionManager;
-import android.telephony.SubscriptionPlan;
-import android.telephony.TelephonyDisplayInfo;
-import android.telephony.TelephonyManager;
-import android.telephony.data.ApnSetting;
-import android.telephony.data.DataCallResponse;
-import android.telephony.data.DataProfile;
-import android.telephony.data.DataService;
-import android.telephony.data.TrafficDescriptor;
-import android.test.mock.MockContentProvider;
-import android.test.mock.MockContentResolver;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.text.TextUtils;
-import android.util.Pair;
-import android.util.SparseArray;
-
-import androidx.test.filters.FlakyTest;
-
-import com.android.internal.R;
-import com.android.internal.telephony.DctConstants;
-import com.android.internal.telephony.ISub;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.RetryManager;
-import com.android.internal.telephony.TelephonyTest;
-import com.android.internal.telephony.data.CellularDataService;
-import com.android.internal.telephony.dataconnection.DataConnectionReasons.DataDisallowedReasonType;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mockito;
-import org.mockito.stubbing.Answer;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.time.Period;
-import java.time.ZonedDateTime;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.Collectors;
-
-public class DcTrackerTest extends TelephonyTest {
- public static final String FAKE_APN1 = "FAKE APN 1";
- public static final String FAKE_APN2 = "FAKE APN 2";
- public static final String FAKE_APN3 = "FAKE APN 3";
- public static final String FAKE_APN4 = "FAKE APN 4";
- public static final String FAKE_APN5 = "FAKE APN 5";
- 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";
- public static final String FAKE_DNS = "55.66.77.88";
- public static final String FAKE_ADDRESS = "99.88.77.66";
- private static final int NETWORK_TYPE_NR_BITMASK =
- 1 << (TelephonyManager.NETWORK_TYPE_NR - 1);
- private static final int NETWORK_TYPE_LTE_BITMASK =
- 1 << (TelephonyManager.NETWORK_TYPE_LTE - 1);
- private static final int NETWORK_TYPE_EHRPD_BITMASK =
- 1 << (TelephonyManager.NETWORK_TYPE_EHRPD - 1);
- private static final Uri PREFERAPN_URI = Uri.parse(
- Telephony.Carriers.CONTENT_URI + "/preferapn");
- private static final int DATA_ENABLED_CHANGED = 0;
- private static final String FAKE_PLMN = "44010";
- private static final long TEST_TIMEOUT = 1000;
-
- // Mocked classes
- ISub mIsub;
- IBinder mBinder;
- SubscriptionInfo mSubscriptionInfo;
- ApnContext mApnContext;
- DataConnection mDataConnection;
- Handler mHandler;
- NetworkPolicyManager mNetworkPolicyManager;
-
- private DcTracker mDct;
- private DcTrackerTestHandler mDcTrackerTestHandler;
-
- private AlarmManager mAlarmManager;
-
- private PersistableBundle mBundle;
-
- private SubscriptionManager.OnSubscriptionsChangedListener mOnSubscriptionsChangedListener;
-
- private final ApnSettingContentProvider mApnSettingContentProvider =
- new ApnSettingContentProvider();
-
- private Message mMessage;
-
- private CellularDataService mCellularDataService;
-
- private void addDataService() {
- mCellularDataService = new CellularDataService();
- ServiceInfo serviceInfo = new ServiceInfo();
- serviceInfo.packageName = "com.android.phone";
- serviceInfo.permission = "android.permission.BIND_TELEPHONY_DATA_SERVICE";
- IntentFilter filter = new IntentFilter();
- mContextFixture.addService(
- DataService.SERVICE_INTERFACE,
- null,
- "com.android.phone",
- mCellularDataService.mBinder,
- serviceInfo,
- filter);
- }
-
- private class DcTrackerTestHandler extends HandlerThread {
-
- private DcTrackerTestHandler(String name) {
- super(name);
- }
-
- @Override
- public void onLooperPrepared() {
- mDct = new DcTracker(mPhone, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
- setReady(true);
- }
- }
-
- private class ApnSettingContentProvider extends MockContentProvider {
- public final String[] FAKE_APN_COLUMNS = new String[]{
- Telephony.Carriers._ID, Telephony.Carriers.NUMERIC,
- Telephony.Carriers.NAME, Telephony.Carriers.APN,
- Telephony.Carriers.PROXY, Telephony.Carriers.PORT,
- Telephony.Carriers.MMSC, Telephony.Carriers.MMSPROXY,
- Telephony.Carriers.MMSPORT, Telephony.Carriers.USER,
- Telephony.Carriers.PASSWORD, Telephony.Carriers.AUTH_TYPE,
- Telephony.Carriers.TYPE,
- Telephony.Carriers.PROTOCOL,
- Telephony.Carriers.ROAMING_PROTOCOL,
- Telephony.Carriers.CARRIER_ENABLED, Telephony.Carriers.BEARER,
- Telephony.Carriers.BEARER_BITMASK,
- Telephony.Carriers.PROFILE_ID,
- Telephony.Carriers.MODEM_PERSIST,
- Telephony.Carriers.MAX_CONNECTIONS,
- Telephony.Carriers.WAIT_TIME_RETRY,
- Telephony.Carriers.TIME_LIMIT_FOR_MAX_CONNECTIONS,
- Telephony.Carriers.MTU,
- Telephony.Carriers.MTU_V4,
- Telephony.Carriers.MTU_V6,
- Telephony.Carriers.MVNO_TYPE,
- Telephony.Carriers.MVNO_MATCH_DATA,
- Telephony.Carriers.NETWORK_TYPE_BITMASK,
- Telephony.Carriers.LINGERING_NETWORK_TYPE_BITMASK,
- Telephony.Carriers.APN_SET_ID,
- Telephony.Carriers.CARRIER_ID,
- Telephony.Carriers.SKIP_464XLAT,
- Telephony.Carriers.ALWAYS_ON
- };
-
- private int mPreferredApnSet = 0;
-
- private Object[] mPreferredApn = null;
-
- private String mFakeApn1Types = "default,supl";
-
- private String mFakeApn5Types = "dun";
-
- private int mFakeApn1Bitmask = NETWORK_TYPE_LTE_BITMASK;
-
- private int mRowIdOffset = 0;
-
- public void setFakeApn1Types(String apnTypes) {
- mFakeApn1Types = apnTypes;
- }
-
- public void setFakeApn5Types(String apnTypes) {
- mFakeApn5Types = apnTypes;
- }
-
- public void setFakeApn1NetworkTypeBitmask(int bitmask) {
- mFakeApn1Bitmask = bitmask;
- }
-
- public void setRowIdOffset(int rowIdOffset) {
- mRowIdOffset = rowIdOffset;
- }
-
- public void setFakePreferredApn(Object[] fakeApn) {
- mPreferredApn = fakeApn;
- }
-
- public Object[] getFakeApn1() {
- return new Object[]{
- 2163 + mRowIdOffset, // id
- FAKE_PLMN, // numeric
- "sp-mode", // name
- FAKE_APN1, // apn
- "", // proxy
- "", // port
- "", // mmsc
- "", // mmsproxy
- "", // mmsport
- "", // user
- "", // password
- -1, // authtype
- mFakeApn1Types, // 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
- 0, // mtu_v4
- 0, // mtu_v6
- "", // mvno_type
- "", // mnvo_match_data
- mFakeApn1Bitmask, // network_type_bitmask
- 0, // lingering_network_type_bitmask
- 0, // apn_set_id
- -1, // carrier_id
- -1, // skip_464xlat
- 0 // always_on
- };
- }
-
- public Object[] getFakeApn2() {
- return new Object[]{
- 2164 + mRowIdOffset, // id
- FAKE_PLMN, // numeric
- "mopera U", // name
- FAKE_APN2, // apn
- "", // proxy
- "", // port
- "", // mmsc
- "", // mmsproxy
- "", // mmsport
- "", // user
- "", // password
- -1, // authtype
- "default,supl", // 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
- 0, // mtu_v4
- 0, // mtu_v6
- "", // mvno_type
- "", // mnvo_match_data
- NETWORK_TYPE_LTE_BITMASK, // network_type_bitmask
- 0, // lingering_network_type_bitmask
- 0, // apn_set_id
- -1, // carrier_id
- -1, // skip_464xlat
- 0 // always_on
- };
- }
-
- public Object[] getFakeApn3() {
- return new Object[]{
- 2165 + mRowIdOffset, // id
- FAKE_PLMN, // numeric
- "b-mobile for Nexus", // name
- FAKE_APN3, // apn
- "", // proxy
- "", // port
- "", // mmsc
- "", // mmsproxy
- "", // mmsport
- "", // user
- "", // password
- -1, // authtype
- "ims", // types
- "IP", // protocol
- "IP", // roaming_protocol
- 1, // carrier_enabled
- 0, // bearer
- 0, // bearer_bitmask
- 2, // profile_id
- 1, // modem_cognitive
- 0, // max_conns
- 0, // wait_time
- 0, // max_conns_time
- 0, // mtu
- 0, // mtu_v4
- 0, // mtu_v6
- "", // mvno_type
- "", // mnvo_match_data
- 0, // network_type_bitmask
- 0, // lingering_network_type_bitmask
- 0, // apn_set_id
- -1, // carrier_id
- -1, // skip_464xlat
- 0 // always_on
- };
- }
-
- public Object[] getFakeApn4() {
- return new Object[]{
- 2166 + mRowIdOffset, // id
- FAKE_PLMN, // numeric
- "sp-mode ehrpd", // name
- FAKE_APN4, // apn
- "", // proxy
- "", // port
- "", // mmsc
- "", // mmsproxy
- "", // mmsport
- "", // user
- "", // password
- -1, // authtype
- "default,supl", // types
- "IP", // protocol
- "IP", // roaming_protocol
- 1, // carrier_enabled
- ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD, // bearer
- 0, // bearer_bitmask
- 0, // profile_id
- 1, // modem_cognitive
- 0, // max_conns
- 0, // wait_time
- 0, // max_conns_time
- 0, // mtu
- 0, // mtu_v4
- 0, // mtu_v6
- "", // mvno_type
- "", // mnvo_match_data
- NETWORK_TYPE_EHRPD_BITMASK, // network_type_bitmask
- 0, // lingering_network_type_bitmask
- 0, // apn_set_id
- -1, // carrier_id
- -1, // skip_464xlat
- 0 // always_on
- };
- }
-
- public Object[] getFakeApn5() {
- return new Object[]{
- 2167 + mRowIdOffset, // id
- FAKE_PLMN, // numeric
- "b-mobile for Nexus", // name
- FAKE_APN5, // apn
- "", // proxy
- "", // port
- "", // mmsc
- "", // mmsproxy
- "", // mmsport
- "", // user
- "", // password
- -1, // authtype
- mFakeApn5Types, // types
- "IP", // protocol
- "IP", // roaming_protocol
- 1, // carrier_enabled
- 0, // bearer
- 0, // bearer_bitmask
- 0, // profile_id
- 1, // modem_cognitive
- 0, // max_conns
- 0, // wait_time
- 0, // max_conns_time
- 0, // mtu
- 0, // mtu_v4
- 0, // mtu_v6
- "", // mvno_type
- "", // mnvo_match_data
- 0, // network_type_bitmask
- 0, // lingering_network_type_bitmask
- 0, // apn_set_id
- -1, // carrier_id
- -1, // skip_464xlat
- 0 // always_on
- };
- }
-
- public Object[] getFakeApn6() {
- return new Object[]{
- 2168 + mRowIdOffset, // id
- FAKE_PLMN, // numeric
- "sp-mode", // name
- FAKE_APN6, // apn
- "", // proxy
- "", // port
- "", // mmsc
- "", // mmsproxy
- "", // mmsport
- "", // user
- "", // password
- -1, // authtype
- "mms,xcap", // 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
- 0, // mtu_v4
- 0, // mtu_v6
- "", // mvno_type
- "", // mnvo_match_data
- NETWORK_TYPE_LTE_BITMASK, // network_type_bitmask
- 0, // lingering_network_type_bitmask
- 0, // apn_set_id
- -1, // carrier_id
- -1, // skip_464xlat
- 0 // always_on
- };
- }
-
- public Object[] getFakeApn7() {
- return new Object[]{
- 2169 + mRowIdOffset, // id
- FAKE_PLMN, // numeric
- "sp-mode", // name
- FAKE_APN7, // apn
- "", // proxy
- "", // port
- "", // mmsc
- "", // mmsproxy
- "", // mmsport
- "", // user
- "", // password
- -1, // authtype
- "default", // 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
- 0, // mtu_v4
- 0, // mtu_v6
- "", // mvno_type
- "", // mnvo_match_data
- NETWORK_TYPE_LTE_BITMASK, // network_type_bitmask
- 0, // lingering_network_type_bitmask
- 1, // apn_set_id
- -1, // carrier_id
- -1, // skip_464xlat
- 0 // always_on
- };
- }
-
- public Object[] getFakeApn8() {
- return new Object[]{
- 2170 + mRowIdOffset, // id
- FAKE_PLMN, // numeric
- "IMS", // name
- FAKE_APN8, // apn
- "", // proxy
- "", // port
- "", // mmsc
- "", // mmsproxy
- "", // mmsport
- "", // user
- "", // password
- -1, // authtype
- "ims", // types
- "IP", // protocol
- "IP", // roaming_protocol
- 1, // carrier_enabled
- ServiceState.RIL_RADIO_TECHNOLOGY_LTE, // bearer
- 0, // bearer_bitmask
- 2, // profile_id
- 1, // modem_cognitive
- 0, // max_conns
- 0, // wait_time
- 0, // max_conns_time
- 0, // mtu
- 0, // mtu_v4
- 0, // mtu_v6
- "", // mvno_type
- "", // mnvo_match_data
- NETWORK_TYPE_LTE_BITMASK, // network_type_bitmask
- 0, // lingering_network_type_bitmask
- -1, // apn_set_id
- -1, // carrier_id
- -1, // skip_464xlat
- 0 // always_on
- };
- }
-
- public Object[] getFakeApn9() {
- return 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
- 0, // mtu_v4
- 0, // mtu_v6
- "", // mvno_type
- "", // mnvo_match_data
- NETWORK_TYPE_NR_BITMASK, // network_type_bitmask
- 0, // lingering_network_type_bitmask
- 0, // apn_set_id
- -1, // carrier_id
- -1, // skip_464xlat
- 0 // always_on
- };
- }
-
- @Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
- String sortOrder) {
- logd("ApnSettingContentProvider: query");
- logd(" uri = " + uri);
- logd(" projection = " + Arrays.toString(projection));
- logd(" selection = " + selection);
- logd(" selectionArgs = " + Arrays.toString(selectionArgs));
- logd(" sortOrder = " + sortOrder);
-
- if (uri.compareTo(Telephony.Carriers.CONTENT_URI) == 0
- || uri.toString().startsWith(Uri.withAppendedPath(
- Telephony.Carriers.CONTENT_URI, "filtered").toString())
- || uri.toString().startsWith(Uri.withAppendedPath(
- Telephony.Carriers.SIM_APN_URI, "filtered").toString())) {
- if (projection == null) {
-
- logd("Query '" + FAKE_PLMN + "' APN settings");
- MatrixCursor mc = new MatrixCursor(FAKE_APN_COLUMNS);
- mc.addRow(getFakeApn1());
- mc.addRow(getFakeApn2());
- mc.addRow(getFakeApn3());
- mc.addRow(getFakeApn4());
- mc.addRow(getFakeApn5());
- mc.addRow(getFakeApn6());
- mc.addRow(getFakeApn7());
- mc.addRow(getFakeApn8());
- mc.addRow(getFakeApn9());
-
- return mc;
- }
- } else if (isPathPrefixMatch(uri,
- Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "preferapnset"))) {
- MatrixCursor mc = new MatrixCursor(
- new String[]{Telephony.Carriers.APN_SET_ID});
- // apn_set_id is the only field used with this URL
- mc.addRow(new Object[]{ mPreferredApnSet });
- mc.addRow(new Object[]{ 0 });
- return mc;
- } else if (isPathPrefixMatch(uri,
- Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "preferapn_no_update"))) {
- if (mPreferredApn == null) {
- return null;
- } else {
- MatrixCursor mc = new MatrixCursor(FAKE_APN_COLUMNS);
- mc.addRow(mPreferredApn);
- return mc;
- }
- }
-
- return null;
- }
-
- @Override
- public int update(Uri url, ContentValues values, String where, String[] whereArgs) {
- mPreferredApnSet = values.getAsInteger(Telephony.Carriers.APN_SET_ID);
- return 1;
- }
-
- @Override
- public int delete(Uri uri, String selection, String[] selectionArgs) {
- return 0;
- }
-
- @Override
- public Uri insert(Uri uri, ContentValues values) {
- return null;
- }
- }
-
- @Before
- public void setUp() throws Exception {
- logd("DcTrackerTest +Setup!");
- super.setUp(getClass().getSimpleName());
- mIsub = Mockito.mock(ISub.class);
- mBinder = Mockito.mock(IBinder.class);
- mSubscriptionInfo = Mockito.mock(SubscriptionInfo.class);
- mApnContext = Mockito.mock(ApnContext.class);
- mDataConnection = Mockito.mock(DataConnection.class);
- mHandler = Mockito.mock(Handler.class);
- mNetworkPolicyManager = Mockito.mock(NetworkPolicyManager.class);
-
- doReturn("fake.action_detached").when(mPhone).getActionDetached();
- doReturn("fake.action_attached").when(mPhone).getActionAttached();
- doReturn(false).when(mPhone).isUsingNewDataStack();
- doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_LTE).when(mServiceState)
- .getRilDataRadioTechnology();
-
- mContextFixture.putStringArrayResource(com.android.internal.R.array
- .config_mobile_tcp_buffers, new String[]{
- "umts:131072,262144,1452032,4096,16384,399360",
- "hspa:131072,262144,2441216,4096,16384,399360",
- "hsupa:131072,262144,2441216,4096,16384,399360",
- "hsdpa:131072,262144,2441216,4096,16384,399360",
- "hspap:131072,262144,2441216,4096,16384,399360",
- "edge:16384,32768,131072,4096,16384,65536",
- "gprs:4096,8192,24576,4096,8192,24576",
- "1xrtt:16384,32768,131070,4096,16384,102400",
- "evdo:131072,262144,1048576,4096,16384,524288",
- "lte:524288,1048576,8388608,262144,524288,4194304"});
-
- mContextFixture.putResource(R.string.config_wwan_data_service_package,
- "com.android.phone");
-
- ((MockContentResolver) mContext.getContentResolver()).addProvider(
- Telephony.Carriers.CONTENT_URI.getAuthority(), mApnSettingContentProvider);
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 0);
-
- doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).when(mAccessNetworksManager)
- .getPreferredTransport(anyInt());
- doReturn(PhoneConstants.State.IDLE).when(mCT).getState();
- doReturn(true).when(mSST).getDesiredPowerState();
- doReturn(true).when(mSST).getPowerStateFromCarrier();
- doAnswer(
- (Answer<Void>) invocation -> {
- mOnSubscriptionsChangedListener =
- (SubscriptionManager.OnSubscriptionsChangedListener)
- invocation.getArguments()[0];
- return null;
- }
- ).when(mSubscriptionManager).addOnSubscriptionsChangedListener(any());
- doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
- doReturn(mNetworkPolicyManager).when(mContext)
- .getSystemService(Context.NETWORK_POLICY_SERVICE);
- doReturn(1).when(mIsub).getDefaultDataSubId();
- doReturn(mIsub).when(mBinder).queryLocalInterface(anyString());
- mServiceManagerMockedServices.put("isub", mBinder);
-
- mContextFixture.putStringArrayResource(
- com.android.internal.R.array.config_cell_retries_per_error_code,
- new String[]{"36,2"});
-
- mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
- mBundle = mContextFixture.getCarrierConfigBundle();
-
- mBundle.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
-
- mSimulatedCommands.setDataCallResult(true, createSetupDataCallResult());
- addDataService();
-
- mDcTrackerTestHandler = new DcTrackerTestHandler(getClass().getSimpleName());
- mDcTrackerTestHandler.start();
- waitUntilReady();
-
- Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
- intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, mPhone.getPhoneId());
- intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, mPhone.getSubId());
- mContext.sendBroadcast(intent);
-
- waitForMs(600);
- logd("DcTrackerTest -Setup!");
- }
-
- @After
- public void tearDown() throws Exception {
- logd("DcTrackerTest -tearDown");
- mDct.removeCallbacksAndMessages(null);
- mDct.stopHandlerThread();
- mDct = null;
- mDcTrackerTestHandler.quit();
- mDcTrackerTestHandler.join();
- mDcTrackerTestHandler = null;
- mCellularDataService.onDestroy();
- mCellularDataService = null;
- mAlarmManager = null;
- mBundle = null;
- mCellularDataService = null;
- waitForMs(100);
- super.tearDown();
- }
-
- // Create a successful data response
- private static SetupDataCallResult createSetupDataCallResult() {
- SetupDataCallResult result = new SetupDataCallResult();
- result.status = 0;
- result.suggestedRetryTime = -1;
- result.cid = 1;
- 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;
- return result;
- }
-
- private void verifyDataProfile(DataProfile dp, String apn, int profileId,
- int supportedApnTypesBitmap, int type, int bearerBitmask) {
- assertEquals(profileId, dp.getProfileId());
- assertEquals(apn, dp.getApn());
- assertEquals(ApnSetting.PROTOCOL_IP, dp.getProtocolType());
- assertEquals(0, dp.getAuthType());
- assertEquals("", dp.getUserName());
- assertEquals("", dp.getPassword());
- assertEquals(type, dp.getType());
- assertEquals(0, dp.getWaitTime());
- assertTrue(dp.isEnabled());
- assertEquals(supportedApnTypesBitmap, dp.getSupportedApnTypesBitmask());
- assertEquals(ApnSetting.PROTOCOL_IP, dp.getRoamingProtocolType());
- assertEquals(bearerBitmask, dp.getBearerBitmask());
- assertEquals(0, dp.getMtu());
- assertTrue(dp.isPersistent());
- assertFalse(dp.isPreferred());
- }
-
- private void verifyDataConnected(final String apnSetting) {
- verify(mAlarmManager, times(1)).set(eq(AlarmManager.ELAPSED_REALTIME), anyLong(),
- any(PendingIntent.class));
-
- assertEquals(apnSetting, mDct.getActiveApnString(ApnSetting.TYPE_DEFAULT_STRING));
- assertArrayEquals(new String[]{ApnSetting.TYPE_DEFAULT_STRING}, mDct.getActiveApnTypes());
-
- assertTrue(mDct.isAnyDataConnected());
- assertEquals(DctConstants.State.CONNECTED, mDct.getState(ApnSetting.TYPE_DEFAULT_STRING));
-
- LinkProperties linkProperties = mDct.getLinkProperties(ApnSetting.TYPE_DEFAULT_STRING);
- assertEquals(FAKE_IFNAME, linkProperties.getInterfaceName());
- assertEquals(1, linkProperties.getAddresses().size());
- assertEquals(FAKE_ADDRESS, linkProperties.getAddresses().get(0).getHostAddress());
- assertEquals(1, linkProperties.getDnsServers().size());
- assertEquals(FAKE_DNS, linkProperties.getDnsServers().get(0).getHostAddress());
- assertEquals(FAKE_GATEWAY, linkProperties.getRoutes().get(0).getGateway().getHostAddress());
- }
-
- private boolean isHandoverPending(int apnType) {
- try {
- Method method = DcTracker.class.getDeclaredMethod("isHandoverPending",
- int.class);
- method.setAccessible(true);
- return (boolean) method.invoke(mDct, apnType);
- } catch (Exception e) {
- fail(e.toString());
- return false;
- }
- }
-
- private void addHandoverCompleteMsg(Message onCompleteMsg,
- @Annotation.ApnType int apnType) {
- try {
- Method method = DcTracker.class.getDeclaredMethod("addHandoverCompleteMsg",
- Message.class, int.class);
- method.setAccessible(true);
- method.invoke(mDct, onCompleteMsg, apnType);
- } catch (Exception e) {
- fail(e.toString());
- }
- }
-
- private void sendInitializationEvents() {
- sendCarrierConfigChanged("");
-
- sendSimStateUpdated("");
-
- sendEventDataConnectionAttached("");
-
- waitForMs(200);
- }
-
- private void sendCarrierConfigChanged(String messagePrefix) {
- logd(messagePrefix + "Sending EVENT_CARRIER_CONFIG_CHANGED");
- mDct.sendEmptyMessage(DctConstants.EVENT_CARRIER_CONFIG_CHANGED);
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- }
-
- private void sendSimStateUpdated(String messagePrefix) {
- logd(messagePrefix + "Sending EVENT_SIM_STATE_UPDATED");
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_SIM_STATE_UPDATED,
- TelephonyManager.SIM_STATE_LOADED, 0));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- }
-
- private void sendEventDataConnectionAttached(String messagePrefix) {
- logd(messagePrefix + "Sending EVENT_DATA_CONNECTION_ATTACHED");
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- }
-
- // Test the unmetered APN setup when data is disabled.
- @Test
- @SmallTest
- public void testTrySetupDataUnmeteredDefaultNotSelected() throws Exception {
- initApns(ApnSetting.TYPE_XCAP_STRING, new String[]{ApnSetting.TYPE_XCAP_STRING});
- doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID).when(mIsub).getDefaultDataSubId();
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_DEFAULT_STRING});
-
- sendInitializationEvents();
-
- mDct.enableApn(ApnSetting.TYPE_XCAP, DcTracker.REQUEST_TYPE_NORMAL, null);
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- // Data connection is running on a different thread. Have to wait.
- waitForMs(200);
- verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
- eq(AccessNetworkType.EUTRAN), any(DataProfile.class),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- }
-
- // Test the normal data call setup scenario.
- @Test
- @MediumTest
- public void testDataSetup() throws Exception {
- DataConnectionReasons dataConnectionReasons = new DataConnectionReasons();
- boolean allowed = mDct.isDataAllowed(dataConnectionReasons);
- assertFalse(dataConnectionReasons.toString(), allowed);
-
- logd("Sending EVENT_ENABLE_APN");
- // APN id 0 is APN_TYPE_DEFAULT
- mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- sendInitializationEvents();
-
- dataConnectionReasons = new DataConnectionReasons();
- allowed = mDct.isDataAllowed(dataConnectionReasons);
- assertTrue(dataConnectionReasons.toString(), allowed);
-
- ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
- // Verify if RIL command was sent properly.
- verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
- eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
-
- verifyDataConnected(FAKE_APN1);
- }
-
- // Test the scenario where the first data call setup is failed, and then retry the setup later.
- @Test
- @MediumTest
- public void testDataRetry() throws Exception {
- AsyncResult ar = new AsyncResult(null,
- new Pair<>(true, DataEnabledSettings.REASON_USER_DATA_ENABLED), null);
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_ENABLED_CHANGED, ar));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- // LOST_CONNECTION(0x10004) is a non-permanent failure, so we'll retry data setup later.
- SetupDataCallResult result = createSetupDataCallResult();
- result.status = 0x10004;
-
- // Simulate RIL fails the data call setup
- mSimulatedCommands.setDataCallResult(true, result);
-
- DataConnectionReasons dataConnectionReasons = new DataConnectionReasons();
- boolean allowed = mDct.isDataAllowed(dataConnectionReasons);
- assertFalse(dataConnectionReasons.toString(), allowed);
-
- logd("Sending EVENT_ENABLE_APN");
- // APN id 0 is APN_TYPE_DEFAULT
- mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- sendInitializationEvents();
-
- dataConnectionReasons = new DataConnectionReasons();
- allowed = mDct.isDataAllowed(dataConnectionReasons);
- assertTrue(dataConnectionReasons.toString(), allowed);
-
- ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
- // Verify if RIL command was sent properly.
- verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
- eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
-
- // This time we'll let RIL command succeed.
- mSimulatedCommands.setDataCallResult(true, createSetupDataCallResult());
-
- //Send event for reconnecting data
- initApns(ApnSetting.TYPE_DEFAULT_STRING, new String[]{ApnSetting.TYPE_ALL_STRING});
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_RECONNECT,
- mPhone.getPhoneId(), DcTracker.REQUEST_TYPE_NORMAL, mApnContext));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- // Data connection is running on a different thread. Have to wait.
- waitForMs(200);
- dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
- // Verify if RIL command was sent properly.
- verify(mSimulatedCommandsVerifier, times(2)).setupDataCall(
- eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- verifyDataProfile(dpCaptor.getValue(), FAKE_APN2, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
-
- // Verify connected with APN2 setting.
- verifyDataConnected(FAKE_APN2);
- }
-
- @Test
- @MediumTest
- @Ignore
- @FlakyTest
- public void testUserDisableData() {
- //step 1: setup two DataCalls one for Metered: default, another one for Non-metered: IMS
- //set Default and MMS to be metered in the CarrierConfigManager
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_DEFAULT_STRING, ApnSetting.TYPE_MMS_STRING});
- mDct.enableApn(ApnSetting.TYPE_IMS, DcTracker.REQUEST_TYPE_NORMAL, null);
- mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
-
- sendInitializationEvents();
-
- ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
- verify(mSimulatedCommandsVerifier, times(2)).setupDataCall(
- eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 5, 1, NETWORK_TYPE_LTE_BITMASK);
-
- logd("Sending DATA_DISABLED_CMD");
- doReturn(false).when(mDataEnabledSettings).isDataEnabled();
- doReturn(false).when(mDataEnabledSettings).isDataEnabled(anyInt());
- AsyncResult ar = new AsyncResult(null,
- new Pair<>(false, DataEnabledSettings.REASON_USER_DATA_ENABLED), null);
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_ENABLED_CHANGED, ar));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- // Data connection is running on a different thread. Have to wait.
- waitForMs(200);
- // expected tear down all metered DataConnections
- verify(mSimulatedCommandsVerifier, times(1)).deactivateDataCall(
- eq(DataService.REQUEST_REASON_NORMAL), anyInt(),
- any(Message.class));
- assertTrue(mDct.isAnyDataConnected());
- assertEquals(DctConstants.State.IDLE, mDct.getState(ApnSetting.TYPE_DEFAULT_STRING));
- assertEquals(DctConstants.State.CONNECTED, mDct.getState(ApnSetting.TYPE_IMS_STRING));
- }
-
- @Test
- @MediumTest
- public void testTrySetupDataMmsAllowedDataDisabled() {
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_DEFAULT_STRING, ApnSetting.TYPE_MMS_STRING});
- mDct.enableApn(ApnSetting.TYPE_MMS, DcTracker.REQUEST_TYPE_NORMAL, null);
- mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
-
- sendInitializationEvents();
-
- ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
- verify(mSimulatedCommandsVerifier, times(2)).setupDataCall(
- eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
-
- List<DataProfile> dataProfiles = dpCaptor.getAllValues();
- assertEquals(2, dataProfiles.size());
-
- //Verify FAKE_APN1
- Optional<DataProfile> fakeApn1 = dataProfiles.stream()
- .filter(dp -> dp.getApn().equals(FAKE_APN1))
- .findFirst();
- assertTrue(fakeApn1.isPresent());
- verifyDataProfile(fakeApn1.get(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
-
- //Verify FAKE_APN6
- Optional<DataProfile> fakeApn6 = dataProfiles.stream()
- .filter(dp -> dp.getApn().equals(FAKE_APN6))
- .findFirst();
- assertTrue(fakeApn6.isPresent());
- verifyDataProfile(fakeApn6.get(), FAKE_APN6, 0, ApnSetting.TYPE_MMS | ApnSetting.TYPE_XCAP,
- 1, NETWORK_TYPE_LTE_BITMASK);
-
- logd("Sending DATA_DISABLED_CMD for default data");
- doReturn(false).when(mDataEnabledSettings).isDataEnabled();
- doReturn(false).when(mDataEnabledSettings).isDataEnabled(anyInt());
- mDct.obtainMessage(DctConstants.EVENT_DATA_ENABLED_OVERRIDE_RULES_CHANGED).sendToTarget();
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- // Data connection is running on a different thread. Have to wait.
- waitForMs(200);
- // expected tear down all metered DataConnections
- verify(mSimulatedCommandsVerifier, times(2)).deactivateDataCall(
- 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));
-
- clearInvocations(mSimulatedCommandsVerifier);
- doReturn(true).when(mDataEnabledSettings).isDataEnabled(ApnSetting.TYPE_MMS);
- mDct.obtainMessage(DctConstants.EVENT_DATA_ENABLED_OVERRIDE_RULES_CHANGED).sendToTarget();
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- // Data connection is running on a different thread. Have to wait.
- waitForMs(200);
- verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
- eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- assertEquals(DctConstants.State.IDLE, mDct.getState(ApnSetting.TYPE_DEFAULT_STRING));
- assertEquals(DctConstants.State.CONNECTED, mDct.getState(ApnSetting.TYPE_MMS_STRING));
- }
-
- @Test
- @MediumTest
- public void testTrySetupDataMmsAlwaysAllowedDataDisabled() {
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_DEFAULT_STRING, ApnSetting.TYPE_MMS_STRING});
- mApnSettingContentProvider.setFakeApn1Types("mms,xcap,default");
- mDct.enableApn(ApnSetting.TYPE_MMS, DcTracker.REQUEST_TYPE_NORMAL, null);
- sendInitializationEvents();
-
- // Verify MMS was set up and is connected
- ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
- verify(mSimulatedCommandsVerifier).setupDataCall(
- eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0,
- ApnSetting.TYPE_MMS | ApnSetting.TYPE_XCAP | ApnSetting.TYPE_DEFAULT,
- 1, NETWORK_TYPE_LTE_BITMASK);
- assertEquals(DctConstants.State.CONNECTED, mDct.getState(ApnSetting.TYPE_MMS_STRING));
-
- // Verify DC has all capabilities specified in fakeApn1Types
- Map<Integer, ApnContext> apnContexts = mDct.getApnContexts().stream().collect(
- Collectors.toMap(ApnContext::getApnTypeBitmask, x -> x));
- assertTrue(apnContexts.get(ApnSetting.TYPE_MMS).getDataConnection()
- .getNetworkCapabilities().hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS));
- assertTrue(apnContexts.get(ApnSetting.TYPE_MMS).getDataConnection()
- .getNetworkCapabilities().hasCapability(NetworkCapabilities.NET_CAPABILITY_XCAP));
- assertTrue(apnContexts.get(ApnSetting.TYPE_MMS).getDataConnection()
- .getNetworkCapabilities().hasCapability(
- NetworkCapabilities.NET_CAPABILITY_INTERNET));
-
- // Disable mobile data
- doReturn(false).when(mDataEnabledSettings).isDataEnabled();
- doReturn(false).when(mDataEnabledSettings).isDataEnabled(anyInt());
- doReturn(false).when(mDataEnabledSettings).isMmsAlwaysAllowed();
- mDct.obtainMessage(DctConstants.EVENT_DATA_ENABLED_OVERRIDE_RULES_CHANGED).sendToTarget();
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- // Expected tear down all metered DataConnections
- waitForMs(200);
- verify(mSimulatedCommandsVerifier).deactivateDataCall(
- anyInt(), eq(DataService.REQUEST_REASON_NORMAL), any(Message.class));
- assertEquals(DctConstants.State.IDLE, mDct.getState(ApnSetting.TYPE_MMS_STRING));
-
- // Allow MMS unconditionally
- clearInvocations(mSimulatedCommandsVerifier);
- doReturn(true).when(mDataEnabledSettings).isMmsAlwaysAllowed();
- doReturn(true).when(mDataEnabledSettings).isDataEnabled(ApnSetting.TYPE_MMS);
- mDct.obtainMessage(DctConstants.EVENT_DATA_ENABLED_OVERRIDE_RULES_CHANGED).sendToTarget();
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- // Verify MMS was set up and is connected
- waitForMs(200);
- verify(mSimulatedCommandsVerifier).setupDataCall(
- eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- assertEquals(DctConstants.State.CONNECTED, mDct.getState(ApnSetting.TYPE_MMS_STRING));
-
- // Ensure MMS data connection has the MMS capability only.
- apnContexts = mDct.getApnContexts().stream().collect(
- Collectors.toMap(ApnContext::getApnTypeBitmask, x -> x));
- assertTrue(apnContexts.get(ApnSetting.TYPE_MMS).getDataConnection()
- .getNetworkCapabilities().hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS));
- assertFalse(apnContexts.get(ApnSetting.TYPE_MMS).getDataConnection()
- .getNetworkCapabilities().hasCapability(NetworkCapabilities.NET_CAPABILITY_XCAP));
- assertFalse(apnContexts.get(ApnSetting.TYPE_MMS).getDataConnection()
- .getNetworkCapabilities().hasCapability(
- NetworkCapabilities.NET_CAPABILITY_INTERNET));
- }
-
- @Test
- @MediumTest
- public void testUserDisableRoaming() {
- //step 1: setup two DataCalls one for Metered: default, another one for Non-metered: IMS
- //step 2: set roaming disabled, data is enabled
- //step 3: under roaming service
- //step 4: only tear down metered data connections.
-
- //set Default and MMS to be metered in the CarrierConfigManager
- boolean roamingEnabled = mDct.getDataRoamingEnabled();
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_DEFAULT_STRING, ApnSetting.TYPE_MMS_STRING});
-
- mDct.enableApn(ApnSetting.TYPE_IMS, DcTracker.REQUEST_TYPE_NORMAL, null);
- waitForHandlerAction(mDct, 1000);
- mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
- waitForHandlerAction(mDct, 1000);
-
- sendInitializationEvents();
-
- ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
- verify(mSimulatedCommandsVerifier, times(2)).setupDataCall(
- eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
-
- //user is in roaming
- doReturn(true).when(mServiceState).getDataRoaming();
- logd("Sending DISABLE_ROAMING_CMD");
- mDct.setDataRoamingEnabledByUser(false);
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_ROAMING_ON));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- // Data connection is running on a different thread. Have to wait.
- waitForMs(200);
- // expected tear down all metered DataConnections
- verify(mSimulatedCommandsVerifier, times(1)).deactivateDataCall(
- eq(DataService.REQUEST_REASON_NORMAL), anyInt(),
- any(Message.class));
- assertTrue(mDct.isAnyDataConnected());
- assertEquals(DctConstants.State.IDLE, mDct.getState(ApnSetting.TYPE_DEFAULT_STRING));
- assertEquals(DctConstants.State.CONNECTED, mDct.getState(ApnSetting.TYPE_IMS_STRING));
-
- // reset roaming settings / data enabled settings at end of this test
- mDct.setDataRoamingEnabledByUser(roamingEnabled);
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- }
-
- @Test
- @MediumTest
- public void testDataCallOnUserDisableRoaming() {
- //step 1: mock under roaming service and user disabled roaming from settings.
- //step 2: user toggled data settings on
- //step 3: only non-metered data call is established
-
- boolean roamingEnabled = mDct.getDataRoamingEnabled();
- doReturn(true).when(mServiceState).getDataRoaming();
-
- //set Default and MMS to be metered in the CarrierConfigManager
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_DEFAULT_STRING, ApnSetting.TYPE_MMS_STRING});
- mDct.enableApn(ApnSetting.TYPE_IMS, DcTracker.REQUEST_TYPE_NORMAL, null);
- mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
-
- logd("Sending DISABLE_ROAMING_CMD");
- mDct.setDataRoamingEnabledByUser(false);
-
- sendInitializationEvents();
-
- ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
-
- verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
- eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- verifyDataProfile(dpCaptor.getValue(), FAKE_APN3, 2, 64, 0, 0);
-
- assertTrue(mDct.isAnyDataConnected());
- assertEquals(DctConstants.State.IDLE, mDct.getState(ApnSetting.TYPE_DEFAULT_STRING));
- assertEquals(DctConstants.State.CONNECTED, mDct.getState(ApnSetting.TYPE_IMS_STRING));
-
- // reset roaming settings / data enabled settings at end of this test
- mDct.setDataRoamingEnabledByUser(roamingEnabled);
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- }
-
- // Test the default data switch scenario.
- @FlakyTest /* flakes 1.57% of the time */
- @Test
- @MediumTest
- public void testDDSResetAutoAttach() throws Exception {
- mContextFixture.putBooleanResource(
- com.android.internal.R.bool.config_auto_attach_data_on_creation, true);
- testDataSetup();
- assertTrue(mDct.shouldAutoAttach());
- mDct.sendEmptyMessage(DctConstants.EVENT_CARRIER_CONFIG_CHANGED);
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- // The auto attach flag should be reset after update
- assertFalse(mDct.shouldAutoAttach());
- }
-
- // Test for API carrierActionSetMeteredApnsEnabled.
- @FlakyTest
- @Ignore
- @Test
- @MediumTest
- public void testCarrierActionSetMeteredApnsEnabled() {
- //step 1: setup two DataCalls one for Internet and IMS
- //step 2: set data is enabled
- //step 3: cold sim is detected
- //step 4: all data connection is torn down
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_DEFAULT_STRING, ApnSetting.TYPE_MMS_STRING});
-
- mDct.enableApn(ApnSetting.TYPE_IMS, DcTracker.REQUEST_TYPE_NORMAL, null);
- mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
-
- sendInitializationEvents();
-
- ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
- verify(mSimulatedCommandsVerifier, times(2)).setupDataCall(
- eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 5, 1, NETWORK_TYPE_LTE_BITMASK);
- assertTrue(mDct.isAnyDataConnected());
-
- AsyncResult ar = new AsyncResult(null,
- new Pair<>(false, DataEnabledSettings.REASON_DATA_ENABLED_BY_CARRIER), null);
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_ENABLED_CHANGED, ar));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- // Data connection is running on a different thread. Have to wait.
- waitForMs(200);
- // Validate all metered data connections have been torn down
- verify(mSimulatedCommandsVerifier, times(1)).deactivateDataCall(
- eq(DataService.REQUEST_REASON_NORMAL), anyInt(),
- any(Message.class));
- assertTrue(mDct.isAnyDataConnected());
- assertEquals(DctConstants.State.IDLE, mDct.getState(ApnSetting.TYPE_DEFAULT_STRING));
- }
-
- private void initApns(String targetApn, String[] canHandleTypes) {
- doReturn(targetApn).when(mApnContext).getApnType();
- doReturn(ApnSetting.getApnTypesBitmaskFromString(mApnContext.getApnType()))
- .when(mApnContext).getApnTypeBitmask();
- doReturn(true).when(mApnContext).isConnectable();
- ApnSetting apnSetting = createApnSetting(ApnSetting.getApnTypesBitmaskFromString(
- TextUtils.join(",", canHandleTypes)));
- doReturn(apnSetting).when(mApnContext).getNextApnSetting();
- doReturn(apnSetting).when(mApnContext).getApnSetting();
- doReturn(mDataConnection).when(mApnContext).getDataConnection();
- doReturn(true).when(mApnContext).isEnabled();
- doReturn(true).when(mApnContext).isDependencyMet();
- doReturn(true).when(mApnContext).isReady();
- doReturn(false).when(mApnContext).hasRestrictedRequests(eq(true));
- }
-
- // Test the emergency APN setup.
- @Test
- @SmallTest
- public void testTrySetupDataEmergencyApn() {
- initApns(ApnSetting.TYPE_EMERGENCY_STRING,
- new String[]{ApnSetting.TYPE_EMERGENCY_STRING});
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_TRY_SETUP_DATA, mApnContext));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- waitForMs(200);
-
- verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
- eq(AccessNetworkType.EUTRAN), any(DataProfile.class), eq(false), eq(false),
- eq(DataService.REQUEST_REASON_NORMAL), any(), anyInt(), any(), any(),
- anyBoolean(), any(Message.class));
- }
-
- // Test the XCAP APN setup.
- @Test
- @SmallTest
- public void testTrySetupDataXcapApn() {
- initApns(ApnSetting.TYPE_XCAP_STRING, new String[]{ApnSetting.TYPE_XCAP_STRING});
- mDct.enableApn(ApnSetting.TYPE_XCAP, DcTracker.REQUEST_TYPE_NORMAL, null);
-
- sendInitializationEvents();
-
- verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
- eq(AccessNetworkType.EUTRAN), any(DataProfile.class), eq(false), eq(false),
- eq(DataService.REQUEST_REASON_NORMAL), any(), anyInt(), any(), any(),
- anyBoolean(), any(Message.class));
- }
-
- // Test the ENTERPRISE APN setup.
- @Test
- public void testTrySetupDataEnterpriseApn() {
- 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_APN1, 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());
- SetupDataCallResult result = createSetupDataCallResult();
- result.cid = 10;
- mSimulatedCommands.setDataCallResult(true, result);
- mDct.enableApn(ApnSetting.TYPE_ENTERPRISE, DcTracker.REQUEST_TYPE_NORMAL, null);
- waitForMs(200);
-
- 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().getDataNetworkName());
- assertTrue(Arrays.equals(DataConnection.getEnterpriseOsAppId(),
- tdCaptor.getValue().getOsAppId()));
- }
-
- // Test the ENTERPRISE APN setup when default data is not set up yet.
- @Test
- public void testTrySetupDataEnterpriseApnNoDefaultData() {
- mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
- .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_NR)
- .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
- .build();
- doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
- anyInt(), anyInt());
- mDct.enableApn(ApnSetting.TYPE_ENTERPRISE, DcTracker.REQUEST_TYPE_NORMAL, null);
- 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().getDataNetworkName());
- assertTrue(Arrays.equals(DataConnection.getEnterpriseOsAppId(),
- tdCaptor.getValue().getOsAppId()));
-
- // Check APN contexts with no DEFAULT set up
- Map<Integer, ApnContext> apnContexts = mDct.getApnContexts()
- .stream().collect(Collectors.toMap(ApnContext::getApnTypeBitmask, x -> x));
- assertEquals(DctConstants.State.IDLE, apnContexts.get(ApnSetting.TYPE_DEFAULT).getState());
- assertEquals(DctConstants.State.FAILED,
- apnContexts.get(ApnSetting.TYPE_ENTERPRISE).getState());
-
- mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
- .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
- .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
- .build();
- doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
- anyInt(), anyInt());
- mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- waitForMs(200);
-
- 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_APN1, tdCaptor.getValue().getDataNetworkName());
- assertEquals(null, tdCaptor.getValue().getOsAppId());
-
- // Check APN contexts after DEFAULT is set up (and ENTERPRISE failure)
- apnContexts = mDct.getApnContexts()
- .stream().collect(Collectors.toMap(ApnContext::getApnTypeBitmask, x -> x));
- assertEquals(DctConstants.State.CONNECTED,
- apnContexts.get(ApnSetting.TYPE_DEFAULT).getState());
- assertEquals(DctConstants.State.FAILED,
- apnContexts.get(ApnSetting.TYPE_ENTERPRISE).getState());
-
- mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
- .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_NR)
- .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
- .build();
- doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
- anyInt(), anyInt());
- SetupDataCallResult result = createSetupDataCallResult();
- result.cid = 10;
- mSimulatedCommands.setDataCallResult(true, result);
- mDct.enableApn(ApnSetting.TYPE_ENTERPRISE, DcTracker.REQUEST_TYPE_NORMAL, null);
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- waitForMs(200);
-
- verify(mSimulatedCommandsVerifier, times(2)).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().getDataNetworkName());
- assertTrue(Arrays.equals(DataConnection.getEnterpriseOsAppId(),
- tdCaptor.getValue().getOsAppId()));
-
- // Check APN contexts after DEFAULT is set up (and ENTERPRISE reenabled)
- apnContexts = mDct.getApnContexts()
- .stream().collect(Collectors.toMap(ApnContext::getApnTypeBitmask, x -> x));
- assertEquals(DctConstants.State.CONNECTED,
- apnContexts.get(ApnSetting.TYPE_DEFAULT).getState());
- assertEquals(DctConstants.State.CONNECTED,
- apnContexts.get(ApnSetting.TYPE_ENTERPRISE).getState());
- }
-
- // Test the ENTERPRISE APN setup when the same CID is returned.
- @Test
- public void testTrySetupDataEnterpriseApnDuplicateCid() {
- mApnSettingContentProvider.setFakeApn1NetworkTypeBitmask(
- NETWORK_TYPE_LTE_BITMASK | NETWORK_TYPE_NR_BITMASK);
- mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
- .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_NR)
- .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
- .build();
- doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
- anyInt(), anyInt());
- // mSimulatedCommandsVerifier will return the same CID in SetupDataCallResult
- mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
- mDct.enableApn(ApnSetting.TYPE_ENTERPRISE, DcTracker.REQUEST_TYPE_NORMAL, null);
- sendInitializationEvents();
- waitForMs(200);
-
- ArgumentCaptor<TrafficDescriptor> tdCaptor =
- ArgumentCaptor.forClass(TrafficDescriptor.class);
- verify(mSimulatedCommandsVerifier, times(2)).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));
- List<TrafficDescriptor> tds = tdCaptor.getAllValues();
- // [0] is default and [1] is enterprise, since default should be set up first
- assertEquals(FAKE_APN1, tds.get(0).getDataNetworkName());
- assertEquals(null, tds.get(0).getOsAppId());
- assertEquals(null, tds.get(1).getDataNetworkName());
- assertTrue(Arrays.equals(DataConnection.getEnterpriseOsAppId(), tds.get(1).getOsAppId()));
-
- // Check APN contexts after DEFAULT and ENTERPRISE set up
- Map<Integer, ApnContext> apnContexts = mDct.getApnContexts()
- .stream().collect(Collectors.toMap(ApnContext::getApnTypeBitmask, x -> x));
- assertEquals(DctConstants.State.CONNECTED,
- apnContexts.get(ApnSetting.TYPE_DEFAULT).getState());
- assertEquals(DctConstants.State.FAILED,
- apnContexts.get(ApnSetting.TYPE_ENTERPRISE).getState());
- }
-
- @Test
- @SmallTest
- public void testGetDataConnectionState() {
- initApns(ApnSetting.TYPE_SUPL_STRING,
- new String[]{ApnSetting.TYPE_SUPL_STRING, ApnSetting.TYPE_DEFAULT_STRING});
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_DEFAULT_STRING});
- mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
- mDct.enableApn(ApnSetting.TYPE_SUPL, DcTracker.REQUEST_TYPE_NORMAL, null);
-
- sendInitializationEvents();
-
- // Assert that both APN_TYPE_SUPL & APN_TYPE_DEFAULT are connected even we only setup data
- // for APN_TYPE_SUPL
- assertEquals(DctConstants.State.CONNECTED, mDct.getState(ApnSetting.TYPE_SUPL_STRING));
- assertEquals(DctConstants.State.CONNECTED, mDct.getState(ApnSetting.TYPE_DEFAULT_STRING));
- }
-
- // Test the unmetered APN setup when data is disabled.
- @Test
- @SmallTest
- public void testTrySetupDataUnmeteredDataDisabled() {
- initApns(ApnSetting.TYPE_SUPL_STRING, new String[]{ApnSetting.TYPE_SUPL_STRING});
- doReturn(false).when(mDataEnabledSettings).isDataEnabled();
- doReturn(false).when(mDataEnabledSettings).isDataEnabled(anyInt());
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_FOTA_STRING});
-
- mDct.enableApn(ApnSetting.TYPE_SUPL, DcTracker.REQUEST_TYPE_NORMAL, null);
-
- sendInitializationEvents();
-
- verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
- eq(AccessNetworkType.EUTRAN), any(DataProfile.class),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- }
-
- // Test the unmetered default APN setup when data is disabled. Default APN should always honor
- // the users's setting.
- @Test
- @SmallTest
- public void testTrySetupDataUnmeteredDefaultDataDisabled() {
- initApns(ApnSetting.TYPE_DEFAULT_STRING, new String[]{ApnSetting.TYPE_DEFAULT_STRING});
- doReturn(false).when(mDataEnabledSettings).isDataEnabled();
- doReturn(false).when(mDataEnabledSettings).isDataEnabled(anyInt());
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_MMS_STRING});
-
- mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
-
- sendInitializationEvents();
-
- verify(mSimulatedCommandsVerifier, never()).setupDataCall(
- eq(AccessNetworkType.EUTRAN), any(DataProfile.class),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- }
-
-
- // Test the metered APN setup when data is disabled.
- @Test
- @SmallTest
- public void testTrySetupMeteredDataDisabled() {
- initApns(ApnSetting.TYPE_DEFAULT_STRING, new String[]{ApnSetting.TYPE_DEFAULT_STRING});
- doReturn(false).when(mDataEnabledSettings).isDataEnabled();
- doReturn(false).when(mDataEnabledSettings).isDataEnabled(anyInt());
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_DEFAULT_STRING});
-
- mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
-
- sendInitializationEvents();
-
- verify(mSimulatedCommandsVerifier, times(0)).setupDataCall(anyInt(), any(DataProfile.class),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- }
-
- // Test the restricted data request when data is disabled.
- @Test
- @SmallTest
- public void testTrySetupRestrictedDataDisabled() {
- initApns(ApnSetting.TYPE_DEFAULT_STRING, new String[]{ApnSetting.TYPE_DEFAULT_STRING});
- doReturn(false).when(mDataEnabledSettings).isDataEnabled();
- doReturn(false).when(mDataEnabledSettings).isDataEnabled(anyInt());
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_DEFAULT_STRING});
-
- sendInitializationEvents();
-
- NetworkRequest nr = new NetworkRequest.Builder()
- .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
- .build();
- mDct.requestNetwork(nr, DcTracker.REQUEST_TYPE_NORMAL, null);
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- // Data connection is running on a different thread. Have to wait.
- waitForMs(200);
- verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(anyInt(), any(DataProfile.class),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- }
-
- // Test the restricted data request when roaming is disabled.
- @Test
- @SmallTest
- public void testTrySetupRestrictedRoamingDisabled() {
- initApns(ApnSetting.TYPE_DEFAULT_STRING, new String[]{ApnSetting.TYPE_DEFAULT_STRING});
-
- mDct.setDataRoamingEnabledByUser(false);
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_DEFAULT_STRING});
- //user is in roaming
- doReturn(true).when(mServiceState).getDataRoaming();
-
- sendInitializationEvents();
-
- NetworkRequest nr = new NetworkRequest.Builder()
- .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
- .build();
- mDct.requestNetwork(nr, DcTracker.REQUEST_TYPE_NORMAL, null);
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- // Data connection is running on a different thread. Have to wait.
- waitForMs(200);
- verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(anyInt(), any(DataProfile.class),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- }
-
- // Test the default data when data is not connectable.
- @Test
- @SmallTest
- public void testTrySetupNotConnectable() {
- initApns(ApnSetting.TYPE_DEFAULT_STRING, new String[]{ApnSetting.TYPE_ALL_STRING});
- doReturn(false).when(mApnContext).isConnectable();
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_DEFAULT_STRING});
-
- sendInitializationEvents();
-
- verify(mSimulatedCommandsVerifier, times(0)).setupDataCall(anyInt(), any(DataProfile.class),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- }
-
- // Test the default data on IWLAN.
- @Test
- @SmallTest
- public void testTrySetupDefaultOnIWLAN() {
- doReturn(true).when(mAccessNetworksManager).isInLegacyMode();
- initApns(ApnSetting.TYPE_DEFAULT_STRING, new String[]{ApnSetting.TYPE_ALL_STRING});
- mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
- .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN)
- .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
- .build();
- doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
- anyInt(), anyInt());
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_DEFAULT_STRING});
-
- sendInitializationEvents();
-
- verify(mSimulatedCommandsVerifier, times(0)).setupDataCall(anyInt(), any(DataProfile.class),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- }
-
- // Test the default data when the phone is in ECBM.
- @Test
- @SmallTest
- public void testTrySetupDefaultInECBM() {
- initApns(ApnSetting.TYPE_DEFAULT_STRING, new String[]{ApnSetting.TYPE_ALL_STRING});
- doReturn(true).when(mPhone).isInEcm();
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_DEFAULT_STRING});
-
- sendInitializationEvents();
-
- verify(mSimulatedCommandsVerifier, times(0)).setupDataCall(anyInt(), any(DataProfile.class),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- }
-
- // Test update waiting apn list when on data rat change
- @FlakyTest /* flakes 0.86% of the time */
- @Ignore
- @Test
- @SmallTest
- public void testUpdateWaitingApnListOnDataRatChange() {
- mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
- .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_EHRPD)
- .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
- .build();
- doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
- anyInt(), anyInt());
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_DEFAULT_STRING});
- mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
- initApns(ApnSetting.TYPE_DEFAULT_STRING, new String[]{ApnSetting.TYPE_ALL_STRING});
-
- sendInitializationEvents();
-
- ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
- // Verify if RIL command was sent properly.
- verify(mSimulatedCommandsVerifier).setupDataCall(
- eq(AccessNetworkType.CDMA2000), dpCaptor.capture(),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- verifyDataProfile(dpCaptor.getValue(), FAKE_APN4, 0, 21, 2, NETWORK_TYPE_EHRPD_BITMASK);
- assertTrue(mDct.isAnyDataConnected());
-
- //data rat change from ehrpd to lte
- logd("Sending EVENT_DATA_RAT_CHANGED");
- mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
- .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
- .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
- .build();
- doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
- anyInt(), anyInt());
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_RAT_CHANGED, null));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- // Data connection is running on a different thread. Have to wait.
- waitForMs(200);
- // Verify the disconnected data call due to rat change and retry manger schedule another
- // data call setup
- verify(mSimulatedCommandsVerifier, times(1)).deactivateDataCall(
- eq(DataService.REQUEST_REASON_NORMAL), anyInt(),
- any(Message.class));
- verify(mAlarmManager, times(1)).setExact(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
- anyLong(), any(PendingIntent.class));
-
- //Send event for reconnecting data
- initApns(ApnSetting.TYPE_DEFAULT_STRING, new String[]{ApnSetting.TYPE_ALL_STRING});
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_RECONNECT,
- mPhone.getPhoneId(), DcTracker.RELEASE_TYPE_NORMAL, mApnContext));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- // Data connection is running on a different thread. Have to wait.
- waitForMs(200);
- // Verify if RIL command was sent properly.
- verify(mSimulatedCommandsVerifier).setupDataCall(
- eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
- assertTrue(mDct.isAnyDataConnected());
- }
-
- /**
- * Test that fetchDunApns() returns list that prioritize the preferred APN when the preferred
- * APN including DUN type.
- */
- @Test
- public void testFetchDunApnWithPreferredApn() {
- // Set support APN types of FAKE_APN1 and FAKE_APN5
- mApnSettingContentProvider.setFakeApn1Types("default,dun");
- mApnSettingContentProvider.setFakeApn5Types("default,dun");
-
- // Set prefer apn set id.
- ContentResolver cr = mContext.getContentResolver();
- ContentValues values = new ContentValues();
- values.put(Telephony.Carriers.APN_SET_ID, 0);
- cr.update(PREFERAPN_URI, values, null, null);
- // Set FAKE_APN5 as the preferred APN.
- mApnSettingContentProvider.setFakePreferredApn(mApnSettingContentProvider.getFakeApn5());
-
- sendInitializationEvents();
-
- // Return the APN list that set the preferred APN at the top.
- ArrayList<ApnSetting> dunApns = mDct.fetchDunApns();
- assertEquals(2, dunApns.size());
- assertEquals(FAKE_APN5, dunApns.get(0).getApnName());
- assertEquals(FAKE_APN1, dunApns.get(1).getApnName());
- }
-
- // This tests simulates the race case where the sim status change event is triggered, the
- // default data connection is attached, and then the carrier config gets changed which bumps
- // the database id which we want to ignore when cleaning up connections and matching against
- // the dun APN. Tests b/158908392.
- @Test
- @SmallTest
- public void testCheckForCompatibleDataConnectionWithDunWhenIdsChange() {
- //Set dun as a support apn type of FAKE_APN1
- mApnSettingContentProvider.setFakeApn1Types("default,supl,dun");
-
- // Enable the default apn
- mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- //Load the sim and attach the data connection without firing the carrier changed event
- final String logMsgPrefix = "testCheckForCompatibleDataConnectionWithDunWhenIdsChange: ";
- sendSimStateUpdated(logMsgPrefix);
- sendEventDataConnectionAttached(logMsgPrefix);
- waitForMs(200);
-
- // Confirm that FAKE_APN1 comes up as a dun candidate
- ApnSetting dunApn = mDct.fetchDunApns().get(0);
- assertEquals(dunApn.getApnName(), FAKE_APN1);
- Map<Integer, ApnContext> apnContexts = mDct.getApnContexts()
- .stream().collect(Collectors.toMap(ApnContext::getApnTypeBitmask, x -> x));
-
- //Double check that the default apn content is connected while the dun apn context is not
- assertEquals(apnContexts.get(ApnSetting.TYPE_DEFAULT).getState(),
- DctConstants.State.CONNECTED);
- assertNotEquals(apnContexts.get(ApnSetting.TYPE_DUN).getState(),
- DctConstants.State.CONNECTED);
-
-
- //Change the row ids the same way as what happens when we have old apn values in the
- //carrier table
- mApnSettingContentProvider.setRowIdOffset(100);
- sendCarrierConfigChanged(logMsgPrefix);
- waitForMs(200);
-
- mDct.enableApn(ApnSetting.TYPE_DUN, DcTracker.REQUEST_TYPE_NORMAL, null);
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- Map<Integer, ApnContext> apnContextsAfterRowIdsChanged = mDct.getApnContexts()
- .stream().collect(Collectors.toMap(ApnContext::getApnTypeBitmask, x -> x));
-
- //Make sure that the data connection used earlier wasn't cleaned up and still in use.
- assertEquals(apnContexts.get(ApnSetting.TYPE_DEFAULT).getDataConnection(),
- apnContextsAfterRowIdsChanged.get(ApnSetting.TYPE_DEFAULT).getDataConnection());
-
- //Check that the DUN is using the same active data connection
- assertEquals(apnContexts.get(ApnSetting.TYPE_DEFAULT).getDataConnection(),
- apnContextsAfterRowIdsChanged.get(ApnSetting.TYPE_DUN).getDataConnection());
- }
-
- @Test
- @SmallTest
- public void testCheckForCompatibleDataConnectionWithEnterprise() {
- // Allow both DEFAULT and ENTERPRISE to use APN 1
- mApnSettingContentProvider.setFakeApn1NetworkTypeBitmask(
- NETWORK_TYPE_LTE_BITMASK | NETWORK_TYPE_NR_BITMASK);
-
- // Enable the DEFAULT APN
- mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- 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_APN1, tdCaptor.getValue().getDataNetworkName());
- assertEquals(null, tdCaptor.getValue().getOsAppId());
-
- // Check APN contexts after DEFAULT is set up
- Map<Integer, ApnContext> apnContexts = mDct.getApnContexts()
- .stream().collect(Collectors.toMap(ApnContext::getApnTypeBitmask, x -> x));
- assertEquals(apnContexts.get(ApnSetting.TYPE_DEFAULT).getState(),
- DctConstants.State.CONNECTED);
- assertNotEquals(apnContexts.get(ApnSetting.TYPE_ENTERPRISE).getState(),
- DctConstants.State.CONNECTED);
-
- // Enable the ENTERPRISE APN
- mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
- .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_NR)
- .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
- .build();
- doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
- anyInt(), anyInt());
- SetupDataCallResult result = createSetupDataCallResult();
- result.cid = 10;
- mSimulatedCommands.setDataCallResult(true, result);
- mDct.enableApn(ApnSetting.TYPE_ENTERPRISE, DcTracker.REQUEST_TYPE_NORMAL, null);
- waitForMs(200);
-
- 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().getDataNetworkName());
- assertTrue(Arrays.equals(DataConnection.getEnterpriseOsAppId(),
- tdCaptor.getValue().getOsAppId()));
-
- // Check APN contexts after ENTERPRISE is set up
- Map<Integer, ApnContext> apnContextsAfterRowIdsChanged = mDct.getApnContexts()
- .stream().collect(Collectors.toMap(ApnContext::getApnTypeBitmask, x -> x));
-
- // Make sure that the data connection used earlier wasn't cleaned up and still in use.
- assertEquals(apnContexts.get(ApnSetting.TYPE_DEFAULT).getDataConnection(),
- apnContextsAfterRowIdsChanged.get(ApnSetting.TYPE_DEFAULT).getDataConnection());
-
- // Check that ENTERPRISE isn't using the same data connection as DEFAULT
- assertNotEquals(apnContexts.get(ApnSetting.TYPE_DEFAULT).getDataConnection(),
- apnContextsAfterRowIdsChanged.get(ApnSetting.TYPE_ENTERPRISE).getDataConnection());
- }
-
- // Test for Data setup with APN Set ID
- @Test
- @SmallTest
- public void testDataSetupWithApnSetId() throws Exception {
- // Set the prefer apn set id to "1"
- ContentResolver cr = mContext.getContentResolver();
- ContentValues values = new ContentValues();
- values.put(Telephony.Carriers.APN_SET_ID, 1);
- cr.update(PREFERAPN_URI, values, null, null);
-
- mDct.enableApn(ApnSetting.TYPE_IMS, DcTracker.REQUEST_TYPE_NORMAL, null);
- mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
-
- sendInitializationEvents();
-
- ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
- verify(mSimulatedCommandsVerifier, times(2)).setupDataCall(
- eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
-
- List<DataProfile> dataProfiles = dpCaptor.getAllValues();
- assertEquals(2, dataProfiles.size());
-
- // Verify to use FAKE APN7 which is Default APN with apnSetId=1(Same as the pereferred
- // APN's set id).
- Optional<DataProfile> fakeApn7 = dataProfiles.stream()
- .filter(dp -> dp.getApn().equals(FAKE_APN7)).findFirst();
- assertTrue(fakeApn7.isPresent());
- verifyDataProfile(fakeApn7.get(), FAKE_APN7, 0, 17, 1, NETWORK_TYPE_LTE_BITMASK);
-
- // Verify to use FAKE APN8 which is IMS APN with apnSetId=-1
- // (Telephony.Carriers.MATCH_ALL_APN_SET_ID).
- Optional<DataProfile> fakeApn8 = dataProfiles.stream()
- .filter(dp -> dp.getApn().equals(FAKE_APN8)).findFirst();
- assertTrue(fakeApn8.isPresent());
- verifyDataProfile(fakeApn8.get(), FAKE_APN8, 2, 64, 1, NETWORK_TYPE_LTE_BITMASK);
- }
-
- // Test oos
- @Test
- @SmallTest
- public void testDataRatChangeOOS() {
- mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
- .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_EHRPD)
- .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
- .build();
- doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
- anyInt(), anyInt());
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_DEFAULT_STRING});
- mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
- initApns(ApnSetting.TYPE_DEFAULT_STRING, new String[]{ApnSetting.TYPE_ALL_STRING});
-
- sendInitializationEvents();
-
- ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
- // Verify if RIL command was sent properly.
- verify(mSimulatedCommandsVerifier).setupDataCall(
- eq(AccessNetworkType.CDMA2000), dpCaptor.capture(),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- verifyDataProfile(dpCaptor.getValue(), FAKE_APN4, 0, 21, 2, NETWORK_TYPE_EHRPD_BITMASK);
- assertTrue(mDct.isAnyDataConnected());
-
- // Data rat change from ehrpd to unknown due to OOS
- logd("Sending EVENT_DATA_RAT_CHANGED");
- mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
- .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_UNKNOWN)
- .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
- .build();
- doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
- anyInt(), anyInt());
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_RAT_CHANGED, null));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- // Data connection is running on a different thread. Have to wait.
- waitForMs(200);
- // Verify data connection is on
- verify(mSimulatedCommandsVerifier, times(0)).deactivateDataCall(
- eq(DataService.REQUEST_REASON_NORMAL), anyInt(),
- any(Message.class));
-
- // Data rat resume from unknown to ehrpd
- mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
- .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_EHRPD)
- .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
- .build();
- doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
- anyInt(), anyInt());
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_RAT_CHANGED, null));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- // Verify the same data connection
- assertEquals(FAKE_APN4, mDct.getActiveApnString(ApnSetting.TYPE_DEFAULT_STRING));
- assertTrue(mDct.isAnyDataConnected());
- }
-
- // Test provisioning
- /*@Test
- @SmallTest
- public void testDataEnableInProvisioning() throws Exception {
- ContentResolver resolver = mContext.getContentResolver();
-
- assertEquals(1, Settings.Global.getInt(resolver, Settings.Global.MOBILE_DATA));
- assertTrue(mDct.isDataEnabled());
- assertTrue(mDct.isUserDataEnabled());
-
- mDct.setUserDataEnabled(false);
- waitForMs(200);
-
- assertEquals(0, Settings.Global.getInt(resolver, Settings.Global.MOBILE_DATA));
- assertFalse(mDct.isDataEnabled());
- assertFalse(mDct.isUserDataEnabled());
-
- // Changing provisioned to 0.
- Settings.Global.putInt(resolver, Settings.Global.DEVICE_PROVISIONED, 0);
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE, null));
- waitForMs(200);
-
- assertTrue(mDct.isDataEnabled());
- assertTrue(mDct.isUserDataEnabled());
-
- // Enable user data during provisioning. It should write to
- // Settings.Global.MOBILE_DATA and keep data enabled when provisioned.
- mDct.setUserDataEnabled(true);
- Settings.Global.putInt(resolver, Settings.Global.DEVICE_PROVISIONED, 1);
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE, null));
- waitForMs(200);
-
- assertTrue(mDct.isDataEnabled());
- assertTrue(mDct.isUserDataEnabled());
- assertEquals(1, Settings.Global.getInt(resolver, Settings.Global.MOBILE_DATA));
- }*/
-
- /*
- @Test
- @SmallTest
- public void testNotifyDataEnabledChanged() throws Exception {
- doAnswer(invocation -> {
- mMessage = (Message) invocation.getArguments()[0];
- return true;
- }).when(mHandler).sendMessageDelayed(any(), anyLong());
-
- // Test registration.
- mDct.registerForDataEnabledChanged(mHandler, DATA_ENABLED_CHANGED, null);
- verifyDataEnabledChangedMessage(true, DataEnabledSettings.REASON_REGISTERED);
-
- // Disable user data. Should receive data enabled change to false.
- mDct.setUserDataEnabled(false);
- waitForMs(200);
- verifyDataEnabledChangedMessage(false, DataEnabledSettings.REASON_USER_DATA_ENABLED);
-
- // Changing provisioned to 0. Shouldn't receive any message, as data enabled remains false.
- ContentResolver resolver = mContext.getContentResolver();
- Settings.Global.putInt(resolver, Settings.Global.DEVICE_PROVISIONED, 0);
- Settings.Global.putInt(resolver, Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED,
- 0);
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DEVICE_PROVISIONED_CHANGE, null));
- waitForMs(200);
- assertFalse(mDct.isDataEnabled());
- verify(mHandler, never()).sendMessageDelayed(any(), anyLong());
-
- // Changing provisioningDataEnabled to 1. It should trigger data enabled change to true.
- Settings.Global.putInt(resolver,
- Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED, 1);
- mDct.sendMessage(mDct.obtainMessage(
- DctConstants.EVENT_DEVICE_PROVISIONING_DATA_SETTING_CHANGE, null));
- waitForMs(200);
- verifyDataEnabledChangedMessage(
- true, DataEnabledSettings.REASON_PROVISIONING_DATA_ENABLED_CHANGED);
- }*/
-
- @Test
- @SmallTest
- public void testNetworkStatusChangedRecoveryOFF() {
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_DEFAULT_STRING, ApnSetting.TYPE_MMS_STRING});
- mDct.enableApn(ApnSetting.TYPE_IMS, DcTracker.REQUEST_TYPE_NORMAL, null);
- mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
-
- sendInitializationEvents();
-
- ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
- verify(mSimulatedCommandsVerifier, times(2)).setupDataCall(
- eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
-
- logd("Sending EVENT_NETWORK_STATUS_CHANGED");
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_NETWORK_STATUS_CHANGED,
- NetworkAgent.VALID_NETWORK, 1, null));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- logd("Sending EVENT_NETWORK_STATUS_CHANGED");
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_NETWORK_STATUS_CHANGED,
- NetworkAgent.INVALID_NETWORK, 1, null));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- waitForMs(200);
-
- // Verify that its no-op when the new data stall detection feature is disabled
- verify(mSimulatedCommandsVerifier, times(0)).getDataCallList(any(Message.class));
- }
-
- @FlakyTest
- @Test
- @SmallTest
- public void testNetworkStatusChangedRecoveryON() {
- ContentResolver resolver = mContext.getContentResolver();
- Settings.Global.putInt(resolver, Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 1);
- Settings.System.putInt(resolver, "radio.data.stall.recovery.action", 0);
- doReturn(new SignalStrength()).when(mPhone).getSignalStrength();
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_DEFAULT_STRING, ApnSetting.TYPE_MMS_STRING});
- mDct.enableApn(ApnSetting.TYPE_IMS, DcTracker.REQUEST_TYPE_NORMAL, null);
- mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
-
- sendInitializationEvents();
-
- ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
- verify(mSimulatedCommandsVerifier, timeout(TEST_TIMEOUT).times(2)).setupDataCall(
- eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
-
- logd("Sending EVENT_NETWORK_STATUS_CHANGED");
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_NETWORK_STATUS_CHANGED,
- NetworkAgent.VALID_NETWORK, 1, null));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- logd("Sending EVENT_NETWORK_STATUS_CHANGED");
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_NETWORK_STATUS_CHANGED,
- NetworkAgent.INVALID_NETWORK, 1, null));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- // Data connection is running on a different thread. Have to wait.
- waitForMs(200);
- verify(mSimulatedCommandsVerifier, times(1)).getDataCallList(any(Message.class));
- }
-
- @FlakyTest
- @Test
- @SmallTest
- public void testRecoveryStepPDPReset() {
- ContentResolver resolver = mContext.getContentResolver();
- Settings.Global.putInt(resolver, Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 1);
- Settings.Global.putLong(resolver,
- Settings.Global.MIN_DURATION_BETWEEN_RECOVERY_STEPS_IN_MS, 100);
- Settings.System.putInt(resolver, "radio.data.stall.recovery.action", 1);
- doReturn(new SignalStrength()).when(mPhone).getSignalStrength();
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_DEFAULT_STRING, ApnSetting.TYPE_MMS_STRING});
- mDct.enableApn(ApnSetting.TYPE_IMS, DcTracker.REQUEST_TYPE_NORMAL, null);
- mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
-
- sendInitializationEvents();
-
- ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
- verify(mSimulatedCommandsVerifier, timeout(TEST_TIMEOUT).times(2)).setupDataCall(
- eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
-
- logd("Sending EVENT_NETWORK_STATUS_CHANGED false");
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_NETWORK_STATUS_CHANGED,
- NetworkAgent.INVALID_NETWORK, 1, null));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- waitForMs(200);
-
- // expected tear down all DataConnections
- verify(mSimulatedCommandsVerifier, times(1)).deactivateDataCall(
- eq(DataService.REQUEST_REASON_NORMAL), anyInt(),
- any(Message.class));
- }
-
-
- @Test
- @SmallTest
- public void testRecoveryStepReRegister() {
- ContentResolver resolver = mContext.getContentResolver();
- Settings.Global.putInt(resolver, Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 1);
- Settings.Global.putLong(resolver,
- Settings.Global.MIN_DURATION_BETWEEN_RECOVERY_STEPS_IN_MS, 100);
- Settings.System.putInt(resolver, "radio.data.stall.recovery.action", 2);
- doReturn(new SignalStrength()).when(mPhone).getSignalStrength();
- doReturn(PhoneConstants.State.IDLE).when(mPhone).getState();
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_DEFAULT_STRING, ApnSetting.TYPE_MMS_STRING});
- mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
-
- sendInitializationEvents();
-
- ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
- verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
- eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
-
- logd("Sending EVENT_NETWORK_STATUS_CHANGED false");
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_NETWORK_STATUS_CHANGED,
- NetworkAgent.INVALID_NETWORK, 1, null));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- // expected to get preferred network type
- verify(mSST, times(1)).reRegisterNetwork(eq(null));
- }
-
- @Test
- @SmallTest
- public void testRecoveryStepRestartRadio() {
- ContentResolver resolver = mContext.getContentResolver();
- Settings.Global.putInt(resolver, Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 1);
- Settings.Global.putLong(resolver,
- Settings.Global.MIN_DURATION_BETWEEN_RECOVERY_STEPS_IN_MS, 100);
- Settings.System.putInt(resolver, "radio.data.stall.recovery.action", 3);
- doReturn(new SignalStrength()).when(mPhone).getSignalStrength();
- doReturn(PhoneConstants.State.IDLE).when(mPhone).getState();
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
- new String[]{ApnSetting.TYPE_DEFAULT_STRING, ApnSetting.TYPE_MMS_STRING});
- mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
-
- sendInitializationEvents();
-
- ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
- verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
- eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
-
- logd("Sending EVENT_NETWORK_STATUS_CHANGED false");
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_NETWORK_STATUS_CHANGED,
- NetworkAgent.INVALID_NETWORK, 1, null));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- // expected to get preferred network type
- verify(mSST, times(1)).powerOffRadioSafely();
- }
-
- private void verifyDataEnabledChangedMessage(boolean enabled, int reason) {
- verify(mHandler, times(1)).sendMessageDelayed(any(), anyLong());
- Pair<Boolean, Integer> result = (Pair) ((AsyncResult) mMessage.obj).result;
- assertEquals(DATA_ENABLED_CHANGED, mMessage.what);
- assertEquals(enabled, result.first);
- assertEquals(reason, (int) result.second);
- clearInvocations(mHandler);
- }
-
- private void setUpSubscriptionPlans(boolean isNrUnmetered) throws Exception {
- List<SubscriptionPlan> plans = new ArrayList<>();
- if (isNrUnmetered) {
- plans.add(SubscriptionPlan.Builder
- .createRecurring(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"),
- Period.ofMonths(1))
- .setDataLimit(SubscriptionPlan.BYTES_UNLIMITED,
- SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
- .setNetworkTypes(new int[] {TelephonyManager.NETWORK_TYPE_NR})
- .build());
- }
- plans.add(SubscriptionPlan.Builder
- .createRecurring(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"),
- Period.ofMonths(1))
- .setDataLimit(1_000_000_000, SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
- .setDataUsage(500_000_000, System.currentTimeMillis())
- .build());
- replaceInstance(DcTracker.class, "mSubscriptionPlans", mDct, plans);
- doReturn(plans.toArray(new SubscriptionPlan[0])).when(mNetworkPolicyManager)
- .getSubscriptionPlans(anyInt(), any());
- }
-
- private void resetSubscriptionPlans() throws Exception {
- replaceInstance(DcTracker.class, "mSubscriptionPlans", mDct, null);
- }
-
- private void setUpSubscriptionOverride(int[] networkTypes, boolean isUnmetered)
- throws Exception {
- List<Integer> networkTypesList = null;
- if (networkTypes != null) {
- networkTypesList = new ArrayList<>();
- for (int networkType : networkTypes) {
- networkTypesList.add(networkType);
- }
- }
- replaceInstance(DcTracker.class, "mUnmeteredNetworkTypes", mDct, networkTypesList);
- replaceInstance(DcTracker.class, "mUnmeteredOverride", mDct, isUnmetered);
- }
-
- private void resetSubscriptionOverride() throws Exception {
- replaceInstance(DcTracker.class, "mUnmeteredNetworkTypes", mDct, null);
- replaceInstance(DcTracker.class, "mUnmeteredOverride", mDct, false);
- }
-
- private boolean isNetworkTypeUnmetered(int networkType) throws Exception {
- Method method = DcTracker.class.getDeclaredMethod(
- "isNetworkTypeUnmetered", int.class);
- method.setAccessible(true);
- return (boolean) method.invoke(mDct, networkType);
- }
-
- private int setUpDataConnection() throws Exception {
- Field dc = DcTracker.class.getDeclaredField("mDataConnections");
- dc.setAccessible(true);
- Field uig = DcTracker.class.getDeclaredField("mUniqueIdGenerator");
- uig.setAccessible(true);
- int id = ((AtomicInteger) uig.get(mDct)).getAndIncrement();
- ((HashMap<Integer, DataConnection>) dc.get(mDct)).put(id, mDataConnection);
- return id;
- }
-
- private void resetDataConnection(int id) throws Exception {
- Field dc = DcTracker.class.getDeclaredField("mDataConnections");
- dc.setAccessible(true);
- ((HashMap<Integer, DataConnection>) dc.get(mDct)).remove(id);
- }
-
- private void setUpWatchdogTimer() {
- // Watchdog active for 10s
- mBundle.putLong(CarrierConfigManager.KEY_5G_WATCHDOG_TIME_MS_LONG, 10000);
- Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
- intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, mPhone.getPhoneId());
- intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, mPhone.getSubId());
- mContext.sendBroadcast(intent);
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- }
-
- private boolean getWatchdogStatus() throws Exception {
- Field field = DcTracker.class.getDeclaredField(("mWatchdog"));
- field.setAccessible(true);
- return (boolean) field.get(mDct);
- }
-
- private Map<Integer, List<Message>> getHandoverCompletionMessages() throws Exception {
- Field field = DcTracker.class.getDeclaredField(("mHandoverCompletionMsgs"));
- field.setAccessible(true);
- return (Map<Integer, List<Message>>) field.get(mDct);
- }
-
- private void setUpTempNotMetered() {
- doReturn((int) TelephonyManager.NETWORK_TYPE_BITMASK_NR)
- .when(mPhone).getRadioAccessFamily();
- doReturn(1).when(mPhone).getSubId();
- mBundle.putBoolean(CarrierConfigManager.KEY_NETWORK_TEMP_NOT_METERED_SUPPORTED_BOOL, true);
- Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
- intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, mPhone.getPhoneId());
- intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, mPhone.getSubId());
- mContext.sendBroadcast(intent);
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- }
-
- @Test
- public void testIsNetworkTypeUnmetered() throws Exception {
- initApns(ApnSetting.TYPE_DEFAULT_STRING, new String[]{ApnSetting.TYPE_ALL_STRING});
-
- // only 5G unmetered
- setUpSubscriptionOverride(new int[]{TelephonyManager.NETWORK_TYPE_NR}, true);
-
- assertTrue(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_NR));
- assertFalse(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_LTE));
- assertFalse(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_UNKNOWN));
-
- // all network types metered
- setUpSubscriptionOverride(TelephonyManager.getAllNetworkTypes(), false);
-
- assertFalse(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_NR));
- assertFalse(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_LTE));
- assertFalse(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_UNKNOWN));
-
- // all network types unmetered
- setUpSubscriptionOverride(TelephonyManager.getAllNetworkTypes(), true);
-
- assertTrue(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_NR));
- assertTrue(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_LTE));
- assertTrue(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_UNKNOWN));
-
- resetSubscriptionOverride();
- }
-
- @Test
- public void testIsNetworkTypeUnmeteredViaSubscriptionPlans() throws Exception {
- initApns(ApnSetting.TYPE_DEFAULT_STRING, new String[]{ApnSetting.TYPE_ALL_STRING});
-
- // only 5G unmetered
- setUpSubscriptionPlans(true);
-
- assertTrue(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_NR));
- assertFalse(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_LTE));
- assertFalse(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_UNKNOWN));
-
- // all network types metered
- setUpSubscriptionPlans(false);
-
- assertFalse(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_NR));
- assertFalse(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_LTE));
- assertFalse(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_UNKNOWN));
-
- // all network types unmetered
- List<SubscriptionPlan> plans = new ArrayList<>();
- plans.add(SubscriptionPlan.Builder
- .createRecurring(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"),
- Period.ofMonths(1))
- .setDataLimit(SubscriptionPlan.BYTES_UNLIMITED,
- SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
- .build());
- replaceInstance(DcTracker.class, "mSubscriptionPlans", mDct, plans);
-
- assertTrue(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_NR));
- assertTrue(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_LTE));
- assertTrue(isNetworkTypeUnmetered(TelephonyManager.NETWORK_TYPE_UNKNOWN));
-
- resetSubscriptionPlans();
- }
-
- @Test
- public void testIsNrUnmeteredSubscriptionPlans() throws Exception {
- initApns(ApnSetting.TYPE_DEFAULT_STRING, new String[]{ApnSetting.TYPE_ALL_STRING});
- int id = setUpDataConnection();
- setUpSubscriptionPlans(false);
- setUpWatchdogTimer();
- doReturn(new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_LTE,
- TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA))
- .when(mDisplayInfoController).getTelephonyDisplayInfo();
- setUpTempNotMetered();
- clearInvocations(mDataConnection);
-
- // NetCapability should be metered when connected to 5G with no unmetered plan or frequency
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_TELEPHONY_DISPLAY_INFO_CHANGED));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- verify(mDataConnection, times(1)).onMeterednessChanged(false);
-
- // Set SubscriptionPlans unmetered
- setUpSubscriptionPlans(true);
-
- // NetCapability should switch to unmetered with an unmetered plan
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_TELEPHONY_DISPLAY_INFO_CHANGED));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- verify(mDataConnection, times(1)).onMeterednessChanged(true);
-
- // Set MMWAVE frequency to unmetered
- mBundle.putBoolean(CarrierConfigManager.KEY_UNMETERED_NR_NSA_MMWAVE_BOOL, true);
- Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
- intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, mPhone.getPhoneId());
- intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, mPhone.getSubId());
- mContext.sendBroadcast(intent);
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- clearInvocations(mDataConnection);
-
- // NetCapability should switch to metered without fr=MMWAVE
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_TELEPHONY_DISPLAY_INFO_CHANGED));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- verify(mDataConnection, times(1)).onMeterednessChanged(false);
-
- // NetCapability should switch to unmetered with fr=MMWAVE
- doReturn(new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_LTE,
- TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED))
- .when(mDisplayInfoController).getTelephonyDisplayInfo();
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_TELEPHONY_DISPLAY_INFO_CHANGED));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- verify(mDataConnection, times(1)).onMeterednessChanged(true);
-
- resetDataConnection(id);
- resetSubscriptionPlans();
- }
-
- @Test
- public void testIsNrUnmeteredCarrierConfigs() throws Exception {
- initApns(ApnSetting.TYPE_DEFAULT_STRING, new String[]{ApnSetting.TYPE_ALL_STRING});
- int id = setUpDataConnection();
- setUpSubscriptionPlans(false);
- setUpWatchdogTimer();
- doReturn(new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_LTE,
- TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA))
- .when(mDisplayInfoController).getTelephonyDisplayInfo();
- setUpTempNotMetered();
- clearInvocations(mDataConnection);
-
- // NetCapability should be metered when connected to 5G with no unmetered plan or frequency
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_TELEPHONY_DISPLAY_INFO_CHANGED));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- verify(mDataConnection, times(1)).onMeterednessChanged(false);
-
- // Set MMWAVE frequency to unmetered
- mBundle.putBoolean(CarrierConfigManager.KEY_UNMETERED_NR_NSA_BOOL, true);
- mBundle.putBoolean(CarrierConfigManager.KEY_UNMETERED_NR_NSA_MMWAVE_BOOL, true);
- Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
- intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, mPhone.getPhoneId());
- intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, mPhone.getSubId());
- mContext.sendBroadcast(intent);
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- clearInvocations(mDataConnection);
-
- // NetCapability should switch to unmetered when fr=MMWAVE and MMWAVE unmetered
- doReturn(new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_LTE,
- TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED))
- .when(mDisplayInfoController).getTelephonyDisplayInfo();
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_TELEPHONY_DISPLAY_INFO_CHANGED));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- verify(mDataConnection, times(1)).onMeterednessChanged(true);
-
- // NetCapability should switch to metered when fr=SUB6 and MMWAVE unmetered
- doReturn(new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_LTE,
- TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA))
- .when(mDisplayInfoController).getTelephonyDisplayInfo();
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_TELEPHONY_DISPLAY_INFO_CHANGED));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- verify(mDataConnection, times(1)).onMeterednessChanged(false);
-
- // Set SUB6 frequency to unmetered
- doReturn(2).when(mPhone).getSubId();
- mBundle.putBoolean(CarrierConfigManager.KEY_UNMETERED_NR_NSA_MMWAVE_BOOL, false);
- mBundle.putBoolean(CarrierConfigManager.KEY_UNMETERED_NR_NSA_SUB6_BOOL, true);
- intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
- intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, mPhone.getPhoneId());
- intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, mPhone.getSubId());
- mContext.sendBroadcast(intent);
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- clearInvocations(mDataConnection);
-
- // NetCapability should switch to unmetered when fr=SUB6 and SUB6 unmetered
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_TELEPHONY_DISPLAY_INFO_CHANGED));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- // Data connection is running on a different thread. Have to wait.
- waitForMs(200);
- verify(mDataConnection, times(1)).onMeterednessChanged(true);
-
- resetDataConnection(id);
- resetSubscriptionPlans();
- }
-
- @Test
- public void testReevaluateUnmeteredConnectionsOnNetworkChange() throws Exception {
- initApns(ApnSetting.TYPE_DEFAULT_STRING, new String[]{ApnSetting.TYPE_ALL_STRING});
- int id = setUpDataConnection();
- setUpSubscriptionPlans(true);
- setUpWatchdogTimer();
- setUpTempNotMetered();
- clearInvocations(mDataConnection);
-
- // NetCapability should be unmetered when connected to 5G
- doReturn(new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_LTE,
- TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA))
- .when(mDisplayInfoController).getTelephonyDisplayInfo();
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_TELEPHONY_DISPLAY_INFO_CHANGED));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- verify(mDataConnection, times(1)).onMeterednessChanged(true);
-
- // NetCapability should be metered when disconnected from 5G
- doReturn(new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_LTE,
- TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE))
- .when(mDisplayInfoController).getTelephonyDisplayInfo();
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_TELEPHONY_DISPLAY_INFO_CHANGED));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- // Data connection is running on a different thread. Have to wait.
- waitForMs(200);
- verify(mDataConnection, times(1)).onMeterednessChanged(false);
-
- resetDataConnection(id);
- resetSubscriptionPlans();
- }
-
- @Test
- public void testReevaluateUnmeteredConnectionsOnWatchdog() throws Exception {
- initApns(ApnSetting.TYPE_DEFAULT_STRING, new String[]{ApnSetting.TYPE_ALL_STRING});
- int id = setUpDataConnection();
- setUpSubscriptionPlans(true);
- setUpWatchdogTimer();
-
- // Watchdog inactive when unmetered and not connected to 5G
- doReturn(new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_LTE,
- TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE))
- .when(mDisplayInfoController).getTelephonyDisplayInfo();
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_NR_TIMER_WATCHDOG));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- assertFalse(getWatchdogStatus());
-
- // Watchdog active when unmetered and connected to 5G
- doReturn(new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_LTE,
- TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA))
- .when(mDisplayInfoController).getTelephonyDisplayInfo();
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_TELEPHONY_DISPLAY_INFO_CHANGED));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- assertTrue(getWatchdogStatus());
-
- // Watchdog inactive when metered
- setUpSubscriptionPlans(false);
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_TELEPHONY_DISPLAY_INFO_CHANGED));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- assertFalse(getWatchdogStatus());
-
- resetDataConnection(id);
- resetSubscriptionPlans();
- }
-
- /**
- * Test if this is a path prefix match against the given Uri. Verifies that
- * scheme, authority, and atomic path segments match.
- *
- * Copied from frameworks/base/core/java/android/net/Uri.java
- */
- private boolean isPathPrefixMatch(Uri uriA, Uri uriB) {
- if (!Objects.equals(uriA.getScheme(), uriB.getScheme())) return false;
- if (!Objects.equals(uriA.getAuthority(), uriB.getAuthority())) return false;
-
- List<String> segA = uriA.getPathSegments();
- List<String> segB = uriB.getPathSegments();
-
- final int size = segB.size();
- if (segA.size() < size) return false;
-
- for (int i = 0; i < size; i++) {
- if (!Objects.equals(segA.get(i), segB.get(i))) {
- return false;
- }
- }
-
- return true;
- }
-
- @Test
- public void testNoApnContextsWhenDataIsDisabled() throws java.lang.InterruptedException {
- //Check that apn contexts are loaded.
- assertTrue(mDct.getApnContexts().size() > 0);
-
- //Do work normally done in teardown.
- mDct.removeCallbacksAndMessages(null);
- mDcTrackerTestHandler.quit();
- mDcTrackerTestHandler.join();
-
- //Set isDataCapable to false for the new DcTracker being created in DcTrackerTestHandler.
- doReturn(false).when(mTelephonyManager).isDataCapable();
- mDcTrackerTestHandler = new DcTrackerTestHandler(getClass().getSimpleName());
- setReady(false);
-
- mDcTrackerTestHandler.start();
- waitUntilReady();
- assertEquals(0, mDct.getApnContexts().size());
-
- //No need to clean up handler because that work is done in teardown.
- }
-
- @Test
- public void testRatChanged() throws Exception {
- DataConnectionReasons dataConnectionReasons = new DataConnectionReasons();
- boolean allowed = mDct.isDataAllowed(dataConnectionReasons);
- assertFalse(dataConnectionReasons.toString(), allowed);
-
- logd("Sending EVENT_ENABLE_APN");
- // APN id 0 is APN_TYPE_DEFAULT
- mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
-
- sendInitializationEvents();
-
- dataConnectionReasons = new DataConnectionReasons();
- allowed = mDct.isDataAllowed(dataConnectionReasons);
- assertTrue(dataConnectionReasons.toString(), allowed);
-
- ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
- // Verify if RIL command was sent properly.
- verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
- eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
- eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);
-
- verifyDataConnected(FAKE_APN1);
-
- doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS).when(mServiceState)
- .getRilDataRadioTechnology();
-
- logd("Sending EVENT_DATA_RAT_CHANGED");
- mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
- .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_UMTS)
- .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
- .build();
- doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
- anyInt(), anyInt());
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_RAT_CHANGED, null));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- // Data connection is running on a different thread. Have to wait.
- waitForMs(200);
- // expected tear down all metered DataConnections
- verify(mSimulatedCommandsVerifier).deactivateDataCall(
- eq(DataService.REQUEST_REASON_NORMAL), anyInt(),
- any(Message.class));
- }
-
- @Test
- public void testApnConfigRepositoryUpdatedOnCarrierConfigChange() {
- assertPriority(ApnSetting.TYPE_CBS_STRING, 2);
- assertPriority(ApnSetting.TYPE_MMS_STRING, 2);
-
- mBundle.putStringArray(CarrierConfigManager.KEY_APN_PRIORITY_STRING_ARRAY,
- new String[] {
- ApnSetting.TYPE_CBS_STRING + ":11",
- ApnSetting.TYPE_MMS_STRING + ":19",
- });
-
- sendInitializationEvents();
-
- Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
- intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, mPhone.getPhoneId());
- intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, mPhone.getSubId());
- mContext.sendBroadcast(intent);
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- assertPriority(ApnSetting.TYPE_CBS_STRING, 11);
- assertPriority(ApnSetting.TYPE_MMS_STRING, 19);
-
- //Ensure apns are in sorted order.
- ApnContext lastApnContext = null;
- for (ApnContext apnContext : mDct.getApnContexts()) {
- if (lastApnContext != null) {
- assertTrue(apnContext.getPriority() <= lastApnContext.getPriority());
- }
- lastApnContext = apnContext;
- }
- }
-
- private void assertPriority(String type, int priority) {
- assertEquals(priority, mDct.getApnContexts().stream()
- .filter(x -> x.getApnType().equals(type))
- .findFirst().get().getPriority());
- }
-
- @Test
- public void testProvisionBroadcastReceiver() {
- Intent intent = new Intent("com.android.internal.telephony.PROVISION");
- intent.putExtra("provision.phone.id", mPhone.getPhoneId());
- try {
- mContext.sendBroadcast(intent);
- } catch (SecurityException e) {
- fail();
- }
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- }
-
- @Test
- public void testRetryHandoverWhenDisconnecting() throws Exception {
- initApns(ApnSetting.TYPE_IMS_STRING, new String[]{ApnSetting.TYPE_IMS_STRING});
- setUpDataConnection();
- SparseArray<ApnContext> apnContextsByType = Mockito.mock(SparseArray.class);
- ConcurrentHashMap<String, ApnContext> apnContexts = Mockito.mock(ConcurrentHashMap.class);
- doReturn(mApnContext).when(apnContextsByType).get(eq(ApnSetting.TYPE_IMS));
- doReturn(mApnContext).when(apnContexts).get(eq(ApnSetting.TYPE_IMS_STRING));
- doReturn(false).when(mApnContext).isConnectable();
- doReturn(false).when(mDataEnabledSettings).isDataEnabled(anyInt());
- doReturn(DctConstants.State.DISCONNECTING).when(mApnContext).getState();
- replaceInstance(DcTracker.class, "mApnContextsByType", mDct, apnContextsByType);
- replaceInstance(DcTracker.class, "mApnContexts", mDct, apnContexts);
-
- sendInitializationEvents();
-
- logd("Sending EVENT_ENABLE_APN");
- // APN id 0 is APN_TYPE_DEFAULT
- mDct.enableApn(ApnSetting.TYPE_IMS, DcTracker.REQUEST_TYPE_HANDOVER,
- mDct.obtainMessage(12345));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- assertTrue(isHandoverPending(ApnSetting.TYPE_IMS));
-
- // Verify no handover request was sent
- verify(mDataConnection, never()).bringUp(any(ApnContext.class), anyInt(), anyInt(),
- any(Message.class), anyInt(), anyInt(), anyInt(), anyBoolean());
-
- doReturn(DctConstants.State.RETRYING).when(mApnContext).getState();
- // Data now is disconnected
- doReturn(true).when(mApnContext).isConnectable();
- doReturn(true).when(mDataEnabledSettings).isDataEnabled(anyInt());
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DISCONNECT_DONE,
- new AsyncResult(Pair.create(mApnContext, 0), null, null)));
-
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- verify(mDataConnection).bringUp(any(ApnContext.class), anyInt(), anyInt(),
- any(Message.class), anyInt(), eq(DcTracker.REQUEST_TYPE_HANDOVER), anyInt(),
- anyBoolean());
- }
-
- @Test
- public void testDataUnthrottled() throws Exception {
- initApns(ApnSetting.TYPE_IMS_STRING, new String[]{ApnSetting.TYPE_IMS_STRING});
- replaceInstance(DcTracker.class, "mDataThrottler", mDct, mDataThrottler);
- mDct.enableApn(ApnSetting.TYPE_IMS, DcTracker.REQUEST_TYPE_NORMAL, null);
- sendInitializationEvents();
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_APN_UNTHROTTLED,
- new AsyncResult(null, FAKE_APN3, null)));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- verify(mDataThrottler).setRetryTime(
- eq(ApnSetting.TYPE_IMS),
- eq(RetryManager.NO_SUGGESTED_RETRY_DELAY),
- eq(DcTracker.REQUEST_TYPE_NORMAL));
- }
-
- @Test
- public void testDataUnthrottledAfterAPNChanged() throws Exception {
- initApns(ApnSetting.TYPE_IMS_STRING, new String[]{ApnSetting.TYPE_IMS_STRING});
- replaceInstance(DcTracker.class, "mDataThrottler", mDct, mDataThrottler);
-
- mDct.enableApn(ApnSetting.TYPE_IMS, DcTracker.REQUEST_TYPE_NORMAL, null);
- sendInitializationEvents();
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_APN_CHANGED, null));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-
- // Verify unthrottling
- verify(mDataThrottler, times(2)).reset();
- }
-
- @Test
- public void testDataUnthrottledOnSimStateChanged() throws Exception {
- initApns(ApnSetting.TYPE_IMS_STRING, new String[]{ApnSetting.TYPE_IMS_STRING});
- replaceInstance(DcTracker.class, "mDataThrottler", mDct, mDataThrottler);
-
- mDct.enableApn(ApnSetting.TYPE_IMS, DcTracker.REQUEST_TYPE_NORMAL, null);
- sendInitializationEvents();
- sendSimStateUpdated("testDataUnthrottledOnSimStateChanged");
-
- // Verify unthrottling
- verify(mDataThrottler, times(2)).reset();
- }
-
- @Test
- public void testHandlingSecondHandoverRequest() throws Exception {
- initApns(ApnSetting.TYPE_IMS_STRING, new String[]{ApnSetting.TYPE_IMS_STRING});
- setUpDataConnection();
- SparseArray<ApnContext> apnContextsByType = Mockito.mock(SparseArray.class);
- ConcurrentHashMap<String, ApnContext> apnContexts = Mockito.mock(ConcurrentHashMap.class);
- doReturn(mApnContext).when(apnContextsByType).get(eq(ApnSetting.TYPE_IMS));
- doReturn(mApnContext).when(apnContexts).get(eq(ApnSetting.TYPE_IMS_STRING));
- doReturn(false).when(mApnContext).isConnectable();
- doReturn(DctConstants.State.CONNECTING).when(mApnContext).getState();
- replaceInstance(DcTracker.class, "mApnContextsByType", mDct, apnContextsByType);
- replaceInstance(DcTracker.class, "mApnContexts", mDct, apnContexts);
-
- sendInitializationEvents();
-
- logd("Sending EVENT_ENABLE_APN");
- // APN id 0 is APN_TYPE_DEFAULT
- Message msg = mDct.obtainMessage(12345);
- mDct.enableApn(ApnSetting.TYPE_IMS, DcTracker.REQUEST_TYPE_HANDOVER, msg);
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- Map<Integer, List<Message>> msgs = getHandoverCompletionMessages();
- // Make sure the messages was queued properly instead of fired right away.
- assertTrue(msgs.get(ApnSetting.TYPE_IMS).contains(msg));
- }
-
- @Test
- public void testDataThrottledNotAllowData() throws Exception {
- initApns(ApnSetting.TYPE_IMS_STRING, new String[]{ApnSetting.TYPE_IMS_STRING});
- replaceInstance(DcTracker.class, "mDataThrottler", mDct, mDataThrottler);
- doReturn(SystemClock.elapsedRealtime() + 100000).when(mDataThrottler)
- .getRetryTime(ApnSetting.TYPE_IMS);
- mDct.enableApn(ApnSetting.TYPE_IMS, DcTracker.REQUEST_TYPE_NORMAL, null);
- sendInitializationEvents();
-
- DataConnectionReasons dataConnectionReasons = new DataConnectionReasons();
- boolean allowed = mDct.isDataAllowed(mApnContext, DcTracker.REQUEST_TYPE_NORMAL,
- dataConnectionReasons);
- assertFalse(dataConnectionReasons.toString(), allowed);
- assertTrue(dataConnectionReasons.contains(DataDisallowedReasonType.DATA_THROTTLED));
-
- // Makre sure no data setup request
- verify(mSimulatedCommandsVerifier, never()).setupDataCall(
- anyInt(), any(DataProfile.class), anyBoolean(), anyBoolean(), anyInt(), any(),
- anyInt(), any(), any(), anyBoolean(), any(Message.class));
- }
-
- @Test
- public void testNotifyDataDisconnected() {
- // Verify notify data disconnected on DCT constructor, initialized in setUp()
- ArgumentCaptor<PreciseDataConnectionState> captor =
- ArgumentCaptor.forClass(PreciseDataConnectionState.class);
- verify(mPhone, times(13)).notifyDataConnection(captor.capture());
- for (PreciseDataConnectionState state : captor.getAllValues()) {
- assertEquals(TelephonyManager.DATA_DISCONNECTED, state.getState());
- }
- }
-
- /**
- * There is a corresponding test {@link DataConnectionTest#testDataServiceTempUnavailable()} to
- * test DataConnection behavior.
- */
- @Test
- public void testDataServiceTempUnavailable() {
- Handler handler = Mockito.mock(Handler.class);
- Message handoverCompleteMessage = Message.obtain(handler);
- addHandoverCompleteMsg(handoverCompleteMessage, ApnSetting.TYPE_IMS);
- initApns(ApnSetting.TYPE_IMS_STRING, new String[]{ApnSetting.TYPE_IMS_STRING});
- mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_SETUP_COMPLETE,
- DcTracker.REQUEST_TYPE_HANDOVER, DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN,
- new AsyncResult(Pair.create(mApnContext, 0),
- DataFailCause.SERVICE_TEMPORARILY_UNAVAILABLE, new Exception())));
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- // Ensure handover is not completed yet
- verify(handler, never()).sendMessageDelayed(any(), anyLong());
- }
-
- @Test
- public void testNormalRequestDoesNotFailHandoverRequest() {
- Handler handler = Mockito.mock(Handler.class);
- Message handoverCompleteMessage = Message.obtain(handler);
- addHandoverCompleteMsg(handoverCompleteMessage, ApnSetting.TYPE_IMS);
- initApns(ApnSetting.TYPE_IMS_STRING, new String[]{ApnSetting.TYPE_IMS_STRING});
- mDct.enableApn(ApnSetting.TYPE_IMS, DcTracker.REQUEST_TYPE_NORMAL, null);
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- // Ensure handover is not completed yet
- verify(handler, never()).sendMessageDelayed(any(), anyLong());
- }
-
- @Test
- public void testPreferenceChangedFallback() {
- Handler handler = Mockito.mock(Handler.class);
- doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WLAN).when(mAccessNetworksManager)
- .getPreferredTransport(anyInt());
- Message handoverCompleteMessage = Message.obtain(handler);
- addHandoverCompleteMsg(handoverCompleteMessage, ApnSetting.TYPE_IMS);
- initApns(ApnSetting.TYPE_IMS_STRING, new String[]{ApnSetting.TYPE_IMS_STRING});
- mDct.enableApn(ApnSetting.TYPE_IMS, DcTracker.REQUEST_TYPE_HANDOVER,
- handoverCompleteMessage);
- waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
- Bundle bundle = handoverCompleteMessage.getData();
- assertTrue(bundle.getBoolean("extra_handover_failure_fallback"));
- }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/RetryManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/RetryManagerTest.java
deleted file mode 100644
index 4acfefb..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/RetryManagerTest.java
+++ /dev/null
@@ -1,996 +0,0 @@
-/**
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.doReturn;
-
-import android.os.PersistableBundle;
-import android.os.SystemClock;
-import android.telephony.CarrierConfigManager;
-import android.telephony.data.ApnSetting;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.internal.telephony.RetryManager;
-import com.android.internal.telephony.SubscriptionController;
-import com.android.internal.telephony.TelephonyTest;
-import com.android.internal.telephony.uicc.UiccController;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.ArrayList;
-
-/**
- * APN retry manager tests
- */
-public class RetryManagerTest extends TelephonyTest {
-
- // This is the real APN data for the Japanese carrier NTT Docomo.
- private final ApnSetting mApn1 = new ApnSetting.Builder()
- .setId(2163)
- .setOperatorNumeric("44010")
- .setEntryName("sp-mode")
- .setApnName("spmode.ne.jp")
- .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL)
- .setProtocol(ApnSetting.PROTOCOL_IP)
- .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
- .setCarrierEnabled(true)
- .build();
-
- private final ApnSetting mApn2 = new ApnSetting.Builder()
- .setId(2164)
- .setOperatorNumeric("44010")
- .setEntryName("mopera U")
- .setApnName("mopera.net")
- .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL)
- .setProtocol(ApnSetting.PROTOCOL_IP)
- .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
- .setCarrierEnabled(true)
- .build();
-
- private final ApnSetting mApn3 = new ApnSetting.Builder()
- .setId(2165)
- .setOperatorNumeric("44010")
- .setEntryName("b-mobile for Nexus")
- .setApnName("bmobile.ne.jp")
- .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL)
- .setProtocol(ApnSetting.PROTOCOL_IP)
- .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
- .setCarrierEnabled(true)
- .build();
-
- private PersistableBundle mBundle;
-
- @Before
- public void setUp() throws Exception {
- super.setUp(getClass().getSimpleName());
- mBundle = mContextFixture.getCarrierConfigBundle();
- doReturn(false).when(mPhone).isUsingNewDataStack();
- replaceInstance(SubscriptionController.class, "sInstance", null, mSubscriptionController);
- replaceInstance(UiccController.class, "mInstance", null, mUiccController);
- }
-
- @After
- public void tearDown() throws Exception {
- mBundle = null;
- super.tearDown();
- }
-
- /**
- * Test the behavior of a retry manager with no waiting APNs set.
- */
- @Test
- @SmallTest
- public void testRetryManagerEmpty() throws Exception {
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
- new String[]{"default:2000"});
-
- RetryManager rm = new RetryManager(mPhone, mDataThrottler, ApnSetting.TYPE_DEFAULT);
-
- long delay = rm.getDelayForNextApn(false);
- assertEquals(RetryManager.NO_RETRY, delay);
-
- ApnSetting nextApn = rm.getNextApnSetting();
- assertTrue(nextApn == null);
- delay = rm.getDelayForNextApn(false);
- assertEquals(RetryManager.NO_RETRY, delay);
- }
-
- /**
- * Test the basic retry scenario where only one APN and no retry configured.
- */
- @Test
- @SmallTest
- public void testRetryManagerOneApnNoRetry() throws Exception {
-
- mBundle.putStringArray(
- CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
- new String[]{"default:"});
-
- ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- waitingApns.add(ApnSetting.makeApnSetting(mApn1));
-
- RetryManager rm = new RetryManager(mPhone, mDataThrottler, ApnSetting.TYPE_DEFAULT);
- rm.setWaitingApns(waitingApns);
-
- ApnSetting nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- long delay = rm.getDelayForNextApn(false);
- assertEquals(RetryManager.NO_RETRY, delay);
- }
-
- /**
- * Test the basic retry scenario where only one APN with two retries configured.
- */
- @Test
- @SmallTest
- public void testRetryManagerOneApnTwoRetries() throws Exception {
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
- new String[]{"supl:2000,3000"});
-
- ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- waitingApns.add(ApnSetting.makeApnSetting(mApn1));
-
- RetryManager rm = new RetryManager(mPhone, mDataThrottler, ApnSetting.TYPE_SUPL);
- rm.setWaitingApns(waitingApns);
-
- ApnSetting nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- long delay = rm.getDelayForNextApn(false);
- assertEquals(2000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(3000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(RetryManager.NO_RETRY, delay);
-
- // No matter how many times we call getNextApnSetting, it should always return the next APN
- // with NO_RETRY because we've already reached the maximum retry count.
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(RetryManager.NO_RETRY, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(RetryManager.NO_RETRY, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(RetryManager.NO_RETRY, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(RetryManager.NO_RETRY, delay);
- }
-
- /**
- * Test the basic retry scenario where two waiting APNs with one retry configured.
- */
- @Test
- @SmallTest
- public void testRetryManagerTwoApnsOneRetry() throws Exception {
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
- new String[]{"others:2000"});
-
- ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- waitingApns.add(ApnSetting.makeApnSetting(mApn1));
- waitingApns.add(ApnSetting.makeApnSetting(mApn2));
-
- RetryManager rm = new RetryManager(mPhone, mDataThrottler, ApnSetting.TYPE_DEFAULT);
- rm.setWaitingApns(waitingApns);
-
- ApnSetting nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- long delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(2000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(RetryManager.NO_RETRY, delay);
- }
-
- /**
- * Test the basic retry scenario where two waiting APNs with two retries configured.
- */
- @Test
- @SmallTest
- public void testRetryManagerTwoApnsTwoRetries() throws Exception {
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
- new String[]{"dun:2000,5000"});
-
- ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- waitingApns.add(ApnSetting.makeApnSetting(mApn1));
- waitingApns.add(ApnSetting.makeApnSetting(mApn2));
-
- RetryManager rm = new RetryManager(mPhone, mDataThrottler, ApnSetting.TYPE_DUN);
- rm.setWaitingApns(waitingApns);
-
- ApnSetting nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- long delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(2000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(5000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(RetryManager.NO_RETRY, delay);
- }
-
- /**
- * Test the basic retry scenario where two mms APNs with two retries configured.
- */
- @Test
- @SmallTest
- public void testRetryManagerTwoMmsApnsTwoRetries() throws Exception {
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
- new String[]{"mms: 3000,6000"});
-
- ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- waitingApns.add(ApnSetting.makeApnSetting(mApn1));
- waitingApns.add(ApnSetting.makeApnSetting(mApn2));
-
- RetryManager rm = new RetryManager(mPhone, mDataThrottler, ApnSetting.TYPE_MMS);
- rm.setWaitingApns(waitingApns);
-
- ApnSetting nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- long delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(3000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(6000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(RetryManager.NO_RETRY, delay);
- }
-
- /**
- * Test the permanent fail scenario with one APN configured.
- */
- @Test
- @SmallTest
- public void testRetryManagerApnPermanentFailed() throws Exception {
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
- new String[]{"fota:1000,4000,7000"});
-
- ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- ApnSetting apn = ApnSetting.makeApnSetting(mApn1);
- waitingApns.add(apn);
-
- RetryManager rm = new RetryManager(mPhone, mDataThrottler, ApnSetting.TYPE_FOTA);
- rm.setWaitingApns(waitingApns);
-
- ApnSetting nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- long delay = rm.getDelayForNextApn(false);
- assertEquals(1000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(4000, delay);
-
- rm.markApnPermanentFailed(apn);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn == null);
- }
-
- /**
- * Test the permanent fail scenario with two APNs configured.
- */
- @Test
- @SmallTest
- public void testRetryManagerApnPermanentFailedWithTwoApns() throws Exception {
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
- new String[]{"mms : 1000,4000,7000"});
-
- ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- ApnSetting myApn1 = ApnSetting.makeApnSetting(mApn1);
- ApnSetting myApn2 = ApnSetting.makeApnSetting(mApn2);
- waitingApns.add(myApn1);
- waitingApns.add(myApn2);
-
- RetryManager rm = new RetryManager(mPhone, mDataThrottler, ApnSetting.TYPE_MMS);
- rm.setWaitingApns(waitingApns);
-
- ApnSetting nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- long delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(1000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- rm.markApnPermanentFailed(myApn1);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(4000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(7000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(RetryManager.NO_RETRY, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(RetryManager.NO_RETRY, delay);
- }
-
- /**
- * Test the permanent fail scenario with three APNs configured.
- */
- @Test
- @SmallTest
- public void testRetryManagerApnPermanentFailedWithThreeApns() throws Exception {
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
- new String[]{"default:2000:2000,3000:3000", "ims:1000,4000"});
-
- ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- ApnSetting myApn1 = ApnSetting.makeApnSetting(mApn1);
- ApnSetting myApn2 = ApnSetting.makeApnSetting(mApn2);
- ApnSetting myApn3 = ApnSetting.makeApnSetting(mApn3);
- waitingApns.add(myApn1);
- waitingApns.add(myApn2);
- waitingApns.add(myApn3);
-
- RetryManager rm = new RetryManager(mPhone, mDataThrottler, ApnSetting.TYPE_IMS);
- rm.setWaitingApns(waitingApns);
-
- ApnSetting nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- long delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- rm.markApnPermanentFailed(myApn2);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn3));
- delay = rm.getDelayForNextApn(false);
- assertEquals(1000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn3));
- delay = rm.getDelayForNextApn(false);
- assertEquals(4000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn3));
- delay = rm.getDelayForNextApn(false);
- assertEquals(RetryManager.NO_RETRY, delay);
- }
-
- /**
- * Test the permanent fail scenario with two APN all failed
- */
- @Test
- @SmallTest
- public void testRetryManagerApnPermanentFailedAll() throws Exception {
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
- new String[]{"default:1000,4000,7000,9000", "mms:1234,4123"});
-
- ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- ApnSetting myApn1 = ApnSetting.makeApnSetting(mApn1);
- ApnSetting myApn2 = ApnSetting.makeApnSetting(mApn2);
- waitingApns.add(myApn1);
- waitingApns.add(myApn2);
-
- RetryManager rm = new RetryManager(mPhone, mDataThrottler, ApnSetting.TYPE_DEFAULT);
- rm.setWaitingApns(waitingApns);
-
- ApnSetting nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- long delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(1000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- rm.markApnPermanentFailed(myApn1);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(4000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(7000, delay);
-
- rm.markApnPermanentFailed(myApn2);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn == null);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn == null);
- }
-
- /**
- * Test the randomized delay scenario.
- */
- @Test
- @SmallTest
- public void testRetryManagerDelayWithRandomization() throws Exception {
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
- new String[]{"default:default_randomization=1000,3000:2000,6000:3000,10000"});
-
- ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- waitingApns.add(ApnSetting.makeApnSetting(mApn1));
-
- RetryManager rm = new RetryManager(mPhone, mDataThrottler, ApnSetting.TYPE_DEFAULT);
- rm.setWaitingApns(waitingApns);
-
- ApnSetting nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- long delay = rm.getDelayForNextApn(false);
- assertTrue(delay >= 3000 && delay < 5000); // 3s + 2s rand
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertTrue(delay >= 6000 && delay < 9000); // 6s + 3s rand
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertTrue(delay >= 10000 && delay < 11000); // 10s + 1s default rand
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(RetryManager.NO_RETRY, delay);
- }
-
- /**
- * Test the retry forever scenario
- */
- @Test
- @SmallTest
- public void testRetryManagerRetryForever() throws Exception {
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
- new String[]{"default:max_retries=infinite,1000,2000"});
-
- ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- waitingApns.add(ApnSetting.makeApnSetting(mApn1));
- waitingApns.add(ApnSetting.makeApnSetting(mApn2));
-
- RetryManager rm = new RetryManager(mPhone, mDataThrottler, ApnSetting.TYPE_DEFAULT);
- rm.setWaitingApns(waitingApns);
-
- ApnSetting nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- long delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(1000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(2000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(2000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(2000, delay);
- }
-
- /**
- * Test the explicit max retry scenario.
- */
- @Test
- @SmallTest
- public void testRetryManagerExplicitMaxRetry() throws Exception {
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
- new String[]{"hipri: max_retries=4,1000,2000"});
-
- ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- waitingApns.add(ApnSetting.makeApnSetting(mApn1));
- waitingApns.add(ApnSetting.makeApnSetting(mApn2));
-
- RetryManager rm = new RetryManager(mPhone, mDataThrottler, ApnSetting.TYPE_HIPRI);
- rm.setWaitingApns(waitingApns);
-
- ApnSetting nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- long delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(1000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(2000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(2000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(2000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(RetryManager.NO_RETRY, delay);
- }
-
- /**
- * Test the fail fast scenario.
- */
- @Test
- @SmallTest
- public void testRetryManagerFailFast() throws Exception {
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
- new String[]{"default:1000,5000"});
-
- mBundle.putLong(CarrierConfigManager.KEY_CARRIER_DATA_CALL_APN_DELAY_FASTER_LONG, 2000);
-
- ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- waitingApns.add(ApnSetting.makeApnSetting(mApn1));
- waitingApns.add(ApnSetting.makeApnSetting(mApn2));
-
- RetryManager rm = new RetryManager(mPhone, mDataThrottler, ApnSetting.TYPE_DEFAULT);
- rm.setWaitingApns(waitingApns);
-
- ApnSetting nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- long delay = rm.getDelayForNextApn(true);
- assertEquals(2000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(true);
- assertEquals(1000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(true);
- assertEquals(2000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(true);
- assertEquals(2000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(true);
- assertEquals(RetryManager.NO_RETRY, delay);
- }
-
- /**
- * Test the permanent fail scenario with two APN all failed and then reset
- */
- @Test
- @SmallTest
- public void testRetryManagerApnPermanentFailedAllAndThenReset() throws Exception {
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
- new String[]{"dun:1000,4000,7000,9000"});
-
- ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- ApnSetting myApn1 = ApnSetting.makeApnSetting(mApn1);
- ApnSetting myApn2 = ApnSetting.makeApnSetting(mApn2);
- waitingApns.add(myApn1);
- waitingApns.add(myApn2);
-
- RetryManager rm = new RetryManager(mPhone, mDataThrottler, ApnSetting.TYPE_DUN);
- rm.setWaitingApns(waitingApns);
-
- ApnSetting nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- long delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(1000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- rm.markApnPermanentFailed(myApn1);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(4000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(7000, delay);
-
- rm.markApnPermanentFailed(myApn2);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn == null);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn == null);
-
- // reset the retry manager
-
- ApnSetting myApn3 = ApnSetting.makeApnSetting(mApn3);
- waitingApns.clear();
- waitingApns.add(myApn3);
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
- new String[]{"dun:3000,8000"});
-
- rm.setWaitingApns(waitingApns);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn3));
- delay = rm.getDelayForNextApn(false);
- assertEquals(3000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn3));
- delay = rm.getDelayForNextApn(false);
- assertEquals(8000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn3));
- delay = rm.getDelayForNextApn(false);
- assertEquals(RetryManager.NO_RETRY, delay);
- }
-
- private void assertRange(long low, long high, long value) {
- if (value >= low && value <= high) return;
- fail("Not in range[" + low + "," + high + "], value=" + value);
- }
-
- /**
- * Test the scenario where modem suggests retry the current APN once
- */
- @Test
- @SmallTest
- public void testRetryManagerModemSuggestedRetryOnce() throws Exception {
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
- new String[]{"others:1000,4000,7000,9000"});
-
- ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- ApnSetting myApn1 = ApnSetting.makeApnSetting(mApn1);
- ApnSetting myApn2 = ApnSetting.makeApnSetting(mApn2);
- waitingApns.add(myApn1);
- waitingApns.add(myApn2);
-
- RetryManager rm = new RetryManager(mPhone, mDataThrottler, ApnSetting.TYPE_MMS);
- rm.setWaitingApns(waitingApns);
-
- ApnSetting nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- long delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(1000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- // Network suggests retrying the current APN
- doReturn(2500 + SystemClock.elapsedRealtime()).when(mDataThrottler)
- .getRetryTime(ApnSetting.TYPE_MMS);
- delay = rm.getDelayForNextApn(false);
- assertRange(2450, 2500, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- doReturn(RetryManager.NO_SUGGESTED_RETRY_DELAY).when(mDataThrottler)
- .getRetryTime(ApnSetting.TYPE_MMS);
- delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- // Modem suggests retrying the current APN
- //rm.setModemSuggestedDelay(30000);
- doReturn(30000 + SystemClock.elapsedRealtime()).when(mDataThrottler)
- .getRetryTime(ApnSetting.TYPE_MMS);
- delay = rm.getDelayForNextApn(false);
- assertRange(29950, 30000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- doReturn(RetryManager.NO_SUGGESTED_RETRY_DELAY).when(mDataThrottler)
- .getRetryTime(ApnSetting.TYPE_MMS);
- delay = rm.getDelayForNextApn(false);
- assertEquals(4000, delay);
- }
-
- /**
- * Test the scenario where modem suggests not retrying
- */
- @Test
- @SmallTest
- public void testRetryManagerModemSuggestedNoRetry() throws Exception {
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
- new String[]{"default:1000,4000,7000,9000"});
-
- ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- ApnSetting myApn1 = ApnSetting.makeApnSetting(mApn1);
- ApnSetting myApn2 = ApnSetting.makeApnSetting(mApn2);
- waitingApns.add(myApn1);
- waitingApns.add(myApn2);
-
- RetryManager rm = new RetryManager(mPhone, mDataThrottler, ApnSetting.TYPE_DEFAULT);
- rm.setWaitingApns(waitingApns);
-
- ApnSetting nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- long delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(1000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- // Modem suggests retrying the current APN
- doReturn(2500 + SystemClock.elapsedRealtime()).when(mDataThrottler)
- .getRetryTime(ApnSetting.TYPE_DEFAULT);
- delay = rm.getDelayForNextApn(false);
- assertRange(2450, 2500, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- doReturn(RetryManager.NO_RETRY).when(mDataThrottler)
- .getRetryTime(ApnSetting.TYPE_DEFAULT);
- delay = rm.getDelayForNextApn(false);
- assertEquals(RetryManager.NO_RETRY, delay);
- }
-
- /**
- * Test the scenario that network suggests the same retry for too many times
- */
- @Test
- @SmallTest
- public void testRetryNetworkSuggestedRetryTooManyTimes() throws Exception {
-
- mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
- new String[]{"mms:2000,3000", "default:1000,4000,7000,9000"});
-
- int maxRetryCount = 10;
-
- mBundle.putInt(CarrierConfigManager
- .KEY_CARRIER_DATA_CALL_RETRY_NETWORK_REQUESTED_MAX_COUNT_INT,
- maxRetryCount);
-
- ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
- ApnSetting myApn1 = ApnSetting.makeApnSetting(mApn1);
- ApnSetting myApn2 = ApnSetting.makeApnSetting(mApn2);
- waitingApns.add(myApn1);
- waitingApns.add(myApn2);
-
- RetryManager rm = new RetryManager(mPhone, mDataThrottler, ApnSetting.TYPE_DEFAULT);
- rm.setWaitingApns(waitingApns);
-
- ApnSetting nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- long delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- delay = rm.getDelayForNextApn(false);
- assertEquals(1000, delay);
-
- for (int i = 0; i < maxRetryCount; i++) {
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- doReturn(2500 + SystemClock.elapsedRealtime()).when(mDataThrottler)
- .getRetryTime(ApnSetting.TYPE_DEFAULT);
- delay = rm.getDelayForNextApn(false);
- assertRange(2450, 2500, delay);
- }
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn1));
- doReturn(2500 + SystemClock.elapsedRealtime()).when(mDataThrottler)
- .getRetryTime(ApnSetting.TYPE_DEFAULT);
- delay = rm.getDelayForNextApn(false);
- assertEquals(20000, delay);
-
- nextApn = rm.getNextApnSetting();
- assertTrue(nextApn.equals(mApn2));
- doReturn(RetryManager.NO_SUGGESTED_RETRY_DELAY).when(mDataThrottler)
- .getRetryTime(ApnSetting.TYPE_DEFAULT);
- delay = rm.getDelayForNextApn(false);
- assertEquals(4000, delay);
- }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMPhoneTest.java.broken b/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMPhoneTest.java.broken
deleted file mode 100644
index 2e9b88c..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMPhoneTest.java.broken
+++ /dev/null
@@ -1,1935 +0,0 @@
-/*
- * Copyright (C) 2007 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 GSMTestHandler.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.gsm;
-
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.telephony.ServiceState;
-import android.test.AndroidTestCase;
-import android.test.PerformanceTestCase;
-
-import android.telephony.DisconnectCause;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CallStateException;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.MmiCode;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.gsm.CallFailCause;
-import com.android.internal.telephony.gsm.GSMPhone;
-import com.android.internal.telephony.gsm.GSMTestHandler;
-import com.android.internal.telephony.gsm.GsmMmiCode;
-import com.android.internal.telephony.gsm.SuppServiceNotification;
-import com.android.internal.telephony.test.SimulatedRadioControl;
-
-import java.util.List;
-
-
-public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase {
- private SimulatedRadioControl mRadioControl;
- private GSMPhone mGSMPhone;
- private GSMTestHandler mGSMTestHandler;
- private Handler mHandler;
-
- private static final int EVENT_PHONE_STATE_CHANGED = 1;
- private static final int EVENT_DISCONNECT = 2;
- private static final int EVENT_RINGING = 3;
- private static final int EVENT_CHANNEL_OPENED = 4;
- private static final int EVENT_POST_DIAL = 5;
- private static final int EVENT_DONE = 6;
- private static final int EVENT_SSN = 7;
- private static final int EVENT_MMI_INITIATE = 8;
- private static final int EVENT_MMI_COMPLETE = 9;
- private static final int EVENT_IN_SERVICE = 10;
- private static final int SUPP_SERVICE_FAILED = 11;
- private static final int SERVICE_STATE_CHANGED = 12;
- private static final int EVENT_OEM_RIL_MESSAGE = 13;
- public static final int ANY_MESSAGE = -1;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mGSMTestHandler = new GSMTestHandler(mContext);
-
- mGSMTestHandler.start();
- synchronized (mGSMTestHandler) {
- do {
- mGSMTestHandler.wait();
- } while (mGSMTestHandler.getGSMPhone() == null);
- }
-
- mGSMPhone = mGSMTestHandler.getGSMPhone();
- mRadioControl = mGSMTestHandler.getSimulatedCommands();
-
- mHandler = mGSMTestHandler.getHandler();
- mGSMPhone.registerForPreciseCallStateChanged(mHandler, EVENT_PHONE_STATE_CHANGED, null);
- mGSMPhone.registerForNewRingingConnection(mHandler, EVENT_RINGING, null);
- mGSMPhone.registerForDisconnect(mHandler, EVENT_DISCONNECT, null);
-
- mGSMPhone.setOnPostDialCharacter(mHandler, EVENT_POST_DIAL, null);
-
- mGSMPhone.registerForSuppServiceNotification(mHandler, EVENT_SSN, null);
- mGSMPhone.registerForMmiInitiate(mHandler, EVENT_MMI_INITIATE, null);
- mGSMPhone.registerForMmiComplete(mHandler, EVENT_MMI_COMPLETE, null);
- mGSMPhone.registerForSuppServiceFailed(mHandler, SUPP_SERVICE_FAILED, null);
-
- mGSMPhone.registerForServiceStateChanged(mHandler, SERVICE_STATE_CHANGED, null);
-
- // wait until we get phone in both voice and data service
- Message msg;
- ServiceState state;
-
- do {
- msg = mGSMTestHandler.waitForMessage(SERVICE_STATE_CHANGED);
- assertNotNull("Message Time Out", msg);
- state = (ServiceState) ((AsyncResult) msg.obj).result;
- } while (state.getState() != ServiceState.STATE_IN_SERVICE);
- }
-
- @Override
- protected void tearDown() throws Exception {
- mRadioControl.shutdown();
-
- mGSMPhone.unregisterForPreciseCallStateChanged(mHandler);
- mGSMPhone.unregisterForNewRingingConnection(mHandler);
- mGSMPhone.unregisterForDisconnect(mHandler);
- mGSMPhone.setOnPostDialCharacter(mHandler, 0, null);
- mGSMPhone.unregisterForSuppServiceNotification(mHandler);
- mGSMPhone.unregisterForMmiInitiate(mHandler);
- mGSMPhone.unregisterForMmiComplete(mHandler);
-
- mGSMPhone = null;
- mRadioControl = null;
- mHandler = null;
- mGSMTestHandler.cleanup();
-
- super.tearDown();
- }
-
- // These test can only be run once.
- public int startPerformance(Intermediates intermediates) {
- return 1;
- }
-
- public boolean isPerformanceOnly() {
- return false;
- }
-
-
- //This test is causing the emulator screen to turn off. I don't understand
- //why, but I'm removing it until we can figure it out.
- public void brokenTestGeneral() throws Exception {
- Connection cn;
- Message msg;
- AsyncResult ar;
-
- // IDLE state
-
- assertEquals(PhoneConstants.State.IDLE, mGSMPhone.getState());
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime());
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
- assertFalse(mGSMPhone.canConference());
-
- // One DIALING connection
-
- mRadioControl.setAutoProgressConnectingCall(false);
-
- mGSMPhone.dial("+13125551212");
-
- assertEquals(PhoneConstants.State.OFFHOOK, mGSMPhone.getState());
-
- msg = mGSMTestHandler.waitForMessage(EVENT_PHONE_STATE_CHANGED);
- assertNotNull("Message Time Out", msg);
-
- assertEquals(PhoneConstants.State.OFFHOOK, mGSMPhone.getState());
- assertEquals(Call.State.DIALING, mGSMPhone.getForegroundCall().getState());
- assertTrue(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
- /*do {
- mGSMTestHandler.waitForMessage(ANY_MESSAGE);
- } while (mGSMPhone.getForegroundCall().getConnections().size() == 0);*/
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.DIALING,
- mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
- cn = mGSMPhone.getForegroundCall().getConnections().get(0);
- assertTrue(!cn.isIncoming());
- assertEquals(Connection.PostDialState.NOT_STARTED, cn.getPostDialState());
-
- assertEquals(DisconnectCause.NOT_DISCONNECTED, cn.getDisconnectCause());
-
- assertFalse(mGSMPhone.canConference());
-
- // One ALERTING connection
-
- mRadioControl.progressConnectingCallState();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- }
- while (mGSMPhone.getForegroundCall().getState() != Call.State.ALERTING);
-
- assertEquals(PhoneConstants.State.OFFHOOK, mGSMPhone.getState());
- assertTrue(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ALERTING, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
- cn = mGSMPhone.getForegroundCall().getConnections().get(0);
- assertTrue(!cn.isIncoming());
- assertEquals(Connection.PostDialState.NOT_STARTED, cn.getPostDialState());
- assertFalse(mGSMPhone.canConference());
-
- // One ACTIVE connection
-
- mRadioControl.progressConnectingCallState();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
- assertEquals(PhoneConstants.State.OFFHOOK, mGSMPhone.getState());
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
- assertTrue(mGSMPhone.getForegroundCall().getEarliestConnectTime() > 0);
-
- cn = mGSMPhone.getForegroundCall().getConnections().get(0);
- assertTrue(!cn.isIncoming());
- assertEquals(Connection.PostDialState.COMPLETE, cn.getPostDialState());
- assertFalse(mGSMPhone.canConference());
-
- // One disconnected connection
- mGSMPhone.getForegroundCall().hangup();
-
- msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
- assertNotNull("Message Time Out", msg);
-
- assertEquals(PhoneConstants.State.IDLE, mGSMPhone.getState());
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
- assertTrue(mGSMPhone.getForegroundCall().getEarliestConnectTime() > 0);
-
- assertFalse(mGSMPhone.canConference());
-
- cn = mGSMPhone.getForegroundCall().getEarliestConnection();
-
- assertEquals(Call.State.DISCONNECTED, cn.getState());
-
- // Back to idle state
-
- mGSMPhone.clearDisconnected();
-
- assertEquals(PhoneConstants.State.IDLE, mGSMPhone.getState());
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime());
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
- assertFalse(mGSMPhone.canConference());
-
- // cn left over from before phone.clearDisconnected();
-
- assertEquals(Call.State.DISCONNECTED, cn.getState());
-
- // One ringing (INCOMING) call
-
- mRadioControl.triggerRing("18005551212");
-
- msg = mGSMTestHandler.waitForMessage(EVENT_RINGING);
- assertNotNull("Message Time Out", msg);
-
- assertEquals(PhoneConstants.State.RINGING, mGSMPhone.getState());
- assertTrue(mGSMPhone.getRingingCall().isRinging());
-
- ar = (AsyncResult) msg.obj;
- cn = (Connection) ar.result;
- assertTrue(cn.isRinging());
- assertEquals(mGSMPhone.getRingingCall(), cn.getCall());
-
- assertEquals(1, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.INCOMING, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getRingingCall().getEarliestCreateTime() > 0);
- assertEquals(0, mGSMPhone.getRingingCall().getEarliestConnectTime());
-
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime());
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
- cn = mGSMPhone.getRingingCall().getConnections().get(0);
- assertTrue(cn.isIncoming());
- assertEquals(Connection.PostDialState.NOT_STARTED, cn.getPostDialState());
-
- assertFalse(mGSMPhone.canConference());
-
- // One mobile terminated active call
- mGSMPhone.acceptCall();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getRingingCall().getConnections().size() == 1);
-
- assertEquals(PhoneConstants.State.OFFHOOK, mGSMPhone.getState());
- assertFalse(mGSMPhone.getRingingCall().isRinging());
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE,
- mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
- assertTrue(mGSMPhone.getForegroundCall().getEarliestConnectTime() > 0);
-
- cn = mGSMPhone.getForegroundCall().getConnections().get(0);
- assertTrue(cn.isIncoming());
- assertEquals(Connection.PostDialState.NOT_STARTED, cn.getPostDialState());
-
- assertFalse(mGSMPhone.canConference());
-
- // One disconnected (local hangup) call
-
- try {
- Connection conn;
- conn = mGSMPhone.getForegroundCall().getConnections().get(0);
- conn.hangup();
- } catch (CallStateException ex) {
- ex.printStackTrace();
- fail("unexpected ex");
- }
-
- msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
- assertNotNull("Message Time Out", msg);
-
- assertEquals(PhoneConstants.State.IDLE, mGSMPhone.getState());
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
- assertFalse(mGSMPhone.getRingingCall().isRinging());
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.DISCONNECTED,
- mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
- assertTrue(mGSMPhone.getForegroundCall().getEarliestConnectTime() > 0);
-
- cn = mGSMPhone.getForegroundCall().getEarliestConnection();
-
- assertEquals(Call.State.DISCONNECTED, cn.getState());
-
- assertEquals(DisconnectCause.LOCAL, cn.getDisconnectCause());
-
- assertFalse(mGSMPhone.canConference());
-
- // Back to idle state
-
- mGSMPhone.clearDisconnected();
-
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
- assertFalse(mGSMPhone.getRingingCall().isRinging());
-
- assertEquals(DisconnectCause.LOCAL, cn.getDisconnectCause());
- assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(PhoneConstants.State.IDLE, mGSMPhone.getState());
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime());
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
- assertFalse(mGSMPhone.canConference());
-
- // cn left over from before phone.clearDisconnected();
-
- assertEquals(Call.State.DISCONNECTED, cn.getState());
-
- // One ringing call
-
- mRadioControl.triggerRing("18005551212");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getRingingCall().getConnections().isEmpty());
-
- assertEquals(PhoneConstants.State.RINGING, mGSMPhone.getState());
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
- assertTrue(mGSMPhone.getRingingCall().isRinging());
-
- assertEquals(1, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.INCOMING, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getRingingCall().getEarliestCreateTime() > 0);
- assertEquals(0, mGSMPhone.getRingingCall().getEarliestConnectTime());
-
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime());
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
- assertFalse(mGSMPhone.canConference());
-
- // One rejected call
- mGSMPhone.rejectCall();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != PhoneConstants.State.IDLE);
-
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
- assertFalse(mGSMPhone.getRingingCall().isRinging());
-
- assertEquals(1, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getRingingCall().getEarliestCreateTime() > 0);
- assertEquals(0, mGSMPhone.getRingingCall().getEarliestConnectTime());
-
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime());
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
- cn = mGSMPhone.getRingingCall().getEarliestConnection();
- assertEquals(Call.State.DISCONNECTED, cn.getState());
-
- assertEquals(DisconnectCause.INCOMING_MISSED, cn.getDisconnectCause());
-
- assertFalse(mGSMPhone.canConference());
-
- // Back to idle state
-
- mGSMPhone.clearDisconnected();
-
- assertEquals(DisconnectCause.INCOMING_MISSED, cn.getDisconnectCause());
- assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(PhoneConstants.State.IDLE, mGSMPhone.getState());
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(0, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestCreateTime());
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
- assertFalse(mGSMPhone.canConference());
- assertEquals(Call.State.DISCONNECTED, cn.getState());
-
- // One ringing call
-
- mRadioControl.triggerRing("18005551212");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getRingingCall().getConnections().isEmpty());
-
- assertEquals(PhoneConstants.State.RINGING, mGSMPhone.getState());
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
- assertTrue(mGSMPhone.getRingingCall().isRinging());
-
- cn = mGSMPhone.getRingingCall().getEarliestConnection();
-
- // Ringing call disconnects
-
- mRadioControl.triggerHangupForeground();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != PhoneConstants.State.IDLE);
-
- assertEquals(DisconnectCause.INCOMING_MISSED, cn.getDisconnectCause());
-
- // One Ringing Call
-
- mRadioControl.triggerRing("18005551212");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != PhoneConstants.State.RINGING);
-
-
- cn = mGSMPhone.getRingingCall().getEarliestConnection();
-
- // One answered call
- mGSMPhone.acceptCall();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != PhoneConstants.State.OFFHOOK);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- // one holding call
- mGSMPhone.switchHoldingAndActive();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getBackgroundCall().getState() == Call.State.IDLE);
-
-
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
- // one active call
- mGSMPhone.switchHoldingAndActive();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- }
- while (mGSMPhone.getBackgroundCall().getState() == Call.State.HOLDING);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- // One disconnected call in the foreground slot
-
- mRadioControl.triggerHangupAll();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != PhoneConstants.State.IDLE);
-
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
- assertEquals(DisconnectCause.NORMAL, cn.getDisconnectCause());
-
- // Test missed calls
-
- mRadioControl.triggerRing("18005551212");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != PhoneConstants.State.RINGING);
-
- mGSMPhone.rejectCall();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (msg.what != EVENT_DISCONNECT);
-
- ar = (AsyncResult) msg.obj;
- cn = (Connection) ar.result;
-
- assertEquals(DisconnectCause.INCOMING_MISSED, cn.getDisconnectCause());
- assertEquals(PhoneConstants.State.IDLE, mGSMPhone.getState());
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getRingingCall().getState());
-
- // Test incoming not missed calls
-
- mRadioControl.triggerRing("18005551212");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != PhoneConstants.State.RINGING);
-
- cn = mGSMPhone.getRingingCall().getEarliestConnection();
-
- mGSMPhone.acceptCall();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != PhoneConstants.State.OFFHOOK);
-
- assertEquals(DisconnectCause.NOT_DISCONNECTED, cn.getDisconnectCause());
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
-
- try {
- mGSMPhone.getForegroundCall().hangup();
- } catch (CallStateException ex) {
- ex.printStackTrace();
- fail("unexpected ex");
- }
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState()
- != Call.State.DISCONNECTED);
-
- assertEquals(DisconnectCause.LOCAL, cn.getDisconnectCause());
-
- //
- // Test held and hangup held calls
- //
-
- // One ALERTING call
- mGSMPhone.dial("+13125551212");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != PhoneConstants.State.OFFHOOK);
-
- assertTrue(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
- mRadioControl.progressConnectingCallState();
- mRadioControl.progressConnectingCallState();
-
- // One ACTIVE call
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
- // One ACTIVE call, one ringing call
-
- mRadioControl.triggerRing("18005551212");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != PhoneConstants.State.RINGING);
-
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
- assertTrue(mGSMPhone.getRingingCall().isRinging());
-
- // One HOLDING call, one ACTIVE call
- mGSMPhone.acceptCall();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != PhoneConstants.State.OFFHOOK);
-
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
- assertTrue(mGSMPhone.canConference());
-
- // Conference the two
- mGSMPhone.conference();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE);
-
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertTrue(mGSMPhone.getForegroundCall().isMultiparty());
- assertFalse(mGSMPhone.canConference());
-
- // Hold the multiparty call
- mGSMPhone.switchHoldingAndActive();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- }
- while (mGSMPhone.getBackgroundCall().getState() != Call.State.HOLDING);
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertTrue(mGSMPhone.getBackgroundCall().isMultiparty());
- assertFalse(mGSMPhone.canConference());
-
- // Multiparty call on hold, call waiting added
-
- mRadioControl.triggerRing("18005558355");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != PhoneConstants.State.RINGING);
-
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
- assertTrue(mGSMPhone.getRingingCall().isRinging());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
- assertTrue(mGSMPhone.getBackgroundCall().isMultiparty());
- assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState());
- assertFalse(mGSMPhone.canConference());
-
- // Hangup conference call, ringing call still around
- mGSMPhone.getBackgroundCall().hangup();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getBackgroundCall().getState() != Call.State.DISCONNECTED);
-
- assertEquals(PhoneConstants.State.RINGING, mGSMPhone.getState());
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getBackgroundCall().getState());
-
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
- assertTrue(mGSMPhone.getRingingCall().isRinging());
-
- // Reject waiting call
- mGSMPhone.rejectCall();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != PhoneConstants.State.IDLE);
-
- assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
- assertFalse(mGSMPhone.getRingingCall().isRinging());
- }
-
- public void testOutgoingCallFailImmediately() throws Exception {
- Message msg;
-
- // Test outgoing call fail-immediately edge case
- // This happens when a call terminated before ever appearing in a
- // call list
- // This should land the immediately-failing call in the
- // ForegroundCall list as an IDLE call
- mRadioControl.setNextDialFailImmediately(true);
-
- Connection cn = mGSMPhone.dial("+13125551212");
-
- msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
- assertNotNull("Message Time Out", msg);
- assertEquals(PhoneConstants.State.IDLE, mGSMPhone.getState());
-
- assertEquals(DisconnectCause.NORMAL, cn.getDisconnectCause());
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
- }
-
- public void testHangupOnOutgoing() throws Exception {
- Connection cn;
- Message msg;
-
- mRadioControl.setAutoProgressConnectingCall(false);
-
- // Test 1: local hangup in "DIALING" state
- mGSMPhone.dial("+13125551212");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- }
- while (mGSMPhone.getForegroundCall().getState() != Call.State.DIALING);
-
- cn = mGSMPhone.getForegroundCall().getEarliestConnection();
-
- mGSMPhone.getForegroundCall().hangup();
-
- msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
- assertNotNull("Message Time Out", msg);
- assertEquals(PhoneConstants.State.IDLE, mGSMPhone.getState());
-
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
- assertEquals(DisconnectCause.LOCAL, cn.getDisconnectCause());
-
- // Test 2: local hangup in "ALERTING" state
- mGSMPhone.dial("+13125551212");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != PhoneConstants.State.OFFHOOK);
-
- mRadioControl.progressConnectingCallState();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- }
- while (mGSMPhone.getForegroundCall().getState() != Call.State.ALERTING);
-
- cn = mGSMPhone.getForegroundCall().getEarliestConnection();
-
- mGSMPhone.getForegroundCall().hangup();
-
- msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
- assertNotNull("Message Time Out", msg);
-
- assertEquals(PhoneConstants.State.IDLE, mGSMPhone.getState());
-
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
- assertEquals(DisconnectCause.LOCAL, cn.getDisconnectCause());
-
- // Test 3: local immediate hangup before GSM index is
- // assigned (CallTracker.hangupPendingMO case)
-
- mRadioControl.pauseResponses();
-
- cn = mGSMPhone.dial("+13125551212");
-
- cn.hangup();
-
- mRadioControl.resumeResponses();
-
- msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
- assertNotNull("Message Time Out", msg);
- assertEquals(PhoneConstants.State.IDLE, mGSMPhone.getState());
-
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
-
- assertEquals(DisconnectCause.LOCAL,
- mGSMPhone.getForegroundCall().getEarliestConnection().getDisconnectCause());
- }
-
- public void testHangupOnChannelClose() throws Exception {
- mGSMPhone.dial("+13125551212");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getConnections().isEmpty());
-
- mRadioControl.shutdown();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- mGSMPhone.clearDisconnected();
- } while (!mGSMPhone.getForegroundCall().getConnections().isEmpty());
- }
-
- public void testIncallMmiCallDeflection() throws Exception {
- Message msg;
-
- // establish an active call
- mGSMPhone.dial("+13125551212");
-
- do {
- mRadioControl.progressConnectingCallState();
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- // establish a ringing (WAITING) call
-
- mRadioControl.triggerRing("18005551212");
-
- msg = mGSMTestHandler.waitForMessage(EVENT_RINGING);
- assertNotNull("Message Time Out", msg);
-
- assertEquals(PhoneConstants.State.RINGING, mGSMPhone.getState());
- assertTrue(mGSMPhone.getRingingCall().isRinging());
- assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- // Simulate entering 0 followed by SEND: release all held calls
- // or sets UDUB for a waiting call.
- mGSMPhone.handleInCallMmiCommands("0");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getRingingCall().getState() == Call.State.WAITING);
-
- assertEquals(PhoneConstants.State.OFFHOOK, mGSMPhone.getState());
- assertFalse(mGSMPhone.getRingingCall().isRinging());
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- // change the active call to holding call
- mGSMPhone.switchHoldingAndActive();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getBackgroundCall().getState() == Call.State.IDLE);
-
-
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
- // Simulate entering 0 followed by SEND: release all held calls
- // or sets UDUB for a waiting call.
- mGSMPhone.handleInCallMmiCommands("0");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getBackgroundCall().getState() == Call.State.HOLDING);
-
- assertEquals(PhoneConstants.State.IDLE, mGSMPhone.getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getBackgroundCall().getState());
- }
-
- public void testIncallMmiCallWaiting() throws Exception {
- Message msg;
-
- // establish an active call
- mGSMPhone.dial("+13125551212");
-
- do {
- mRadioControl.progressConnectingCallState();
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- // establish a ringing (WAITING) call
-
- mRadioControl.triggerRing("18005551212");
-
- do {
- msg = mGSMTestHandler.waitForMessage(ANY_MESSAGE);
- assertNotNull("Message Time Out", msg);
- } while (msg.what != EVENT_RINGING);
-
- assertEquals(PhoneConstants.State.RINGING, mGSMPhone.getState());
- assertTrue(mGSMPhone.getRingingCall().isRinging());
- assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- // Simulate entering 1 followed by SEND: release all active calls
- // (if any exist) and accepts the other (held or waiting) call.
-
- mGSMPhone.handleInCallMmiCommands("1");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getRingingCall().getState() == Call.State.WAITING);
-
- assertEquals(PhoneConstants.State.OFFHOOK, mGSMPhone.getState());
- assertFalse(mGSMPhone.getRingingCall().isRinging());
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals("18005551212",
- mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
-
- // change the active call to holding call
- mGSMPhone.switchHoldingAndActive();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getBackgroundCall().getState() == Call.State.IDLE);
-
- assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
- // Simulate entering 1 followed by SEND: release all active calls
- // (if any exist) and accepts the other (held or waiting) call.
- mGSMPhone.handleInCallMmiCommands("1");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE);
-
- assertEquals(PhoneConstants.State.OFFHOOK, mGSMPhone.getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
- assertEquals("18005551212",
- mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
-
- // at this point, the active call with number==18005551212 should
- // have the gsm index of 2
-
- mRadioControl.triggerRing("16505550100");
-
- msg = mGSMTestHandler.waitForMessage(EVENT_RINGING);
- assertNotNull("Message Time Out", msg);
-
- assertEquals(PhoneConstants.State.RINGING, mGSMPhone.getState());
- assertTrue(mGSMPhone.getRingingCall().isRinging());
- assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- // Simulate entering "12" followed by SEND: release the call with
- // gsm index equals to 2.
- mGSMPhone.handleInCallMmiCommands("12");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() == Call.State.ACTIVE);
-
- assertEquals(PhoneConstants.State.RINGING, mGSMPhone.getState());
- assertTrue(mGSMPhone.getRingingCall().isRinging());
- assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- mGSMPhone.acceptCall();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getState() != PhoneConstants.State.OFFHOOK);
-
- assertEquals(PhoneConstants.State.OFFHOOK, mGSMPhone.getState());
- assertFalse(mGSMPhone.getRingingCall().isRinging());
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- // at this point, the call with number==16505550100 should
- // have the gsm index of 1
- mGSMPhone.dial("+13125551212");
-
- do {
- mRadioControl.progressConnectingCallState();
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE ||
- mGSMPhone.getBackgroundCall().getState() != Call.State.HOLDING);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
- // at this point, the active call with number==13125551212 should
- // have the gsm index of 2
-
- // Simulate entering "11" followed by SEND: release the call with
- // gsm index equals to 1. This should not be allowed, and a
- // Supplementary Service notification must be received.
- mGSMPhone.handleInCallMmiCommands("11");
-
- msg = mGSMTestHandler.waitForMessage(SUPP_SERVICE_FAILED);
- assertNotNull("Message Time Out", msg);
- assertFalse("IncallMmiCallWaiting: command should not work on holding call", msg == null);
-
- // Simulate entering "12" followed by SEND: release the call with
- // gsm index equals to 2.
- mGSMPhone.handleInCallMmiCommands("12");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() == Call.State.ACTIVE);
-
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
- // Simulate entering 1 followed by SEND: release all active calls
- // (if any exist) and accepts the other (held or waiting) call.
- mGSMPhone.handleInCallMmiCommands("1");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE);
-
- assertEquals(PhoneConstants.State.OFFHOOK, mGSMPhone.getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
- assertEquals("16505550100",
- mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
-
- // Simulate entering "11" followed by SEND: release the call with
- // gsm index equals to 1.
- mGSMPhone.handleInCallMmiCommands("11");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() == Call.State.ACTIVE);
-
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
- }
-
- public void testIncallMmiCallHold() throws Exception {
- Message msg;
-
- // establish an active call
- mGSMPhone.dial("13125551212");
-
- do {
- mRadioControl.progressConnectingCallState();
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- // establish a ringing (WAITING) call
-
- mRadioControl.triggerRing("18005551212");
-
- msg = mGSMTestHandler.waitForMessage(EVENT_RINGING);
- assertNotNull("Message Time Out", msg);
-
- assertEquals(PhoneConstants.State.RINGING, mGSMPhone.getState());
- assertTrue(mGSMPhone.getRingingCall().isRinging());
- assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- // simulate entering 2 followed by SEND: place all active calls
- // (if any exist) on hold and accepts the other (held or waiting)
- // call
-
- mGSMPhone.handleInCallMmiCommands("2");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getRingingCall().getState() == Call.State.WAITING);
-
-
- assertFalse(mGSMPhone.getRingingCall().isRinging());
- assertEquals(PhoneConstants.State.OFFHOOK, mGSMPhone.getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE,
- mGSMPhone.getForegroundCall().getState());
- assertEquals("18005551212",
- mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
- assertEquals("13125551212",
- mGSMPhone.getBackgroundCall().getConnections().get(0).getAddress());
-
- // swap the active and holding calls
- mGSMPhone.handleInCallMmiCommands("2");
-
- msg = mGSMTestHandler.waitForMessage(EVENT_PHONE_STATE_CHANGED);
- assertNotNull("Message Time Out", msg);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals("13125551212",
- mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
- assertEquals("18005551212",
- mGSMPhone.getBackgroundCall().getConnections().get(0).getAddress());
-
- // merge the calls
- mGSMPhone.conference();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
- assertEquals(2, mGSMPhone.getForegroundCall().getConnections().size());
-
- // at this point, we have an active conference call, with
- // call(1) = 13125551212 and call(2) = 18005551212
-
- // Simulate entering "23" followed by SEND: places all active call
- // on hold except call 3. This should fail and a supplementary service
- // failed notification should be received.
-
- mGSMPhone.handleInCallMmiCommands("23");
-
- msg = mGSMTestHandler.waitForMessage(SUPP_SERVICE_FAILED);
- assertNotNull("Message Time Out", msg);
- assertFalse("IncallMmiCallHold: separate should have failed!", msg == null);
-
- // Simulate entering "21" followed by SEND: places all active call
- // on hold except call 1.
- mGSMPhone.handleInCallMmiCommands("21");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getBackgroundCall().getState() == Call.State.IDLE);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals("13125551212",
- mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
- assertEquals("18005551212",
- mGSMPhone.getBackgroundCall().getConnections().get(0).getAddress());
- }
-
- public void testIncallMmiMultipartyServices() throws Exception {
- // establish an active call
- mGSMPhone.dial("13125551212");
-
- do {
- mRadioControl.progressConnectingCallState();
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- // dial another call
- mGSMPhone.dial("18005551212");
-
- do {
- mRadioControl.progressConnectingCallState();
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
- mGSMPhone.handleInCallMmiCommands("3");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE);
-
- assertEquals(PhoneConstants.State.OFFHOOK, mGSMPhone.getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals("18005551212",
- mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
- assertEquals("13125551212",
- mGSMPhone.getForegroundCall().getConnections().get(1).getAddress());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
- }
-
- public void testCallIndex() throws Exception {
- Message msg;
-
- // establish the first call
- mGSMPhone.dial("16505550100");
-
- do {
- mRadioControl.progressConnectingCallState();
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- String baseNumber = "1650555010";
-
- for (int i = 1; i < 6; i++) {
- String number = baseNumber + i;
-
- mGSMPhone.dial(number);
-
- do {
- mRadioControl.progressConnectingCallState();
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
- if (mGSMPhone.getBackgroundCall().getConnections().size() >= 5) {
- break;
- }
-
- mGSMPhone.conference();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
- }
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals("16505550105",
- mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
- // create an incoming call, this call should have the call index
- // of 7
- mRadioControl.triggerRing("18005551212");
-
- msg = mGSMTestHandler.waitForMessage(EVENT_RINGING);
- assertNotNull("Message Time Out", msg);
-
- assertEquals(PhoneConstants.State.RINGING, mGSMPhone.getState());
- assertTrue(mGSMPhone.getRingingCall().isRinging());
- assertEquals(Call.State.WAITING, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
-
- // hangup the background call and accept the ringing call
- mGSMPhone.getBackgroundCall().hangup();
- mGSMPhone.acceptCall();
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getRingingCall().getState() != Call.State.IDLE);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals("18005551212",
- mGSMPhone.getForegroundCall().getConnections().get(0).getAddress());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
- assertEquals("16505550105",
- mGSMPhone.getBackgroundCall().getConnections().get(0).getAddress());
-
- mGSMPhone.handleInCallMmiCommands("17");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() == Call.State.ACTIVE);
-
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.HOLDING, mGSMPhone.getBackgroundCall().getState());
- assertEquals("16505550105",
- mGSMPhone.getBackgroundCall().getConnections().get(0).
- getAddress());
-
- mGSMPhone.handleInCallMmiCommands("1");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
-
- assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- mGSMPhone.handleInCallMmiCommands("16");
-
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (mGSMPhone.getForegroundCall().getState() == Call.State.ACTIVE);
-
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
- }
-
- public void testPostDialSequences() throws Exception {
- Message msg;
- AsyncResult ar;
- Connection cn;
-
- mGSMPhone.dial("+13125551212,1234;5N8xx");
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- ar = (AsyncResult) (msg.obj);
- cn = (Connection) (ar.result);
- assertEquals(',', msg.arg1);
- assertEquals("1234;5N8", cn.getRemainingPostDialString());
-
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- assertEquals('1', msg.arg1);
- ar = (AsyncResult) (msg.obj);
- assertEquals(Connection.PostDialState.STARTED, ar.userObj);
-
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- assertEquals('2', msg.arg1);
- ar = (AsyncResult) (msg.obj);
- assertEquals(Connection.PostDialState.STARTED, ar.userObj);
-
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- assertEquals('3', msg.arg1);
- ar = (AsyncResult) (msg.obj);
- assertEquals(Connection.PostDialState.STARTED, ar.userObj);
-
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- assertEquals('4', msg.arg1);
- ar = (AsyncResult) (msg.obj);
- assertEquals(Connection.PostDialState.STARTED, ar.userObj);
-
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- assertEquals(';', msg.arg1);
- ar = (AsyncResult) (msg.obj);
- cn = (Connection) (ar.result);
- assertEquals(Connection.PostDialState.WAIT, cn.getPostDialState());
- assertEquals(Connection.PostDialState.WAIT, ar.userObj);
- cn.proceedAfterWaitChar();
-
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- assertEquals('5', msg.arg1);
- ar = (AsyncResult) (msg.obj);
- assertEquals(Connection.PostDialState.STARTED, ar.userObj);
-
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertEquals('N', msg.arg1);
- ar = (AsyncResult) (msg.obj);
- cn = (Connection) (ar.result);
- assertEquals(Connection.PostDialState.WILD, cn.getPostDialState());
- assertEquals(Connection.PostDialState.WILD, ar.userObj);
- cn.proceedAfterWildChar(",6;7");
-
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- ar = (AsyncResult) (msg.obj);
- cn = (Connection) (ar.result);
- assertEquals(',', msg.arg1);
- assertEquals("6;78", cn.getRemainingPostDialString());
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- assertEquals('6', msg.arg1);
- ar = (AsyncResult) (msg.obj);
- assertEquals(Connection.PostDialState.STARTED, ar.userObj);
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- assertEquals(';', msg.arg1);
- ar = (AsyncResult) (msg.obj);
- cn = (Connection) (ar.result);
- assertEquals(Connection.PostDialState.WAIT, cn.getPostDialState());
- assertEquals(Connection.PostDialState.WAIT, ar.userObj);
- cn.proceedAfterWaitChar();
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- assertEquals('7', msg.arg1);
- ar = (AsyncResult) (msg.obj);
- assertEquals(Connection.PostDialState.STARTED, ar.userObj);
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- assertEquals('8', msg.arg1);
- ar = (AsyncResult) (msg.obj);
- assertEquals(Connection.PostDialState.STARTED, ar.userObj);
-
- // Bogus chars at end should be ignored
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- assertEquals(0, msg.arg1);
- ar = (AsyncResult) (msg.obj);
- cn = (Connection) (ar.result);
- assertEquals(Connection.PostDialState.COMPLETE,
- cn.getPostDialState());
- assertEquals(Connection.PostDialState.COMPLETE, ar.userObj);
- }
-
- public void testPostDialCancel() throws Exception {
- Message msg;
- AsyncResult ar;
- Connection cn;
-
- mGSMPhone.dial("+13125551212,N");
- mRadioControl.progressConnectingToActive();
-
- mRadioControl.progressConnectingToActive();
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertNotNull("Message Time Out", msg);
- assertEquals(',', msg.arg1);
-
- msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
- assertEquals('N', msg.arg1);
- ar = (AsyncResult) (msg.obj);
- cn = (Connection) (ar.result);
- assertEquals(Connection.PostDialState.WILD, cn.getPostDialState());
- cn.cancelPostDial();
-
- assertEquals(Connection.PostDialState.CANCELLED, cn.getPostDialState());
- }
-
- public void testOutgoingCallFail() throws Exception {
- Message msg;
- /*
- * normal clearing
- */
-
- mRadioControl.setNextCallFailCause(CallFailCause.NORMAL_CLEARING);
- mRadioControl.setAutoProgressConnectingCall(false);
-
- Connection cn = mGSMPhone.dial("+13125551212");
-
- mRadioControl.progressConnectingCallState();
-
- // I'm just progressing the call state to
- // ensure getCurrentCalls() gets processed...
- // Normally these failure conditions would happen in DIALING
- // not ALERTING
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (cn.getState() == Call.State.DIALING);
-
-
- mRadioControl.triggerHangupAll();
- msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
- assertNotNull("Message Time Out", msg);
- assertEquals(PhoneConstants.State.IDLE, mGSMPhone.getState());
-
- assertEquals(DisconnectCause.NORMAL, cn.getDisconnectCause());
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
- /*
- * busy
- */
-
- mRadioControl.setNextCallFailCause(CallFailCause.USER_BUSY);
- mRadioControl.setAutoProgressConnectingCall(false);
-
- cn = mGSMPhone.dial("+13125551212");
-
- mRadioControl.progressConnectingCallState();
-
- // I'm just progressing the call state to
- // ensure getCurrentCalls() gets processed...
- // Normally these failure conditions would happen in DIALING
- // not ALERTING
- do {
- assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
- } while (cn.getState() == Call.State.DIALING);
-
-
- mRadioControl.triggerHangupAll();
- msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
- assertNotNull("Message Time Out", msg);
- assertEquals(PhoneConstants.State.IDLE, mGSMPhone.getState());
-
- assertEquals(DisconnectCause.BUSY, cn.getDisconnectCause());
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.DISCONNECTED,
- mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
-
- /*
- * congestion
- */
-
- mRadioControl.setNextCallFailCause(CallFailCause.NO_CIRCUIT_AVAIL);
- mRadioControl.setAutoProgressConnectingCall(false);
-
- cn = mGSMPhone.dial("+13125551212");
-
- mRadioControl.progressConnectingCallState();
-
- // I'm just progressing the call state to
- // ensure getCurrentCalls() gets processed...
- // Normally these failure conditions would happen in DIALING
- // not ALERTING
- do {
- msg = mGSMTestHandler.waitForMessage(ANY_MESSAGE);
- assertNotNull("Message Time Out", msg);
- } while (cn.getState() == Call.State.DIALING);
-
-
- mRadioControl.triggerHangupAll();
-
- // Unlike the while loops above, this one waits
- // for a "phone state changed" message back to "idle"
- do {
- msg = mGSMTestHandler.waitForMessage(ANY_MESSAGE);
- assertNotNull("Message Time Out", msg);
- } while (!(msg.what == EVENT_PHONE_STATE_CHANGED
- && mGSMPhone.getState() == PhoneConstants.State.IDLE));
-
- assertEquals(PhoneConstants.State.IDLE, mGSMPhone.getState());
-
- assertEquals(DisconnectCause.CONGESTION, cn.getDisconnectCause());
-
- assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
- assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
- assertEquals(0, mGSMPhone.getBackgroundCall().getConnections().size());
-
- assertEquals(Call.State.IDLE, mGSMPhone.getRingingCall().getState());
- assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
- assertEquals(Call.State.IDLE, mGSMPhone.getBackgroundCall().getState());
-
- assertTrue(mGSMPhone.getForegroundCall().getEarliestCreateTime() > 0);
- assertEquals(0, mGSMPhone.getForegroundCall().getEarliestConnectTime());
- }
-
- public void testSSNotification() throws Exception {
- // MO
- runTest(0, SuppServiceNotification.MO_CODE_UNCONDITIONAL_CF_ACTIVE);
- runTest(0, SuppServiceNotification.MO_CODE_CALL_IS_WAITING);
- runTest(0, SuppServiceNotification.MO_CODE_CALL_DEFLECTED);
-
- // MT
- runTest(1, SuppServiceNotification.MT_CODE_FORWARDED_CALL);
- runTest(1, SuppServiceNotification.MT_CODE_CALL_CONNECTED_ECT);
- runTest(1, SuppServiceNotification.MT_CODE_ADDITIONAL_CALL_FORWARDED);
- }
-
- private void runTest(int type, int code) {
- Message msg;
-
- mRadioControl.triggerSsn(type, code);
-
- msg = mGSMTestHandler.waitForMessage(EVENT_SSN);
- assertNotNull("Message Time Out", msg);
- AsyncResult ar = (AsyncResult) msg.obj;
-
- assertNull(ar.exception);
-
- SuppServiceNotification notification =
- (SuppServiceNotification) ar.result;
-
- assertEquals(type, notification.notificationType);
- assertEquals(code, notification.code);
- }
-
- public void testUssd() throws Exception {
- // Quick hack to work around a race condition in this test:
- // We may initiate a USSD MMI before GSMPhone receives its initial
- // GSMTestHandler.EVENT_RADIO_OFF_OR_NOT_AVAILABLE event. When the phone sees this
- // event, it will cancel the just issued USSD MMI, which we don't
- // want. So sleep a little first.
- try {
- Thread.sleep(1000);
- } catch (InterruptedException ex) {
- // do nothing
- }
-
- verifyNormal();
- verifyCancel();
- varifyNetworkInitiated();
- }
-
- private void varifyNetworkInitiated() {
- Message msg;
- AsyncResult ar;
- MmiCode mmi;
-
- // Receive an incoming NOTIFY
- mRadioControl.triggerIncomingUssd("0", "NOTIFY message");
- msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
- assertNotNull("Message Time Out", msg);
- ar = (AsyncResult) msg.obj;
- mmi = (MmiCode) ar.result;
-
- assertFalse(mmi.isUssdRequest());
-
- // Receive a REQUEST and send response
- mRadioControl.triggerIncomingUssd("1", "REQUEST Message");
- msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
- assertNotNull("Message Time Out", msg);
- ar = (AsyncResult) msg.obj;
- mmi = (MmiCode) ar.result;
-
- assertTrue(mmi.isUssdRequest());
-
- mGSMPhone.sendUssdResponse("## TEST: TEST_GSMPhone responding...");
- msg = mGSMTestHandler.waitForMessage(EVENT_MMI_INITIATE);
- assertNotNull("Message Time Out", msg);
- ar = (AsyncResult) msg.obj;
- mmi = (MmiCode) ar.result;
-
- GsmMmiCode gsmMmi = (GsmMmiCode) mmi;
- assertTrue(gsmMmi.isPendingUSSD());
- msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
- assertNotNull("Message Time Out", msg);
- ar = (AsyncResult) msg.obj;
- mmi = (MmiCode) ar.result;
-
- assertNull(ar.exception);
- assertFalse(mmi.isUssdRequest());
-
- // Receive a REQUEST and cancel
- mRadioControl.triggerIncomingUssd("1", "REQUEST Message");
- msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
- assertNotNull("Message Time Out", msg);
- ar = (AsyncResult) msg.obj;
- mmi = (MmiCode) ar.result;
-
- assertTrue(mmi.isUssdRequest());
-
- mmi.cancel();
- msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
- assertNotNull("Message Time Out", msg);
-
- ar = (AsyncResult) msg.obj;
- mmi = (MmiCode) ar.result;
-
- assertNull(ar.exception);
- assertEquals(MmiCode.State.CANCELLED, mmi.getState());
-
- List mmiList = mGSMPhone.getPendingMmiCodes();
- assertEquals(0, mmiList.size());
- }
-
- private void verifyNormal() throws CallStateException {
- Message msg;
- AsyncResult ar;
- MmiCode mmi;
-
- mGSMPhone.dial("#646#");
-
- msg = mGSMTestHandler.waitForMessage(EVENT_MMI_INITIATE);
- assertNotNull("Message Time Out", msg);
-
- msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
- assertNotNull("Message Time Out", msg);
-
- ar = (AsyncResult) msg.obj;
- mmi = (MmiCode) ar.result;
- assertEquals(MmiCode.State.COMPLETE, mmi.getState());
- }
-
-
- private void verifyCancel() throws CallStateException {
- /**
- * This case makes an assumption that dial() will add the USSD
- * to the "pending MMI codes" list before it returns. This seems
- * like reasonable semantics. It also assumes that the USSD
- * request in question won't complete until we get back to the
- * event loop, thus cancel() is safe.
- */
- Message msg;
-
- mGSMPhone.dial("#646#");
-
- List<? extends MmiCode> pendingMmis = mGSMPhone.getPendingMmiCodes();
-
- assertEquals(1, pendingMmis.size());
-
- MmiCode mmi = pendingMmis.get(0);
- assertTrue(mmi.isCancelable());
- mmi.cancel();
-
- msg = mGSMTestHandler.waitForMessage(EVENT_MMI_INITIATE);
- assertNotNull("Message Time Out", msg);
-
- msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
- assertNotNull("Message Time Out", msg);
-
- AsyncResult ar = (AsyncResult) msg.obj;
- mmi = (MmiCode) ar.result;
-
- assertEquals(MmiCode.State.CANCELLED, mmi.getState());
- }
-
- public void testRilHooks() throws Exception {
- //
- // These test cases all assume the RIL OEM hooks
- // just echo back their input
- //
-
- Message msg;
- AsyncResult ar;
-
- // null byte array
-
- mGSMPhone.invokeOemRilRequestRaw(null, mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE));
-
- msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE);
- assertNotNull("Message Time Out", msg);
-
- ar = ((AsyncResult) msg.obj);
-
- assertNull(ar.result);
- assertNull(ar.exception);
-
- // empty byte array
-
- mGSMPhone.invokeOemRilRequestRaw(new byte[0], mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE));
-
- msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE);
- assertNotNull("Message Time Out", msg);
-
- ar = ((AsyncResult) msg.obj);
-
- assertEquals(0, ((byte[]) (ar.result)).length);
- assertNull(ar.exception);
-
- // byte array with data
-
- mGSMPhone.invokeOemRilRequestRaw("Hello".getBytes("utf-8"),
- mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE));
-
- msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE);
- assertNotNull("Message Time Out", msg);
-
- ar = ((AsyncResult) msg.obj);
-
- assertEquals("Hello", new String(((byte[]) (ar.result)), "utf-8"));
- assertNull(ar.exception);
-
- // null strings
-
- mGSMPhone.invokeOemRilRequestStrings(null, mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE));
-
- msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE);
- assertNotNull("Message Time Out", msg);
-
- ar = ((AsyncResult) msg.obj);
-
- assertNull(ar.result);
- assertNull(ar.exception);
-
- // empty byte array
-
- mGSMPhone.invokeOemRilRequestStrings(new String[0],
- mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE));
-
- msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE);
- assertNotNull("Message Time Out", msg);
-
- ar = ((AsyncResult) msg.obj);
-
- assertEquals(0, ((String[]) (ar.result)).length);
- assertNull(ar.exception);
-
- // Strings with data
-
- String s[] = new String[1];
-
- s[0] = "Hello";
-
- mGSMPhone.invokeOemRilRequestStrings(s, mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE));
-
- msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE);
- assertNotNull("Message Time Out", msg);
-
- ar = ((AsyncResult) msg.obj);
-
- assertEquals("Hello", ((String[]) (ar.result))[0]);
- assertEquals(1, ((String[]) (ar.result)).length);
- assertNull(ar.exception);
- }
-
- public void testMmi() throws Exception {
- mRadioControl.setAutoProgressConnectingCall(false);
-
- // "valid" MMI sequences
- runValidMmi("*#67#", false);
- runValidMmi("##43*11#", false);
- runValidMmi("#33*1234*11#", false);
- runValidMmi("*21*6505551234**5#", false);
- runValidMmi("**03**1234*4321*4321#", false);
- // pound string
- runValidMmi("5308234092307540923#", true);
- // short code
- runValidMmi("22", true);
- // as part of call setup
- runValidMmiWithConnect("*31#6505551234");
-
- // invalid MMI sequences
- runNotMmi("6505551234");
- runNotMmi("1234#*12#34566654");
- runNotMmi("*#*#12#*");
- }
-
- private void runValidMmi(String dialString, boolean cancelable) throws CallStateException {
- Connection c = mGSMPhone.dial(dialString);
- assertNull(c);
- Message msg = mGSMTestHandler.waitForMessage(EVENT_MMI_INITIATE);
- assertNotNull("Message Time Out", msg);
- // Should not be cancelable.
- AsyncResult ar = (AsyncResult) msg.obj;
- MmiCode mmi = (MmiCode) ar.result;
- assertEquals(cancelable, mmi.isCancelable());
-
- msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
- assertNotNull("Message Time Out", msg);
- }
-
- private void runValidMmiWithConnect(String dialString) throws CallStateException {
- mRadioControl.pauseResponses();
-
- Connection c = mGSMPhone.dial(dialString);
- assertNotNull(c);
-
- hangup(c);
- }
-
- private void hangup(Connection cn) throws CallStateException {
- cn.hangup();
-
- mRadioControl.resumeResponses();
- assertNotNull(mGSMTestHandler.waitForMessage(EVENT_DISCONNECT));
-
- }
-
- private void runNotMmi(String dialString) throws CallStateException {
- mRadioControl.pauseResponses();
-
- Connection c = mGSMPhone.dial(dialString);
- assertNotNull(c);
-
- hangup(c);
- }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMTestHandler.java.broken b/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMTestHandler.java.broken
deleted file mode 100644
index 16861fa..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GSMTestHandler.java.broken
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2009 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.gsm;
-
-import android.content.Context;
-
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import com.android.telephony.Rlog;
-
-import com.android.internal.telephony.gsm.GSMPhone;
-import com.android.internal.telephony.test.SimulatedCommands;
-import com.android.internal.telephony.TestPhoneNotifier;
-
-/**
- * This class creates a HandlerThread which waits for the various messages.
- */
-public class GSMTestHandler extends HandlerThread implements Handler.Callback {
-
- private Handler mHandler;
- private Message mCurrentMessage;
-
- private Boolean mMsgConsumed;
- private SimulatedCommands sc;
- private GSMPhone mGSMPhone;
- private Context mContext;
-
- private static final int FAIL_TIMEOUT_MILLIS = 5 * 1000;
-
- public GSMTestHandler(Context context) {
- super("GSMPhoneTest");
- mMsgConsumed = false;
- mContext = context;
- }
-
- @Override
- protected void onLooperPrepared() {
- sc = new SimulatedCommands();
- mGSMPhone = new GSMPhone(mContext, sc, new TestPhoneNotifier(), true);
- mHandler = new Handler(getLooper(), this);
- synchronized (this) {
- notifyAll();
- }
- }
-
- public boolean handleMessage(Message msg) {
- synchronized (this) {
- mCurrentMessage = msg;
- this.notifyAll();
- while(!mMsgConsumed) {
- try {
- this.wait();
- } catch (InterruptedException e) {}
- }
- mMsgConsumed = false;
- }
- return true;
- }
-
-
- public void cleanup() {
- Looper looper = getLooper();
- if (looper != null) looper.quit();
- mHandler = null;
- }
-
- public Handler getHandler() {
- return mHandler;
- }
-
- public SimulatedCommands getSimulatedCommands() {
- return sc;
- }
-
- public GSMPhone getGSMPhone() {
- return mGSMPhone;
- }
-
- public Message waitForMessage(int code) {
- Message msg;
- while(true) {
- msg = null;
- synchronized (this) {
- try {
- this.wait(FAIL_TIMEOUT_MILLIS);
- } catch (InterruptedException e) {
- }
-
- // Check if timeout has occurred.
- if (mCurrentMessage != null) {
- // Consume the message
- msg = Message.obtain();
- msg.copyFrom(mCurrentMessage);
- mCurrentMessage = null;
- mMsgConsumed = true;
- this.notifyAll();
- }
- }
- if (msg == null || code == GSMPhoneTest.ANY_MESSAGE || msg.what == code) return msg;
- }
- }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadCommands.java.broken b/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadCommands.java.broken
deleted file mode 100644
index a9d869c..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadCommands.java.broken
+++ /dev/null
@@ -1,694 +0,0 @@
-/*
- * Copyright (C) 2011 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.gsm;
-
-import android.content.Context;
-import android.os.AsyncResult;
-import android.os.Message;
-import android.os.SystemClock;
-import com.android.telephony.Rlog;
-
-import com.android.internal.telephony.BaseCommands;
-import com.android.internal.telephony.UUSInfo;
-import com.android.internal.telephony.uicc.IccIoResult;
-import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
-
-import junit.framework.Assert;
-
-/**
- * Dummy BaseCommands for UsimDataDownloadTest. Only implements UICC envelope and
- * SMS acknowledgement commands.
- */
-class UsimDataDownloadCommands extends BaseCommands {
- private static final String TAG = "UsimDataDownloadCommands";
-
- private boolean mExpectingAcknowledgeGsmSms; // true if expecting ack GSM SMS
- private boolean mExpectingAcknowledgeGsmSmsSuccess; // true if expecting ack SMS success
- private int mExpectingAcknowledgeGsmSmsFailureCause; // expecting ack SMS failure cause
- private String mExpectingAcknowledgeGsmSmsPdu; // expecting ack SMS PDU
-
- private boolean mExpectingSendEnvelope; // true to expect a send envelope command
- private String mExpectingSendEnvelopeContents; // expected string for send envelope
- private int mExpectingSendEnvelopeResponseSw1; // SW1/SW2 response status
- private int mExpectingSendEnvelopeResponseSw2; // SW1/SW2 response status
- private String mExpectingSendEnvelopeResponse; // Response string for Send Envelope
-
- UsimDataDownloadCommands(Context context) {
- super(context);
- }
-
- /**
- * Expect a call to acknowledgeLastIncomingGsmSms with success flag and failure cause.
- * @param success true if expecting success; false if expecting failure
- * @param cause the failure cause, if success is false
- */
- synchronized void expectAcknowledgeGsmSms(boolean success, int cause) {
- Assert.assertFalse("expectAcknowledgeGsmSms called twice", mExpectingAcknowledgeGsmSms);
- mExpectingAcknowledgeGsmSms = true;
- mExpectingAcknowledgeGsmSmsSuccess = success;
- mExpectingAcknowledgeGsmSmsFailureCause = cause;
- }
-
- /**
- * Expect a call to acknowledgeLastIncomingGsmSmsWithPdu with success flag and PDU.
- * @param success true if expecting success; false if expecting failure
- * @param ackPdu the acknowledgement PDU to expect
- */
- synchronized void expectAcknowledgeGsmSmsWithPdu(boolean success, String ackPdu) {
- Assert.assertFalse("expectAcknowledgeGsmSms called twice", mExpectingAcknowledgeGsmSms);
- mExpectingAcknowledgeGsmSms = true;
- mExpectingAcknowledgeGsmSmsSuccess = success;
- mExpectingAcknowledgeGsmSmsPdu = ackPdu;
- }
-
- /**
- * Expect a call to sendEnvelopeWithStatus().
- * @param contents expected envelope contents to send
- * @param sw1 simulated SW1 status to return
- * @param sw2 simulated SW2 status to return
- * @param response simulated envelope response to return
- */
- synchronized void expectSendEnvelope(String contents, int sw1, int sw2, String response) {
- Assert.assertFalse("expectSendEnvelope called twice", mExpectingSendEnvelope);
- mExpectingSendEnvelope = true;
- mExpectingSendEnvelopeContents = contents;
- mExpectingSendEnvelopeResponseSw1 = sw1;
- mExpectingSendEnvelopeResponseSw2 = sw2;
- mExpectingSendEnvelopeResponse = response;
- }
-
- synchronized void assertExpectedMethodsCalled() {
- long stopTime = SystemClock.elapsedRealtime() + 5000;
- while ((mExpectingAcknowledgeGsmSms || mExpectingSendEnvelope)
- && SystemClock.elapsedRealtime() < stopTime) {
- try {
- wait();
- } catch (InterruptedException ignored) {}
- }
- Assert.assertFalse("expecting SMS acknowledge call", mExpectingAcknowledgeGsmSms);
- Assert.assertFalse("expecting send envelope call", mExpectingSendEnvelope);
- }
-
- @Override
- public synchronized void acknowledgeLastIncomingGsmSms(boolean success, int cause,
- Message response) {
- Rlog.d(TAG, "acknowledgeLastIncomingGsmSms: success=" + success + ", cause=" + cause);
- Assert.assertTrue("unexpected call to acknowledge SMS", mExpectingAcknowledgeGsmSms);
- Assert.assertEquals(mExpectingAcknowledgeGsmSmsSuccess, success);
- Assert.assertEquals(mExpectingAcknowledgeGsmSmsFailureCause, cause);
- mExpectingAcknowledgeGsmSms = false;
- if (response != null) {
- AsyncResult.forMessage(response);
- response.sendToTarget();
- }
- notifyAll(); // wake up assertExpectedMethodsCalled()
- }
-
- @Override
- public synchronized void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu,
- Message response) {
- Rlog.d(TAG, "acknowledgeLastIncomingGsmSmsWithPdu: success=" + success
- + ", ackPDU= " + ackPdu);
- Assert.assertTrue("unexpected call to acknowledge SMS", mExpectingAcknowledgeGsmSms);
- Assert.assertEquals(mExpectingAcknowledgeGsmSmsSuccess, success);
- Assert.assertEquals(mExpectingAcknowledgeGsmSmsPdu, ackPdu);
- mExpectingAcknowledgeGsmSms = false;
- if (response != null) {
- AsyncResult.forMessage(response);
- response.sendToTarget();
- }
- notifyAll(); // wake up assertExpectedMethodsCalled()
- }
-
- @Override
- public synchronized void sendEnvelopeWithStatus(String contents, Message response) {
- // Add spaces between hex bytes for readability
- StringBuilder builder = new StringBuilder();
- for (int i = 0; i < contents.length(); i += 2) {
- builder.append(contents.charAt(i)).append(contents.charAt(i+1)).append(' ');
- }
- Rlog.d(TAG, "sendEnvelopeWithStatus: " + builder.toString());
-
- Assert.assertTrue("unexpected call to send envelope", mExpectingSendEnvelope);
- Assert.assertEquals(mExpectingSendEnvelopeContents, contents);
- mExpectingSendEnvelope = false;
-
- IccIoResult result = new IccIoResult(mExpectingSendEnvelopeResponseSw1,
- mExpectingSendEnvelopeResponseSw2, mExpectingSendEnvelopeResponse);
-
- if (response != null) {
- AsyncResult.forMessage(response, result, null);
- response.sendToTarget();
- }
- notifyAll(); // wake up assertExpectedMethodsCalled()
- }
-
- @Override
- public void setSuppServiceNotifications(boolean enable, Message result) {
- }
-
- @Override
- public void supplyIccPin(String pin, Message result) {
- }
-
- @Override
- public void supplyIccPinForApp(String pin, String aid, Message result) {
- }
-
- @Override
- public void supplyIccPuk(String puk, String newPin, Message result) {
- }
-
- @Override
- public void supplyIccPukForApp(String puk, String newPin, String aid, Message result) {
- }
-
- @Override
- public void supplyIccPin2(String pin2, Message result) {
- }
-
- @Override
- public void supplyIccPin2ForApp(String pin2, String aid, Message result) {
- }
-
- @Override
- public void supplyIccPuk2(String puk2, String newPin2, Message result) {
- }
-
- @Override
- public void supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message result) {
- }
-
- @Override
- public void changeIccPin(String oldPin, String newPin, Message result) {
- }
-
- @Override
- public void changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message result) {
- }
-
- @Override
- public void changeIccPin2(String oldPin2, String newPin2, Message result) {
- }
-
- @Override
- public void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr, Message result) {
- }
-
- @Override
- public void changeBarringPassword(String facility, String oldPwd, String newPwd,
- Message result) {
- }
-
- @Override
- public void supplyNetworkDepersonalization(String netpin, Message result) {
- }
-
- @Override
- public void getCurrentCalls(Message result) {
- }
-
- @Override
- public void getPDPContextList(Message result) {
- }
-
- @Override
- public void getDataCallList(Message result) {
- }
-
- @Override
- public void dial(String address, int clirMode, Message result) {
- }
-
- @Override
- public void dial(String address, int clirMode, UUSInfo uusInfo, Message result) {
- }
-
- @Override
- public void getIMSI(Message result) {
- }
-
- @Override
- public void getIMEI(Message result) {
- }
-
- @Override
- public void getIMEISV(Message result) {
- }
-
- @Override
- public void hangupConnection(int gsmIndex, Message result) {
- }
-
- @Override
- public void hangupWaitingOrBackground(Message result) {
- }
-
- @Override
- public void hangupForegroundResumeBackground(Message result) {
- }
-
- @Override
- public void switchWaitingOrHoldingAndActive(Message result) {
- }
-
- @Override
- public void conference(Message result) {
- }
-
- @Override
- public void setPreferredVoicePrivacy(boolean enable, Message result) {
- }
-
- @Override
- public void getPreferredVoicePrivacy(Message result) {
- }
-
- @Override
- public void separateConnection(int gsmIndex, Message result) {
- }
-
- @Override
- public void acceptCall(Message result) {
- }
-
- @Override
- public void rejectCall(Message result) {
- }
-
- @Override
- public void explicitCallTransfer(Message result) {
- }
-
- @Override
- public void getLastCallFailCause(Message result) {
- }
-
- @Override
- public void getLastPdpFailCause(Message result) {
- }
-
- @Override
- public void getLastDataCallFailCause(Message result) {
- }
-
- @Override
- public void setMute(boolean enableMute, Message response) {
- }
-
- @Override
- public void getMute(Message response) {
- }
-
- @Override
- public void getSignalStrength(Message response) {
- }
-
- @Override
- public void getVoiceRegistrationState(Message response) {
- }
-
- @Override
- public void getDataRegistrationState(Message response) {
- }
-
- @Override
- public void getOperator(Message response) {
- }
-
- @Override
- public void sendDtmf(char c, Message result) {
- }
-
- @Override
- public void startDtmf(char c, Message result) {
- }
-
- @Override
- public void stopDtmf(Message result) {
- }
-
- @Override
- public void sendBurstDtmf(String dtmfString, int on, int off, Message result) {
- }
-
- @Override
- public void sendSMS(String smscPDU, String pdu, Message response) {
- }
-
- @Override
- public void sendSMSExpectMore(String smscPDU, String pdu, Message response) {
- }
-
- @Override
- public void sendCdmaSms(byte[] pdu, Message response) {
- }
-
- @Override
- public void sendImsGsmSms (String smscPDU, String pdu,
- int retry, int messageRef, Message response) {
- }
-
- @Override
- public void sendImsCdmaSms(byte[] pdu, int retry, int messageRef,
- Message response) {
- }
-
- @Override
- public void deleteSmsOnSim(int index, Message response) {
- }
-
- @Override
- public void deleteSmsOnRuim(int index, Message response) {
- }
-
- @Override
- public void writeSmsToSim(int status, String smsc, String pdu, Message response) {
- }
-
- @Override
- public void writeSmsToRuim(int status, byte[] pdu, Message response) {
- }
-
- @Override
- public void setRadioPower(boolean on, Message response) {
- }
-
- @Override
- public void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message response) {
- }
-
- @Override
- public void iccIO(int command, int fileid, String path, int p1, int p2, int p3, String data,
- String pin2, Message response) {
- }
-
- @Override
- public void queryCLIP(Message response) {
- }
-
- @Override
- public void getCLIR(Message response) {
- }
-
- @Override
- public void setCLIR(int clirMode, Message response) {
- }
-
- @Override
- public void queryCallWaiting(int serviceClass, Message response) {
- }
-
- @Override
- public void setCallWaiting(boolean enable, int serviceClass, Message response) {
- }
-
- @Override
- public void setCallForward(int action, int cfReason, int serviceClass, String number,
- int timeSeconds, Message response) {
- }
-
- @Override
- public void queryCallForwardStatus(int cfReason, int serviceClass, String number,
- Message response) {
- }
-
- @Override
- public void setNetworkSelectionModeAutomatic(Message response) {
- }
-
- @Override
- public void setNetworkSelectionModeManual(String operatorNumeric, Message response) {
- }
-
- @Override
- public void getNetworkSelectionMode(Message response) {
- }
-
- @Override
- public void getAvailableNetworks(Message response) {
- }
-
- @Override
- public void getBasebandVersion(Message response) {
- }
-
- @Override
- public void queryFacilityLock(String facility, String password, int serviceClass,
- Message response) {
- }
-
- @Override
- public void queryFacilityLockForApp(String facility, String password, int serviceClass,
- String appId, Message response) {
- }
-
- @Override
- public void setFacilityLock(String facility, boolean lockState, String password,
- int serviceClass, Message response) {
- }
-
- @Override
- public void setFacilityLockForApp(String facility, boolean lockState, String password,
- int serviceClass, String appId, Message response) {
- }
-
- @Override
- public void sendUSSD(String ussdString, Message response) {
- }
-
- @Override
- public void cancelPendingUssd(Message response) {
- }
-
- @Override
- public void resetRadio(Message result) {
- }
-
- @Override
- public void setBandMode(int bandMode, Message response) {
- }
-
- @Override
- public void queryAvailableBandMode(Message response) {
- }
-
- @Override
- public void setPreferredNetworkType(int networkType, Message response) {
- }
-
- @Override
- public void getPreferredNetworkType(Message response) {
- }
-
- @Override
- public void setLocationUpdates(boolean enable, Message response) {
- }
-
- @Override
- public void getSmscAddress(Message result) {
- }
-
- @Override
- public void setSmscAddress(String address, Message result) {
- }
-
- @Override
- public void reportSmsMemoryStatus(boolean available, Message result) {
- }
-
- @Override
- public void reportStkServiceIsRunning(Message result) {
- }
-
- @Override
- public void invokeOemRilRequestRaw(byte[] data, Message response) {
- }
-
- @Override
- public void invokeOemRilRequestStrings(String[] strings, Message response) {
- }
-
- @Override
- public void sendTerminalResponse(String contents, Message response) {
- }
-
- @Override
- public void sendEnvelope(String contents, Message response) {
- }
-
- @Override
- public void handleCallSetupRequestFromSim(boolean accept, Message response) {
- }
-
- @Override
- public void setGsmBroadcastActivation(boolean activate, Message result) {
- }
-
- @Override
- public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response) {
- }
-
- @Override
- public void getGsmBroadcastConfig(Message response) {
- }
-
- @Override
- public void getDeviceIdentity(Message response) {
- }
-
- @Override
- public void getCDMASubscription(Message response) {
- }
-
- @Override
- public void getImsRegistrationState (Message result) {
- }
-
- @Override
- public void sendCDMAFeatureCode(String FeatureCode, Message response) {
- }
-
- @Override
- public void setPhoneType(int phoneType) {
- }
-
- @Override
- public void queryCdmaRoamingPreference(Message response) {
- }
-
- @Override
- public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
- }
-
- @Override
- public void setCdmaSubscriptionSource(int cdmaSubscriptionType, Message response) {
- }
-
- @Override
- public void getCdmaSubscriptionSource(Message response) {
- }
-
- @Override
- public void setTTYMode(int ttyMode, Message response) {
- }
-
- @Override
- public void queryTTYMode(Message response) {
- }
-
- @Override
- public void setupDataCall(String radioTechnology, String profile, String apn, String user,
- String password, String authType, String protocol, Message result) {
- }
-
- @Override
- public void deactivateDataCall(int cid, int reason, Message result) {
- }
-
- @Override
- public void setCdmaBroadcastActivation(boolean activate, Message result) {
- }
-
- @Override
- public void setCdmaBroadcastConfig(CdmaSmsBroadcastConfigInfo[] configs, Message response) {
- }
-
- @Override
- public void getCdmaBroadcastConfig(Message result) {
- }
-
- @Override
- public void exitEmergencyCallbackMode(Message response) {
- }
-
- @Override
- public void getIccCardStatus(Message result) {
- }
-
- @Override
- public void requestIsimAuthentication(String nonce, Message response) {
- }
-
- @Override
- public void requestIccSimAuthentication(String data, Message response) {
- }
-
- @Override
- public void getVoiceRadioTechnology(Message response) {
- }
-
- @Override
- public void getCellInfoList(Message result) {
- }
-
- @Override
- public void setCellInfoListRate(int rateInMillis, Message response) {
- }
-
- @Override
- public void setInitialAttachApn(String apn, String protocol, int authType, String username,
- String password, Message result) {
- }
-
- @Override
- public void setDataProfile(DataProfile[] dps, Message result) {
- }
-
- @Override
- public void getIMSIForApp(String aid, Message result) {
- }
-
- @Override
- public void iccIOForApp(int command, int fileid, String path, int p1, int p2, int p3,
- String data, String pin2, String aid, Message response) {
- }
-
- @Override
- public void iccOpenLogicalChannel(String AID, Message response) {
- }
-
- @Override
- public void iccCloseLogicalChannel(int channel, Message response) {
- }
-
- @Override
- public void iccTransmitApduLogicalChannel(int channel, int cla, int instruction,
- int p1, int p2, int p3, String data, Message response) {
- }
-
- @Override
- public void iccTransmitApduBasicChannel(int cla, int instruction, int p1, int p2,
- int p3, String data, Message response) {
- }
-
- @Override
- public void nvReadItem(int itemID, Message response) {
- }
-
- @Override
- public void nvWriteItem(int itemID, String itemValue, Message response) {
- }
-
- @Override
- public void nvWriteCdmaPrl(byte[] preferredRoamingList, Message response) {
- }
-
- @Override
- public void nvResetConfig(int resetType, Message response) {
- }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadTest.java.broken b/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadTest.java.broken
deleted file mode 100644
index 9fbb86c..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/UsimDataDownloadTest.java.broken
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2011 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.gsm;
-
-import android.os.HandlerThread;
-import android.test.AndroidTestCase;
-import com.android.telephony.Rlog;
-
-import java.nio.charset.Charset;
-
-/**
- * Test SMS-PP data download to UICC.
- * Uses test messages from 3GPP TS 31.124 section 27.22.5.
- */
-public class UsimDataDownloadTest extends AndroidTestCase {
- private static final String TAG = "UsimDataDownloadTest";
-
- class TestHandlerThread extends HandlerThread {
- private UsimDataDownloadHandler mHandler;
-
- TestHandlerThread() {
- super("TestHandlerThread");
- }
-
- @Override
- protected void onLooperPrepared() {
- synchronized (this) {
- mHandler = new UsimDataDownloadHandler(mCi, 0);
- notifyAll();
- }
- }
-
- UsimDataDownloadHandler getHandler() {
- synchronized (this) {
- while (mHandler == null) {
- try {
- wait();
- } catch (InterruptedException ignored) {}
- }
- return mHandler;
- }
- }
- }
-
- private UsimDataDownloadCommands mCi;
- private TestHandlerThread mHandlerThread;
- UsimDataDownloadHandler mHandler;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mCi = new UsimDataDownloadCommands(mContext);
- mHandlerThread = new TestHandlerThread();
- mHandlerThread.start();
- mHandler = mHandlerThread.getHandler();
- Rlog.d(TAG, "mHandler is constructed");
- }
-
- @Override
- protected void tearDown() throws Exception {
- mHandlerThread.quit();
- super.tearDown();
- }
-
- // SMS-PP Message 3.1.1
- private static final byte[] SMS_PP_MESSAGE_3_1_1 = {
- // Service center address
- 0x09, (byte) 0x91, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, (byte) 0xf8,
-
- 0x04, 0x04, (byte) 0x91, 0x21, 0x43, 0x7f, 0x16, (byte) 0x89, 0x10, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x0d, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61,
- 0x67, 0x65, 0x20, 0x31
- };
-
- // SMS-PP Download Envelope 3.1.1
- private static final String SMS_PP_ENVELOPE_3_1_1 = "d12d8202838106099111223344556677f88b1c04"
- + "049121437f16891010000000000d546573744d6573736167652031";
-
- // SMS-PP Message 3.1.5
- private static final byte[] SMS_PP_MESSAGE_3_1_5 = {
- // Service center address
- 0x09, (byte) 0x91, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, (byte) 0xf8,
-
- 0x44, 0x04, (byte) 0x91, 0x21, 0x43, 0x7f, (byte) 0xf6, (byte) 0x89, 0x10, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x1e, 0x02, 0x70, 0x00, 0x00, 0x19, 0x00, 0x0d, 0x00, 0x00,
- 0x00, 0x00, (byte) 0xbf, (byte) 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
- (byte) 0xdc, (byte) 0xdc, (byte) 0xdc, (byte) 0xdc, (byte) 0xdc, (byte) 0xdc,
- (byte) 0xdc, (byte) 0xdc, (byte) 0xdc, (byte) 0xdc
- };
-
- // SMS-PP Download Envelope 3.1.5
- private static final String SMS_PP_ENVELOPE_3_1_5 = "d13e8202838106099111223344556677f88b2d44"
- + "049121437ff6891010000000001e0270000019000d00000000bfff00000000000100"
- + "dcdcdcdcdcdcdcdcdcdc";
-
- public void testDataDownloadMessage1() {
- SmsMessage message = SmsMessage.createFromPdu(SMS_PP_MESSAGE_3_1_1);
- assertTrue("message is SMS-PP data download", message.isUsimDataDownload());
-
- mCi.expectSendEnvelope(SMS_PP_ENVELOPE_3_1_1, 0x90, 0x00, "");
- mCi.expectAcknowledgeGsmSms(true, 0);
- mHandler.startDataDownload(message);
- mCi.assertExpectedMethodsCalled();
-
- mCi.expectSendEnvelope(SMS_PP_ENVELOPE_3_1_1, 0x90, 0x00, "0123456789");
- mCi.expectAcknowledgeGsmSmsWithPdu(true, "00077f16050123456789");
- mHandler.startDataDownload(message);
- mCi.assertExpectedMethodsCalled();
-
- mCi.expectSendEnvelope(SMS_PP_ENVELOPE_3_1_1, 0x62, 0xff, "0123456789abcdef");
- mCi.expectAcknowledgeGsmSmsWithPdu(false, "00d5077f16080123456789abcdef");
- mHandler.startDataDownload(message);
- mCi.assertExpectedMethodsCalled();
- }
-
- public void testDataDownloadMessage5() {
- SmsMessage message = SmsMessage.createFromPdu(SMS_PP_MESSAGE_3_1_5);
- assertTrue("message is SMS-PP data download", message.isUsimDataDownload());
-
- mCi.expectSendEnvelope(SMS_PP_ENVELOPE_3_1_5, 0x90, 0x00, "9876543210");
- mCi.expectAcknowledgeGsmSmsWithPdu(true, "00077ff6059876543210");
- mHandler.startDataDownload(message);
- mCi.assertExpectedMethodsCalled();
-
- mCi.expectSendEnvelope(SMS_PP_ENVELOPE_3_1_5, 0x93, 0x00, "");
- mCi.expectAcknowledgeGsmSms(false, 0xd4); // SIM toolkit busy
- mHandler.startDataDownload(message);
- mCi.assertExpectedMethodsCalled();
- }
-}
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 c0b9923..4f1bdac 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
@@ -1876,11 +1876,14 @@
assertEquals(1, mCTUT.getConnections().size());
assertNotNull(mCTUT.getPendingMO());
assertEquals(Call.State.DIALING, mCTUT.mForegroundCall.getState());
+ assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState());
mCTUT.cleanupAndRemoveConnection(conn);
assertEquals(0, mCTUT.getConnections().size());
assertNull(mCTUT.getPendingMO());
assertEquals(Call.State.IDLE, mCTUT.mForegroundCall.getState());
+
+ assertEquals(PhoneConstants.State.IDLE, mCTUT.getState());
}
@Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java
index ab8ee33..e46b822 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java
@@ -31,9 +31,6 @@
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_VERY_FAST;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_VERY_SLOW;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
@@ -233,8 +230,6 @@
mCall1Proto.bearerAtStart = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
mCall1Proto.bearerAtEnd = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_CS;
mCall1Proto.direction = VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO;
- mCall1Proto.setupDuration =
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_VERY_FAST;
mCall1Proto.setupFailed = false;
mCall1Proto.disconnectReasonCode = DisconnectCause.LOCAL;
mCall1Proto.disconnectExtraCode = 0;
@@ -263,8 +258,6 @@
mCall2Proto.bearerAtStart = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
mCall2Proto.bearerAtEnd = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
mCall2Proto.direction = VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT;
- mCall2Proto.setupDuration =
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_VERY_FAST;
mCall2Proto.setupFailed = false;
mCall2Proto.disconnectReasonCode = ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE;
mCall2Proto.disconnectExtraCode = 0;
@@ -292,8 +285,6 @@
mCall3Proto.bearerAtStart = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
mCall3Proto.bearerAtEnd = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
mCall3Proto.direction = VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT;
- mCall3Proto.setupDuration =
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
mCall3Proto.setupFailed = false;
mCall3Proto.disconnectReasonCode = ImsReasonInfo.CODE_USER_TERMINATED;
mCall3Proto.disconnectExtraCode = 0;
@@ -320,8 +311,6 @@
mCall4Proto.bearerAtStart = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_CS;
mCall4Proto.bearerAtEnd = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_CS;
mCall4Proto.direction = VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO;
- mCall4Proto.setupDuration =
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_VERY_SLOW;
mCall4Proto.setupFailed = true;
mCall4Proto.disconnectReasonCode = DisconnectCause.NORMAL;
mCall4Proto.disconnectExtraCode = 0;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/TelephonyMetricsTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/TelephonyMetricsTest.java
index 111e5d2..c26dd22 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/TelephonyMetricsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/TelephonyMetricsTest.java
@@ -25,11 +25,6 @@
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SEND_SMS;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SETUP_DATA_CALL;
import static com.android.internal.telephony.data.LinkBandwidthEstimator.NUM_SIGNAL_LEVEL;
-import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_ADDRESS;
-import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_DNS;
-import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_GATEWAY;
-import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_IFNAME;
-import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_PCSCF_ADDRESS;
import static com.android.internal.telephony.nano.TelephonyProto.PdpType.PDP_TYPE_IPV4V6;
import static org.junit.Assert.assertArrayEquals;
@@ -89,6 +84,11 @@
import java.util.Arrays;
public class TelephonyMetricsTest extends TelephonyTest {
+ private static final String FAKE_ADDRESS = "99.88.77.66";
+ private static final String FAKE_DNS = "55.66.77.88";
+ private static final String FAKE_GATEWAY = "11.22.33.44";
+ private static final String FAKE_IFNAME = "FAKE IFNAME";
+ private static final String FAKE_PCSCF_ADDRESS = "22.33.44.55";
// Mocked classes
private ImsCallSession mImsCallSession;
private ServiceState mServiceState;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java
index ac554dd..fb556e6 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java
@@ -30,10 +30,6 @@
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_SUPER_WIDEBAND;
import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_UNKNOWN;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_ULTRA_FAST;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_UNKNOWN;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_VERY_SLOW;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
@@ -81,6 +77,7 @@
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
@@ -230,8 +227,6 @@
VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO,
TelephonyManager.NETWORK_TYPE_LTE,
ImsReasonInfo.CODE_REMOTE_CALL_DECLINE);
- expectedCall.setupDuration =
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
expectedCall.setupDurationMillis = 200;
expectedCall.setupFailed = true;
expectedCall.ratAtConnected = TelephonyManager.NETWORK_TYPE_UNKNOWN;
@@ -375,8 +370,6 @@
VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO,
TelephonyManager.NETWORK_TYPE_LTE,
ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE);
- expectedCall.setupDuration =
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
expectedCall.setupDurationMillis = 200;
expectedCall.setupFailed = false;
expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_EVS_SWB;
@@ -536,8 +529,6 @@
VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT,
TelephonyManager.NETWORK_TYPE_LTE,
ImsReasonInfo.CODE_USER_TERMINATED);
- expectedCall.setupDuration =
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
expectedCall.setupDurationMillis = 80;
expectedCall.setupFailed = false;
expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
@@ -820,8 +811,6 @@
VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT,
TelephonyManager.NETWORK_TYPE_LTE,
ImsReasonInfo.CODE_USER_TERMINATED);
- expectedCall.setupDuration =
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
expectedCall.setupDurationMillis = 80;
expectedCall.setupFailed = false;
expectedCall.codecBitmask =
@@ -876,8 +865,6 @@
VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT,
TelephonyManager.NETWORK_TYPE_LTE,
ImsReasonInfo.CODE_USER_TERMINATED);
- expectedCall.setupDuration =
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
expectedCall.setupDurationMillis = 80;
expectedCall.setupFailed = false;
expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
@@ -940,6 +927,7 @@
@Test
@SmallTest
+ @Ignore("b/256234604")
public void singleImsCall_ratSwitchToUnknown() {
setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mImsStats).getImsVoiceRadioTech();
@@ -955,7 +943,6 @@
VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT,
TelephonyManager.NETWORK_TYPE_LTE,
ImsReasonInfo.CODE_USER_TERMINATED);
- expectedCall.setupDuration = 1;
expectedCall.setupDurationMillis = 80;
expectedCall.setupFailed = false;
expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
@@ -1093,8 +1080,6 @@
VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT,
TelephonyManager.NETWORK_TYPE_LTE,
ImsReasonInfo.CODE_USER_TERMINATED);
- expectedCall.setupDuration =
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
expectedCall.setupDurationMillis = 80;
expectedCall.setupFailed = false;
expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
@@ -1148,8 +1133,6 @@
VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO,
TelephonyManager.NETWORK_TYPE_LTE,
ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE);
- expectedCall0.setupDuration =
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
expectedCall0.setupDurationMillis = 80;
expectedCall0.setupFailed = false;
expectedCall0.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
@@ -1172,8 +1155,6 @@
VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT,
TelephonyManager.NETWORK_TYPE_LTE,
ImsReasonInfo.CODE_USER_TERMINATED);
- expectedCall1.setupDuration =
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
expectedCall1.setupDurationMillis = 20;
expectedCall1.setupFailed = false;
expectedCall1.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
@@ -1282,8 +1263,6 @@
VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO,
TelephonyManager.NETWORK_TYPE_LTE,
ImsReasonInfo.CODE_USER_TERMINATED);
- expectedCall0.setupDuration =
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
expectedCall0.setupDurationMillis = 80;
expectedCall0.setupFailed = false;
expectedCall0.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
@@ -1306,8 +1285,6 @@
VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT,
TelephonyManager.NETWORK_TYPE_LTE,
ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE);
- expectedCall1.setupDuration =
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
expectedCall1.setupDurationMillis = 20;
expectedCall1.setupFailed = false;
expectedCall1.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
@@ -1416,8 +1393,6 @@
VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO,
TelephonyManager.NETWORK_TYPE_LTE,
ImsReasonInfo.CODE_USER_TERMINATED);
- expectedCall0.setupDuration =
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
expectedCall0.setupDurationMillis = 80;
expectedCall0.setupFailed = false;
expectedCall0.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
@@ -1438,8 +1413,6 @@
VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT,
TelephonyManager.NETWORK_TYPE_LTE,
ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE);
- expectedCall1.setupDuration =
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
expectedCall1.setupDurationMillis = 20;
expectedCall1.setupFailed = false;
expectedCall1.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
@@ -1531,8 +1504,6 @@
DisconnectCause.NORMAL);
expectedCall.ratAtEnd = TelephonyManager.NETWORK_TYPE_UMTS;
expectedCall.bandAtEnd = 0;
- expectedCall.setupDuration =
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_VERY_SLOW;
expectedCall.setupDurationMillis = 5000;
expectedCall.disconnectExtraCode = PreciseDisconnectCause.CALL_REJECTED;
expectedCall.ratSwitchCount = 1L;
@@ -1654,8 +1625,6 @@
expectedCall.ratAtConnected = TelephonyManager.NETWORK_TYPE_UMTS;
expectedCall.ratAtEnd = TelephonyManager.NETWORK_TYPE_UMTS;
expectedCall.bandAtEnd = 0;
- expectedCall.setupDuration =
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_VERY_SLOW;
expectedCall.setupDurationMillis = 5000;
expectedCall.disconnectExtraCode = PreciseDisconnectCause.NORMAL;
expectedCall.ratSwitchCount = 1L;
@@ -1720,8 +1689,6 @@
VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT,
TelephonyManager.NETWORK_TYPE_UMTS,
DisconnectCause.NORMAL);
- expectedCall.setupDuration =
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_UNKNOWN;
expectedCall.setupDurationMillis = 0;
expectedCall.disconnectExtraCode = PreciseDisconnectCause.CALL_REJECTED;
expectedCall.setupFailed = true;
@@ -1777,8 +1744,6 @@
VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT,
TelephonyManager.NETWORK_TYPE_UMTS,
DisconnectCause.NORMAL);
- expectedCall.setupDuration =
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_ULTRA_FAST;
expectedCall.setupDurationMillis = 500;
expectedCall.disconnectExtraCode = PreciseDisconnectCause.NORMAL;
expectedCall.setupFailed = false;
@@ -1838,8 +1803,6 @@
VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT,
TelephonyManager.NETWORK_TYPE_LTE,
ImsReasonInfo.CODE_LOCAL_HO_NOT_FEASIBLE);
- expectedCall.setupDuration =
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
expectedCall.setupDurationMillis = 80;
expectedCall.setupFailed = false;
expectedCall.srvccFailureCount = 2L;
@@ -1919,8 +1882,6 @@
VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT,
TelephonyManager.NETWORK_TYPE_LTE,
ImsReasonInfo.CODE_USER_TERMINATED);
- expectedCall.setupDuration =
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
expectedCall.setupDurationMillis = 80;
expectedCall.setupFailed = false;
expectedCall.srvccCancellationCount = 2L;
@@ -1991,8 +1952,6 @@
TelephonyManager.NETWORK_TYPE_LTE,
DisconnectCause.NORMAL);
expectedCall.disconnectExtraCode = PreciseDisconnectCause.NORMAL;
- expectedCall.setupDuration =
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
expectedCall.setupDurationMillis = 80;
expectedCall.setupFailed = false;
expectedCall.srvccCancellationCount = 1L;
@@ -2090,8 +2049,6 @@
TelephonyManager.NETWORK_TYPE_LTE,
DisconnectCause.NORMAL);
expectedCall0.disconnectExtraCode = PreciseDisconnectCause.NORMAL;
- expectedCall0.setupDuration =
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
expectedCall0.setupDurationMillis = 80;
expectedCall0.setupFailed = false;
expectedCall0.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
@@ -2119,8 +2076,6 @@
TelephonyManager.NETWORK_TYPE_LTE,
DisconnectCause.NORMAL);
expectedCall1.disconnectExtraCode = PreciseDisconnectCause.NORMAL;
- expectedCall1.setupDuration =
- VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
expectedCall1.setupDurationMillis = 20;
expectedCall1.setupFailed = false;
expectedCall1.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
@@ -2365,7 +2320,6 @@
call.bearerAtStart = bearer;
call.bearerAtEnd = bearer;
call.direction = direction;
- call.setupDuration = VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_UNKNOWN;
call.setupDurationMillis = 0;
call.setupFailed = true;
call.disconnectReasonCode = reason;
@@ -2400,7 +2354,6 @@
call.bearerAtStart = bearer;
call.bearerAtEnd = bearer;
call.direction = direction;
- call.setupDuration = VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_UNKNOWN;
call.setupDurationMillis = 0;
call.setupFailed = true;
call.disconnectReasonCode = reason;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/nitz/OWNERS b/tests/telephonytests/src/com/android/internal/telephony/nitz/OWNERS
new file mode 100644
index 0000000..be0513d
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/nitz/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 847766
+include platform/frameworks/base:/services/core/java/com/android/server/timezonedetector/OWNERS
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRulesTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRulesTest.java
index c885f5a..3deb501 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRulesTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRulesTest.java
@@ -42,7 +42,6 @@
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
@@ -581,28 +580,20 @@
// Read binary - since params are identical across files, we need to keep track of which
// file was selected most recently and give back that content.
- Map<String, String> binaryContent =
- new HashMap<>() {
- {
- // ODF
- put("5031", "A706300404025207");
- // DODF
- put(
- "5207",
- "A1293000300F0C0D4750205345204163632043746CA1143012060A2A864886FC6B"
- + "81480101300404024200");
- // ACMF
- put("4200", "301004080102030405060708300404024300");
- // ACRF
- put("4300", "3010A0080406FFFFFFFFFFFF300404024310");
- // ACCF
- put(
- "4310",
- "30220420B9CFCE1C47A6AC713442718F15EF55B00B3A6D1A6D48CB46249FA8EB51"
- + "465350302204204C36AF4A5BDAD97C1F3D8B283416D244496C2AC5EA"
- + "FE8226079EF6F676FD1859");
- }
- };
+ Map<String, String> binaryContent = Map.of(
+ // ODF
+ "5031", "A706300404025207",
+ // DODF
+ "5207", "A1293000300F0C0D4750205345204163632043746CA1143012060A2A864886FC6B"
+ + "81480101300404024200",
+ // ACMF
+ "4200", "301004080102030405060708300404024300",
+ // ACRF
+ "4300", "3010A0080406FFFFFFFFFFFF300404024310",
+ // ACCF
+ "4310", "30220420B9CFCE1C47A6AC713442718F15EF55B00B3A6D1A6D48CB46249FA8EB51"
+ + "465350302204204C36AF4A5BDAD97C1F3D8B283416D244496C2AC5EA"
+ + "FE8226079EF6F676FD1859");
doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
@@ -687,21 +678,15 @@
// Read binary - since params are identical across files, we need to keep track of which
// file was selected most recently and give back that content.
- Map<String, String> binaryContent =
- new HashMap<>() {
- {
- // ODF fails
- put("5031", "");
- // ACRF
- put("4300", "3010A0080406FFFFFFFFFFFF300404024310");
- // ACCF
- put(
- "4310",
- "30220420B9CFCE1C47A6AC713442718F15EF55B00B3A6D1A6D48CB46249FA8EB51"
- + "465350302204204C36AF4A5BDAD97C1F3D8B283416D244496C2AC5EA"
- + "FE8226079EF6F676FD1859");
- }
- };
+ Map<String, String> binaryContent = Map.of(
+ // ODF fails
+ "5031", "",
+ // ACRF
+ "4300", "3010A0080406FFFFFFFFFFFF300404024310",
+ // ACCF
+ "4310", "30220420B9CFCE1C47A6AC713442718F15EF55B00B3A6D1A6D48CB46249FA8EB51"
+ + "465350302204204C36AF4A5BDAD97C1F3D8B283416D244496C2AC5EA"
+ + "FE8226079EF6F676FD1859");
doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
diff --git a/tools/tdi b/tools/tdi
deleted file mode 100755
index 940a83b..0000000
--- a/tools/tdi
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/bin/bash
-# Telephony Debug Intents
-#set -x
-
-file_name='tdi'
-
-# Get the command as the first parameter
-cmd=$1
-shift
-
-function dc_errors()
-{
- if [ "$1" == "" ]; then
- echo "Usage: $file_name $cmd <dc> <count> <cause> <retry-time>"
- echo " <dc> must specifiy the DataConnection such as DC or GsmDC-1"
- echo " <count> := number of times to retry"
- echo " <cause> := From DataConnection.FailCause; such as -3 for SIGNAL_LOST"
- echo " <retry-time> := suggested retry time in milli-seconds"
- exit
- fi
- the_DC=$1
- echo "the_DC=$the_DC"
-
- if [ "$2" != "" ]; then
- counter="--ei counter $2";
- fi
- echo "counter=$counter"
-
- if [ "$3" != "" ]; then
- fail_cause="--ei fail_cause $3";
- fi
- echo "fail_cause=$fail_cause"
-
- if [ "$4" != "" ]; then
- suggested_retry_time="--ei suggested_retry_time $4";
- fi
- echo "suggested_retry_time=$suggested_retry_time"
-
-
- adb shell am broadcast -a com.android.internal.telephony.$the_DC.action_fail_bringup $counter $fail_cause $suggested_retry_time
-}
-
-
-case ${cmd} in
- dce) dc_errors "$@";;
- # Add more commands in the future
- *) echo 'Broadcast telephony debug intents'; echo 'usage: tdi [dce]'; echo ' dce=DC errors';;
-esac