Update network request evaluation for satellite when data roaming off

Satellite connectivity often comes through partnerships and therefore it gets classified as Data Roaming connection. Due to high cost nature of Data Roaming setting, users generally keep it off. In contrast to high cost of international roaming services, satellite comes with same cost as data plan. So, carriers would want the devices to get connected to satellite even though if data roaming is turned off. Therefore, we are enabling carriers to decide if they want to bypass data roaming for Satellite connectivity. So we are introducing a carrier config. And also updating the evaluate network request of DataNetworkController to incorporate the carrier config check and handling network request evaluation accordingly.

More information could be found at: go/satellite-and-dataroaming

Bug: 381359023
Flag: EXEMPT bugfix
Test: atest CarrierConfigManagerTest DataNetworkControllerTest
Manual test: In mock satellite mode with data roaming off, without the carrier config satellite network request fails whereas with carrier config satellite network request passes

Change-Id: Ieaaabef898002f717325816bf6651cc1f9d97537
diff --git a/flags/satellite.aconfig b/flags/satellite.aconfig
index ee4570e..f043ad9 100644
--- a/flags/satellite.aconfig
+++ b/flags/satellite.aconfig
@@ -81,3 +81,13 @@
   bug: "357638490"
   is_exported: true
 }
+
+# OWNER=karthickmj TARGET=25Q4
+flag {
+
+  name: "satellite_25q4_apis"
+  namespace: "telephony"
+  description: "This flag controls the changes for the new satellite APIs"
+  bug: "383254935"
+  is_exported: true
+}
diff --git a/src/java/com/android/internal/telephony/data/DataConfigManager.java b/src/java/com/android/internal/telephony/data/DataConfigManager.java
index 89b0fec..543f064 100644
--- a/src/java/com/android/internal/telephony/data/DataConfigManager.java
+++ b/src/java/com/android/internal/telephony/data/DataConfigManager.java
@@ -892,6 +892,17 @@
     }
 
     /**
+     * Returns whether the data roaming setting for satellite connection is ignored.
+     *
+     * @return {@code true} if data roaming setting for satellite connection is ignored,
+     * {@code false} otherwise.
+     */
+    public boolean isIgnoringDataRoamingSettingForSatellite() {
+        return mCarrierConfig.getBoolean(
+            CarrierConfigManager.KEY_SATELLITE_IGNORE_DATA_ROAMING_SETTING_BOOL);
+    }
+
+    /**
      * @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/DataNetworkController.java b/src/java/com/android/internal/telephony/data/DataNetworkController.java
index d5bc741..9899405 100644
--- a/src/java/com/android/internal/telephony/data/DataNetworkController.java
+++ b/src/java/com/android/internal/telephony/data/DataNetworkController.java
@@ -1664,7 +1664,11 @@
         }
 
         // Check if data roaming is disabled.
-        if (mServiceState.getDataRoaming() && !mDataSettingsManager.isDataRoamingEnabled()) {
+        // But if the data roaming setting for satellite connection is ignored as the satellite
+        // data plan is included in the user mobile plan, then we should not disallow data due to
+        // roaming disabled.
+        if (mServiceState.getDataRoaming() && !mDataSettingsManager.isDataRoamingEnabled()
+                    && !shouldIgnoreDataRoamingSettingForSatellite()) {
             evaluation.addDataDisallowedReason(DataDisallowedReason.ROAMING_DISABLED);
         }
 
@@ -1811,6 +1815,18 @@
     }
 
     /**
+     * Returns whether the data roaming setting should be ignored for satellite connection,
+     * as the satellite data plan is included in the user mobile plan.
+     *
+     * @return {@code true} if the data roaming setting should be ignored for satellite connection.
+     * {@code false} otherwise.
+     */
+    private boolean shouldIgnoreDataRoamingSettingForSatellite() {
+        return mServiceState.isUsingNonTerrestrialNetwork()
+                && mDataConfigManager.isIgnoringDataRoamingSettingForSatellite();
+    }
+
+    /**
      * This method
      *  - At evaluation network request and evaluation data network determines, if
      *    bootstrap sim current data usage reached bootstrap sim max data limit allowed set
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 4cc10d9..f6fbdf6 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
@@ -1988,6 +1988,194 @@
     }
 
     @Test
+    public void testIgnoreDataRoamingSettingForSatellite() throws Exception {
+        // set up satellite network and register data roaming
+        mIsNonTerrestrialNetwork = true;
+        doReturn(true).when(mServiceState).getDataRoaming();
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
+
+        // Enable data roaming setting
+        mDataNetworkControllerUT.getDataSettingsManager().setDataRoamingEnabled(true);
+
+        // Set network request transport with Internet capability
+        mDataNetworkControllerUT.addNetworkRequest(
+                createNetworkRequest(true,
+                        NetworkCapabilities.NET_CAPABILITY_INTERNET,
+                        NetworkCapabilities.NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED));
+        processAllMessages();
+
+        // Verify internet is connected
+        verifyInternetConnected();
+        Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
+
+        // Disable data roaming setting
+        mDataNetworkControllerUT.getDataSettingsManager().setDataRoamingEnabled(false);
+        processAllMessages();
+
+        // Verify internet is not connected
+        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+        Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
+
+        // Setup carrier to bypass data roaming off setting for satellite network
+        mCarrierConfig.putBoolean(
+                CarrierConfigManager.KEY_SATELLITE_IGNORE_DATA_ROAMING_SETTING_BOOL, true);
+        carrierConfigChanged();
+        processAllMessages();
+
+        // Verify internet is connected
+        verifyInternetConnected();
+        Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
+
+        // reset satellite network and roaming registration
+        mIsNonTerrestrialNetwork = false;
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
+    }
+
+    @Test
+    public void testIgnoreDataRoamingSettingForSatelliteWithBandwithConstrained() throws Exception {
+        // set up satellite network and register data roaming
+        mIsNonTerrestrialNetwork = true;
+        doReturn(true).when(mServiceState).getDataRoaming();
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
+
+        // Enable data roaming setting
+        mDataNetworkControllerUT.getDataSettingsManager().setDataRoamingEnabled(true);
+
+        // Set network request transport with Internet capability
+        mDataNetworkControllerUT.addNetworkRequest(
+                createNetworkRequest(true, NetworkCapabilities.NET_CAPABILITY_INTERNET));
+        processAllMessages();
+
+        // Verify internet is connected
+        verifyInternetConnected();
+        Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
+
+        // Disable data roaming setting
+        mDataNetworkControllerUT.getDataSettingsManager().setDataRoamingEnabled(false);
+        processAllMessages();
+
+        // Verify internet is not connected
+        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+        Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
+
+        // Setup carrier to bypass data roaming off setting for satellite network
+        mCarrierConfig.putBoolean(
+                CarrierConfigManager.KEY_SATELLITE_IGNORE_DATA_ROAMING_SETTING_BOOL, true);
+        carrierConfigChanged();
+        processAllMessages();
+
+        // Verify internet is connected
+        verifyInternetConnected();
+        Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
+
+        // reset satellite network and roaming registration
+        mIsNonTerrestrialNetwork = false;
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
+    }
+
+    @Test
+    public void testIgnoreDataRoamingSettingForSatelliteForUnrestrictedNetwork() throws Exception {
+        // set up satellite network and register data roaming
+        mIsNonTerrestrialNetwork = true;
+        doReturn(true).when(mServiceState).getDataRoaming();
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
+
+        // Disable data roaming setting
+        mDataNetworkControllerUT.getDataSettingsManager().setDataRoamingEnabled(false);
+
+        // Set network request transport with Internet capability
+        mDataNetworkControllerUT.addNetworkRequest(
+                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
+        processAllMessages();
+
+        // Verify internet is not connected
+        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+        Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
+
+        // Setup carrier to bypass data roaming off setting for satellite network
+        mCarrierConfig.putBoolean(
+                CarrierConfigManager.KEY_SATELLITE_IGNORE_DATA_ROAMING_SETTING_BOOL, true);
+        carrierConfigChanged();
+        processAllMessages();
+
+        // Verify internet is still not connected
+        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+        Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
+
+        // Setup satellite data support mode serve all network requests
+        mCarrierConfig.putInt(
+                CarrierConfigManager.KEY_SATELLITE_DATA_SUPPORT_MODE_INT,
+                CarrierConfigManager.SATELLITE_DATA_SUPPORT_ALL);
+        carrierConfigChanged();
+        processAllMessages();
+
+        // Verify internet is connected
+        verifyInternetConnected();
+        Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
+
+        // reset satellite network and roaming registration
+        mIsNonTerrestrialNetwork = false;
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
+    }
+
+    @Test
+    public void testIgnoreDataRoamingSettingForSatelliteConfigForTerrestialNetwork() throws Exception {
+        // set up terrestrial network and roaming registration
+        mIsNonTerrestrialNetwork = false;
+        doReturn(true).when(mServiceState).getDataRoaming();
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
+
+        // Enable data roaming setting
+        mDataNetworkControllerUT.getDataSettingsManager().setDataRoamingEnabled(true);
+
+        // Set network request transport with Internet capability
+        mDataNetworkControllerUT.addNetworkRequest(
+                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
+        processAllMessages();
+
+        // Verify internet is connected
+        verifyInternetConnected();
+        Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
+
+        // Disable data roaming setting
+        mDataNetworkControllerUT.getDataSettingsManager().setDataRoamingEnabled(false);
+        processAllMessages();
+
+        // Verify internet is not connected
+        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+        Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
+
+        // Setup carrier to bypass data roaming off setting for satellite network
+        mCarrierConfig.putBoolean(
+                CarrierConfigManager.KEY_SATELLITE_IGNORE_DATA_ROAMING_SETTING_BOOL, true);
+        carrierConfigChanged();
+        processAllMessages();
+
+        // Verify internet is still not connected
+        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+        Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
+
+        // Enable data roaming again
+        mDataNetworkControllerUT.getDataSettingsManager().setDataRoamingEnabled(true);
+        processAllMessages();
+
+        // Verify internet is connected again
+        verifyInternetConnected();
+        Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
+
+        // reset roaming registration
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
+    }
+
+    @Test
     public void testDataEnabledChanged() throws Exception {
         mDataNetworkControllerUT.getDataSettingsManager().setDataEnabled(
                 TelephonyManager.DATA_ENABLED_REASON_USER, false, mContext.getOpPackageName());