aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-09-23 10:15:23 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-09-23 10:15:23 +0000
commitfa9c68d243ea7fd140e0740e083c7fba85a0d43c (patch)
tree8b04364c66ca59abce437de2175c1e2a083edda9
parent970dad03df4e0b91048158c9a24fa911d4a80af0 (diff)
parentc5dc59f7a82992193d151c96517277a517a5fcc2 (diff)
downloadtelephony-android13-mainline-scheduling-release.tar.gz
Snap for 9098257 from c5dc59f7a82992193d151c96517277a517a5fcc2 to mainline-scheduling-releaseaml_sch_331113000aml_sch_331111000android13-mainline-scheduling-release
Change-Id: Ibac857732533f550f00fdbc30f2d114a799398db
-rw-r--r--src/java/com/android/internal/telephony/data/DataNetwork.java89
-rw-r--r--src/java/com/android/internal/telephony/data/DataNetworkController.java93
-rw-r--r--tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java159
3 files changed, 268 insertions, 73 deletions
diff --git a/src/java/com/android/internal/telephony/data/DataNetwork.java b/src/java/com/android/internal/telephony/data/DataNetwork.java
index f85bc13cae..e483d2b0b7 100644
--- a/src/java/com/android/internal/telephony/data/DataNetwork.java
+++ b/src/java/com/android/internal/telephony/data/DataNetwork.java
@@ -628,10 +628,10 @@ public class DataNetwork extends StateMachine {
private @NonNull DataAllowedReason mDataAllowedReason;
/**
- * PCO (Protocol Configuration Options) data received from the network. Key is the PCO id, value
- * is the PCO content.
+ * PCO (Protocol Configuration Options) data received from the network. The first key is the
+ * cid of the PCO data, the second key is the PCO id, the value is the PCO data.
*/
- private final @NonNull Map<Integer, PcoData> mPcoData = new ArrayMap<>();
+ private final @NonNull Map<Integer, Map<Integer, PcoData>> mPcoData = new ArrayMap<>();
/** The QOS bearer sessions. */
private final @NonNull List<QosBearerSession> mQosBearerSessions = new ArrayList<>();
@@ -983,6 +983,7 @@ public class DataNetwork extends StateMachine {
public void enter() {
logv("Registering all events.");
mDataConfigManager.registerForConfigUpdate(getHandler(), EVENT_DATA_CONFIG_UPDATED);
+ mRil.registerForPcoData(getHandler(), EVENT_PCO_DATA_RECEIVED, null);
mPhone.getDisplayInfoController().registerForTelephonyDisplayInfoChanged(
getHandler(), EVENT_DISPLAY_INFO_CHANGED, null);
mPhone.getServiceStateTracker().registerForServiceStateChanged(getHandler(),
@@ -1035,6 +1036,7 @@ public class DataNetwork extends StateMachine {
mPhone.getDisplayInfoController().unregisterForTelephonyDisplayInfoChanged(
getHandler());
mDataConfigManager.unregisterForConfigUpdate(getHandler());
+ mRil.unregisterForPcoData(getHandler());
}
@Override
@@ -1081,9 +1083,13 @@ public class DataNetwork extends StateMachine {
updateNetworkCapabilities();
break;
}
+ case EVENT_PCO_DATA_RECEIVED: {
+ AsyncResult ar = (AsyncResult) msg.obj;
+ onPcoDataReceived((PcoData) ar.result);
+ break;
+ }
case EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED:
case EVENT_TEAR_DOWN_NETWORK:
- case EVENT_PCO_DATA_RECEIVED:
case EVENT_STUCK_IN_TRANSIENT_STATE:
case EVENT_DISPLAY_INFO_CHANGED:
case EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET:
@@ -1162,7 +1168,6 @@ public class DataNetwork extends StateMachine {
break;
case EVENT_START_HANDOVER:
case EVENT_TEAR_DOWN_NETWORK:
- case EVENT_PCO_DATA_RECEIVED:
case EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET:
// Defer the request until connected or disconnected.
log("Defer message " + eventToString(msg.what));
@@ -1229,6 +1234,13 @@ public class DataNetwork extends StateMachine {
}
}
+ // If we've ever received PCO data before connected, now it's the time to
+ // process it.
+ mPcoData.getOrDefault(mCid.get(mTransport), Collections.emptyMap())
+ .forEach((pcoId, pcoData) -> {
+ onPcoDataChanged(pcoData);
+ });
+
notifyPreciseDataConnectionState();
updateSuspendState();
}
@@ -1279,10 +1291,6 @@ public class DataNetwork extends StateMachine {
case EVENT_SUBSCRIPTION_PLAN_OVERRIDE:
updateMeteredAndCongested();
break;
- case EVENT_PCO_DATA_RECEIVED:
- ar = (AsyncResult) msg.obj;
- onPcoDataReceived((PcoData) ar.result);
- break;
case EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE:
int resultCode = msg.arg1;
onDeactivateResponse(resultCode);
@@ -1353,10 +1361,6 @@ public class DataNetwork extends StateMachine {
onHandoverResponse(resultCode, dataCallResponse,
(DataHandoverRetryEntry) msg.obj);
break;
- case EVENT_PCO_DATA_RECEIVED:
- AsyncResult ar = (AsyncResult) msg.obj;
- onPcoDataReceived((PcoData) ar.result);
- break;
case EVENT_STUCK_IN_TRANSIENT_STATE:
reportAnomaly("Data service did not respond the handover request within "
+ TimeUnit.MILLISECONDS.toSeconds(
@@ -1545,7 +1549,6 @@ public class DataNetwork extends StateMachine {
private void registerForWwanEvents() {
registerForBandwidthUpdate();
mKeepaliveTracker.registerForKeepaliveStatus();
- mRil.registerForPcoData(this.getHandler(), EVENT_PCO_DATA_RECEIVED, null);
}
/**
@@ -1554,7 +1557,6 @@ public class DataNetwork extends StateMachine {
private void unregisterForWwanEvents() {
unregisterForBandwidthUpdate();
mKeepaliveTracker.unregisterForKeepaliveStatus();
- mRil.unregisterForPcoData(this.getHandler());
}
@Override
@@ -3111,8 +3113,6 @@ public class DataNetwork extends StateMachine {
mDataProfile = mHandoverDataProfile;
updateDataNetwork(response);
if (mTransport != AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
- // Handover from WWAN to WLAN
- mPcoData.clear();
unregisterForWwanEvents();
} else {
// Handover from WLAN to WWAN
@@ -3139,36 +3139,55 @@ public class DataNetwork extends StateMachine {
}
/**
+ * Called when PCO data changes.
+ *
+ * @param pcoData The PCO data.
+ */
+ private void onPcoDataChanged(@NonNull PcoData pcoData) {
+ log("onPcoDataChanged: " + pcoData);
+ mDataNetworkCallback.invokeFromExecutor(
+ () -> mDataNetworkCallback.onPcoDataChanged(DataNetwork.this));
+ if (mDataProfile.getApnSetting() != null) {
+ for (int apnType : mDataProfile.getApnSetting().getApnTypes()) {
+ Intent intent = new Intent(TelephonyManager.ACTION_CARRIER_SIGNAL_PCO_VALUE);
+ intent.putExtra(TelephonyManager.EXTRA_APN_TYPE, 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);
+ }
+ }
+ }
+
+ /**
* Called when receiving PCO (Protocol Configuration Options) data from the cellular network.
*
* @param pcoData PCO data.
*/
private void onPcoDataReceived(@NonNull PcoData pcoData) {
- if (pcoData.cid != getId()) return;
- PcoData oldData = mPcoData.put(pcoData.pcoId, pcoData);
+ // Save all the PCO data received, even though it might be unrelated to this data network.
+ // The network might be still in connecting state. Save all now and use it when entering
+ // connected state.
+ log("onPcoDataReceived: " + pcoData);
+ PcoData oldData = mPcoData.computeIfAbsent(pcoData.cid, m -> new ArrayMap<>())
+ .put(pcoData.pcoId, pcoData);
+ if (getId() == INVALID_CID || pcoData.cid != getId()) return;
if (!Objects.equals(oldData, pcoData)) {
- log("onPcoDataReceived: " + pcoData);
- mDataNetworkCallback.invokeFromExecutor(
- () -> mDataNetworkCallback.onPcoDataChanged(DataNetwork.this));
- if (mDataProfile.getApnSetting() != null) {
- for (int apnType : mDataProfile.getApnSetting().getApnTypes()) {
- Intent intent = new Intent(TelephonyManager.ACTION_CARRIER_SIGNAL_PCO_VALUE);
- intent.putExtra(TelephonyManager.EXTRA_APN_TYPE, 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);
- }
- }
+ onPcoDataChanged(pcoData);
}
}
/**
- * @return The PCO data received from the network.
+ * @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).
*/
public @NonNull Map<Integer, PcoData> getPcoData() {
- return mPcoData;
+ if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN
+ || mCid.get(mTransport) == INVALID_CID) {
+ return Collections.emptyMap();
+ }
+ return mPcoData.getOrDefault(mCid.get(mTransport), Collections.emptyMap());
}
/**
diff --git a/src/java/com/android/internal/telephony/data/DataNetworkController.java b/src/java/com/android/internal/telephony/data/DataNetworkController.java
index 7be0a4d8de..4b02428a10 100644
--- a/src/java/com/android/internal/telephony/data/DataNetworkController.java
+++ b/src/java/com/android/internal/telephony/data/DataNetworkController.java
@@ -1285,21 +1285,37 @@ public class DataNetworkController extends Handler {
}
/**
- * @return {@code true} if checking registration state is needed before setup data network.
- * {@code false} indicates regardless in-service or out-of-service, setup data request will
- * be sent down to the data service.
+ * @param ss The service state to be checked
+ * @param transport The transport is used to determine the data registration state
+ *
+ * @return {@code true} if data is in service or if voice is in service on legacy CS
+ * connections (2G/3G) on the non-DDS. In those cases we attempt to attach PS. We don't try for
+ * newer RAT because for those PS attach already occurred.
*/
- private boolean shouldCheckRegistrationState() {
- // Always don't check registration state on non-DDS sub.
- if (mPhone.getPhoneId() != PhoneSwitcher.getInstance().getPreferredDataPhoneId()) {
- return false;
- }
+ private boolean serviceStateAllowsPSAttach(@NonNull ServiceState ss,
+ @TransportType int transport) {
+ // Use the data registration state from the modem instead of the current data registration
+ // state, which can be overridden.
+ int nriRegState = getDataRegistrationState(ss, transport);
+ if (nriRegState == NetworkRegistrationInfo.REGISTRATION_STATE_HOME
+ || nriRegState == NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING) return true;
- // TODO: Expand this method to support more scenarios if needed. On Android 12 or older
- // Android, auto attach is enabled by default. We dropped that support in Android 13 since
- // it's for the old 2G network. If there are other scenarios that we need to support
- // auto-attach, can implement the logic in this method.
- return true;
+ // If data is OOS on the non-DDS,
+ // attempt to attach PS on 2G/3G if CS connection is available.
+ return ss.getVoiceRegState() == ServiceState.STATE_IN_SERVICE
+ && mPhone.getPhoneId() != PhoneSwitcher.getInstance().getPreferredDataPhoneId()
+ && isLegacyCs(ss.getVoiceNetworkType());
+ }
+
+ /**
+ * @param voiceNetworkType The voice network type to be checked.
+ * @return {@code true} if the network type is on legacy CS connection.
+ */
+ private boolean isLegacyCs(@NetworkType int voiceNetworkType) {
+ int voiceAccessNetworkType = DataUtils.networkTypeToAccessNetworkType(voiceNetworkType);
+ return voiceAccessNetworkType == AccessNetworkType.GERAN
+ || voiceAccessNetworkType == AccessNetworkType.UTRAN
+ || voiceAccessNetworkType == AccessNetworkType.CDMA2000;
}
/**
@@ -1384,10 +1400,7 @@ public class DataNetworkController extends Handler {
return evaluation;
}
- int regState = getDataRegistrationState(transport);
- if (shouldCheckRegistrationState()
- && regState != NetworkRegistrationInfo.REGISTRATION_STATE_HOME
- && regState != NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING) {
+ if (!serviceStateAllowsPSAttach(mServiceState, transport)) {
evaluation.addDataDisallowedReason(DataDisallowedReason.NOT_IN_SERVICE);
}
@@ -1548,7 +1561,7 @@ public class DataNetworkController extends Handler {
+ TelephonyManager.getNetworkTypeName(getDataNetworkType(transport))
+ ", reg state="
+ NetworkRegistrationInfo.registrationStateToString(
- getDataRegistrationState(transport))
+ getDataRegistrationState(mServiceState, transport))
+ ", " + networkRequest);
}
return evaluation;
@@ -2992,7 +3005,7 @@ public class DataNetworkController extends Handler {
}
if (nrAdvancedCapableByPco != mNrAdvancedCapableByPco) {
- log("onPcoDataChanged: mNrAdvancedCapableByPco = " + mNrAdvancedCapableByPco);
+ log("onPcoDataChanged: mNrAdvancedCapableByPco = " + nrAdvancedCapableByPco);
mNrAdvancedCapableByPco = nrAdvancedCapableByPco;
mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
() -> callback.onNrAdvancedCapableByPcoChanged(mNrAdvancedCapableByPco)));
@@ -3064,27 +3077,39 @@ public class DataNetworkController extends Handler {
/**
* Check if needed to re-evaluate the unsatisfied network requests.
*
- * @param oldNri Previous network registration info.
- * @param newNri Current network registration info.
+ * @param oldSS Previous raw service state.
+ * @param newSS Current raw service state.
+ * @param transport The network transport to be checked.
* @return {@code true} if needed to re-evaluate the unsatisfied network requests.
*/
- private boolean shouldReevaluateNetworkRequests(@Nullable NetworkRegistrationInfo oldNri,
- @Nullable NetworkRegistrationInfo newNri) {
- if (newNri == null) return false;
- if (newNri.getAccessNetworkTechnology() == TelephonyManager.NETWORK_TYPE_UNKNOWN) {
+ private boolean shouldReevaluateNetworkRequests(@NonNull ServiceState oldSS,
+ @NonNull ServiceState newSS, @TransportType int transport) {
+ NetworkRegistrationInfo oldPsNri = oldSS.getNetworkRegistrationInfo(
+ NetworkRegistrationInfo.DOMAIN_PS, transport);
+ NetworkRegistrationInfo newPsNri = newSS.getNetworkRegistrationInfo(
+ NetworkRegistrationInfo.DOMAIN_PS, transport);
+
+ if (newPsNri == null) return false;
+ if (newPsNri.getAccessNetworkTechnology() == TelephonyManager.NETWORK_TYPE_UNKNOWN) {
// Sometimes devices temporarily lose signal and RAT becomes unknown. We don't setup
// data in this case.
return false;
}
- if (oldNri == null
- || oldNri.getAccessNetworkTechnology() != newNri.getAccessNetworkTechnology()
- || (!oldNri.isInService() && newNri.isInService())) {
+ if (oldPsNri == null
+ || oldPsNri.getAccessNetworkTechnology() != newPsNri.getAccessNetworkTechnology()
+ || (!oldPsNri.isInService() && newPsNri.isInService())) {
return true;
}
- DataSpecificRegistrationInfo oldDsri = oldNri.getDataSpecificInfo();
- DataSpecificRegistrationInfo newDsri = newNri.getDataSpecificInfo();
+ // If CS connection is back to service on non-DDS, reevaluate for potential PS
+ if (!serviceStateAllowsPSAttach(oldSS, transport)
+ && serviceStateAllowsPSAttach(newSS, transport)) {
+ return true;
+ }
+
+ DataSpecificRegistrationInfo oldDsri = oldPsNri.getDataSpecificInfo();
+ DataSpecificRegistrationInfo newDsri = newPsNri.getDataSpecificInfo();
if (oldDsri == null) return false;
if ((newDsri == null || newDsri.getVopsSupportInfo() == null
@@ -3139,7 +3164,7 @@ public class DataNetworkController extends Handler {
evaluateDataNetworks = true;
}
}
- if (shouldReevaluateNetworkRequests(oldNri, newNri)) {
+ if (shouldReevaluateNetworkRequests(mServiceState, newServiceState, transport)) {
if (!hasMessages(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS)) {
sendMessage(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS,
DataEvaluationReason.DATA_SERVICE_STATE_CHANGED));
@@ -3276,11 +3301,13 @@ public class DataNetworkController extends Handler {
/**
* Get data registration state based on transport.
*
+ * @param ss The service state from which to extract the data registration state.
* @param transport The transport.
* @return The registration state.
*/
- private @RegistrationState int getDataRegistrationState(@TransportType int transport) {
- NetworkRegistrationInfo nri = mServiceState.getNetworkRegistrationInfo(
+ private @RegistrationState int getDataRegistrationState(@NonNull ServiceState ss,
+ @TransportType int transport) {
+ NetworkRegistrationInfo nri = ss.getNetworkRegistrationInfo(
NetworkRegistrationInfo.DOMAIN_PS, transport);
if (nri != null) {
return nri.getRegistrationState();
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 52b487af00..0078277aa7 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
@@ -75,6 +75,7 @@ import android.telephony.SubscriptionInfo;
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;
@@ -478,17 +479,31 @@ public class DataNetworkControllerTest extends TelephonyTest {
new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
LteVopsSupportInfo.LTE_STATUS_SUPPORTED));
- serviceStateChanged(networkType, regState, dsri);
+ serviceStateChanged(networkType, regState, regState,
+ NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
}
private void serviceStateChanged(@NetworkType int networkType,
@RegistrationState int regState, DataSpecificRegistrationInfo dsri) {
+ serviceStateChanged(networkType, regState, regState,
+ NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
+ }
+
+ private void serviceStateChanged(@NetworkType int networkType,
+ @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,
+ LteVopsSupportInfo.LTE_STATUS_SUPPORTED));
+ }
+
ServiceState ss = new ServiceState();
ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.setAccessNetworkTechnology(networkType)
- .setRegistrationState(regState)
+ .setRegistrationState(dataRegState)
.setDomain(NetworkRegistrationInfo.DOMAIN_PS)
.setDataSpecificInfo(dsri)
.build());
@@ -496,18 +511,20 @@ public class DataNetworkControllerTest extends TelephonyTest {
ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN)
- .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
+ .setRegistrationState(iwlanRegState)
.setDomain(NetworkRegistrationInfo.DOMAIN_PS)
.build());
ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.setAccessNetworkTechnology(networkType)
- .setRegistrationState(regState)
+ .setRegistrationState(voiceRegState)
.setDomain(NetworkRegistrationInfo.DOMAIN_CS)
.build());
- ss.setDataRoamingFromRegistration(regState
+ ss.setDataRoamingFromRegistration(dataRegState
== NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
+ processServiceStateRegStateForTest(ss);
+
doReturn(ss).when(mSST).getServiceState();
doReturn(ss).when(mPhone).getServiceState();
@@ -515,6 +532,28 @@ public class DataNetworkControllerTest extends TelephonyTest {
processAllMessages();
}
+ // set SS reg state base on SST impl, where WLAN overrides WWAN's data reg.
+ private void processServiceStateRegStateForTest(ServiceState ss) {
+ int wlanRegState = ss.getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS,
+ AccessNetworkConstants.TRANSPORT_TYPE_WLAN).getRegistrationState();
+ if (wlanRegState == NetworkRegistrationInfo.REGISTRATION_STATE_HOME) {
+ ss.setDataRegState(ServiceState.STATE_IN_SERVICE);
+ } else {
+ int cellularRegState = ss.getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS,
+ AccessNetworkConstants.TRANSPORT_TYPE_WWAN).getRegistrationState();
+ int dataState = (cellularRegState == NetworkRegistrationInfo.REGISTRATION_STATE_HOME
+ || cellularRegState == NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING)
+ ? ServiceState.STATE_IN_SERVICE : ServiceState.STATE_OUT_OF_SERVICE;
+ ss.setDataRegState(dataState);
+ }
+ int voiceRegState = ss.getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_CS,
+ AccessNetworkConstants.TRANSPORT_TYPE_WWAN).getRegistrationState();
+ int voiceState = (voiceRegState == NetworkRegistrationInfo.REGISTRATION_STATE_HOME
+ || voiceRegState == NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING)
+ ? ServiceState.STATE_IN_SERVICE : ServiceState.STATE_OUT_OF_SERVICE;
+ ss.setVoiceRegState(voiceState);
+ }
+
private void updateTransport(@NetCapability int capability, @TransportType int transport) {
doReturn(transport).when(mAccessNetworksManager)
.getPreferredTransportByNetworkCapability(capability);
@@ -2303,6 +2342,76 @@ public class DataNetworkControllerTest extends TelephonyTest {
}
@Test
+ public void testNrAdvancedByEarlyPco() {
+ Mockito.reset(mMockedWwanDataServiceManager);
+ mDataNetworkControllerUT.addNetworkRequest(
+ createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
+ processAllMessages();
+
+ // PCO data arrives before data network entering connected state.
+ mSimulatedCommands.triggerPcoData(1, "IPV6", 1234, new byte[]{1});
+ processAllMessages();
+
+ ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
+ verify(mMockedWwanDataServiceManager).setupDataCall(anyInt(), any(DataProfile.class),
+ anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(), any(), any(), anyBoolean(),
+ messageCaptor.capture());
+
+ // Send setup data call complete message.
+ Message msg = messageCaptor.getValue();
+ msg.getData().putParcelable("data_call_response",
+ createDataCallResponse(1, DataCallResponse.LINK_STATUS_ACTIVE));
+ msg.arg1 = DataServiceCallback.RESULT_SUCCESS;
+ msg.sendToTarget();
+ processAllMessages();
+
+ verify(mMockedDataNetworkControllerCallback).onNrAdvancedCapableByPcoChanged(eq(true));
+ }
+
+ @Test
+ public void testNrAdvancedByPcoMultipleNetworks() throws Exception {
+ testSetupDataNetwork();
+ setSuccessfulSetupDataResponse(mMockedDataServiceManagers
+ .get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN), 2);
+ testSetupImsDataNetwork();
+
+ verify(mMockedDataNetworkControllerCallback, never())
+ .onNrAdvancedCapableByPcoChanged(anyBoolean());
+ mSimulatedCommands.triggerPcoData(2, "IPV6", 1234, new byte[]{1});
+ processAllMessages();
+ verify(mMockedDataNetworkControllerCallback).onNrAdvancedCapableByPcoChanged(eq(true));
+ }
+
+ @Test
+ public void testNrAdvancedByEarlyUnrelatedPco() {
+ Mockito.reset(mMockedWwanDataServiceManager);
+ mDataNetworkControllerUT.addNetworkRequest(
+ createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
+ processAllMessages();
+
+ // Unrelated PCO data arrives before data network entering connected state.
+ mSimulatedCommands.triggerPcoData(2, "IPV6", 1234, new byte[]{1});
+ processAllMessages();
+
+ ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
+ verify(mMockedWwanDataServiceManager).setupDataCall(anyInt(), any(DataProfile.class),
+ anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(), any(), any(), anyBoolean(),
+ messageCaptor.capture());
+
+ // Send setup data call complete message.
+ Message msg = messageCaptor.getValue();
+ msg.getData().putParcelable("data_call_response",
+ createDataCallResponse(1, DataCallResponse.LINK_STATUS_ACTIVE));
+ msg.arg1 = DataServiceCallback.RESULT_SUCCESS;
+ msg.sendToTarget();
+ processAllMessages();
+
+ verify(mMockedDataNetworkControllerCallback, never()).onNrAdvancedCapableByPcoChanged(
+ anyBoolean());
+ }
+
+
+ @Test
public void testSetupDataNetworkVcnManaged() throws Exception {
// VCN managed
setVcnManagerPolicy(true, false);
@@ -2778,6 +2887,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
.setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
.setDomain(NetworkRegistrationInfo.DOMAIN_CS)
.build());
+ processServiceStateRegStateForTest(ss);
doReturn(ss).when(mSST).getServiceState();
doReturn(ss).when(mPhone).getServiceState();
@@ -2827,6 +2937,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
.setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
.setDomain(NetworkRegistrationInfo.DOMAIN_CS)
.build());
+ processServiceStateRegStateForTest(ss);
doReturn(ss).when(mSST).getServiceState();
doReturn(ss).when(mPhone).getServiceState();
@@ -2885,6 +2996,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
.setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
.setDomain(NetworkRegistrationInfo.DOMAIN_CS)
.build());
+ processServiceStateRegStateForTest(ss);
doReturn(ss).when(mSST).getServiceState();
doReturn(ss).when(mPhone).getServiceState();
@@ -2948,6 +3060,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
.setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
.setDomain(NetworkRegistrationInfo.DOMAIN_CS)
.build());
+ processServiceStateRegStateForTest(ss);
doReturn(ss).when(mSST).getServiceState();
doReturn(ss).when(mPhone).getServiceState();
@@ -2994,6 +3107,7 @@ public class DataNetworkControllerTest extends TelephonyTest {
.setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
.setDomain(NetworkRegistrationInfo.DOMAIN_CS)
.build());
+ processServiceStateRegStateForTest(ss);
doReturn(ss).when(mSST).getServiceState();
doReturn(ss).when(mPhone).getServiceState();
@@ -3146,4 +3260,39 @@ public class DataNetworkControllerTest extends TelephonyTest {
// Data should be torn down on this non-preferred sub.
verifyAllDataDisconnected();
}
+
+ @Test
+ public void testSetupDataOnNonDds() throws Exception {
+ // Now DDS switched to phone 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,
+ // data, voice, Iwlan reg state
+ NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING,
+ NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING,
+ NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING, null);
+ mDataNetworkControllerUT.addNetworkRequest(request);
+ processAllMessages();
+
+ 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,
+ 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,
+ NetworkRegistrationInfo.REGISTRATION_STATE_HOME,
+ NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING, null);
+
+ verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_MMS);
+ }
}