Merge "Apply Location Information Encryption" into main
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index ab677d5..095bf9c 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -83,7 +83,7 @@
     <string name="make_and_receive_calls" msgid="4868913166494621109">"कल गर्नुहोस् र प्राप्त गर्नुहोस्"</string>
     <string name="smart_forwarding_settings_menu" msgid="8850429887958938540">"स्मार्ट तरिकाले फर्वार्ड गर्ने सुविधा"</string>
     <string name="smart_forwarding_settings_menu_summary" msgid="5096947726032885325">"एउटा नम्बर सम्पर्क क्षेत्रबाहिर भएका बेला कल सधैँ आफ्नो अर्को नम्बरमा फर्वार्ड गर्नुहोस्"</string>
-    <string name="voicemail_notifications_preference_title" msgid="7829238858063382977">"सूचनाहरू"</string>
+    <string name="voicemail_notifications_preference_title" msgid="7829238858063382977">"नोटिफिकेसनहरू"</string>
     <string name="cell_broadcast_settings" msgid="8135324242541809924">"आपत्‌कालीन प्रसारणहरू"</string>
     <string name="call_settings" msgid="3677282690157603818">"कल सेटिङहरू"</string>
     <string name="additional_gsm_call_settings" msgid="1561980168685658846">"अतिरिक्त सेटिङहरू"</string>
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index a3d8baf..0548aa5 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -15017,4 +15017,25 @@
             Binder.restoreCallingIdentity(identity);
         }
     }
+
+    /**
+     * Get list of applications that are optimized for low bandwidth satellite data.
+     *
+     * @return List of Application Name with data optimized network property.
+     * {@link #PROPERTY_SATELLITE_DATA_OPTIMIZED}
+     */
+    @Override
+    public List<String> getSatelliteDataOptimizedApps() {
+        enforceSatelliteCommunicationPermission("getSatelliteDataOptimizedApps");
+        List<String> appNames = new ArrayList<>();
+        int userId = Binder.getCallingUserHandle().getIdentifier();
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            appNames = mSatelliteController.getSatelliteDataOptimizedApps(userId);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+
+        return appNames;
+    }
 }
diff --git a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
index b713a2c..b490b35 100644
--- a/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
+++ b/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java
@@ -278,6 +278,7 @@
     @NonNull
     private List<String> mSatelliteCountryCodes;
     private boolean mIsSatelliteAllowAccessControl;
+    protected int mSatelliteAccessConfigVersion;
     @Nullable
     private File mSatelliteS2CellFile;
     @Nullable
@@ -358,6 +359,8 @@
             "config_updater_satellite_country_codes";
     private static final String CONFIG_UPDATER_SATELLITE_IS_ALLOW_ACCESS_CONTROL_KEY =
             "config_updater_satellite_is_allow_access_control";
+    protected static final String CONFIG_UPDATER_SATELLITE_VERSION_KEY =
+            "config_updater_satellite_version";
 
     private static final String LATEST_SATELLITE_COMMUNICATION_ALLOWED_SET_TIME_KEY =
             "latest_satellite_communication_allowed_set_time";
@@ -432,7 +435,7 @@
                     plogd("Location settings is just enabled");
                     sendRequestAsync(EVENT_LOCATION_SETTINGS_ENABLED, null);
                 } else {
-                    plogd("Location settings is just enabled");
+                    plogd("Location settings is just disabled");
                     sendRequestAsync(EVENT_LOCATION_SETTINGS_DISABLED, null);
                 }
             }
@@ -1088,19 +1091,21 @@
         }
     }
 
-    private void deleteSharedPreferencesCountryCodes(@NonNull Context context) {
+    private void deleteSharedPreferencesbyKey(
+            @NonNull Context context, @NonNull String key) {
+        plogd("deletedeleteSharedPreferencesbyKey: " + key);
         if (mSharedPreferences == null) {
-            plogd("deleteSharedPreferencesCountryCodes: mSharedPreferences is null");
+            plogd("deleteSharedPreferencesbyKey: mSharedPreferences is null");
             initSharedPreferences(context);
         }
         if (mSharedPreferences == null) {
-            plogd("deleteSharedPreferencesCountryCodes: mSharedPreferences is still null");
+            plogd("deleteSharedPreferencesbyKey: mSharedPreferences is still null");
             return;
         }
         try {
-            mSharedPreferences.edit().remove(CONFIG_UPDATER_SATELLITE_COUNTRY_CODES_KEY).apply();
+            mSharedPreferences.edit().remove(key).apply();
         } catch (Exception ex) {
-            ploge("deleteSharedPreferencesCountryCodes error : " + ex);
+            ploge("deleteSharedPreferencesbyKey error : " + ex);
         }
     }
 
@@ -1125,6 +1130,27 @@
         }
     }
 
+    private boolean updateSharedPreferencesSatelliteAccessConfigVersion(
+            @NonNull Context context, int version) {
+        if (mSharedPreferences == null) {
+            plogd("updateSharedPreferencesSatelliteAccessConfigVersion: "
+                    + "mSharedPreferences is null");
+            initSharedPreferences(context);
+        }
+        if (mSharedPreferences == null) {
+            ploge("updateSharedPreferencesSatelliteAccessConfigVersion: "
+                    + "mSharedPreferences is null");
+            return false;
+        }
+        try {
+            mSharedPreferences.edit().putInt(CONFIG_UPDATER_SATELLITE_VERSION_KEY, version).apply();
+            return true;
+        } catch (Exception ex) {
+            ploge("updateSharedPreferencesSatelliteAccessConfigVersion error: " + ex);
+            return false;
+        }
+    }
+
     private void persistLatestSatelliteCommunicationAllowedState() {
         if (mSharedPreferences == null) {
             ploge("persistLatestSatelliteCommunicationAllowedState: mSharedPreferences is null");
@@ -1155,6 +1181,14 @@
             return;
         }
 
+        // satellite access config version
+        int satelliteAccessConfigVersion = satelliteConfig.getSatelliteConfigDataVersion();
+        if (satelliteAccessConfigVersion <= 0) {
+            plogd("updateSatelliteAccessDataWithConfigUpdaterData: version is invalid: "
+                    + satelliteAccessConfigVersion);
+            return;
+        }
+
         // validation check country code
         List<String> satelliteCountryCodes = satelliteConfig.getDeviceSatelliteCountryCodes();
         if (!isValidCountryCodes(satelliteCountryCodes)) {
@@ -1262,17 +1296,37 @@
                     + " into shared preferences");
             localS2CellFile.delete();
             localSatelliteAccessConfigFile.delete();
-            deleteSharedPreferencesCountryCodes(context);
+            deleteSharedPreferencesbyKey(
+                    context, CONFIG_UPDATER_SATELLITE_COUNTRY_CODES_KEY);
             mConfigUpdaterMetricsStats.reportOemConfigError(
                     SatelliteConstants.CONFIG_UPDATE_RESULT_IO_ERROR);
             return;
         }
 
+        // copy version of satellite access config into the shared preferences of phone
+        if (!updateSharedPreferencesSatelliteAccessConfigVersion(
+                context, satelliteAccessConfigVersion)) {
+            ploge("updateSatelliteAccessDataWithConfigUpdaterData: "
+                    + "fail to copy satelliteAccessConfigVersion"
+                    + " into shared preferences");
+            localS2CellFile.delete();
+            localSatelliteAccessConfigFile.delete();
+            deleteSharedPreferencesbyKey(
+                    context, CONFIG_UPDATER_SATELLITE_COUNTRY_CODES_KEY);
+            deleteSharedPreferencesbyKey(
+                    context, CONFIG_UPDATER_SATELLITE_IS_ALLOW_ACCESS_CONTROL_KEY);
+            mConfigUpdaterMetricsStats.reportOemConfigError(
+                    SatelliteConstants.CONFIG_UPDATE_RESULT_IO_ERROR);
+            return;
+        }
+
+        mSatelliteAccessConfigVersion = satelliteAccessConfigVersion;
         mSatelliteS2CellFile = localS2CellFile;
         mSatelliteAccessConfigFile = localSatelliteAccessConfigFile;
         mSatelliteCountryCodes = satelliteCountryCodes;
         mIsSatelliteAllowAccessControl = satelliteConfig.isSatelliteDataForAllowedRegion();
-        plogd("Use s2 cell file=" + mSatelliteS2CellFile.getAbsolutePath()
+        plogd("mSatelliteAccessConfigVersion=" + mSatelliteAccessConfigVersion
+                + "Use s2 cell file=" + mSatelliteS2CellFile.getAbsolutePath()
                 + ", mSatelliteAccessConfigFile=" + mSatelliteAccessConfigFile.getAbsolutePath()
                 + ", country codes=" + String.join(",", mSatelliteCountryCodes)
                 + ", mIsSatelliteAllowAccessControl=" + mIsSatelliteAllowAccessControl
@@ -1363,11 +1417,19 @@
             return;
         }
 
+        int satelliteConfigVersion = mSharedPreferences.getInt(
+                CONFIG_UPDATER_SATELLITE_VERSION_KEY, 0);
+        if (satelliteConfigVersion <= 0) {
+            ploge("loadConfigUpdaterConfigs: satelliteConfigVersion is invalid: "
+                    + satelliteConfigVersion);
+            return;
+        }
+
         Set<String> countryCodes =
                 mSharedPreferences.getStringSet(CONFIG_UPDATER_SATELLITE_COUNTRY_CODES_KEY, null);
 
         if (countryCodes == null || countryCodes.isEmpty()) {
-            ploge("config updater country codes are either null or empty");
+            ploge("loadConfigUpdaterConfigs: configupdater country codes are either null or empty");
             return;
         }
 
@@ -1378,7 +1440,7 @@
         File s2CellFile = getConfigUpdaterSatelliteConfigFileFromLocalDirectory(
                 CONFIG_UPDATER_S2_CELL_FILE_NAME);
         if (s2CellFile == null) {
-            ploge("s2CellFile is null");
+            ploge("loadConfigUpdaterConfigs: s2CellFile is null");
             return;
         }
 
@@ -1389,11 +1451,18 @@
             return;
         }
 
-        plogd("use config updater config data");
+        mSatelliteAccessConfigVersion = satelliteConfigVersion;
         mSatelliteS2CellFile = s2CellFile;
         mSatelliteAccessConfigFile = satelliteAccessConfigJsonFile;
         mSatelliteCountryCodes = countryCodes.stream().collect(Collectors.toList());
         mIsSatelliteAllowAccessControl = isSatelliteAllowAccessControl;
+        plogd("loadConfigUpdaterConfigs: use satellite config data from configupdater: "
+                + " mSatelliteAccessConfigVersion=" + mSatelliteAccessConfigVersion
+                + ", Use s2 cell file=" + mSatelliteS2CellFile.getAbsolutePath()
+                + ", mSatelliteAccessConfigFile=" + mSatelliteAccessConfigFile.getAbsolutePath()
+                + ", country codes=" + String.join(",", mSatelliteCountryCodes)
+                + ", mIsSatelliteAllowAccessControl=" + mIsSatelliteAllowAccessControl
+                + " from ConfigUpdater");
         mAccessControllerMetricsStats.setConfigDataSource(
                 SatelliteConstants.CONFIG_DATA_SOURCE_CONFIG_UPDATER);
     }
@@ -3079,6 +3148,9 @@
             mControllerMetricsStats.reportFailedSatelliteAccessCheckCount();
         }
 
+        mControllerMetricsStats.reportCurrentVersionOfSatelliteAccessConfig(
+                mSatelliteAccessConfigVersion);
+
         mAccessControllerMetricsStats
                 .setLocationQueryTime(mLocationQueryStartTimeMillis)
                 .setTotalCheckingTime(mTotalCheckingStartTimeMillis)
diff --git a/src/com/android/phone/settings/RadioInfo.java b/src/com/android/phone/settings/RadioInfo.java
index ab7a3bf..5f0b2c1 100644
--- a/src/com/android/phone/settings/RadioInfo.java
+++ b/src/com/android/phone/settings/RadioInfo.java
@@ -2004,7 +2004,8 @@
     private static final int SATELLITE_CHANNEL = 8665;
     private final OnCheckedChangeListener mForceSatelliteChannelOnChangeListener =
             (buttonView, isChecked) -> {
-                if (!SubscriptionManager.isValidSubscriptionId(mSubId)) {
+
+                if (!isValidSubscription(mSubId)) {
                     loge("Force satellite channel invalid subId " + mSubId);
                     return;
                 }
@@ -2237,11 +2238,9 @@
                         dataMode);
                 overrideBundle.putBoolean(
                         KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, false);
-                log("satData: mMockSatelliteDataListener: new " + overrideBundle);
-                if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
+                if (isValidSubscription(mSubId)) {
                     getCarrierConfig().overrideConfig(mSubId, overrideBundle, false);
-                } else {
-                    Log.e(TAG, "SubscriptionId is not valid: " + mSubId);
+                    log("satData: mMockSatelliteDataListener: Updated new config" + overrideBundle);
                 }
             };
 
@@ -2271,7 +2270,7 @@
     }
 
     private void reloadCarrierConfigDefaults() {
-        if (mSatelliteDataOriginalBundle[mPhoneId] != null) {
+        if (mSatelliteDataOriginalBundle[mPhoneId] != null && isValidSubscription(mSubId)) {
             log("satData: Setting originalCarrierConfig = "
                     + mSatelliteDataOriginalBundle[mPhoneId]);
             getCarrierConfig().overrideConfig(mSubId, mSatelliteDataOriginalBundle[mPhoneId],
@@ -2281,24 +2280,40 @@
 
     private boolean isValidOperator(int subId) {
         String operatorNumeric = null;
-        if (SubscriptionManager.isValidSubscriptionId(subId)) {
-            operatorNumeric = mTelephonyManager
-                    .getNetworkOperatorForPhone(mPhoneId);
+        if (isValidSubscription(subId)) {
+            operatorNumeric = mTelephonyManager.getNetworkOperatorForPhone(mPhoneId);
             TelephonyManager tm;
-            if (TextUtils.isEmpty(operatorNumeric)
-                    && (tm = getSystemService(TelephonyManager.class)) != null) {
+            if (TextUtils.isEmpty(operatorNumeric) && (tm = getSystemService(
+                    TelephonyManager.class)) != null) {
                 operatorNumeric = tm.getSimOperatorNumericForPhone(mPhoneId);
             }
         }
         return !TextUtils.isEmpty(operatorNumeric);
     }
 
+    /**
+     * This method will do extra check to validate the subId.
+     * <p>
+     * In case user opens the radioInfo when sim is active and enable some checks and go to the
+     * SIM settings screen and disabled the screen. Upon return to radioInfo screen subId is still
+     * valid but not in active state any more.
+     */
+    private boolean isValidSubscription(int subId) {
+        boolean isValidSubId = false;
+        if (SubscriptionManager.isValidSubscriptionId(subId)) {
+            SubscriptionManager mSm = getSystemService(SubscriptionManager.class);
+            isValidSubId = mSm.isActiveSubscriptionId(subId);
+        }
+        log("isValidSubscription, subId [ " + subId + " ] = " + isValidSubId);
+        return isValidSubId;
+    }
+
     private final OnCheckedChangeListener mMockSatelliteListener =
             (buttonView, isChecked) -> {
                 int subId = mSubId;
                 int phoneId = mPhoneId;
                 if (SubscriptionManager.isValidPhoneId(phoneId)
-                        && SubscriptionManager.isValidSubscriptionId(subId)) {
+                        && isValidSubscription(subId)) {
                     if (getCarrierConfig() == null) return;
                     if (isChecked) {
                         if (!isValidOperator(subId)) {
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index d793db9..6860b25 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -23,7 +23,6 @@
 import static android.telephony.TelephonyManager.HAL_SERVICE_VOICE;
 
 import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_GSM;
-import static com.android.internal.telephony.flags.Flags.carrierEnabledSatelliteFlag;
 
 import android.annotation.NonNull;
 import android.app.AlertDialog;
@@ -1318,7 +1317,8 @@
             }
 
             if (!isEmergencyNumber) {
-                if (isCallDisallowedDueToSatellite(phone)
+                if ((isCallDisallowedDueToSatellite(phone)
+                        || isCallDisallowedDueToNtnEligibility(phone))
                         && (imsPhone == null || !imsPhone.canMakeWifiCall())) {
                     Log.d(this, "onCreateOutgoingConnection, cannot make call "
                             + "when device is connected to carrier roaming satellite network");
@@ -4843,23 +4843,17 @@
      * else {@code false}.
      */
     private boolean isCallDisallowedDueToSatellite(Phone phone) {
-        if (!carrierEnabledSatelliteFlag()) {
-            return false;
-        }
-
         if (phone == null) {
             return false;
         }
 
         if (!mSatelliteController.isInSatelliteModeForCarrierRoaming(phone)) {
-            // Device is not connected to satellite
+            // Phone is not connected to carrier roaming ntn
             return false;
         }
 
-        List<Integer> capabilities =
-                mSatelliteController.getCapabilitiesForCarrierRoamingSatelliteMode(phone);
-        if (capabilities.contains(NetworkRegistrationInfo.SERVICE_TYPE_VOICE)) {
-            // Call is supported while using satellite
+        if (isVoiceSupportedInSatelliteMode(phone)) {
+            // Call is supported in satellite mode
             return false;
         }
 
@@ -4867,6 +4861,42 @@
         return true;
     }
 
+    private boolean isCallDisallowedDueToNtnEligibility(@Nullable Phone phone) {
+        if (phone == null) {
+            Log.d(this, "isCallDisallowedDueToNtnEligibility: phone is null");
+            return false;
+        }
+
+        if (!mSatelliteController.getLastNotifiedNtnEligibility(phone)) {
+            // Phone is not carrier roaming ntn eligible
+            Log.d(this, "isCallDisallowedDueToNtnEligibility: eligibility is false");
+            return false;
+        }
+
+        if (isVoiceSupportedInSatelliteMode(phone)) {
+            // Call is supported in satellite mode
+            Log.d(this, "isCallDisallowedDueToNtnEligibility: voice is supported");
+            return false;
+        }
+
+        // Call is disallowed while eligibility is true
+        Log.d(this, "isCallDisallowedDueToNtnEligibility: return true");
+        return true;
+    }
+
+    private boolean isVoiceSupportedInSatelliteMode(@NonNull Phone phone) {
+        List<Integer> capabilities =
+                mSatelliteController.getCapabilitiesForCarrierRoamingSatelliteMode(phone);
+        if (capabilities.contains(NetworkRegistrationInfo.SERVICE_TYPE_VOICE)) {
+            // Call is supported in satellite mode
+            Log.d(this, "isVoiceSupportedInSatelliteMode: voice is supported");
+            return true;
+        }
+
+        Log.d(this, "isVoiceSupportedInSatelliteMode: voice is not supported");
+        return false;
+    }
+
     private boolean getTurnOffOemEnabledSatelliteDuringEmergencyCall() {
         boolean turnOffSatellite = false;
         try {
diff --git a/tests/src/com/android/phone/PhoneInterfaceManagerTest.java b/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
index ef6a02a..bbcb52b 100644
--- a/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
+++ b/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
@@ -46,6 +46,7 @@
 import android.platform.test.flag.junit.SetFlagsRule;
 import android.preference.PreferenceManager;
 import android.telephony.RadioAccessFamily;
+import android.telephony.Rlog;
 import android.telephony.TelephonyManager;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -74,6 +75,7 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 import java.util.Collections;
+import java.util.List;
 import java.util.Locale;
 
 /**
@@ -85,6 +87,8 @@
     @Rule
     public TestRule compatChangeRule = new PlatformCompatChangeRule();
 
+    private static final String TAG = "PhoneInterfaceManagerTest";
+
     private PhoneInterfaceManager mPhoneInterfaceManager;
     private SharedPreferences mSharedPreferences;
     @Mock private IIntegerConsumer mIIntegerConsumer;
@@ -322,6 +326,10 @@
                 mPhoneInterfaceManager).getDefaultPhone();
     }
 
+    private static void loge(String message) {
+        Rlog.e(TAG, message);
+    }
+
     @Test
     public void setNullCipherNotificationsEnabled_allReqsMet_successfullyEnabled() {
         setModemSupportsNullCipherNotification(true);
@@ -550,4 +558,25 @@
         String packageName = mPhoneInterfaceManager.getCurrentPackageName();
         assertEquals(null, packageName);
     }
+
+    @Test
+    public void testGetSatelliteDataOptimizedApps() throws Exception {
+        doReturn(true).when(mFeatureFlags).carrierRoamingNbIotNtn();
+        mPhoneInterfaceManager.setFeatureFlags(mFeatureFlags);
+        loge("FeatureFlagApi is set to return true");
+
+        boolean containsCtsApp = false;
+        String ctsPackageName = "android.telephony.cts";
+        List<String> listSatelliteApplications =
+                mPhoneInterfaceManager.getSatelliteDataOptimizedApps();
+
+        for (String packageName : listSatelliteApplications) {
+            if (ctsPackageName.equals(packageName)) {
+                containsCtsApp = true;
+            }
+        }
+
+        assertFalse(containsCtsApp);
+    }
+
 }
diff --git a/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java b/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java
index d532289..12d848c 100644
--- a/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java
+++ b/tests/src/com/android/phone/satellite/accesscontrol/SatelliteAccessControllerTest.java
@@ -34,6 +34,7 @@
 
 import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.ALLOWED_STATE_CACHE_VALID_DURATION_NANOS;
 import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.CMD_IS_SATELLITE_COMMUNICATION_ALLOWED;
+import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.CONFIG_UPDATER_SATELLITE_VERSION_KEY;
 import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.DEFAULT_DELAY_MINUTES_BEFORE_VALIDATING_POSSIBLE_CHANGE_IN_ALLOWED_REGION;
 import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.DEFAULT_MAX_RETRY_COUNT_FOR_VALIDATING_POSSIBLE_CHANGE_IN_ALLOWED_REGION;
 import static com.android.phone.satellite.accesscontrol.SatelliteAccessController.DEFAULT_REGIONAL_SATELLITE_CONFIG_ID;
@@ -407,6 +408,8 @@
         when(mMockSharedPreferences.getBoolean(anyString(), anyBoolean())).thenReturn(true);
         when(mMockSharedPreferences.getStringSet(anyString(), any()))
                 .thenReturn(Set.of(TEST_SATELLITE_COUNTRY_CODES));
+        when(mMockSharedPreferences.getInt(
+                eq(CONFIG_UPDATER_SATELLITE_VERSION_KEY), anyInt())).thenReturn(0);
         doReturn(mMockSharedPreferencesEditor).when(mMockSharedPreferences).edit();
         doReturn(mMockSharedPreferencesEditor).when(mMockSharedPreferencesEditor)
                 .putBoolean(anyString(), anyBoolean());
@@ -414,6 +417,8 @@
                 .putStringSet(anyString(), any());
         doReturn(mMockSharedPreferencesEditor).when(mMockSharedPreferencesEditor)
                 .putLong(anyString(), anyLong());
+        doReturn(mMockSharedPreferencesEditor).when(mMockSharedPreferencesEditor)
+                .putInt(anyString(), anyInt());
         doNothing().when(mMockSharedPreferencesEditor).apply();
 
         when(mMockFeatureFlags.satellitePersistentLogging()).thenReturn(true);
@@ -1441,7 +1446,7 @@
 
 
     @Test
-    public void testUpdateSatelliteConfigData() throws Exception {
+    public void testUpdateSatelliteAccessDataWithConfigUpdaterData() throws Exception {
         logd("registering for config update changed");
         verify(mMockSatelliteController).registerForConfigUpdateChanged(
                 mConfigUpdateHandlerCaptor.capture(), mConfigUpdateIntCaptor.capture(),
@@ -1457,8 +1462,9 @@
 
         // These APIs are executed during loadRemoteConfigs
         logd("verify load remote configs shared preferences method calls");
-        verify(mMockSharedPreferences, times(1)).getStringSet(anyString(), any());
-        verify(mMockSharedPreferences, times(5)).getBoolean(anyString(), anyBoolean());
+        verify(mMockSharedPreferences, times(1)).getInt(anyString(), anyInt());
+        verify(mMockSharedPreferences, times(0)).getStringSet(anyString(), any());
+        verify(mMockSharedPreferences, times(4)).getBoolean(anyString(), anyBoolean());
 
         // satelliteConfig is null
         logd("test for satelliteConfig is null");
@@ -1472,10 +1478,10 @@
         verify(mMockCachedAccessRestrictionMap, never()).clear();
         verify(mMockSatelliteController, times(1)).getSatelliteConfig();
 
-        // satelliteConfig has invalid country codes
-        logd("test for satelliteConfig with invalid country codes");
+        // satelliteConfig has satellite config data version(0) which is from device config.
+        logd("test for satelliteConfig from device config version 0");
         SatelliteConfig mockConfig = mock(SatelliteConfig.class);
-        doReturn(List.of("USA", "JAP")).when(mockConfig).getDeviceSatelliteCountryCodes();
+        doReturn(0).when(mockConfig).getSatelliteConfigDataVersion();
         doReturn(mockConfig).when(mMockSatelliteController).getSatelliteConfig();
         doReturn(false).when(mockConfig).isSatelliteDataForAllowedRegion();
 
@@ -1483,6 +1489,24 @@
         verify(mMockSharedPreferences, never()).edit();
         verify(mMockCachedAccessRestrictionMap, never()).clear();
         verify(mMockSatelliteController, times(2)).getSatelliteConfig();
+        verify(mockConfig, times(1)).getSatelliteConfigDataVersion();
+        verify(mockConfig, times(0)).getDeviceSatelliteCountryCodes();
+        verify(mockConfig, times(0)).isSatelliteDataForAllowedRegion();
+        verify(mockConfig, times(0)).getSatelliteS2CellFile(mMockContext);
+        verify(mockConfig, times(0)).getSatelliteAccessConfigJsonFile(mMockContext);
+
+        // satelliteConfig has invalid country codes
+        logd("test for satelliteConfig with invalid country codes");
+        doReturn(1).when(mockConfig).getSatelliteConfigDataVersion();
+        doReturn(List.of("USA", "JAP")).when(mockConfig).getDeviceSatelliteCountryCodes();
+        doReturn(mockConfig).when(mMockSatelliteController).getSatelliteConfig();
+        doReturn(false).when(mockConfig).isSatelliteDataForAllowedRegion();
+
+        sendConfigUpdateChangedEvent(mMockContext);
+        verify(mMockSharedPreferences, never()).edit();
+        verify(mMockCachedAccessRestrictionMap, never()).clear();
+        verify(mMockSatelliteController, times(3)).getSatelliteConfig();
+        verify(mockConfig, times(2)).getSatelliteConfigDataVersion();
         verify(mockConfig, times(1)).getDeviceSatelliteCountryCodes();
         verify(mockConfig, times(0)).isSatelliteDataForAllowedRegion();
         verify(mockConfig, times(0)).getSatelliteS2CellFile(mMockContext);
@@ -1497,7 +1521,8 @@
         sendConfigUpdateChangedEvent(mMockContext);
         verify(mMockSharedPreferences, never()).edit();
         verify(mMockCachedAccessRestrictionMap, never()).clear();
-        verify(mMockSatelliteController, times(3)).getSatelliteConfig();
+        verify(mMockSatelliteController, times(4)).getSatelliteConfig();
+        verify(mockConfig, times(3)).getSatelliteConfigDataVersion();
         verify(mockConfig, times(2)).getDeviceSatelliteCountryCodes();
         verify(mockConfig, times(1)).isSatelliteDataForAllowedRegion();
         verify(mockConfig, times(0)).getSatelliteS2CellFile(mMockContext);
@@ -1522,7 +1547,8 @@
         sendConfigUpdateChangedEvent(mMockContext);
         verify(mMockSharedPreferences, never()).edit();
         verify(mMockCachedAccessRestrictionMap, never()).clear();
-        verify(mMockSatelliteController, times(4)).getSatelliteConfig();
+        verify(mMockSatelliteController, times(5)).getSatelliteConfig();
+        verify(mockConfig, times(4)).getSatelliteConfigDataVersion();
         verify(mockConfig, times(3)).getDeviceSatelliteCountryCodes();
         verify(mockConfig, times(2)).isSatelliteDataForAllowedRegion();
         verify(mockConfig, times(1)).getSatelliteS2CellFile(mMockContext);
@@ -1549,7 +1575,8 @@
         sendConfigUpdateChangedEvent(mMockContext);
         verify(mMockSharedPreferences, never()).edit();
         verify(mMockCachedAccessRestrictionMap, never()).clear();
-        verify(mMockSatelliteController, times(5)).getSatelliteConfig();
+        verify(mMockSatelliteController, times(6)).getSatelliteConfig();
+        verify(mockConfig, times(5)).getSatelliteConfigDataVersion();
         verify(mockConfig, times(4)).getDeviceSatelliteCountryCodes();
         verify(mockConfig, times(3)).isSatelliteDataForAllowedRegion();
         verify(mockConfig, times(2)).getSatelliteS2CellFile(mMockContext);
@@ -1576,9 +1603,10 @@
                 .getSatelliteAccessConfigJsonFile(mMockContext);
 
         sendConfigUpdateChangedEvent(mMockContext);
-        verify(mMockSharedPreferences, times(2)).edit();
+        verify(mMockSharedPreferences, times(3)).edit();
         verify(mMockCachedAccessRestrictionMap, times(1)).clear();
-        verify(mMockSatelliteController, times(6)).getSatelliteConfig();
+        verify(mMockSatelliteController, times(7)).getSatelliteConfig();
+        verify(mockConfig, times(6)).getSatelliteConfigDataVersion();
         verify(mockConfig, times(5)).getDeviceSatelliteCountryCodes();
         verify(mockConfig, times(5)).isSatelliteDataForAllowedRegion();
         verify(mockConfig, times(3)).getSatelliteS2CellFile(mMockContext);
@@ -1638,6 +1666,8 @@
 
         logd("Creating sats2.dat and satellite_access_config.json files");
         // set given sats2.dat and satellite_access_config.json as device geofence files
+        doReturn(0).when(mMockSharedPreferences)
+                .getInt(eq(CONFIG_UPDATER_SATELLITE_VERSION_KEY), anyInt());
         String sats2FilePath = setupTestFileFromRawResource(sats2ResId, targetSats2FileName);
         when(mMockResources.getString(
                         com.android.internal.R.string.config_oem_enabled_satellite_s2cell_file))
@@ -1651,6 +1681,7 @@
     }
 
     private void setupOtaGeofenceData(
+            int version,
             SatelliteConfig mockConfig,
             int sats2ResId,
             String targetSats2FileName,
@@ -1679,6 +1710,9 @@
         doReturn(List.of(TEST_SATELLITE_COUNTRY_CODES))
                 .when(mockConfig)
                 .getDeviceSatelliteCountryCodes();
+        doReturn(version).when(mockConfig).getSatelliteConfigDataVersion();
+        doReturn(version).when(mMockSharedPreferences)
+                .getInt(eq(CONFIG_UPDATER_SATELLITE_VERSION_KEY), anyInt());
     }
 
     private boolean areOnDeviceAndOtaFilesValidAndDifferent(
@@ -1774,6 +1808,7 @@
                 "v15_sats2.dat",
                 com.android.phone.tests.R.raw.v15_satellite_access_config,
                 "v15_satellite_access_config.json");
+        assertEquals(0, mSatelliteAccessControllerUT.getSatelliteAccessConfigVersion());
         assertTrue(isLocationAllowed(bundleCaptor, mockResultReceiverIterator, locationUS));
         assertFalse(isLocationAllowed(bundleCaptor, mockResultReceiverIterator, locationKR));
         assertFalse(isLocationAllowed(bundleCaptor, mockResultReceiverIterator, locationTW));
@@ -1822,6 +1857,7 @@
                         + " Simulate config update for v16 files. Expectation: locationUS -"
                         + " allowed; locationKR - allowed; locationTW - allowed");
         setupOtaGeofenceData(
+                16,
                 mockConfig,
                 com.android.phone.tests.R.raw.v16_sats2,
                 "v16_sats2.dat",
@@ -1829,6 +1865,8 @@
                 "v16_satellite_access_config.json",
                 new String[] {"US", "CA", "UK", "KR", "TW"});
         sendConfigUpdateChangedEvent(mMockContext);
+
+        assertEquals(16, mSatelliteAccessControllerUT.getSatelliteAccessConfigVersion());
         assertTrue(isLocationAllowed(bundleCaptor, mockResultReceiverIterator, locationUS));
         assertTrue(isLocationAllowed(bundleCaptor, mockResultReceiverIterator, locationKR));
         assertTrue(isLocationAllowed(bundleCaptor, mockResultReceiverIterator, locationTW));
@@ -1883,6 +1921,7 @@
                         + " Simulate config update for v17 files. Expectation: locationUS -"
                         + " allowed; locationKR - not allowed; locationTW - not allowed");
         setupOtaGeofenceData(
+                17,
                 mockConfig,
                 com.android.phone.tests.R.raw.v17_sats2,
                 "v17_sats2.dat",
@@ -1890,6 +1929,8 @@
                 "v17_satellite_access_config.json",
                 new String[] {"US", "CA", "UK", "KR", "TW"});
         sendConfigUpdateChangedEvent(mMockContext);
+
+        assertEquals(17, mSatelliteAccessControllerUT.getSatelliteAccessConfigVersion());
         assertTrue(isLocationAllowed(bundleCaptor, mockResultReceiverIterator, locationUS));
         assertFalse(isLocationAllowed(bundleCaptor, mockResultReceiverIterator, locationKR));
         assertFalse(isLocationAllowed(bundleCaptor, mockResultReceiverIterator, locationTW));
@@ -2714,5 +2755,11 @@
                 return mSatelliteAccessConfigMap;
             }
         }
+
+        public int getSatelliteAccessConfigVersion() {
+            synchronized (mLock) {
+                return mSatelliteAccessConfigVersion;
+            }
+        }
     }
 }
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
index 2fc2757..12b34d0 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
@@ -3894,6 +3894,36 @@
     }
 
     @Test
+    public void testNormalCallWhenEligibilityIsTrue() throws Exception {
+        mSetFlagsRule.enableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG);
+        mSetFlagsRule.enableFlags(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN);
+
+        setupForCallTest();
+
+        // Carrier roaming ntn eligibility is true and call is not supported
+        when(mSatelliteController.getLastNotifiedNtnEligibility(any())).thenReturn(true);
+        when(mSatelliteController.getCapabilitiesForCarrierRoamingSatelliteMode(any()))
+                .thenReturn(List.of(NetworkRegistrationInfo.SERVICE_TYPE_DATA));
+
+        mConnection = mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1,
+                createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, "1234", TELECOM_CALL_ID1));
+        DisconnectCause disconnectCause = mConnection.getDisconnectCause();
+        assertEquals(android.telephony.DisconnectCause.SATELLITE_ENABLED,
+                disconnectCause.getTelephonyDisconnectCause());
+        assertEquals(DISCONNECT_REASON_CARRIER_ROAMING_SATELLITE_MODE, disconnectCause.getReason());
+
+        // Carrier roaming ntn eligibility is true and call is supported
+        setupForCallTest();
+        when(mSatelliteController.getCapabilitiesForCarrierRoamingSatelliteMode(any())).thenReturn(
+                List.of(NetworkRegistrationInfo.SERVICE_TYPE_VOICE));
+
+        // UnsupportedOperationException is thrown as we cannot perform actual call
+        assertThrows(UnsupportedOperationException.class, () -> mTestConnectionService
+                .onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1,
+                        createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, "1234", "TC@2")));
+    }
+
+    @Test
     public void testIsAvailableForEmergencyCallsNotForCrossSim() {
         Phone mockPhone = Mockito.mock(Phone.class);
         when(mockPhone.getImsRegistrationTech()).thenReturn(