Loading src/java/com/android/internal/telephony/NetworkTypeController.java +25 −3 Original line number Diff line number Diff line Loading @@ -100,8 +100,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_UPDATE_NR_ADVANCED_STATE = 16; private static final String[] sEvents = new String[EVENT_PCO_DATA_CHANGED + 1]; private static final String[] sEvents = new String[EVENT_UPDATE_NR_ADVANCED_STATE + 1]; static { sEvents[EVENT_UPDATE] = "EVENT_UPDATE"; sEvents[EVENT_QUIT] = "EVENT_QUIT"; Loading @@ -119,6 +120,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_UPDATE_NR_ADVANCED_STATE] = "EVENT_UPDATE_NR_ADVANCED_STATE"; } private final Phone mPhone; Loading Loading @@ -218,8 +220,10 @@ public class NetworkTypeController extends StateMachine { IntentFilter filter = new IntentFilter(); filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone); if (!mPhone.isUsingNewDataStack()) { mPhone.mCi.registerForPcoData(getHandler(), EVENT_PCO_DATA_CHANGED, null); } } private void unRegisterForAllEvents() { mPhone.unregisterForRadioOffOrNotAvailable(getHandler()); Loading @@ -230,8 +234,10 @@ public class NetworkTypeController extends StateMachine { mPhone.getServiceStateTracker().unregisterForNrFrequencyChanged(getHandler()); mPhone.getDeviceStateMonitor().unregisterForPhysicalChannelConfigNotifChanged(getHandler()); mPhone.getContext().unregisterReceiver(mIntentReceiver); if (!mPhone.isUsingNewDataStack()) { mPhone.mCi.unregisterForPcoData(getHandler()); } } private void parseCarrierConfigs() { String nrIconConfiguration = CarrierConfigManager.getDefaultConfig().getString( Loading Loading @@ -288,6 +294,18 @@ public class NetworkTypeController extends StateMachine { CarrierConfigManager.KEY_ADDITIONAL_NR_ADVANCED_BANDS_INT_ARRAY); mNrAdvancedCapablePcoId = b.getInt( CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT); if (mNrAdvancedCapablePcoId > 0 && mPhone.isUsingNewDataStack()) { mPhone.getDataNetworkController().registerDataNetworkControllerCallback( new DataNetworkControllerCallback(getHandler()::post) { @Override public void onNrAdvancedCapableByPcoChanged( boolean nrAdvancedCapable) { log("mIsNrAdvancedAllowedByPco=" + nrAdvancedCapable); mIsNrAdvancedAllowedByPco = nrAdvancedCapable; sendMessage(EVENT_UPDATE_NR_ADVANCED_STATE); } }); } mEnableNrAdvancedWhileRoaming = b.getBoolean( CarrierConfigManager.KEY_ENABLE_NR_ADVANCED_WHILE_ROAMING_BOOL); mIsUsingUserDataForRrcDetection = b.getBoolean( Loading Loading @@ -531,6 +549,7 @@ public class NetworkTypeController extends StateMachine { case EVENT_NR_FREQUENCY_CHANGED: case EVENT_PCO_DATA_CHANGED: case EVENT_BANDWIDTH_CHANGED: case EVENT_UPDATE_NR_ADVANCED_STATE: // ignored break; case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED: Loading Loading @@ -885,6 +904,9 @@ public class NetworkTypeController extends StateMachine { case EVENT_PCO_DATA_CHANGED: handlePcoData((AsyncResult) msg.obj); break; case EVENT_UPDATE_NR_ADVANCED_STATE: updateNrAdvancedState(); break; case EVENT_NR_FREQUENCY_CHANGED: case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED: if (isUsingPhysicalChannelConfigForRrcDetection()) { Loading src/java/com/android/internal/telephony/data/DataConfigManager.java +8 −0 Original line number Diff line number Diff line Loading @@ -791,6 +791,14 @@ public class DataConfigManager extends Handler { CarrierConfigManager.KEY_DEFAULT_PREFERRED_APN_NAME_STRING)); } /** * @return The PCO id used for determine if data networks are using NR advanved networks. 0 * indicates this feature is disabled. */ public int getNrAdvancedCapablePcoId() { return mCarrierConfig.getInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT); } /** * Registration point for subscription info ready * Loading src/java/com/android/internal/telephony/data/DataNetwork.java +73 −30 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Intent; import android.net.ConnectivityManager; import android.net.LinkAddress; import android.net.LinkProperties; Loading Loading @@ -48,6 +49,7 @@ import android.telephony.Annotation.ValidationStatus; import android.telephony.DataFailCause; import android.telephony.LinkCapacityEstimate; import android.telephony.NetworkRegistrationInfo; import android.telephony.PcoData; import android.telephony.PreciseDataConnectionState; import android.telephony.ServiceState; import android.telephony.SubscriptionPlan; Loading @@ -63,6 +65,7 @@ import android.telephony.data.NetworkSliceInfo; import android.telephony.data.QosBearerSession; import android.telephony.data.TrafficDescriptor; import android.text.TextUtils; import android.util.ArrayMap; import android.util.IndentingPrintWriter; import android.util.LocalLog; import android.util.Pair; Loading Loading @@ -91,6 +94,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.Executor; Loading Loading @@ -177,6 +181,9 @@ public class DataNetwork extends StateMachine { /** Event for subscription plan changed or unmetered/congested override set. */ private static final int EVENT_SUBSCRIPTION_PLAN_OVERRIDE = 16; /** Event for PCO data received from network. */ private static final int EVENT_PCO_DATA_RECEIVED = 17; /** The default MTU for IPv4 network. */ private static final int DEFAULT_MTU_V4 = 1280; Loading Loading @@ -357,7 +364,7 @@ public class DataNetwork extends StateMachine { * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}. The reason for storing both is that * during handover, both cid will be used. */ private SparseIntArray mCid = new SparseIntArray(2); private final SparseIntArray mCid = new SparseIntArray(2); /** PDU session id. */ private int mPduSessionId = DataCallResponse.PDU_SESSION_ID_NOT_SET; Loading Loading @@ -414,7 +421,8 @@ public class DataNetwork extends StateMachine { private boolean mCongested = false; /** The network requests associated with this data network */ private @NonNull NetworkRequestList mAttachedNetworkRequestList = new NetworkRequestList(); private final @NonNull NetworkRequestList mAttachedNetworkRequestList = new NetworkRequestList(); /** * The latest data call response received from either Loading Loading @@ -443,16 +451,16 @@ public class DataNetwork extends StateMachine { * The current transport of the data network. For handover, the current transport will be set * after handover completes. */ private @TransportType int mTransport = AccessNetworkConstants.TRANSPORT_TYPE_INVALID; private @TransportType int mTransport; /** * The preferred transport of the data network. If the preferred transport is different from * the current transport, then handover will happen. * PCO (Protocol Configuration Options) data received from the network. Key is the PCO id, value * is the PCO content. */ private @TransportType int mPreferredTransport = AccessNetworkConstants.TRANSPORT_TYPE_INVALID; private final @NonNull Map<Integer, PcoData> mPcoData = new ArrayMap<>(); /** The QOS bearer sessions. */ private @NonNull List<QosBearerSession> mQosBearerSessions = new ArrayList<>(); private final @NonNull List<QosBearerSession> mQosBearerSessions = new ArrayList<>(); /** * The network bandwidth. Loading Loading @@ -592,6 +600,13 @@ public class DataNetwork extends StateMachine { */ public abstract void onLinkStatusChanged(@NonNull DataNetwork dataNetwork, @LinkStatus int linkStatus); /** * Called when PCO data changed. * * @param dataNetwork The data network. */ public abstract void onPcoDataChanged(@NonNull DataNetwork dataNetwork); } /** Loading Loading @@ -803,6 +818,7 @@ public class DataNetwork extends StateMachine { case EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED: case EVENT_BANDWIDTH_ESTIMATE_FROM_BANDWIDTH_ESTIMATOR_CHANGED: case EVENT_TEAR_DOWN_NETWORK: case EVENT_PCO_DATA_RECEIVED: // Ignore the events when not in the correct state. break; default: Loading Loading @@ -862,6 +878,7 @@ public class DataNetwork extends StateMachine { break; case EVENT_START_HANDOVER: case EVENT_TEAR_DOWN_NETWORK: case EVENT_PCO_DATA_RECEIVED: // Defer the request until connected or disconnected. deferMessage(msg); break; Loading Loading @@ -947,6 +964,10 @@ 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; default: return NOT_HANDLED; } Loading Loading @@ -985,6 +1006,10 @@ 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; default: return NOT_HANDLED; } Loading Loading @@ -1040,8 +1065,7 @@ public class DataNetwork extends StateMachine { } if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN && mEverConnected) { mKeepaliveTracker.unregisterForKeepaliveStatus(); unregisterForBandwidthUpdate(); unregisterForWwanEvents(); } } Loading @@ -1058,7 +1082,7 @@ public class DataNetwork extends StateMachine { private void registerForWwanEvents() { registerForBandwidthUpdate(); mKeepaliveTracker.registerForKeepaliveStatus(); // Todo: Register for PCO events. mRil.registerForPcoData(this.getHandler(), EVENT_PCO_DATA_RECEIVED, null); } /** Loading @@ -1067,7 +1091,7 @@ public class DataNetwork extends StateMachine { private void unregisterForWwanEvents() { unregisterForBandwidthUpdate(); mKeepaliveTracker.unregisterForKeepaliveStatus(); // Todo: Unregister for PCO events. mRil.unregisterForPcoData(this.getHandler()); } @Override Loading Loading @@ -1245,24 +1269,6 @@ public class DataNetwork extends StateMachine { return mDataProfile; } /** * Update the preferred transport based on the attached network request. */ private void updatePreferredTransports() { if (mAttachedNetworkRequestList.size() == 0) return; // Get the highest priority network request. TelephonyNetworkRequest networkRequest = mAttachedNetworkRequestList.get(0); mPreferredTransport = mAccessNetworksManager.getPreferredTransportByNetworkCapability( networkRequest.getApnTypeNetworkCapability()); if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_INVALID) { mTransport = mPreferredTransport; } // TODO: Compare preferred transport and current transport. If they are different, initiate // handover. } /** * Update data suspended state. */ Loading Loading @@ -1502,7 +1508,8 @@ public class DataNetwork extends StateMachine { mNetworkSliceInfo = response.getSliceInfo(); mQosBearerSessions = response.getQosBearerSessions(); mQosBearerSessions.clear(); mQosBearerSessions.addAll(response.getQosBearerSessions()); if (mQosCallbackTracker != null) { mQosCallbackTracker.updateSessions(mQosBearerSessions); } Loading Loading @@ -2115,6 +2122,7 @@ public class DataNetwork extends StateMachine { updateDataNetwork(response); if (mTransport != AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { // Handover from WWAN to WLAN mPcoData.clear(); unregisterForWwanEvents(); } else { // Handover from WLAN to WWAN Loading @@ -2139,6 +2147,39 @@ public class DataNetwork extends StateMachine { transitionTo(mConnectedState); } /** * 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); 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); } } } } /** * @return The PCO data received from the network. */ public @NonNull Map<Integer, PcoData> getPcoData() { return mPcoData; } /** * Convert the data tear down reason to string. * Loading Loading @@ -2218,6 +2259,8 @@ public class DataNetwork extends StateMachine { return "EVENT_HANDOVER_RESPONSE"; case EVENT_SUBSCRIPTION_PLAN_OVERRIDE: return "EVENT_SUBSCRIPTION_PLAN_OVERRIDE"; case EVENT_PCO_DATA_RECEIVED: return "EVENT_PCO_DATA_RECEIVED"; default: return "Unknown(" + event + ")"; } Loading src/java/com/android/internal/telephony/data/DataNetworkController.java +54 −5 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import android.telephony.CarrierConfigManager; import android.telephony.DataFailCause; import android.telephony.NetworkRegistrationInfo; import android.telephony.NetworkRegistrationInfo.RegistrationState; import android.telephony.PcoData; import android.telephony.ServiceState; import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; Loading Loading @@ -221,19 +222,21 @@ public class DataNetworkController extends Handler { private @NonNull ServiceState mServiceState; /** The list of SubscriptionPlans, updated when initialized and when plans are changed. */ private @NonNull List<SubscriptionPlan> mSubscriptionPlans = new ArrayList<>(); private final @NonNull List<SubscriptionPlan> mSubscriptionPlans = new ArrayList<>(); /** * The set of network types an unmetered override applies to, set by onSubscriptionOverride * and cleared when the device is rebooted or the override expires. */ private @NonNull @NetworkType Set<Integer> mUnmeteredOverrideNetworkTypes = new ArraySet<>(); private final @NonNull @NetworkType Set<Integer> mUnmeteredOverrideNetworkTypes = new ArraySet<>(); /** * The set of network types a congested override applies to, set by onSubscriptionOverride * and cleared when the device is rebooted or the override expires. */ private @NonNull @NetworkType Set<Integer> mCongestedOverrideNetworkTypes = new ArraySet<>(); private final @NonNull @NetworkType Set<Integer> mCongestedOverrideNetworkTypes = new ArraySet<>(); /** * The list of all network requests. Loading Loading @@ -275,6 +278,9 @@ public class DataNetworkController extends Handler { /** Indicates if packet switch data is restricted by the network. */ private boolean mPsRestricted = false; /** Indicates if NR advanced is allowed by PCO. */ private boolean mNrAdvancedCapableByPco = false; /** * Indicates if the data services are bound. Key if the transport type, and value is the boolean * indicating service is bound or not. Loading Loading @@ -520,6 +526,14 @@ public class DataNetworkController extends Handler { * @param status The latest link status. */ public void onPhysicalLinkStatusChanged(@LinkStatus int status) {} /** * Called when NR advanced capable by PCO changed. * * @param nrAdvancedCapable {@code true} if at least one of the data network is NR advanced * capable. */ public void onNrAdvancedCapableByPcoChanged(boolean nrAdvancedCapable) {} } /** Loading Loading @@ -928,7 +942,8 @@ public class DataNetworkController extends Handler { case EVENT_SUBSCRIPTION_PLANS_CHANGED: SubscriptionPlan[] plans = (SubscriptionPlan[]) msg.obj; log("Subscription plans changed: " + Arrays.toString(plans)); mSubscriptionPlans = Arrays.asList(plans); mSubscriptionPlans.clear(); mSubscriptionPlans.addAll(Arrays.asList(plans)); mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( () -> callback.onSubscriptionPlanOverride())); break; Loading Loading @@ -1849,6 +1864,11 @@ public class DataNetworkController extends Handler { @LinkStatus int linkStatus) { DataNetworkController.this.onLinkStatusChanged(dataNetwork, linkStatus); } @Override public void onPcoDataChanged(@NonNull DataNetwork dataNetwork) { DataNetworkController.this.onPcoDataChanged(dataNetwork); } })); if (!mAnyDataNetworkExisting) { mAnyDataNetworkExisting = true; Loading Loading @@ -2244,7 +2264,8 @@ public class DataNetworkController extends Handler { private void updateSubscriptionPlans() { SubscriptionPlan[] plans = mNetworkPolicyManager.getSubscriptionPlans( mSubId, mPhone.getContext().getOpPackageName()); mSubscriptionPlans = plans != null ? Arrays.asList(plans) : Collections.emptyList(); mSubscriptionPlans.clear(); mSubscriptionPlans.addAll(plans != null ? Arrays.asList(plans) : Collections.emptyList()); mCongestedOverrideNetworkTypes.clear(); mUnmeteredOverrideNetworkTypes.clear(); log("Subscription plans initialized: " + mSubscriptionPlans); Loading Loading @@ -2275,6 +2296,34 @@ public class DataNetworkController extends Handler { } } /** * Called when PCO data changed. * * @param dataNetwork The data network. */ private void onPcoDataChanged(@NonNull DataNetwork dataNetwork) { // Check if any data network is using NR advanced bands. int nrAdvancedPcoId = mDataConfigManager.getNrAdvancedCapablePcoId(); if (nrAdvancedPcoId != 0) { boolean nrAdvancedCapableByPco = false; for (DataNetwork network : mDataNetworkList) { PcoData pcoData = network.getPcoData().get(nrAdvancedPcoId); if (pcoData != null && pcoData.contents.length > 0 && pcoData.contents[pcoData.contents.length - 1] == 1) { nrAdvancedCapableByPco = true; break; } } if (nrAdvancedCapableByPco != mNrAdvancedCapableByPco) { log("onPcoDataChanged: mNrAdvancedCapableByPco = " + mNrAdvancedCapableByPco); mNrAdvancedCapableByPco = nrAdvancedCapableByPco; mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( () -> callback.onNrAdvancedCapableByPcoChanged(mNrAdvancedCapableByPco))); } } } /** * Check if needed to re-evaluate the existing data networks. * Loading tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java +8 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.telephony.IccOpenLogicalChannelResponse; import android.telephony.ImsiEncryptionInfo; import android.telephony.NetworkRegistrationInfo; import android.telephony.NetworkScanRequest; import android.telephony.PcoData; import android.telephony.ServiceState; import android.telephony.SignalStrength; import android.telephony.SignalThresholdInfo; Loading Loading @@ -2335,10 +2336,12 @@ public class SimulatedCommands extends BaseCommands @Override public void registerForPcoData(Handler h, int what, Object obj) { mPcoDataRegistrants.addUnique(h, what, obj); } @Override public void unregisterForPcoData(Handler h) { mPcoDataRegistrants.remove(h); } @Override Loading Loading @@ -2499,4 +2502,9 @@ public class SimulatedCommands extends BaseCommands public void notifySimPhonebookChanged() { mSimPhonebookChangedRegistrants.notifyRegistrants(); } public void triggerPcoData(int cid, String bearerProto, int pcoId, byte[] contents) { PcoData response = new PcoData(cid, bearerProto, pcoId, contents); mPcoDataRegistrants.notifyRegistrants(new AsyncResult(null, response, null)); } } Loading
src/java/com/android/internal/telephony/NetworkTypeController.java +25 −3 Original line number Diff line number Diff line Loading @@ -100,8 +100,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_UPDATE_NR_ADVANCED_STATE = 16; private static final String[] sEvents = new String[EVENT_PCO_DATA_CHANGED + 1]; private static final String[] sEvents = new String[EVENT_UPDATE_NR_ADVANCED_STATE + 1]; static { sEvents[EVENT_UPDATE] = "EVENT_UPDATE"; sEvents[EVENT_QUIT] = "EVENT_QUIT"; Loading @@ -119,6 +120,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_UPDATE_NR_ADVANCED_STATE] = "EVENT_UPDATE_NR_ADVANCED_STATE"; } private final Phone mPhone; Loading Loading @@ -218,8 +220,10 @@ public class NetworkTypeController extends StateMachine { IntentFilter filter = new IntentFilter(); filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone); if (!mPhone.isUsingNewDataStack()) { mPhone.mCi.registerForPcoData(getHandler(), EVENT_PCO_DATA_CHANGED, null); } } private void unRegisterForAllEvents() { mPhone.unregisterForRadioOffOrNotAvailable(getHandler()); Loading @@ -230,8 +234,10 @@ public class NetworkTypeController extends StateMachine { mPhone.getServiceStateTracker().unregisterForNrFrequencyChanged(getHandler()); mPhone.getDeviceStateMonitor().unregisterForPhysicalChannelConfigNotifChanged(getHandler()); mPhone.getContext().unregisterReceiver(mIntentReceiver); if (!mPhone.isUsingNewDataStack()) { mPhone.mCi.unregisterForPcoData(getHandler()); } } private void parseCarrierConfigs() { String nrIconConfiguration = CarrierConfigManager.getDefaultConfig().getString( Loading Loading @@ -288,6 +294,18 @@ public class NetworkTypeController extends StateMachine { CarrierConfigManager.KEY_ADDITIONAL_NR_ADVANCED_BANDS_INT_ARRAY); mNrAdvancedCapablePcoId = b.getInt( CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT); if (mNrAdvancedCapablePcoId > 0 && mPhone.isUsingNewDataStack()) { mPhone.getDataNetworkController().registerDataNetworkControllerCallback( new DataNetworkControllerCallback(getHandler()::post) { @Override public void onNrAdvancedCapableByPcoChanged( boolean nrAdvancedCapable) { log("mIsNrAdvancedAllowedByPco=" + nrAdvancedCapable); mIsNrAdvancedAllowedByPco = nrAdvancedCapable; sendMessage(EVENT_UPDATE_NR_ADVANCED_STATE); } }); } mEnableNrAdvancedWhileRoaming = b.getBoolean( CarrierConfigManager.KEY_ENABLE_NR_ADVANCED_WHILE_ROAMING_BOOL); mIsUsingUserDataForRrcDetection = b.getBoolean( Loading Loading @@ -531,6 +549,7 @@ public class NetworkTypeController extends StateMachine { case EVENT_NR_FREQUENCY_CHANGED: case EVENT_PCO_DATA_CHANGED: case EVENT_BANDWIDTH_CHANGED: case EVENT_UPDATE_NR_ADVANCED_STATE: // ignored break; case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED: Loading Loading @@ -885,6 +904,9 @@ public class NetworkTypeController extends StateMachine { case EVENT_PCO_DATA_CHANGED: handlePcoData((AsyncResult) msg.obj); break; case EVENT_UPDATE_NR_ADVANCED_STATE: updateNrAdvancedState(); break; case EVENT_NR_FREQUENCY_CHANGED: case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED: if (isUsingPhysicalChannelConfigForRrcDetection()) { Loading
src/java/com/android/internal/telephony/data/DataConfigManager.java +8 −0 Original line number Diff line number Diff line Loading @@ -791,6 +791,14 @@ public class DataConfigManager extends Handler { CarrierConfigManager.KEY_DEFAULT_PREFERRED_APN_NAME_STRING)); } /** * @return The PCO id used for determine if data networks are using NR advanved networks. 0 * indicates this feature is disabled. */ public int getNrAdvancedCapablePcoId() { return mCarrierConfig.getInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT); } /** * Registration point for subscription info ready * Loading
src/java/com/android/internal/telephony/data/DataNetwork.java +73 −30 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Intent; import android.net.ConnectivityManager; import android.net.LinkAddress; import android.net.LinkProperties; Loading Loading @@ -48,6 +49,7 @@ import android.telephony.Annotation.ValidationStatus; import android.telephony.DataFailCause; import android.telephony.LinkCapacityEstimate; import android.telephony.NetworkRegistrationInfo; import android.telephony.PcoData; import android.telephony.PreciseDataConnectionState; import android.telephony.ServiceState; import android.telephony.SubscriptionPlan; Loading @@ -63,6 +65,7 @@ import android.telephony.data.NetworkSliceInfo; import android.telephony.data.QosBearerSession; import android.telephony.data.TrafficDescriptor; import android.text.TextUtils; import android.util.ArrayMap; import android.util.IndentingPrintWriter; import android.util.LocalLog; import android.util.Pair; Loading Loading @@ -91,6 +94,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.Executor; Loading Loading @@ -177,6 +181,9 @@ public class DataNetwork extends StateMachine { /** Event for subscription plan changed or unmetered/congested override set. */ private static final int EVENT_SUBSCRIPTION_PLAN_OVERRIDE = 16; /** Event for PCO data received from network. */ private static final int EVENT_PCO_DATA_RECEIVED = 17; /** The default MTU for IPv4 network. */ private static final int DEFAULT_MTU_V4 = 1280; Loading Loading @@ -357,7 +364,7 @@ public class DataNetwork extends StateMachine { * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}. The reason for storing both is that * during handover, both cid will be used. */ private SparseIntArray mCid = new SparseIntArray(2); private final SparseIntArray mCid = new SparseIntArray(2); /** PDU session id. */ private int mPduSessionId = DataCallResponse.PDU_SESSION_ID_NOT_SET; Loading Loading @@ -414,7 +421,8 @@ public class DataNetwork extends StateMachine { private boolean mCongested = false; /** The network requests associated with this data network */ private @NonNull NetworkRequestList mAttachedNetworkRequestList = new NetworkRequestList(); private final @NonNull NetworkRequestList mAttachedNetworkRequestList = new NetworkRequestList(); /** * The latest data call response received from either Loading Loading @@ -443,16 +451,16 @@ public class DataNetwork extends StateMachine { * The current transport of the data network. For handover, the current transport will be set * after handover completes. */ private @TransportType int mTransport = AccessNetworkConstants.TRANSPORT_TYPE_INVALID; private @TransportType int mTransport; /** * The preferred transport of the data network. If the preferred transport is different from * the current transport, then handover will happen. * PCO (Protocol Configuration Options) data received from the network. Key is the PCO id, value * is the PCO content. */ private @TransportType int mPreferredTransport = AccessNetworkConstants.TRANSPORT_TYPE_INVALID; private final @NonNull Map<Integer, PcoData> mPcoData = new ArrayMap<>(); /** The QOS bearer sessions. */ private @NonNull List<QosBearerSession> mQosBearerSessions = new ArrayList<>(); private final @NonNull List<QosBearerSession> mQosBearerSessions = new ArrayList<>(); /** * The network bandwidth. Loading Loading @@ -592,6 +600,13 @@ public class DataNetwork extends StateMachine { */ public abstract void onLinkStatusChanged(@NonNull DataNetwork dataNetwork, @LinkStatus int linkStatus); /** * Called when PCO data changed. * * @param dataNetwork The data network. */ public abstract void onPcoDataChanged(@NonNull DataNetwork dataNetwork); } /** Loading Loading @@ -803,6 +818,7 @@ public class DataNetwork extends StateMachine { case EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED: case EVENT_BANDWIDTH_ESTIMATE_FROM_BANDWIDTH_ESTIMATOR_CHANGED: case EVENT_TEAR_DOWN_NETWORK: case EVENT_PCO_DATA_RECEIVED: // Ignore the events when not in the correct state. break; default: Loading Loading @@ -862,6 +878,7 @@ public class DataNetwork extends StateMachine { break; case EVENT_START_HANDOVER: case EVENT_TEAR_DOWN_NETWORK: case EVENT_PCO_DATA_RECEIVED: // Defer the request until connected or disconnected. deferMessage(msg); break; Loading Loading @@ -947,6 +964,10 @@ 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; default: return NOT_HANDLED; } Loading Loading @@ -985,6 +1006,10 @@ 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; default: return NOT_HANDLED; } Loading Loading @@ -1040,8 +1065,7 @@ public class DataNetwork extends StateMachine { } if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN && mEverConnected) { mKeepaliveTracker.unregisterForKeepaliveStatus(); unregisterForBandwidthUpdate(); unregisterForWwanEvents(); } } Loading @@ -1058,7 +1082,7 @@ public class DataNetwork extends StateMachine { private void registerForWwanEvents() { registerForBandwidthUpdate(); mKeepaliveTracker.registerForKeepaliveStatus(); // Todo: Register for PCO events. mRil.registerForPcoData(this.getHandler(), EVENT_PCO_DATA_RECEIVED, null); } /** Loading @@ -1067,7 +1091,7 @@ public class DataNetwork extends StateMachine { private void unregisterForWwanEvents() { unregisterForBandwidthUpdate(); mKeepaliveTracker.unregisterForKeepaliveStatus(); // Todo: Unregister for PCO events. mRil.unregisterForPcoData(this.getHandler()); } @Override Loading Loading @@ -1245,24 +1269,6 @@ public class DataNetwork extends StateMachine { return mDataProfile; } /** * Update the preferred transport based on the attached network request. */ private void updatePreferredTransports() { if (mAttachedNetworkRequestList.size() == 0) return; // Get the highest priority network request. TelephonyNetworkRequest networkRequest = mAttachedNetworkRequestList.get(0); mPreferredTransport = mAccessNetworksManager.getPreferredTransportByNetworkCapability( networkRequest.getApnTypeNetworkCapability()); if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_INVALID) { mTransport = mPreferredTransport; } // TODO: Compare preferred transport and current transport. If they are different, initiate // handover. } /** * Update data suspended state. */ Loading Loading @@ -1502,7 +1508,8 @@ public class DataNetwork extends StateMachine { mNetworkSliceInfo = response.getSliceInfo(); mQosBearerSessions = response.getQosBearerSessions(); mQosBearerSessions.clear(); mQosBearerSessions.addAll(response.getQosBearerSessions()); if (mQosCallbackTracker != null) { mQosCallbackTracker.updateSessions(mQosBearerSessions); } Loading Loading @@ -2115,6 +2122,7 @@ public class DataNetwork extends StateMachine { updateDataNetwork(response); if (mTransport != AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { // Handover from WWAN to WLAN mPcoData.clear(); unregisterForWwanEvents(); } else { // Handover from WLAN to WWAN Loading @@ -2139,6 +2147,39 @@ public class DataNetwork extends StateMachine { transitionTo(mConnectedState); } /** * 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); 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); } } } } /** * @return The PCO data received from the network. */ public @NonNull Map<Integer, PcoData> getPcoData() { return mPcoData; } /** * Convert the data tear down reason to string. * Loading Loading @@ -2218,6 +2259,8 @@ public class DataNetwork extends StateMachine { return "EVENT_HANDOVER_RESPONSE"; case EVENT_SUBSCRIPTION_PLAN_OVERRIDE: return "EVENT_SUBSCRIPTION_PLAN_OVERRIDE"; case EVENT_PCO_DATA_RECEIVED: return "EVENT_PCO_DATA_RECEIVED"; default: return "Unknown(" + event + ")"; } Loading
src/java/com/android/internal/telephony/data/DataNetworkController.java +54 −5 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import android.telephony.CarrierConfigManager; import android.telephony.DataFailCause; import android.telephony.NetworkRegistrationInfo; import android.telephony.NetworkRegistrationInfo.RegistrationState; import android.telephony.PcoData; import android.telephony.ServiceState; import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; Loading Loading @@ -221,19 +222,21 @@ public class DataNetworkController extends Handler { private @NonNull ServiceState mServiceState; /** The list of SubscriptionPlans, updated when initialized and when plans are changed. */ private @NonNull List<SubscriptionPlan> mSubscriptionPlans = new ArrayList<>(); private final @NonNull List<SubscriptionPlan> mSubscriptionPlans = new ArrayList<>(); /** * The set of network types an unmetered override applies to, set by onSubscriptionOverride * and cleared when the device is rebooted or the override expires. */ private @NonNull @NetworkType Set<Integer> mUnmeteredOverrideNetworkTypes = new ArraySet<>(); private final @NonNull @NetworkType Set<Integer> mUnmeteredOverrideNetworkTypes = new ArraySet<>(); /** * The set of network types a congested override applies to, set by onSubscriptionOverride * and cleared when the device is rebooted or the override expires. */ private @NonNull @NetworkType Set<Integer> mCongestedOverrideNetworkTypes = new ArraySet<>(); private final @NonNull @NetworkType Set<Integer> mCongestedOverrideNetworkTypes = new ArraySet<>(); /** * The list of all network requests. Loading Loading @@ -275,6 +278,9 @@ public class DataNetworkController extends Handler { /** Indicates if packet switch data is restricted by the network. */ private boolean mPsRestricted = false; /** Indicates if NR advanced is allowed by PCO. */ private boolean mNrAdvancedCapableByPco = false; /** * Indicates if the data services are bound. Key if the transport type, and value is the boolean * indicating service is bound or not. Loading Loading @@ -520,6 +526,14 @@ public class DataNetworkController extends Handler { * @param status The latest link status. */ public void onPhysicalLinkStatusChanged(@LinkStatus int status) {} /** * Called when NR advanced capable by PCO changed. * * @param nrAdvancedCapable {@code true} if at least one of the data network is NR advanced * capable. */ public void onNrAdvancedCapableByPcoChanged(boolean nrAdvancedCapable) {} } /** Loading Loading @@ -928,7 +942,8 @@ public class DataNetworkController extends Handler { case EVENT_SUBSCRIPTION_PLANS_CHANGED: SubscriptionPlan[] plans = (SubscriptionPlan[]) msg.obj; log("Subscription plans changed: " + Arrays.toString(plans)); mSubscriptionPlans = Arrays.asList(plans); mSubscriptionPlans.clear(); mSubscriptionPlans.addAll(Arrays.asList(plans)); mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( () -> callback.onSubscriptionPlanOverride())); break; Loading Loading @@ -1849,6 +1864,11 @@ public class DataNetworkController extends Handler { @LinkStatus int linkStatus) { DataNetworkController.this.onLinkStatusChanged(dataNetwork, linkStatus); } @Override public void onPcoDataChanged(@NonNull DataNetwork dataNetwork) { DataNetworkController.this.onPcoDataChanged(dataNetwork); } })); if (!mAnyDataNetworkExisting) { mAnyDataNetworkExisting = true; Loading Loading @@ -2244,7 +2264,8 @@ public class DataNetworkController extends Handler { private void updateSubscriptionPlans() { SubscriptionPlan[] plans = mNetworkPolicyManager.getSubscriptionPlans( mSubId, mPhone.getContext().getOpPackageName()); mSubscriptionPlans = plans != null ? Arrays.asList(plans) : Collections.emptyList(); mSubscriptionPlans.clear(); mSubscriptionPlans.addAll(plans != null ? Arrays.asList(plans) : Collections.emptyList()); mCongestedOverrideNetworkTypes.clear(); mUnmeteredOverrideNetworkTypes.clear(); log("Subscription plans initialized: " + mSubscriptionPlans); Loading Loading @@ -2275,6 +2296,34 @@ public class DataNetworkController extends Handler { } } /** * Called when PCO data changed. * * @param dataNetwork The data network. */ private void onPcoDataChanged(@NonNull DataNetwork dataNetwork) { // Check if any data network is using NR advanced bands. int nrAdvancedPcoId = mDataConfigManager.getNrAdvancedCapablePcoId(); if (nrAdvancedPcoId != 0) { boolean nrAdvancedCapableByPco = false; for (DataNetwork network : mDataNetworkList) { PcoData pcoData = network.getPcoData().get(nrAdvancedPcoId); if (pcoData != null && pcoData.contents.length > 0 && pcoData.contents[pcoData.contents.length - 1] == 1) { nrAdvancedCapableByPco = true; break; } } if (nrAdvancedCapableByPco != mNrAdvancedCapableByPco) { log("onPcoDataChanged: mNrAdvancedCapableByPco = " + mNrAdvancedCapableByPco); mNrAdvancedCapableByPco = nrAdvancedCapableByPco; mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor( () -> callback.onNrAdvancedCapableByPcoChanged(mNrAdvancedCapableByPco))); } } } /** * Check if needed to re-evaluate the existing data networks. * Loading
tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java +8 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.telephony.IccOpenLogicalChannelResponse; import android.telephony.ImsiEncryptionInfo; import android.telephony.NetworkRegistrationInfo; import android.telephony.NetworkScanRequest; import android.telephony.PcoData; import android.telephony.ServiceState; import android.telephony.SignalStrength; import android.telephony.SignalThresholdInfo; Loading Loading @@ -2335,10 +2336,12 @@ public class SimulatedCommands extends BaseCommands @Override public void registerForPcoData(Handler h, int what, Object obj) { mPcoDataRegistrants.addUnique(h, what, obj); } @Override public void unregisterForPcoData(Handler h) { mPcoDataRegistrants.remove(h); } @Override Loading Loading @@ -2499,4 +2502,9 @@ public class SimulatedCommands extends BaseCommands public void notifySimPhonebookChanged() { mSimPhonebookChangedRegistrants.notifyRegistrants(); } public void triggerPcoData(int cid, String bearerProto, int pcoId, byte[] contents) { PcoData response = new PcoData(cid, bearerProto, pcoId, contents); mPcoDataRegistrants.notifyRegistrants(new AsyncResult(null, response, null)); } }