Merge "Avoid PDN Tear down at Out of service scenario" into main
diff --git a/src/java/com/android/internal/telephony/data/DataNetworkController.java b/src/java/com/android/internal/telephony/data/DataNetworkController.java
index 00612f7..6b916f2 100644
--- a/src/java/com/android/internal/telephony/data/DataNetworkController.java
+++ b/src/java/com/android/internal/telephony/data/DataNetworkController.java
@@ -1640,8 +1640,14 @@
             evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_CONFIG_NOT_READY);
         }
 
-        if (mFeatureFlags.dataServiceCheck() && !isDataServiceSupported(transport)) {
-            evaluation.addDataDisallowedReason(DataDisallowedReason.SERVICE_OPTION_NOT_SUPPORTED);
+        if (mFeatureFlags.dataServiceCheck()) {
+            NetworkRegistrationInfo nri = mServiceState.getNetworkRegistrationInfo(
+                    NetworkRegistrationInfo.DOMAIN_PS, transport);
+            if (nri != null && !nri.getAvailableServices().contains(
+                    NetworkRegistrationInfo.SERVICE_TYPE_DATA)) {
+                evaluation.addDataDisallowedReason(
+                        DataDisallowedReason.SERVICE_OPTION_NOT_SUPPORTED);
+            }
         }
 
         // Check CS call state and see if concurrent voice/data is allowed.
@@ -1977,9 +1983,14 @@
             evaluation.addDataDisallowedReason(DataDisallowedReason.CDMA_EMERGENCY_CALLBACK_MODE);
         }
 
-        if (mFeatureFlags.dataServiceCheck()
-                && !isDataServiceSupported(dataNetwork.getTransport())) {
-            evaluation.addDataDisallowedReason(DataDisallowedReason.SERVICE_OPTION_NOT_SUPPORTED);
+        if (mFeatureFlags.dataServiceCheck()) {
+            NetworkRegistrationInfo nri = mServiceState.getNetworkRegistrationInfo(
+                    NetworkRegistrationInfo.DOMAIN_PS, dataNetwork.getTransport());
+            if (nri != null && nri.isInService() && !nri.getAvailableServices().contains(
+                    NetworkRegistrationInfo.SERVICE_TYPE_DATA)) {
+                evaluation.addDataDisallowedReason(
+                        DataDisallowedReason.SERVICE_OPTION_NOT_SUPPORTED);
+            }
         }
 
         // If the network is satellite, then the network must be restricted.
@@ -2177,21 +2188,6 @@
     }
 
     /**
-     * Check if the available services support data service.
-     * {@link NetworkRegistrationInfo#SERVICE_TYPE_DATA} service or not.
-     *
-     * @param transport The preferred transport type for the request. The transport here is
-     * WWAN/WLAN.
-     * @return {@code true} if data services is supported, otherwise {@code false}.
-     */
-    private boolean isDataServiceSupported(@TransportType int transport) {
-        NetworkRegistrationInfo nri = mServiceState.getNetworkRegistrationInfo(
-                    NetworkRegistrationInfo.DOMAIN_PS, transport);
-        return nri != null && nri.getAvailableServices().contains(
-                    NetworkRegistrationInfo.SERVICE_TYPE_DATA);
-    }
-
-    /**
      * Check if the transport from connectivity service can satisfy the network request. Note the
      * transport here is connectivity service's transport (Wifi, cellular, satellite, etc..), not
      * the widely used {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN WLAN},
@@ -3803,6 +3799,22 @@
     }
 
     /**
+     * Check if network available services list is changed
+     *
+     * @param oldNri Previous network registration info.
+     * @param newNri Current network registration info.
+     * @return {@code true} if available services list is changed else return false
+     */
+    private boolean areNetworkAvailableServicesChanged(@NonNull NetworkRegistrationInfo oldNri,
+            @NonNull NetworkRegistrationInfo newNri) {
+        List<Integer> oldAvailableServicesList = oldNri.getAvailableServices();
+        List<Integer> newAvailableServicesList = newNri.getAvailableServices();
+
+        return !(oldAvailableServicesList.size() == newAvailableServicesList.size()
+                && oldAvailableServicesList.stream().allMatch(newAvailableServicesList::contains));
+    }
+
+    /**
      * Check if needed to re-evaluate the existing data networks.
      *
      * @param oldNri Previous network registration info.
@@ -3818,6 +3830,10 @@
             return false;
         }
 
+        if (areNetworkAvailableServicesChanged(oldNri, newNri)) {
+            return true;
+        }
+
         if (oldNri.getAccessNetworkTechnology() != newNri.getAccessNetworkTechnology()
                 // Some CarrierConfig disallows vops in nonVops area for specified home/roaming.
                 || (oldNri.isRoaming() != newNri.isRoaming())) {
@@ -3863,6 +3879,10 @@
             return false;
         }
 
+        if (areNetworkAvailableServicesChanged(oldPsNri, newPsNri)) {
+            return true;
+        }
+
         if (oldPsNri == null
                 || oldPsNri.getAccessNetworkTechnology() != newPsNri.getAccessNetworkTechnology()
                 || (!oldPsNri.isInService() && newPsNri.isInService())
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 0ac0b0e..a7bd9bc 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
@@ -186,7 +186,7 @@
     private LinkBandwidthEstimatorCallback mLinkBandwidthEstimatorCallback;
 
     private boolean mIsNonTerrestrialNetwork = false;
-    private ArrayList<Integer> mCarrierSupportedSatelliteServices = new ArrayList<>();
+    private ArrayList<Integer> mCarrierSupportedServices = new ArrayList<>();
 
     private final DataProfile mGeneralPurposeDataProfile = new DataProfile.Builder()
             .setApnSetting(new ApnSetting.Builder()
@@ -692,7 +692,7 @@
                 .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
                 .setDataSpecificInfo(dsri)
                 .setIsNonTerrestrialNetwork(mIsNonTerrestrialNetwork)
-                .setAvailableServices(mCarrierSupportedSatelliteServices)
+                .setAvailableServices(mCarrierSupportedServices)
                 .setEmergencyOnly(isEmergencyOnly)
                 .build());
 
@@ -702,7 +702,7 @@
                 .setRegistrationState(iwlanRegState)
                 .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
                 .setIsNonTerrestrialNetwork(mIsNonTerrestrialNetwork)
-                .setAvailableServices(mCarrierSupportedSatelliteServices)
+                .setAvailableServices(mCarrierSupportedServices)
                 .setEmergencyOnly(isEmergencyOnly)
                 .build());
 
@@ -1124,7 +1124,7 @@
         doReturn(CarrierConfigManager.SATELLITE_DATA_SUPPORT_ONLY_RESTRICTED)
                 .when(mSatelliteController)
                 .getSatelliteDataServicePolicyForPlmn(anyInt(), any());
-        mCarrierSupportedSatelliteServices.add(NetworkRegistrationInfo.SERVICE_TYPE_DATA);
+        mCarrierSupportedServices.add(NetworkRegistrationInfo.SERVICE_TYPE_DATA);
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
         logd("DataNetworkControllerTest -Setup!");
@@ -1538,10 +1538,8 @@
     public void testMovingFromInServiceToNoService() throws Exception {
         testSetupDataNetwork();
 
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING);
-        // Verify we don't tear down the data network.
-        verifyInternetConnected();
+        // clear available services at no service
+        mCarrierSupportedServices.clear();
 
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_UNKNOWN,
                 NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING);
@@ -1550,6 +1548,137 @@
     }
 
     @Test
+    public void testInServiceAvailableServicesChanged() throws Exception {
+        testSetupDataNetwork();
+
+        List<DataDisallowedReason> reasons = mDataNetworkControllerUT
+                .getInternetDataDisallowedReasons();
+        assertThat(reasons).isEmpty();
+
+        // Add available services sms to existing available services with data
+        mCarrierSupportedServices.add(NetworkRegistrationInfo.SERVICE_TYPE_SMS);
+
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
+
+        // Verify we don't tear down the data network.
+        verifyInternetConnected();
+
+
+        mCarrierSupportedServices.clear();
+        // Add available services data and mms
+        mCarrierSupportedServices.add(NetworkRegistrationInfo.SERVICE_TYPE_DATA);
+        mCarrierSupportedServices.add(NetworkRegistrationInfo.SERVICE_TYPE_MMS);
+
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
+
+        // Verify we don't tear down the data network.
+        verifyInternetConnected();
+
+        // clear all available services
+        mCarrierSupportedServices.clear();
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
+
+        // Verify internet is not connected
+        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+
+        reasons = mDataNetworkControllerUT.getInternetDataDisallowedReasons();
+        assertThat(reasons).contains(DataDisallowedReason.SERVICE_OPTION_NOT_SUPPORTED);
+
+    }
+
+    @Test
+    public void testHomeToRoamingAvailableServicesChangedWithDataRoamingDisabled()
+            throws Exception {
+        testSetupDataNetwork();
+
+        List<DataDisallowedReason> reasons = mDataNetworkControllerUT
+                .getInternetDataDisallowedReasons();
+        assertThat(reasons).isEmpty();
+
+        // Disable data roaming setting
+        mDataNetworkControllerUT.getDataSettingsManager().setDataRoamingEnabled(false);
+
+        // Home to roaming with same available services
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
+
+        // Verify internet is not connected due to roaming disabled
+        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+
+        reasons = mDataNetworkControllerUT.getInternetDataDisallowedReasons();
+        assertThat(reasons).contains(DataDisallowedReason.ROAMING_DISABLED);
+    }
+
+    @Test
+    public void testHomeToRoamingAvailableServicesChangedWithDataRoamingEnabled()
+            throws Exception {
+        testSetupDataNetwork();
+
+        List<DataDisallowedReason> reasons = mDataNetworkControllerUT
+                .getInternetDataDisallowedReasons();
+        assertThat(reasons).isEmpty();
+
+        // Enable data roaming setting
+        mDataNetworkControllerUT.getDataSettingsManager().setDataRoamingEnabled(true);
+
+        // Home to roaming with same available services
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
+
+        // Verify we don't tear down the data network since available services as still data
+        // with data roaming enabled
+        verifyInternetConnected();
+
+        // clear all available services
+        mCarrierSupportedServices.clear();
+        // At roaming
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
+
+        // Verify internet is not connected
+        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+
+        reasons = mDataNetworkControllerUT.getInternetDataDisallowedReasons();
+        assertThat(reasons).contains(DataDisallowedReason.SERVICE_OPTION_NOT_SUPPORTED);
+    }
+
+    @Test
+    public void testOnAvailableServiceChanged_WithReevaluateNetworkRequest()
+            throws Exception {
+        // clear available services at no service
+        mCarrierSupportedServices.clear();
+
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
+
+        // Set network request transport with Internet capability
+        mDataNetworkControllerUT.addNetworkRequest(
+                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
+        processAllMessages();
+
+        // Verify internet is not connected due to roaming disabled
+        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+
+        List<DataDisallowedReason> reasons = mDataNetworkControllerUT
+                .getInternetDataDisallowedReasons();
+        assertThat(reasons).contains(DataDisallowedReason.SERVICE_OPTION_NOT_SUPPORTED);
+
+        // add available services with data, re-evaluate network request
+        mCarrierSupportedServices.add(NetworkRegistrationInfo.SERVICE_TYPE_DATA);
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
+
+        // Verify now internet was connected
+        verifyInternetConnected();
+
+        reasons = mDataNetworkControllerUT.getInternetDataDisallowedReasons();
+        assertThat(reasons).isEmpty();
+    }
+
+    @Test
     public void testPsRestrictedAndLifted() throws Exception {
         testSetupDataNetwork();
         Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
@@ -1572,7 +1701,6 @@
         verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
         verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_INTERNET);
 
-
         // PS unrestricted, new setup is allowed
         mDataNetworkControllerUT.obtainMessage(7/*EVENT_PS_RESTRICT_DISABLED*/).sendToTarget();
         processAllMessages();
@@ -2129,7 +2257,7 @@
 
         // reset satellite network and roaming registration
         mIsNonTerrestrialNetwork = false;
-        mCarrierSupportedSatelliteServices.clear();
+        mCarrierSupportedServices.clear();
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
     }
@@ -5846,8 +5974,8 @@
     @Test
     public void testNotRestrictedDataConnectionRequest_WithoutDataServiceSupport()
             throws Exception {
-        mCarrierSupportedSatelliteServices.clear();
-        mCarrierSupportedSatelliteServices.add(NetworkRegistrationInfo.SERVICE_TYPE_VOICE);
+        mCarrierSupportedServices.clear();
+        mCarrierSupportedServices.add(NetworkRegistrationInfo.SERVICE_TYPE_VOICE);
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
 
@@ -5863,7 +5991,7 @@
         Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
 
         // reset satellite network and roaming registration
-        mCarrierSupportedSatelliteServices.clear();
+        mCarrierSupportedServices.clear();
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
     }
@@ -5872,8 +6000,8 @@
     public void testConnection_WithDataServiceCheckFlagDisabled_WithoutDataServiceSupport()
             throws Exception {
         doReturn(false).when(mFeatureFlags).dataServiceCheck();
-        mCarrierSupportedSatelliteServices.clear();
-        mCarrierSupportedSatelliteServices.add(NetworkRegistrationInfo.SERVICE_TYPE_VOICE);
+        mCarrierSupportedServices.clear();
+        mCarrierSupportedServices.add(NetworkRegistrationInfo.SERVICE_TYPE_VOICE);
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
 
@@ -5889,7 +6017,7 @@
         Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
 
         // reset satellite network and roaming registration
-        mCarrierSupportedSatelliteServices.clear();
+        mCarrierSupportedServices.clear();
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
     }
@@ -5897,8 +6025,8 @@
     @Test
     public void testRestrictedDataConnectionRequest_WithoutDataServiceSupport()
             throws Exception {
-        mCarrierSupportedSatelliteServices.clear();
-        mCarrierSupportedSatelliteServices.add(NetworkRegistrationInfo.SERVICE_TYPE_VOICE);
+        mCarrierSupportedServices.clear();
+        mCarrierSupportedServices.add(NetworkRegistrationInfo.SERVICE_TYPE_VOICE);
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
 
@@ -5918,7 +6046,7 @@
         Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
 
         // reset satellite network and roaming registration
-        mCarrierSupportedSatelliteServices.clear();
+        mCarrierSupportedServices.clear();
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
     }
@@ -5947,7 +6075,7 @@
 
         // reset satellite network and roaming registration
         mIsNonTerrestrialNetwork = false;
-        mCarrierSupportedSatelliteServices.clear();
+        mCarrierSupportedServices.clear();
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
     }
@@ -5982,7 +6110,7 @@
 
         // reset satellite network and roaming registration
         mIsNonTerrestrialNetwork = false;
-        mCarrierSupportedSatelliteServices.clear();
+        mCarrierSupportedServices.clear();
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
     }
@@ -6017,7 +6145,7 @@
 
         // reset satellite network and roaming registration
         mIsNonTerrestrialNetwork = false;
-        mCarrierSupportedSatelliteServices.clear();
+        mCarrierSupportedServices.clear();
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
     }
@@ -6053,7 +6181,7 @@
 
         // reset satellite network and roaming registration
         mIsNonTerrestrialNetwork = false;
-        mCarrierSupportedSatelliteServices.clear();
+        mCarrierSupportedServices.clear();
         serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
     }