Loading src/java/com/android/internal/telephony/NetworkTypeController.java +89 −31 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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"; Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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() { Loading @@ -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() { Loading Loading @@ -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; Loading Loading @@ -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); } Loading Loading @@ -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()) { Loading @@ -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: Loading @@ -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"); Loading Loading @@ -924,8 +953,40 @@ public class NetworkTypeController extends StateMachine { } mIsNrAdvanced = isNrAdvanced(); } } 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); } } // 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; Loading @@ -934,27 +995,24 @@ public class NetworkTypeController extends StateMachine { 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(); 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 final NrConnectedState mNrConnectedState = new NrConnectedState(); private void transitionWithTimerTo(IState destState) { String destName = destState.getName(); OverrideTimerRule rule = mOverrideTimerRules.get(mPreviousState); Loading tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java +73 −17 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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) Loading @@ -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; Loading Loading @@ -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()); Loading Loading @@ -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, Loading @@ -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, Loading @@ -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(); Loading @@ -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)); Loading @@ -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(); Loading @@ -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(); Loading @@ -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 Loading Loading
src/java/com/android/internal/telephony/NetworkTypeController.java +89 −31 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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"; Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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() { Loading @@ -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() { Loading Loading @@ -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; Loading Loading @@ -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); } Loading Loading @@ -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()) { Loading @@ -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: Loading @@ -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"); Loading Loading @@ -924,8 +953,40 @@ public class NetworkTypeController extends StateMachine { } mIsNrAdvanced = isNrAdvanced(); } } 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); } } // 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; Loading @@ -934,27 +995,24 @@ public class NetworkTypeController extends StateMachine { 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(); 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 final NrConnectedState mNrConnectedState = new NrConnectedState(); private void transitionWithTimerTo(IState destState) { String destName = destState.getName(); OverrideTimerRule rule = mOverrideTimerRules.get(mPreviousState); Loading
tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java +73 −17 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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) Loading @@ -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; Loading Loading @@ -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()); Loading Loading @@ -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, Loading @@ -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, Loading @@ -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(); Loading @@ -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)); Loading @@ -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(); Loading @@ -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(); Loading @@ -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 Loading