Merge "Update network request evaluation for satellite when data roaming off" into main
diff --git a/flags/calling.aconfig b/flags/calling.aconfig
index 65cfbaf..27d3518 100644
--- a/flags/calling.aconfig
+++ b/flags/calling.aconfig
@@ -71,3 +71,14 @@
     bug:"359064059"
     is_exported: true
 }
+
+# OWNER=sewookseo TARGET=25Q2
+flag {
+    name: "pass_copied_call_state_list"
+    namespace: "telephony"
+    description: "To prevent passing the TelephonyRegistry's original instance to listeners in the same process"
+    bug:"379126049"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
\ No newline at end of file
diff --git a/flags/data.aconfig b/flags/data.aconfig
index 17d1adb..4a90c10 100644
--- a/flags/data.aconfig
+++ b/flags/data.aconfig
@@ -121,7 +121,7 @@
   }
 }
 
-# OWNER=TBD TARGET=TBD
+# OWNER=jackyu TARGET=25Q2
 flag {
   name: "oem_paid_private"
   namespace: "telephony"
diff --git a/flags/misc.aconfig b/flags/misc.aconfig
index 03d1f4e..ec7b8fa 100644
--- a/flags/misc.aconfig
+++ b/flags/misc.aconfig
@@ -230,3 +230,19 @@
         purpose: PURPOSE_BUGFIX
     }
 }
+
+# OWNER=jackyu TARGET=25Q2
+flag {
+    name: "deprecate_cdma"
+    namespace: "telephony"
+    description: "Deprecate CDMA and NV APIS"
+    bug: "379356026"
+}
+
+# OWNER=jackyu TARGET=25Q2
+flag {
+    name: "cleanup_cdma"
+    namespace: "telephony"
+    description: "Disable CDMA and NV backing code"
+    bug: "379356026"
+}
diff --git a/flags/uicc.aconfig b/flags/uicc.aconfig
index edb4ce2..8561dac 100644
--- a/flags/uicc.aconfig
+++ b/flags/uicc.aconfig
@@ -118,3 +118,11 @@
     description: "This flag controls to get a group id level2."
     bug:"381171540"
 }
+
+# OWNER=jinjeong TARGET=25Q2
+flag {
+    name: "action_sim_preference_settings"
+    namespace: "telephony"
+    description: "This flag controls to launch sim preference page in Setting"
+    bug:"381319469"
+}
diff --git a/src/java/com/android/internal/telephony/DisplayInfoController.java b/src/java/com/android/internal/telephony/DisplayInfoController.java
index d3f0264..bb19a31 100644
--- a/src/java/com/android/internal/telephony/DisplayInfoController.java
+++ b/src/java/com/android/internal/telephony/DisplayInfoController.java
@@ -110,7 +110,7 @@
         mTelephonyDisplayInfo = new TelephonyDisplayInfo(
                 TelephonyManager.NETWORK_TYPE_UNKNOWN,
                 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
-                false);
+                false, false, false);
         mNetworkTypeController = new NetworkTypeController(phone, this, featureFlags);
         // EVENT_UPDATE will transition from DefaultState to the current state
         // and update the TelephonyDisplayInfo based on the current state.
@@ -132,7 +132,9 @@
         TelephonyDisplayInfo newDisplayInfo = new TelephonyDisplayInfo(
                 mNetworkTypeController.getDataNetworkType(),
                 mNetworkTypeController.getOverrideNetworkType(),
-                isRoaming());
+                isRoaming(),
+                mPhone.getServiceStateTracker().getServiceState().isUsingNonTerrestrialNetwork(),
+                mNetworkTypeController.getSatelliteConstrainedData());
         if (!newDisplayInfo.equals(mTelephonyDisplayInfo)) {
             logl("TelephonyDisplayInfo changed from " + mTelephonyDisplayInfo + " to "
                     + newDisplayInfo);
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index 5a73cae..f190a43 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -775,6 +775,7 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     @Override
     public int getPhoneType() {
+        if (mFeatureFlags.cleanupCdma()) return PhoneConstants.PHONE_TYPE_GSM;
         if (mPrecisePhoneType == PhoneConstants.PHONE_TYPE_GSM) {
             return PhoneConstants.PHONE_TYPE_GSM;
         } else {
diff --git a/src/java/com/android/internal/telephony/InboundSmsHandler.java b/src/java/com/android/internal/telephony/InboundSmsHandler.java
index f404e04..52ceda5 100644
--- a/src/java/com/android/internal/telephony/InboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/InboundSmsHandler.java
@@ -764,6 +764,15 @@
             return Intents.RESULT_SMS_HANDLED;
         }
 
+        if (mFeatureFlags.carrierRoamingNbIotNtn()) {
+            SatelliteController satelliteController = SatelliteController.getInstance();
+            if (satelliteController != null
+                    && satelliteController.shouldDropSms(mPhone)) {
+                log("SMS not supported during satellite session.");
+                return Intents.RESULT_SMS_HANDLED;
+            }
+        }
+
         int result = dispatchMessageRadioSpecific(smsb, smsSource, token);
 
         // In case of error, add to metrics. This is not required in case of success, as the
diff --git a/src/java/com/android/internal/telephony/NetworkTypeController.java b/src/java/com/android/internal/telephony/NetworkTypeController.java
index 081a5c8..b12a3df 100644
--- a/src/java/com/android/internal/telephony/NetworkTypeController.java
+++ b/src/java/com/android/internal/telephony/NetworkTypeController.java
@@ -22,7 +22,13 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
 import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.Message;
 import android.os.PersistableBundle;
 import android.os.PowerManager;
@@ -233,6 +239,72 @@
     private boolean mDoesPccListIndicateIdle = false;
 
     private boolean mInVoiceCall = false;
+    private boolean mIsSatelliteConstrainedData = false;
+    private boolean mIsSatelliteNetworkCallbackRegistered = false;
+    private ConnectivityManager mConnectivityManager;
+
+    private final ConnectivityManager.NetworkCallback mNetworkCallback =
+            new ConnectivityManager.NetworkCallback() {
+                @Override
+                public void onAvailable(Network network) {
+                    log("On Available: " + network);
+                    if (network != null) {
+                        if (mConnectivityManager != null) {
+                            NetworkCapabilities capabilities =
+                                    mConnectivityManager.getNetworkCapabilities(network);
+                            updateBandwidthConstrainedStatus(capabilities);
+                        } else {
+                            log("network is null");
+                        }
+                    }
+                }
+
+                @Override
+                public void onCapabilitiesChanged(Network network,
+                        NetworkCapabilities networkCapabilities) {
+                    log("onCapabilitiesChanged: " + network);
+                    if (network != null) {
+                        updateBandwidthConstrainedStatus(networkCapabilities);
+                    } else {
+                        log("network is null");
+                    }
+                }
+
+                @Override
+                public void onLost(Network network) {
+                    log("Network Lost");
+                    if (mIsSatelliteConstrainedData) {
+                        mIsSatelliteConstrainedData = false;
+                        mDisplayInfoController.updateTelephonyDisplayInfo();
+                    }
+                }
+            };
+
+    private boolean isBandwidthConstrainedCapabilitySupported(NetworkCapabilities
+            capabilities) {
+        // TODO (b/382002908: Remove try catch exception for
+        //  NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED & replace datautils with
+        //  NetworkCapabilities on api availability at mainline module)
+        try {
+            return capabilities.hasTransport(
+                    NetworkCapabilities.TRANSPORT_SATELLITE) &&
+                    !capabilities.hasCapability(DataUtils.NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED);
+        } catch (Exception ignored) {
+            log("NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED not supported ");
+            return false;
+        }
+    }
+
+    private void updateBandwidthConstrainedStatus(NetworkCapabilities capabilities) {
+        if (capabilities != null) {
+            mIsSatelliteConstrainedData
+                    = isBandwidthConstrainedCapabilitySupported(capabilities);
+            log("satellite constrained data status : " + mIsSatelliteConstrainedData);
+            mDisplayInfoController.updateTelephonyDisplayInfo();
+        } else {
+            log("capabilities is null");
+        }
+    }
 
     /**
      * NetworkTypeController constructor.
@@ -266,9 +338,42 @@
         mServiceState = mPhone.getServiceStateTracker().getServiceState();
         mPhysicalChannelConfigs = mPhone.getServiceStateTracker().getPhysicalChannelConfigList();
 
+        if(mFeatureFlags.carrierEnabledSatelliteFlag()) {
+            registerForSatelliteNetwork();
+        }
+
         sendMessage(EVENT_INITIALIZE);
     }
 
+    public synchronized void registerForSatelliteNetwork() {
+        if (!mIsSatelliteNetworkCallbackRegistered) {
+            mIsSatelliteNetworkCallbackRegistered = true;
+            HandlerThread handlerThread = new HandlerThread("SatelliteDataUsageThread");
+            handlerThread.start();
+            Handler handler = new Handler(handlerThread.getLooper());
+
+            NetworkRequest.Builder builder = new NetworkRequest.Builder();
+            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+            // TODO (b/382002908: Remove try catch exception for
+            //  NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED & replace datautils with
+            //  NetworkCapabilities on api availability at mainline module)
+            try {
+                builder.removeCapability(DataUtils.NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED);
+            } catch (Exception ignored) {
+                log("NET_CAPABILITY_NOT_BANDWIDTH_CONSTRAINED not supported ");
+            }
+            mConnectivityManager =
+                    (ConnectivityManager) mPhone.getContext()
+                            .getSystemService(Context.CONNECTIVITY_SERVICE);
+            if (mConnectivityManager != null) {
+                mConnectivityManager.registerBestMatchingNetworkCallback(
+                        builder.build(), mNetworkCallback, handler);
+            } else {
+                loge("network callback not registered");
+            }
+        }
+    }
+
     /**
      * @return The current override network type, used to create TelephonyDisplayInfo in
      * DisplayInfoController.
@@ -289,6 +394,15 @@
     }
 
     /**
+     * @return satellite bandwidth constrained connection status, used to create
+     * TelephonyDisplayInfo in DisplayInfoController.
+     *
+     */
+    public boolean getSatelliteConstrainedData() {
+       return mIsSatelliteConstrainedData;
+    }
+
+    /**
      * @return {@code true} if either the primary or secondary 5G icon timers are active,
      * and {@code false} if neither are.
      */
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index 5998d46..0c645a0 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -2284,6 +2284,7 @@
      * @param response is callback message to report one of TelephonyManager#CDMA_ROAMING_MODE_*
      */
     public void queryCdmaRoamingPreference(Message response) {
+        if (mFeatureFlags.cleanupCdma()) return;
         mCi.queryCdmaRoamingPreference(response);
     }
 
@@ -2293,6 +2294,7 @@
      * @param response is callback message to report one of TelephonyManager#CDMA_SUBSCRIPTION_*
      */
     public void queryCdmaSubscriptionMode(Message response) {
+        if (mFeatureFlags.cleanupCdma()) return;
         mCi.getCdmaSubscriptionSource(response);
     }
 
@@ -2330,6 +2332,7 @@
      * @param response is callback message
      */
     public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
+        if (mFeatureFlags.cleanupCdma()) return;
         mCi.setCdmaRoamingPreference(cdmaRoamingType, response);
     }
 
@@ -2339,6 +2342,7 @@
      * @param response is callback message
      */
     public void setCdmaSubscriptionMode(int cdmaSubscriptionType, Message response) {
+        if (mFeatureFlags.cleanupCdma()) return;
         mCi.setCdmaSubscriptionSource(cdmaSubscriptionType, response);
     }
 
@@ -2775,6 +2779,7 @@
      * @param workSource calling WorkSource
      */
     public void nvReadItem(int itemID, Message response, WorkSource workSource) {
+        if (mFeatureFlags.cleanupCdma()) return;
         mCi.nvReadItem(itemID, response, workSource);
     }
 
@@ -2789,6 +2794,7 @@
      */
     public void nvWriteItem(int itemID, String itemValue, Message response,
             WorkSource workSource) {
+        if (mFeatureFlags.cleanupCdma()) return;
         mCi.nvWriteItem(itemID, itemValue, response, workSource);
     }
 
@@ -2800,6 +2806,7 @@
      * @param response Callback message.
      */
     public void nvWriteCdmaPrl(byte[] preferredRoamingList, Message response) {
+        if (mFeatureFlags.cleanupCdma()) return;
         mCi.nvWriteCdmaPrl(preferredRoamingList, response);
     }
 
@@ -2821,6 +2828,7 @@
      * @param response Callback message.
      */
     public void resetModemConfig(Message response) {
+        if (mFeatureFlags.cleanupCdma()) return;
         mCi.nvResetConfig(3 /* factory NV reset */, response);
     }
 
@@ -2830,6 +2838,7 @@
      * @param response Callback message.
      */
     public void eraseModemConfig(Message response) {
+        if (mFeatureFlags.cleanupCdma()) return;
         mCi.nvResetConfig(2 /* erase NV */, response);
     }
 
@@ -3511,6 +3520,7 @@
      * @param obj User object.
      */
     public void registerForNumberInfo(Handler h, int what, Object obj) {
+        if (mFeatureFlags.cleanupCdma()) return;
         mCi.registerForNumberInfo(h, what, obj);
     }
 
@@ -3521,6 +3531,7 @@
      * @param h Handler to be removed from the registrant list.
      */
     public void unregisterForNumberInfo(Handler h) {
+        if (mFeatureFlags.cleanupCdma()) return;
         mCi.unregisterForNumberInfo(h);
     }
 
@@ -3536,6 +3547,7 @@
      * @param obj User object.
      */
     public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) {
+        if (mFeatureFlags.cleanupCdma()) return;
         mCi.registerForRedirectedNumberInfo(h, what, obj);
     }
 
@@ -3546,6 +3558,7 @@
      * @param h Handler to be removed from the registrant list.
      */
     public void unregisterForRedirectedNumberInfo(Handler h) {
+        if (mFeatureFlags.cleanupCdma()) return;
         mCi.unregisterForRedirectedNumberInfo(h);
     }
 
@@ -3561,6 +3574,7 @@
      * @param obj User object.
      */
     public void registerForLineControlInfo(Handler h, int what, Object obj) {
+        if (mFeatureFlags.cleanupCdma()) return;
         mCi.registerForLineControlInfo(h, what, obj);
     }
 
@@ -3571,6 +3585,7 @@
      * @param h Handler to be removed from the registrant list.
      */
     public void unregisterForLineControlInfo(Handler h) {
+        if (mFeatureFlags.cleanupCdma()) return;
         mCi.unregisterForLineControlInfo(h);
     }
 
@@ -3586,6 +3601,7 @@
      * @param obj User object.
      */
     public void registerFoT53ClirlInfo(Handler h, int what, Object obj) {
+        if (mFeatureFlags.cleanupCdma()) return;
         mCi.registerFoT53ClirlInfo(h, what, obj);
     }
 
@@ -3596,6 +3612,7 @@
      * @param h Handler to be removed from the registrant list.
      */
     public void unregisterForT53ClirInfo(Handler h) {
+        if (mFeatureFlags.cleanupCdma()) return;
         mCi.unregisterForT53ClirInfo(h);
     }
 
@@ -3611,6 +3628,7 @@
      * @param obj User object.
      */
     public void registerForT53AudioControlInfo(Handler h, int what, Object obj) {
+        if (mFeatureFlags.cleanupCdma()) return;
         mCi.registerForT53AudioControlInfo(h, what, obj);
     }
 
@@ -3621,6 +3639,7 @@
      * @param h Handler to be removed from the registrant list.
      */
     public void unregisterForT53AudioControlInfo(Handler h) {
+        if (mFeatureFlags.cleanupCdma()) return;
         mCi.unregisterForT53AudioControlInfo(h);
     }
 
@@ -4159,8 +4178,11 @@
 
         setRoamingOverrideHelper(gsmRoamingList, GSM_ROAMING_LIST_OVERRIDE_PREFIX, iccId);
         setRoamingOverrideHelper(gsmNonRoamingList, GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX, iccId);
-        setRoamingOverrideHelper(cdmaRoamingList, CDMA_ROAMING_LIST_OVERRIDE_PREFIX, iccId);
-        setRoamingOverrideHelper(cdmaNonRoamingList, CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX, iccId);
+        if (!mFeatureFlags.cleanupCdma()) {
+            setRoamingOverrideHelper(cdmaRoamingList, CDMA_ROAMING_LIST_OVERRIDE_PREFIX, iccId);
+            setRoamingOverrideHelper(cdmaNonRoamingList, CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX,
+                    iccId);
+        }
 
         // Refresh.
         ServiceStateTracker tracker = getServiceStateTracker();
diff --git a/src/java/com/android/internal/telephony/RIL.java b/src/java/com/android/internal/telephony/RIL.java
index 1bb9984..b2550a2 100644
--- a/src/java/com/android/internal/telephony/RIL.java
+++ b/src/java/com/android/internal/telephony/RIL.java
@@ -1125,6 +1125,9 @@
             SparseArray<RadioServiceProxy> proxies, @NonNull FeatureFlags flags) {
         super(context);
         mFeatureFlags = flags;
+        if (mFeatureFlags.cleanupCdma()) {
+            cdmaSubscription = TelephonyManager.CDMA_SUBSCRIPTION_UNKNOWN;
+        }
         if (RILJ_LOGD) {
             riljLog("RIL: init allowedNetworkTypes=" + allowedNetworkTypes
                     + " cdmaSubscription=" + cdmaSubscription + ")");
@@ -3218,6 +3221,8 @@
 
     @Override
     public void setCdmaSubscriptionSource(int cdmaSubscription, Message result) {
+        if (mFeatureFlags.cleanupCdma()) return;
+
         RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class);
         if (!canMakeRequest("setCdmaSubscriptionSource", simProxy, result, RADIO_HAL_VERSION_1_4)) {
             return;
@@ -3238,6 +3243,8 @@
 
     @Override
     public void queryCdmaRoamingPreference(Message result) {
+        if (mFeatureFlags.cleanupCdma()) return;
+
         RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class);
         if (!canMakeRequest("queryCdmaRoamingPreference", networkProxy, result,
                 RADIO_HAL_VERSION_1_4)) {
@@ -3258,6 +3265,8 @@
 
     @Override
     public void setCdmaRoamingPreference(int cdmaRoamingType, Message result) {
+        if (mFeatureFlags.cleanupCdma()) return;
+
         RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class);
         if (!canMakeRequest("setCdmaRoamingPreference", networkProxy, result,
                 RADIO_HAL_VERSION_1_4)) {
@@ -3357,6 +3366,8 @@
 
     @Override
     public void sendCDMAFeatureCode(String featureCode, Message result) {
+        if (mFeatureFlags.cleanupCdma()) return;
+
         RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class);
         if (!canMakeRequest("sendCDMAFeatureCode", voiceProxy, result, RADIO_HAL_VERSION_1_4)) {
             return;
@@ -3397,6 +3408,8 @@
 
     @Override
     public void sendCdmaSMSExpectMore(byte[] pdu, Message result) {
+        if (mFeatureFlags.cleanupCdma()) return;
+
         RadioMessagingProxy messagingProxy = getRadioServiceProxy(RadioMessagingProxy.class);
         if (!canMakeRequest("sendCdmaSMSExpectMore", messagingProxy, result,
                 RADIO_HAL_VERSION_1_4)) {
@@ -3423,6 +3436,8 @@
 
     @Override
     public void sendCdmaSms(byte[] pdu, Message result) {
+        if (mFeatureFlags.cleanupCdma()) return;
+
         RadioMessagingProxy messagingProxy = getRadioServiceProxy(RadioMessagingProxy.class);
         if (!canMakeRequest("sendCdmaSms", messagingProxy, result, RADIO_HAL_VERSION_1_4)) {
             return;
@@ -3444,6 +3459,8 @@
 
     @Override
     public void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message result) {
+        if (mFeatureFlags.cleanupCdma()) return;
+
         RadioMessagingProxy messagingProxy = getRadioServiceProxy(RadioMessagingProxy.class);
         if (!canMakeRequest("acknowledgeLastIncomingCdmaSms", messagingProxy, result,
                 RADIO_HAL_VERSION_1_4)) {
@@ -3531,6 +3548,8 @@
 
     @Override
     public void getCdmaBroadcastConfig(Message result) {
+        if (mFeatureFlags.cleanupCdma()) return;
+
         RadioMessagingProxy messagingProxy = getRadioServiceProxy(RadioMessagingProxy.class);
         if (!canMakeRequest("getCdmaBroadcastConfig", messagingProxy, result,
                 RADIO_HAL_VERSION_1_4)) {
@@ -3551,6 +3570,8 @@
 
     @Override
     public void setCdmaBroadcastConfig(CdmaSmsBroadcastConfigInfo[] configs, Message result) {
+        if (mFeatureFlags.cleanupCdma()) return;
+
         RadioMessagingProxy messagingProxy = getRadioServiceProxy(RadioMessagingProxy.class);
         if (!canMakeRequest("setCdmaBroadcastConfig", messagingProxy, result,
                 RADIO_HAL_VERSION_1_4)) {
@@ -3575,6 +3596,8 @@
 
     @Override
     public void setCdmaBroadcastActivation(boolean activate, Message result) {
+        if (mFeatureFlags.cleanupCdma()) return;
+
         RadioMessagingProxy messagingProxy = getRadioServiceProxy(RadioMessagingProxy.class);
         if (!canMakeRequest("setCdmaBroadcastActivation", messagingProxy, result,
                 RADIO_HAL_VERSION_1_4)) {
@@ -3596,6 +3619,8 @@
 
     @Override
     public void getCDMASubscription(Message result) {
+        if (mFeatureFlags.cleanupCdma()) return;
+
         RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class);
         if (!canMakeRequest("getCDMASubscription", simProxy, result, RADIO_HAL_VERSION_1_4)) {
             return;
@@ -3634,6 +3659,8 @@
 
     @Override
     public void deleteSmsOnRuim(int index, Message result) {
+        if (mFeatureFlags.cleanupCdma()) return;
+
         RadioMessagingProxy messagingProxy = getRadioServiceProxy(RadioMessagingProxy.class);
         if (!canMakeRequest("deleteSmsOnRuim", messagingProxy, result, RADIO_HAL_VERSION_1_4)) {
             return;
@@ -3787,6 +3814,8 @@
 
     @Override
     public void getCdmaSubscriptionSource(Message result) {
+        if (mFeatureFlags.cleanupCdma()) return;
+
         RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class);
         if (!canMakeRequest("getCdmaSubscriptionSource", simProxy, result, RADIO_HAL_VERSION_1_4)) {
             return;
@@ -4074,6 +4103,8 @@
 
     @Override
     public void nvReadItem(int itemID, Message result, WorkSource workSource) {
+        if (mFeatureFlags.cleanupCdma()) return;
+
         RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class);
         if (!canMakeRequest("nvReadItem", modemProxy, result, RADIO_HAL_VERSION_1_4)) {
             return;
@@ -4094,6 +4125,8 @@
 
     @Override
     public void nvWriteItem(int itemId, String itemValue, Message result, WorkSource workSource) {
+        if (mFeatureFlags.cleanupCdma()) return;
+
         RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class);
         if (!canMakeRequest("nvWriteItem", modemProxy, result, RADIO_HAL_VERSION_1_4)) {
             return;
@@ -4115,6 +4148,8 @@
 
     @Override
     public void nvWriteCdmaPrl(byte[] preferredRoamingList, Message result) {
+        if (mFeatureFlags.cleanupCdma()) return;
+
         RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class);
         if (!canMakeRequest("nvWriteCdmaPrl", modemProxy, result, RADIO_HAL_VERSION_1_4)) {
             return;
@@ -4135,6 +4170,9 @@
 
     @Override
     public void nvResetConfig(int resetType, Message result) {
+        // Disable all NV reset functions except modem restart.
+        if (mFeatureFlags.cleanupCdma() && resetType != 1) return;
+
         RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class);
         if (!canMakeRequest("nvResetConfig", modemProxy, result, RADIO_HAL_VERSION_1_4)) {
             return;
@@ -6118,6 +6156,8 @@
 
     @UnsupportedAppUsage
     void notifyRegistrantsCdmaInfoRec(CdmaInformationRecords infoRec) {
+        if (mFeatureFlags.cleanupCdma()) return;
+
         int response = RIL_UNSOL_CDMA_INFO_REC;
         if (infoRec.record instanceof CdmaInformationRecords.CdmaDisplayInfoRec) {
             if (mDisplayInfoRegistrants != null) {
diff --git a/src/java/com/android/internal/telephony/RILUtils.java b/src/java/com/android/internal/telephony/RILUtils.java
index e39e135..fb07fb3 100644
--- a/src/java/com/android/internal/telephony/RILUtils.java
+++ b/src/java/com/android/internal/telephony/RILUtils.java
@@ -387,6 +387,7 @@
 import com.android.internal.telephony.cdma.sms.SmsEnvelope;
 import com.android.internal.telephony.data.KeepaliveStatus;
 import com.android.internal.telephony.data.KeepaliveStatus.KeepaliveStatusCode;
+import com.android.internal.telephony.flags.Flags;
 import com.android.internal.telephony.imsphone.ImsCallInfo;
 import com.android.internal.telephony.uicc.AdnCapacity;
 import com.android.internal.telephony.uicc.IccCardApplicationStatus;
@@ -397,6 +398,7 @@
 import com.android.internal.telephony.uicc.IccUtils;
 import com.android.internal.telephony.uicc.PortUtils;
 import com.android.internal.telephony.uicc.SimPhonebookRecord;
+import com.android.internal.telephony.uicc.SimTypeInfo;
 import com.android.telephony.Rlog;
 
 import java.io.ByteArrayInputStream;
@@ -1172,6 +1174,10 @@
          * 2 - erase NV reset (SCRTN)
          * 3 - factory reset (RTN)
          */
+        if (Flags.cleanupCdma()) {
+            if (resetType == 1) return android.hardware.radio.V1_0.ResetNvType.RELOAD;
+            return -1;
+        }
         switch (resetType) {
             case 1: return android.hardware.radio.V1_0.ResetNvType.RELOAD;
             case 2: return android.hardware.radio.V1_0.ResetNvType.ERASE;
@@ -1192,6 +1198,10 @@
          * 2 - erase NV reset (SCRTN)
          * 3 - factory reset (RTN)
          */
+        if (Flags.cleanupCdma()) {
+            if (resetType == 1) return android.hardware.radio.modem.ResetNvType.RELOAD;
+            return -1;
+        }
         switch (resetType) {
             case 1: return android.hardware.radio.modem.ResetNvType.RELOAD;
             case 2: return android.hardware.radio.modem.ResetNvType.ERASE;
@@ -2916,6 +2926,7 @@
      */
     public static CellSignalStrengthGsm convertHalGsmSignalStrength(
             android.hardware.radio.V1_0.GsmSignalStrength ss) {
+        if (ss == null) return new CellSignalStrengthGsm();
         CellSignalStrengthGsm ret = new CellSignalStrengthGsm(
                 CellSignalStrength.getRssiDbmFromAsu(ss.signalStrength), ss.bitErrorRate,
                 ss.timingAdvance);
@@ -2933,6 +2944,7 @@
      */
     public static CellSignalStrengthGsm convertHalGsmSignalStrength(
             android.hardware.radio.network.GsmSignalStrength ss) {
+        if (ss == null) return new CellSignalStrengthGsm();
         CellSignalStrengthGsm ret = new CellSignalStrengthGsm(
                 CellSignalStrength.getRssiDbmFromAsu(ss.signalStrength), ss.bitErrorRate,
                 ss.timingAdvance);
@@ -2953,6 +2965,7 @@
     public static CellSignalStrengthCdma convertHalCdmaSignalStrength(
             android.hardware.radio.V1_0.CdmaSignalStrength cdma,
             android.hardware.radio.V1_0.EvdoSignalStrength evdo) {
+        if (cdma == null || evdo == null) return new CellSignalStrengthCdma();
         return new CellSignalStrengthCdma(-cdma.dbm, -cdma.ecio, -evdo.dbm, -evdo.ecio,
                 evdo.signalNoiseRatio);
     }
@@ -2967,6 +2980,7 @@
     public static CellSignalStrengthCdma convertHalCdmaSignalStrength(
             android.hardware.radio.network.CdmaSignalStrength cdma,
             android.hardware.radio.network.EvdoSignalStrength evdo) {
+        if (cdma == null || evdo == null) return new CellSignalStrengthCdma();
         return new CellSignalStrengthCdma(-cdma.dbm, -cdma.ecio, -evdo.dbm, -evdo.ecio,
                 evdo.signalNoiseRatio);
     }
@@ -3430,9 +3444,11 @@
             android.hardware.radio.data.SetupDataCallResult result) {
         if (result == null) return null;
         List<LinkAddress> laList = new ArrayList<>();
-        for (android.hardware.radio.data.LinkAddress la : result.addresses) {
-            laList.add(convertToLinkAddress(la.address, la.addressProperties,
-                    la.deprecationTime, la.expirationTime));
+        if (result.addresses != null) {
+            for (android.hardware.radio.data.LinkAddress la : result.addresses) {
+                laList.add(convertToLinkAddress(la.address, la.addressProperties,
+                        la.deprecationTime, la.expirationTime));
+            }
         }
         List<InetAddress> dnsList = new ArrayList<>();
         if (result.dnses != null) {
@@ -3474,15 +3490,19 @@
             }
         }
         List<QosBearerSession> qosSessions = new ArrayList<>();
-        for (android.hardware.radio.data.QosSession session : result.qosSessions) {
-            qosSessions.add(convertHalQosBearerSession(session));
+        if (result.qosSessions != null) {
+            for (android.hardware.radio.data.QosSession session : result.qosSessions) {
+                qosSessions.add(convertHalQosBearerSession(session));
+            }
         }
         List<TrafficDescriptor> trafficDescriptors = new ArrayList<>();
-        for (android.hardware.radio.data.TrafficDescriptor td : result.trafficDescriptors) {
-            try {
-                trafficDescriptors.add(convertHalTrafficDescriptor(td));
-            } catch (IllegalArgumentException e) {
-                loge("convertHalDataCallResult: Failed to convert traffic descriptor. e=" + e);
+        if (result.trafficDescriptors != null) {
+            for (android.hardware.radio.data.TrafficDescriptor td : result.trafficDescriptors) {
+                try {
+                    trafficDescriptors.add(convertHalTrafficDescriptor(td));
+                } catch (IllegalArgumentException e) {
+                    loge("convertHalDataCallResult: Failed to convert traffic descriptor. e=" + e);
+                }
             }
         }
 
@@ -3662,6 +3682,7 @@
     }
 
     private static Qos convertHalQos(android.hardware.radio.V1_6.Qos qos) {
+        if (qos == null) return null;
         switch (qos.getDiscriminator()) {
             case android.hardware.radio.V1_6.Qos.hidl_discriminator.eps:
                 android.hardware.radio.V1_6.EpsQos eps = qos.eps();
@@ -3677,6 +3698,7 @@
     }
 
     private static Qos convertHalQos(android.hardware.radio.data.Qos qos) {
+        if (qos == null) return null;
         switch (qos.getTag()) {
             case android.hardware.radio.data.Qos.eps:
                 android.hardware.radio.data.EpsQos eps = qos.getEps();
@@ -4222,7 +4244,8 @@
             iccCardStatus.setCardState(cardStatus10.cardState);
             iccCardStatus.setUniversalPinState(cardStatus10.universalPinState);
             iccCardStatus.mGsmUmtsSubscriptionAppIndex = cardStatus10.gsmUmtsSubscriptionAppIndex;
-            iccCardStatus.mCdmaSubscriptionAppIndex = cardStatus10.cdmaSubscriptionAppIndex;
+            iccCardStatus.mCdmaSubscriptionAppIndex =
+                    Flags.cleanupCdma() ? -1 : cardStatus10.cdmaSubscriptionAppIndex;
             iccCardStatus.mImsSubscriptionAppIndex = cardStatus10.imsSubscriptionAppIndex;
             int numApplications = cardStatus10.applications.size();
 
@@ -4292,7 +4315,8 @@
         iccCardStatus.setMultipleEnabledProfilesMode(cardStatus.supportedMepMode);
         iccCardStatus.setUniversalPinState(cardStatus.universalPinState);
         iccCardStatus.mGsmUmtsSubscriptionAppIndex = cardStatus.gsmUmtsSubscriptionAppIndex;
-        iccCardStatus.mCdmaSubscriptionAppIndex = cardStatus.cdmaSubscriptionAppIndex;
+        iccCardStatus.mCdmaSubscriptionAppIndex =
+                Flags.cleanupCdma() ? -1 : cardStatus.cdmaSubscriptionAppIndex;
         iccCardStatus.mImsSubscriptionAppIndex = cardStatus.imsSubscriptionAppIndex;
         iccCardStatus.atr = cardStatus.atr;
         iccCardStatus.iccid = cardStatus.iccid;
@@ -5879,6 +5903,23 @@
                 securityAlgorithmUpdate.isUnprotectedEmergency);
     }
 
+    /** Convert an AIDL-based SimTypeInfo to its Java wrapper. */
+    public static ArrayList<SimTypeInfo> convertAidlSimTypeInfo(
+            android.hardware.radio.config.SimTypeInfo[] simTypeInfos) {
+        ArrayList<SimTypeInfo> response = new ArrayList<>();
+        if (simTypeInfos == null) {
+            loge("convertAidlSimTypeInfo received NULL simTypeInfos");
+            return response;
+        }
+        for (android.hardware.radio.config.SimTypeInfo simTypeInfo : simTypeInfos) {
+            SimTypeInfo info = new SimTypeInfo();
+            info.mSupportedSimTypes = simTypeInfo.supportedSimTypes;
+            info.setCurrentSimType(simTypeInfo.currentSimType);
+            response.add(info);
+        }
+        return response;
+    }
+
     private static void logd(String log) {
         Rlog.d("RILUtils", log);
     }
diff --git a/src/java/com/android/internal/telephony/RadioConfigProxy.java b/src/java/com/android/internal/telephony/RadioConfigProxy.java
index 9f34e29..153747b 100644
--- a/src/java/com/android/internal/telephony/RadioConfigProxy.java
+++ b/src/java/com/android/internal/telephony/RadioConfigProxy.java
@@ -281,7 +281,11 @@
         }
 
         public void linkToDeath(long cookie) throws RemoteException {
-            mService.linkToDeath(this, cookie);
+            if (mService != null) {
+                mService.linkToDeath(this, cookie);
+            } else {
+                Rlog.w(TAG, "linkToDeath: skipping since mService is null");
+            }
         }
 
         public void clear() {
@@ -316,7 +320,11 @@
         }
 
         public void linkToDeath(int cookie) throws RemoteException {
-            mService.linkToDeath(this, cookie);
+            if (mService != null) {
+                mService.linkToDeath(this, cookie);
+            } else {
+                Rlog.w(TAG, "linkToDeath: skipping since mService is null");
+            }
         }
 
         public void clear() {
diff --git a/src/java/com/android/internal/telephony/RadioConfigResponseAidl.java b/src/java/com/android/internal/telephony/RadioConfigResponseAidl.java
index 0a41b11..6142fc2 100644
--- a/src/java/com/android/internal/telephony/RadioConfigResponseAidl.java
+++ b/src/java/com/android/internal/telephony/RadioConfigResponseAidl.java
@@ -21,10 +21,10 @@
 import android.telephony.PhoneCapability;
 
 import com.android.internal.telephony.uicc.IccSlotStatus;
+import com.android.internal.telephony.uicc.SimTypeInfo;
 import com.android.telephony.Rlog;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Set;
 
 /**
@@ -47,8 +47,7 @@
      */
     @Override
     public void getHalDeviceCapabilitiesResponse(
-            android.hardware.radio.RadioResponseInfo info,
-            boolean modemReducedFeatureSet1) throws RemoteException {
+            RadioResponseInfo info, boolean modemReducedFeatureSet1) throws RemoteException {
         // convert hal device capabilities to RadioInterfaceCapabilities
         RILRequest rr = mRadioConfig.processResponse(info);
         if (rr != null) {
@@ -71,8 +70,7 @@
      */
     @Override
     public void getNumOfLiveModemsResponse(
-            android.hardware.radio.RadioResponseInfo info, byte numOfLiveModems)
-            throws RemoteException {
+            RadioResponseInfo info, byte numOfLiveModems) throws RemoteException {
         RILRequest rr = mRadioConfig.processResponse(info);
         if (rr != null) {
             if (info.error == android.hardware.radio.RadioError.NONE) {
@@ -93,9 +91,8 @@
      */
     @Override
     public void getPhoneCapabilityResponse(
-            android.hardware.radio.RadioResponseInfo info,
-            android.hardware.radio.config.PhoneCapability phoneCapability)
-            throws RemoteException {
+            RadioResponseInfo info,
+            android.hardware.radio.config.PhoneCapability phoneCapability) throws RemoteException {
         RILRequest rr = mRadioConfig.processResponse(info);
         if (rr != null) {
             PhoneCapability ret = RILUtils.convertHalPhoneCapability(
@@ -118,9 +115,7 @@
      */
     @Override
     public void getSimultaneousCallingSupportResponse(
-            android.hardware.radio.RadioResponseInfo info,
-            int[] enabledLogicalSlots)
-            throws RemoteException {
+            RadioResponseInfo info, int[] enabledLogicalSlots) throws RemoteException {
         RILRequest rr = mRadioConfig.processResponse(info);
         if (rr != null) {
             ArrayList<Integer> ret = RILUtils.primitiveArrayToArrayList(enabledLogicalSlots);
@@ -142,7 +137,7 @@
      */
     @Override
     public void getSimSlotsStatusResponse(
-            android.hardware.radio.RadioResponseInfo info,
+            RadioResponseInfo info,
             android.hardware.radio.config.SimSlotStatus[] slotStatus)
             throws RemoteException {
         RILRequest rr = mRadioConfig.processResponse(info);
@@ -166,8 +161,7 @@
      * Currently this is being used as the callback for RadioConfig.setNumOfLiveModems() method
      */
     @Override
-    public void setNumOfLiveModemsResponse(
-            android.hardware.radio.RadioResponseInfo info) throws RemoteException {
+    public void setNumOfLiveModemsResponse(RadioResponseInfo info) throws RemoteException {
         RILRequest rr = mRadioConfig.processResponse(info);
         if (rr != null) {
             if (info.error == android.hardware.radio.RadioError.NONE) {
@@ -187,8 +181,7 @@
      * Response function for IRadioConfig.setPreferredDataModem().
      */
     @Override
-    public void setPreferredDataModemResponse(
-            android.hardware.radio.RadioResponseInfo info) throws RemoteException {
+    public void setPreferredDataModemResponse(RadioResponseInfo info) throws RemoteException {
         RILRequest rr = mRadioConfig.processResponse(info);
         if (rr != null) {
             if (info.error == android.hardware.radio.RadioError.NONE) {
@@ -208,8 +201,7 @@
      * Response function for IRadioConfig.setSimSlotsMapping().
      */
     @Override
-    public void setSimSlotsMappingResponse(
-            android.hardware.radio.RadioResponseInfo info) throws RemoteException {
+    public void setSimSlotsMappingResponse(RadioResponseInfo info) throws RemoteException {
         RILRequest rr = mRadioConfig.processResponse(info);
         if (rr != null) {
             if (info.error == android.hardware.radio.RadioError.NONE) {
@@ -225,6 +217,48 @@
         }
     }
 
+    /**
+     * Response function for IRadioConfig.getSimTypeInfo().
+     */
+    @Override
+    public void getSimTypeInfoResponse(
+            RadioResponseInfo info,
+            android.hardware.radio.config.SimTypeInfo[] simTypeInfo) throws RemoteException {
+        RILRequest rr = mRadioConfig.processResponse(info);
+        if (rr != null) {
+            ArrayList<SimTypeInfo> ret = RILUtils.convertAidlSimTypeInfo(simTypeInfo);
+            if (info.error == android.hardware.radio.RadioError.NONE) {
+                // send response
+                RadioResponse.sendMessageResponse(rr.mResult, ret);
+                logd(rr, RILUtils.requestToString(rr.mRequest) + " " + ret.toString());
+            } else {
+                rr.onError(info.error, null);
+                loge(rr, RILUtils.requestToString(rr.mRequest) + " error " + info.error);
+            }
+        } else {
+            loge("getSimTypeInfoResponse: Error " + info.toString());
+        }
+    }
+
+    /**
+     * Response function for IRadioConfig.setSimTypeResponse().
+     */
+    @Override
+    public void setSimTypeResponse(RadioResponseInfo info) throws RemoteException {
+        RILRequest rr = mRadioConfig.processResponse(info);
+        if (rr != null) {
+            if (info.error == android.hardware.radio.RadioError.NONE) {
+                // send response
+                RadioResponse.sendMessageResponse(rr.mResult, null);
+                logd(rr, RILUtils.requestToString(rr.mRequest));
+            } else {
+                rr.onError(info.error, null);
+                loge(rr, RILUtils.requestToString(rr.mRequest) + " error " + info.error);
+            }
+        } else {
+            loge("setSimTypeResponse: Error " + info.toString());
+        }
+    }
     private static void logd(String log) {
         Rlog.d(TAG, log);
     }
diff --git a/src/java/com/android/internal/telephony/RadioMessagingProxy.java b/src/java/com/android/internal/telephony/RadioMessagingProxy.java
index c652284..624c82d 100644
--- a/src/java/com/android/internal/telephony/RadioMessagingProxy.java
+++ b/src/java/com/android/internal/telephony/RadioMessagingProxy.java
@@ -20,6 +20,7 @@
 import android.telephony.Rlog;
 
 import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
+import com.android.internal.telephony.flags.Flags;
 import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
 
 import java.util.ArrayList;
@@ -107,6 +108,7 @@
      */
     public void acknowledgeLastIncomingCdmaSms(int serial, boolean success, int cause)
             throws RemoteException {
+        if (Flags.cleanupCdma()) return;
         if (isEmpty()) return;
         if (isAidl()) {
             android.hardware.radio.messaging.CdmaSmsAck msg =
@@ -147,6 +149,7 @@
      * @throws RemoteException
      */
     public void deleteSmsOnRuim(int serial, int index) throws RemoteException {
+        if (Flags.cleanupCdma()) return;
         if (isEmpty()) return;
         if (isAidl()) {
             mMessagingProxy.deleteSmsOnRuim(serial, index);
@@ -176,6 +179,7 @@
      * @throws RemoteException
      */
     public void getCdmaBroadcastConfig(int serial) throws RemoteException {
+        if (Flags.cleanupCdma()) return;
         if (isEmpty()) return;
         if (isAidl()) {
             mMessagingProxy.getCdmaBroadcastConfig(serial);
@@ -248,6 +252,7 @@
      * @throws RemoteException
      */
     public void sendCdmaSms(int serial, byte[] pdu) throws RemoteException {
+        if (Flags.cleanupCdma()) return;
         if (isEmpty()) return;
         if (isAidl()) {
             mMessagingProxy.sendCdmaSms(serial, RILUtils.convertToHalCdmaSmsMessageAidl(pdu));
@@ -266,6 +271,7 @@
      * @throws RemoteException
      */
     public void sendCdmaSmsExpectMore(int serial, byte[] pdu) throws RemoteException {
+        if (Flags.cleanupCdma()) return;
         if (isEmpty()) return;
         if (isAidl()) {
             mMessagingProxy.sendCdmaSmsExpectMore(
@@ -378,6 +384,7 @@
      * @throws RemoteException
      */
     public void setCdmaBroadcastActivation(int serial, boolean activate) throws RemoteException {
+        if (Flags.cleanupCdma()) return;
         if (isEmpty()) return;
         if (isAidl()) {
             mMessagingProxy.setCdmaBroadcastActivation(serial, activate);
@@ -394,6 +401,7 @@
      */
     public void setCdmaBroadcastConfig(int serial, CdmaSmsBroadcastConfigInfo[] configs)
             throws RemoteException {
+        if (Flags.cleanupCdma()) return;
         if (isEmpty()) return;
         if (isAidl()) {
             ArrayList<android.hardware.radio.messaging.CdmaBroadcastSmsConfigInfo> halConfigs =
@@ -513,6 +521,7 @@
      * @throws RemoteException
      */
     public void writeSmsToRuim(int serial, int status, byte[] pdu) throws RemoteException {
+        if (Flags.cleanupCdma()) return;
         if (isEmpty()) return;
         if (isAidl()) {
             android.hardware.radio.messaging.CdmaSmsWriteArgs args =
diff --git a/src/java/com/android/internal/telephony/RadioModemProxy.java b/src/java/com/android/internal/telephony/RadioModemProxy.java
index cdcbcc0..bc19d55 100644
--- a/src/java/com/android/internal/telephony/RadioModemProxy.java
+++ b/src/java/com/android/internal/telephony/RadioModemProxy.java
@@ -19,6 +19,8 @@
 import android.os.RemoteException;
 import android.telephony.Rlog;
 
+import com.android.internal.telephony.flags.Flags;
+
 /**
  * A holder for IRadioModem.
  * Use getAidl to get IRadioModem and call the AIDL implementations of the HAL APIs.
@@ -195,6 +197,7 @@
      * @throws RemoteException
      */
     public void nvReadItem(int serial, int itemId) throws RemoteException {
+        if (Flags.cleanupCdma()) return;
         if (isEmpty()) return;
         if (isAidl()) {
             mModemProxy.nvReadItem(serial, itemId);
@@ -210,6 +213,7 @@
      * @throws RemoteException
      */
     public void nvResetConfig(int serial, int resetType) throws RemoteException {
+        if (Flags.cleanupCdma() && resetType != 1) return;
         if (isEmpty()) return;
         if (isAidl()) {
             mModemProxy.nvResetConfig(serial, RILUtils.convertToHalResetNvTypeAidl(resetType));
@@ -225,6 +229,7 @@
      * @throws RemoteException
      */
     public void nvWriteCdmaPrl(int serial, byte[] prl) throws RemoteException {
+        if (Flags.cleanupCdma()) return;
         if (isEmpty()) return;
         if (isAidl()) {
             mModemProxy.nvWriteCdmaPrl(serial, prl);
@@ -241,6 +246,7 @@
      * @throws RemoteException
      */
     public void nvWriteItem(int serial, int itemId, String itemValue) throws RemoteException {
+        if (Flags.cleanupCdma()) return;
         if (isEmpty()) return;
         if (isAidl()) {
             android.hardware.radio.modem.NvWriteItem item =
diff --git a/src/java/com/android/internal/telephony/RadioNetworkProxy.java b/src/java/com/android/internal/telephony/RadioNetworkProxy.java
index 12e6c90..6748462 100644
--- a/src/java/com/android/internal/telephony/RadioNetworkProxy.java
+++ b/src/java/com/android/internal/telephony/RadioNetworkProxy.java
@@ -28,6 +28,8 @@
 import android.telephony.Rlog;
 import android.telephony.SignalThresholdInfo;
 
+import com.android.internal.telephony.flags.Flags;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -130,6 +132,7 @@
      * @throws RemoteException
      */
     public void getAvailableBandModes(int serial) throws RemoteException {
+        if (Flags.cleanupCdma()) return;
         if (isEmpty()) return;
         if (isAidl()) {
             mNetworkProxy.getAvailableBandModes(serial);
@@ -172,6 +175,7 @@
      * @throws RemoteException
      */
     public void getCdmaRoamingPreference(int serial) throws RemoteException {
+        if (Flags.cleanupCdma()) return;
         if (isEmpty()) return;
         if (isAidl()) {
             mNetworkProxy.getCdmaRoamingPreference(serial);
@@ -398,6 +402,7 @@
      * @throws RemoteException
      */
     public void setBandMode(int serial, int bandMode) throws RemoteException {
+        if (Flags.cleanupCdma()) return;
         if (isEmpty()) return;
         if (isAidl()) {
             mNetworkProxy.setBandMode(serial, bandMode);
@@ -431,6 +436,7 @@
      * @throws RemoteException
      */
     public void setCdmaRoamingPreference(int serial, int cdmaRoamingType) throws RemoteException {
+        if (Flags.cleanupCdma()) return;
         if (isEmpty()) return;
         if (isAidl()) {
             mNetworkProxy.setCdmaRoamingPreference(serial, cdmaRoamingType);
@@ -521,6 +527,7 @@
      * @throws RemoteException
      */
     public void setLocationUpdates(int serial, boolean enable) throws RemoteException {
+        if (Flags.cleanupCdma()) return;
         if (isEmpty()) return;
         if (isAidl()) {
             mNetworkProxy.setLocationUpdates(serial, enable);
@@ -625,6 +632,7 @@
      * @throws RemoteException
      */
     public void setSuppServiceNotifications(int serial, boolean enable) throws RemoteException {
+        if (Flags.cleanupCdma()) return;
         if (isEmpty()) return;
         if (isAidl()) {
             mNetworkProxy.setSuppServiceNotifications(serial, enable);
diff --git a/src/java/com/android/internal/telephony/RadioSimProxy.java b/src/java/com/android/internal/telephony/RadioSimProxy.java
index 1c864fe..65fbfa4 100644
--- a/src/java/com/android/internal/telephony/RadioSimProxy.java
+++ b/src/java/com/android/internal/telephony/RadioSimProxy.java
@@ -21,6 +21,7 @@
 import android.telephony.ImsiEncryptionInfo;
 import android.telephony.Rlog;
 
+import com.android.internal.telephony.flags.Flags;
 import com.android.internal.telephony.uicc.IccCardApplicationStatus.PersoSubState;
 import com.android.internal.telephony.uicc.SimPhonebookRecord;
 
@@ -168,6 +169,7 @@
      * @throws RemoteException
      */
     public void getCdmaSubscription(int serial) throws RemoteException {
+        if (Flags.cleanupCdma()) return;
         if (isEmpty()) return;
         if (isAidl()) {
             mSimProxy.getCdmaSubscription(serial);
@@ -182,6 +184,7 @@
      * @throws RemoteException
      */
     public void getCdmaSubscriptionSource(int serial) throws RemoteException {
+        if (Flags.cleanupCdma()) return;
         if (isEmpty()) return;
         if (isAidl()) {
             mSimProxy.getCdmaSubscriptionSource(serial);
@@ -631,6 +634,7 @@
      * @throws RemoteException
      */
     public void setCdmaSubscriptionSource(int serial, int cdmaSub) throws RemoteException {
+        if (Flags.cleanupCdma()) return;
         if (isEmpty()) return;
         if (isAidl()) {
             mSimProxy.setCdmaSubscriptionSource(serial, cdmaSub);
@@ -689,6 +693,7 @@
      */
     public void setUiccSubscription(int serial, int slotId, int appIndex, int subId, int subStatus)
             throws RemoteException {
+        if (Flags.cleanupCdma()) return;
         if (isEmpty()) return;
         if (isAidl()) {
             android.hardware.radio.sim.SelectUiccSub info =
diff --git a/src/java/com/android/internal/telephony/RadioVoiceProxy.java b/src/java/com/android/internal/telephony/RadioVoiceProxy.java
index e57a61d..d85017b 100644
--- a/src/java/com/android/internal/telephony/RadioVoiceProxy.java
+++ b/src/java/com/android/internal/telephony/RadioVoiceProxy.java
@@ -21,6 +21,8 @@
 import android.telephony.Rlog;
 import android.telephony.emergency.EmergencyNumber;
 
+import com.android.internal.telephony.flags.Flags;
+
 import java.util.ArrayList;
 
 /**
@@ -488,6 +490,7 @@
      * @throws RemoteException
      */
     public void sendCdmaFeatureCode(int serial, String featureCode) throws RemoteException {
+        if (Flags.cleanupCdma()) return;
         if (isEmpty()) return;
         if (isAidl()) {
             mVoiceProxy.sendCdmaFeatureCode(serial, featureCode);
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index 3309d21..d0b2527 100644
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -76,6 +76,8 @@
 import android.telephony.TelephonyManager;
 import android.telephony.VoiceSpecificRegistrationInfo;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
+import android.telephony.satellite.ISatelliteModemStateCallback;
+import android.telephony.satellite.SatelliteManager;
 import android.text.TextUtils;
 import android.util.EventLog;
 import android.util.LocalLog;
@@ -619,6 +621,83 @@
      */
     private AccessNetworksManagerCallback mAccessNetworksManagerCallback = null;
 
+    /**
+     * Listens status of nb iot satellite modem.
+     */
+    private SatelliteModemStateListener mSatelliteModemStateListener = null;
+
+    /**
+     * SatelliteModemStateListener class
+     */
+    protected class SatelliteModemStateListener extends ISatelliteModemStateCallback.Stub {
+
+        /**
+         * Satellite Modem Connection Status. True when satellite is connected
+         */
+        private boolean mSatelliteNbIotConnected = false;
+
+        /**
+         * Marks the satellite display change as true.
+         */
+        private boolean mUpdateSatelliteCarrierDisplay = false;
+
+        @Override
+        public void onSatelliteModemStateChanged(int state) {
+            boolean isConnected = isInConnectedState();
+            if (isConnected != mSatelliteNbIotConnected) {
+                log("Satellite connection state is changed to " + isConnected);
+                mSatelliteNbIotConnected = isConnected;
+                mUpdateSatelliteCarrierDisplay = true;
+                // trigger pollStats() because the service state is already OOO in demo mode.
+                pollState();
+            }
+        }
+
+        @Override
+        public void onEmergencyModeChanged(boolean isEmergency) {}
+
+        @Override
+        public void onRegistrationFailure(int causeCode) {}
+
+        @Override
+        public void onTerrestrialNetworkAvailableChanged(boolean isAvailable) {}
+
+        /**
+         * Returns true when statellite is connected.
+         *
+         * Note that this connection state is only applicable carrier roaming nb iot satellite.
+         */
+        public boolean isInConnectedState() {
+            SatelliteController sc = SatelliteController.getInstance();
+            if (sc == null) {
+                return false;
+            }
+            int subId = sc.getSelectedSatelliteSubId();
+            if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID
+                    || subId != mPhone.getSubId()
+                    || subId == sc.getNtnOnlySubscriptionId()) {
+                return false;
+            }
+            return sc.isInConnectedState();
+        }
+
+        /**
+         * Returns true if the satellite connection has changed and the satellite display needs
+         * to be updated.
+         */
+        public boolean needToUpdateSatelliteCarrierDisplay() {
+            return mUpdateSatelliteCarrierDisplay;
+        }
+
+        /**
+         * The satellite carrier display update is complete and is marked to not be updated any
+         * further.
+         */
+        public void doneForUpdateSatelliteCarrierDisplay() {
+            mUpdateSatelliteCarrierDisplay = false;
+        }
+    }
+
     public ServiceStateTracker(GsmCdmaPhone phone, CommandsInterface ci,
             FeatureFlags featureFlags) {
         mNitzState = TelephonyComponentFactory.getInstance()
@@ -2912,6 +2991,17 @@
             crossSimSpnFormat = crossSimSpnFormats[crossSimSpnFormatIdx];
         }
 
+        String satellitePlmn = null;
+        SatelliteModemStateListener satelliteModemStateListener = getSatelliteModemStateListener();
+        if (combinedRegState == ServiceState.STATE_OUT_OF_SERVICE
+                && satelliteModemStateListener != null
+                && satelliteModemStateListener.isInConnectedState()) {
+            // If device is connected to the nb-iot satellite,
+            // 1) No service but nb-iot satellite is connected ->
+            //    expected to show "Satellite" for demo mode.
+            satellitePlmn = getSatelliteDisplayName();
+        }
+
         if (mPhone.isPhoneTypeGsm()) {
             // The values of plmn/showPlmn change in different scenarios.
             // 1) No service but emergency call allowed -> expected
@@ -2981,7 +3071,12 @@
                     && ((rule & CARRIER_NAME_DISPLAY_BITMASK_SHOW_SPN)
                     == CARRIER_NAME_DISPLAY_BITMASK_SHOW_SPN);
             if (DBG) log("updateCarrierDisplayName: rawSpn = " + spn);
-            if (!TextUtils.isEmpty(crossSimSpnFormat)) {
+            if (!TextUtils.isEmpty(satellitePlmn)) {
+                plmn = satellitePlmn;
+                showPlmn = true;
+                showSpn = false;
+                log("updateCarrierDisplayName: Update satellite network name:" + plmn);
+            } else if (!TextUtils.isEmpty(crossSimSpnFormat)) {
                 if (!TextUtils.isEmpty(spn)) {
                     // Show SPN + Cross-SIM Calling If SIM has SPN and SPN display condition
                     // is satisfied or SPN override is enabled for this carrier.
@@ -3077,6 +3172,46 @@
                 .build();
     }
 
+    private void updateSatelliteDisplayOverride() {
+        String satelliteDisplayName = getSatelliteDisplayName();
+        if (TextUtils.isEmpty(satelliteDisplayName)) {
+            // Return, if there is no value to override.
+            return;
+        }
+
+        SatelliteModemStateListener satelliteModemStateListener = getSatelliteModemStateListener();
+        if (satelliteModemStateListener != null
+                && satelliteModemStateListener.isInConnectedState()) {
+            // override satellite display name.
+            mNewSS.setOperatorName(
+                    satelliteDisplayName, satelliteDisplayName, mNewSS.getOperatorNumeric());
+            log("Override satellite display name to " + satelliteDisplayName);
+        }
+    }
+
+    @Nullable
+    private SatelliteModemStateListener getSatelliteModemStateListener() {
+        if (mSatelliteModemStateListener != null) {
+            return mSatelliteModemStateListener;
+        }
+
+        SatelliteController sc = SatelliteController.getInstance();
+        if (sc != null) {
+            SatelliteModemStateListener listener = new SatelliteModemStateListener();
+            if (sc.registerForSatelliteModemStateChanged(listener)
+                    == SatelliteManager.SATELLITE_RESULT_SUCCESS) {
+                mSatelliteModemStateListener = listener;
+                log("created SatelliteModemStateListener");
+            }
+        }
+        return mSatelliteModemStateListener;
+    }
+
+    private String getSatelliteDisplayName() {
+        return mCarrierConfig.getString(
+                        CarrierConfigManager.KEY_SATELLITE_DISPLAY_NAME_STRING);
+    }
+
     /**
      * Returns whether out-of-service will be displayed as "no service" to the user.
      */
@@ -3431,6 +3566,19 @@
                 NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
         setPhyCellInfoFromCellIdentity(mNewSS, networkRegState.getCellIdentity());
 
+        boolean hasSatelliteConnectionChanged = false;
+        SatelliteModemStateListener satelliteModemStateListener = getSatelliteModemStateListener();
+        if (satelliteModemStateListener != null) {
+            hasSatelliteConnectionChanged =
+                    satelliteModemStateListener.needToUpdateSatelliteCarrierDisplay();
+            if (hasSatelliteConnectionChanged) {
+                log("Poll ServiceState done : hasSatelliteConnectionChanged="
+                        + hasSatelliteConnectionChanged);
+                satelliteModemStateListener.doneForUpdateSatelliteCarrierDisplay();
+                updateSatelliteDisplayOverride();
+            }
+        }
+
         if (DBG) {
             log("Poll ServiceState done: oldSS=" + mSS);
             log("Poll ServiceState done: newSS=" + mNewSS);
@@ -3700,7 +3848,8 @@
         // Trigger updateCarrierDisplayName when
         // 1. Service state is changed.
         // 2. phone type is Cdma or CdmaLte and ERI text has changed.
-        if (hasChanged || (!mPhone.isPhoneTypeGsm() && hasEriChanged)) {
+        if (hasChanged || (!mPhone.isPhoneTypeGsm() && hasEriChanged)
+                || hasSatelliteConnectionChanged) {
             updateCarrierDisplayName();
         }
 
diff --git a/src/java/com/android/internal/telephony/SmsDispatchersController.java b/src/java/com/android/internal/telephony/SmsDispatchersController.java
index 91aac26..373ee4a 100644
--- a/src/java/com/android/internal/telephony/SmsDispatchersController.java
+++ b/src/java/com/android/internal/telephony/SmsDispatchersController.java
@@ -139,12 +139,12 @@
     /** Time at which the current PARTIAL_SEGMENT_WAIT_DURATION timer was started */
     private long mCurrentWaitStartTime = INVALID_TIME;
 
-    private SMSDispatcher mCdmaDispatcher;
+    private SMSDispatcher mCdmaDispatcher = null;
     private SMSDispatcher mGsmDispatcher;
     private ImsSmsDispatcher mImsSmsDispatcher;
 
     private GsmInboundSmsHandler mGsmInboundSmsHandler;
-    private CdmaInboundSmsHandler mCdmaInboundSmsHandler;
+    private CdmaInboundSmsHandler mCdmaInboundSmsHandler = null;
 
     private Phone mPhone;
     /** Outgoing message counter. Shared by all dispatchers. */
@@ -409,11 +409,14 @@
         // Create dispatchers, inbound SMS handlers and
         // broadcast undelivered messages in raw table.
         mImsSmsDispatcher = new ImsSmsDispatcher(phone, this, ImsManager::getConnector);
-        mCdmaDispatcher = new CdmaSMSDispatcher(phone, this);
         mGsmInboundSmsHandler = GsmInboundSmsHandler.makeInboundSmsHandler(phone.getContext(),
                 storageMonitor, phone, looper, mFeatureFlags);
-        mCdmaInboundSmsHandler = CdmaInboundSmsHandler.makeInboundSmsHandler(phone.getContext(),
-                storageMonitor, phone, (CdmaSMSDispatcher) mCdmaDispatcher, looper, mFeatureFlags);
+        if (!mFeatureFlags.cleanupCdma()) {
+            mCdmaDispatcher = new CdmaSMSDispatcher(phone, this);
+            mCdmaInboundSmsHandler = CdmaInboundSmsHandler.makeInboundSmsHandler(phone.getContext(),
+                    storageMonitor, phone, (CdmaSMSDispatcher) mCdmaDispatcher, looper,
+                    mFeatureFlags);
+        }
         mGsmDispatcher = new GsmSMSDispatcher(phone, this, mGsmInboundSmsHandler);
         SmsBroadcastUndelivered.initialize(phone.getContext(),
                 mGsmInboundSmsHandler, mCdmaInboundSmsHandler, mFeatureFlags);
@@ -455,9 +458,9 @@
         mCi.unregisterForImsNetworkStateChanged(this);
         mPhone.unregisterForServiceStateChanged(this);
         mGsmDispatcher.dispose();
-        mCdmaDispatcher.dispose();
+        if (mCdmaDispatcher != null) mCdmaDispatcher.dispose();
         mGsmInboundSmsHandler.dispose();
-        mCdmaInboundSmsHandler.dispose();
+        if (mCdmaInboundSmsHandler != null) mCdmaInboundSmsHandler.dispose();
         // Cancels the domain selection request if it's still in progress.
         finishDomainSelection(mDscHolder);
         finishDomainSelection(mEmergencyDscHolder);
@@ -577,7 +580,7 @@
 
             default:
                 if (isCdmaMo()) {
-                    mCdmaDispatcher.handleMessage(msg);
+                    if (mCdmaDispatcher != null) mCdmaDispatcher.handleMessage(msg);
                 } else {
                     mGsmDispatcher.handleMessage(msg);
                 }
@@ -659,7 +662,8 @@
 
     private void handlePartialSegmentTimerExpiry(long waitTimerStart) {
         if (mGsmInboundSmsHandler.getCurrentState().getName().equals("WaitingState")
-                || mCdmaInboundSmsHandler.getCurrentState().getName().equals("WaitingState")) {
+                || (mCdmaInboundSmsHandler != null
+                && mCdmaInboundSmsHandler.getCurrentState().getName().equals("WaitingState"))) {
             logd("handlePartialSegmentTimerExpiry: ignoring timer expiry as InboundSmsHandler is"
                     + " in WaitingState");
             return;
@@ -790,7 +794,7 @@
                         + ", format=" + format + "to mGsmInboundSmsHandler");
                 mGsmInboundSmsHandler.sendMessage(
                         InboundSmsHandler.EVENT_INJECT_SMS, isOverIms ? 1 : 0, token, ar);
-            } else if (format.equals(SmsConstants.FORMAT_3GPP2)) {
+            } else if (format.equals(SmsConstants.FORMAT_3GPP2) && mCdmaInboundSmsHandler != null) {
                 Rlog.i(TAG, "SmsDispatchersController:injectSmsText Sending msg=" + msg
                         + ", format=" + format + "to mCdmaInboundSmsHandler");
                 mCdmaInboundSmsHandler.sendMessage(
@@ -998,6 +1002,7 @@
      * @return true if Cdma format should be used for MO SMS, false otherwise.
      */
     protected boolean isCdmaMo() {
+        if (mFeatureFlags.cleanupCdma()) return false;
         if (!isIms()) {
             // IMS is not registered, use Voice technology to determine SMS format.
             return (PhoneConstants.PHONE_TYPE_CDMA == mPhone.getPhoneType());
@@ -1013,6 +1018,7 @@
      * @return true if format given is CDMA format, false otherwise.
      */
     public boolean isCdmaFormat(String format) {
+        if (mFeatureFlags.cleanupCdma()) return false;
         return (mCdmaDispatcher.getFormat().equals(format));
     }
 
@@ -2286,9 +2292,9 @@
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         mGsmInboundSmsHandler.dump(fd, pw, args);
-        mCdmaInboundSmsHandler.dump(fd, pw, args);
+        if (mCdmaInboundSmsHandler != null) mCdmaInboundSmsHandler.dump(fd, pw, args);
         mGsmDispatcher.dump(fd, pw, args);
-        mCdmaDispatcher.dump(fd, pw, args);
+        if (mCdmaDispatcher != null) mCdmaDispatcher.dump(fd, pw, args);
         mImsSmsDispatcher.dump(fd, pw, args);
     }
 
diff --git a/src/java/com/android/internal/telephony/cdma/CdmaSubscriptionSourceManager.java b/src/java/com/android/internal/telephony/cdma/CdmaSubscriptionSourceManager.java
index 0fac334..eea49e3 100644
--- a/src/java/com/android/internal/telephony/cdma/CdmaSubscriptionSourceManager.java
+++ b/src/java/com/android/internal/telephony/cdma/CdmaSubscriptionSourceManager.java
@@ -28,6 +28,7 @@
 
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.flags.Flags;
 import com.android.telephony.Rlog;
 
 import java.util.concurrent.atomic.AtomicInteger;
@@ -63,6 +64,7 @@
 
     // Constructor
     private CdmaSubscriptionSourceManager(Context context, CommandsInterface ci) {
+        if (Flags.cleanupCdma()) return;
         mCi = ci;
         mCi.registerForCdmaSubscriptionChanged(this, EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED, null);
         mCi.registerForOn(this, EVENT_RADIO_ON, null);
@@ -97,7 +99,7 @@
         mCdmaSubscriptionSourceChangedRegistrants.remove(h);
         synchronized (sReferenceCountMonitor) {
             sReferenceCount--;
-            if (sReferenceCount <= 0) {
+            if (sReferenceCount <= 0 && mCi != null) {
                 mCi.unregisterForCdmaSubscriptionChanged(this);
                 mCi.unregisterForOn(this);
                 mCi.unregisterForSubscriptionStatusChanged(this);
@@ -112,6 +114,7 @@
      */
     @Override
     public void handleMessage(Message msg) {
+        if (Flags.cleanupCdma()) return;
         AsyncResult ar;
         switch (msg.what) {
             case EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
@@ -165,6 +168,8 @@
      * @return Default CDMA subscription source from Settings DB if present.
      */
     public static int getDefault(Context context) {
+        if (Flags.cleanupCdma()) return Phone.CDMA_SUBSCRIPTION_UNKNOWN;
+
         // Get the default value from the Settings
         int subscriptionSource = Settings.Global.getInt(context.getContentResolver(),
                 Settings.Global.CDMA_SUBSCRIPTION_MODE, Phone.PREFERRED_CDMA_SUBSCRIPTION);
diff --git a/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java b/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java
index 113c3ee..5c3bcb0 100644
--- a/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java
+++ b/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java
@@ -20,6 +20,7 @@
 import static android.telephony.satellite.SatelliteManager.DATAGRAM_TYPE_SMS;
 import static android.telephony.satellite.SatelliteManager.DATAGRAM_TYPE_UNKNOWN;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_MODEM_TIMEOUT;
@@ -418,7 +419,7 @@
             case EVENT_MT_SMS_POLLING_THROTTLE_TIMED_OUT: {
                 synchronized (mLock) {
                     mIsMtSmsPollingThrottled = false;
-                    if (mIsAligned && mModemState == SATELLITE_MODEM_STATE_CONNECTED) {
+                    if (allowMtSmsPolling()) {
                         sendMtSmsPollingMessage();
                     }
                 }
@@ -514,8 +515,7 @@
             mIsAligned = isAligned;
             plogd("setDeviceAlignedWithSatellite: " + mIsAligned);
             if (isAligned && mIsDemoMode) handleEventSatelliteAligned();
-            if (isAligned && !mIsMtSmsPollingThrottled
-                    && mModemState == SATELLITE_MODEM_STATE_CONNECTED) {
+            if (allowMtSmsPolling()) {
                 sendMtSmsPollingMessage();
             }
         }
@@ -810,9 +810,6 @@
                     stopDatagramWaitForConnectedStateTimer();
                     sendPendingMessages();
                 }
-                if (mIsAligned && !mIsMtSmsPollingThrottled) {
-                    sendMtSmsPollingMessage();
-                }
             }
 
             if (state == SATELLITE_MODEM_STATE_NOT_CONNECTED) {
@@ -821,6 +818,10 @@
                     mShouldPollMtSms = shouldPollMtSms();
                 }
             }
+
+            if (allowMtSmsPolling()) {
+                sendMtSmsPollingMessage();
+            }
         }
     }
 
@@ -1334,6 +1335,32 @@
         removeMessages(EVENT_MT_SMS_POLLING_THROTTLE_TIMED_OUT);
     }
 
+    @GuardedBy("mLock")
+    private boolean allowMtSmsPolling() {
+        if (!mFeatureFlags.carrierRoamingNbIotNtn()) return false;
+
+        if (mIsMtSmsPollingThrottled) return false;
+
+        if (!mIsAligned) return false;
+
+        boolean isModemStateConnectedOrTransferring =
+                mModemState == SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED
+                        || mModemState
+                                == SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING;
+        if (!isModemStateConnectedOrTransferring && !allowCheckMessageInNotConnected()) {
+            plogd("EVENT_MT_SMS_POLLING_THROTTLE_TIMED_OUT:"
+                    + " allow_check_message_in_not_connected is disabled");
+            return false;
+        }
+
+        return true;
+    }
+
+    private boolean allowCheckMessageInNotConnected() {
+        return mContext.getResources()
+                .getBoolean(R.bool.config_satellite_allow_check_message_in_not_connected);
+    }
+
     private static void logd(@NonNull String log) {
         Rlog.d(TAG, log);
     }
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteController.java b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
index 55980ea..a64f24c 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
@@ -34,6 +34,7 @@
 import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL;
 import static android.telephony.CarrierConfigManager.KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT;
 import static android.telephony.CarrierConfigManager.KEY_SATELLITE_DATA_SUPPORT_MODE_INT;
+import static android.telephony.CarrierConfigManager.KEY_SATELLITE_DISPLAY_NAME_STRING;
 import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL;
 import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ESOS_SUPPORTED_BOOL;
 import static android.telephony.CarrierConfigManager.KEY_SATELLITE_NIDD_APN_NAME_STRING;
@@ -42,7 +43,7 @@
 import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ROAMING_P2P_SMS_SUPPORTED_BOOL;
 import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ROAMING_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT;
 import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ROAMING_TURN_OFF_SESSION_FOR_EMERGENCY_CALL_BOOL;
-import static android.telephony.CarrierConfigManager.KEY_SATELLITE_SOS_MAX_DATAGRAM_SIZE;
+import static android.telephony.CarrierConfigManager.KEY_SATELLITE_SOS_MAX_DATAGRAM_SIZE_BYTES_INT;
 import static android.telephony.CarrierConfigManager.KEY_SATELLITE_SUPPORTED_MSG_APPS_STRING_ARRAY;
 import static android.telephony.SubscriptionManager.SATELLITE_ATTACH_ENABLED_FOR_CARRIER;
 import static android.telephony.SubscriptionManager.SATELLITE_ENTITLEMENT_STATUS;
@@ -724,7 +725,7 @@
     // device.
     private List<DeviceState> mDeviceStates = new ArrayList();
 
-    public static final int RESULT_RECEIVER_COUNT_ANOMALY_THRESHOLD = 100;
+    public static final int RESULT_RECEIVER_COUNT_ANOMALY_THRESHOLD = 500;
     protected final Object mResultReceiverTotalCountLock = new Object();
     @GuardedBy("mResultReceiverTotalCountLock")
     protected int mResultReceiverTotalCount;
@@ -4273,7 +4274,11 @@
         logd("onSatelliteEntitlementStatusUpdated subId=" + subId + ", entitlementEnabled="
                 + entitlementEnabled + ", allowedPlmnList=["
                 + String.join(",", allowedPlmnList) + "]" + ", barredPlmnList=["
-                + String.join(",", barredPlmnList) + "]");
+                + String.join(",", barredPlmnList) + "]"
+                + ", plmnDataPlanMap =" + plmnDataPlanMap.toString()
+                + ", plmnServiceTypeMap =" + plmnServiceTypeMap.toString()
+                + ", plmnDataServicePolicyMap=" + plmnDataServicePolicyMap.toString()
+                + ", plmnVoiceServicePolicyMap=" + plmnVoiceServicePolicyMap.toString());
 
         synchronized (mSupportedSatelliteServicesLock) {
             if (mSatelliteEntitlementStatusPerCarrier.get(subId, false) != entitlementEnabled) {
@@ -5404,6 +5409,7 @@
                 config = mCarrierConfigManager.getConfigForSubId(subId,
                         KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE,
                         KEY_SATELLITE_ATTACH_SUPPORTED_BOOL,
+                        KEY_SATELLITE_DISPLAY_NAME_STRING,
                         KEY_SATELLITE_ROAMING_TURN_OFF_SESSION_FOR_EMERGENCY_CALL_BOOL,
                         KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT,
                         KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL,
@@ -5419,7 +5425,7 @@
                         KEY_SATELLITE_ROAMING_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT,
                         KEY_SATELLITE_ROAMING_P2P_SMS_INACTIVITY_TIMEOUT_SEC_INT,
                         KEY_SATELLITE_ROAMING_ESOS_INACTIVITY_TIMEOUT_SEC_INT,
-                        KEY_SATELLITE_SOS_MAX_DATAGRAM_SIZE,
+                        KEY_SATELLITE_SOS_MAX_DATAGRAM_SIZE_BYTES_INT,
                         KEY_SATELLITE_SUPPORTED_MSG_APPS_STRING_ARRAY,
                         KEY_REGIONAL_SATELLITE_EARFCN_BUNDLE,
                         KEY_SATELLITE_DATA_SUPPORT_MODE_INT
@@ -7223,6 +7229,29 @@
     }
 
     /**
+     * Request to get the name to display for Satellite.
+     *
+     * @param result The result receiver that returns the name to display for the satellite
+     *               or an error code if the request failed.
+     */
+    public void requestSatelliteDisplayName(@NonNull ResultReceiver result) {
+        if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
+            plogd("requestSatelliteDisplayName: carrierRoamingNbIotNtn flag is disabled");
+            result.send(SatelliteManager.SATELLITE_RESULT_NOT_SUPPORTED, null);
+            return;
+        }
+
+        int subId = getSelectedSatelliteSubId();
+        String displayName = getConfigForSubId(subId).getString(
+                KEY_SATELLITE_DISPLAY_NAME_STRING, "Satellite");
+
+        plogd("requestSatelliteDisplayName: " + displayName);
+        Bundle bundle = new Bundle();
+        bundle.putString(SatelliteManager.KEY_SATELLITE_DISPLAY_NAME, displayName);
+        result.send(SATELLITE_RESULT_SUCCESS, bundle);
+    }
+
+    /**
      * Request to get list of prioritized satellite tokens to be used for provision.
      *
      * @param result The result receiver, which returns the list of prioritized satellite tokens
@@ -7969,8 +7998,8 @@
     private void overrideSatelliteCapabilitiesIfApplicable() {
         int subId = getSelectedSatelliteSubId();
         PersistableBundle config = getPersistableBundle(subId);
-        if (config.containsKey(KEY_SATELLITE_SOS_MAX_DATAGRAM_SIZE)) {
-            int datagramSize = config.getInt(KEY_SATELLITE_SOS_MAX_DATAGRAM_SIZE);
+        if (config.containsKey(KEY_SATELLITE_SOS_MAX_DATAGRAM_SIZE_BYTES_INT)) {
+            int datagramSize = config.getInt(KEY_SATELLITE_SOS_MAX_DATAGRAM_SIZE_BYTES_INT);
             SubscriptionInfo subInfo = mSubscriptionManagerService.getSubscriptionInfo(subId);
             if (!(subInfo == null || subInfo.isOnlyNonTerrestrialNetwork())) {
                 synchronized (mSatelliteCapabilitiesLock) {
@@ -7980,7 +8009,10 @@
         }
     }
 
-    private int getNtnOnlySubscriptionId() {
+    /**
+     * This method returns subscription id for supporting Ntn Only
+     */
+    public int getNtnOnlySubscriptionId() {
         List<SubscriptionInfo> infoList = mSubscriptionManagerService.getAllSubInfoList(
                         mContext.getOpPackageName(), mContext.getAttributionTag());
         int subId = infoList.stream()
@@ -8197,11 +8229,15 @@
         return carrierRoamingNtnSignalStrength;
     }
 
-    private boolean isInConnectedState() {
+    /**
+     * Returns satellite connected state from modem, return true if connected.
+     */
+    public boolean isInConnectedState() {
         synchronized (mSatelliteModemStateLock) {
             switch (mSatelliteModemState) {
-                case SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED:
-                case SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING:
+                case SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED: //fallthrough
+                case SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING: //fallthrough
+                case SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_RETRYING:
                     plogd("isInConnectedState: return true");
                     return true;
                 default:
@@ -8250,6 +8286,21 @@
         }
     }
 
+    /** Returns whether to drop SMS or not. */
+    public boolean shouldDropSms(@Nullable Phone phone) {
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            if (!isInCarrierRoamingNbIotNtn(phone)) {
+                return false;
+            }
+
+            int[] services = getSupportedServicesOnCarrierRoamingNtn(phone.getSubId());
+            return !ArrayUtils.contains(services, NetworkRegistrationInfo.SERVICE_TYPE_SMS);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
     private boolean isWaitingForSatelliteModemOff() {
         synchronized (mSatelliteEnabledRequestLock) {
             return mWaitingForSatelliteModemOff;
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java b/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java
index 64bd2b7..e924878 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java
@@ -76,6 +76,7 @@
 import com.android.internal.telephony.flags.Flags;
 import com.android.internal.telephony.metrics.SatelliteStats;
 
+import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 
@@ -274,12 +275,13 @@
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
     protected boolean isSatelliteAllowedByReasons() {
         SatelliteManager satelliteManager = mContext.getSystemService(SatelliteManager.class);
-        List<Integer> disallowedReasons = satelliteManager.getSatelliteDisallowedReasons();
-        if (disallowedReasons.stream().anyMatch(r ->
+        int[] disallowedReasons = satelliteManager.getSatelliteDisallowedReasons();
+        if (Arrays.stream(disallowedReasons).anyMatch(r ->
                 (r == SATELLITE_DISALLOWED_REASON_UNSUPPORTED_DEFAULT_MSG_APP
                         || r == SATELLITE_DISALLOWED_REASON_NOT_PROVISIONED
                         || r == SATELLITE_DISALLOWED_REASON_NOT_SUPPORTED))) {
-            plogd("isAllowedForDefaultMessageApp:false, disallowedReasons=" + disallowedReasons);
+            plogd("isAllowedForDefaultMessageApp:false, disallowedReasons="
+                    + Arrays.toString(disallowedReasons));
             return false;
         }
         return true;
@@ -671,7 +673,7 @@
 
     @NonNull private Bundle createExtraBundleForEventDisplayEmergencyMessage(
             boolean isTestEmergencyNumber) {
-        int handoverType = EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS;
+        int handoverType = getEmergencyCallToSatelliteHandoverType();
         Pair<String, String> oemSatelliteMessagingApp =
                 getOemEnabledSatelliteHandoverAppFromOverlayConfig(mContext);
         String packageName = oemSatelliteMessagingApp.first;
@@ -679,10 +681,8 @@
         String action = getSatelliteEmergencyHandoverIntentActionFromOverlayConfig(mContext,
                 isTestEmergencyNumber);
 
-        if (isSatelliteConnectedViaCarrierWithinHysteresisTime()
-                || isEmergencyCallToSatelliteHandoverTypeT911Enforced()) {
+        if (handoverType == EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911) {
             ComponentName defaultSmsAppComponent = getDefaultSmsApp();
-            handoverType = EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911;
             packageName = defaultSmsAppComponent.getPackageName();
             className = defaultSmsAppComponent.getClassName();
         }
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java b/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java
index b2861d3..f2f4cac 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java
@@ -874,10 +874,19 @@
             stopNbIotInactivityTimer();
 
             //Enable Cellular Modem scanning
-            Message onCompleted =
+            boolean configSatelliteAllowTnScanningDuringSatelliteSession =
+                    mContext.getResources().getBoolean(
+                        R.bool.config_satellite_allow_tn_scanning_during_satellite_session);
+            if (configSatelliteAllowTnScanningDuringSatelliteSession) {
+                Message onCompleted =
                     obtainMessage(EVENT_ENABLE_CELLULAR_MODEM_WHILE_SATELLITE_MODE_IS_ON_DONE);
-            mSatelliteModemInterface.enableCellularModemWhileSatelliteModeIsOn(true, onCompleted);
-            if (isConcurrentTnScanningSupported()) {
+                mSatelliteModemInterface
+                    .enableCellularModemWhileSatelliteModeIsOn(true, onCompleted);
+            } else {
+                plogd("Device does not allow cellular modem scanning");
+            }
+            if (isConcurrentTnScanningSupported()
+                    || !configSatelliteAllowTnScanningDuringSatelliteSession) {
                 plogd("IDLE state is hidden from clients");
             } else {
                 notifyStateChangedEvent(SatelliteManager.SATELLITE_MODEM_STATE_IDLE);
diff --git a/src/java/com/android/internal/telephony/uicc/SimTypeInfo.java b/src/java/com/android/internal/telephony/uicc/SimTypeInfo.java
new file mode 100644
index 0000000..b19e42a
--- /dev/null
+++ b/src/java/com/android/internal/telephony/uicc/SimTypeInfo.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.uicc;
+
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This class contains the sim type information of active physical slot ids.
+ */
+public class SimTypeInfo {
+
+    /**
+     * SimType (bit mask)
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+            SimType.SIM_TYPE_UNKNOWN,
+            SimType.SIM_TYPE_PHYSICAL,
+            SimType.SIM_TYPE_ESIM,
+    })
+    public @interface SimType {
+        /** Unknown SIM */
+        int SIM_TYPE_UNKNOWN = 0;
+        /** Physical SIM (Can have eUICC capabilities) */
+        int SIM_TYPE_PHYSICAL = 1 << 0;
+        /** Embedded SIM*/
+        int SIM_TYPE_ESIM = 1 << 1;
+    }
+
+    public @SimType int mCurrentSimType = SimType.SIM_TYPE_UNKNOWN;
+    // Bitmask of the supported {@code SimType}s
+    public int mSupportedSimTypes;
+
+    /**
+     * Set the current SimType according to the input type.
+     */
+    public void setCurrentSimType(int simType) {
+        switch(simType) {
+            case android.hardware.radio.config.SimType.UNKNOWN:
+                mCurrentSimType = SimType.SIM_TYPE_UNKNOWN;
+                break;
+            case android.hardware.radio.config.SimType.PHYSICAL:
+                mCurrentSimType = SimType.SIM_TYPE_PHYSICAL;
+                break;
+            case android.hardware.radio.config.SimType.ESIM:
+                mCurrentSimType = SimType.SIM_TYPE_ESIM;
+                break;
+            default:
+                throw new RuntimeException("Unrecognized RIL_SimType: " + simType);
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("SimTypeInfo {activeSimType=").append(mCurrentSimType).append(",")
+                .append("supportedSimType=").append(mSupportedSimTypes);
+        sb.append("}");
+        return sb.toString();
+    }
+}
diff --git a/src/java/com/android/internal/telephony/uicc/euicc/apdu/ApduSender.java b/src/java/com/android/internal/telephony/uicc/euicc/apdu/ApduSender.java
index 1d9dc68..309fe79 100644
--- a/src/java/com/android/internal/telephony/uicc/euicc/apdu/ApduSender.java
+++ b/src/java/com/android/internal/telephony/uicc/euicc/apdu/ApduSender.java
@@ -233,9 +233,17 @@
                         if (channel == IccOpenLogicalChannelResponse.INVALID_CHANNEL
                                 || status != IccOpenLogicalChannelResponse.STATUS_NO_ERROR) {
                             mChannelOpened = false;
-                            resultCallback.onException(
-                                    new ApduException("Failed to open logical channel for AID: "
-                                            + mAid + ", with status: " + status));
+                            returnRespnseOrException(
+                                    channel,
+                                    /* closeChannelImmediately= */ false,
+                                    /* response= */ null,
+                                    new ApduException(
+                                            "Failed to open logical channel for AID: "
+                                                    + mAid
+                                                    + ", with status: "
+                                                    + status),
+                                    resultCallback,
+                                    handler);
                             return;
                         }
                         PreferenceManager.getDefaultSharedPreferences(mContext)
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CellIdentityCdmaTest.java b/tests/telephonytests/src/com/android/internal/telephony/CellIdentityCdmaTest.java
index c7668ca..53719b1 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CellIdentityCdmaTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CellIdentityCdmaTest.java
@@ -24,6 +24,8 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.internal.telephony.flags.Flags;
+
 /** Unit tests for {@link CellIdentityCdma}. */
 
 public class CellIdentityCdmaTest extends AndroidTestCase {
@@ -44,6 +46,7 @@
 
     @SmallTest
     public void testConstructor() {
+        if (Flags.cleanupCdma()) return;
         CellIdentityCdma  ci =
                 new CellIdentityCdma(NETWORK_ID, SYSTEM_ID, BASESTATION_ID, LONGITUDE, LATITUDE,
                         ALPHA_LONG, ALPHA_SHORT);
@@ -61,6 +64,7 @@
 
     @SmallTest
     public void testNullIsland() {
+        if (Flags.cleanupCdma()) return;
         CellIdentityCdma  ci =
                 new CellIdentityCdma(NETWORK_ID, SYSTEM_ID, BASESTATION_ID, -1, 0,
                         ALPHA_LONG, ALPHA_SHORT);
@@ -71,6 +75,7 @@
 
     @SmallTest
     public void testEquals() {
+        if (Flags.cleanupCdma()) return;
         CellIdentityCdma  ciA =
                 new CellIdentityCdma(NETWORK_ID, SYSTEM_ID, BASESTATION_ID, LONGITUDE, LATITUDE,
                         ALPHA_LONG, ALPHA_SHORT);
@@ -97,6 +102,7 @@
 
     @SmallTest
     public void testParcel() {
+        if (Flags.cleanupCdma()) return;
         CellIdentityCdma  ci =
                 new CellIdentityCdma(NETWORK_ID, SYSTEM_ID, BASESTATION_ID, LONGITUDE, LATITUDE,
                         ALPHA_LONG, ALPHA_SHORT);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CellSignalStrengthCdmaTest.java b/tests/telephonytests/src/com/android/internal/telephony/CellSignalStrengthCdmaTest.java
index 3a20497..ab5e732 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CellSignalStrengthCdmaTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CellSignalStrengthCdmaTest.java
@@ -26,6 +26,8 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.internal.telephony.flags.Flags;
+
 /** Unit tests for {@link CellSignalStrengthCdma}. */
 
 public class CellSignalStrengthCdmaTest extends AndroidTestCase {
@@ -38,6 +40,7 @@
 
     @SmallTest
     public void testConstructor() {
+        if (Flags.cleanupCdma()) return;
         CellSignalStrengthCdma css = new CellSignalStrengthCdma(
                 CDMA_DBM, CDMA_ECIO, EVDO_DBM, EVDO_ECIO, EVDO_SNR);
         assertEquals(CDMA_DBM, css.getCdmaDbm());
@@ -49,6 +52,7 @@
 
     @SmallTest
     public void testInvalidConstructor() {
+        if (Flags.cleanupCdma()) return;
         CellSignalStrengthCdma css = new CellSignalStrengthCdma(200, 2000, 20, 400, 200);
         assertEquals(Integer.MAX_VALUE, css.getCdmaDbm());
         assertEquals(Integer.MAX_VALUE, css.getCdmaEcio());
@@ -59,6 +63,7 @@
 
     @SmallTest
     public void testDefaultConstructor() {
+        if (Flags.cleanupCdma()) return;
         CellSignalStrengthCdma css = new CellSignalStrengthCdma();
         assertEquals(Integer.MAX_VALUE, css.getCdmaDbm());
         assertEquals(Integer.MAX_VALUE, css.getCdmaEcio());
@@ -69,6 +74,7 @@
 
     @SmallTest
     public void testEquals() {
+        if (Flags.cleanupCdma()) return;
         assertTrue(new CellSignalStrengthCdma(
                 CDMA_DBM, CDMA_ECIO, EVDO_DBM, EVDO_ECIO, EVDO_SNR).equals(
                         new CellSignalStrengthCdma(
@@ -80,6 +86,7 @@
 
     @SmallTest
     public void testParcel() {
+        if (Flags.cleanupCdma()) return;
         CellSignalStrengthCdma css = new CellSignalStrengthCdma(
                 CDMA_DBM, CDMA_ECIO, EVDO_DBM, EVDO_ECIO, EVDO_SNR);
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java
index f92643a..a7923cf 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java
@@ -1044,7 +1044,8 @@
             doReturn(new TelephonyDisplayInfo(
                     mNetworkTypeController.getDataNetworkType(),
                     mNetworkTypeController.getOverrideNetworkType(),
-                    false)).when(mDisplayInfoController).getTelephonyDisplayInfo();
+                    false, false, false))
+                    .when(mDisplayInfoController).getTelephonyDisplayInfo();
             return null;
         }).when(mDisplayInfoController).updateTelephonyDisplayInfo();
         mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
index 70bdcba..404c1b2 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
@@ -89,6 +89,8 @@
 import android.telephony.cdma.CdmaCellLocation;
 import android.telephony.gsm.GsmCellLocation;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
+import android.telephony.satellite.ISatelliteModemStateCallback;
+import android.telephony.satellite.SatelliteManager;
 import android.text.TextUtils;
 import android.util.Pair;
 
@@ -185,6 +187,7 @@
     private static final String[] CARRIER_CONFIG_PNN = new String[] {
             String.format("%s,%s", HOME_PNN, "short"), "f2,s2"
     };
+    private static final String SATELLITE_DISPLAY_NAME = "SatelliteTest";
 
     private class ServiceStateTrackerTestHandler extends HandlerThread {
 
@@ -391,6 +394,11 @@
                     30  /* SIGNAL_STRENGTH_GREAT */
                 });
 
+        // satellite display name
+        mBundle.putString(
+                CarrierConfigManager.KEY_SATELLITE_DISPLAY_NAME_STRING,
+                SATELLITE_DISPLAY_NAME);
+
         sendCarrierConfigUpdate(PHONE_ID);
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
 
@@ -3546,4 +3554,42 @@
             }
         }
     }
+
+    @Test
+    public void testSatelliteModemStateCallback() throws Exception {
+        ArgumentCaptor<ISatelliteModemStateCallback> captor =
+                ArgumentCaptor.forClass(ISatelliteModemStateCallback.class);
+        verify(mSatelliteController, times(1)).registerForSatelliteModemStateChanged(
+                captor.capture());
+        ISatelliteModemStateCallback callback = captor.getValue();
+
+        doReturn(1).when(mSatelliteController).getSelectedSatelliteSubId();
+        doReturn(1).when(mPhone).getSubId();
+
+        mSimulatedCommands.setVoiceRegState(
+                NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING);
+        mSimulatedCommands.setVoiceRadioTech(ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN);
+        mSimulatedCommands.setDataRegState(
+                NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING);
+        mSimulatedCommands.setDataRadioTech(ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN);
+        doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mServiceState).getState();
+        doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mServiceState).getDataRegistrationState();
+        sst.mSS = mServiceState;
+
+        mBundle.putBoolean(
+                CarrierConfigManager.KEY_ENABLE_CARRIER_DISPLAY_NAME_RESOLVER_BOOL, false);
+        sendCarrierConfigUpdate(PHONE_ID);
+
+        doReturn(true).when(mSatelliteController).isInConnectedState();
+        callback.onSatelliteModemStateChanged(SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED);
+        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+
+        // update the spn
+        sst.updateCarrierDisplayName();
+
+        Bundle b = getExtrasFromLastSpnUpdateIntent();
+        assertThat(b.getString(TelephonyManager.EXTRA_PLMN)).isEqualTo(SATELLITE_DISPLAY_NAME);
+        assertThat(b.getBoolean(TelephonyManager.EXTRA_SHOW_PLMN)).isTrue();
+    }
+
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthControllerTest.java
index 7e4cb08..b59c4de 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthControllerTest.java
@@ -64,6 +64,7 @@
 
 import androidx.test.filters.MediumTest;
 
+import com.android.internal.telephony.flags.Flags;
 import com.android.internal.util.ArrayUtils;
 
 import org.junit.After;
@@ -470,19 +471,21 @@
         assertEquals(mSsc.getSignalStrength(), ss);
         assertEquals(mSsc.getSignalStrength().isGsm(), true);
 
-        // Send in CDMA-only Signal Strength Info and expect isGsm == false
-        ss = new SignalStrength(
-                new CellSignalStrengthCdma(-90, -12,
-                        SignalStrength.INVALID, SignalStrength.INVALID, SignalStrength.INVALID),
-                new CellSignalStrengthGsm(),
-                new CellSignalStrengthWcdma(),
-                new CellSignalStrengthTdscdma(),
-                new CellSignalStrengthLte(),
-                new CellSignalStrengthNr());
+        if (!Flags.cleanupCdma()) {
+            // Send in CDMA-only Signal Strength Info and expect isGsm == false
+            ss = new SignalStrength(
+                    new CellSignalStrengthCdma(-90, -12,
+                            SignalStrength.INVALID, SignalStrength.INVALID, SignalStrength.INVALID),
+                    new CellSignalStrengthGsm(),
+                    new CellSignalStrengthWcdma(),
+                    new CellSignalStrengthTdscdma(),
+                    new CellSignalStrengthLte(),
+                    new CellSignalStrengthNr());
 
-        sendSignalStrength(ss);
-        assertEquals(mSsc.getSignalStrength(), ss);
-        assertEquals(mSsc.getSignalStrength().isGsm(), false);
+            sendSignalStrength(ss);
+            assertEquals(mSsc.getSignalStrength(), ss);
+            assertEquals(mSsc.getSignalStrength().isGsm(), false);
+        }
     }
 
     @Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthTest.java b/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthTest.java
index 8df4052..786bb94 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthTest.java
@@ -137,7 +137,7 @@
         ArrayList<Byte> NrCqiReport = new ArrayList<>(
                 Arrays.asList((byte) 3, (byte) 2 , (byte) 1));
         SignalStrength s = new SignalStrength(
-                new CellSignalStrengthCdma(-93, -132, -89, -125, 5),
+                new CellSignalStrengthCdma(),
                 new CellSignalStrengthGsm(-79, 2, 5),
                 new CellSignalStrengthWcdma(-94, 4, -102, -5),
                 new CellSignalStrengthTdscdma(-95, 2, -103),
@@ -175,7 +175,6 @@
     public void testGetCellSignalStrengths() throws Exception {
         CellSignalStrengthLte lte = new CellSignalStrengthLte(-85, -91, -6, -10, 1, 12, 1);
         CellSignalStrengthGsm gsm = new CellSignalStrengthGsm(-79, 2, 5);
-        CellSignalStrengthCdma cdma = new CellSignalStrengthCdma(-93, -132, -89, -125, 5);
         CellSignalStrengthWcdma wcdma = new CellSignalStrengthWcdma(-94, 4, -102, -5);
         CellSignalStrengthTdscdma tdscdma = new CellSignalStrengthTdscdma(-95, 2, -103);
 
@@ -194,16 +193,16 @@
 
         // Test that a multiple objects are properly stored and returned by getCellSignalStrengths()
         s = new SignalStrength(
-                cdma,
+                new CellSignalStrengthCdma(),
                 new CellSignalStrengthGsm(),
-                new CellSignalStrengthWcdma(),
+                wcdma,
                 new CellSignalStrengthTdscdma(),
                 lte,
                 new CellSignalStrengthNr());
 
         css = s.getCellSignalStrengths();
         assertEquals(2, css.size());
-        assertTrue(css.contains(cdma));
+        assertTrue(css.contains(wcdma));
         assertTrue(css.contains(lte));
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
index f934371..e5aa541 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
@@ -56,6 +56,7 @@
 import android.telephony.AccessNetworkConstants;
 import android.telephony.Annotation;
 import android.telephony.BarringInfo;
+import android.telephony.CallState;
 import android.telephony.CellIdentity;
 import android.telephony.CellIdentityGsm;
 import android.telephony.CellIdentityLte;
@@ -141,6 +142,7 @@
     private int[] mCarrierRoamingNtnAvailableServices;
     private NtnSignalStrength mCarrierRoamingNtnSignalStrength;
     private boolean mIsSatelliteEnabled;
+    private final List<List<CallState>> mCallStateList = new ArrayList<>();
 
     // All events contribute to TelephonyRegistry#isPhoneStatePermissionRequired
     private static final Set<Integer> READ_PHONE_STATE_EVENTS;
@@ -224,7 +226,8 @@
             TelephonyCallback.EmergencyCallbackModeListener,
             TelephonyCallback.CarrierRoamingNtnModeListener,
             TelephonyCallback.SecurityAlgorithmsListener,
-            TelephonyCallback.CellularIdentifierDisclosedListener {
+            TelephonyCallback.CellularIdentifierDisclosedListener,
+            TelephonyCallback.CallAttributesListener {
         // This class isn't mockable to get invocation counts because the IBinder is null and
         // crashes the TelephonyRegistry. Make a cheesy verify(times()) alternative.
         public AtomicInteger invocationCount = new AtomicInteger(0);
@@ -374,6 +377,12 @@
         public void onCellularIdentifierDisclosedChanged(CellularIdentifierDisclosure disclosure) {
             invocationCount.incrementAndGet();
         }
+
+        @Override
+        public void onCallStatesChanged(List<CallState> callStateList) {
+            invocationCount.incrementAndGet();
+            mCallStateList.add(callStateList);
+        }
     }
 
     public class MySatelliteStateChangeListener implements ISatelliteStateChangeListener {
@@ -448,6 +457,7 @@
             mPhysicalChannelConfigs = null;
         }
         mCellLocation = null;
+        mCallStateList.clear();
         super.tearDown();
     }
 
@@ -1344,7 +1354,7 @@
         TelephonyDisplayInfo displayInfo = new TelephonyDisplayInfo(
                 TelephonyManager.NETWORK_TYPE_LTE,
                 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
-                false);
+                false, false, false);
 
         // Notify with invalid subId on default phone. Should NOT trigger callback.
         mTelephonyRegistry.notifyDisplayInfoChanged(0, INVALID_SUBSCRIPTION_ID, displayInfo);
@@ -1371,11 +1381,11 @@
         TelephonyDisplayInfo displayInfo = new TelephonyDisplayInfo(
                 TelephonyManager.NETWORK_TYPE_LTE,
                 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
-                false);
+                false, false, false);
         TelephonyDisplayInfo expectDisplayInfo = new TelephonyDisplayInfo(
                 TelephonyManager.NETWORK_TYPE_LTE,
                 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE,
-                false);
+                false, false, false);
 
         // Notify with invalid subId on default phone. Should NOT trigger callback.
         mTelephonyRegistry.notifyDisplayInfoChanged(0, INVALID_SUBSCRIPTION_ID, displayInfo);
@@ -1398,11 +1408,11 @@
         TelephonyDisplayInfo displayInfo = new TelephonyDisplayInfo(
                 TelephonyManager.NETWORK_TYPE_LTE,
                 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED,
-                false);
+                false, false, false);
         TelephonyDisplayInfo expectDisplayInfo = new TelephonyDisplayInfo(
                 TelephonyManager.NETWORK_TYPE_LTE,
                 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE,
-                false);
+                false, false, false);
         TelephonyCallback telephonyCallback2 = new TelephonyCallbackWrapper() {
             @Override
             public void onDisplayInfoChanged(TelephonyDisplayInfo displayInfoNotify) {
@@ -1772,6 +1782,37 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_PASS_COPIED_CALL_STATE_LIST)
+    public void testNotifyPreciseCallStateChangedInProcess() {
+        doReturn(mMockSubInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
+        doReturn(0/*slotIndex*/).when(mMockSubInfo).getSimSlotIndex();
+
+        final int subId = 1;
+        int[] events = {TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED};
+
+        mTelephonyRegistry.listenWithEventList(false, false, subId, mContext.getOpPackageName(),
+                mContext.getAttributionTag(), mTelephonyCallback.callback, events, false);
+        processAllMessages();
+
+        int[] callState = {0, 5, 0};
+        String[] imsCallId = {"0", "1", "0"};
+        int[] imsServiceType = {0, 1, 0};
+        int[] imsCallType = {0, 1, 0};
+        int[] callState2 = {0, 1, 0};
+        mTelephonyRegistry.notifyPreciseCallState(
+                /*phoneId*/ 0, subId, callState, imsCallId, imsServiceType, imsCallType);
+        mTelephonyRegistry.notifyPreciseCallState(
+                /*phoneId*/ 0, subId, callState2, imsCallId, imsServiceType, imsCallType);
+        processAllMessages();
+
+        assertEquals(2, mCallStateList.size());
+        //make sure the call state is from the first report(callState).
+        assertEquals(5, mCallStateList.get(0).getFirst().getCallState());
+        //make sure the call state is from the second report(callState2).
+        assertEquals(1, mCallStateList.get(1).getFirst().getCallState());
+    }
+
+    @Test
     @EnableFlags(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
     public void testNotifyCarrierRoamingNtnSignalStrengthChanged() {
         int subId = INVALID_SUBSCRIPTION_ID;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
index 88eea32..0db881c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
@@ -811,7 +811,7 @@
         doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_LTE).when(mServiceState)
                 .getRilDataRadioTechnology();
         doReturn(new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_LTE,
-                TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, false))
+                TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, false, false, false))
                 .when(mDisplayInfoController).getTelephonyDisplayInfo();
         doReturn(mPhone).when(mCT).getPhone();
         doReturn(mImsEcbm).when(mImsManager).getEcbmInterface();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/AutoDataSwitchControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/AutoDataSwitchControllerTest.java
index 0e2676e..d3f3050 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/AutoDataSwitchControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/AutoDataSwitchControllerTest.java
@@ -101,9 +101,11 @@
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
         mGoodTelephonyDisplayInfo = new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_NR,
-                TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED, false /*roaming*/);
+                TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED, false /*roaming*/,
+                false/*isNtn*/, false/*isSatelliteConstrainedDataStatus*/);
         mBadTelephonyDisplayInfo = new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_UMTS,
-                TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, false /*roaming*/);
+                TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, false /*roaming*/,
+                false/*isNtn*/, false/*isSatelliteConstrainedDataStatus*/);
         mMockedPhoneSwitcherCallback =
                 mock(AutoDataSwitchController.AutoDataSwitchControllerCallback.class);
         mMockedAlarmManager = mock(AlarmManager.class);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataConfigManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataConfigManagerTest.java
index 95cefd8..88dce51 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataConfigManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataConfigManagerTest.java
@@ -126,20 +126,23 @@
         doReturn(SignalStrength.SIGNAL_STRENGTH_POOR).when(signalStrength).getLevel();
         assertThat(mDataConfigManagerUT.getAutoDataSwitchScore(new TelephonyDisplayInfo(
                         TelephonyManager.NETWORK_TYPE_LTE,
-                        TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED, false/*isRoaming*/),
+                        TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED, false/*isRoaming*/,
+                        false/*isNtn*/, false/*isSatelliteConstrainedDataStatus*/),
                 signalStrength)).isEqualTo(10227);
         // Verify if entry contains any invalid negative scores, should yield 0.
         doReturn(SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN).when(signalStrength).getLevel();
         assertThat(mDataConfigManagerUT.getAutoDataSwitchScore(new TelephonyDisplayInfo(
                         TelephonyManager.NETWORK_TYPE_LTE,
-                        TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, false/*isRoaming*/),
+                        TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, false/*isRoaming*/,
+                        false/*isNtn*/, false/*isSatelliteConstrainedDataStatus*/),
                 signalStrength))
                 .isEqualTo(0/*OUT_OF_SERVICE_AUTO_DATA_SWITCH_SCORE*/);
         // Verify non-existent entry should yield -1
         doReturn(SignalStrength.SIGNAL_STRENGTH_POOR).when(signalStrength).getLevel();
         assertThat(mDataConfigManagerUT.getAutoDataSwitchScore(new TelephonyDisplayInfo(
                         TelephonyManager.NETWORK_TYPE_EDGE,
-                        TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, false/*isRoaming*/),
+                        TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, false/*isRoaming*/,
+                        false/*isNtn*/, false/*isSatelliteConstrainedDataStatus*/),
                 signalStrength))
                 .isEqualTo(0/*OUT_OF_SERVICE_AUTO_DATA_SWITCH_SCORE*/);
     }
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 f6fbdf6..fad1d93 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
@@ -2666,7 +2666,7 @@
 
         // Change data network type to NR
         doReturn(new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_NR,
-                TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, false))
+                TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, false, false, false))
                 .when(mDisplayInfoController).getTelephonyDisplayInfo();
         dataNetwork.sendMessage(13/*EVENT_DISPLAY_INFO_CHANGED*/);
         processAllMessages();
@@ -2709,7 +2709,7 @@
 
         // Change data network type to NR
         doReturn(new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_NR,
-                TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, false))
+                TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, false, false, false))
                 .when(mDisplayInfoController).getTelephonyDisplayInfo();
         dataNetwork.sendMessage(13/*EVENT_DISPLAY_INFO_CHANGED*/);
         processAllMessages();
@@ -2765,7 +2765,7 @@
 
         // Change data network type to NR
         doReturn(new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_NR,
-                TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, false))
+                TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, false, false, false))
                 .when(mDisplayInfoController).getTelephonyDisplayInfo();
         dataNetwork.sendMessage(13/*EVENT_DISPLAY_INFO_CHANGED*/);
         processAllMessages();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
index f7990b9..6e41448 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
@@ -146,7 +146,7 @@
     private AutoDataSwitchController.AutoDataSwitchControllerCallback mAutoDataSwitchCallback;
     private TelephonyDisplayInfo mTelephonyDisplayInfo = new TelephonyDisplayInfo(
             TelephonyManager.NETWORK_TYPE_NR,
-            TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, false);
+            TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE, false, false, false);
     private SubscriptionManagerServiceCallback mSubscriptionManagerServiceCallback;
 
     @Before
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 dc973af..566e5b9 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramDispatcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramDispatcherTest.java
@@ -60,6 +60,7 @@
 import android.testing.TestableLooper;
 
 import com.android.internal.R;
+import com.android.internal.os.SomeArgs;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.SmsDispatchersController;
@@ -1140,6 +1141,166 @@
         assertFalse(mDatagramDispatcherUT.isDatagramWaitForConnectedStateTimerStarted());
     }
 
+   @Test
+   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)));
+
+        verify(mMockSmsDispatchersController, times(1)).sendMtSmsPollingMessage();
+   }
+
+    @Test
+    public void
+            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)));
+
+        verifyZeroInteractions(mMockSmsDispatchersController);
+   }
+
+    @Test
+    public void
+            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)));
+
+        verifyZeroInteractions(mMockSmsDispatchersController);
+   }
+
+
+
+    @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);
+
+        mDatagramDispatcherUT.setDeviceAlignedWithSatellite(true);
+
+        verify(mMockSmsDispatchersController, times(1)).sendMtSmsPollingMessage();
+    }
+
+    @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);
+
+        verifyZeroInteractions(mMockSmsDispatchersController);
+    }
+
+    @Test
+    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);
+
+        mDatagramDispatcherUT.onSatelliteModemStateChanged(
+                SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED);
+
+        verify(mMockSmsDispatchersController, times(1)).sendMtSmsPollingMessage();
+    }
+
+    @Test
+    public void testOnSatelliteModemStateChanged_connected_sendsMtSmsPoll() {
+        setShouldPollMtSmsTrue();
+        mDatagramDispatcherUT.setDeviceAlignedWithSatellite(true);
+        when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
+
+        mDatagramDispatcherUT.onSatelliteModemStateChanged(
+                SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED);
+
+        verify(mMockSmsDispatchersController, times(1)).sendMtSmsPollingMessage();
+    }
+
+    @Test
+    public void testOnSatelliteModemStateChanged_transferring_sendsMtSmsPoll() {
+        setShouldPollMtSmsTrue();
+        mDatagramDispatcherUT.setDeviceAlignedWithSatellite(true);
+        when(mFeatureFlags.carrierRoamingNbIotNtn()).thenReturn(true);
+
+        mDatagramDispatcherUT.onSatelliteModemStateChanged(
+                SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING);
+
+        verify(mMockSmsDispatchersController, times(1)).sendMtSmsPollingMessage();
+    }
+
+    @Test
+    public void testOnSatelliteModemStateChanged_throttled_doesNotSendMtSmsPoll() {
+        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);
+
+        verify(mMockSmsDispatchersController, times(0)).sendMtSmsPollingMessage();
+    }
+
+    private void setModemState(int state) {
+        mDatagramDispatcherUT.onSatelliteModemStateChanged(state);
+    }
+
+    private void setShouldPollMtSmsTrue() {
+        // Set mHasEnteredConnectedState true
+        setModemState(SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED);
+        // Set the following so shouldPollMtSms returns true
+        mContextFixture.putBooleanResource(R.bool.config_enabled_mt_sms_polling, true);
+        when(mMockSatelliteController.shouldSendSmsToDatagramDispatcher(any(Phone.class)))
+                .thenReturn(true);
+        // This will trigger mShouldPollMtSms = shouldPollMtSms
+        setModemState(SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED);
+    }
+
+    private void startMtSmsPollingThrottle() {
+        // Call sendSms to put message in mPendingSmsMap with isMtSmsPolling=true
+        PendingRequest pendingRequest = new PendingRequest(
+                SmsDispatchersController.PendingRequest.TYPE_TEXT, null, "test-app",
+                Binder.getCallingUserHandle().getIdentifier(), "1111", "2222", asArrayList(null),
+                asArrayList(null), false, null, 0, asArrayList("text"), null, false, 0, false,
+                10, 100L, false, /* isMtSmsPolling= */ true);
+        mDatagramDispatcherUT.sendSms(pendingRequest);
+        SomeArgs args = SomeArgs.obtain();
+        args.arg1 = mPhone.getSubId();
+        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));
+    }
+
     private boolean waitForIntegerConsumerResult(int expectedNumberOfEvents) {
         for (int i = 0; i < expectedNumberOfEvents; i++) {
             try {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSessionControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSessionControllerTest.java
index 8c1ae50..0d11fed 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSessionControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSessionControllerTest.java
@@ -150,7 +150,9 @@
         when(resources.getBoolean(
                  R.bool.config_satellite_modem_support_concurrent_tn_scanning))
             .thenReturn(false);
-
+        when(resources.getBoolean(
+                 R.bool.config_satellite_allow_tn_scanning_during_satellite_session))
+            .thenReturn(true);
         when(mFeatureFlags.satellitePersistentLogging()).thenReturn(true);
         when(mMockSatelliteController.isSatelliteAttachRequired()).thenReturn(false);
         when(mMockSatelliteController.isSatelliteRoamingP2pSmSSupported(