Merge "Configure satellite network capabilities" into main
diff --git a/src/java/com/android/internal/telephony/data/DataConfigManager.java b/src/java/com/android/internal/telephony/data/DataConfigManager.java
index 4177cc4..20761e2 100644
--- a/src/java/com/android/internal/telephony/data/DataConfigManager.java
+++ b/src/java/com/android/internal/telephony/data/DataConfigManager.java
@@ -714,8 +714,7 @@
/**
* Update the voice over PS related config from the carrier config.
*/
- private void updateVopsConfig() {
- synchronized (this) {
+ private synchronized void updateVopsConfig() {
mShouldKeepNetworkUpInNonVops = mCarrierConfig.getBoolean(CarrierConfigManager
.Ims.KEY_KEEP_PDN_UP_IN_NO_VOPS_BOOL);
int[] allowedNetworkTypes = mCarrierConfig.getIntArray(
@@ -723,7 +722,6 @@
if (allowedNetworkTypes != null) {
Arrays.stream(allowedNetworkTypes).forEach(mEnabledVopsNetworkTypesInNonVops::add);
}
- }
}
/**
@@ -886,6 +884,14 @@
}
/**
+ * @return What kind of traffic is supported on an unrestricted satellite network.
+ */
+ @CarrierConfigManager.SATELLITE_DATA_SUPPORT_MODE
+ public int getSatelliteDataSupportMode() {
+ return mCarrierConfig.getInt(CarrierConfigManager.KEY_SATELLITE_DATA_SUPPORT_MODE_INT);
+ }
+
+ /**
* @return Whether data throttling should be reset when the TAC changes from the carrier config.
*/
public boolean shouldResetDataThrottlingWhenTacChanges() {
diff --git a/src/java/com/android/internal/telephony/data/DataNetwork.java b/src/java/com/android/internal/telephony/data/DataNetwork.java
index 57d242b..8369874 100644
--- a/src/java/com/android/internal/telephony/data/DataNetwork.java
+++ b/src/java/com/android/internal/telephony/data/DataNetwork.java
@@ -2445,6 +2445,7 @@
}
// Always start with not-restricted, and then remove if needed.
+ // By default, NET_CAPABILITY_NOT_RESTRICTED and NET_CAPABILITY_NOT_CONSTRAINED are included
builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
// When data is disabled, or data roaming is disabled and the device is roaming, we need
@@ -2483,11 +2484,6 @@
builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
}
- // mark the network as restricted when service state is non-terrestrial(satellite network)
- if (mFlags.satelliteInternet() && mIsSatellite) {
- builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
- }
-
// Check if the feature force MMS on IWLAN is enabled. When the feature is enabled, MMS
// will be attempted on IWLAN if possible, even if existing cellular networks already
// supports IWLAN.
@@ -2529,6 +2525,23 @@
builder.setLinkDownstreamBandwidthKbps(mNetworkBandwidth.downlinkBandwidthKbps);
builder.setLinkUpstreamBandwidthKbps(mNetworkBandwidth.uplinkBandwidthKbps);
+ // Configure the network as restricted/constrained for unrestricted satellite network.
+ if (mFlags.satelliteInternet() && mIsSatellite && builder.build()
+ .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)) {
+ switch (mDataConfigManager.getSatelliteDataSupportMode()) {
+ case CarrierConfigManager.SATELLITE_DATA_SUPPORT_ONLY_RESTRICTED
+ -> builder.removeCapability(
+ NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+ case CarrierConfigManager.SATELLITE_DATA_SUPPORT_BANDWIDTH_CONSTRAINED -> {
+ try {
+ builder.removeCapability(DataUtils
+ .NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED);
+ } catch (Exception ignored) { }
+ }
+ // default case CarrierConfigManager.SATELLITE_DATA_SUPPORT_ALL
+ }
+ }
+
NetworkCapabilities nc = builder.build();
if (mNetworkCapabilities == null || mNetworkAgent == null) {
// This is the first time when network capabilities is created. The agent is not created
diff --git a/src/java/com/android/internal/telephony/data/DataNetworkController.java b/src/java/com/android/internal/telephony/data/DataNetworkController.java
index 008da14..30172db 100644
--- a/src/java/com/android/internal/telephony/data/DataNetworkController.java
+++ b/src/java/com/android/internal/telephony/data/DataNetworkController.java
@@ -1947,22 +1947,12 @@
// If the network is satellite, then the network must be restricted.
if (mFeatureFlags.satelliteInternet()) {
// The IWLAN data network should remain intact even when satellite is connected.
- if (dataNetwork.getTransport() != AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
- // On satellite, every data network needs to be restricted.
- if (mServiceState.isUsingNonTerrestrialNetwork()
- && dataNetwork.getNetworkCapabilities()
- .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)) {
- evaluation.addDataDisallowedReason(
- DataDisallowedReason.DATA_NETWORK_TRANSPORT_NOT_ALLOWED);
- }
-
- // Check if the transport is compatible with the network
- if (mServiceState.isUsingNonTerrestrialNetwork() != dataNetwork.isSatellite()) {
- // Since we don't support satellite/cellular network handover, we should always
- // tear down the network when transport changes.
- evaluation.addDataDisallowedReason(
- DataDisallowedReason.DATA_NETWORK_TRANSPORT_NOT_ALLOWED);
- }
+ if (dataNetwork.getTransport() != AccessNetworkConstants.TRANSPORT_TYPE_WLAN
+ && mServiceState.isUsingNonTerrestrialNetwork() != dataNetwork.isSatellite()) {
+ // Since we don't support satellite/cellular network handover, we should always
+ // tear down the network when transport changes.
+ evaluation.addDataDisallowedReason(
+ DataDisallowedReason.DATA_NETWORK_TRANSPORT_NOT_ALLOWED);
}
}
@@ -2171,11 +2161,24 @@
return true;
}
- // When the device is on satellite, only restricted network request can request network.
- if (mServiceState.isUsingNonTerrestrialNetwork()
- && networkRequest.hasCapability(
- NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)) {
- return false;
+ // When the device is on satellite, only restricted/constrained network request can request
+ // network.
+ if (mServiceState.isUsingNonTerrestrialNetwork() && networkRequest.hasCapability(
+ NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)) {
+ switch (mDataConfigManager.getSatelliteDataSupportMode()) {
+ case CarrierConfigManager.SATELLITE_DATA_SUPPORT_ONLY_RESTRICTED -> {
+ return false;
+ }
+ case CarrierConfigManager.SATELLITE_DATA_SUPPORT_BANDWIDTH_CONSTRAINED -> {
+ try {
+ if (networkRequest.hasCapability(DataUtils
+ .NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED)) {
+ return false;
+ }
+ } catch (Exception ignored) { }
+ }
+ // default case CarrierConfigManager.SATELLITE_DATA_SUPPORT_ALL
+ }
}
// If the network request does not specify cellular or satellite, then it can be
diff --git a/src/java/com/android/internal/telephony/data/DataUtils.java b/src/java/com/android/internal/telephony/data/DataUtils.java
index 8b95913..20da97f 100644
--- a/src/java/com/android/internal/telephony/data/DataUtils.java
+++ b/src/java/com/android/internal/telephony/data/DataUtils.java
@@ -59,6 +59,7 @@
* This class contains all the utility methods used by telephony data stack.
*/
public class DataUtils {
+ public static final int NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED = 37;
/** The time format for converting time to readable string. */
private static final SimpleDateFormat TIME_FORMAT =
new SimpleDateFormat("HH:mm:ss.SSS", Locale.US);
@@ -165,6 +166,7 @@
case NetworkCapabilities.NET_CAPABILITY_MMTEL -> "MMTEL";
case NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY -> "PRIORITIZE_LATENCY";
case NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH -> "PRIORITIZE_BANDWIDTH";
+ case NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED -> "NOT_BANDWIDTH_CONSTRAINED";
default -> {
loge("Unknown network capability(" + netCap + ")");
yield "Unknown(" + netCap + ")";
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
index 9d1c05e..60dcb59 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
@@ -5052,18 +5052,84 @@
@Test
public void testNonTerrestrialNetwork() throws Exception {
+ TelephonyNetworkRequest request;
mIsNonTerrestrialNetwork = true;
serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
- mDataNetworkControllerUT.addNetworkRequest(
- createNetworkRequest(false, NetworkCapabilities.NET_CAPABILITY_RCS));
+ // By default, Test only support restricted network, regardless whether constrained.
+ // Verify not_restricted network not supported.
+ request = createNetworkRequest(false, NetworkCapabilities.NET_CAPABILITY_RCS);
+ mDataNetworkControllerUT.addNetworkRequest(request);
processAllMessages();
verifyAllDataDisconnected();
+ mDataNetworkControllerUT.removeNetworkRequest(request);
- mDataNetworkControllerUT.addNetworkRequest(
- createNetworkRequest(true, NetworkCapabilities.NET_CAPABILITY_RCS));
+ // Verify restricted network is supported.
+ request = createNetworkRequest(true, NetworkCapabilities.NET_CAPABILITY_RCS);
+ mDataNetworkControllerUT.addNetworkRequest(request);
processAllMessages();
verifyConnectedNetworkHasDataProfile(mNtnDataProfile);
+ mDataNetworkControllerUT.removeNetworkRequest(request);
+ getDataNetworks().get(0).tearDown(DataNetwork
+ .TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED);
+
+ // Test constrained network is supported, regardless whether it's restricted
+ processAllFutureMessages();
+ verifyAllDataDisconnected();
+ mCarrierConfig.putInt(CarrierConfigManager.KEY_SATELLITE_DATA_SUPPORT_MODE_INT,
+ CarrierConfigManager.SATELLITE_DATA_SUPPORT_BANDWIDTH_CONSTRAINED);
+ carrierConfigChanged();
+ // Verify not_restricted, not_constrained network not supported.
+ NetworkCapabilities netCaps = new NetworkCapabilities();
+ netCaps.addCapability(NetworkCapabilities.NET_CAPABILITY_RCS);
+ try {
+ netCaps.addCapability(DataUtils.NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED);
+ } catch (Exception ignored) { }
+ request = new TelephonyNetworkRequest(new NetworkRequest(netCaps,
+ ConnectivityManager.TYPE_MOBILE, ++mNetworkRequestId,
+ NetworkRequest.Type.REQUEST), mPhone, mFeatureFlags);
+
+ mDataNetworkControllerUT.addNetworkRequest(request);
+ processAllMessages();
+ verifyAllDataDisconnected();
+ mDataNetworkControllerUT.removeNetworkRequest(request);
+
+ // Verify restricted, not_constrained network is supported.
+ netCaps = new NetworkCapabilities();
+ netCaps.addCapability(NetworkCapabilities.NET_CAPABILITY_RCS);
+ netCaps.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+ try {
+ netCaps.addCapability(DataUtils.NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED);
+ } catch (Exception ignored) { }
+ request = new TelephonyNetworkRequest(new NetworkRequest(netCaps,
+ ConnectivityManager.TYPE_MOBILE, ++mNetworkRequestId,
+ NetworkRequest.Type.REQUEST), mPhone, mFeatureFlags);
+ mDataNetworkControllerUT.addNetworkRequest(request);
+ processAllMessages();
+ verifyConnectedNetworkHasDataProfile(mNtnDataProfile);
+ mDataNetworkControllerUT.removeNetworkRequest(request);
+ getDataNetworks().get(0).tearDown(DataNetwork
+ .TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED);
+
+ // TODO(enable after NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED become a default cap)
+ // Test not constrained network supported
+// processAllFutureMessages();
+// verifyAllDataDisconnected();
+// mCarrierConfig.putInt(CarrierConfigManager.KEY_SATELLITE_DATA_SUPPORT_MODE_INT,
+// CarrierConfigManager.SATELLITE_DATA_SUPPORT_ALL);
+// carrierConfigChanged();
+//
+// netCaps = new NetworkCapabilities();
+// netCaps.addCapability(NetworkCapabilities.NET_CAPABILITY_RCS);
+// try {
+// netCaps.addCapability(DataUtils.NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED);
+// } catch (Exception ignored) {}
+// mDataNetworkControllerUT.addNetworkRequest(
+// new TelephonyNetworkRequest(new NetworkRequest(netCaps,
+// ConnectivityManager.TYPE_MOBILE, ++mNetworkRequestId,
+// NetworkRequest.Type.REQUEST), mPhone, mFeatureFlags));
+// processAllMessages();
+// verifyConnectedNetworkHasDataProfile(mNtnDataProfile);
}
@Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
index d5a52ea..7795e42 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
@@ -53,6 +53,7 @@
import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.Annotation;
import android.telephony.Annotation.DataFailureCause;
+import android.telephony.CarrierConfigManager;
import android.telephony.DataFailCause;
import android.telephony.DataSpecificRegistrationInfo;
import android.telephony.LteVopsSupportInfo;
@@ -333,33 +334,40 @@
private void serviceStateChanged(@Annotation.NetworkType int networkType,
@NetworkRegistrationInfo.RegistrationState int regState,
DataSpecificRegistrationInfo dsri, boolean isNtn) {
- ServiceState ss = new ServiceState();
- ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
+ doReturn(isNtn).when(mServiceState).isUsingNonTerrestrialNetwork();
+
+ doReturn(new NetworkRegistrationInfo.Builder()
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.setAccessNetworkTechnology(networkType)
.setRegistrationState(regState)
.setDomain(NetworkRegistrationInfo.DOMAIN_PS)
.setDataSpecificInfo(dsri)
.setIsNonTerrestrialNetwork(isNtn)
- .build());
+ .build()).when(mServiceState)
+ .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS,
+ AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
- ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
+ doReturn(new NetworkRegistrationInfo.Builder()
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
.setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN)
.setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
.setDomain(NetworkRegistrationInfo.DOMAIN_PS)
- .build());
+ .build()).when(mServiceState)
+ .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS,
+ AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
- ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
+ doReturn(new NetworkRegistrationInfo.Builder()
.setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
.setAccessNetworkTechnology(networkType)
.setRegistrationState(regState)
.setDomain(NetworkRegistrationInfo.DOMAIN_CS)
- .build());
- ss.setDataRoamingFromRegistration(regState
- == NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
- doReturn(ss).when(mSST).getServiceState();
- doReturn(ss).when(mPhone).getServiceState();
+ .build()).when(mServiceState)
+ .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_CS,
+ AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+
+ boolean isRoaming = regState == NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING;
+ doReturn(isRoaming).when(mServiceState).getDataRoamingFromRegistration();
+ doReturn(isRoaming).when(mServiceState).getDataRoaming();
if (mDataNetworkUT != null) {
mDataNetworkUT.obtainMessage(9/*EVENT_SERVICE_STATE_CHANGED*/).sendToTarget();
@@ -420,6 +428,8 @@
doReturn(Set.of(NetworkCapabilities.NET_CAPABILITY_IMS,
NetworkCapabilities.NET_CAPABILITY_EIMS, NetworkCapabilities.NET_CAPABILITY_XCAP))
.when(mDataConfigManager).getForcedCellularTransportCapabilities();
+ doReturn(CarrierConfigManager.SATELLITE_DATA_SUPPORT_ONLY_RESTRICTED)
+ .when(mDataConfigManager).getSatelliteDataSupportMode();
doReturn(true).when(mFeatureFlags).carrierEnabledSatelliteFlag();
doReturn(true).when(mFeatureFlags).satelliteInternet();
@@ -2373,6 +2383,7 @@
}
private void setupNonTerrestrialDataNetwork() {
+ doReturn(true).when(mServiceState).isUsingNonTerrestrialNetwork();
NetworkRequestList networkRequestList = new NetworkRequestList();
networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
@@ -2387,6 +2398,8 @@
AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
DataAllowedReason.NORMAL, mDataNetworkCallback);
processAllMessages();
+
+ assertThat(mDataNetworkUT.isSatellite()).isTrue();
}
private void setupTerrestrialDataNetwork() {
@@ -2509,6 +2522,42 @@
}
@Test
+ public void testUnrestrictedSatelliteNetworkCapabilities() {
+ setupNonTerrestrialDataNetwork();
+ assertThat(mDataNetworkUT.isSatellite()).isTrue();
+
+ assertThat(mDataNetworkUT.getNetworkCapabilities()
+ .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)).isFalse();
+
+ // Test constrained traffic
+ doReturn(CarrierConfigManager.SATELLITE_DATA_SUPPORT_BANDWIDTH_CONSTRAINED)
+ .when(mDataConfigManager).getSatelliteDataSupportMode();
+ mDataNetworkUT.sendMessage(22/*EVENT_VOICE_CALL_STARTED*/); // update network capabilities
+ processAllMessages();
+
+ assertThat(mDataNetworkUT.getNetworkCapabilities()
+ .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)).isTrue();
+ try {
+ assertThat(mDataNetworkUT.getNetworkCapabilities()
+ .hasCapability(DataUtils.NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED)).isFalse();
+ } catch (Exception ignored) { }
+
+ // Test not constrained traffic
+ doReturn(CarrierConfigManager.SATELLITE_DATA_SUPPORT_ALL)
+ .when(mDataConfigManager).getSatelliteDataSupportMode();
+ mDataNetworkUT.sendMessage(22/*EVENT_VOICE_CALL_STARTED*/); // update network capabilities
+ processAllMessages();
+
+ assertThat(mDataNetworkUT.getNetworkCapabilities()
+ .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)).isTrue();
+ // TODO(enable after NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED become a default cap)
+// try {
+// assertThat(mDataNetworkUT.getNetworkCapabilities()
+// .hasCapability(DataUtils.NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED)).isTrue();
+// } catch (Exception ignored) {}
+ }
+
+ @Test
public void testIsTransportSatelliteSupportNonImsNonTerrestrialNetwork() throws Exception {
// Service state at Non-terrestrial network
serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,