aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-08-29 01:33:05 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-08-29 01:33:05 +0000
commit2ad8d21c67d1ec39be6f4c91ce435b17f52eb7c6 (patch)
tree5d7e78f6893db08d7fdbce195a575187593abcca
parenta9ff1ec7cdefa1167605a3b509ed0d7aa4bd2d4e (diff)
parent685ca30a1eb4c87fd27bd08d2c944623459402c0 (diff)
downloadtelephony-android-13.0.0_r14.tar.gz
Change-Id: Ifa4085d2f4a891eab1dc01975ba9abd7dbc89488
-rw-r--r--src/java/com/android/internal/telephony/data/DataNetwork.java90
-rw-r--r--src/java/com/android/internal/telephony/data/DataNetworkController.java2
-rw-r--r--tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java70
3 files changed, 126 insertions, 36 deletions
diff --git a/src/java/com/android/internal/telephony/data/DataNetwork.java b/src/java/com/android/internal/telephony/data/DataNetwork.java
index 4e45a8b24d..8581759dc0 100644
--- a/src/java/com/android/internal/telephony/data/DataNetwork.java
+++ b/src/java/com/android/internal/telephony/data/DataNetwork.java
@@ -644,10 +644,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<>();
@@ -1009,6 +1009,8 @@ public class DataNetwork extends StateMachine {
sendMessage(EVENT_DATA_CONFIG_UPDATED);
}
};
+ mRil.registerForPcoData(getHandler(), EVENT_PCO_DATA_RECEIVED, null);
+
mDataConfigManager.registerCallback(mDataConfigManagerCallback);
mPhone.getDisplayInfoController().registerForTelephonyDisplayInfoChanged(
getHandler(), EVENT_DISPLAY_INFO_CHANGED, null);
@@ -1061,6 +1063,7 @@ public class DataNetwork extends StateMachine {
mPhone.getServiceStateTracker().unregisterForServiceStateChanged(getHandler());
mPhone.getDisplayInfoController().unregisterForTelephonyDisplayInfoChanged(
getHandler());
+ mRil.unregisterForPcoData(getHandler());
mDataConfigManager.unregisterCallback(mDataConfigManagerCallback);
}
@@ -1108,12 +1111,16 @@ public class DataNetwork extends StateMachine {
updateNetworkCapabilities();
break;
}
+ case EVENT_PCO_DATA_RECEIVED: {
+ AsyncResult ar = (AsyncResult) msg.obj;
+ onPcoDataReceived((PcoData) ar.result);
+ break;
+ }
case EVENT_NOTIFY_HANDOVER_CANCELLED_RESPONSE:
log("Notified handover cancelled.");
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:
@@ -1193,7 +1200,6 @@ public class DataNetwork extends StateMachine {
break;
case EVENT_NOTIFY_HANDOVER_STARTED:
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));
@@ -1260,6 +1266,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();
}
@@ -1323,10 +1336,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);
@@ -1400,10 +1409,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:
// enable detection only for valid timeout range
reportAnomaly("Data service did not respond the handover request within "
@@ -1593,7 +1598,6 @@ public class DataNetwork extends StateMachine {
private void registerForWwanEvents() {
registerForBandwidthUpdate();
mKeepaliveTracker.registerForKeepaliveStatus();
- mRil.registerForPcoData(this.getHandler(), EVENT_PCO_DATA_RECEIVED, null);
}
/**
@@ -1602,7 +1606,6 @@ public class DataNetwork extends StateMachine {
private void unregisterForWwanEvents() {
unregisterForBandwidthUpdate();
mKeepaliveTracker.unregisterForKeepaliveStatus();
- mRil.unregisterForPcoData(this.getHandler());
}
@Override
@@ -3166,8 +3169,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
@@ -3202,34 +3203,53 @@ public class DataNetwork extends StateMachine {
/**
* Called when receiving PCO (Protocol Configuration Options) data from the cellular network.
*
+ * @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 729c97ea26..ba075a1c7d 100644
--- a/src/java/com/android/internal/telephony/data/DataNetworkController.java
+++ b/src/java/com/android/internal/telephony/data/DataNetworkController.java
@@ -3030,7 +3030,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)));
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 2db1560001..0fc6c3c780 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
@@ -2375,6 +2375,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);