aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/java/com/android/internal/telephony/NetworkTypeController.java120
-rw-r--r--tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java90
2 files changed, 162 insertions, 48 deletions
diff --git a/src/java/com/android/internal/telephony/NetworkTypeController.java b/src/java/com/android/internal/telephony/NetworkTypeController.java
index 92f277c249..4984d98ac3 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.NonNull;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -33,13 +34,14 @@ 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.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.ArraySet;
-import com.android.internal.telephony.dataconnection.DataConnection;
import com.android.internal.telephony.dataconnection.DcController;
import com.android.internal.telephony.dataconnection.DcController.PhysicalLinkState;
-import com.android.internal.telephony.dataconnection.DcTracker;
+import com.android.internal.telephony.uicc.IccUtils;
import com.android.internal.telephony.util.ArrayUtils;
import com.android.internal.util.IState;
import com.android.internal.util.IndentingPrintWriter;
@@ -54,6 +56,7 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.IntStream;
@@ -99,8 +102,9 @@ public class NetworkTypeController extends StateMachine {
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_DATA_CALL_LIST_CHANGED = 16;
- private static final String[] sEvents = new String[EVENT_PCO_DATA_CHANGED + 1];
+ private static final String[] sEvents = new String[EVENT_DATA_CALL_LIST_CHANGED + 1];
static {
sEvents[EVENT_UPDATE] = "EVENT_UPDATE";
sEvents[EVENT_QUIT] = "EVENT_QUIT";
@@ -118,6 +122,7 @@ public class NetworkTypeController extends StateMachine {
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_DATA_CALL_LIST_CHANGED] = "EVENT_DATA_CALL_LIST_CHANGED";
}
private final Phone mPhone;
@@ -152,6 +157,10 @@ public class NetworkTypeController extends StateMachine {
private boolean mIsPhysicalChannelConfig16Supported;
private Boolean mIsNrAdvancedAllowedByPco = false;
private int mNrAdvancedCapablePcoId = 0;
+ /** The key is the cid, the value is the PCO data. */
+ private final @NonNull Map<Integer, PcoData> mPcoDataMap = new ArrayMap<>();
+ /** Active data connection cid set. */
+ private final @NonNull Set<Integer> mActiveDcCidSet = new ArraySet<>();
private boolean mIsUsingUserDataForRrcDetection = false;
private boolean mEnableNrAdvancedWhileRoaming = true;
@@ -222,7 +231,13 @@ public class NetworkTypeController extends StateMachine {
IntentFilter filter = new IntentFilter();
filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
+
+ // TODO: This is a temporarily solution for S. Ideally PCO and data call list changed event
+ // should not be exposed outside of the data modules. PCO for 5G icon has been well
+ // supported in the new data architecture in T. This temp solution must be removed in T
+ // along with other old data modules.
mPhone.mCi.registerForPcoData(getHandler(), EVENT_PCO_DATA_CHANGED, null);
+ mPhone.mCi.registerForDataCallListChanged(getHandler(), EVENT_DATA_CALL_LIST_CHANGED, null);
}
private void unRegisterForAllEvents() {
@@ -235,6 +250,7 @@ public class NetworkTypeController extends StateMachine {
mPhone.getDeviceStateMonitor().unregisterForPhysicalChannelConfigNotifChanged(getHandler());
mPhone.getContext().unregisterReceiver(mIntentReceiver);
mPhone.mCi.unregisterForPcoData(getHandler());
+ mPhone.mCi.unregisterForDataCallListChanged(getHandler());
}
private void parseCarrierConfigs() {
@@ -518,10 +534,12 @@ public class NetworkTypeController extends StateMachine {
registerForAllEvents();
parseCarrierConfigs();
break;
+ case EVENT_PCO_DATA_CHANGED:
+ handlePcoData((AsyncResult) msg.obj);
+ break;
case EVENT_DATA_RAT_CHANGED:
case EVENT_NR_STATE_CHANGED:
case EVENT_NR_FREQUENCY_CHANGED:
- case EVENT_PCO_DATA_CHANGED:
case EVENT_BANDWIDTH_CHANGED:
// ignored
break;
@@ -563,6 +581,10 @@ public class NetworkTypeController extends StateMachine {
resetAllTimers();
transitionTo(mLegacyState);
break;
+ case EVENT_DATA_CALL_LIST_CHANGED:
+ ar = (AsyncResult) msg.obj;
+ handleDataCallList((List<DataCallResponse>) ar.result);
+ break;
default:
throw new RuntimeException("Received invalid event: " + msg.what);
}
@@ -855,6 +877,7 @@ public class NetworkTypeController extends StateMachine {
if (DBG) log("NrConnectedState: process " + getEventName(msg.what));
updateTimers();
int rat = getDataNetworkType();
+ AsyncResult ar;
switch (msg.what) {
case EVENT_DATA_RAT_CHANGED:
if (rat == TelephonyManager.NETWORK_TYPE_NR || isLte(rat) && isNrConnected()) {
@@ -876,6 +899,12 @@ public class NetworkTypeController extends StateMachine {
break;
case EVENT_PCO_DATA_CHANGED:
handlePcoData((AsyncResult) msg.obj);
+ updateNrAdvancedState();
+ break;
+ case EVENT_DATA_CALL_LIST_CHANGED:
+ ar = (AsyncResult) msg.obj;
+ handleDataCallList((List<DataCallResponse>) ar.result);
+ updateNrAdvancedState();
break;
case EVENT_NR_FREQUENCY_CHANGED:
case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
@@ -885,7 +914,7 @@ public class NetworkTypeController extends StateMachine {
updateNrAdvancedState();
break;
case EVENT_PHYSICAL_LINK_STATE_CHANGED:
- AsyncResult ar = (AsyncResult) msg.obj;
+ ar = (AsyncResult) msg.obj;
mPhysicalLinkState = (int) ar.result;
if (!isNrConnected()) {
log("NR state changed. Sending EVENT_NR_STATE_CHANGED");
@@ -924,36 +953,65 @@ public class NetworkTypeController extends StateMachine {
}
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 : false;
- updateNrAdvancedState();
+ private final NrConnectedState mNrConnectedState = new NrConnectedState();
+
+ // TODO: This is a temporarily solution for S. Ideally PCO and data call list changed event
+ // should not be exposed outside of the data modules. PCO for 5G icon has been well
+ // supported in the new data architecture in T. This temp solution must be removed in T
+ // along with other old data modules.
+ private void handleDataCallList(@NonNull List<DataCallResponse> dataCallResponseList) {
+ if (mNrAdvancedCapablePcoId == 0) return;
+ mActiveDcCidSet.clear();
+ for (DataCallResponse response : dataCallResponseList) {
+ if (response.getLinkStatus() == DataCallResponse.LINK_STATUS_ACTIVE
+ || response.getLinkStatus() == DataCallResponse.LINK_STATUS_DORMANT) {
+ mActiveDcCidSet.add(response.getId());
}
}
+
+ log("Active cids=" + mActiveDcCidSet);
+ boolean nrAdvancedAllowedByPco = mPcoDataMap.values().stream()
+ .anyMatch(pco -> pco.contents[pco.contents.length - 1] == 1
+ && mActiveDcCidSet.contains(pco.cid));
+ if (mIsNrAdvancedAllowedByPco != nrAdvancedAllowedByPco) {
+ mIsNrAdvancedAllowedByPco = nrAdvancedAllowedByPco;
+ log("nrAdvancedAllowedByPco=" + nrAdvancedAllowedByPco);
+ }
}
- private final NrConnectedState mNrConnectedState = new NrConnectedState();
+ // TODO: This is a temporarily solution for S. Ideally PCO and data call list changed event
+ // should not be exposed outside of the data modules. PCO for 5G icon has been well
+ // supported in the new data architecture in T. This temp solution must be removed in T
+ // along with other old data modules.
+ private void handlePcoData(AsyncResult ar) {
+ if (mNrAdvancedCapablePcoId == 0) return;
+ 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 + ", "
+ + IccUtils.bytesToHexString(pcodata.contents));
+ if (pcodata.pcoId != mNrAdvancedCapablePcoId || pcodata.contents == null
+ || pcodata.contents.length == 0) {
+ log("Dropped irrelevant PCO data");
+ return;
+ }
+
+ mPcoDataMap.put(pcodata.cid, pcodata);
+ boolean nrAdvancedAllowedByPco = mPcoDataMap.values().stream()
+ .anyMatch(pco -> pco.contents[pco.contents.length - 1] == 1
+ && mActiveDcCidSet.contains(pco.cid));
+ if (mIsNrAdvancedAllowedByPco != nrAdvancedAllowedByPco) {
+ mIsNrAdvancedAllowedByPco = nrAdvancedAllowedByPco;
+ log("nrAdvancedAllowedByPco=" + nrAdvancedAllowedByPco);
+ }
+ }
private void transitionWithTimerTo(IState destState) {
String destName = destState.getName();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java
index bdd35f1472..d113dece4b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java
@@ -16,13 +16,22 @@
package com.android.internal.telephony;
+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.anyInt;
import static org.mockito.Mockito.doReturn;
+import android.annotation.NonNull;
import android.content.Intent;
+import android.net.InetAddresses;
+import android.net.LinkAddress;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Looper;
@@ -36,6 +45,7 @@ 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;
@@ -52,6 +62,7 @@ import org.mockito.Mock;
import java.lang.reflect.Method;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
@RunWith(AndroidTestingRunner.class)
@@ -71,6 +82,8 @@ public class NetworkTypeControllerTest extends TelephonyTest {
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_DATA_CALL_LIST_CHANGED = 16;
private NetworkTypeController mNetworkTypeController;
private PersistableBundle mBundle;
@@ -99,6 +112,25 @@ public class NetworkTypeControllerTest extends TelephonyTest {
processAllMessages();
}
+ private @NonNull DataCallResponse getDataCallResponse(int cid) {
+ return new DataCallResponse.Builder()
+ .setCause(0)
+ .setRetryDurationMillis(-1)
+ .setId(cid)
+ .setLinkStatus(DataCallResponse.LINK_STATUS_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();
+ }
+
@Before
public void setUp() throws Exception {
super.setUp(getClass().getSimpleName());
@@ -469,11 +501,12 @@ public class NetworkTypeControllerTest extends TelephonyTest {
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);
+ mNetworkTypeController.sendMessage(EVENT_DATA_CALL_LIST_CHANGED,
+ new AsyncResult(null, List.of(getDataCallResponse(cid)), null));
+ processAllMessages();
mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0xFF03);
broadcastCarrierConfigs();
+ processAllMessages();
mNetworkTypeController.sendMessage(EVENT_PCO_DATA_CHANGED,
@@ -494,11 +527,12 @@ public class NetworkTypeControllerTest extends TelephonyTest {
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);
+ mNetworkTypeController.sendMessage(EVENT_DATA_CALL_LIST_CHANGED,
+ new AsyncResult(null, List.of(getDataCallResponse(cid)), null));
+ processAllMessages();
mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0xFF03);
broadcastCarrierConfigs();
+ processAllMessages();
mNetworkTypeController.sendMessage(EVENT_PCO_DATA_CHANGED,
@@ -519,9 +553,8 @@ public class NetworkTypeControllerTest extends TelephonyTest {
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);
+ mNetworkTypeController.sendMessage(EVENT_DATA_CALL_LIST_CHANGED,
+ new AsyncResult(null, List.of(getDataCallResponse(cid)), null));
mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0xFF00);
broadcastCarrierConfigs();
@@ -540,13 +573,37 @@ public class NetworkTypeControllerTest extends TelephonyTest {
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();
+ processAllMessages();
+
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);
+ mNetworkTypeController.sendMessage(EVENT_DATA_CALL_LIST_CHANGED,
+ new AsyncResult(null, List.of(getDataCallResponse(cid)), null));
+
+ 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();
mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0xFF03);
broadcastCarrierConfigs();
+ processAllMessages();
+
+ int cid = 1;
+ byte[] contents = new byte[]{31, 1, 84, 1};
+ mNetworkTypeController.sendMessage(EVENT_DATA_CALL_LIST_CHANGED,
+ new AsyncResult(null, List.of(getDataCallResponse(cid)), null));
mNetworkTypeController.sendMessage(EVENT_PCO_DATA_CHANGED,
new AsyncResult(null, new PcoData(cid, "", 0xff03, contents), null));
@@ -556,7 +613,7 @@ public class NetworkTypeControllerTest extends TelephonyTest {
}
@Test
- public void testTransitionToCurrentStateNrConnectedWithNrAdvancedCapableAndPcoLength4()
+ public void testTransitionToCurrentStateNrConnectedWithNrAdvancedCapableButCidNotMatched()
throws Exception {
assertEquals("DefaultState", getCurrentState().getName());
doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
@@ -564,9 +621,8 @@ public class NetworkTypeControllerTest extends TelephonyTest {
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);
+ mNetworkTypeController.sendMessage(EVENT_DATA_CALL_LIST_CHANGED,
+ new AsyncResult(null, List.of(getDataCallResponse(2)), null));
mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0xFF03);
broadcastCarrierConfigs();
@@ -574,7 +630,7 @@ public class NetworkTypeControllerTest extends TelephonyTest {
new AsyncResult(null, new PcoData(cid, "", 0xff03, contents), null));
mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
processAllMessages();
- assertEquals("connected_mmwave", getCurrentState().getName());
+ assertEquals("connected", getCurrentState().getName());
}
@Test