Merge cherrypicks of ['googleplex-android-review.googlesource.com/32710850', 'googleplex-android-review.googlesource.com/32711605', 'googleplex-android-review.googlesource.com/32744249'] into 25Q2-release.

Change-Id: I44b4e719004d211babfd876d9373c5d1cf169480
diff --git a/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java b/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java
index 0d4a2da..dc6be3a 100644
--- a/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java
+++ b/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java
@@ -1382,8 +1382,6 @@
     }
 
     private boolean allowMtSmsPolling() {
-        if (!mFeatureFlags.carrierRoamingNbIotNtn()) return false;
-
         SatelliteController satelliteController = SatelliteController.getInstance();
         int subId = satelliteController.getSelectedSatelliteSubId();
         boolean isP2PSmsDisallowed =
@@ -1394,20 +1392,33 @@
         }
 
         boolean isModemStateConnectedOrTransferring;
+        boolean isAligned;
+        boolean isMtSmsPollingThrottled;
         synchronized (mLock) {
-            if (!mIsAligned) return false;
-
+            isMtSmsPollingThrottled = mIsMtSmsPollingThrottled;
+            isAligned = mIsAligned;
             isModemStateConnectedOrTransferring =
                     mModemState == SATELLITE_MODEM_STATE_CONNECTED
                             || mModemState == SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING;
         }
 
-        if (!isModemStateConnectedOrTransferring && !allowCheckMessageInNotConnected()) {
-            plogd("EVENT_MT_SMS_POLLING_THROTTLE_TIMED_OUT:"
-                    + " allow_check_message_in_not_connected is disabled");
+        if (isMtSmsPollingThrottled) {
+            plogd("allowMtSmsPolling: polling is throttled");
             return false;
         }
 
+        if (!isAligned) {
+            plogd("allowMtSmsPolling: not aligned");
+            return false;
+        }
+
+        if (!isModemStateConnectedOrTransferring && !allowCheckMessageInNotConnected()) {
+            plogd("allowMtSmsPolling: not in service and "
+                    + "allow_check_message_in_not_connected is disabled");
+            return false;
+        }
+
+        plogd("allowMtSmsPolling: return true");
         return true;
     }
 
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteController.java b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
index e4cf041..a39ba91 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
@@ -1307,7 +1307,8 @@
         }
     }
 
-    private static final class SatelliteControllerHandlerRequest {
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    public static final class SatelliteControllerHandlerRequest {
         /** The argument to use for the request */
         public @NonNull Object argument;
         /** The caller needs to specify the phone to be used for the request */
@@ -1315,7 +1316,7 @@
         /** The result of the request that is run on the main thread */
         public @Nullable Object result;
 
-        SatelliteControllerHandlerRequest(Object argument, Phone phone) {
+        public SatelliteControllerHandlerRequest(Object argument, Phone phone) {
             this.argument = argument;
             this.phone = phone;
         }
@@ -2302,7 +2303,7 @@
                     int subId = (int) ar.userObj;
                     int error = SatelliteServiceUtils.getSatelliteError(
                             ar, "isSatelliteEnabledForCarrier");
-                    boolean satelliteEnabled = (boolean) ar.result;
+                    boolean satelliteEnabled = (Boolean) ar.result;
                     plogd("EVENT_GET_SATELLITE_ENABLED_FOR_CARRIER_DONE: subId=" + subId
                             + " error=" + error + " satelliteEnabled=" + satelliteEnabled);
 
@@ -6129,7 +6130,8 @@
      * @param subId subscription ID
      * @return {@code true} if satellite modem is enabled, {@code false} otherwise.
      */
-    private boolean isSatelliteEnabledForCarrierAtModem(int subId) {
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    public boolean isSatelliteEnabledForCarrierAtModem(int subId) {
         synchronized (mIsSatelliteEnabledLock) {
             return mIsSatelliteAttachEnabledForCarrierArrayPerSub.getOrDefault(subId, false);
         }
@@ -7925,14 +7927,37 @@
         }
 
         if(carrierTagIds == null) {
-            plogd("isSatelliteAvailableAtCurrentLocation: tagids for carrier satellite enabled " +
-                    "are not available");
-            return false;
+            String satelliteAccessConfigFile =
+                getSatelliteAccessConfigurationFileFromOverlayConfig();
+            if (TextUtils.isEmpty(satelliteAccessConfigFile)) {
+                plogd("isSatelliteAvailableAtCurrentLocation: device does not support"
+                          + " custom satellite access configuration per location");
+                return true;
+            } else {
+                plogd("isSatelliteAvailableAtCurrentLocation: tagids for carrier "
+                          + info.getCarrierName() + ", subId=" + info.getSubscriptionId()
+                          + " are not available");
+                return false;
+            }
         }
 
         return isCarrierSatelliteAvailableAtCurrentLocation(carrierTagIds);
     }
 
+    @Nullable
+    private String getSatelliteAccessConfigurationFileFromOverlayConfig() {
+        String satelliteAccessConfigFile = null;
+        try {
+            satelliteAccessConfigFile = mContext.getResources().getString(
+                    com.android.internal.R.string.satellite_access_config_file);
+        } catch (Resources.NotFoundException ex) {
+            loge("getSatelliteAccessConfigurationFileFromOverlayConfig: got ex=" + ex);
+        }
+
+        logd("satelliteAccessConfigFile =" + satelliteAccessConfigFile);
+        return satelliteAccessConfigFile;
+    }
+
     /**
      * Compares tagIds and determine if
      * carrier satellite is available at current location while selecting highest priority profile.
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java b/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
index 2ebd258..9e5d9de 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteModemInterface.java
@@ -1160,13 +1160,9 @@
                         }, new IBooleanConsumer.Stub() {
                             @Override
                             public void accept(boolean result) {
-                                // Convert for compatibility with SatelliteResponse
-                                // TODO: This should just report result instead.
-                                int[] enabled = new int[] {result ? 1 : 0};
-                                plogd("requestIsSatelliteEnabledForCarrier: "
-                                        + Arrays.toString(enabled));
+                                plogd("requestIsSatelliteEnabledForCarrier: " + result);
                                 Binder.withCleanCallingIdentity(() -> sendMessageWithResult(
-                                        message, enabled,
+                                        message, result,
                                         SatelliteManager.SATELLITE_RESULT_SUCCESS));
                             }
                         });
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramDispatcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramDispatcherTest.java
index f383068..745a5b2 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramDispatcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramDispatcherTest.java
@@ -1145,13 +1145,11 @@
    public void testHandleMessage_eventMtSmsPollingThrottleTimedOut_sendsMtSmsPollInNotConnected() {
         setShouldPollMtSmsTrue();
         mDatagramDispatcherUT.setDeviceAlignedWithSatellite(true);
-        when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
         mContextFixture.putBooleanResource(
                 R.bool.config_satellite_allow_check_message_in_not_connected, true);
 
-        mDatagramDispatcherUT.handleMessage(
-                mDatagramDispatcherUT.obtainMessage(10 /*EVENT_MT_SMS_POLLING_THROTTLE_TIMED_OUT*/,
-                        new AsyncResult(null, null, null)));
+        mDatagramDispatcherUT.obtainMessage(10 /*EVENT_MT_SMS_POLLING_THROTTLE_TIMED_OUT*/,
+                new AsyncResult(null, null, null)).sendToTarget();
         processAllMessages();
 
         verify(mMockSmsDispatchersController, times(1)).sendMtSmsPollingMessage();
@@ -1162,14 +1160,13 @@
             testHandleMessage_eventMtSmsPollingThrottleTimedOut_configDisabled_doesNotSendMtSmsPoll() {
         setShouldPollMtSmsTrue();
         mDatagramDispatcherUT.setDeviceAlignedWithSatellite(true);
-        when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
         // Set config_satellite_allow_check_message_in_not_connected to false
         mContextFixture.putBooleanResource(
                 R.bool.config_satellite_allow_check_message_in_not_connected, false);
 
-        mDatagramDispatcherUT.handleMessage(
-                mDatagramDispatcherUT.obtainMessage(10 /*EVENT_MT_SMS_POLLING_THROTTLE_TIMED_OUT*/,
-                        new AsyncResult(null, null, null)));
+        mDatagramDispatcherUT.obtainMessage(10 /*EVENT_MT_SMS_POLLING_THROTTLE_TIMED_OUT*/,
+                new AsyncResult(null, null, null)).sendToTarget();
+        processAllMessages();
 
         verifyNoMoreInteractions(mMockSmsDispatchersController);
    }
@@ -1179,16 +1176,14 @@
             testHandleMessage_eventMtSmsPollingThrottleTimedOut_flagDisabled_doesNotSendMtSmsPoll() {
         setShouldPollMtSmsTrue();
         mDatagramDispatcherUT.setDeviceAlignedWithSatellite(true);
-        // Set flag to false
-        when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(false);
         mContextFixture.putBooleanResource(
                 R.bool.config_satellite_allow_check_message_in_not_connected, true);
 
-        mDatagramDispatcherUT.handleMessage(
-                mDatagramDispatcherUT.obtainMessage(10 /*EVENT_MT_SMS_POLLING_THROTTLE_TIMED_OUT*/,
-                        new AsyncResult(null, null, null)));
+        mDatagramDispatcherUT.obtainMessage(10 /*EVENT_MT_SMS_POLLING_THROTTLE_TIMED_OUT*/,
+                new AsyncResult(null, null, null)).sendToTarget();
+        processAllMessages();
 
-        verifyNoMoreInteractions(mMockSmsDispatchersController);
+        verify(mMockSmsDispatchersController, times(1)).sendMtSmsPollingMessage();
    }
 
 
@@ -1196,7 +1191,6 @@
     @Test
     public void testSetDeviceAlignedWithSatellite_isAligned_notConnected_sendsMtSmsPoll() {
         setShouldPollMtSmsTrue();
-        when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
         mContextFixture.putBooleanResource(
                 R.bool.config_satellite_allow_check_message_in_not_connected, true);
 
@@ -1209,11 +1203,11 @@
     @Test
     public void testSetDeviceAlignedWithSatellite_notAligned_doesNotSendsMtSmsPoll() {
         setShouldPollMtSmsTrue();
-        when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
         mContextFixture.putBooleanResource(
                 R.bool.config_satellite_allow_check_message_in_not_connected, true);
 
         mDatagramDispatcherUT.setDeviceAlignedWithSatellite(false);
+        processAllMessages();
 
         verifyNoMoreInteractions(mMockSmsDispatchersController);
     }
@@ -1222,7 +1216,6 @@
     public void testOnSatelliteModemStateChanged_notConnected_sendsMtSmsPoll() {
         setShouldPollMtSmsTrue();
         mDatagramDispatcherUT.setDeviceAlignedWithSatellite(true);
-        when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
         mContextFixture.putBooleanResource(
                 R.bool.config_satellite_allow_check_message_in_not_connected, true);
 
@@ -1237,7 +1230,6 @@
     public void testOnSatelliteModemStateChanged_connected_sendsMtSmsPoll() {
         setShouldPollMtSmsTrue();
         mDatagramDispatcherUT.setDeviceAlignedWithSatellite(true);
-        when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
 
         mDatagramDispatcherUT.onSatelliteModemStateChanged(
                 SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED);
@@ -1250,7 +1242,6 @@
     public void testOnSatelliteModemStateChanged_transferring_sendsMtSmsPoll() {
         setShouldPollMtSmsTrue();
         mDatagramDispatcherUT.setDeviceAlignedWithSatellite(true);
-        when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
 
         mDatagramDispatcherUT.onSatelliteModemStateChanged(
                 SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING);
@@ -1264,9 +1255,11 @@
         startMtSmsPollingThrottle();
         setShouldPollMtSmsTrue();
         mDatagramDispatcherUT.setDeviceAlignedWithSatellite(true);
-        when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
         mContextFixture.putBooleanResource(
                 R.bool.config_satellite_allow_check_message_in_not_connected, true);
+        mDatagramDispatcherUT.onSatelliteModemStateChanged(
+                SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED);
+        processAllMessages();
 
         verify(mMockSmsDispatchersController, times(0)).sendMtSmsPollingMessage();
     }
@@ -1274,7 +1267,6 @@
     @Test
     public void testOnSatelliteModemStateChanged_onFirstConnected_sendsMtSmsPoll() {
         mDatagramDispatcherUT.setDeviceAlignedWithSatellite(true);
-        when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
         // Set the following so shouldPollMtSms returns true
         mContextFixture.putBooleanResource(R.bool.config_enabled_mt_sms_polling, true);
         when(mMockSatelliteController.shouldSendSmsToDatagramDispatcher(any(Phone.class)))
@@ -1290,7 +1282,6 @@
     @Test
     public void testSendsMtSmsPoll_P2PSmsAllowed() {
         mDatagramDispatcherUT.setDeviceAlignedWithSatellite(true);
-        when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
         mContextFixture.putBooleanResource(R.bool.config_enabled_mt_sms_polling, true);
         when(mMockSatelliteController.shouldSendSmsToDatagramDispatcher(any(Phone.class)))
                 .thenReturn(true);
@@ -1344,8 +1335,7 @@
         args.arg2 = pendingRequest.uniqueMessageId;
         args.arg3 = true;
         // EVENT_SEND_SMS_DONE to trigger handleEventSendSmsDone which will start the throttle
-        mDatagramDispatcherUT.handleMessage(
-                mDatagramDispatcherUT.obtainMessage(9 /*EVENT_SEND_SMS_DONE*/, args));
+        mDatagramDispatcherUT.obtainMessage(9 /*EVENT_SEND_SMS_DONE*/, args).sendToTarget();
     }
 
     private boolean waitForIntegerConsumerResult(int expectedNumberOfEvents) {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
index a519067..60cd83b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
@@ -5693,6 +5693,22 @@
                 61 /* CMD_EVALUATE_CARRIER_ROAMING_NTN_ELIGIBILITY_CHANGE */).sendToTarget();
     }
 
+    private void sendCmdGetSatelliteEnabledForCarrier(Phone phone) {
+        SatelliteController.SatelliteControllerHandlerRequest request =
+                new SatelliteController.SatelliteControllerHandlerRequest(null, phone);
+        Message msg = mSatelliteControllerUT.obtainMessage(
+                64 /* CMD_GET_SATELLITE_ENABLED_FOR_CARRIER */, request);
+        msg.sendToTarget();
+    }
+
+    private void sendEventGetSatelliteEnabledForCarrierDone(int subId, Boolean result,
+            Throwable exception) {
+        Message msg = mSatelliteControllerUT.obtainMessage(
+                65 /* EVENT_GET_SATELLITE_ENABLED_FOR_CARRIER_DONE */, subId);
+        msg.obj = new AsyncResult(subId, result, exception);
+        msg.sendToTarget();
+    }
+
     private void setRadioPower(boolean on) {
         mSimulatedCommands.setRadioPower(on, false, false, null);
     }
@@ -6040,6 +6056,11 @@
             return mLocationServiceEnabled;
         }
 
+        @Override
+        protected boolean isSatelliteAvailableAtCurrentLocation(@Nullable SubscriptionInfo info) {
+            return super.isSatelliteAvailableAtCurrentLocation(info);
+        }
+
         void setSatelliteProvisioned(@Nullable Boolean isProvisioned) {
             synchronized (mDeviceProvisionLock) {
                 mIsDeviceProvisioned = isProvisioned;
@@ -6950,6 +6971,61 @@
         assertTrue(mSatelliteControllerUT.isCarrierRoamingNtnEligible(mPhone));
     }
 
+    @Test
+    public void testIsSatelliteAvailableAtCurrentLocation() throws Exception {
+        SubscriptionInfo ntnOnlySubscriptionInfo = new SubscriptionInfo.Builder()
+                .setOnlyNonTerrestrialNetwork(true)
+                .build();
+        SubscriptionInfo esosSubscriptionInfo = new SubscriptionInfo.Builder()
+                .setSatelliteESOSSupported(true)
+                .build();
+        Field currentLocationTagIdsField = SatelliteController.class.getDeclaredField(
+                "mCurrentLocationTagIds");
+        currentLocationTagIdsField.setAccessible(true);
+
+        // Null subscription info
+        assertFalse(mSatelliteControllerUT.isSatelliteAvailableAtCurrentLocation(null));
+
+        // Satellite is not allowed
+        mSatelliteControllerUT.setIsSatelliteAllowedState(false);
+        assertFalse(mSatelliteControllerUT.isSatelliteAvailableAtCurrentLocation(
+                ntnOnlySubscriptionInfo));
+        assertFalse(mSatelliteControllerUT.isSatelliteAvailableAtCurrentLocation(
+                esosSubscriptionInfo));
+
+        // Satellite is allowed
+        mSatelliteControllerUT.setIsSatelliteAllowedState(true);
+        assertTrue(mSatelliteControllerUT.isSatelliteAvailableAtCurrentLocation(
+                ntnOnlySubscriptionInfo));
+
+        // Both config_verizon_satellite_enabled_tagids and satellite_access_config_file
+        // are not configured
+        assertTrue(mSatelliteControllerUT.isSatelliteAvailableAtCurrentLocation(
+                esosSubscriptionInfo));
+
+        // config_verizon_satellite_enabled_tagids is not configured whereas
+        // satellite_access_config_file is configured
+        mContextFixture.putResource(
+                com.android.internal.R.string.satellite_access_config_file,
+                "test_satellite_access_config_file");
+        assertFalse(mSatelliteControllerUT.isSatelliteAvailableAtCurrentLocation(
+                esosSubscriptionInfo));
+
+        // Both config_verizon_satellite_enabled_tagids and satellite_access_config_file
+        // are configured, but mCurrentLocationTagIds is empty
+        mContextFixture.putIntArrayResource(
+                R.array.config_verizon_satellite_enabled_tagids,
+                new int[]{1001});
+        assertFalse(mSatelliteControllerUT.isSatelliteAvailableAtCurrentLocation(
+                esosSubscriptionInfo));
+
+        // Both config_verizon_satellite_enabled_tagids and satellite_access_config_file
+        // are configured, and mCurrentLocationTagIds contains the carrier tag id
+        currentLocationTagIdsField.set(mSatelliteControllerUT, Arrays.asList(1001));
+        assertTrue(mSatelliteControllerUT.isSatelliteAvailableAtCurrentLocation(
+                esosSubscriptionInfo));
+    }
+
     public void testNotifyNtnEligibilityLocationServiceStatusChanged() {
         // Enable CarrierRoamingNtn
         mContextFixture.putBooleanResource(
@@ -7009,4 +7085,27 @@
 
         verify(mPhone, times(1)).notifyCarrierRoamingNtnEligibleStateChanged(eq(true));
     }
+
+    @Test
+    public void testGetSatelliteEnabledForCarrier() {
+        reset(mPhone);
+        sendCmdGetSatelliteEnabledForCarrier(mPhone);
+        processAllMessages();
+        verify(mPhone, times(1)).isSatelliteEnabledForCarrier(anyInt(), any());
+        reset(mPhone);
+
+        sendEventGetSatelliteEnabledForCarrierDone(mPhone.getSubId(), false,
+                new SatelliteException(SATELLITE_RESULT_ERROR));
+        processAllMessages();
+        assertFalse(mSatelliteControllerUT.isSatelliteEnabledForCarrierAtModem(mPhone.getSubId()));
+
+        sendEventGetSatelliteEnabledForCarrierDone(mPhone.getSubId(), true, null);
+        processAllMessages();
+        assertTrue(mSatelliteControllerUT.isSatelliteEnabledForCarrierAtModem(mPhone.getSubId()));
+
+        sendEventGetSatelliteEnabledForCarrierDone(mPhone.getSubId(), false, null);
+        processAllMessages();
+        assertFalse(mSatelliteControllerUT.isSatelliteEnabledForCarrierAtModem(mPhone.getSubId()));
+    }
+
 }