Merge "Replaced send broadcast with user aware version" into main
diff --git a/flags/subscription.aconfig b/flags/subscription.aconfig
index dc17a61..76485be 100644
--- a/flags/subscription.aconfig
+++ b/flags/subscription.aconfig
@@ -28,14 +28,6 @@
   bug: "296097429"
 }
 
-# OWNER=rambowang TARGET=24Q3
-flag {
-  name: "data_only_service_allow_emergency_call_only"
-  namespace: "telephony"
-  description: "Support emergency call only for data only cellular service."
-  bug: "296097429"
-}
-
 # OWNER=hhshin TARGET=24Q3
 flag {
   name: "support_psim_to_esim_conversion"
diff --git a/src/java/com/android/internal/telephony/NetworkTypeController.java b/src/java/com/android/internal/telephony/NetworkTypeController.java
index 9b1bd24..6a331cf 100644
--- a/src/java/com/android/internal/telephony/NetworkTypeController.java
+++ b/src/java/com/android/internal/telephony/NetworkTypeController.java
@@ -1314,6 +1314,7 @@
             mRatchetedNrBands.addAll(nrBands);
         } else {
             if (mFeatureFlags.supportNrSaRrcIdle() && mDoesPccListIndicateIdle
+                    && anchorNrCellId != mLastAnchorNrCellId
                     && isUsingPhysicalChannelConfigForRrcDetection()
                     && !mPrimaryCellChangedWhileIdle
                     && !isNrAdvancedForPccFields(nrBandwidths, nrBands)) {
@@ -1352,11 +1353,13 @@
         if (secondaryRule != null) {
             int secondaryDuration = secondaryRule.getSecondaryTimer(mSecondaryTimerState);
             long durationMillis = secondaryDuration * 1000L;
-            if ((mSecondaryTimerExpireTimestamp - SystemClock.uptimeMillis()) > durationMillis) {
+            long now = SystemClock.uptimeMillis();
+            if ((mSecondaryTimerExpireTimestamp - now) > durationMillis) {
                 if (DBG) log("Due to PCI change, reduce the secondary timer to " + durationMillis);
                 removeMessages(EVENT_SECONDARY_TIMER_EXPIRED);
                 sendMessageDelayed(EVENT_SECONDARY_TIMER_EXPIRED, mSecondaryTimerState,
                         durationMillis);
+                mSecondaryTimerExpireTimestamp = now + durationMillis;
             }
         } else {
             loge("!! Secondary timer is active, but found no rule for " + mPrimaryTimerState);
diff --git a/src/java/com/android/internal/telephony/cdnr/CarrierDisplayNameData.java b/src/java/com/android/internal/telephony/cdnr/CarrierDisplayNameData.java
index 59745dc..597bad3 100644
--- a/src/java/com/android/internal/telephony/cdnr/CarrierDisplayNameData.java
+++ b/src/java/com/android/internal/telephony/cdnr/CarrierDisplayNameData.java
@@ -18,6 +18,7 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.telephony.Rlog;
 
 import java.util.Objects;
 
@@ -25,6 +26,9 @@
  * A container of carrier display name.
  */
 public class CarrierDisplayNameData implements Parcelable {
+
+    private static final String LOG_TAG = "CarrierDisplayNameData";
+
     /** Service provider name. */
     private final String mSpn;
 
@@ -40,8 +44,18 @@
     /** {@code True} if display PLMN network name is required. */
     private final boolean mShowPlmn;
 
-    private CarrierDisplayNameData(String spn, String dataSpn, boolean showSpn, String plmn,
-            boolean showPlmn) {
+    private CarrierDisplayNameData(
+            String spn, String dataSpn, boolean showSpn, String plmn, boolean showPlmn) {
+        final String logString = "Data SPN must be provided if SPN is provided";
+        if (spn != null && dataSpn == null) {
+            Rlog.e(LOG_TAG, logString);
+            if (android.os.Build.isDebuggable()) {
+                throw new IllegalArgumentException(logString);
+            } else {
+                dataSpn = spn;
+            }
+        }
+
         this.mSpn = spn;
         this.mDataSpn = dataSpn;
         this.mShowSpn = showSpn;
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteController.java b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
index 7566ef6..672e683 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
@@ -1232,28 +1232,39 @@
                 break;
             }
 
-            case EVENT_WAIT_FOR_SATELLITE_ENABLING_RESPONSE_TIMED_OUT:
+            case EVENT_WAIT_FOR_SATELLITE_ENABLING_RESPONSE_TIMED_OUT: {
                 handleEventWaitForSatelliteEnablingResponseTimedOut(
                         (RequestSatelliteEnabledArgument) msg.obj);
                 break;
+            }
 
             case CMD_UPDATE_SATELLITE_ENABLE_ATTRIBUTES: {
                 request = (SatelliteControllerHandlerRequest) msg.obj;
                 RequestSatelliteEnabledArgument argument =
                         (RequestSatelliteEnabledArgument) request.argument;
 
+                if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
+                    plogd("UpdateEnableAttributes: carrierRoamingNbIotNtn flag is disabled");
+                    sendErrorAndReportSessionMetrics(
+                            SatelliteManager.SATELLITE_RESULT_INVALID_ARGUMENTS, argument.callback);
+                    synchronized (mSatelliteEnabledRequestLock) {
+                        mSatelliteEnableAttributesUpdateRequest = null;
+                    }
+                    break;
+                }
+
                 synchronized (mSatelliteEnabledRequestLock) {
                     if (mSatelliteEnabledRequest != null) {
                         plogd("UpdateEnableAttributes: Satellite is being enabled. Need to "
                                 + "wait until enable complete before updating attributes");
-                        return;
+                        break;
                     }
                     if (isSatelliteBeingDisabled()) {
                         plogd("UpdateEnableAttributes: Satellite is being disabled. Aborting the "
                                 + "enable attributes update request");
                         mSatelliteEnableAttributesUpdateRequest = null;
                         argument.callback.accept(SATELLITE_RESULT_REQUEST_ABORTED);
-                        return;
+                        break;
                     }
                 }
                 onCompleted = obtainMessage(EVENT_UPDATE_SATELLITE_ENABLE_ATTRIBUTES_DONE, request);
@@ -1923,6 +1934,12 @@
                      * carriers want to disable satellite for prioritizing emergency calls. Thus,
                      * we need to push the disable request to modem while enable is in progress.
                      */
+                    if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
+                        plogd("requestSatelliteEnabled: carrierRoamingNbIotNtn flag is disabled");
+                        sendErrorAndReportSessionMetrics(
+                                SatelliteManager.SATELLITE_RESULT_ENABLE_IN_PROGRESS, result);
+                        return;
+                    }
                     mSatelliteDisabledRequest = request;
                 }
             }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierDisplayNameResolverTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierDisplayNameResolverTest.java
index 2ccfe0c..17fb829 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierDisplayNameResolverTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierDisplayNameResolverTest.java
@@ -18,6 +18,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doReturn;
 
@@ -271,4 +272,14 @@
         assertThat(data.shouldShowPlmn()).isTrue();
         assertThat(data.getPlmn()).isEqualTo(HOME_PLMN_NUMERIC);
     }
+
+    @Test
+    public void testCarrierDisplayNameData_enforceNonNullDataSpn() {
+        try {
+            CarrierDisplayNameData cdnd = new CarrierDisplayNameData.Builder()
+                    .setSpn("testSpn").build();
+            fail("Expected IAE");
+        } catch (IllegalArgumentException expected) {
+        }
+    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java
index 738f765..f92643a 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java
@@ -1649,8 +1649,23 @@
                 mNetworkTypeController.getOverrideNetworkType());
         assertTrue(mNetworkTypeController.areAnyTimersActive());
 
+
+        // the timer has been reduced from 20 - 6s(advance band) to 5s(regular). Suppose passed 1s,
+        // a new PCC shouldn't affect the timer.
+        moveTimeForward(1 * 1000);
+        mNetworkTypeController.sendMessage(11 /* EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED */,
+                new AsyncResult(null, Collections.emptyList(), null));
+        mNetworkTypeController.sendMessage(11 /* EVENT_PHYSICAL_CHANNEL_CONFIGS_CHANGED */,
+                new AsyncResult(null, List.of(
+                        new PhysicalChannelConfig.Builder()
+                                .setPhysicalCellId(3)
+                                .setNetworkType(TelephonyManager.NETWORK_TYPE_NR)
+                                .setCellConnectionStatus(CellInfo.CONNECTION_PRIMARY_SERVING)
+                                .build()), null));
+        processAllMessages();
+
         // Verify the timer has been reduced from 20 - 6s(advance band) to 5s(regular).
-        moveTimeForward(5 * 1000);
+        moveTimeForward(4 * 1000);
         processAllMessages();
 
         assertEquals("connected_rrc_idle", getCurrentState().getName());
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 a9775c0..58a77a7 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
@@ -921,6 +921,7 @@
 
     @Test
     public void testRequestSatelliteEnabled() {
+        when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
         mIsSatelliteEnabledSemaphore.drainPermits();
 
         // Fail to enable satellite when SatelliteController is not fully loaded yet.