Merge "Set Data SPN to SPN when not overridden" into main
diff --git a/flags/misc.aconfig b/flags/misc.aconfig
index 538a114..65ce401 100644
--- a/flags/misc.aconfig
+++ b/flags/misc.aconfig
@@ -96,39 +96,6 @@
     bug:"271921464"
 }
 
-# OWNER=rambowang TARGET=24Q3
-flag {
-    name: "fix_crash_on_getting_config_when_phone_is_gone"
-    namespace: "telephony"
-    description: "Fix VCN crash when calling CarrierConfigManager.getConfigForSubId while phone process has gone."
-    bug:"319791612"
-    metadata {
-        purpose: PURPOSE_BUGFIX
-    }
-}
-
-# OWNER=rambowang TARGET=24Q3
-flag {
-    name: "add_anomaly_when_notify_config_changed_with_invalid_phone"
-    namespace: "telephony"
-    description: "Report anomaly when CarrierConfigLoader received config change with sub that maps to invalid phoneId"
-    bug:"270757342"
-    metadata {
-        purpose: PURPOSE_BUGFIX
-    }
-}
-
-# OWNER=rambowang TARGET=24Q3
-flag {
-    name: "hide_preinstalled_carrier_app_at_most_once"
-    namespace: "telephony"
-    description: "Fix bug when preloaded carrier app is uninstalled and lose provisioning data"
-    bug:"158028151"
-    metadata {
-        purpose: PURPOSE_BUGFIX
-    }
-}
-
 # OWNER=sangyun TARGET=24Q3
 flag {
     name: "roaming_notification_for_single_data_network"
@@ -218,17 +185,6 @@
     }
 }
 
-# OWNER=rambowang TARGET=24Q4
-flag {
-    name: "support_phone_uid_check_for_multiuser"
-    namespace: "telephony"
-    description: "Check phone/system processes from UID with multiuser-aware way"
-    bug:"328511085"
-    metadata {
-        purpose: PURPOSE_BUGFIX
-    }
-}
-
 # OWNER=joonhunshin TARGET=24Q4
 flag {
     name: "use_carrier_config_for_cfnry_time_via_mmi"
diff --git a/flags/uicc.aconfig b/flags/uicc.aconfig
index f41fad3..14341d9 100644
--- a/flags/uicc.aconfig
+++ b/flags/uicc.aconfig
@@ -43,14 +43,6 @@
     bug:"318348580"
 }
 
-# OWNER=rambowang TARGET=24Q3
-flag {
-    name: "cleanup_open_logical_channel_record_on_dispose"
-    namespace: "telephony"
-    description: "This flag cleans up the OpenLogicalChannelRecord once SIM is removed"
-    bug:"335046531"
-}
-
 # OWNER=arunvoddu TARGET=24Q4
 flag {
     name: "set_carrier_restriction_status"
diff --git a/proto/src/persist_atoms.proto b/proto/src/persist_atoms.proto
index 2010ce1..3f964b3 100644
--- a/proto/src/persist_atoms.proto
+++ b/proto/src/persist_atoms.proto
@@ -718,6 +718,8 @@
     optional int32 count_of_allowed_satellite_access = 26;
     optional int32 count_of_disallowed_satellite_access = 27;
     optional int32 count_of_satellite_access_check_fail = 28;
+    optional bool is_provisioned = 29;
+    optional int32 carrier_id = 30;
 }
 
 message SatelliteSession {
@@ -734,6 +736,10 @@
     optional int32 count_of_incoming_datagram_failed = 11;
     optional bool is_demo_mode = 12;
     optional int32 max_ntn_signal_strength_level = 13;
+    optional int32 carrier_id = 14;
+    optional int32 count_of_satellite_notification_displayed = 15;
+    optional int32 count_of_auto_exit_due_to_screen_off = 16;
+    optional int32 count_of_auto_exit_due_to_tn_network = 17;
 }
 
 message SatelliteIncomingDatagram {
@@ -741,6 +747,7 @@
     optional int32 datagram_size_bytes = 2;
     optional int64 datagram_transfer_time_millis = 3;
     optional bool is_demo_mode = 4;
+    optional int32 carrier_id = 5;
 }
 
 message SatelliteOutgoingDatagram {
@@ -749,6 +756,7 @@
     optional int32 datagram_size_bytes = 3;
     optional int64 datagram_transfer_time_millis = 4;
     optional bool is_demo_mode = 5;
+    optional int32 carrier_id = 6;
 }
 
 message SatelliteProvision {
@@ -756,6 +764,7 @@
     optional int32 provisioning_time_sec = 2;
     optional bool is_provision_request = 3;
     optional bool is_canceled = 4;
+    optional int32 carrier_id = 5;
 }
 
 message SatelliteSosMessageRecommender {
@@ -767,6 +776,8 @@
     optional bool is_multi_sim = 6;
     optional int32 recommending_handover_type = 7;
     optional bool is_satellite_allowed_in_current_location = 8;
+    optional bool is_wifi_connected = 9;
+    optional int32 carrier_id = 10;
 }
 
 message DataNetworkValidation {
@@ -806,6 +817,7 @@
     optional int32 satellite_session_gap_min_sec = 5;
     optional int32 satellite_session_gap_avg_sec = 6;
     optional int32 satellite_session_gap_max_sec = 7;
+    optional int32 carrier_id = 8;
 }
 
 message SatelliteEntitlement {
@@ -833,4 +845,5 @@
     optional int32 result_code = 7;
     repeated string country_codes = 8;
     optional int32 config_data_source = 9;
+    optional int32 carrier_id = 10;
 }
diff --git a/src/java/com/android/internal/telephony/InboundSmsHandler.java b/src/java/com/android/internal/telephony/InboundSmsHandler.java
index 37d8aa6..891f3f4 100644
--- a/src/java/com/android/internal/telephony/InboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/InboundSmsHandler.java
@@ -305,9 +305,9 @@
         mResolver = context.getContentResolver();
         mWapPush = new WapPushOverSms(context, mFeatureFlags);
 
-        boolean smsCapable = mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_sms_capable);
-        mSmsReceiveDisabled = !TelephonyManager.from(mContext).getSmsReceiveCapableForPhone(
+        TelephonyManager telephonyManager = TelephonyManager.from(mContext);
+        boolean smsCapable = telephonyManager.isDeviceSmsCapable();
+        mSmsReceiveDisabled = !telephonyManager.getSmsReceiveCapableForPhone(
                 mPhone.getPhoneId(), smsCapable);
 
         PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
diff --git a/src/java/com/android/internal/telephony/MockModem.java b/src/java/com/android/internal/telephony/MockModem.java
index e894ed9..1fcdc2a 100644
--- a/src/java/com/android/internal/telephony/MockModem.java
+++ b/src/java/com/android/internal/telephony/MockModem.java
@@ -32,7 +32,6 @@
 import android.os.IBinder;
 import android.os.UserHandle;
 
-import com.android.internal.telephony.flags.Flags;
 import com.android.telephony.Rlog;
 
 /** This class provides wrapper APIs for binding interfaces to mock service. */
@@ -161,12 +160,8 @@
         intent.setAction(actionName + phoneId);
         intent.putExtra(PHONE_ID, phoneId);
 
-        if (Flags.supportPhoneUidCheckForMultiuser()) {
-            status = mContext.bindServiceAsUser(intent, serviceConnection, Context.BIND_AUTO_CREATE,
-                    UserHandle.of(ActivityManager.getCurrentUser()));
-        } else {
-            status = mContext.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
-        }
+        status = mContext.bindServiceAsUser(intent, serviceConnection, Context.BIND_AUTO_CREATE,
+                UserHandle.of(ActivityManager.getCurrentUser()));
         return status;
     }
 
diff --git a/src/java/com/android/internal/telephony/RIL.java b/src/java/com/android/internal/telephony/RIL.java
index b354b1a..88ead6f 100644
--- a/src/java/com/android/internal/telephony/RIL.java
+++ b/src/java/com/android/internal/telephony/RIL.java
@@ -1047,10 +1047,16 @@
                     }
                 } else {
                     mDisabledRadioServices.get(service).add(mPhoneId);
-                    mHalVersion.put(service, RADIO_HAL_VERSION_UNKNOWN);
-                    riljLoge("getRadioServiceProxy: set " + serviceToString(service) + " for "
-                            + HIDL_SERVICE_NAME[mPhoneId] + " as disabled\n"
-                            + android.util.Log.getStackTraceString(new RuntimeException()));
+                    if (isRadioServiceSupported(service)) {
+                        mHalVersion.put(service, RADIO_HAL_VERSION_UNKNOWN);
+                        riljLoge("getRadioServiceProxy: set " + serviceToString(service) + " for "
+                                + HIDL_SERVICE_NAME[mPhoneId] + " as disabled\n"
+                                + android.util.Log.getStackTraceString(new RuntimeException()));
+                    } else {
+                        mHalVersion.put(service, RADIO_HAL_VERSION_UNSUPPORTED);
+                        riljLog("getRadioServiceProxy: set " + serviceToString(service) + " for "
+                                + HIDL_SERVICE_NAME[mPhoneId] + " as disabled (unsupported)");
+                    }
                 }
             }
         } catch (RemoteException e) {
diff --git a/src/java/com/android/internal/telephony/SMSDispatcher.java b/src/java/com/android/internal/telephony/SMSDispatcher.java
index 3ae13f8..2f2b62a 100644
--- a/src/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/src/java/com/android/internal/telephony/SMSDispatcher.java
@@ -52,7 +52,6 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.PersistableBundle;
-import android.os.Process;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
@@ -256,8 +255,7 @@
         mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor(
                 Settings.Global.SMS_SHORT_CODE_RULE), false, mSettingsObserver);
 
-        mSmsCapable = mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_sms_capable);
+        mSmsCapable = mTelephonyManager.isDeviceSmsCapable();
         mSmsSendDisabled = !mTelephonyManager.getSmsSendCapableForPhone(
                 mPhone.getPhoneId(), mSmsCapable);
         IntentFilter intentFilter = new IntentFilter();
@@ -3039,24 +3037,6 @@
         return SubscriptionManager.getSubscriptionId(mPhone.getPhoneId());
     }
 
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    private void checkCallerIsPhoneOrCarrierApp() {
-        int uid = Binder.getCallingUid();
-        int appId = UserHandle.getAppId(uid);
-        if (appId == Process.PHONE_UID || uid == 0) {
-            return;
-        }
-        try {
-            PackageManager pm = mContext.getPackageManager();
-            ApplicationInfo ai = pm.getApplicationInfo(getCarrierAppPackageName(), 0);
-            if (UserHandle.getAppId(ai.uid) != UserHandle.getAppId(Binder.getCallingUid())) {
-                throw new SecurityException("Caller is not phone or carrier app!");
-            }
-        } catch (PackageManager.NameNotFoundException re) {
-            throw new SecurityException("Caller is not phone or carrier app!");
-        }
-    }
-
     protected boolean isCdmaMo() {
         return mSmsDispatchersController.isCdmaMo();
     }
diff --git a/src/java/com/android/internal/telephony/TelephonyCountryDetector.java b/src/java/com/android/internal/telephony/TelephonyCountryDetector.java
index b604431..c2d6018 100644
--- a/src/java/com/android/internal/telephony/TelephonyCountryDetector.java
+++ b/src/java/com/android/internal/telephony/TelephonyCountryDetector.java
@@ -558,7 +558,11 @@
         }
     }
 
-    private boolean isWifiNetworkConnected() {
+    /**
+     * Check whether Wi-Fi network is connected or not.
+     * @return {@code true} is Wi-Fi is connected, {@code false} otherwise.
+     */
+    public boolean isWifiNetworkConnected() {
         Network activeNetwork = mConnectivityManager.getActiveNetwork();
         NetworkCapabilities networkCapabilities =
                 mConnectivityManager.getNetworkCapabilities(activeNetwork);
diff --git a/src/java/com/android/internal/telephony/domainselection/DomainSelectionConnection.java b/src/java/com/android/internal/telephony/domainselection/DomainSelectionConnection.java
index c3276b2..677db87 100644
--- a/src/java/com/android/internal/telephony/domainselection/DomainSelectionConnection.java
+++ b/src/java/com/android/internal/telephony/domainselection/DomainSelectionConnection.java
@@ -43,6 +43,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.infra.AndroidFuture;
+import com.android.internal.telephony.CommandException;
 import com.android.internal.telephony.IDomainSelector;
 import com.android.internal.telephony.ITransportSelectorCallback;
 import com.android.internal.telephony.ITransportSelectorResultCallback;
@@ -70,7 +71,9 @@
     protected static final int EVENT_SERVICE_CONNECTED = 3;
     protected static final int EVENT_SERVICE_BINDING_TIMEOUT = 4;
     protected static final int EVENT_RESET_NETWORK_SCAN_DONE = 5;
-    protected static final int EVENT_LAST = EVENT_RESET_NETWORK_SCAN_DONE;
+    protected static final int EVENT_TRIGGER_NETWORK_SCAN_DONE = 6;
+    protected static final int EVENT_MODEM_RESET = 7;
+    protected static final int EVENT_LAST = EVENT_MODEM_RESET;
 
     private static final int DEFAULT_BIND_RETRY_TIMEOUT_MS = 4 * 1000;
 
@@ -308,6 +311,23 @@
                                 mPendingScanRequest.mScanType, false);
                     }
                     break;
+                case EVENT_TRIGGER_NETWORK_SCAN_DONE:
+                    synchronized (mLock) {
+                        if (checkState(STATUS_DISPOSED) || !checkState(STATUS_WAIT_SCAN_RESULT)) {
+                            return;
+                        }
+                        ar = (AsyncResult) msg.obj;
+                        if (ar != null && ar.exception != null) {
+                            onTriggerNetworkScanError((Integer) ar.userObj,
+                                    ((CommandException) ar.exception).getCommandError());
+                        }
+                    }
+                    break;
+                case EVENT_MODEM_RESET:
+                    synchronized (mLock) {
+                        onModemReset();
+                    }
+                    break;
                 default:
                     loge("handleMessage unexpected msg=" + msg.what);
                     break;
@@ -532,10 +552,13 @@
             if (!mRegisteredRegistrant) {
                 mPhone.registerForEmergencyNetworkScan(mHandler,
                         EVENT_EMERGENCY_NETWORK_SCAN_RESULT, null);
+                mPhone.mCi.registerForModemReset(mHandler, EVENT_MODEM_RESET, null);
                 mRegisteredRegistrant = true;
             }
             setState(STATUS_WAIT_SCAN_RESULT);
-            mPhone.triggerEmergencyNetworkScan(preferredNetworks, scanType, null);
+            mPhone.triggerEmergencyNetworkScan(preferredNetworks, scanType,
+                    mHandler.obtainMessage(EVENT_TRIGGER_NETWORK_SCAN_DONE,
+                            Integer.valueOf(scanType)));
             mPendingScanRequest = null;
         }
     }
@@ -725,6 +748,7 @@
         setState(STATUS_DISPOSED);
         if (mRegisteredRegistrant) {
             mPhone.unregisterForEmergencyNetworkScan(mHandler);
+            mPhone.mCi.unregisterForModemReset(mHandler);
             mRegisteredRegistrant = false;
         }
         onCancel(true);
@@ -749,6 +773,34 @@
         }
     }
 
+    private void onTriggerNetworkScanError(int scanType, CommandException.Error error) {
+        loge("onTriggerNetworkScanError scanType=" + scanType + ", error=" + error);
+
+        if (shouldTerminateCallOnRadioNotAvailable()
+                && error == CommandException.Error.RADIO_NOT_AVAILABLE) {
+            clearState(STATUS_WAIT_SCAN_RESULT);
+            onSelectionTerminated(DisconnectCause.POWER_OFF);
+            dispose();
+            return;
+        }
+    }
+
+    private void onModemReset() {
+        loge("onModemReset status=" + mStatus);
+        if (!shouldTerminateCallOnRadioNotAvailable()) {
+            return;
+        }
+        if (checkState(STATUS_DISPOSED) || checkState(STATUS_DOMAIN_SELECTED)) {
+            return;
+        }
+        onSelectionTerminated(DisconnectCause.POWER_OFF);
+        dispose();
+    }
+
+    private boolean shouldTerminateCallOnRadioNotAvailable() {
+        return mIsEmergency && mSelectorType == DomainSelectionService.SELECTOR_TYPE_CALLING;
+    }
+
     /**
      * Get the  preferred transport.
      *
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsNrSaModeHandler.java b/src/java/com/android/internal/telephony/imsphone/ImsNrSaModeHandler.java
index 234723f..f2b5dee 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsNrSaModeHandler.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsNrSaModeHandler.java
@@ -27,6 +27,8 @@
 import static android.telephony.ims.stub.ImsRegistrationImplBase.ImsRegistrationTech;
 import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN;
 
+import static com.android.internal.telephony.CommandsInterface.IMS_MMTEL_CAPABILITY_VOICE;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
@@ -52,21 +54,19 @@
 public class ImsNrSaModeHandler extends Handler{
 
     public static final String TAG = "ImsNrSaModeHandler";
-    public static final String MMTEL_FEATURE_TAG =
-            "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel\"";
 
     private static final int MSG_PRECISE_CALL_STATE_CHANGED = 101;
-    private static final int MSG_REQUEST_IS_VONR_ENABLED = 102;
-    private static final int MSG_RESULT_IS_VONR_ENABLED = 103;
+    private static final int MSG_RESULT_IS_VONR_ENABLED = 102;
 
     private final @NonNull ImsPhone mPhone;
     private @Nullable CarrierConfigManager mCarrierConfigManager;
 
     private @NrSaDisablePolicy int mNrSaDisablePolicy;
     private boolean mIsNrSaDisabledForWfc;
-    private boolean mIsVowifiRegistered;
+    private boolean mIsWifiRegistered;
     private boolean mIsInImsCall;
     private boolean mIsNrSaSupported;
+    private boolean mIsVoiceCapable;
 
     private final CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener =
             (slotIndex, subId, carrierId, specificCarrierId) -> setNrSaDisablePolicy(subId);
@@ -100,37 +100,16 @@
      */
     public void onImsRegistered(
             @ImsRegistrationTech int imsRadioTech, @NonNull Set<String> featureTags) {
-        if (mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_NONE) {
+        if (!mIsNrSaSupported || mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_NONE) {
             return;
         }
 
         Log.d(TAG, "onImsRegistered: ImsRegistrationTech = " + imsRadioTech);
 
-        boolean isVowifiRegChanged = false;
-
-        if (isVowifiRegistered() && imsRadioTech != REGISTRATION_TECH_IWLAN) {
-            setVowifiRegStatus(false);
-            isVowifiRegChanged = true;
-        } else if (!isVowifiRegistered() && imsRadioTech == REGISTRATION_TECH_IWLAN
-                && featureTags.contains(MMTEL_FEATURE_TAG)) {
-            setVowifiRegStatus(true);
-            isVowifiRegChanged = true;
-        }
-
-        if (isVowifiRegChanged) {
-            if (mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_VOWIFI_REGISTERED) {
-                setNrSaMode(!isVowifiRegistered());
-            } else if ((mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_WFC_ESTABLISHED
-                    || mNrSaDisablePolicy
-                    == NR_SA_DISABLE_POLICY_WFC_ESTABLISHED_WHEN_VONR_DISABLED)
-                    && isImsCallOngoing()) {
-                if (mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_WFC_ESTABLISHED_WHEN_VONR_DISABLED) {
-                    requestIsVonrEnabled(!isVowifiRegistered());
-                    return;
-                }
-
-                setNrSaMode(!isVowifiRegistered());
-            }
+        final boolean isNewWifiRegistered = imsRadioTech == REGISTRATION_TECH_IWLAN;
+        if (isWifiRegistered() != isNewWifiRegistered) {
+            setWifiRegStatus(isNewWifiRegistered);
+            calculateAndControlNrSaIfNeeded();
         }
     }
 
@@ -141,27 +120,15 @@
      */
     public void onImsUnregistered(
             @ImsRegistrationTech int imsRadioTech) {
-        if (mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_NONE
-                || imsRadioTech != REGISTRATION_TECH_IWLAN || !isVowifiRegistered()) {
+        if (!mIsNrSaSupported || mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_NONE
+                || imsRadioTech != REGISTRATION_TECH_IWLAN || !isWifiRegistered()) {
             return;
         }
 
         Log.d(TAG, "onImsUnregistered : ImsRegistrationTech = " + imsRadioTech);
 
-        setVowifiRegStatus(false);
-
-        if (mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_VOWIFI_REGISTERED) {
-            setNrSaMode(true);
-        } else if ((mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_WFC_ESTABLISHED
-                || mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_WFC_ESTABLISHED_WHEN_VONR_DISABLED)
-                && isImsCallOngoing()) {
-            if (mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_WFC_ESTABLISHED_WHEN_VONR_DISABLED) {
-                requestIsVonrEnabled(true);
-                return;
-            }
-
-            setNrSaMode(true);
-        }
+        setWifiRegStatus(false);
+        calculateAndControlNrSaIfNeeded();
     }
 
     /**
@@ -182,13 +149,23 @@
             isImsCallStatusChanged = true;
         }
 
-        if (isVowifiRegistered() && isImsCallStatusChanged) {
-            if (mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_WFC_ESTABLISHED_WHEN_VONR_DISABLED) {
-                requestIsVonrEnabled(!isImsCallOngoing());
-                return;
-            }
+        if (isWifiRegistered() && isImsCallStatusChanged) {
+            calculateAndControlNrSaIfNeeded();
+        }
+    }
 
-            setNrSaMode(!isImsCallOngoing());
+    /**
+     * Updates Capability.
+     */
+    public void updateImsCapability(int capabilities) {
+        if (!mIsNrSaSupported || mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_NONE) {
+            return;
+        }
+
+        boolean isVoiceCapable = (IMS_MMTEL_CAPABILITY_VOICE & capabilities) != 0;
+        if (mIsVoiceCapable != isVoiceCapable) {
+            mIsVoiceCapable = isVoiceCapable;
+            calculateAndControlNrSaIfNeeded();
         }
     }
 
@@ -200,11 +177,6 @@
             case MSG_PRECISE_CALL_STATE_CHANGED :
                 onPreciseCallStateChanged();
                 break;
-            case MSG_REQUEST_IS_VONR_ENABLED :
-                Log.d(TAG, "request isVoNrEnabled");
-                mPhone.getDefaultPhone().mCi.isVoNrEnabled(
-                        obtainMessage(MSG_RESULT_IS_VONR_ENABLED, msg.obj), null);
-                break;
             case MSG_RESULT_IS_VONR_ENABLED :
                 ar = (AsyncResult) msg.obj;
 
@@ -212,8 +184,9 @@
                     boolean vonrEnabled = ((Boolean) ar.result).booleanValue();
 
                     Log.d(TAG, "result isVoNrEnabled = " + vonrEnabled);
-                    if (!vonrEnabled) {
-                        setNrSaMode(((Boolean) ar.userObj).booleanValue());
+                    if (isWifiCallingOngoing() && !vonrEnabled) {
+                        // If still WiFi calling is ongoing and VoNR is disabled, disable NR SA.
+                        setNrSaMode(false);
                     }
                 }
 
@@ -262,14 +235,18 @@
         if (mPhone.getSubId() == subId && mCarrierConfigManager != null) {
             PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(mPhone.getSubId(),
                     KEY_NR_SA_DISABLE_POLICY_INT, KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY);
-            mNrSaDisablePolicy = bundle.getInt(KEY_NR_SA_DISABLE_POLICY_INT);
             int[] nrAvailabilities = bundle.getIntArray(KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY);
             mIsNrSaSupported = nrAvailabilities != null
                     && Arrays.stream(nrAvailabilities).anyMatch(
                             value -> value == CARRIER_NR_AVAILABILITY_SA);
 
-            Log.d(TAG, "setNrSaDisablePolicy : NrSaDisablePolicy = "
-                    + mNrSaDisablePolicy + ", IsNrSaSupported = "  + mIsNrSaSupported);
+            if (!mIsNrSaSupported) {
+                return;
+            }
+
+            mNrSaDisablePolicy = bundle.getInt(KEY_NR_SA_DISABLE_POLICY_INT);
+
+            Log.d(TAG, "setNrSaDisablePolicy : NrSaDisablePolicy = " + mNrSaDisablePolicy);
 
             if (mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_WFC_ESTABLISHED_WHEN_VONR_DISABLED
                     || mNrSaDisablePolicy == NR_SA_DISABLE_POLICY_WFC_ESTABLISHED) {
@@ -280,27 +257,20 @@
         }
     }
 
-    private void requestIsVonrEnabled(boolean onOrOff) {
-        Message msg = obtainMessage(MSG_REQUEST_IS_VONR_ENABLED, onOrOff);
-        msg.sendToTarget();
-    }
-
     private void setNrSaMode(boolean onOrOff) {
-        if (mIsNrSaSupported) {
-            mPhone.getDefaultPhone().setN1ModeEnabled(onOrOff, null);
-            Log.i(TAG, "setNrSaMode : " + onOrOff);
+        mPhone.getDefaultPhone().setN1ModeEnabled(onOrOff, null);
+        Log.i(TAG, "setNrSaMode : " + onOrOff);
 
-            setNrSaDisabledForWfc(!onOrOff);
-        }
+        setNrSaDisabledForWfc(!onOrOff);
     }
 
     /**
-     * Sets VoWiFi reg status.
+     * Sets WiFi reg status.
      */
     @VisibleForTesting
-    public void setVowifiRegStatus(boolean registered) {
-        Log.d(TAG, "setVowifiRegStatus : " + registered);
-        mIsVowifiRegistered = registered;
+    public void setWifiRegStatus(boolean registered) {
+        Log.d(TAG, "setWifiRegStatus : " + registered);
+        mIsWifiRegistered = registered;
     }
 
     /**
@@ -313,8 +283,8 @@
     }
 
     @VisibleForTesting
-    public boolean isVowifiRegistered() {
-        return mIsVowifiRegistered;
+    public boolean isWifiRegistered() {
+        return mIsWifiRegistered;
     }
 
     @VisibleForTesting
@@ -322,8 +292,7 @@
         return mIsInImsCall;
     }
 
-    @VisibleForTesting
-    public boolean isNrSaDisabledForWfc() {
+    private boolean isNrSaDisabledForWfc() {
         return mIsNrSaDisabledForWfc;
     }
 
@@ -353,4 +322,56 @@
 
         return false;
     }
+
+    private void calculateAndControlNrSaIfNeeded() {
+        switch (mNrSaDisablePolicy) {
+            case NR_SA_DISABLE_POLICY_VOWIFI_REGISTERED:
+                if (isNrSaDisabledForWfc() == isWifiRegisteredForVoice()) {
+                    // NR SA is already disabled or condition is not met for disabling NR SA.
+                    // So, no need for further action
+                    return;
+                }
+
+                // Disable NR SA if VoWiFi registered otherwise enable
+                setNrSaMode(!isWifiRegisteredForVoice());
+                return;
+            case NR_SA_DISABLE_POLICY_WFC_ESTABLISHED:
+                if (isNrSaDisabledForWfc() == isWifiCallingOngoing()) {
+                    // NR SA is already disabled or condition is not met for disabling NR SA.
+                    // So, no need for further action
+                    return;
+                }
+
+                // Disable NR SA if VoWiFi call established otherwise enable
+                setNrSaMode(!isWifiCallingOngoing());
+                return;
+            case NR_SA_DISABLE_POLICY_WFC_ESTABLISHED_WHEN_VONR_DISABLED:
+                if (isNrSaDisabledForWfc() == isWifiCallingOngoing()) {
+                    // NR SA is already disabled or condition is not met for disabling NR SA.
+                    // So, no need for further action
+                    return;
+                }
+
+                if (isWifiCallingOngoing()) {
+                    // Query whether VoNR is enabled or not.
+                    mPhone.getDefaultPhone().mCi.isVoNrEnabled(
+                            obtainMessage(MSG_RESULT_IS_VONR_ENABLED), null);
+                    return;
+                }
+
+                // Enable NR SA if there are no VoWiFi calls.
+                setNrSaMode(true);
+                return;
+            default:
+                break;
+        }
+    }
+
+    private boolean isWifiRegisteredForVoice() {
+        return isWifiRegistered() && mIsVoiceCapable;
+    }
+
+    private boolean isWifiCallingOngoing() {
+        return isWifiRegistered() && mIsVoiceCapable && isImsCallOngoing();
+    }
 }
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
index cb188ea..22b8a75 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
@@ -2762,7 +2762,7 @@
     }
 
     /**
-     * Update IMS registration information to modem.
+     * Update IMS registration information to modem and other modules.
      *
      * @param capabilities indicate MMTEL capability such as VOICE, VIDEO and SMS.
      */
@@ -2783,6 +2783,8 @@
             mDefaultPhone.mCi.updateImsRegistrationInfo(mImsRegistrationState,
                     mImsRegistrationTech, 0, capabilities, null);
             mNotifiedRegisteredState = true;
+
+            mImsNrSaModeHandler.updateImsCapability(capabilities);
         }
     }
 
diff --git a/src/java/com/android/internal/telephony/metrics/MetricsCollector.java b/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
index 2367ef5..767c39a 100644
--- a/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
+++ b/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
@@ -1475,7 +1475,9 @@
                 satelliteController.countOfDatagramTypeKeepAliveFail,
                 satelliteController.countOfAllowedSatelliteAccess,
                 satelliteController.countOfDisallowedSatelliteAccess,
-                satelliteController.countOfSatelliteAccessCheckFail);
+                satelliteController.countOfSatelliteAccessCheckFail,
+                satelliteController.isProvisioned,
+                satelliteController.carrierId);
     }
 
     private static StatsEvent buildStatsEvent(SatelliteSession satelliteSession) {
@@ -1493,7 +1495,11 @@
                 satelliteSession.countOfIncomingDatagramSuccess,
                 satelliteSession.countOfIncomingDatagramFailed,
                 satelliteSession.isDemoMode,
-                satelliteSession.maxNtnSignalStrengthLevel);
+                satelliteSession.maxNtnSignalStrengthLevel,
+                satelliteSession.carrierId,
+                satelliteSession.countOfSatelliteNotificationDisplayed,
+                satelliteSession.countOfAutoExitDueToScreenOff,
+                satelliteSession.countOfAutoExitDueToTnNetwork);
     }
 
     private static StatsEvent buildStatsEvent(SatelliteIncomingDatagram stats) {
@@ -1502,7 +1508,8 @@
                 stats.resultCode,
                 stats.datagramSizeBytes,
                 stats.datagramTransferTimeMillis,
-                stats.isDemoMode);
+                stats.isDemoMode,
+                stats.carrierId);
     }
 
     private static StatsEvent buildStatsEvent(SatelliteOutgoingDatagram stats) {
@@ -1512,7 +1519,8 @@
                 stats.resultCode,
                 stats.datagramSizeBytes,
                 stats.datagramTransferTimeMillis,
-                stats.isDemoMode);
+                stats.isDemoMode,
+                stats.carrierId);
     }
 
     private static StatsEvent buildStatsEvent(SatelliteProvision stats) {
@@ -1521,7 +1529,8 @@
                 stats.resultCode,
                 stats.provisioningTimeSec,
                 stats.isProvisionRequest,
-                stats.isCanceled);
+                stats.isCanceled,
+                stats.carrierId);
     }
 
     private static StatsEvent buildStatsEvent(SatelliteSosMessageRecommender stats) {
@@ -1534,7 +1543,9 @@
                 stats.count,
                 stats.isMultiSim,
                 stats.recommendingHandoverType,
-                stats.isSatelliteAllowedInCurrentLocation);
+                stats.isSatelliteAllowedInCurrentLocation,
+                stats.isWifiConnected,
+                stats.carrierId);
     }
 
     private static StatsEvent buildStatsEvent(DataNetworkValidation stats) {
@@ -1579,7 +1590,8 @@
                 stats.countOfSatelliteNotificationDisplayed,
                 stats.satelliteSessionGapMinSec,
                 stats.satelliteSessionGapAvgSec,
-                stats.satelliteSessionGapMaxSec);
+                stats.satelliteSessionGapMaxSec,
+                stats.carrierId);
     }
 
     private static StatsEvent buildStatsEvent(SatelliteEntitlement stats) {
@@ -1611,7 +1623,8 @@
                 stats.isEmergency,
                 stats.resultCode,
                 stats.countryCodes,
-                stats.configDataSource);
+                stats.configDataSource,
+                stats.carrierId);
     }
 
     /** Returns all phones in {@link PhoneFactory}, or an empty array if phones not made yet. */
diff --git a/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java b/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java
index 12dab7a..9fc0e6f 100644
--- a/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java
+++ b/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java
@@ -770,6 +770,8 @@
         atom.countOfAllowedSatelliteAccess += stats.countOfAllowedSatelliteAccess;
         atom.countOfDisallowedSatelliteAccess += stats.countOfDisallowedSatelliteAccess;
         atom.countOfSatelliteAccessCheckFail += stats.countOfSatelliteAccessCheckFail;
+        atom.isProvisioned = stats.isProvisioned;
+        atom.carrierId = stats.carrierId;
 
         mAtoms.satelliteController = atomArray;
         saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
@@ -869,6 +871,7 @@
         atom.satelliteSessionGapMinSec = stats.satelliteSessionGapMinSec;
         atom.satelliteSessionGapAvgSec = stats.satelliteSessionGapAvgSec;
         atom.satelliteSessionGapMaxSec = stats.satelliteSessionGapMaxSec;
+        atom.carrierId = stats.carrierId;
 
         mAtoms.carrierRoamingSatelliteControllerStats = atomArray;
         saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
@@ -2331,7 +2334,12 @@
                     && stats.countOfIncomingDatagramSuccess == key.countOfIncomingDatagramSuccess
                     && stats.countOfIncomingDatagramFailed == key.countOfIncomingDatagramFailed
                     && stats.isDemoMode == key.isDemoMode
-                    && stats.maxNtnSignalStrengthLevel == key.maxNtnSignalStrengthLevel) {
+                    && stats.maxNtnSignalStrengthLevel == key.maxNtnSignalStrengthLevel
+                    && stats.carrierId == key.carrierId
+                    && stats.countOfSatelliteNotificationDisplayed
+                    == key.countOfSatelliteNotificationDisplayed
+                    && stats.countOfAutoExitDueToScreenOff == key.countOfAutoExitDueToScreenOff
+                    && stats.countOfAutoExitDueToTnNetwork == key.countOfAutoExitDueToTnNetwork) {
                 return stats;
             }
         }
@@ -2350,7 +2358,9 @@
                     && stats.isImsRegistered == key.isImsRegistered
                     && stats.cellularServiceState == key.cellularServiceState
                     && stats.isMultiSim == key.isMultiSim
-                    && stats.recommendingHandoverType == key.recommendingHandoverType) {
+                    && stats.recommendingHandoverType == key.recommendingHandoverType
+                    && stats.isWifiConnected == key.isWifiConnected
+                    && stats.carrierId == key.carrierId) {
                 return stats;
             }
         }
diff --git a/src/java/com/android/internal/telephony/metrics/SatelliteStats.java b/src/java/com/android/internal/telephony/metrics/SatelliteStats.java
index c2b2753..ddf0a4e 100644
--- a/src/java/com/android/internal/telephony/metrics/SatelliteStats.java
+++ b/src/java/com/android/internal/telephony/metrics/SatelliteStats.java
@@ -17,6 +17,7 @@
 package com.android.internal.telephony.metrics;
 
 import static android.telephony.satellite.NtnSignalStrength.NTN_SIGNAL_STRENGTH_NONE;
+import static android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID;
 
 import android.telephony.satellite.NtnSignalStrength;
 import android.telephony.satellite.SatelliteManager;
@@ -37,6 +38,7 @@
 import com.android.telephony.Rlog;
 
 import java.util.Arrays;
+import java.util.Optional;
 
 /** Tracks Satellite metrics for each phone */
 public class SatelliteStats {
@@ -91,6 +93,8 @@
         private final int mCountOfAllowedSatelliteAccess;
         private final int mCountOfDisallowedSatelliteAccess;
         private final int mCountOfSatelliteAccessCheckFail;
+        private static boolean sIsProvisioned;
+        private static int sCarrierId = UNKNOWN_CARRIER_ID;
 
         private SatelliteControllerParams(Builder builder) {
             this.mCountOfSatelliteServiceEnablementsSuccess =
@@ -136,6 +140,16 @@
                     builder.mCountOfDisallowedSatelliteAccess;
             this.mCountOfSatelliteAccessCheckFail =
                     builder.mCountOfSatelliteAccessCheckFail;
+
+            // isProvisioned value should be updated only when it is meaningful.
+            if (builder.mIsProvisioned.isPresent()) {
+                this.sIsProvisioned = builder.mIsProvisioned.get();
+            }
+
+            // Carrier ID value should be updated only when it is meaningful.
+            if (builder.mCarrierId.isPresent()) {
+                this.sCarrierId = builder.mCarrierId.get();
+            }
         }
 
         public int getCountOfSatelliteServiceEnablementsSuccess() {
@@ -250,6 +264,14 @@
             return mCountOfSatelliteAccessCheckFail;
         }
 
+        public boolean isProvisioned() {
+            return sIsProvisioned;
+        }
+
+        public int getCarrierId() {
+            return sCarrierId;
+        }
+
         /**
          * A builder class to create {@link SatelliteControllerParams} data structure class
          */
@@ -282,6 +304,8 @@
             private int mCountOfAllowedSatelliteAccess = 0;
             private int mCountOfDisallowedSatelliteAccess = 0;
             private int mCountOfSatelliteAccessCheckFail = 0;
+            private Optional<Boolean> mIsProvisioned = Optional.empty();
+            private Optional<Integer> mCarrierId = Optional.empty();
 
             /**
              * Sets countOfSatelliteServiceEnablementsSuccess value of {@link SatelliteController}
@@ -561,6 +585,24 @@
             }
 
             /**
+             * Sets isProvisioned value of {@link SatelliteController} atom
+             * then returns Builder class
+             */
+            public Builder setIsProvisioned(boolean isProvisioned) {
+                this.mIsProvisioned = Optional.of(isProvisioned);
+                return this;
+            }
+
+            /**
+             * Sets Carrier ID value of {@link SatelliteController} atom
+             * then returns Builder class
+             */
+            public Builder setCarrierId(int carrierId) {
+                this.mCarrierId = Optional.of(carrierId);
+                return this;
+            }
+
+            /**
              * Returns ControllerParams, which contains whole component of
              * {@link SatelliteController} atom
              */
@@ -609,6 +651,8 @@
                     + ", countOfAllowedSatelliteAccess=" + mCountOfAllowedSatelliteAccess
                     + ", countOfDisallowedSatelliteAccess=" + mCountOfDisallowedSatelliteAccess
                     + ", countOfSatelliteAccessCheckFail=" + mCountOfSatelliteAccessCheckFail
+                    + ", isProvisioned=" + sIsProvisioned
+                    + ", carrierId=" + sCarrierId
                     + ")";
         }
     }
@@ -630,6 +674,11 @@
         private final int mCountOfIncomingDatagramFailed;
         private final boolean mIsDemoMode;
         private final @NtnSignalStrength.NtnSignalStrengthLevel int mMaxNtnSignalStrengthLevel;
+        private final int mCarrierId;
+        private final int mCountOfSatelliteNotificationDisplayed;
+        private final int mCountOfAutoExitDueToScreenOff;
+        private final int mCountOfAutoExitDueToTnNetwork;
+
 
         private SatelliteSessionParams(Builder builder) {
             this.mSatelliteServiceInitializationResult =
@@ -646,6 +695,11 @@
             this.mCountOfIncomingDatagramFailed = builder.mCountOfIncomingDatagramFailed;
             this.mIsDemoMode = builder.mIsDemoMode;
             this.mMaxNtnSignalStrengthLevel = builder.mMaxNtnSignalStrengthLevel;
+            this.mCarrierId = builder.mCarrierId;
+            this.mCountOfSatelliteNotificationDisplayed =
+                    builder.mCountOfSatelliteNotificationDisplayed;
+            this.mCountOfAutoExitDueToScreenOff = builder.mCountOfAutoExitDueToScreenOff;
+            this.mCountOfAutoExitDueToTnNetwork = builder.mCountOfAutoExitDueToTnNetwork;
         }
 
         public int getSatelliteServiceInitializationResult() {
@@ -696,6 +750,22 @@
             return mMaxNtnSignalStrengthLevel;
         }
 
+        public int getCarrierId() {
+            return mCarrierId;
+        }
+
+        public int getCountOfSatelliteNotificationDisplayed() {
+            return mCountOfSatelliteNotificationDisplayed;
+        }
+
+        public int getCountOfAutoExitDueToScreenOff() {
+            return mCountOfAutoExitDueToScreenOff;
+        }
+
+        public int getCountOfAutoExitDueToTnNetwork() {
+            return mCountOfAutoExitDueToTnNetwork;
+        }
+
         /**
          * A builder class to create {@link SatelliteSessionParams} data structure class
          */
@@ -713,6 +783,10 @@
             private boolean mIsDemoMode = false;
             private @NtnSignalStrength.NtnSignalStrengthLevel int mMaxNtnSignalStrengthLevel =
                     NTN_SIGNAL_STRENGTH_NONE;
+            private int mCarrierId = UNKNOWN_CARRIER_ID;
+            private int mCountOfSatelliteNotificationDisplayed = -1;
+            private int mCountOfAutoExitDueToScreenOff = -1;
+            private int mCountOfAutoExitDueToTnNetwork = -1;
 
             /**
              * Sets satelliteServiceInitializationResult value of {@link SatelliteSession}
@@ -788,13 +862,49 @@
                 return this;
             }
 
-            /** Sets the max ntn signal strength for the satellite session */
+            /** Sets the max ntn signal strength for the satellite session. */
             public Builder setMaxNtnSignalStrengthLevel(
                     @NtnSignalStrength.NtnSignalStrengthLevel int maxNtnSignalStrengthLevel) {
                 this.mMaxNtnSignalStrengthLevel = maxNtnSignalStrengthLevel;
                 return this;
             }
 
+            /** Sets the currently active NB-IoT NTN carrier ID. */
+            public Builder setCarrierId(int carrierId) {
+                this.mCarrierId = carrierId;
+                return this;
+            }
+
+            /**
+             * Sets Total number of times the user is notified that the device is eligible for
+             * satellite service for this session.
+             */
+            public Builder setCountOfSatelliteNotificationDisplayed(
+                    int countOfSatelliteNotificationDisplayed) {
+                this.mCountOfSatelliteNotificationDisplayed = countOfSatelliteNotificationDisplayed;
+                return this;
+            }
+
+            /**
+             * Sets Total number of times exit P2P message service automatically due to screen is
+             * off and timer is expired.
+             */
+            public Builder setCountOfAutoExitDueToScreenOff(
+                    int countOfAutoExitDueToScreenOff) {
+                this.mCountOfAutoExitDueToScreenOff = countOfAutoExitDueToScreenOff;
+                return this;
+            }
+
+            /**
+             * Sets Total number of times times exit P2P message service automatically due to
+             * scan TN network.
+             */
+            public Builder setCountOfAutoExitDueToTnNetwork(
+                    int countOfAutoExitDueToTnNetwork) {
+                this.mCountOfAutoExitDueToTnNetwork = countOfAutoExitDueToTnNetwork;
+                return this;
+            }
+
             /**
              * Returns SessionParams, which contains whole component of
              * {@link SatelliteSession} atom
@@ -820,6 +930,11 @@
                     + ", CountOfIncomingDatagramFailed=" + mCountOfIncomingDatagramFailed
                     + ", IsDemoMode=" + mIsDemoMode
                     + ", MaxNtnSignalStrengthLevel=" + mMaxNtnSignalStrengthLevel
+                    + ", CarrierId=" + mCarrierId
+                    + ", CountOfSatelliteNotificationDisplayed"
+                    + mCountOfSatelliteNotificationDisplayed
+                    + ", CountOfAutoExitDueToScreenOff" + mCountOfAutoExitDueToScreenOff
+                    + ", CountOfAutoExitDueToTnNetwork" + mCountOfAutoExitDueToTnNetwork
                     + ")";
         }
     }
@@ -833,12 +948,14 @@
         private final int mDatagramSizeBytes;
         private final long mDatagramTransferTimeMillis;
         private final boolean mIsDemoMode;
+        private final int mCarrierId;
 
         private SatelliteIncomingDatagramParams(Builder builder) {
             this.mResultCode = builder.mResultCode;
             this.mDatagramSizeBytes = builder.mDatagramSizeBytes;
             this.mDatagramTransferTimeMillis = builder.mDatagramTransferTimeMillis;
             this.mIsDemoMode = builder.mIsDemoMode;
+            this.mCarrierId = builder.mCarrierId;
         }
 
         public int getResultCode() {
@@ -857,6 +974,10 @@
             return mIsDemoMode;
         }
 
+        public int getCarrierId() {
+            return mCarrierId;
+        }
+
         /**
          * A builder class to create {@link SatelliteIncomingDatagramParams} data structure class
          */
@@ -865,6 +986,7 @@
             private int mDatagramSizeBytes = -1;
             private long mDatagramTransferTimeMillis = -1;
             private boolean mIsDemoMode = false;
+            private int mCarrierId = UNKNOWN_CARRIER_ID;
 
             /**
              * Sets resultCode value of {@link SatelliteIncomingDatagram} atom
@@ -902,6 +1024,12 @@
                 return this;
             }
 
+            /** Sets the currently active NB-IoT NTN carrier ID. */
+            public Builder setCarrierId(int carrierId) {
+                this.mCarrierId = carrierId;
+                return this;
+            }
+
             /**
              * Returns IncomingDatagramParams, which contains whole component of
              * {@link SatelliteIncomingDatagram} atom
@@ -919,6 +1047,7 @@
                     + ", datagramSizeBytes=" + mDatagramSizeBytes
                     + ", datagramTransferTimeMillis=" + mDatagramTransferTimeMillis
                     + ", isDemoMode=" + mIsDemoMode
+                    + ", CarrierId=" + mCarrierId
                     + ")";
         }
     }
@@ -933,6 +1062,7 @@
         private final int mDatagramSizeBytes;
         private final long mDatagramTransferTimeMillis;
         private final boolean mIsDemoMode;
+        private final int mCarrierId;
 
         private SatelliteOutgoingDatagramParams(Builder builder) {
             this.mDatagramType = builder.mDatagramType;
@@ -940,6 +1070,7 @@
             this.mDatagramSizeBytes = builder.mDatagramSizeBytes;
             this.mDatagramTransferTimeMillis = builder.mDatagramTransferTimeMillis;
             this.mIsDemoMode = builder.mIsDemoMode;
+            this.mCarrierId = builder.mCarrierId;
         }
 
         public int getDatagramType() {
@@ -962,6 +1093,10 @@
             return mIsDemoMode;
         }
 
+        public int getCarrierId() {
+            return mCarrierId;
+        }
+
         /**
          * A builder class to create {@link SatelliteOutgoingDatagramParams} data structure class
          */
@@ -971,6 +1106,7 @@
             private int mDatagramSizeBytes = -1;
             private long mDatagramTransferTimeMillis = -1;
             private boolean mIsDemoMode = false;
+            private int mCarrierId = UNKNOWN_CARRIER_ID;
 
             /**
              * Sets datagramType value of {@link SatelliteOutgoingDatagram} atom
@@ -1017,6 +1153,12 @@
                 return this;
             }
 
+            /** Sets the currently active NB-IoT NTN carrier ID. */
+            public Builder setCarrierId(int carrierId) {
+                this.mCarrierId = carrierId;
+                return this;
+            }
+
             /**
              * Returns OutgoingDatagramParams, which contains whole component of
              * {@link SatelliteOutgoingDatagram} atom
@@ -1035,6 +1177,7 @@
                     + ", datagramSizeBytes=" + mDatagramSizeBytes
                     + ", datagramTransferTimeMillis=" + mDatagramTransferTimeMillis
                     + ", isDemoMode=" + mIsDemoMode
+                    + ", CarrierId=" + mCarrierId
                     + ")";
         }
     }
@@ -1048,12 +1191,14 @@
         private final int mProvisioningTimeSec;
         private final boolean mIsProvisionRequest;
         private final boolean mIsCanceled;
+        private final int mCarrierId;
 
         private SatelliteProvisionParams(Builder builder) {
             this.mResultCode = builder.mResultCode;
             this.mProvisioningTimeSec = builder.mProvisioningTimeSec;
             this.mIsProvisionRequest = builder.mIsProvisionRequest;
             this.mIsCanceled = builder.mIsCanceled;
+            this.mCarrierId = builder.mCarrierId;
         }
 
         public int getResultCode() {
@@ -1072,6 +1217,10 @@
             return mIsCanceled;
         }
 
+        public int getCarrierId() {
+            return mCarrierId;
+        }
+
         /**
          * A builder class to create {@link SatelliteProvisionParams} data structure class
          */
@@ -1080,6 +1229,7 @@
             private int mProvisioningTimeSec = -1;
             private boolean mIsProvisionRequest = false;
             private boolean mIsCanceled = false;
+            private int mCarrierId = UNKNOWN_CARRIER_ID;
 
             /**
              * Sets resultCode value of {@link SatelliteProvision} atom
@@ -1117,6 +1267,12 @@
                 return this;
             }
 
+            /** Sets the currently active NB-IoT NTN carrier ID. */
+            public Builder setCarrierId(int carrierId) {
+                this.mCarrierId = carrierId;
+                return this;
+            }
+
             /**
              * Returns ProvisionParams, which contains whole component of
              * {@link SatelliteProvision} atom
@@ -1133,7 +1289,9 @@
                     + "resultCode=" + mResultCode
                     + ", provisioningTimeSec=" + mProvisioningTimeSec
                     + ", isProvisionRequest=" + mIsProvisionRequest
-                    + ", isCanceled" + mIsCanceled + ")";
+                    + ", isCanceled" + mIsCanceled
+                    + ", CarrierId=" + mCarrierId
+                    + ")";
         }
     }
 
@@ -1149,6 +1307,8 @@
         private final boolean mIsMultiSim;
         private final int mRecommendingHandoverType;
         private final boolean mIsSatelliteAllowedInCurrentLocation;
+        private final boolean mIsWifiConnected;
+        private final int mCarrierId;
 
         private SatelliteSosMessageRecommenderParams(Builder builder) {
             this.mIsDisplaySosMessageSent = builder.mIsDisplaySosMessageSent;
@@ -1159,6 +1319,8 @@
             this.mRecommendingHandoverType = builder.mRecommendingHandoverType;
             this.mIsSatelliteAllowedInCurrentLocation =
                     builder.mIsSatelliteAllowedInCurrentLocation;
+            this.mIsWifiConnected = builder.mIsWifiConnected;
+            this.mCarrierId = builder.mCarrierId;
         }
 
         public boolean isDisplaySosMessageSent() {
@@ -1189,6 +1351,14 @@
             return mIsSatelliteAllowedInCurrentLocation;
         }
 
+        public boolean isWifiConnected() {
+            return mIsWifiConnected;
+        }
+
+        public int getCarrierId() {
+            return mCarrierId;
+        }
+
         /**
          * A builder class to create {@link SatelliteProvisionParams} data structure class
          */
@@ -1200,6 +1370,8 @@
             private boolean mIsMultiSim = false;
             private int mRecommendingHandoverType = -1;
             private boolean mIsSatelliteAllowedInCurrentLocation = false;
+            private boolean mIsWifiConnected = false;
+            private int mCarrierId = UNKNOWN_CARRIER_ID;
 
 
             /**
@@ -1268,6 +1440,24 @@
             }
 
             /**
+             * Sets whether Wi-Fi is connected value of {@link SatelliteSosMessageRecommender} atom
+             * then returns Builder class
+             */
+            public Builder setIsWifiConnected(boolean isWifiConnected) {
+                this.mIsWifiConnected = isWifiConnected;
+                return this;
+            }
+
+            /**
+             * Sets carrier ID value of {@link SatelliteSosMessageRecommender} atom then returns
+             * Builder class.
+             */
+            public Builder setCarrierId(int carrierId) {
+                this.mCarrierId = carrierId;
+                return this;
+            }
+
+            /**
              * Returns SosMessageRecommenderParams, which contains whole component of
              * {@link SatelliteSosMessageRecommenderParams} atom
              */
@@ -1287,7 +1477,10 @@
                     + ", isMultiSim=" + mIsMultiSim
                     + ", recommendingHandoverType=" + mRecommendingHandoverType
                     + ", isSatelliteAllowedInCurrentLocation="
-                    + mIsSatelliteAllowedInCurrentLocation + ")";
+                    + mIsSatelliteAllowedInCurrentLocation
+                    + ", isWifiConnected=" + mIsWifiConnected
+                    + ", carrierId=" + mCarrierId
+                    + ")";
         }
     }
 
@@ -1614,6 +1807,7 @@
         private final int mSatelliteSessionGapMinSec;
         private final int mSatelliteSessionGapAvgSec;
         private final int mSatelliteSessionGapMaxSec;
+        private static int sCarrierId;
 
         private CarrierRoamingSatelliteControllerStatsParams(Builder builder) {
             this.mConfigDataSource = builder.mConfigDataSource;
@@ -1626,6 +1820,11 @@
             this.mSatelliteSessionGapMinSec = builder.mSatelliteSessionGapMinSec;
             this.mSatelliteSessionGapAvgSec = builder.mSatelliteSessionGapAvgSec;
             this.mSatelliteSessionGapMaxSec = builder.mSatelliteSessionGapMaxSec;
+
+            // Carrier ID value should be updated only when it is meaningful.
+            if (builder.mCarrierId.isPresent()) {
+                this.sCarrierId = builder.mCarrierId.get();
+            }
         }
 
         public int getConfigDataSource() {
@@ -1657,6 +1856,10 @@
             return mSatelliteSessionGapMaxSec;
         }
 
+        public int getCarrierId() {
+            return sCarrierId;
+        }
+
         /**
          * A builder class to create {@link CarrierRoamingSatelliteControllerStatsParams}
          * data structure class
@@ -1669,6 +1872,7 @@
             private int mSatelliteSessionGapMinSec = 0;
             private int mSatelliteSessionGapAvgSec = 0;
             private int mSatelliteSessionGapMaxSec = 0;
+            private Optional<Integer> mCarrierId = Optional.empty();
 
             /**
              * Sets configDataSource value of {@link CarrierRoamingSatelliteControllerStats} atom
@@ -1736,6 +1940,12 @@
                 return this;
             }
 
+            /** Sets the currently active NB-IoT NTN carrier ID. */
+            public Builder setCarrierId(int carrierId) {
+                this.mCarrierId = Optional.of(carrierId);
+                return this;
+            }
+
             /**
              * Returns CarrierRoamingSatelliteControllerStatsParams, which contains whole component
              * of {@link CarrierRoamingSatelliteControllerStats} atom
@@ -1759,6 +1969,7 @@
                     + ", satelliteSessionGapMinSec=" + mSatelliteSessionGapMinSec
                     + ", satelliteSessionGapAvgSec=" + mSatelliteSessionGapAvgSec
                     + ", satelliteSessionGapMaxSec=" + mSatelliteSessionGapMaxSec
+                    + ", CarrierId=" + sCarrierId
                     + ")";
         }
     }
@@ -1990,6 +2201,7 @@
         private final @SatelliteManager.SatelliteResult int mResultCode;
         private final String[] mCountryCodes;
         private final @SatelliteConstants.ConfigDataSource int mConfigDataSource;
+        private final int mCarrierId;
 
         private SatelliteAccessControllerParams(Builder builder) {
             this.mAccessControlType = builder.mAccessControlType;
@@ -2001,6 +2213,7 @@
             this.mResultCode = builder.mResultCode;
             this.mCountryCodes = builder.mCountryCodes;
             this.mConfigDataSource = builder.mConfigDataSource;
+            this.mCarrierId = builder.mCarrierId;
         }
 
         public @SatelliteConstants.AccessControlType int getAccessControlType() {
@@ -2039,6 +2252,10 @@
             return mConfigDataSource;
         }
 
+        public int getCarrierId() {
+            return mCarrierId;
+        }
+
         /**
          * A builder class to create {@link SatelliteAccessControllerParams} data structure class
          */
@@ -2052,6 +2269,7 @@
             private @SatelliteManager.SatelliteResult int mResultCode;
             private String[] mCountryCodes;
             private @SatelliteConstants.ConfigDataSource int mConfigDataSource;
+            private int mCarrierId = UNKNOWN_CARRIER_ID;
 
             /**
              * Sets AccessControlType value of {@link #SatelliteAccessController}
@@ -2113,6 +2331,12 @@
                 return this;
             }
 
+            /** Sets the currently active NB-IoT NTN carrier ID. */
+            public Builder setCarrierId(int carrierId) {
+                this.mCarrierId = carrierId;
+                return this;
+            }
+
             /**
              * Returns AccessControllerParams, which contains whole component of
              * {@link #SatelliteAccessController} atom
@@ -2135,6 +2359,7 @@
                     + ", ResultCode=" + mResultCode
                     + ", CountryCodes=" + Arrays.toString(mCountryCodes)
                     + ", ConfigDataSource=" + mConfigDataSource
+                    + ", CarrierId=" + mCarrierId
                     + ")";
         }
     }
@@ -2175,6 +2400,11 @@
         proto.countOfDemoModeIncomingDatagramFail = param.getCountOfDemoModeIncomingDatagramFail();
         proto.countOfDatagramTypeKeepAliveSuccess = param.getCountOfDatagramTypeKeepAliveSuccess();
         proto.countOfDatagramTypeKeepAliveFail = param.getCountOfDatagramTypeKeepAliveFail();
+        proto.countOfAllowedSatelliteAccess = param.getCountOfAllowedSatelliteAccess();
+        proto.countOfDisallowedSatelliteAccess = param.getCountOfDisallowedSatelliteAccess();
+        proto.countOfSatelliteAccessCheckFail = param.getCountOfSatelliteAccessCheckFail();
+        proto.isProvisioned = param.isProvisioned();
+        proto.carrierId = param.getCarrierId();
         mAtomsStorage.addSatelliteControllerStats(proto);
     }
 
@@ -2195,6 +2425,11 @@
         proto.countOfIncomingDatagramFailed = param.getCountOfOutgoingDatagramFailed();
         proto.isDemoMode = param.getIsDemoMode();
         proto.maxNtnSignalStrengthLevel = param.getMaxNtnSignalStrengthLevel();
+        proto.carrierId = param.getCarrierId();
+        proto.countOfSatelliteNotificationDisplayed =
+                param.getCountOfSatelliteNotificationDisplayed();
+        proto.countOfAutoExitDueToScreenOff = param.getCountOfAutoExitDueToScreenOff();
+        proto.countOfAutoExitDueToTnNetwork = param.getCountOfAutoExitDueToTnNetwork();
         mAtomsStorage.addSatelliteSessionStats(proto);
     }
 
@@ -2206,6 +2441,7 @@
         proto.datagramSizeBytes = param.getDatagramSizeBytes();
         proto.datagramTransferTimeMillis = param.getDatagramTransferTimeMillis();
         proto.isDemoMode = param.getIsDemoMode();
+        proto.carrierId = param.getCarrierId();
         mAtomsStorage.addSatelliteIncomingDatagramStats(proto);
     }
 
@@ -2218,6 +2454,7 @@
         proto.datagramSizeBytes = param.getDatagramSizeBytes();
         proto.datagramTransferTimeMillis = param.getDatagramTransferTimeMillis();
         proto.isDemoMode = param.getIsDemoMode();
+        proto.carrierId = param.getCarrierId();
         mAtomsStorage.addSatelliteOutgoingDatagramStats(proto);
     }
 
@@ -2228,6 +2465,7 @@
         proto.provisioningTimeSec = param.getProvisioningTimeSec();
         proto.isProvisionRequest = param.getIsProvisionRequest();
         proto.isCanceled = param.getIsCanceled();
+        proto.carrierId = param.getCarrierId();
         mAtomsStorage.addSatelliteProvisionStats(proto);
     }
 
@@ -2242,6 +2480,8 @@
         proto.isMultiSim = param.isMultiSim();
         proto.recommendingHandoverType = param.getRecommendingHandoverType();
         proto.isSatelliteAllowedInCurrentLocation = param.isSatelliteAllowedInCurrentLocation();
+        proto.isWifiConnected = param.isWifiConnected();
+        proto.carrierId = param.getCarrierId();
         proto.count = 1;
         mAtomsStorage.addSatelliteSosMessageRecommenderStats(proto);
     }
@@ -2280,6 +2520,7 @@
         proto.satelliteSessionGapMinSec = param.mSatelliteSessionGapMinSec;
         proto.satelliteSessionGapAvgSec = param.mSatelliteSessionGapAvgSec;
         proto.satelliteSessionGapMaxSec = param.mSatelliteSessionGapMaxSec;
+        proto.carrierId = param.getCarrierId();
         mAtomsStorage.addCarrierRoamingSatelliteControllerStats(proto);
     }
 
@@ -2317,6 +2558,7 @@
         proto.resultCode = param.getResultCode();
         proto.countryCodes = param.getCountryCodes();
         proto.configDataSource = param.getConfigDataSource();
+        proto.carrierId = param.getCarrierId();
         mAtomsStorage.addSatelliteAccessControllerStats(proto);
     }
 }
diff --git a/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java b/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java
index 40183c1..682123f 100644
--- a/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java
+++ b/src/java/com/android/internal/telephony/satellite/DatagramDispatcher.java
@@ -729,6 +729,7 @@
                         .setDatagramTransferTimeMillis(argument.datagramStartTime > 0
                                 ? (System.currentTimeMillis() - argument.datagramStartTime) : 0)
                         .setIsDemoMode(mIsDemoMode)
+                        .setCarrierId(SatelliteController.getInstance().getSatelliteCarrierId())
                         .build());
         if (resultCode == SatelliteManager.SATELLITE_RESULT_SUCCESS) {
             mControllerMetricsStats.reportOutgoingDatagramSuccessCount(argument.datagramType,
diff --git a/src/java/com/android/internal/telephony/satellite/DatagramReceiver.java b/src/java/com/android/internal/telephony/satellite/DatagramReceiver.java
index 7a92286..9cff658 100644
--- a/src/java/com/android/internal/telephony/satellite/DatagramReceiver.java
+++ b/src/java/com/android/internal/telephony/satellite/DatagramReceiver.java
@@ -747,6 +747,7 @@
                         .setDatagramSizeBytes(datagramSizeRoundedBytes)
                         .setDatagramTransferTimeMillis(datagramTransferTime)
                         .setIsDemoMode(mIsDemoMode)
+                        .setCarrierId(SatelliteController.getInstance().getSatelliteCarrierId())
                         .build());
 
         mControllerMetricsStats.reportIncomingDatagramCount(resultCode, mIsDemoMode);
diff --git a/src/java/com/android/internal/telephony/satellite/DemoSimulator.java b/src/java/com/android/internal/telephony/satellite/DemoSimulator.java
index 3c31ae8..7b64c61 100644
--- a/src/java/com/android/internal/telephony/satellite/DemoSimulator.java
+++ b/src/java/com/android/internal/telephony/satellite/DemoSimulator.java
@@ -131,7 +131,7 @@
                 NtnSignalStrength ntnSignalStrength = new NtnSignalStrength();
                 ntnSignalStrength.signalStrengthLevel = 0;
                 mISatelliteListener.onSatelliteModemStateChanged(
-                        SatelliteModemState.SATELLITE_MODEM_STATE_NOT_CONNECTED);
+                        SatelliteModemState.SATELLITE_MODEM_STATE_OUT_OF_SERVICE);
                 mISatelliteListener.onNtnSignalStrengthChanged(ntnSignalStrength);
 
                 synchronized (mLock) {
@@ -191,7 +191,7 @@
                 NtnSignalStrength ntnSignalStrength = new NtnSignalStrength();
                 ntnSignalStrength.signalStrengthLevel = 2;
                 mISatelliteListener.onSatelliteModemStateChanged(
-                        SatelliteModemState.SATELLITE_MODEM_STATE_CONNECTED);
+                        SatelliteModemState.SATELLITE_MODEM_STATE_IN_SERVICE);
                 mISatelliteListener.onNtnSignalStrengthChanged(ntnSignalStrength);
 
                 synchronized (mLock) {
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteController.java b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
index 2272f69..0177b3f 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteController.java
@@ -29,16 +29,17 @@
 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_ENTITLEMENT_SUPPORTED_BOOL;
-import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ESOS_INACTIVITY_TIMEOUT_SEC_INT;
 import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ESOS_SUPPORTED_BOOL;
 import static android.telephony.CarrierConfigManager.KEY_SATELLITE_NIDD_APN_NAME_STRING;
-import static android.telephony.CarrierConfigManager.KEY_SATELLITE_P2P_SMS_INACTIVITY_TIMEOUT_SEC_INT;
+import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ROAMING_ESOS_INACTIVITY_TIMEOUT_SEC_INT;
+import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ROAMING_P2P_SMS_INACTIVITY_TIMEOUT_SEC_INT;
 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_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT;
 import static android.telephony.SubscriptionManager.SATELLITE_ATTACH_ENABLED_FOR_CARRIER;
 import static android.telephony.SubscriptionManager.SATELLITE_ENTITLEMENT_STATUS;
 import static android.telephony.SubscriptionManager.isValidSubscriptionId;
+import static android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID;
 import static android.telephony.satellite.NtnSignalStrength.NTN_SIGNAL_STRENGTH_NONE;
 import static android.telephony.satellite.SatelliteManager.EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS;
 import static android.telephony.satellite.SatelliteManager.EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911;
@@ -46,7 +47,9 @@
 import static android.telephony.satellite.SatelliteManager.SATELLITE_COMMUNICATION_RESTRICTION_REASON_ENTITLEMENT;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_COMMUNICATION_RESTRICTION_REASON_USER;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_INVALID_ARGUMENTS;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_MODEM_ERROR;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_MODEM_TIMEOUT;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_REQUEST_ABORTED;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;
 
@@ -238,7 +241,7 @@
     private static final int EVENT_UPDATE_NTN_SIGNAL_STRENGTH_REPORTING_DONE = 36;
     private static final int EVENT_SERVICE_STATE_CHANGED = 37;
     private static final int EVENT_SATELLITE_CAPABILITIES_CHANGED = 38;
-    private static final int EVENT_WAIT_FOR_SATELLITE_ENABLING_RESPONSE_TIMED_OUT = 39;
+    protected static final int EVENT_WAIT_FOR_SATELLITE_ENABLING_RESPONSE_TIMED_OUT = 39;
     private static final int EVENT_SATELLITE_CONFIG_DATA_UPDATED = 40;
     private static final int EVENT_SATELLITE_SUPPORTED_STATE_CHANGED = 41;
     private static final int EVENT_NOTIFY_NTN_HYSTERESIS_TIMED_OUT = 42;
@@ -249,6 +252,10 @@
     private static final int EVENT_WIFI_CONNECTIVITY_STATE_CHANGED = 47;
     private static final int EVENT_SATELLITE_ACCESS_RESTRICTION_CHECKING_RESULT = 48;
     protected static final int EVENT_WAIT_FOR_CELLULAR_MODEM_OFF_TIMED_OUT = 49;
+    private static final int CMD_UPDATE_SATELLITE_ENABLE_ATTRIBUTES = 50;
+    private static final int EVENT_UPDATE_SATELLITE_ENABLE_ATTRIBUTES_DONE = 51;
+    protected static final int
+            EVENT_WAIT_FOR_UPDATE_SATELLITE_ENABLE_ATTRIBUTES_RESPONSE_TIMED_OUT = 52;
 
     @NonNull private static SatelliteController sInstance;
     @NonNull private final Context mContext;
@@ -292,15 +299,28 @@
     private boolean mDisableWifiOnSatelliteEnabled = false;
 
     private final Object mSatelliteEnabledRequestLock = new Object();
+    /* This variable is used to store the first enable request that framework has received in the
+     * current session.
+     */
     @GuardedBy("mSatelliteEnabledRequestLock")
     private RequestSatelliteEnabledArgument mSatelliteEnabledRequest = null;
+    /* This variable is used to store a disable request that framework has received.
+     */
+    @GuardedBy("mSatelliteEnabledRequestLock")
+    private RequestSatelliteEnabledArgument mSatelliteDisabledRequest = null;
+    /* This variable is used to store an enable request that updates the enable attributes of an
+     * existing satellite session.
+     */
+    @GuardedBy("mSatelliteEnabledRequestLock")
+    private RequestSatelliteEnabledArgument mSatelliteEnableAttributesUpdateRequest = null;
     /** Flag to indicate that satellite is enabled successfully
      * and waiting for all the radios to be disabled so that success can be sent to callback
      */
     @GuardedBy("mSatelliteEnabledRequestLock")
     private boolean mWaitingForRadioDisabled = false;
-
+    @GuardedBy("mSatelliteEnabledRequestLock")
     private boolean mWaitingForDisableSatelliteModemResponse = false;
+    @GuardedBy("mSatelliteEnabledRequestLock")
     private boolean mWaitingForSatelliteModemOff = false;
 
     private final AtomicBoolean mRegisteredForPendingDatagramCountWithSatelliteService =
@@ -1125,7 +1145,11 @@
                             + argument.enableSatellite + " was already processed");
                     return;
                 }
-                stopWaitForSatelliteEnablingResponseTimer(argument);
+                if (shouldStopWaitForEnableResponseTimer(argument)) {
+                    stopWaitForSatelliteEnablingResponseTimer(argument);
+                } else {
+                    plogd("Still waiting for the OFF state from modem");
+                }
 
                 if (error == SATELLITE_RESULT_SUCCESS) {
                     if (argument.enableSatellite) {
@@ -1133,57 +1157,38 @@
                             mWaitingForRadioDisabled = true;
                             setDemoModeEnabled(argument.enableDemoMode);
                         }
+                        // TODO (b/361139260): Start a timer to wait for other radios off
                         setSettingsKeyForSatelliteMode(SATELLITE_MODE_ENABLED_TRUE);
                         setSettingsKeyToAllowDeviceRotation(SATELLITE_MODE_ENABLED_TRUE);
                         evaluateToSendSatelliteEnabledSuccess();
                     } else {
-                        /**
-                         * Unregister Importance Listener for Pointing UI
-                         * when Satellite is disabled
-                         */
+                        // Unregister importance listener for PointingUI when satellite is disabled
                         if (mNeedsSatellitePointing) {
                             mPointingAppController.removeListenerForPointingUI();
                         }
                         synchronized (mSatelliteEnabledRequestLock) {
-                            if (mSatelliteEnabledRequest != null &&
-                                    mSatelliteEnabledRequest.enableSatellite == true &&
-                                    argument.enableSatellite == false && mWaitingForRadioDisabled) {
-                                // Previous mSatelliteEnabledRequest is successful but waiting for
-                                // all radios to be turned off.
-                                mSatelliteEnabledRequest.callback.accept(
-                                        SATELLITE_RESULT_SUCCESS);
-                            }
-                        }
-
-                        synchronized (mIsSatelliteEnabledLock) {
                             if (!mWaitingForSatelliteModemOff) {
                                 moveSatelliteToOffStateAndCleanUpResources(
-                                        SATELLITE_RESULT_SUCCESS,
-                                        argument.callback);
-                            } else {
-                                plogd("Wait for satellite modem off before updating satellite"
-                                        + " modem state");
+                                        SATELLITE_RESULT_SUCCESS);
                             }
                             mWaitingForDisableSatelliteModemResponse = false;
                         }
                     }
-                    // Request Ntn signal strength report when satellite enabled or disabled done.
+                    // Request NTN signal strength report when satellite enabled or disabled done.
                     mLatestRequestedStateForNtnSignalStrengthReport.set(argument.enableSatellite);
                     updateNtnSignalStrengthReporting(argument.enableSatellite);
                 } else {
-                    synchronized (mSatelliteEnabledRequestLock) {
-                        if (mSatelliteEnabledRequest != null &&
-                                mSatelliteEnabledRequest.enableSatellite == true &&
-                                argument.enableSatellite == false && mWaitingForRadioDisabled) {
-                            // Previous mSatelliteEnabledRequest is successful but waiting for
-                            // all radios to be turned off.
-                            mSatelliteEnabledRequest.callback.accept(
-                                    SATELLITE_RESULT_SUCCESS);
-                        }
+                    if (argument.enableSatellite) {
+                        /* Framework need to abort the enable attributes update request if any since
+                         * modem failed to enable satellite.
+                         */
+                        abortSatelliteEnableAttributesUpdateRequest(
+                                SATELLITE_RESULT_REQUEST_ABORTED);
+                        resetSatelliteEnabledRequest();
+                    } else {
+                        resetSatelliteDisabledRequest();
                     }
-                    notifyEnablementFailedToSatelliteSessionController();
-                    resetSatelliteEnabledRequest();
-
+                    notifyEnablementFailedToSatelliteSessionController(argument.enableSatellite);
                     // If Satellite enable/disable request returned Error, no need to wait for radio
                     argument.callback.accept(error);
                 }
@@ -1193,7 +1198,8 @@
                             .setSatelliteTechnology(getSupportedNtnRadioTechnology())
                             .setInitializationProcessingTime(
                                     System.currentTimeMillis() - mSessionProcessingTimeStamp)
-                            .setIsDemoMode(mIsDemoModeEnabled);
+                            .setIsDemoMode(mIsDemoModeEnabled)
+                            .setCarrierId(getSatelliteCarrierId());
                     mSessionProcessingTimeStamp = 0;
 
                     if (error == SATELLITE_RESULT_SUCCESS) {
@@ -1212,12 +1218,9 @@
                             .reportSessionMetrics();
                     mSessionStartTimeStamp = 0;
                     mSessionProcessingTimeStamp = 0;
-
                     mControllerMetricsStats.onSatelliteDisabled();
-
                     handlePersistentLoggingOnSessionEnd(mIsEmergency);
-
-                    synchronized (mIsSatelliteEnabledLock) {
+                    synchronized (mSatelliteEnabledRequestLock) {
                         mWaitingForDisableSatelliteModemResponse = false;
                     }
                 }
@@ -1229,6 +1232,74 @@
                         (RequestSatelliteEnabledArgument) msg.obj);
                 break;
 
+            case CMD_UPDATE_SATELLITE_ENABLE_ATTRIBUTES: {
+                request = (SatelliteControllerHandlerRequest) msg.obj;
+                RequestSatelliteEnabledArgument argument =
+                        (RequestSatelliteEnabledArgument) request.argument;
+
+                synchronized (mSatelliteEnabledRequestLock) {
+                    if (mSatelliteEnabledRequest != null) {
+                        plogd("UpdateEnableAttributes: Satellite is being enabled. Need to "
+                                + "wait until enable complete before updating attributes");
+                        return;
+                    }
+                    if (isSatelliteBeingDisabled()) {
+                        plogd("UpdateEnableAttributes: Satellite is being disabled. Aborting the "
+                                + "enable attributes update request");
+                        mSatelliteEnableAttributesUpdateRequest = null;
+                        argument.callback.accept(SATELLITE_RESULT_REQUEST_ABORTED);
+                        return;
+                    }
+                }
+                onCompleted = obtainMessage(EVENT_UPDATE_SATELLITE_ENABLE_ATTRIBUTES_DONE, request);
+                mSatelliteModemInterface.requestSatelliteEnabled(
+                        createModemEnableRequest(argument), onCompleted);
+                startWaitForUpdateSatelliteEnableAttributesResponseTimer(argument);
+                break;
+            }
+
+            case EVENT_UPDATE_SATELLITE_ENABLE_ATTRIBUTES_DONE: {
+                ar = (AsyncResult) msg.obj;
+                request = (SatelliteControllerHandlerRequest) ar.userObj;
+                RequestSatelliteEnabledArgument argument =
+                        (RequestSatelliteEnabledArgument) request.argument;
+                int error =  SatelliteServiceUtils.getSatelliteError(
+                        ar, "updateSatelliteEnableAttributes");
+                plogd("EVENT_UPDATE_SATELLITE_ENABLE_ATTRIBUTES_DONE = " + error);
+
+                /*
+                 * The timer to wait for EVENT_UPDATE_SATELLITE_ENABLE_ATTRIBUTES_DONE might have
+                 * expired and thus the request resources might have been cleaned up.
+                 */
+                if (!shouldProcessEventUpdateSatelliteEnableAttributesDone(argument)) {
+                    plogw("The update request ID=" + argument.requestId + " was already processed");
+                    return;
+                }
+                stopWaitForUpdateSatelliteEnableAttributesResponseTimer(argument);
+
+                if (error == SATELLITE_RESULT_SUCCESS) {
+                    setDemoModeEnabled(argument.enableDemoMode);
+                    setEmergencyMode(argument.isEmergency);
+                }
+                synchronized (mSatelliteEnabledRequestLock) {
+                    mSatelliteEnableAttributesUpdateRequest = null;
+                }
+                argument.callback.accept(error);
+                break;
+            }
+
+            case EVENT_WAIT_FOR_UPDATE_SATELLITE_ENABLE_ATTRIBUTES_RESPONSE_TIMED_OUT: {
+                RequestSatelliteEnabledArgument argument =
+                        (RequestSatelliteEnabledArgument) msg.obj;
+                plogw("Timed out to wait for the response from the modem for the request to "
+                        + "update satellite enable attributes, request ID = " + argument.requestId);
+                synchronized (mSatelliteEnabledRequestLock) {
+                    mSatelliteEnableAttributesUpdateRequest = null;
+                }
+                argument.callback.accept(SATELLITE_RESULT_MODEM_TIMEOUT);
+                break;
+            }
+
             case CMD_IS_SATELLITE_ENABLED: {
                 request = (SatelliteControllerHandlerRequest) msg.obj;
                 onCompleted = obtainMessage(EVENT_IS_SATELLITE_ENABLED_DONE, request);
@@ -1253,7 +1324,7 @@
                         updateSatelliteEnabledState(enabled, "EVENT_IS_SATELLITE_ENABLED_DONE");
                     }
                 } else if (error == SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED) {
-                    updateSatelliteSupportedStateWhenSatelliteServiceConnected(false);
+                    updateSatelliteSupportedState(false);
                 }
                 ((ResultReceiver) request.argument).send(error, bundle);
                 break;
@@ -1279,7 +1350,7 @@
                         boolean supported = (boolean) ar.result;
                         plogd("isSatelliteSupported: " + supported);
                         bundle.putBoolean(SatelliteManager.KEY_SATELLITE_SUPPORTED, supported);
-                        updateSatelliteSupportedStateWhenSatelliteServiceConnected(supported);
+                        updateSatelliteSupportedState(supported);
                     }
                 }
                 ((ResultReceiver) request.argument).send(error, bundle);
@@ -1781,26 +1852,6 @@
             enableDemoMode = false;
         }
 
-        synchronized (mIsSatelliteEnabledLock) {
-            if (mIsSatelliteEnabled != null) {
-                if (mIsSatelliteEnabled == enableSatellite) {
-                    if (enableDemoMode != mIsDemoModeEnabled) {
-                        ploge("Received invalid demo mode while satellite session is enabled"
-                                + " enableDemoMode = " + enableDemoMode);
-                        sendErrorAndReportSessionMetrics(
-                                SATELLITE_RESULT_INVALID_ARGUMENTS, result);
-                        return;
-                    } else {
-                        plogd("Enable request matches with current state"
-                                + " enableSatellite = " + enableSatellite);
-                        sendErrorAndReportSessionMetrics(
-                                SatelliteManager.SATELLITE_RESULT_SUCCESS, result);
-                        return;
-                    }
-                }
-            }
-        }
-
         RequestSatelliteEnabledArgument request =
                 new RequestSatelliteEnabledArgument(enableSatellite, enableDemoMode, isEmergency,
                         result);
@@ -1815,25 +1866,132 @@
          *      4. ongoing request = enable, current request = disable: send request to modem
          */
         synchronized (mSatelliteEnabledRequestLock) {
-            if (mSatelliteEnabledRequest == null) {
-                mSatelliteEnabledRequest = request;
-            } else if (mSatelliteEnabledRequest.enableSatellite == request.enableSatellite) {
-                plogd("requestSatelliteEnabled enableSatellite: " + enableSatellite
-                        + " is already in progress.");
-                sendErrorAndReportSessionMetrics(
-                        SatelliteManager.SATELLITE_RESULT_REQUEST_IN_PROGRESS, result);
+            if (!isSatelliteEnabledRequestInProgress()) {
+                synchronized (mIsSatelliteEnabledLock) {
+                    if (mIsSatelliteEnabled != null && mIsSatelliteEnabled == enableSatellite) {
+                        evaluateToUpdateSatelliteEnabledAttributes(result,
+                                SatelliteManager.SATELLITE_RESULT_SUCCESS, request,
+                                mIsDemoModeEnabled, mIsEmergency);
+                        return;
+                    }
+                }
+                if (enableSatellite) {
+                    mSatelliteEnabledRequest = request;
+                } else {
+                    mSatelliteDisabledRequest = request;
+                }
+            } else if (isSatelliteBeingDisabled()) {
+                int resultCode = SatelliteManager.SATELLITE_RESULT_REQUEST_IN_PROGRESS;
+                if (enableSatellite) {
+                    plogw("requestSatelliteEnabled: The enable request cannot be "
+                            + "processed since disable satellite is in progress.");
+                    resultCode = SatelliteManager.SATELLITE_RESULT_DISABLE_IN_PROGRESS;
+                } else {
+                    plogd("requestSatelliteEnabled: Disable is already in progress.");
+                }
+                sendErrorAndReportSessionMetrics(resultCode, result);
                 return;
-            } else if (mSatelliteEnabledRequest.enableSatellite == false
-                    && request.enableSatellite == true) {
-                plogd("requestSatelliteEnabled enableSatellite: " + enableSatellite + " cannot be "
-                        + "processed. Disable satellite is already in progress.");
-                sendErrorAndReportSessionMetrics(
-                        SatelliteManager.SATELLITE_RESULT_ERROR, result);
+            } else {
+                // Satellite is being enabled or satellite enable attributes are being updated
+                if (enableSatellite) {
+                    if (mSatelliteEnableAttributesUpdateRequest == null) {
+                        /* Satellite is being enabled and framework receive a new enable request to
+                         * update the enable attributes.
+                         */
+                        evaluateToUpdateSatelliteEnabledAttributes(result,
+                                SatelliteManager.SATELLITE_RESULT_REQUEST_IN_PROGRESS,
+                                request, mSatelliteEnabledRequest.enableDemoMode,
+                                mSatelliteEnabledRequest.isEmergency);
+                    } else {
+                        /* The enable attributes update request is already being processed.
+                         * Framework can't handle one more request to update enable attributes.
+                         */
+                        plogd("requestSatelliteEnabled: enable attributes update request is already"
+                                + " in progress.");
+                        sendErrorAndReportSessionMetrics(
+                                SatelliteManager.SATELLITE_RESULT_REQUEST_IN_PROGRESS, result);
+                    }
+                    return;
+                } else {
+                    /* Users might want to end the satellite session while it is being enabled, or
+                     * the satellite session need to be disabled for an emergency call. Note: some
+                     * carriers want to disable satellite for prioritizing emergency calls. Thus,
+                     * we need to push the disable request to modem while enable is in progress.
+                     */
+                    mSatelliteDisabledRequest = request;
+                }
+            }
+        }
+        sendRequestAsync(CMD_SET_SATELLITE_ENABLED, request, null);
+    }
+
+    /**
+     * Validate the newly-received enable attributes against the current ones. If the new attributes
+     * are valid and different from the current ones, framework will send a request to update the
+     * enable attributes to modem. Otherwise, framework will return
+     * {@code SATELLITE_RESULT_INVALID_ARGUMENTS} to the requesting clients.
+     *
+     * @param result The callback that returns the result to the requesting client.
+     * @param resultCode The result code to send back to the requesting client when framework does
+     *                   not need to reconfigure modem.
+     * @param enableRequest The new enable request to update satellite enable attributes.
+     * @param currentDemoMode The current demo mode at framework.
+     * @param currentEmergencyMode The current emergency mode at framework.
+     */
+    private void evaluateToUpdateSatelliteEnabledAttributes(@NonNull Consumer<Integer> result,
+            @SatelliteManager.SatelliteResult int resultCode,
+            @NonNull RequestSatelliteEnabledArgument enableRequest, boolean currentDemoMode,
+            boolean currentEmergencyMode) {
+        boolean needToReconfigureModem = false;
+        if (enableRequest.enableDemoMode != currentDemoMode) {
+            if (enableRequest.enableDemoMode) {
+                ploge("Moving from real mode to demo mode is rejected");
+                sendErrorAndReportSessionMetrics(SATELLITE_RESULT_INVALID_ARGUMENTS, result);
                 return;
+            } else {
+                plogd("Moving from demo mode to real mode. Need to reconfigure"
+                        + " modem with real mode");
+                needToReconfigureModem = true;
+            }
+        } else if (enableRequest.isEmergency != currentEmergencyMode) {
+            if (enableRequest.isEmergency) {
+                plogd("Moving from non-emergency to emergency mode. Need to "
+                        + "reconfigure modem");
+                needToReconfigureModem = true;
+            } else {
+                plogd("Non-emergency requests can be served during an emergency"
+                        + " satellite session. No need to reconfigure modem.");
             }
         }
 
-        sendRequestAsync(CMD_SET_SATELLITE_ENABLED, request, null);
+        if (needToReconfigureModem) {
+            synchronized (mSatelliteEnabledRequestLock) {
+                mSatelliteEnableAttributesUpdateRequest = enableRequest;
+            }
+            sendRequestAsync(
+                    CMD_UPDATE_SATELLITE_ENABLE_ATTRIBUTES, enableRequest, null);
+        } else {
+            if (resultCode != SatelliteManager.SATELLITE_RESULT_SUCCESS) {
+                plogd("requestSatelliteEnabled enable satellite is already in progress.");
+            }
+            sendErrorAndReportSessionMetrics(resultCode, result);
+        }
+        return;
+    }
+
+    /**
+     * @return {@code true} when either enable request, disable request, or enable attributes update
+     * request is in progress, {@code false} otherwise.
+     */
+    private boolean isSatelliteEnabledRequestInProgress() {
+        synchronized (mSatelliteEnabledRequestLock) {
+            plogd("mSatelliteEnabledRequest: " + (mSatelliteEnabledRequest != null)
+                    + ", mSatelliteDisabledRequest: " + (mSatelliteDisabledRequest != null)
+                    + ", mSatelliteEnableAttributesUpdateRequest: "
+                    + (mSatelliteEnableAttributesUpdateRequest != null));
+            return (mSatelliteEnabledRequest != null || mSatelliteDisabledRequest != null
+                    || mSatelliteEnableAttributesUpdateRequest != null);
+        }
     }
 
     /**
@@ -1895,6 +2053,18 @@
     }
 
     /**
+     * Get whether satellite modem is being disabled.
+     *
+     * @return {@code true} if the satellite modem is being disabled and {@code false} otherwise.
+     */
+    public boolean isSatelliteBeingDisabled() {
+        if (mSatelliteSessionController != null) {
+            return mSatelliteSessionController.isInDisablingState();
+        }
+        return false;
+    }
+
+    /**
      * Request to get whether the satellite service demo mode is enabled.
      *
      * @param result The result receiver that returns whether the satellite demo mode is enabled
@@ -2146,7 +2316,7 @@
         try {
             callback.onSatelliteProvisionStateChanged(isProvisioned);
         } catch (RemoteException ex) {
-            loge("setSatelliteServicePackageName: " + ex);
+            loge("registerForSatelliteProvisionStateChanged: " + ex);
         }
         synchronized (mSatelliteViaOemProvisionLock) {
             plogd("registerForSatelliteProvisionStateChanged: report current provisioned "
@@ -2907,20 +3077,20 @@
             plogd("onSatelliteServiceConnected: oemEnabledSatelliteFlag is disabled");
             return;
         }
+
         if (mSatelliteModemInterface.isSatelliteServiceSupported()) {
-            synchronized (mIsSatelliteSupportedLock) {
-                if (mIsSatelliteSupported == null) {
-                    ResultReceiver receiver = new ResultReceiver(this) {
-                        @Override
-                        protected void onReceiveResult(
-                                int resultCode, Bundle resultData) {
-                            plogd("onSatelliteServiceConnected.requestIsSatelliteSupported:"
-                                    + " resultCode=" + resultCode);
-                        }
-                    };
-                    requestIsSatelliteSupported(receiver);
+            plogd("onSatelliteServiceConnected");
+            // Vendor service might have just come back from a crash
+            moveSatelliteToOffStateAndCleanUpResources(SATELLITE_RESULT_MODEM_ERROR);
+            ResultReceiver receiver = new ResultReceiver(this) {
+                @Override
+                protected void onReceiveResult(
+                        int resultCode, Bundle resultData) {
+                    plogd("onSatelliteServiceConnected.requestIsSatelliteSupported:"
+                            + " resultCode=" + resultCode);
                 }
-            }
+            };
+            requestIsSatelliteSupported(receiver);
         } else {
             plogd("onSatelliteServiceConnected: Satellite vendor service is not supported."
                     + " Ignored the event");
@@ -3126,7 +3296,7 @@
      * @return {@code Pair<true, subscription ID>} if any subscription on the device is connected to
      * satellite, {@code Pair<false, null>} otherwise.
      */
-    private Pair<Boolean, Integer> isUsingNonTerrestrialNetworkViaCarrier() {
+    Pair<Boolean, Integer> isUsingNonTerrestrialNetworkViaCarrier() {
         if (!mFeatureFlags.carrierEnabledSatelliteFlag()) {
             logd("isUsingNonTerrestrialNetwork: carrierEnabledSatelliteFlag is disabled");
             return new Pair<>(false, null);
@@ -3241,11 +3411,7 @@
      *                      {@code false} otherwise.
      */
     public boolean getRequestIsEmergency() {
-        if (mFeatureFlags.carrierRoamingNbIotNtn()) {
-            return mIsEmergency;
-        }
-
-        return false;
+        return mIsEmergency;
     }
 
     /**
@@ -3496,6 +3662,7 @@
             mProvisionMetricsStats
                     .setResultCode(SatelliteManager.SATELLITE_RESULT_INVALID_TELEPHONY_STATE)
                     .setIsProvisionRequest(true)
+                    .setCarrierId(getSatelliteCarrierId())
                     .reportProvisionMetrics();
             mControllerMetricsStats.reportProvisionCount(
                     SatelliteManager.SATELLITE_RESULT_INVALID_TELEPHONY_STATE);
@@ -3514,6 +3681,7 @@
         }
         mProvisionMetricsStats.setResultCode(result)
                 .setIsProvisionRequest(true)
+                .setCarrierId(getSatelliteCarrierId())
                 .reportProvisionMetrics();
         mControllerMetricsStats.reportProvisionCount(result);
     }
@@ -3543,6 +3711,7 @@
         }
         mProvisionMetricsStats.setResultCode(result)
                 .setIsProvisionRequest(false)
+                .setCarrierId(getSatelliteCarrierId())
                 .reportProvisionMetrics();
         mControllerMetricsStats.reportDeprovisionCount(result);
     }
@@ -3592,14 +3761,9 @@
                 return mOverriddenIsSatelliteViaOemProvisioned;
             }
 
-            if (mIsSatelliteViaOemProvisioned != null) {
-                return mIsSatelliteViaOemProvisioned;
-            }
-
             if (mIsSatelliteViaOemProvisioned == null) {
                 mIsSatelliteViaOemProvisioned = getPersistedOemEnabledSatelliteProvisionStatus();
             }
-
             return mIsSatelliteViaOemProvisioned;
         }
     }
@@ -3614,10 +3778,14 @@
             ploge("handleSatelliteEnabled: mSatelliteSessionController is not initialized yet");
         }
 
+        /* Framework will send back the disable result to the requesting client only after receiving
+         * both confirmation for the disable request from modem, and OFF state from modem if the
+         * modem is not in OFF state.
+         */
         if (!argument.enableSatellite && mSatelliteModemInterface.isSatelliteServiceSupported()) {
-            synchronized (mIsSatelliteEnabledLock) {
+            synchronized (mSatelliteEnabledRequestLock) {
                 mWaitingForDisableSatelliteModemResponse = true;
-                mWaitingForSatelliteModemOff = true;
+                if (!isSatelliteDisabled()) mWaitingForSatelliteModemOff = true;
             }
         }
 
@@ -3660,14 +3828,14 @@
         evaluateEnablingSatelliteForCarrier(argument.subId, argument.reason, argument.callback);
     }
 
-    private void updateSatelliteSupportedStateWhenSatelliteServiceConnected(boolean supported) {
+    private void updateSatelliteSupportedState(boolean supported) {
         synchronized (mIsSatelliteSupportedLock) {
             mIsSatelliteSupported = supported;
         }
         mSatelliteSessionController = SatelliteSessionController.make(
                 mContext, getLooper(), mFeatureFlags, supported);
-        plogd("create a new SatelliteSessionController due to isSatelliteSupported state has "
-                + "changed to " + supported);
+        plogd("updateSatelliteSupportedState: create a new SatelliteSessionController because "
+                + "satellite supported state has changed to " + supported);
 
         if (supported) {
             registerForPendingDatagramCount();
@@ -3679,14 +3847,14 @@
                     new ResultReceiver(this) {
                         @Override
                         protected void onReceiveResult(int resultCode, Bundle resultData) {
-                            plogd("requestIsSatelliteProvisioned: resultCode=" + resultCode
-                                    + ", resultData=" + resultData);
-                            requestSatelliteEnabled(//SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
-                                    false, false, false,
+                            plogd("updateSatelliteSupportedState.requestIsSatelliteProvisioned: "
+                                    + "resultCode=" + resultCode + ", resultData=" + resultData);
+                            requestSatelliteEnabled(false, false, false,
                                     new IIntegerConsumer.Stub() {
                                         @Override
                                         public void accept(int result) {
-                                            plogd("requestSatelliteEnabled: result=" + result);
+                                            plogd("updateSatelliteSupportedState."
+                                                    + "requestSatelliteEnabled: result=" + result);
                                         }
                                     });
                         }
@@ -3695,8 +3863,8 @@
                     new ResultReceiver(this) {
                         @Override
                         protected void onReceiveResult(int resultCode, Bundle resultData) {
-                            plogd("requestSatelliteCapabilities: resultCode=" + resultCode
-                                    + ", resultData=" + resultData);
+                            plogd("updateSatelliteSupportedState.requestSatelliteCapabilities: "
+                                    + "resultCode=" + resultCode + ", resultData=" + resultData);
                         }
                     });
         }
@@ -3824,6 +3992,12 @@
                 getPrioritizedSatelliteSubscriberProvisionStatusList();
         plogd("handleEventSatelliteSubscriptionProvisionStateChanged: " + informList);
         notifySatelliteSubscriptionProvisionStateChanged(informList);
+        // Report updated provisioned status
+        synchronized (mSatelliteTokenProvisionedLock) {
+            boolean isProvisioned = !mProvisionedSubscriberId.isEmpty()
+                    && mProvisionedSubscriberId.containsValue(Boolean.TRUE);
+            mControllerMetricsStats.setIsProvisioned(isProvisioned);
+        }
     }
 
     private void notifySatelliteSubscriptionProvisionStateChanged(
@@ -3847,37 +4021,45 @@
         plogd("handleEventSatelliteModemStateChanged: state=" + state);
         if (state == SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE
                 || state == SatelliteManager.SATELLITE_MODEM_STATE_OFF) {
-            synchronized (mIsSatelliteEnabledLock) {
-                if ((state == SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE)
-                        || ((mIsSatelliteEnabled == null || isSatelliteEnabled())
-                        && !mWaitingForDisableSatelliteModemResponse)) {
-                    int error = (state == SatelliteManager.SATELLITE_MODEM_STATE_OFF)
-                            ? SATELLITE_RESULT_SUCCESS
-                            : SatelliteManager.SATELLITE_RESULT_INVALID_MODEM_STATE;
-                    Consumer<Integer> callback = null;
-                    synchronized (mSatelliteEnabledRequestLock) {
-                        if (mSatelliteEnabledRequest != null) {
-                            callback = mSatelliteEnabledRequest.callback;
-                        }
-                    }
-                    moveSatelliteToOffStateAndCleanUpResources(error, callback);
+            synchronized (mSatelliteEnabledRequestLock) {
+                if (!mWaitingForDisableSatelliteModemResponse) {
+                    moveSatelliteToOffStateAndCleanUpResources(
+                            SATELLITE_RESULT_SUCCESS);
                 } else {
-                    plogd("Either waiting for the response of disabling satellite modem or the"
-                            + " event should be ignored because isSatelliteEnabled="
-                            + isSatelliteEnabled()
-                            + ", mIsSatelliteEnabled=" + mIsSatelliteEnabled);
+                    notifyModemStateChangedToSessionController(
+                            SatelliteManager.SATELLITE_MODEM_STATE_OFF);
                 }
                 mWaitingForSatelliteModemOff = false;
             }
         } else {
-            if (mSatelliteSessionController != null) {
-                mSatelliteSessionController.onSatelliteModemStateChanged(state);
+            if (isSatelliteEnabled() || isSatelliteBeingEnabled() || isSatelliteBeingDisabled()) {
+                notifyModemStateChangedToSessionController(state);
             } else {
-                ploge("handleEventSatelliteModemStateChanged: mSatelliteSessionController is null");
+                // Telephony framework and modem are out of sync. We need to disable modem
+                synchronized (mSatelliteEnabledRequestLock) {
+                    plogw("Satellite modem is in a bad state. Disabling satellite modem now ...");
+                    Consumer<Integer> result = integer -> plogd(
+                            "handleEventSatelliteModemStateChanged: disabling satellite result="
+                            + integer);
+                    mSatelliteDisabledRequest = new RequestSatelliteEnabledArgument(
+                            false /* enableSatellite */, false /* enableDemoMode */,
+                            false /* isEmergency */, result);
+                    sendRequestAsync(CMD_SET_SATELLITE_ENABLED, mSatelliteDisabledRequest, null);
+                }
             }
         }
     }
 
+    private void notifyModemStateChangedToSessionController(
+            @SatelliteManager.SatelliteModemState int state) {
+        if (mSatelliteSessionController != null) {
+            mSatelliteSessionController.onSatelliteModemStateChanged(state);
+        } else {
+            ploge("notifyModemStateChangedToSessionController: mSatelliteSessionController is "
+                    + "null");
+        }
+    }
+
     private void handleEventNtnSignalStrengthChanged(NtnSignalStrength ntnSignalStrength) {
         logd("handleEventNtnSignalStrengthChanged: ntnSignalStrength=" + ntnSignalStrength);
         if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
@@ -3941,7 +4123,7 @@
                 return;
             }
 
-            updateSatelliteSupportedStateWhenSatelliteServiceConnected(supported);
+            updateSatelliteSupportedState(supported);
 
             /* In case satellite has been reported as not support from modem, but satellite is
                enabled, request disable satellite. */
@@ -3949,15 +4131,13 @@
                 if (!supported && mIsSatelliteEnabled != null && mIsSatelliteEnabled) {
                     plogd("Invoke requestSatelliteEnabled(), supported=false, "
                             + "mIsSatelliteEnabled=true");
-                    requestSatelliteEnabled(//SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
-                            false /* enableSatellite */, false /* enableDemoMode */,
+                    requestSatelliteEnabled(false /* enableSatellite */, false /* enableDemoMode */,
                             false /* isEmergency */,
                             new IIntegerConsumer.Stub() {
                                 @Override
                                 public void accept(int result) {
                                     plogd("handleSatelliteSupportedStateChangedEvent: request "
-                                            + "satellite disable, result="
-                                            + result);
+                                            + "satellite disable, result=" + result);
                                 }
                             });
 
@@ -4111,10 +4291,6 @@
             if (areAllRadiosDisabled() && (mSatelliteEnabledRequest != null)
                     && mWaitingForRadioDisabled) {
                 plogd("Sending success to callback that sent enable satellite request");
-                mIsEmergency = mSatelliteEnabledRequest.isEmergency;
-                if (mSatelliteSessionController != null) {
-                    mSatelliteSessionController.onEmergencyModeChanged(mIsEmergency);
-                }
                 synchronized (mIsSatelliteEnabledLock) {
                     mIsSatelliteEnabled = mSatelliteEnabledRequest.enableSatellite;
                 }
@@ -4122,6 +4298,7 @@
                 updateSatelliteEnabledState(
                         mSatelliteEnabledRequest.enableSatellite,
                         "EVENT_SET_SATELLITE_ENABLED_DONE");
+                setEmergencyMode(mSatelliteEnabledRequest.isEmergency);
                 if (mSatelliteEnabledRequest.enableSatellite
                         && !mSatelliteEnabledRequest.isEmergency) {
                     plogd("Starting pointingUI needFullscreenPointingUI=" + true
@@ -4131,6 +4308,11 @@
                 }
                 mSatelliteEnabledRequest = null;
                 mWaitingForRadioDisabled = false;
+
+                if (mSatelliteEnableAttributesUpdateRequest != null) {
+                    sendRequestAsync(CMD_UPDATE_SATELLITE_ENABLE_ATTRIBUTES,
+                            mSatelliteEnableAttributesUpdateRequest, null);
+                }
             }
         }
     }
@@ -4143,21 +4325,37 @@
         }
     }
 
-    private void moveSatelliteToOffStateAndCleanUpResources(
-            @SatelliteManager.SatelliteResult int error, @Nullable Consumer<Integer> callback) {
+    private void resetSatelliteDisabledRequest() {
+        plogd("resetSatelliteDisabledRequest");
+        synchronized (mSatelliteEnabledRequestLock) {
+            mSatelliteDisabledRequest = null;
+            mWaitingForDisableSatelliteModemResponse = false;
+            mWaitingForSatelliteModemOff = false;
+        }
+    }
+
+    /**
+     * Move to OFF state and clean up resources.
+     *
+     * @param resultCode The result code will be returned to requesting clients.
+     */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+    public void moveSatelliteToOffStateAndCleanUpResources(
+            @SatelliteManager.SatelliteResult int resultCode) {
         plogd("moveSatelliteToOffStateAndCleanUpResources");
         synchronized (mIsSatelliteEnabledLock) {
-            resetSatelliteEnabledRequest();
             setDemoModeEnabled(false);
             handlePersistentLoggingOnSessionEnd(mIsEmergency);
-            mIsEmergency = false;
-            if (mSatelliteSessionController != null) {
-                mSatelliteSessionController.onEmergencyModeChanged(mIsEmergency);
-            }
+            setEmergencyMode(false);
             mIsSatelliteEnabled = false;
             setSettingsKeyForSatelliteMode(SATELLITE_MODE_ENABLED_FALSE);
             setSettingsKeyToAllowDeviceRotation(SATELLITE_MODE_ENABLED_FALSE);
-            if (callback != null) callback.accept(error);
+            abortSatelliteDisableRequest(resultCode);
+            abortSatelliteEnableRequest(resultCode);
+            abortSatelliteEnableAttributesUpdateRequest(resultCode);
+            resetSatelliteEnabledRequest();
+            resetSatelliteDisabledRequest();
+            // TODO (b/361139260): Stop timer to wait for other radios off
             updateSatelliteEnabledState(
                     false, "moveSatelliteToOffStateAndCleanUpResources");
         }
@@ -4169,6 +4367,18 @@
         plogd("setDemoModeEnabled: mIsDemoModeEnabled=" + mIsDemoModeEnabled);
     }
 
+    private void setEmergencyMode(boolean isEmergency) {
+        plogd("setEmergencyMode: mIsEmergency=" + mIsEmergency + ", isEmergency=" + isEmergency);
+        if (mIsEmergency != isEmergency) {
+            mIsEmergency = isEmergency;
+            if (mSatelliteSessionController != null) {
+                mSatelliteSessionController.onEmergencyModeChanged(mIsEmergency);
+            } else {
+                plogw("setEmergencyMode: mSatelliteSessionController is null");
+            }
+        }
+    }
+
     private boolean isMockModemAllowed() {
         return (DEBUG || SystemProperties.getBoolean(ALLOW_MOCK_MODEM_PROPERTY, false));
     }
@@ -4341,9 +4551,9 @@
                     KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT,
                     KEY_CARRIER_SUPPORTED_SATELLITE_NOTIFICATION_HYSTERESIS_SEC_INT,
                     KEY_CARRIER_ROAMING_NTN_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_INT,
-                    KEY_SATELLITE_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT,
-                    KEY_SATELLITE_P2P_SMS_INACTIVITY_TIMEOUT_SEC_INT,
-                    KEY_SATELLITE_ESOS_INACTIVITY_TIMEOUT_SEC_INT
+                    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
             );
         }
         if (config == null || config.isEmpty()) {
@@ -4783,6 +4993,7 @@
         mSessionMetricsStats.setInitializationResult(error)
                 .setSatelliteTechnology(getSupportedNtnRadioTechnology())
                 .setIsDemoMode(mIsDemoModeEnabled)
+                .setCarrierId(getSatelliteCarrierId())
                 .reportSessionMetrics();
         mSessionStartTimeStamp = 0;
         mSessionProcessingTimeStamp = 0;
@@ -5158,70 +5369,96 @@
         }
     }
 
+    private void startWaitForUpdateSatelliteEnableAttributesResponseTimer(
+            @NonNull RequestSatelliteEnabledArgument argument) {
+        synchronized (mSatelliteEnabledRequestLock) {
+            if (hasMessages(EVENT_WAIT_FOR_UPDATE_SATELLITE_ENABLE_ATTRIBUTES_RESPONSE_TIMED_OUT,
+                    argument)) {
+                plogd("WaitForUpdateSatelliteEnableAttributesResponseTimer of request ID "
+                        + argument.requestId + " was already started");
+                return;
+            }
+            plogd("Start timer to wait for response of the update satellite enable attributes"
+                    + " request ID=" + argument.requestId
+                    + ", enableSatellite=" + argument.enableSatellite
+                    + ", mWaitTimeForSatelliteEnablingResponse="
+                    + mWaitTimeForSatelliteEnablingResponse);
+            sendMessageDelayed(obtainMessage(
+                    EVENT_WAIT_FOR_UPDATE_SATELLITE_ENABLE_ATTRIBUTES_RESPONSE_TIMED_OUT,
+                    argument), mWaitTimeForSatelliteEnablingResponse);
+        }
+    }
+
+    private void stopWaitForUpdateSatelliteEnableAttributesResponseTimer(
+            @NonNull RequestSatelliteEnabledArgument argument) {
+        synchronized (mSatelliteEnabledRequestLock) {
+            plogd("Stop timer to wait for response of the enable attributes update request ID="
+                    + argument.requestId + ", enableSatellite=" + argument.enableSatellite);
+            removeMessages(
+                    EVENT_WAIT_FOR_UPDATE_SATELLITE_ENABLE_ATTRIBUTES_RESPONSE_TIMED_OUT, argument);
+        }
+    }
+
+    private boolean shouldProcessEventUpdateSatelliteEnableAttributesDone(
+            @NonNull RequestSatelliteEnabledArgument argument) {
+        synchronized (mSatelliteEnabledRequestLock) {
+            if (hasMessages(EVENT_WAIT_FOR_UPDATE_SATELLITE_ENABLE_ATTRIBUTES_RESPONSE_TIMED_OUT,
+                    argument)) {
+                return true;
+            }
+            return false;
+        }
+    }
+
     private void handleEventWaitForSatelliteEnablingResponseTimedOut(
             @NonNull RequestSatelliteEnabledArgument argument) {
         plogw("Timed out to wait for response of the satellite enabling request ID="
                 + argument.requestId + ", enableSatellite=" + argument.enableSatellite);
 
-        synchronized (mSatelliteEnabledRequestLock) {
-            if (mSatelliteEnabledRequest != null) {
-                if (mSatelliteEnabledRequest.enableSatellite && !argument.enableSatellite
-                        && mWaitingForRadioDisabled) {
-                    // Previous mSatelliteEnabledRequest is successful but waiting for
-                    // all radios to be turned off.
-                    mSatelliteEnabledRequest.callback.accept(SATELLITE_RESULT_SUCCESS);
-                    resetSatelliteEnabledRequest();
-                } else if (mSatelliteEnabledRequest.requestId == argument.requestId) {
-                    resetSatelliteEnabledRequest();
-                }
-            }
-        }
         argument.callback.accept(SATELLITE_RESULT_MODEM_TIMEOUT);
-
         synchronized (mIsSatelliteEnabledLock) {
             if (argument.enableSatellite) {
-                if (!mWaitingForDisableSatelliteModemResponse && !mWaitingForSatelliteModemOff) {
-                    resetSatelliteEnabledRequest();
-                    IIntegerConsumer callback = new IIntegerConsumer.Stub() {
-                        @Override
-                        public void accept(int result) {
-                            plogd("handleEventWaitForSatelliteEnablingResponseTimedOut: "
-                                    + "disable satellite result=" + result);
-                        }
-                    };
-                    Consumer<Integer> result =
-                            FunctionalUtils.ignoreRemoteException(callback::accept);
-                    RequestSatelliteEnabledArgument request = new RequestSatelliteEnabledArgument(
-                            false, false, false, result);
-                    synchronized (mSatelliteEnabledRequestLock) {
-                        mSatelliteEnabledRequest = request;
+                resetSatelliteEnabledRequest();
+                abortSatelliteEnableAttributesUpdateRequest(SATELLITE_RESULT_REQUEST_ABORTED);
+                synchronized (mSatelliteEnabledRequestLock) {
+                    if (mSatelliteDisabledRequest == null) {
+                        IIntegerConsumer callback = new IIntegerConsumer.Stub() {
+                            @Override
+                            public void accept(int result) {
+                                plogd("handleEventWaitForSatelliteEnablingResponseTimedOut: "
+                                        + "disable satellite result=" + result);
+                            }
+                        };
+                        Consumer<Integer> result =
+                                FunctionalUtils.ignoreRemoteException(callback::accept);
+                        mSatelliteDisabledRequest = new RequestSatelliteEnabledArgument(
+                                false, false, false, result);
+                        sendRequestAsync(CMD_SET_SATELLITE_ENABLED, mSatelliteDisabledRequest,
+                                null);
                     }
-                    sendRequestAsync(CMD_SET_SATELLITE_ENABLED, request, null);
                 }
-                notifyEnablementFailedToSatelliteSessionController();
+
                 mControllerMetricsStats.reportServiceEnablementFailCount();
                 mSessionMetricsStats.setInitializationResult(SATELLITE_RESULT_MODEM_TIMEOUT)
                         .setSatelliteTechnology(getSupportedNtnRadioTechnology())
                         .setInitializationProcessingTime(
                                 System.currentTimeMillis() - mSessionProcessingTimeStamp)
                         .setIsDemoMode(mIsDemoModeEnabled)
+                        .setCarrierId(getSatelliteCarrierId())
                         .reportSessionMetrics();
-                mSessionStartTimeStamp = 0;
-                mSessionProcessingTimeStamp = 0;
             } else {
-                notifyEnablementFailedToSatelliteSessionController();
+                resetSatelliteDisabledRequest();
                 mControllerMetricsStats.onSatelliteDisabled();
-                mWaitingForDisableSatelliteModemResponse = false;
-                mWaitingForSatelliteModemOff = false;
                 mSessionMetricsStats.setTerminationResult(SATELLITE_RESULT_MODEM_TIMEOUT)
                         .setSatelliteTechnology(getSupportedNtnRadioTechnology())
                         .setTerminationProcessingTime(
                                 System.currentTimeMillis() - mSessionProcessingTimeStamp)
                         .setSessionDurationSec(calculateSessionDurationTimeSec())
                         .reportSessionMetrics();
-                mSessionStartTimeStamp = 0;
-                mSessionProcessingTimeStamp = 0;
             }
+            notifyEnablementFailedToSatelliteSessionController(argument.enableSatellite);
+            mSessionStartTimeStamp = 0;
+            mSessionProcessingTimeStamp = 0;
         }
     }
 
@@ -5422,6 +5659,8 @@
                 notificationBuilder.build(), UserHandle.ALL);
 
         mCarrierRoamingSatelliteControllerStats.reportCountOfSatelliteNotificationDisplayed();
+        mCarrierRoamingSatelliteControllerStats.reportCarrierId(getSatelliteCarrierId());
+        mSessionMetricsStats.addCountOfSatelliteNotificationDisplayed();
     }
 
     private void resetCarrierRoamingSatelliteModeParams() {
@@ -5469,15 +5708,61 @@
                 - mSessionMetricsStats.getSessionTerminationProcessingTimeMillis()) / 1000);
     }
 
-    private void notifyEnablementFailedToSatelliteSessionController() {
+    private void notifyEnablementFailedToSatelliteSessionController(boolean enabled) {
         if (mSatelliteSessionController != null) {
-            mSatelliteSessionController.onSatelliteEnablementFailed();
+            mSatelliteSessionController.onSatelliteEnablementFailed(enabled);
         } else {
             ploge("notifyEnablementFailedToSatelliteSessionController: mSatelliteSessionController"
                     + " is not initialized yet");
         }
     }
 
+    private void abortSatelliteEnableRequest(@SatelliteManager.SatelliteResult int resultCode) {
+        synchronized (mSatelliteEnabledRequestLock) {
+            if (mSatelliteEnabledRequest != null) {
+                plogw("abortSatelliteEnableRequest");
+                if (resultCode == SATELLITE_RESULT_SUCCESS) {
+                    resultCode = SATELLITE_RESULT_REQUEST_ABORTED;
+                }
+                mSatelliteEnabledRequest.callback.accept(resultCode);
+                stopWaitForSatelliteEnablingResponseTimer(mSatelliteEnabledRequest);
+                mSatelliteEnabledRequest = null;
+            }
+        }
+    }
+
+    private void abortSatelliteDisableRequest(@SatelliteManager.SatelliteResult int resultCode) {
+        synchronized (mSatelliteEnabledRequestLock) {
+            if (mSatelliteDisabledRequest != null) {
+                plogd("abortSatelliteDisableRequest");
+                mSatelliteDisabledRequest.callback.accept(resultCode);
+                stopWaitForSatelliteEnablingResponseTimer(mSatelliteDisabledRequest);
+                mSatelliteDisabledRequest = null;
+            }
+        }
+    }
+
+    private void abortSatelliteEnableAttributesUpdateRequest(
+            @SatelliteManager.SatelliteResult int resultCode) {
+        synchronized (mSatelliteEnabledRequestLock) {
+            if (mSatelliteEnableAttributesUpdateRequest != null) {
+                plogd("abortSatelliteEnableAttributesUpdateRequest");
+                if (resultCode == SATELLITE_RESULT_SUCCESS) {
+                    resultCode = SATELLITE_RESULT_REQUEST_ABORTED;
+                }
+                mSatelliteEnableAttributesUpdateRequest.callback.accept(resultCode);
+                stopWaitForUpdateSatelliteEnableAttributesResponseTimer(
+                        mSatelliteEnableAttributesUpdateRequest);
+                mSatelliteEnableAttributesUpdateRequest = null;
+            }
+        }
+    }
+
+    private void stopWaitForEnableResponseTimers() {
+        plogd("stopWaitForEnableResponseTimers");
+        removeMessages(EVENT_WAIT_FOR_SATELLITE_ENABLING_RESPONSE_TIMED_OUT);
+    }
+
     private long getDemoPointingAlignedDurationMillisFromResources() {
         long durationMillis = 15000L;
         try {
@@ -5918,6 +6203,25 @@
                 mSatellitePhone = SatelliteServiceUtils.getPhone();
             }
             plogd("mSatellitePhone:" + (mSatellitePhone != null) + ", subId=" + subId);
+            int carrierId = mSatellitePhone.getCarrierId();
+            if (carrierId != UNKNOWN_CARRIER_ID) {
+                mControllerMetricsStats.setCarrierId(carrierId);
+            } else {
+                logd("setSatellitePhone: Carrier ID is UNKNOWN_CARRIER_ID");
+            }
+        }
+    }
+
+    /** Return the carrier ID of the binding satellite subscription. */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+    public int getSatelliteCarrierId() {
+        synchronized (mSatellitePhoneLock) {
+            if (mSatellitePhone != null) {
+                return mSatellitePhone.getCarrierId();
+            } else {
+                logd("getSatelliteCarrierId: returns UNKNOWN_CARRIER_ID");
+                return UNKNOWN_CARRIER_ID;
+            }
         }
     }
 
@@ -6100,4 +6404,22 @@
         intentFilter.addAction(SubscriptionManager.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED);
         mContext.registerReceiver(mDefaultSmsSubscriptionChangedBroadcastReceiver, intentFilter);
     }
+
+    FeatureFlags getFeatureFlags() {
+        return mFeatureFlags;
+    }
+
+    private boolean isSatelliteDisabled() {
+        synchronized (mIsSatelliteEnabledLock) {
+            return ((mIsSatelliteEnabled != null) && !mIsSatelliteEnabled);
+        }
+    }
+
+    private boolean shouldStopWaitForEnableResponseTimer(
+            @NonNull RequestSatelliteEnabledArgument argument) {
+        if (argument.enableSatellite) return true;
+        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 8ea9067..c4babcb 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteSOSMessageRecommender.java
@@ -68,6 +68,8 @@
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.SmsApplication;
+import com.android.internal.telephony.TelephonyCountryDetector;
+import com.android.internal.telephony.flags.FeatureFlags;
 import com.android.internal.telephony.flags.Flags;
 import com.android.internal.telephony.metrics.SatelliteStats;
 
@@ -96,7 +98,11 @@
     @NonNull private final Context mContext;
     @NonNull
     private final SatelliteController mSatelliteController;
+    @NonNull
+    private final TelephonyCountryDetector mCountryDetector;
     private ImsManager mImsManager;
+    @NonNull
+    private final FeatureFlags mFeatureFlags;
 
     private Connection mEmergencyConnection = null;
     private final ISatelliteProvisionStateCallback mISatelliteProvisionStateCallback;
@@ -150,6 +156,8 @@
         }
         mContext = context;
         mSatelliteController = satelliteController;
+        mFeatureFlags = mSatelliteController.getFeatureFlags();
+        mCountryDetector = TelephonyCountryDetector.getInstance(context, mFeatureFlags);
         mImsManager = imsManager;
         mOemEnabledTimeoutMillis =
                 getOemEnabledEmergencyCallWaitForConnectionTimeoutMillis(context);
@@ -321,7 +329,7 @@
                     + ", isCellularAvailable=" + isCellularAvailable
                     + ", isSatelliteAllowed=" + isSatelliteAllowed()
                     + ", shouldTrackCall=" + shouldTrackCall(mEmergencyConnection.getState()));
-            reportEsosRecommenderDecision(isDialerNotified);
+            reportESosRecommenderDecision(isDialerNotified);
             cleanUpResources();
         }
     }
@@ -378,7 +386,7 @@
         }
 
         if (!shouldTrackCall(state)) {
-            reportEsosRecommenderDecision(false);
+            reportESosRecommenderDecision(false);
             cleanUpResources();
         } else {
             // Location service will enter emergency mode only when connection state changes to
@@ -390,7 +398,7 @@
         }
     }
 
-    private void reportEsosRecommenderDecision(boolean isDialerNotified) {
+    private void reportESosRecommenderDecision(boolean isDialerNotified) {
         SatelliteStats.getInstance().onSatelliteSosMessageRecommender(
                 new SatelliteStats.SatelliteSosMessageRecommenderParams.Builder()
                         .setDisplaySosMessageSent(isDialerNotified)
@@ -400,7 +408,8 @@
                         .setIsMultiSim(isMultiSim())
                         .setRecommendingHandoverType(getEmergencyCallToSatelliteHandoverType())
                         .setIsSatelliteAllowedInCurrentLocation(isSatelliteAllowed())
-                        .build());
+                        .setIsWifiConnected(mCountryDetector.isWifiNetworkConnected())
+                        .setCarrierId(getAvailableNtnCarrierID()).build());
     }
 
     private void cleanUpResources() {
@@ -809,6 +818,23 @@
         }
     }
 
+    /** Returns the carrier ID of NTN subscription */
+    private int getAvailableNtnCarrierID() {
+        Pair<Boolean, Integer> ntnSubInfo =
+                mSatelliteController.isUsingNonTerrestrialNetworkViaCarrier();
+        if (ntnSubInfo.first) {
+            TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
+            return tm.createForSubscriptionId(ntnSubInfo.second).getSimCarrierId();
+        }
+
+        Phone satellitePhone = mSatelliteController.getSatellitePhone();
+        if (satellitePhone != null) {
+            return satellitePhone.getCarrierId();
+        }
+
+        return TelephonyManager.UNKNOWN_CARRIER_ID;
+    }
+
     private void plogd(@NonNull String log) {
         Rlog.d(TAG, log);
         if (mPersistentLogger != null) {
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteServiceUtils.java b/src/java/com/android/internal/telephony/satellite/SatelliteServiceUtils.java
index 1bae3bf..21c5c44 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteServiceUtils.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteServiceUtils.java
@@ -174,9 +174,9 @@
                 return SatelliteManager.SATELLITE_MODEM_STATE_OFF;
             case SatelliteModemState.SATELLITE_MODEM_STATE_UNAVAILABLE:
                 return SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE;
-            case SatelliteModemState.SATELLITE_MODEM_STATE_NOT_CONNECTED:
+            case SatelliteModemState.SATELLITE_MODEM_STATE_OUT_OF_SERVICE:
                 return SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED;
-            case SatelliteModemState.SATELLITE_MODEM_STATE_CONNECTED:
+            case SatelliteModemState.SATELLITE_MODEM_STATE_IN_SERVICE:
                 return SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED;
             default:
                 loge("Received invalid modem state: " + modemState);
diff --git a/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java b/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java
index ed6ea24..f4208f7 100644
--- a/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java
+++ b/src/java/com/android/internal/telephony/satellite/SatelliteSessionController.java
@@ -16,9 +16,9 @@
 
 package com.android.internal.telephony.satellite;
 
-import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ESOS_INACTIVITY_TIMEOUT_SEC_INT;
-import static android.telephony.CarrierConfigManager.KEY_SATELLITE_P2P_SMS_INACTIVITY_TIMEOUT_SEC_INT;
-import static android.telephony.CarrierConfigManager.KEY_SATELLITE_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT;
+import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ROAMING_ESOS_INACTIVITY_TIMEOUT_SEC_INT;
+import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ROAMING_P2P_SMS_INACTIVITY_TIMEOUT_SEC_INT;
+import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ROAMING_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_NONE;
@@ -28,6 +28,13 @@
 import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_SUCCESS;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_WAITING_TO_CONNECT;
+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_ENABLING_SATELLITE;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_LISTENING;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_REQUEST_ABORTED;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -60,6 +67,7 @@
 import com.android.internal.telephony.IIntegerConsumer;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.flags.FeatureFlags;
+import com.android.internal.telephony.satellite.metrics.SessionMetricsStats;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
 import com.android.telephony.Rlog;
@@ -167,6 +175,7 @@
     @NonNull private final DatagramController mDatagramController;
     @Nullable private PersistentLogger mPersistentLogger = null;
     @Nullable private DeviceStateMonitor mDeviceStateMonitor;
+    @NonNull private SessionMetricsStats mSessionMetricsStats;
 
     @NonNull private FeatureFlags mFeatureFlags;
 
@@ -195,7 +204,9 @@
             @NonNull FeatureFlags featureFlags,
             boolean isSatelliteSupported) {
         if (sInstance == null || isSatelliteSupported != sInstance.mIsSatelliteSupported) {
+            ConcurrentHashMap<IBinder, ISatelliteModemStateCallback> existingListeners = null;
             if (sInstance != null) {
+                existingListeners = sInstance.mListeners;
                 sInstance.cleanUpResource();
             }
 
@@ -205,6 +216,10 @@
                     featureFlags,
                     isSatelliteSupported,
                     SatelliteModemInterface.getInstance());
+            if (existingListeners != null) {
+                Log.d(TAG, "make() existingListeners: " + existingListeners.size());
+                sInstance.mListeners.putAll(existingListeners);
+            }
         }
         return sInstance;
     }
@@ -242,8 +257,8 @@
                 getSatelliteNbIotInactivityTimeoutMillis();
         mListeners = new ConcurrentHashMap<>();
         mIsSendingTriggeredDuringTransferringState = new AtomicBoolean(false);
-        mPreviousState = SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN;
-        mCurrentState = SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN;
+        mPreviousState = SATELLITE_MODEM_STATE_UNKNOWN;
+        mCurrentState = SATELLITE_MODEM_STATE_UNKNOWN;
         mIsSatelliteSupported = isSatelliteSupported;
         mExponentialBackoff = new ExponentialBackoff(REBIND_INITIAL_DELAY, REBIND_MAXIMUM_DELAY,
                 REBIND_MULTIPLIER, looper, () -> {
@@ -267,6 +282,7 @@
             phone = SatelliteServiceUtils.getPhone();
         }
         mDeviceStateMonitor = phone.getDeviceStateMonitor();
+        mSessionMetricsStats = SessionMetricsStats.getInstance();
 
         addState(mUnavailableState);
         addState(mPowerOffState);
@@ -324,10 +340,12 @@
     /**
      * {@link SatelliteController} uses this function to notify {@link SatelliteSessionController}
      * that the satellite enablement has just failed.
+     *
+     * @param enabled {@code true} if satellite is enabled, {@code false} satellite is disabled.
      */
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-    public void onSatelliteEnablementFailed() {
-        sendMessage(EVENT_SATELLITE_ENABLEMENT_FAILED);
+    public void onSatelliteEnablementFailed(boolean enabled) {
+        sendMessage(EVENT_SATELLITE_ENABLEMENT_FAILED, enabled);
     }
 
     /**
@@ -512,13 +530,24 @@
     }
 
     /**
+     * Get whether state machine is in disabling state.
+     *
+     * @return {@code true} if state machine is in disabling state and {@code false} otherwise.
+     */
+    public boolean isInDisablingState() {
+        if (DBG) plogd("isInDisablingState: getCurrentState=" + getCurrentState());
+        return getCurrentState() == mDisablingState;
+    }
+
+    /**
      * Release all resource.
      */
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
     public void cleanUpResource() {
-        if (DBG) plogd("cleanUpResource");
+        plogd("cleanUpResource");
         mIsDeviceAlignedWithSatellite = false;
         unregisterForScreenStateChanged();
+        quitNow();
     }
 
     private boolean isDemoMode() {
@@ -557,6 +586,8 @@
         public void enter() {
             if (DBG) plogd("Entering PowerOffState");
 
+            mSatelliteController.moveSatelliteToOffStateAndCleanUpResources(
+                    SATELLITE_RESULT_REQUEST_ABORTED);
             mPreviousState = mCurrentState;
             mCurrentState = SatelliteManager.SATELLITE_MODEM_STATE_OFF;
             mIsSendingTriggeredDuringTransferringState.set(false);
@@ -605,8 +636,8 @@
             if (DBG) plogd("Entering EnablingState");
 
             mPreviousState = mCurrentState;
-            mCurrentState = SatelliteManager.SATELLITE_MODEM_STATE_ENABLING_SATELLITE;
-            notifyStateChangedEvent(SatelliteManager.SATELLITE_MODEM_STATE_ENABLING_SATELLITE);
+            mCurrentState = SATELLITE_MODEM_STATE_ENABLING_SATELLITE;
+            notifyStateChangedEvent(SATELLITE_MODEM_STATE_ENABLING_SATELLITE);
         }
 
         @Override
@@ -622,10 +653,17 @@
                     handleSatelliteEnabledStateChanged((boolean) msg.obj);
                     break;
                 case EVENT_SATELLITE_ENABLEMENT_FAILED:
-                    transitionTo(mPowerOffState);
+                    if ((boolean) msg.obj) {
+                        transitionTo(mPowerOffState);
+                    } else {
+                        ploge("Unexpected failed disable event in EnablingState");
+                    }
                     break;
                 case EVENT_SATELLITE_MODEM_STATE_CHANGED:
-                    deferMessage(msg);
+                    handleSatelliteModemStateChanged(msg);
+                    break;
+                case EVENT_SATELLITE_ENABLEMENT_STARTED:
+                    handleSatelliteEnablementStarted((boolean) msg.obj);
                     break;
             }
             // Ignore all unexpected events.
@@ -653,6 +691,15 @@
                 transitionTo(mPowerOffState);
             }
         }
+
+        private void handleSatelliteModemStateChanged(@NonNull Message msg) {
+            int state = msg.arg1;
+            if (state == SatelliteManager.SATELLITE_MODEM_STATE_OFF) {
+                transitionTo(mPowerOffState);
+            } else {
+                deferMessage(msg);
+            }
+        }
     }
 
     private class DisablingState extends State {
@@ -680,17 +727,30 @@
                     handleSatelliteEnabledStateChanged((boolean) msg.obj);
                     break;
                 case EVENT_SATELLITE_ENABLEMENT_FAILED:
-                    if (mPreviousState == SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED
-                            || mPreviousState
-                            == SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING
-                            || mPreviousState == SatelliteManager.SATELLITE_MODEM_STATE_LISTENING) {
+                    boolean enablingSatellite = (boolean) msg.obj;
+                    if (enablingSatellite) {
+                        /* Framework received a disable request when the enable request was in
+                         * progress. We need to set the previous state to OFF since the enable has
+                         * failed so that when disable fail, we can move to OFF state properly.
+                         */
+                        mPreviousState = SatelliteManager.SATELLITE_MODEM_STATE_OFF;
+                        plogd("Enable request has failed. Set mPreviousState to OFF");
+                        break;
+                    }
+                    if (mPreviousState == SATELLITE_MODEM_STATE_CONNECTED
+                            || mPreviousState == SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING
+                            || mPreviousState == SATELLITE_MODEM_STATE_LISTENING) {
                         transitionTo(mConnectedState);
+                    } else if (mPreviousState == SATELLITE_MODEM_STATE_ENABLING_SATELLITE) {
+                        transitionTo(mEnablingState);
+                    } else if (mPreviousState == SatelliteManager.SATELLITE_MODEM_STATE_OFF) {
+                        transitionTo(mPowerOffState);
                     } else {
                         transitionTo(mNotConnectedState);
                     }
                     break;
                 case EVENT_SATELLITE_MODEM_STATE_CHANGED:
-                    handleEventSatelliteModemStateChanged(msg.arg1);
+                    handleEventSatelliteModemStateChanged(msg);
                     break;
             }
             // Ignore all unexpected events.
@@ -699,16 +759,25 @@
 
         private void handleSatelliteEnabledStateChanged(boolean on) {
             if (on) {
-                plogw("Unexpected power on event while disabling satellite");
+                /* Framework received a disable request when the enable request was in progress.
+                 * We need to set the previous state to NOT_CONNECTED since the enable has
+                 * succeeded so that when disable fail, we can move to NOT_CONNECTED state properly.
+                 */
+                mPreviousState = SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED;
+                plogd("Enable request has succeeded. Set mPreviousState to NOT_CONNECTED");
             } else {
                 transitionTo(mPowerOffState);
             }
         }
 
-        private void handleEventSatelliteModemStateChanged(
-                @SatelliteManager.SatelliteModemState int state) {
+        private void handleEventSatelliteModemStateChanged(@NonNull Message msg) {
+            int state = msg.arg1;
             if (state == SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED) {
                 mPreviousState = state;
+            } else if (state == SatelliteManager.SATELLITE_MODEM_STATE_OFF) {
+                plogd("Modem OFF state will be processed after getting the confirmation of the"
+                        + " disable request");
+                deferMessage(msg);
             }
         }
     }
@@ -749,6 +818,9 @@
                 case EVENT_SCREEN_OFF_INACTIVITY_TIMER_TIMED_OUT:
                     handleEventScreenOffInactivityTimerTimedOut();
                     break;
+                case EVENT_SATELLITE_MODEM_STATE_CHANGED:
+                    handleSatelliteModemStateChanged(msg);
+                    break;
             }
             // Ignore all unexpected events.
             return HANDLED;
@@ -792,6 +864,13 @@
             }
         }
 
+        private void handleSatelliteModemStateChanged(@NonNull Message msg) {
+            int state = msg.arg1;
+            if (state == SatelliteManager.SATELLITE_MODEM_STATE_OFF) {
+                transitionTo(mPowerOffState);
+            }
+        }
+
         private void disableCellularModemWhileSatelliteModeIsOn() {
             synchronized (mLock) {
                 if (mIsDisableCellularModemInProgress) {
@@ -823,8 +902,8 @@
             if (DBG) plogd("Entering TransferringState");
             stopNbIotInactivityTimer();
             mPreviousState = mCurrentState;
-            mCurrentState = SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING;
-            notifyStateChangedEvent(SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING);
+            mCurrentState = SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING;
+            notifyStateChangedEvent(SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING);
         }
 
         @Override
@@ -879,6 +958,8 @@
                 @SatelliteManager.SatelliteModemState int state) {
             if (state == SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED) {
                 transitionTo(mNotConnectedState);
+            } else if (state == SatelliteManager.SATELLITE_MODEM_STATE_OFF) {
+                transitionTo(mPowerOffState);
             }
         }
     }
@@ -889,11 +970,11 @@
             if (DBG) plogd("Entering ListeningState");
 
             mPreviousState = mCurrentState;
-            mCurrentState = SatelliteManager.SATELLITE_MODEM_STATE_LISTENING;
+            mCurrentState = SATELLITE_MODEM_STATE_LISTENING;
             long timeoutMillis = updateListeningMode(true);
             sendMessageDelayed(EVENT_LISTENING_TIMER_TIMEOUT, timeoutMillis);
             mIsSendingTriggeredDuringTransferringState.set(false);
-            notifyStateChangedEvent(SatelliteManager.SATELLITE_MODEM_STATE_LISTENING);
+            notifyStateChangedEvent(SATELLITE_MODEM_STATE_LISTENING);
         }
 
         @Override
@@ -926,6 +1007,9 @@
                 case EVENT_SCREEN_OFF_INACTIVITY_TIMER_TIMED_OUT:
                     handleEventScreenOffInactivityTimerTimedOut();
                     break;
+                case EVENT_SATELLITE_MODEM_STATE_CHANGED:
+                    handleEventSatelliteModemStateChange(msg);
+                    break;
             }
             // Ignore all unexpected events.
             return HANDLED;
@@ -951,6 +1035,13 @@
                 transitionTo(mTransferringState);
             }
         }
+
+        private void handleEventSatelliteModemStateChange(@NonNull Message msg) {
+            int state = msg.arg1;
+            if (state == SatelliteManager.SATELLITE_MODEM_STATE_OFF) {
+                transitionTo(mPowerOffState);
+            }
+        }
     }
 
     private class NotConnectedState extends State {
@@ -1007,8 +1098,10 @@
 
         private void handleEventSatelliteModemStateChanged(
                 @SatelliteManager.SatelliteModemState int state) {
-            if (state == SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED) {
+            if (state == SATELLITE_MODEM_STATE_CONNECTED) {
                 transitionTo(mConnectedState);
+            } else if (state == SatelliteManager.SATELLITE_MODEM_STATE_OFF) {
+                transitionTo(mPowerOffState);
             }
         }
 
@@ -1040,8 +1133,8 @@
             if (DBG) plogd("Entering ConnectedState");
 
             mPreviousState = mCurrentState;
-            mCurrentState = SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED;
-            notifyStateChangedEvent(SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED);
+            mCurrentState = SATELLITE_MODEM_STATE_CONNECTED;
+            notifyStateChangedEvent(SATELLITE_MODEM_STATE_CONNECTED);
             startNbIotInactivityTimer();
         }
 
@@ -1085,6 +1178,8 @@
                 @SatelliteManager.SatelliteModemState int state) {
             if (state == SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED) {
                 transitionTo(mNotConnectedState);
+            } else if (state == SatelliteManager.SATELLITE_MODEM_STATE_OFF) {
+                transitionTo(mPowerOffState);
             }
         }
 
@@ -1380,21 +1475,21 @@
     private int getScreenOffInactivityTimeoutDurationSec() {
         PersistableBundle config = mSatelliteController.getPersistableBundle(getSubId());
 
-        return config.getInt(KEY_SATELLITE_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT,
+        return config.getInt(KEY_SATELLITE_ROAMING_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT,
                 DEFAULT_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC);
     }
 
     private int getP2pSmsInactivityTimeoutDurationSec() {
         PersistableBundle config = mSatelliteController.getPersistableBundle(getSubId());
 
-        return config.getInt(KEY_SATELLITE_P2P_SMS_INACTIVITY_TIMEOUT_SEC_INT,
+        return config.getInt(KEY_SATELLITE_ROAMING_P2P_SMS_INACTIVITY_TIMEOUT_SEC_INT,
                 DEFAULT_P2P_SMS_INACTIVITY_TIMEOUT_SEC);
     }
 
     private int getEsosInactivityTimeoutDurationSec() {
         PersistableBundle config = mSatelliteController.getPersistableBundle(getSubId());
 
-        return config.getInt(KEY_SATELLITE_ESOS_INACTIVITY_TIMEOUT_SEC_INT,
+        return config.getInt(KEY_SATELLITE_ROAMING_ESOS_INACTIVITY_TIMEOUT_SEC_INT,
                 DEFAULT_ESOS_INACTIVITY_TIMEOUT_SEC);
     }
 
@@ -1464,6 +1559,10 @@
                     @Override
                     public void accept(int result) {
                         plogd("requestSatelliteEnabled result=" + result);
+                        if (result == SATELLITE_RESULT_SUCCESS) {
+                            mSessionMetricsStats.addCountOfAutoExitDueToScreenOff();
+                        }
+                        // TODO(b/364738085): Add CountOfAutoExitDueToTnNetwork
                     }
                 });
     }
diff --git a/src/java/com/android/internal/telephony/satellite/metrics/AccessControllerMetricsStats.java b/src/java/com/android/internal/telephony/satellite/metrics/AccessControllerMetricsStats.java
index 13ba709..25f6976 100644
--- a/src/java/com/android/internal/telephony/satellite/metrics/AccessControllerMetricsStats.java
+++ b/src/java/com/android/internal/telephony/satellite/metrics/AccessControllerMetricsStats.java
@@ -15,6 +15,7 @@
  */
 package com.android.internal.telephony.satellite.metrics;
 
+import static android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;
 
 import static com.android.internal.telephony.satellite.SatelliteConstants.CONFIG_DATA_SOURCE_UNKNOWN;
@@ -42,6 +43,7 @@
     private @SatelliteManager.SatelliteResult int mResultCode;
     private String[] mCountryCodes;
     private @SatelliteConstants.ConfigDataSource int mConfigDataSource;
+    private int mCarrierId;
     private AccessControllerMetricsStats() {
         initializeAccessControllerMetricsParam();
     }
@@ -70,6 +72,7 @@
         mResultCode = SATELLITE_RESULT_SUCCESS;
         mCountryCodes = new String[0];
         mConfigDataSource = CONFIG_DATA_SOURCE_UNKNOWN;
+        mCarrierId = UNKNOWN_CARRIER_ID;
     }
     /**
      * Sets the Access Control Type for current satellite enablement.
@@ -161,6 +164,17 @@
         logd("setConfigDataSource: config data source = " + mConfigDataSource);
         return this;
     }
+
+    /**
+     * Sets the carrier id for NTN satellite service.
+     * @param carrierId Carrier ID of currently available NTN Satellite Network.
+     */
+    public AccessControllerMetricsStats setCarrierId(int carrierId) {
+        mCarrierId = carrierId;
+        logd("setCarrierId: Carrier ID = " + mCarrierId);
+        return this;
+    }
+
     /** Report the access controller metrics atoms to PersistAtomsStorage in telephony. */
     public void reportAccessControllerMetrics() {
         SatelliteStats.SatelliteAccessControllerParams accessControllerParams =
@@ -174,6 +188,7 @@
                         .setResult(mResultCode)
                         .setCountryCodes(mCountryCodes)
                         .setConfigDatasource(mConfigDataSource)
+                        .setCarrierId(mCarrierId)
                         .build();
         logd("reportAccessControllerMetrics: " + accessControllerParams.toString());
         SatelliteStats.getInstance().onSatelliteAccessControllerMetrics(accessControllerParams);
diff --git a/src/java/com/android/internal/telephony/satellite/metrics/CarrierRoamingSatelliteControllerStats.java b/src/java/com/android/internal/telephony/satellite/metrics/CarrierRoamingSatelliteControllerStats.java
index 9524b75..b0cea29 100644
--- a/src/java/com/android/internal/telephony/satellite/metrics/CarrierRoamingSatelliteControllerStats.java
+++ b/src/java/com/android/internal/telephony/satellite/metrics/CarrierRoamingSatelliteControllerStats.java
@@ -80,6 +80,14 @@
                         .build());
     }
 
+    /** Capture the NB-IoT NTN carrier ID */
+    public void reportCarrierId(int carrierId) {
+        mSatelliteStats.onCarrierRoamingSatelliteControllerStatsMetrics(
+                new SatelliteStats.CarrierRoamingSatelliteControllerStatsParams.Builder()
+                        .setCarrierId(carrierId)
+                        .build());
+    }
+
     private static void logd(@NonNull String log) {
         Log.d(TAG, log);
     }
diff --git a/src/java/com/android/internal/telephony/satellite/metrics/ControllerMetricsStats.java b/src/java/com/android/internal/telephony/satellite/metrics/ControllerMetricsStats.java
index 7dff2e6..9f42d3d 100644
--- a/src/java/com/android/internal/telephony/satellite/metrics/ControllerMetricsStats.java
+++ b/src/java/com/android/internal/telephony/satellite/metrics/ControllerMetricsStats.java
@@ -371,6 +371,24 @@
         }
     }
 
+    /** Capture the latest provisioned state for satellite service */
+    @VisibleForTesting
+    public void setIsProvisioned(boolean isProvisioned) {
+        mSatelliteStats.onSatelliteControllerMetrics(
+                new SatelliteStats.SatelliteControllerParams.Builder()
+                        .setIsProvisioned(isProvisioned)
+                        .build());
+    }
+
+    /** Capture the NB-IoT NTN carrier ID */
+    @VisibleForTesting
+    public void setCarrierId(int carrierId) {
+        mSatelliteStats.onSatelliteControllerMetrics(
+                new SatelliteStats.SatelliteControllerParams.Builder()
+                        .setCarrierId(carrierId)
+                        .build());
+    }
+
     /** Receives the battery status whether it is in charging or not, update interval is 60 sec. */
     private final BroadcastReceiver mBatteryStatusReceiver = new BroadcastReceiver() {
         private long mLastUpdatedTime = 0;
diff --git a/src/java/com/android/internal/telephony/satellite/metrics/ProvisionMetricsStats.java b/src/java/com/android/internal/telephony/satellite/metrics/ProvisionMetricsStats.java
index 0647231..73be042 100644
--- a/src/java/com/android/internal/telephony/satellite/metrics/ProvisionMetricsStats.java
+++ b/src/java/com/android/internal/telephony/satellite/metrics/ProvisionMetricsStats.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony.satellite.metrics;
 
+import static android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID;
+
 import android.annotation.NonNull;
 import android.telephony.satellite.SatelliteManager;
 import android.util.Log;
@@ -37,6 +39,7 @@
     private int mProvisioningStartTimeSec;
     private boolean mIsProvisionRequest;
     private boolean mIsCanceled;
+    private int mCarrierId;
 
     private ProvisionMetricsStats() {
         initializeProvisionParams();
@@ -80,6 +83,12 @@
         return this;
     }
 
+    /** Sets the Carrier of NTN satellite */
+    public ProvisionMetricsStats setCarrierId(int carrierId) {
+        mCarrierId = carrierId;
+        return this;
+    }
+
     /** Report the provision metrics atoms to PersistAtomsStorage in telephony */
     public void reportProvisionMetrics() {
         SatelliteStats.SatelliteProvisionParams provisionParams =
@@ -89,9 +98,10 @@
                                 (System.currentTimeMillis() / 1000) - mProvisioningStartTimeSec)
                         .setIsProvisionRequest(mIsProvisionRequest)
                         .setIsCanceled(mIsCanceled)
+                        .setCarrierId(mCarrierId)
                         .build();
         SatelliteStats.getInstance().onSatelliteProvisionMetrics(provisionParams);
-        logd("reportProvisionMetrics: " + provisionParams.toString());
+        logd("reportProvisionMetrics: " + provisionParams);
         initializeProvisionParams();
     }
 
@@ -100,6 +110,7 @@
         mProvisioningStartTimeSec = INVALID_TIME;
         mIsProvisionRequest = false;
         mIsCanceled = false;
+        mCarrierId = UNKNOWN_CARRIER_ID;
     }
 
     private static void logd(@NonNull String log) {
diff --git a/src/java/com/android/internal/telephony/satellite/metrics/SessionMetricsStats.java b/src/java/com/android/internal/telephony/satellite/metrics/SessionMetricsStats.java
index 65181c0..a234378 100644
--- a/src/java/com/android/internal/telephony/satellite/metrics/SessionMetricsStats.java
+++ b/src/java/com/android/internal/telephony/satellite/metrics/SessionMetricsStats.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.satellite.metrics;
 
+import static android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID;
 import static android.telephony.satellite.NtnSignalStrength.NTN_SIGNAL_STRENGTH_NONE;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;
 
@@ -52,6 +53,10 @@
     private int mCountOfIncomingDatagramFailed;
     private boolean mIsDemoMode;
     private @NtnSignalStrength.NtnSignalStrengthLevel int mMaxNtnSignalStrengthLevel;
+    private int mCarrierId;
+    private int mCountOfSatelliteNotificationDisplayed;
+    private int mCountOfAutoExitDueToScreenOff;
+    private int mCountOfAutoExitDueToTnNetwork;
 
     private SessionMetricsStats() {
         initializeSessionMetricsParam();
@@ -213,6 +218,35 @@
         return this;
     }
 
+    /** Sets the Carrier ID of this NTN session. */
+    public SessionMetricsStats setCarrierId(int carrierId) {
+        mCarrierId = carrierId;
+        logd("setCarrierId(" + carrierId + ")");
+        return this;
+    }
+
+    /** Increase the count of Satellite Notification Display. */
+    public SessionMetricsStats addCountOfSatelliteNotificationDisplayed() {
+        mCountOfSatelliteNotificationDisplayed++;
+        logd("addCountOfSatelliteNotificationDisplayed: current count="
+                + mCountOfSatelliteNotificationDisplayed);
+        return this;
+    }
+
+    /** Increase the count of auto exit from P2P satellite messaging due to screen off. */
+    public SessionMetricsStats addCountOfAutoExitDueToScreenOff() {
+        mCountOfAutoExitDueToScreenOff++;
+        logd("addCountOfAutoExitDueToScreenOff: current count=" + mCountOfAutoExitDueToScreenOff);
+        return this;
+    }
+
+    /** Increase the count of auto exit from P2P satellite messaging due to scan TN network. */
+    public SessionMetricsStats addCountOfAutoExitDueToTnNetwork() {
+        mCountOfAutoExitDueToTnNetwork++;
+        logd("addCountOfAutoExitDueToTnNetwork: current count=" + mCountOfAutoExitDueToTnNetwork);
+        return this;
+    }
+
     /** Report the session metrics atoms to PersistAtomsStorage in telephony. */
     public void reportSessionMetrics() {
         SatelliteStats.SatelliteSessionParams sessionParams =
@@ -229,6 +263,11 @@
                         .setCountOfIncomingDatagramFailed(mCountOfIncomingDatagramFailed)
                         .setIsDemoMode(mIsDemoMode)
                         .setMaxNtnSignalStrengthLevel(mMaxNtnSignalStrengthLevel)
+                        .setCarrierId(mCarrierId)
+                        .setCountOfSatelliteNotificationDisplayed(
+                                mCountOfSatelliteNotificationDisplayed)
+                        .setCountOfAutoExitDueToScreenOff(mCountOfAutoExitDueToScreenOff)
+                        .setCountOfAutoExitDueToTnNetwork(mCountOfAutoExitDueToTnNetwork)
                         .build();
         logd("reportSessionMetrics: " + sessionParams.toString());
         SatelliteStats.getInstance().onSatelliteSessionMetrics(sessionParams);
@@ -277,6 +316,10 @@
         mCountOfIncomingDatagramFailed = 0;
         mIsDemoMode = false;
         mMaxNtnSignalStrengthLevel = NTN_SIGNAL_STRENGTH_NONE;
+        mCarrierId = UNKNOWN_CARRIER_ID;
+        mCountOfSatelliteNotificationDisplayed = 0;
+        mCountOfAutoExitDueToScreenOff = 0;
+        mCountOfAutoExitDueToTnNetwork = 0;
     }
 
     private static void logd(@NonNull String log) {
diff --git a/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
index 6ef7328..87d6d27 100644
--- a/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
+++ b/src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java
@@ -4557,16 +4557,9 @@
      */
     @NonNull
     private String getCallingPackage() {
-        if (Flags.supportPhoneUidCheckForMultiuser()) {
-            if (UserHandle.isSameApp(Binder.getCallingUid(), Process.PHONE_UID)) {
-                // Too many packages running with phone uid. Just return one here.
-                return "com.android.phone";
-            }
-        } else {
-            if (Binder.getCallingUid() == Process.PHONE_UID) {
-                // Too many packages running with phone uid. Just return one here.
-                return "com.android.phone";
-            }
+        if (UserHandle.isSameApp(Binder.getCallingUid(), Process.PHONE_UID)) {
+            // Too many packages running with phone uid. Just return one here.
+            return "com.android.phone";
         }
         return Arrays.toString(mContext.getPackageManager().getPackagesForUid(
                 Binder.getCallingUid()));
diff --git a/src/java/com/android/internal/telephony/uicc/UiccPort.java b/src/java/com/android/internal/telephony/uicc/UiccPort.java
index 9e341ef..905db70 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccPort.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccPort.java
@@ -31,7 +31,6 @@
 import com.android.internal.telephony.TelephonyComponentFactory;
 import com.android.internal.telephony.flags.FeatureFlags;
 import com.android.internal.telephony.flags.FeatureFlagsImpl;
-import com.android.internal.telephony.flags.Flags;
 import com.android.telephony.Rlog;
 
 import java.io.FileDescriptor;
@@ -442,15 +441,13 @@
      * channel that may have been assigned to other client.
      */
     private void cleanupOpenLogicalChannelRecordsIfNeeded() {
-        if (Flags.cleanupOpenLogicalChannelRecordOnDispose()) {
-            synchronized (mOpenChannelRecords) {
-                for (OpenLogicalChannelRecord record : mOpenChannelRecords) {
-                    if (DBG) log("Clean up " + record);
-                    record.mRequest.binder.unlinkToDeath(record, /*flags=*/ 0);
-                    record.mRequest.binder = null;
-                }
-                mOpenChannelRecords.clear();
+        synchronized (mOpenChannelRecords) {
+            for (OpenLogicalChannelRecord record : mOpenChannelRecords) {
+                if (DBG) log("Clean up " + record);
+                record.mRequest.binder.unlinkToDeath(record, /*flags=*/ 0);
+                record.mRequest.binder = null;
             }
+            mOpenChannelRecords.clear();
         }
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierAppUtilsTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierAppUtilsTest.java
index e06e4fe..cb37d88 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierAppUtilsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierAppUtilsTest.java
@@ -23,7 +23,6 @@
 import android.os.Bundle;
 import android.os.CarrierAssociatedAppEntry;
 import android.os.UserHandle;
-import android.platform.test.flag.junit.SetFlagsRule;
 import android.provider.Settings;
 import android.telephony.TelephonyManager;
 import android.test.mock.MockContentProvider;
@@ -35,12 +34,9 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.internal.telephony.flags.Flags;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Ignore;
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mockito;
@@ -63,9 +59,6 @@
     private static final int USER_ID = 12345;
     private static final String CALLING_PACKAGE = "phone";
 
-    @Rule
-    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
-
     // Mocked classes
     private Context mContext;
     private PackageManager mPackageManager;
@@ -86,7 +79,6 @@
 
     @Before
     public void setUp() throws Exception {
-        mSetFlagsRule.enableFlags(Flags.FLAG_HIDE_PREINSTALLED_CARRIER_APP_AT_MOST_ONCE);
         System.setProperty("dexmaker.dexcache",
                 InstrumentationRegistry.getTargetContext().getCacheDir().getPath());
         Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java
index 3b4f869..ac89501 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java
@@ -41,7 +41,6 @@
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.permission.LegacyPermissionManager;
-import android.platform.test.flag.junit.SetFlagsRule;
 import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.telephony.SubscriptionManager;
@@ -52,13 +51,11 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.telephony.flags.FeatureFlags;
-import com.android.internal.telephony.flags.Flags;
 import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.server.pm.permission.LegacyPermissionManagerService;
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 
 import java.lang.reflect.Field;
@@ -75,9 +72,6 @@
     private static final String FEATURE = "com.example.feature";
     private static final String MSG = "message";
 
-    @Rule
-    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
-
     // Mocked classes
     private Context mMockContext;
     private AppOpsManager mMockAppOps;
@@ -97,7 +91,6 @@
 
     @Before
     public void setUp() throws Exception {
-        mSetFlagsRule.enableFlags(Flags.FLAG_SUPPORT_PHONE_UID_CHECK_FOR_MULTIUSER);
         mMockContext = mock(Context.class);
         mMockAppOps = mock(AppOpsManager.class);
         mMockSubscriptionManager = mock(SubscriptionManager.class);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/domainselection/DomainSelectionConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/domainselection/DomainSelectionConnectionTest.java
index 5fd7a77..2f3fabf 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/domainselection/DomainSelectionConnectionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/domainselection/DomainSelectionConnectionTest.java
@@ -17,8 +17,10 @@
 
 import static android.telephony.AccessNetworkConstants.AccessNetworkType.EUTRAN;
 import static android.telephony.AccessNetworkConstants.AccessNetworkType.UTRAN;
+import static android.telephony.DomainSelectionService.SCAN_TYPE_FULL_SERVICE;
 import static android.telephony.DomainSelectionService.SCAN_TYPE_NO_PREFERENCE;
 import static android.telephony.DomainSelectionService.SELECTOR_TYPE_CALLING;
+import static android.telephony.DomainSelectionService.SELECTOR_TYPE_SMS;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -46,6 +48,7 @@
 import android.telephony.DisconnectCause;
 import android.telephony.DomainSelectionService;
 import android.telephony.EmergencyRegistrationResult;
+import android.telephony.NetworkRegistrationInfo;
 import android.telephony.PreciseDisconnectCause;
 import android.telephony.data.ApnSetting;
 import android.telephony.ims.ImsReasonInfo;
@@ -55,6 +58,8 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.telephony.CallFailCause;
+import com.android.internal.telephony.CommandException;
+import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.IDomainSelector;
 import com.android.internal.telephony.ITransportSelectorCallback;
 import com.android.internal.telephony.ITransportSelectorResultCallback;
@@ -83,6 +88,7 @@
 
     private static final String TELECOM_CALL_ID1 = "TC1";
 
+    private CommandsInterface mCi;
     private DomainSelectionController mDomainSelectionController;
     private DomainSelectionConnection.DomainSelectionConnectionCallback mConnectionCallback;
     private DomainSelectionConnection mDsc;
@@ -91,6 +97,9 @@
     public void setUp() throws Exception {
         super.setUp(this.getClass().getSimpleName());
 
+        mCi = Mockito.mock(CommandsInterface.class);
+        mPhone.mCi = mCi;
+
         mDomainSelectionController = Mockito.mock(DomainSelectionController.class);
         doReturn(true).when(mDomainSelectionController).selectDomain(any(), any());
         mConnectionCallback =
@@ -187,6 +196,7 @@
 
         verify(mPhone).registerForEmergencyNetworkScan(
                 handlerCaptor.capture(), eventCaptor.capture(), any());
+        verify(mCi).registerForModemReset(any(), anyInt(), any());
 
         int[] expectedPreferredNetworks = new int[] { EUTRAN, UTRAN };
 
@@ -235,6 +245,7 @@
         processAllMessages();
 
         verify(mPhone).registerForEmergencyNetworkScan(any(), anyInt(), any());
+        verify(mCi).registerForModemReset(any(), anyInt(), any());
         verify(mPhone).triggerEmergencyNetworkScan(any(), anyInt(), any());
 
         wwanCallback.onCancel();
@@ -280,6 +291,7 @@
         verify(mPhone).cancelEmergencyNetworkScan(eq(true), msgCaptor.capture());
 
         verify(mPhone, times(0)).registerForEmergencyNetworkScan(any(), anyInt(), any());
+        verify(mCi, times(0)).registerForModemReset(any(), anyInt(), any());
         verify(mPhone, times(0)).triggerEmergencyNetworkScan(any(), anyInt(), any());
 
         Message msg = msgCaptor.getValue();
@@ -295,6 +307,7 @@
 
         verify(mPhone).registerForEmergencyNetworkScan(
                 handlerCaptor.capture(), eventCaptor.capture(), any());
+        verify(mCi).registerForModemReset(any(), anyInt(), any());
 
         int[] expectedPreferredNetworks = new int[] { EUTRAN, UTRAN };
 
@@ -350,6 +363,7 @@
 
         verify(mPhone).cancelEmergencyNetworkScan(eq(true), msgCaptor.capture());
         verify(mPhone, times(0)).registerForEmergencyNetworkScan(any(), anyInt(), any());
+        verify(mCi, times(0)).registerForModemReset(any(), anyInt(), any());
         verify(mPhone, times(0)).triggerEmergencyNetworkScan(any(), anyInt(), any());
 
         Message msg = msgCaptor.getValue();
@@ -363,6 +377,7 @@
 
         // Verify that scan is requested.
         verify(mPhone).registerForEmergencyNetworkScan(any(), anyInt(), any());
+        verify(mCi).registerForModemReset(any(), anyInt(), any());
         verify(mPhone).triggerEmergencyNetworkScan(any(), anyInt(), any());
 
         // Cancele scan after reset completes.
@@ -410,6 +425,7 @@
 
         verify(mPhone).cancelEmergencyNetworkScan(eq(true), msgCaptor.capture());
         verify(mPhone, times(0)).registerForEmergencyNetworkScan(any(), anyInt(), any());
+        verify(mCi, times(0)).registerForModemReset(any(), anyInt(), any());
         verify(mPhone, times(0)).triggerEmergencyNetworkScan(any(), anyInt(), any());
 
         Message msg = msgCaptor.getValue();
@@ -430,11 +446,270 @@
 
         // Verify there is no scan request after reset completes.
         verify(mPhone, times(0)).registerForEmergencyNetworkScan(any(), anyInt(), any());
+        verify(mCi, times(0)).registerForModemReset(any(), anyInt(), any());
         verify(mPhone, times(0)).triggerEmergencyNetworkScan(any(), anyInt(), any());
     }
 
     @Test
     @SmallTest
+    public void testWwanSelectorCallbackOnRequestEmergencyNetworkScanAndRadioNotAvailableError()
+            throws Exception {
+        mDsc = createConnection(mPhone, SELECTOR_TYPE_CALLING, true,
+                mDomainSelectionController);
+
+        ITransportSelectorCallback transportCallback = mDsc.getTransportSelectorCallback();
+
+        assertNotNull(transportCallback);
+
+        DomainSelectionService.SelectionAttributes attr = getSelectionAttributes(
+                mPhone.getPhoneId(), mPhone.getSubId(), SELECTOR_TYPE_CALLING, true,
+                false, 0, TELECOM_CALL_ID1, null, null, null);
+
+        mDsc.selectDomain(attr);
+
+        IDomainSelector domainSelector = Mockito.mock(IDomainSelector.class);
+        transportCallback.onCreated(domainSelector);
+
+        IWwanSelectorCallback wwanCallback = onWwanSelected(transportCallback);
+
+        assertNotNull(wwanCallback);
+
+        int[] preferredNetworks = new int[] { EUTRAN, UTRAN };
+        int scanType = SCAN_TYPE_NO_PREFERENCE;
+        IWwanSelectorResultCallback resultCallback =
+                Mockito.mock(IWwanSelectorResultCallback.class);
+
+        wwanCallback.onRequestEmergencyNetworkScan(preferredNetworks, scanType,
+                false, resultCallback);
+        processAllMessages();
+
+        ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
+        ArgumentCaptor<Message> msgCaptor = ArgumentCaptor.forClass(Message.class);
+
+        verify(mPhone).registerForEmergencyNetworkScan(handlerCaptor.capture(), anyInt(), any());
+        verify(mCi).registerForModemReset(any(), anyInt(), any());
+        processAllMessages();
+
+        int[] expectedPreferredNetworks = new int[] { EUTRAN, UTRAN };
+
+        verify(mPhone).triggerEmergencyNetworkScan(eq(expectedPreferredNetworks),
+                eq(scanType), msgCaptor.capture());
+
+        Handler handler = handlerCaptor.getValue();
+        Message msg = msgCaptor.getValue();
+
+        assertNotNull(handler);
+        assertNotNull(msg);
+
+        CommandException commandException =
+                new CommandException(CommandException.Error.RADIO_NOT_AVAILABLE);
+        handler.sendMessage(handler.obtainMessage(msg.what,
+                new AsyncResult((Integer) scanType, null, commandException)));
+        processAllMessages();
+
+        verify(resultCallback, times(0)).onComplete(any());
+        verify(mPhone).unregisterForEmergencyNetworkScan(any());
+        verify(mCi).unregisterForModemReset(any());
+        verify(mPhone, times(0)).cancelEmergencyNetworkScan(anyBoolean(), any());
+        verify(mDomainSelectionController).removeConnection(eq(mDsc));
+    }
+
+    @Test
+    @SmallTest
+    public void testModemResetOnRequestEmergencyNetworkDuringNetworkScan()
+            throws Exception {
+        mDsc = createConnection(mPhone, SELECTOR_TYPE_CALLING, true,
+                mDomainSelectionController);
+
+        ITransportSelectorCallback transportCallback = mDsc.getTransportSelectorCallback();
+
+        assertNotNull(transportCallback);
+
+        DomainSelectionService.SelectionAttributes attr = getSelectionAttributes(
+                mPhone.getPhoneId(), mPhone.getSubId(), SELECTOR_TYPE_CALLING, true,
+                false, 0, TELECOM_CALL_ID1, null, null, null);
+
+        mDsc.selectDomain(attr);
+
+        IDomainSelector domainSelector = Mockito.mock(IDomainSelector.class);
+        transportCallback.onCreated(domainSelector);
+
+        IWwanSelectorCallback wwanCallback = onWwanSelected(transportCallback);
+
+        assertNotNull(wwanCallback);
+
+        int[] preferredNetworks = new int[] { EUTRAN, UTRAN };
+        int scanType = SCAN_TYPE_FULL_SERVICE;
+        IWwanSelectorResultCallback resultCallback =
+                Mockito.mock(IWwanSelectorResultCallback.class);
+
+        wwanCallback.onRequestEmergencyNetworkScan(preferredNetworks, scanType, false,
+                resultCallback);
+        processAllMessages();
+
+        ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
+        ArgumentCaptor<Integer> eventCaptor = ArgumentCaptor.forClass(Integer.class);
+
+        verify(mPhone).registerForEmergencyNetworkScan(any(), anyInt(), any());
+        verify(mCi).registerForModemReset(handlerCaptor.capture(), eventCaptor.capture(),
+                any());
+        processAllMessages();
+
+        int[] expectedPreferredNetworks = new int[] { EUTRAN, UTRAN };
+
+        verify(mPhone).triggerEmergencyNetworkScan(eq(expectedPreferredNetworks),
+                eq(scanType), any());
+
+        Handler handler = handlerCaptor.getValue();
+        Integer event = eventCaptor.getValue();
+
+        assertNotNull(handler);
+        assertNotNull(event);
+
+        handler.sendMessage(handler.obtainMessage(event.intValue(),
+                new AsyncResult(null, null, null)));
+        processAllMessages();
+
+        verify(resultCallback, times(0)).onComplete(any());
+        verify(mPhone).unregisterForEmergencyNetworkScan(any());
+        verify(mCi).unregisterForModemReset(any());
+        verify(mPhone).cancelEmergencyNetworkScan(anyBoolean(), any());
+    }
+
+    @Test
+    @SmallTest
+    public void testModemResetOnRequestEmergencyNetworkDuringNetworkScanForSms()
+            throws Exception {
+        mDsc = createConnection(mPhone, SELECTOR_TYPE_SMS, true,
+                mDomainSelectionController);
+
+        ITransportSelectorCallback transportCallback = mDsc.getTransportSelectorCallback();
+
+        assertNotNull(transportCallback);
+
+        DomainSelectionService.SelectionAttributes attr = getSelectionAttributes(
+                mPhone.getPhoneId(), mPhone.getSubId(), SELECTOR_TYPE_SMS, true,
+                false, 0, TELECOM_CALL_ID1, null, null, null);
+
+        mDsc.selectDomain(attr);
+
+        IDomainSelector domainSelector = Mockito.mock(IDomainSelector.class);
+        transportCallback.onCreated(domainSelector);
+
+        IWwanSelectorCallback wwanCallback = onWwanSelected(transportCallback);
+
+        assertNotNull(wwanCallback);
+
+        int[] preferredNetworks = new int[] { EUTRAN, UTRAN };
+        int scanType = SCAN_TYPE_FULL_SERVICE;
+        IWwanSelectorResultCallback resultCallback =
+                Mockito.mock(IWwanSelectorResultCallback.class);
+
+        wwanCallback.onRequestEmergencyNetworkScan(preferredNetworks, scanType, false,
+                resultCallback);
+        processAllMessages();
+
+        ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
+        ArgumentCaptor<Integer> eventCaptor = ArgumentCaptor.forClass(Integer.class);
+
+        verify(mPhone).registerForEmergencyNetworkScan(any(), anyInt(), any());
+        verify(mCi).registerForModemReset(handlerCaptor.capture(), eventCaptor.capture(),
+                any());
+        processAllMessages();
+
+        int[] expectedPreferredNetworks = new int[] { EUTRAN, UTRAN };
+
+        verify(mPhone).triggerEmergencyNetworkScan(eq(expectedPreferredNetworks),
+                eq(scanType), any());
+
+        Handler handler = handlerCaptor.getValue();
+        Integer event = eventCaptor.getValue();
+
+        assertNotNull(handler);
+        assertNotNull(event);
+
+        handler.sendMessage(handler.obtainMessage(event.intValue(),
+                new AsyncResult(null, null, null)));
+        processAllMessages();
+
+        verify(mPhone, times(0)).unregisterForEmergencyNetworkScan(any());
+        verify(mCi, times(0)).unregisterForModemReset(any());
+        verify(mPhone, times(0)).cancelEmergencyNetworkScan(anyBoolean(), any());
+    }
+
+    @Test
+    @SmallTest
+    public void testModemResetOnRequestEmergencyNetworkAfterNetworkScanDone()
+            throws Exception {
+        mDsc = createConnection(mPhone, SELECTOR_TYPE_CALLING, true,
+                mDomainSelectionController);
+
+        ITransportSelectorCallback transportCallback = mDsc.getTransportSelectorCallback();
+
+        assertNotNull(transportCallback);
+
+        DomainSelectionService.SelectionAttributes attr = getSelectionAttributes(
+                mPhone.getPhoneId(), mPhone.getSubId(), SELECTOR_TYPE_CALLING, true,
+                false, 0, TELECOM_CALL_ID1, null, null, null);
+
+        mDsc.selectDomain(attr);
+
+        IDomainSelector domainSelector = Mockito.mock(IDomainSelector.class);
+        transportCallback.onCreated(domainSelector);
+
+        IWwanSelectorCallback wwanCallback = onWwanSelected(transportCallback);
+
+        assertNotNull(wwanCallback);
+
+        int[] preferredNetworks = new int[] { EUTRAN, UTRAN };
+        int scanType = SCAN_TYPE_FULL_SERVICE;
+        IWwanSelectorResultCallback resultCallback =
+                Mockito.mock(IWwanSelectorResultCallback.class);
+
+        wwanCallback.onRequestEmergencyNetworkScan(preferredNetworks, scanType, false,
+                resultCallback);
+        processAllMessages();
+
+        ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
+        ArgumentCaptor<Integer> scanEventCaptor = ArgumentCaptor.forClass(Integer.class);
+        ArgumentCaptor<Integer> resetEventCaptor = ArgumentCaptor.forClass(Integer.class);
+
+        verify(mPhone).registerForEmergencyNetworkScan(any(), scanEventCaptor.capture(), any());
+        verify(mCi).registerForModemReset(handlerCaptor.capture(),
+                resetEventCaptor.capture(), any());
+        processAllMessages();
+
+        int[] expectedPreferredNetworks = new int[] { EUTRAN, UTRAN };
+
+        verify(mPhone).triggerEmergencyNetworkScan(eq(expectedPreferredNetworks),
+                eq(scanType), any());
+
+        Handler handler = handlerCaptor.getValue();
+        Integer scanEvent = scanEventCaptor.getValue();
+        Integer resetEvent = resetEventCaptor.getValue();
+
+        assertNotNull(handler);
+        assertNotNull(scanEvent);
+        assertNotNull(resetEvent);
+
+        EmergencyRegistrationResult regResult =
+                new EmergencyRegistrationResult(UTRAN, 0, 0, true, false, 0, 0, "", "", "");
+        handler.sendMessage(handler.obtainMessage(scanEvent,
+                new AsyncResult(null, regResult, null)));
+        processAllMessages();
+        wwanCallback.onDomainSelected(NetworkRegistrationInfo.DOMAIN_CS_PS, true);
+
+        handler.sendMessage(handler.obtainMessage(resetEvent, new AsyncResult(null, null, null)));
+        processAllMessages();
+
+        verify(resultCallback).onComplete(any());
+        verify(mPhone, times(0)).unregisterForEmergencyNetworkScan(any());
+        verify(mCi, times(0)).unregisterForModemReset(any());
+        verify(mPhone, times(0)).cancelEmergencyNetworkScan(anyBoolean(), any());
+    }
+
+    @Test
+    @SmallTest
     public void testDomainSelectorCancelSelection() throws Exception {
         mDsc = createConnection(mPhone, SELECTOR_TYPE_CALLING, true,
                 mDomainSelectionController);
@@ -601,6 +876,7 @@
 
         verify(mPhone).registerForEmergencyNetworkScan(
                 handlerCaptor.capture(), eventCaptor.capture(), any());
+        verify(mCi).registerForModemReset(any(), anyInt(), any());
 
         int[] expectedPreferredNetworks = new int[] { EUTRAN, UTRAN };
 
@@ -686,6 +962,7 @@
 
         verify(mPhone).registerForEmergencyNetworkScan(
                 handlerCaptor.capture(), eventCaptor.capture(), any());
+        verify(mCi).registerForModemReset(any(), anyInt(), any());
 
         int[] expectedPreferredNetworks = new int[] { EUTRAN, UTRAN };
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsNrSaModeHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsNrSaModeHandlerTest.java
index 3b362b1..8cf422e 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsNrSaModeHandlerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsNrSaModeHandlerTest.java
@@ -16,7 +16,6 @@
 
 package com.android.internal.telephony.imsphone;
 
-import static android.telephony.CarrierConfigManager.CARRIER_NR_AVAILABILITY_NSA;
 import static android.telephony.CarrierConfigManager.CARRIER_NR_AVAILABILITY_SA;
 import static android.telephony.CarrierConfigManager.Ims.KEY_NR_SA_DISABLE_POLICY_INT;
 import static android.telephony.CarrierConfigManager.Ims.NR_SA_DISABLE_POLICY_NONE;
@@ -24,6 +23,7 @@
 import static android.telephony.CarrierConfigManager.Ims.NR_SA_DISABLE_POLICY_WFC_ESTABLISHED;
 import static android.telephony.CarrierConfigManager.Ims.NR_SA_DISABLE_POLICY_WFC_ESTABLISHED_WHEN_VONR_DISABLED;
 import static android.telephony.CarrierConfigManager.KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY;
+import static android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE;
 import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN;
 import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
 
@@ -32,6 +32,7 @@
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
 import android.os.Handler;
@@ -55,7 +56,6 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-import java.util.Arrays;
 import java.util.Set;
 
 @RunWith(AndroidTestingRunner.class)
@@ -69,7 +69,7 @@
     private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener;
     private Handler mPreciseCallStateHandler;
 
-    private Phone mPassthroughPhone;
+    private Phone mDefaultPhone;
 
     @Mock private ImsPhoneCall mForegroundCall;
     @Mock private ImsPhoneCall mBackgroundCall;
@@ -77,8 +77,7 @@
     private Call.State mIdleState = ImsPhoneCall.State.IDLE;
 
     private int mAnyInt = 0;
-    private final Set<String> mFeatureTags =
-            new ArraySet<String>(Arrays.asList(ImsNrSaModeHandler.MMTEL_FEATURE_TAG));
+    private final Set<String> mFeatureTags = new ArraySet<String>();
 
     @Before
     public void setUp() throws Exception {
@@ -96,12 +95,12 @@
         doReturn(mContextFixture.getCarrierConfigBundle()).when(mCarrierConfigManager)
                 .getConfigForSubId(anyInt(), any());
 
-        mPassthroughPhone = new GsmCdmaPhone(
+        mDefaultPhone = new GsmCdmaPhone(
                 mContext, mSimulatedCommands, mNotifier, true, 0,
                 PhoneConstants.PHONE_TYPE_GSM, mTelephonyComponentFactory,
                 (c, p) -> mImsManager, mFeatureFlags);
 
-        doReturn(mPassthroughPhone).when(mImsPhone).getDefaultPhone();
+        doReturn(mDefaultPhone).when(mImsPhone).getDefaultPhone();
 
         doReturn(mForegroundCall).when(mImsPhone).getForegroundCall();
         doReturn(mBackgroundCall).when(mImsPhone).getBackgroundCall();
@@ -140,19 +139,19 @@
     }
 
     @Test
-    public void testOnImsRegisteredWithSaDisablePolicyNone() {
+    public void testOnImsRegisteredWithNrSaCapabilityAndVoiceCapabilityAndSaDisablePolicyNone() {
         mContextFixture.getCarrierConfigBundle().putInt(
                 KEY_NR_SA_DISABLE_POLICY_INT, NR_SA_DISABLE_POLICY_NONE);
         mContextFixture.getCarrierConfigBundle().putIntArray(
                 KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{CARRIER_NR_AVAILABILITY_SA});
 
         mCarrierConfigChangeListener.onCarrierConfigChanged(mAnyInt, mAnyInt, mAnyInt, mAnyInt);
-
-        mTestImsNrSaModeHandler.setVowifiRegStatus(false);
+        mTestImsNrSaModeHandler.updateImsCapability(CAPABILITY_TYPE_VOICE);
+        mTestImsNrSaModeHandler.setWifiRegStatus(false);
 
         mTestImsNrSaModeHandler.onImsRegistered(REGISTRATION_TECH_IWLAN, mFeatureTags);
 
-        assertFalse(mTestImsNrSaModeHandler.isVowifiRegistered());
+        assertFalse(mTestImsNrSaModeHandler.isWifiRegistered());
     }
 
     @Test
@@ -163,17 +162,24 @@
                 KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{CARRIER_NR_AVAILABILITY_SA});
 
         mCarrierConfigChangeListener.onCarrierConfigChanged(mAnyInt, mAnyInt, mAnyInt, mAnyInt);
+        mTestImsNrSaModeHandler.updateImsCapability(CAPABILITY_TYPE_VOICE);
 
         verify(mImsPhone).registerForPreciseCallStateChanged(any(), anyInt(), any());
 
         mSimulatedCommands.setN1ModeEnabled(false, null);
-        mTestImsNrSaModeHandler.setVowifiRegStatus(true);
+        mTestImsNrSaModeHandler.setNrSaDisabledForWfc(true);
+        mTestImsNrSaModeHandler.setWifiRegStatus(true);
         mTestImsNrSaModeHandler.setImsCallStatus(true);
 
         mTestImsNrSaModeHandler.onImsRegistered(REGISTRATION_TECH_NONE, mFeatureTags);
 
-        assertFalse(mTestImsNrSaModeHandler.isVowifiRegistered());
         assertTrue(mSimulatedCommands.isN1ModeEnabled());
+        assertFalse(mTestImsNrSaModeHandler.isWifiRegistered());
+
+        mTestImsNrSaModeHandler.onImsRegistered(REGISTRATION_TECH_IWLAN, mFeatureTags);
+
+        assertFalse(mSimulatedCommands.isN1ModeEnabled());
+        assertTrue(mTestImsNrSaModeHandler.isWifiRegistered());
     }
 
     @Test
@@ -185,54 +191,42 @@
                 KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{CARRIER_NR_AVAILABILITY_SA});
 
         mCarrierConfigChangeListener.onCarrierConfigChanged(mAnyInt, mAnyInt, mAnyInt, mAnyInt);
+        mTestImsNrSaModeHandler.updateImsCapability(CAPABILITY_TYPE_VOICE);
 
         verify(mImsPhone).registerForPreciseCallStateChanged(any(), anyInt(), any());
 
         mSimulatedCommands.setN1ModeEnabled(true, null);
-        mTestImsNrSaModeHandler.setVowifiRegStatus(false);
+        mTestImsNrSaModeHandler.setWifiRegStatus(false);
         mTestImsNrSaModeHandler.setImsCallStatus(true);
         mSimulatedCommands.setVonrEnabled(true);
 
         mTestImsNrSaModeHandler.onImsRegistered(REGISTRATION_TECH_IWLAN, mFeatureTags);
         processAllMessages();
 
-        assertTrue(mTestImsNrSaModeHandler.isVowifiRegistered());
         assertTrue(mSimulatedCommands.isN1ModeEnabled());
+        assertTrue(mTestImsNrSaModeHandler.isWifiRegistered());
 
         mSimulatedCommands.setN1ModeEnabled(true, null);
-        mTestImsNrSaModeHandler.setVowifiRegStatus(false);
+        mTestImsNrSaModeHandler.setWifiRegStatus(false);
         mTestImsNrSaModeHandler.setImsCallStatus(true);
         mSimulatedCommands.setVonrEnabled(false);
 
         mTestImsNrSaModeHandler.onImsRegistered(REGISTRATION_TECH_IWLAN, mFeatureTags);
         processAllMessages();
 
-        assertTrue(mTestImsNrSaModeHandler.isVowifiRegistered());
         assertFalse(mSimulatedCommands.isN1ModeEnabled());
+        assertTrue(mTestImsNrSaModeHandler.isWifiRegistered());
 
         mSimulatedCommands.setN1ModeEnabled(true, null);
-        mTestImsNrSaModeHandler.setVowifiRegStatus(false);
+        mTestImsNrSaModeHandler.setWifiRegStatus(false);
         mTestImsNrSaModeHandler.setImsCallStatus(true);
-        mSimulatedCommands.setVonrEnabled(false);
+        mSimulatedCommands.setVonrEnabled(true);
 
-        mFeatureTags.remove(ImsNrSaModeHandler.MMTEL_FEATURE_TAG);
-        mTestImsNrSaModeHandler.onImsRegistered(REGISTRATION_TECH_IWLAN, mFeatureTags);
+        mTestImsNrSaModeHandler.onImsRegistered(REGISTRATION_TECH_NONE, mFeatureTags);
         processAllMessages();
 
-        assertFalse(mTestImsNrSaModeHandler.isVowifiRegistered());
         assertTrue(mSimulatedCommands.isN1ModeEnabled());
-
-        mSimulatedCommands.setN1ModeEnabled(true, null);
-        mTestImsNrSaModeHandler.setVowifiRegStatus(false);
-        mTestImsNrSaModeHandler.setImsCallStatus(true);
-        mSimulatedCommands.setVonrEnabled(false);
-
-        mFeatureTags.add(ImsNrSaModeHandler.MMTEL_FEATURE_TAG);
-        mTestImsNrSaModeHandler.onImsRegistered(REGISTRATION_TECH_IWLAN, mFeatureTags);
-        processAllMessages();
-
-        assertTrue(mTestImsNrSaModeHandler.isVowifiRegistered());
-        assertFalse(mSimulatedCommands.isN1ModeEnabled());
+        assertFalse(mTestImsNrSaModeHandler.isWifiRegistered());
     }
 
     @Test
@@ -243,26 +237,50 @@
                 KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{CARRIER_NR_AVAILABILITY_SA});
 
         mCarrierConfigChangeListener.onCarrierConfigChanged(mAnyInt, mAnyInt, mAnyInt, mAnyInt);
+        mTestImsNrSaModeHandler.updateImsCapability(CAPABILITY_TYPE_VOICE);
+
+        verify(mImsPhone).unregisterForPreciseCallStateChanged(mTestImsNrSaModeHandler);
 
         mSimulatedCommands.setN1ModeEnabled(true, null);
-        mTestImsNrSaModeHandler.setVowifiRegStatus(false);
+        mTestImsNrSaModeHandler.setWifiRegStatus(false);
 
         mTestImsNrSaModeHandler.onImsRegistered(REGISTRATION_TECH_IWLAN, mFeatureTags);
 
-        assertTrue(mTestImsNrSaModeHandler.isVowifiRegistered());
         assertFalse(mSimulatedCommands.isN1ModeEnabled());
+        assertTrue(mTestImsNrSaModeHandler.isWifiRegistered());
 
         mSimulatedCommands.setN1ModeEnabled(false, null);
-        mTestImsNrSaModeHandler.setVowifiRegStatus(true);
+        mTestImsNrSaModeHandler.setWifiRegStatus(true);
 
         mTestImsNrSaModeHandler.onImsRegistered(REGISTRATION_TECH_NONE, mFeatureTags);
 
-        assertFalse(mTestImsNrSaModeHandler.isVowifiRegistered());
         assertTrue(mSimulatedCommands.isN1ModeEnabled());
+        assertFalse(mTestImsNrSaModeHandler.isWifiRegistered());
     }
 
     @Test
-    public void testOnImsUnregisteredDoNothingIfNotVowifiRegNoti() {
+    public void testOnImsRegisteredWithoutNrSaCapabilityWithSaDisablePolicyVowifiRegistered() {
+        mContextFixture.getCarrierConfigBundle().putInt(
+                KEY_NR_SA_DISABLE_POLICY_INT, NR_SA_DISABLE_POLICY_VOWIFI_REGISTERED);
+        mContextFixture.getCarrierConfigBundle().putIntArray(
+                KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{});
+
+        mCarrierConfigChangeListener.onCarrierConfigChanged(mAnyInt, mAnyInt, mAnyInt, mAnyInt);
+        mTestImsNrSaModeHandler.updateImsCapability(CAPABILITY_TYPE_VOICE);
+
+        verify(mImsPhone, times(0)).unregisterForPreciseCallStateChanged(mTestImsNrSaModeHandler);
+
+        mSimulatedCommands.setN1ModeEnabled(true, null);
+        mTestImsNrSaModeHandler.setWifiRegStatus(false);
+
+        mTestImsNrSaModeHandler.onImsRegistered(REGISTRATION_TECH_IWLAN, mFeatureTags);
+
+        assertTrue(mSimulatedCommands.isN1ModeEnabled());
+        assertFalse(mTestImsNrSaModeHandler.isWifiRegistered());
+    }
+
+    @Test
+    public void testOnImsRegisteredWithoutVoiceCapabilityWithSaDisablePolicyVowifiRegistered() {
         mContextFixture.getCarrierConfigBundle().putInt(
                 KEY_NR_SA_DISABLE_POLICY_INT, NR_SA_DISABLE_POLICY_VOWIFI_REGISTERED);
         mContextFixture.getCarrierConfigBundle().putIntArray(
@@ -270,37 +288,100 @@
 
         mCarrierConfigChangeListener.onCarrierConfigChanged(mAnyInt, mAnyInt, mAnyInt, mAnyInt);
 
-        mTestImsNrSaModeHandler.setVowifiRegStatus(true);
+        verify(mImsPhone).unregisterForPreciseCallStateChanged(mTestImsNrSaModeHandler);
 
-        mTestImsNrSaModeHandler.onImsUnregistered(REGISTRATION_TECH_NONE);
+        mSimulatedCommands.setN1ModeEnabled(true, null);
+        mTestImsNrSaModeHandler.setWifiRegStatus(false);
 
-        assertTrue(mTestImsNrSaModeHandler.isVowifiRegistered());
+        mTestImsNrSaModeHandler.onImsRegistered(REGISTRATION_TECH_IWLAN, mFeatureTags);
+
+        assertTrue(mSimulatedCommands.isN1ModeEnabled());
+        assertTrue(mTestImsNrSaModeHandler.isWifiRegistered());
     }
 
     @Test
-    public void testOnImsUnregisteredWithSaDisablePolicyVowifiRegistered() {
+    public void testOnImsUnregisteredWithoutNrSaCapability() {
         mContextFixture.getCarrierConfigBundle().putInt(
                 KEY_NR_SA_DISABLE_POLICY_INT, NR_SA_DISABLE_POLICY_VOWIFI_REGISTERED);
         mContextFixture.getCarrierConfigBundle().putIntArray(
-                KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{CARRIER_NR_AVAILABILITY_SA});
+                KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{});
 
         mCarrierConfigChangeListener.onCarrierConfigChanged(mAnyInt, mAnyInt, mAnyInt, mAnyInt);
 
-        mSimulatedCommands.setN1ModeEnabled(false, null);
-        mTestImsNrSaModeHandler.setVowifiRegStatus(true);
+        mTestImsNrSaModeHandler.setWifiRegStatus(true);
 
         mTestImsNrSaModeHandler.onImsUnregistered(REGISTRATION_TECH_IWLAN);
 
-        assertFalse(mTestImsNrSaModeHandler.isVowifiRegistered());
-        assertTrue(mSimulatedCommands.isN1ModeEnabled());
+        assertTrue(mTestImsNrSaModeHandler.isWifiRegistered());
+    }
+
+
+    @Test
+    public void testOnImsUnregisteredWithSaDisablePolicyNone() {
+        mContextFixture.getCarrierConfigBundle().putInt(
+                KEY_NR_SA_DISABLE_POLICY_INT, NR_SA_DISABLE_POLICY_NONE);
+        mContextFixture.getCarrierConfigBundle().putIntArray(
+                KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{CARRIER_NR_AVAILABILITY_SA});
+
+        mCarrierConfigChangeListener.onCarrierConfigChanged(mAnyInt, mAnyInt, mAnyInt, mAnyInt);
+
+        mTestImsNrSaModeHandler.setWifiRegStatus(true);
+
+        mTestImsNrSaModeHandler.onImsUnregistered(REGISTRATION_TECH_IWLAN);
+
+        assertTrue(mTestImsNrSaModeHandler.isWifiRegistered());
+    }
+
+    @Test
+    public void testOnImsUnregisteredWithoutRadioTechIwlan() {
+        mContextFixture.getCarrierConfigBundle().putInt(
+                KEY_NR_SA_DISABLE_POLICY_INT, NR_SA_DISABLE_POLICY_VOWIFI_REGISTERED);
+        mContextFixture.getCarrierConfigBundle().putIntArray(
+                KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{CARRIER_NR_AVAILABILITY_SA});
+
+        mCarrierConfigChangeListener.onCarrierConfigChanged(mAnyInt, mAnyInt, mAnyInt, mAnyInt);
+
+        mTestImsNrSaModeHandler.setWifiRegStatus(true);
+
+        mTestImsNrSaModeHandler.onImsUnregistered(NR_SA_DISABLE_POLICY_NONE);
+
+        assertTrue(mTestImsNrSaModeHandler.isWifiRegistered());
+    }
+
+    @Test
+    public void testOnImsUnregisteredWithoutWifiResistring() {
+        mContextFixture.getCarrierConfigBundle().putInt(
+                KEY_NR_SA_DISABLE_POLICY_INT, NR_SA_DISABLE_POLICY_VOWIFI_REGISTERED);
+        mContextFixture.getCarrierConfigBundle().putIntArray(
+                KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{CARRIER_NR_AVAILABILITY_SA});
+
+        mCarrierConfigChangeListener.onCarrierConfigChanged(mAnyInt, mAnyInt, mAnyInt, mAnyInt);
+
+        mTestImsNrSaModeHandler.setWifiRegStatus(false);
+
+        mTestImsNrSaModeHandler.onImsUnregistered(REGISTRATION_TECH_IWLAN);
+
+        assertFalse(mTestImsNrSaModeHandler.isWifiRegistered());
+    }
+
+    @Test
+    public void testOnImsUnregisteredWithNrSaCapabilityAndVoiceCapabilityAndRadioTechIwlan() {
+        mContextFixture.getCarrierConfigBundle().putInt(
+                KEY_NR_SA_DISABLE_POLICY_INT, NR_SA_DISABLE_POLICY_VOWIFI_REGISTERED);
+        mContextFixture.getCarrierConfigBundle().putIntArray(
+                KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{CARRIER_NR_AVAILABILITY_SA});
+
+        mCarrierConfigChangeListener.onCarrierConfigChanged(mAnyInt, mAnyInt, mAnyInt, mAnyInt);
+        mTestImsNrSaModeHandler.updateImsCapability(CAPABILITY_TYPE_VOICE);
 
         mSimulatedCommands.setN1ModeEnabled(false, null);
-        mTestImsNrSaModeHandler.setVowifiRegStatus(true);
+        mTestImsNrSaModeHandler.setNrSaDisabledForWfc(true);
+        mTestImsNrSaModeHandler.setWifiRegStatus(true);
 
-        mTestImsNrSaModeHandler.onImsUnregistered(REGISTRATION_TECH_NONE);
+        mTestImsNrSaModeHandler.onImsUnregistered(REGISTRATION_TECH_IWLAN);
 
-        assertTrue(mTestImsNrSaModeHandler.isVowifiRegistered());
-        assertFalse(mSimulatedCommands.isN1ModeEnabled());
+        assertTrue(mSimulatedCommands.isN1ModeEnabled());
+        assertFalse(mTestImsNrSaModeHandler.isWifiRegistered());
     }
 
     @Test
@@ -311,12 +392,13 @@
                 KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{CARRIER_NR_AVAILABILITY_SA});
 
         mCarrierConfigChangeListener.onCarrierConfigChanged(mAnyInt, mAnyInt, mAnyInt, mAnyInt);
+        mTestImsNrSaModeHandler.updateImsCapability(CAPABILITY_TYPE_VOICE);
 
         verify(mImsPhone).registerForPreciseCallStateChanged(
                 mPreciseCallStateHandlerCaptor.capture(), anyInt(), any());
         mPreciseCallStateHandler = mPreciseCallStateHandlerCaptor.getValue();
 
-        mTestImsNrSaModeHandler.setVowifiRegStatus(true);
+        mTestImsNrSaModeHandler.setWifiRegStatus(true);
         mSimulatedCommands.setN1ModeEnabled(true, null);
 
         mPreciseCallStateHandler.handleMessage(mPreciseCallStateHandler.obtainMessage(101));
@@ -324,38 +406,55 @@
         assertTrue(mTestImsNrSaModeHandler.isImsCallOngoing());
         assertFalse(mSimulatedCommands.isN1ModeEnabled());
 
-        mTestImsNrSaModeHandler.setVowifiRegStatus(false);
-        mSimulatedCommands.setN1ModeEnabled(true, null);
-
-        doReturn(mActiveState).when(mForegroundCall).getState();
-        doReturn(mActiveState).when(mBackgroundCall).getState();
-        mPreciseCallStateHandler.handleMessage(mPreciseCallStateHandler.obtainMessage(101));
-
-        assertTrue(mTestImsNrSaModeHandler.isImsCallOngoing());
-        assertTrue(mSimulatedCommands.isN1ModeEnabled());
-
-        mTestImsNrSaModeHandler.setVowifiRegStatus(false);
-        mTestImsNrSaModeHandler.setImsCallStatus(false);
-        mSimulatedCommands.setN1ModeEnabled(true, null);
-
         doReturn(mIdleState).when(mForegroundCall).getState();
         doReturn(mIdleState).when(mBackgroundCall).getState();
         mPreciseCallStateHandler.handleMessage(mPreciseCallStateHandler.obtainMessage(101));
 
         assertFalse(mTestImsNrSaModeHandler.isImsCallOngoing());
         assertTrue(mSimulatedCommands.isN1ModeEnabled());
-
-        mTestImsNrSaModeHandler.setVowifiRegStatus(true);
-        mTestImsNrSaModeHandler.setImsCallStatus(true);
-        mSimulatedCommands.setN1ModeEnabled(false, null);
-        mPreciseCallStateHandler.handleMessage(mPreciseCallStateHandler.obtainMessage(101));
-
-        assertFalse(mTestImsNrSaModeHandler.isImsCallOngoing());
-        assertTrue(mSimulatedCommands.isN1ModeEnabled());
     }
 
     @Test
-    public void testUnregisterForPreciseCallStateChangeIfNeeded() {
+    public void testOnPreciseCallStateChangedWithSaDisablePolicyWfcEstablishedWithVonrDisabled() {
+        mContextFixture.getCarrierConfigBundle().putInt(
+                KEY_NR_SA_DISABLE_POLICY_INT,
+                NR_SA_DISABLE_POLICY_WFC_ESTABLISHED_WHEN_VONR_DISABLED);
+        mContextFixture.getCarrierConfigBundle().putIntArray(
+                KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{CARRIER_NR_AVAILABILITY_SA});
+
+        mCarrierConfigChangeListener.onCarrierConfigChanged(mAnyInt, mAnyInt, mAnyInt, mAnyInt);
+        mTestImsNrSaModeHandler.updateImsCapability(CAPABILITY_TYPE_VOICE);
+
+        verify(mImsPhone).registerForPreciseCallStateChanged(
+                mPreciseCallStateHandlerCaptor.capture(), anyInt(), any());
+        mPreciseCallStateHandler = mPreciseCallStateHandlerCaptor.getValue();
+
+        mTestImsNrSaModeHandler.setWifiRegStatus(true);
+        mSimulatedCommands.setN1ModeEnabled(true, null);
+        mSimulatedCommands.setVonrEnabled(false);
+
+        mPreciseCallStateHandler.handleMessage(mPreciseCallStateHandler.obtainMessage(101));
+        processAllMessages();
+
+        assertFalse(mSimulatedCommands.isN1ModeEnabled());
+
+        doReturn(mIdleState).when(mForegroundCall).getState();
+        doReturn(mIdleState).when(mBackgroundCall).getState();
+        mPreciseCallStateHandler.handleMessage(mPreciseCallStateHandler.obtainMessage(101));
+
+        assertTrue(mSimulatedCommands.isN1ModeEnabled());
+
+        doReturn(mActiveState).when(mForegroundCall).getState();
+        doReturn(mActiveState).when(mBackgroundCall).getState();
+        mPreciseCallStateHandler.handleMessage(mPreciseCallStateHandler.obtainMessage(101));
+        mTestImsNrSaModeHandler.setImsCallStatus(false);
+        processAllMessages();
+
+        assertTrue(mSimulatedCommands.isN1ModeEnabled());
+    }
+
+    @Test
+    public void testOnCarrierConfigChangedRegisterOrUnregisterListenerForPreciseCallStateChange() {
         mContextFixture.getCarrierConfigBundle().putInt(
                 KEY_NR_SA_DISABLE_POLICY_INT, NR_SA_DISABLE_POLICY_WFC_ESTABLISHED);
         mContextFixture.getCarrierConfigBundle().putIntArray(
@@ -376,20 +475,29 @@
     }
 
     @Test
-    public void testNrSaModeIsNotHandledWhenNotSupported() {
+    public void testUpdateImsCapabilityWithSaDisablePolicyWfcEstablished() {
         mContextFixture.getCarrierConfigBundle().putInt(
                 KEY_NR_SA_DISABLE_POLICY_INT, NR_SA_DISABLE_POLICY_WFC_ESTABLISHED);
         mContextFixture.getCarrierConfigBundle().putIntArray(
-                KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{CARRIER_NR_AVAILABILITY_NSA});
+                KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY, new int[]{CARRIER_NR_AVAILABILITY_SA});
 
         mCarrierConfigChangeListener.onCarrierConfigChanged(mAnyInt, mAnyInt, mAnyInt, mAnyInt);
 
-        mSimulatedCommands.setN1ModeEnabled(false, null);
-        mTestImsNrSaModeHandler.setVowifiRegStatus(true);
+        verify(mImsPhone).registerForPreciseCallStateChanged(
+                mPreciseCallStateHandlerCaptor.capture(), anyInt(), any());
+        mPreciseCallStateHandler = mPreciseCallStateHandlerCaptor.getValue();
 
-        mTestImsNrSaModeHandler.onImsRegistered(REGISTRATION_TECH_NONE, mFeatureTags);
+        mTestImsNrSaModeHandler.setWifiRegStatus(true);
+        mSimulatedCommands.setN1ModeEnabled(true, null);
+        mPreciseCallStateHandler.handleMessage(mPreciseCallStateHandler.obtainMessage(101));
 
-        assertFalse(mTestImsNrSaModeHandler.isVowifiRegistered());
+        assertTrue(mTestImsNrSaModeHandler.isImsCallOngoing());
+        assertTrue(mSimulatedCommands.isN1ModeEnabled());
+
+        mTestImsNrSaModeHandler.updateImsCapability(CAPABILITY_TYPE_VOICE);
         assertFalse(mSimulatedCommands.isN1ModeEnabled());
+
+        mTestImsNrSaModeHandler.updateImsCapability(0);
+        assertTrue(mSimulatedCommands.isN1ModeEnabled());
     }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java
index b62d9e1..c986be4 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java
@@ -1146,6 +1146,8 @@
         mSatelliteController1.countOfDemoModeIncomingDatagramFail = 2;
         mSatelliteController1.countOfDatagramTypeKeepAliveSuccess = 1;
         mSatelliteController1.countOfDatagramTypeKeepAliveFail = 2;
+        mSatelliteController1.isProvisioned = true;
+        mSatelliteController1.carrierId = 1;
 
         mSatelliteController2 = new SatelliteController();
         mSatelliteController2.countOfSatelliteServiceEnablementsSuccess = 2 + 1;
@@ -1173,6 +1175,8 @@
         mSatelliteController2.countOfDemoModeIncomingDatagramFail = 3;
         mSatelliteController2.countOfDatagramTypeKeepAliveSuccess = 4;
         mSatelliteController2.countOfDatagramTypeKeepAliveFail = 5;
+        mSatelliteController2.isProvisioned = false;
+        mSatelliteController2.carrierId = 10;
 
         // SatelliteController atom has one data point
         mSatelliteControllers =
@@ -1197,6 +1201,10 @@
         mSatelliteSession1.countOfIncomingDatagramFailed = 0;
         mSatelliteSession1.isDemoMode = false;
         mSatelliteSession1.maxNtnSignalStrengthLevel = 2;
+        mSatelliteSession1.carrierId = 2;
+        mSatelliteSession1.countOfSatelliteNotificationDisplayed = 4;
+        mSatelliteSession1.countOfAutoExitDueToScreenOff = 6;
+        mSatelliteSession1.countOfAutoExitDueToTnNetwork = 7;
 
         mSatelliteSession2 = new SatelliteSession();
         mSatelliteSession2.satelliteServiceInitializationResult =
@@ -1215,6 +1223,10 @@
         mSatelliteSession2.countOfIncomingDatagramFailed = 1;
         mSatelliteSession2.isDemoMode = true;
         mSatelliteSession2.maxNtnSignalStrengthLevel = 4;
+        mSatelliteSession2.carrierId = 20;
+        mSatelliteSession2.countOfSatelliteNotificationDisplayed = 40;
+        mSatelliteSession2.countOfAutoExitDueToScreenOff = 60;
+        mSatelliteSession2.countOfAutoExitDueToTnNetwork = 70;
 
         mSatelliteSessions =
                 new SatelliteSession[] {
@@ -1226,12 +1238,14 @@
         mSatelliteIncomingDatagram1.datagramSizeBytes = 1 * 1024;
         mSatelliteIncomingDatagram1.datagramTransferTimeMillis = 3 * 1000;
         mSatelliteIncomingDatagram1.isDemoMode = false;
+        mSatelliteIncomingDatagram1.carrierId = 1;
 
         mSatelliteIncomingDatagram2 = new SatelliteIncomingDatagram();
         mSatelliteIncomingDatagram2.resultCode = SatelliteProtoEnums.SATELLITE_RESULT_MODEM_ERROR;
         mSatelliteIncomingDatagram2.datagramSizeBytes = 512;
         mSatelliteIncomingDatagram2.datagramTransferTimeMillis = 1 * 1000;
-        mSatelliteIncomingDatagram1.isDemoMode = true;
+        mSatelliteIncomingDatagram2.isDemoMode = true;
+        mSatelliteIncomingDatagram2.carrierId = 10;
 
         mSatelliteIncomingDatagrams =
                 new SatelliteIncomingDatagram[] {
@@ -1245,6 +1259,7 @@
         mSatelliteOutgoingDatagram1.datagramSizeBytes = 1 * 1024;
         mSatelliteOutgoingDatagram1.datagramTransferTimeMillis = 3 * 1000;
         mSatelliteOutgoingDatagram1.isDemoMode = false;
+        mSatelliteOutgoingDatagram1.carrierId = 1;
 
         mSatelliteOutgoingDatagram2 = new SatelliteOutgoingDatagram();
         mSatelliteOutgoingDatagram2.datagramType =
@@ -1252,7 +1267,8 @@
         mSatelliteOutgoingDatagram2.resultCode = SatelliteProtoEnums.SATELLITE_RESULT_MODEM_ERROR;
         mSatelliteOutgoingDatagram2.datagramSizeBytes = 512;
         mSatelliteOutgoingDatagram2.datagramTransferTimeMillis = 1 * 1000;
-        mSatelliteOutgoingDatagram1.isDemoMode = true;
+        mSatelliteOutgoingDatagram2.isDemoMode = true;
+        mSatelliteOutgoingDatagram2.carrierId = 10;
 
         mSatelliteOutgoingDatagrams =
                 new SatelliteOutgoingDatagram[] {
@@ -1264,6 +1280,7 @@
         mSatelliteProvision1.provisioningTimeSec = 3 * 60;
         mSatelliteProvision1.isProvisionRequest = true;
         mSatelliteProvision1.isCanceled = false;
+        mSatelliteProvision1.carrierId = 1;
 
         mSatelliteProvision2 = new SatelliteProvision();
         mSatelliteProvision2.resultCode =
@@ -1271,6 +1288,7 @@
         mSatelliteProvision2.provisioningTimeSec = 0;
         mSatelliteProvision2.isProvisionRequest = false;
         mSatelliteProvision2.isCanceled = true;
+        mSatelliteProvision2.carrierId = 10;
 
         mSatelliteProvisions =
                 new SatelliteProvision[] {
@@ -1286,6 +1304,8 @@
         mSatelliteSosMessageRecommender1.isMultiSim = true;
         mSatelliteSosMessageRecommender1.recommendingHandoverType = 1;
         mSatelliteSosMessageRecommender1.isSatelliteAllowedInCurrentLocation = true;
+        mSatelliteSosMessageRecommender1.isWifiConnected = true;
+        mSatelliteSosMessageRecommender1.carrierId = 1;
         mSatelliteSosMessageRecommender1.count = 1;
 
         mSatelliteSosMessageRecommender2 = new SatelliteSosMessageRecommender();
@@ -1297,6 +1317,9 @@
         mSatelliteSosMessageRecommender2.isMultiSim = false;
         mSatelliteSosMessageRecommender2.recommendingHandoverType = 0;
         mSatelliteSosMessageRecommender2.isSatelliteAllowedInCurrentLocation = true;
+        mSatelliteSosMessageRecommender2.isWifiConnected = false;
+        mSatelliteSosMessageRecommender2.carrierId = 2;
+
         mSatelliteSosMessageRecommender2.count = 1;
 
         mSatelliteSosMessageRecommenders =
@@ -1352,6 +1375,7 @@
         mCarrierRoamingSatelliteControllerStats1.satelliteSessionGapMinSec = 2;
         mCarrierRoamingSatelliteControllerStats1.satelliteSessionGapAvgSec = 3;
         mCarrierRoamingSatelliteControllerStats1.satelliteSessionGapMaxSec = 4;
+        mCarrierRoamingSatelliteControllerStats1.carrierId = 1;
 
         mCarrierRoamingSatelliteControllerStats2 = new CarrierRoamingSatelliteControllerStats();
         mCarrierRoamingSatelliteControllerStats2.configDataSource =
@@ -1362,6 +1386,7 @@
         mCarrierRoamingSatelliteControllerStats2.satelliteSessionGapMinSec = 5;
         mCarrierRoamingSatelliteControllerStats2.satelliteSessionGapAvgSec = 10;
         mCarrierRoamingSatelliteControllerStats2.satelliteSessionGapMaxSec = 15;
+        mCarrierRoamingSatelliteControllerStats2.carrierId = 10;
 
         // CarrierRoamingSatelliteController has one data point
         mCarrierRoamingSatelliteControllerStats = new CarrierRoamingSatelliteControllerStats[] {
@@ -1380,7 +1405,7 @@
         mSatelliteEntitlement2.result = 1;
         mSatelliteEntitlement2.entitlementStatus =
                 SatelliteProtoEnums.SATELLITE_ENTITLEMENT_STATUS_DISABLED;
-        mSatelliteEntitlement1.isRetry = true;
+        mSatelliteEntitlement2.isRetry = true;
         mSatelliteEntitlement2.count = 1;
 
         mSatelliteEntitlements = new SatelliteEntitlement[] {mSatelliteEntitlement1,
@@ -1414,10 +1439,11 @@
         mSatelliteAccessController1.resultCode = SATELLITE_RESULT_SUCCESS;
         mSatelliteAccessController1.countryCodes = new String[]{"AB", "CD"};
         mSatelliteAccessController1.configDataSource = CONFIG_DATA_SOURCE_DEVICE_CONFIG;
+        mSatelliteAccessController1.carrierId = 1;
 
         mSatelliteAccessController2 = new SatelliteAccessController();
-        mSatelliteAccessController1.accessControlType = ACCESS_CONTROL_TYPE_CURRENT_LOCATION;
-        mSatelliteAccessController1.locationQueryTimeMillis = TimeUnit.SECONDS.toMillis(4);
+        mSatelliteAccessController2.accessControlType = ACCESS_CONTROL_TYPE_CURRENT_LOCATION;
+        mSatelliteAccessController2.locationQueryTimeMillis = TimeUnit.SECONDS.toMillis(4);
         mSatelliteAccessController2.onDeviceLookupTimeMillis = TimeUnit.SECONDS.toMillis(5);
         mSatelliteAccessController2.totalCheckingTimeMillis = TimeUnit.SECONDS.toMillis(6);
         mSatelliteAccessController2.isAllowed = false;
@@ -1425,6 +1451,7 @@
         mSatelliteAccessController2.resultCode = SATELLITE_RESULT_SUCCESS;
         mSatelliteAccessController2.countryCodes = new String[]{"EF", "GH"};
         mSatelliteAccessController2.configDataSource = CONFIG_DATA_SOURCE_CONFIG_UPDATER;
+        mSatelliteAccessController2.carrierId = 10;
 
         mSatelliteAccessControllers = new SatelliteAccessController[]{
                 mSatelliteAccessController1, mSatelliteAccessController2
@@ -4421,6 +4448,8 @@
         expected.countOfDatagramTypeKeepAliveFail =
                 mSatelliteController1.countOfDatagramTypeKeepAliveFail
                         + mSatelliteController2.countOfDatagramTypeKeepAliveFail;
+        expected.isProvisioned = mSatelliteController2.isProvisioned;
+        expected.carrierId = mSatelliteController2.carrierId;
 
         // Service state and service switch should be added successfully
         verifyCurrentStateSavedToFileOnce();
@@ -4973,6 +5002,7 @@
                 mCarrierRoamingSatelliteControllerStats2.satelliteSessionGapAvgSec;
         expected.satelliteSessionGapMaxSec =
                 mCarrierRoamingSatelliteControllerStats2.satelliteSessionGapMaxSec;
+        expected.carrierId = mCarrierRoamingSatelliteControllerStats2.carrierId;
 
         verifyCurrentStateSavedToFileOnce();
         CarrierRoamingSatelliteControllerStats[] output =
@@ -5825,6 +5855,18 @@
                 expectedStats.countOfDemoModeIncomingDatagramSuccess);
         assertEquals(tested[0].countOfDemoModeIncomingDatagramFail,
                 expectedStats.countOfDemoModeIncomingDatagramFail);
+        assertEquals(tested[0].countOfDatagramTypeKeepAliveSuccess,
+                expectedStats.countOfDatagramTypeKeepAliveSuccess);
+        assertEquals(tested[0].countOfDatagramTypeKeepAliveFail,
+                expectedStats.countOfDatagramTypeKeepAliveFail);
+        assertEquals(tested[0].countOfAllowedSatelliteAccess,
+                expectedStats.countOfAllowedSatelliteAccess);
+        assertEquals(tested[0].countOfDisallowedSatelliteAccess,
+                expectedStats.countOfDisallowedSatelliteAccess);
+        assertEquals(tested[0].countOfSatelliteAccessCheckFail,
+                expectedStats.countOfSatelliteAccessCheckFail);
+        assertEquals(tested[0].isProvisioned, expectedStats.isProvisioned);
+        assertEquals(tested[0].carrierId, expectedStats.carrierId);
     }
 
     private static void assertHasStatsAndCount(
@@ -5851,7 +5893,14 @@
                         == expectedStats.countOfIncomingDatagramSuccess
                     && stats.countOfIncomingDatagramFailed
                         == expectedStats.countOfIncomingDatagramFailed
-                    && stats.isDemoMode == expectedStats.isDemoMode) {
+                    && stats.isDemoMode == expectedStats.isDemoMode
+                    && stats.carrierId == expectedStats.carrierId
+                    && stats.countOfSatelliteNotificationDisplayed
+                    == expectedStats.countOfSatelliteNotificationDisplayed
+                    && stats.countOfAutoExitDueToScreenOff
+                    == expectedStats.countOfAutoExitDueToScreenOff
+                    && stats.countOfAutoExitDueToTnNetwork
+                    == expectedStats.countOfAutoExitDueToTnNetwork) {
                 actualCount = stats.count;
             }
         }
@@ -5868,7 +5917,8 @@
                     && stats.datagramSizeBytes == expectedStats.datagramSizeBytes
                     && stats.datagramTransferTimeMillis
                         == expectedStats.datagramTransferTimeMillis
-                    && stats.isDemoMode == expectedStats.isDemoMode) {
+                    && stats.isDemoMode == expectedStats.isDemoMode
+                    && stats.carrierId == expectedStats.carrierId) {
                 actualCount++;
             }
         }
@@ -5886,7 +5936,8 @@
                     && stats.datagramSizeBytes == expectedStats.datagramSizeBytes
                     && stats.datagramTransferTimeMillis
                         == expectedStats.datagramTransferTimeMillis
-                    && stats.isDemoMode == expectedStats.isDemoMode) {
+                    && stats.isDemoMode == expectedStats.isDemoMode
+                    && stats.carrierId == expectedStats.carrierId) {
                 actualCount++;
             }
         }
@@ -5902,7 +5953,8 @@
             if (stats.resultCode == expectedStats.resultCode
                     && stats.provisioningTimeSec == expectedStats.provisioningTimeSec
                     && stats.isProvisionRequest == expectedStats.isProvisionRequest
-                    && stats.isCanceled == expectedStats.isCanceled) {
+                    && stats.isCanceled == expectedStats.isCanceled
+                    && stats.carrierId == expectedStats.carrierId) {
                 actualCount++;
             }
         }
@@ -5923,7 +5975,9 @@
                     && stats.isMultiSim == expectedStats.isMultiSim
                     && stats.recommendingHandoverType == expectedStats.recommendingHandoverType
                     && stats.isSatelliteAllowedInCurrentLocation
-                    == expectedStats.isSatelliteAllowedInCurrentLocation) {
+                    == expectedStats.isSatelliteAllowedInCurrentLocation
+                    && stats.isWifiConnected == expectedStats.isWifiConnected
+                    && stats.carrierId == expectedStats.carrierId) {
                 actualCount = stats.count;
             }
         }
@@ -5945,7 +5999,8 @@
                     && stats.isEmergency == expectedStats.isEmergency
                     && stats.resultCode == expectedStats.resultCode
                     && Arrays.equals(stats.countryCodes, expectedStats.countryCodes)
-                    && stats.configDataSource == expectedStats.configDataSource) {
+                    && stats.configDataSource == expectedStats.configDataSource
+                    && stats.carrierId == expectedStats.carrierId) {
                 actualCount++;
             }
         }
@@ -6205,6 +6260,8 @@
         assertEquals(tested[0].satelliteSessionGapMinSec, expectedStats.satelliteSessionGapMinSec);
         assertEquals(tested[0].satelliteSessionGapAvgSec, expectedStats.satelliteSessionGapAvgSec);
         assertEquals(tested[0].satelliteSessionGapMaxSec, expectedStats.satelliteSessionGapMaxSec);
+        assertEquals(tested[0].carrierId, expectedStats.carrierId);
+
     }
 
     private static void assertHasStatsAndCount(
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/SatelliteStatsTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/SatelliteStatsTest.java
index 97f7935..da0dfe9 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/SatelliteStatsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/SatelliteStatsTest.java
@@ -23,6 +23,7 @@
 import static com.android.internal.telephony.satellite.SatelliteConstants.ACCESS_CONTROL_TYPE_CACHED_COUNTRY_CODE;
 
 import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 
@@ -102,6 +103,10 @@
                         .setCountOfDemoModeIncomingDatagramFail(2)
                         .setCountOfDatagramTypeKeepAliveSuccess(1)
                         .setCountOfDatagramTypeKeepAliveFail(2)
+                        .setCountOfAllowedSatelliteAccess(1)
+                        .setCountOfDisallowedSatelliteAccess(2)
+                        .setCountOfSatelliteAccessCheckFail(3)
+                        .setIsProvisioned(true)
                         .build();
 
         mSatelliteStats.onSatelliteControllerMetrics(param);
@@ -160,6 +165,59 @@
                 stats.countOfDatagramTypeKeepAliveSuccess);
         assertEquals(param.getCountOfDatagramTypeKeepAliveFail(),
                 stats.countOfDatagramTypeKeepAliveFail);
+        assertEquals(param.getCountOfAllowedSatelliteAccess(), stats.countOfAllowedSatelliteAccess);
+        assertEquals(param.getCountOfDisallowedSatelliteAccess(),
+                stats.countOfDisallowedSatelliteAccess);
+        assertEquals(param.getCountOfSatelliteAccessCheckFail(),
+                stats.countOfSatelliteAccessCheckFail);
+        assertEquals(param.isProvisioned(), stats.isProvisioned);
+
+        verifyNoMoreInteractions(mPersistAtomsStorage);
+    }
+
+    @Test
+    public void onSatelliteControllerMetrics_isProvisioned() throws Exception {
+        SatelliteStats.SatelliteControllerParams param =
+                new SatelliteStats.SatelliteControllerParams.Builder()
+                        .setCountOfSatelliteServiceEnablementsSuccess(2)
+                        .setIsProvisioned(true)
+                        .build();
+        mSatelliteStats.onSatelliteControllerMetrics(param);
+
+        ArgumentCaptor<SatelliteController> captor =
+                ArgumentCaptor.forClass(SatelliteController.class);
+        verify(mPersistAtomsStorage, times(1)).addSatelliteControllerStats(captor.capture());
+        SatelliteController stats = captor.getValue();
+        assertEquals(param.getCountOfSatelliteServiceEnablementsSuccess(),
+                stats.countOfSatelliteServiceEnablementsSuccess);
+        assertEquals(param.isProvisioned(), stats.isProvisioned);
+
+        param = new SatelliteStats.SatelliteControllerParams.Builder()
+                .setCountOfSatelliteServiceEnablementsSuccess(2)
+                .build();
+        mSatelliteStats.onSatelliteControllerMetrics(param);
+
+        captor = ArgumentCaptor.forClass(SatelliteController.class);
+        verify(mPersistAtomsStorage, times(2)).addSatelliteControllerStats(captor.capture());
+        stats = captor.getValue();
+        // count should be added
+        assertEquals(2, stats.countOfSatelliteServiceEnablementsSuccess);
+        // isProvisioned value should not be updated
+        assertEquals(true, stats.isProvisioned);
+
+        param = new SatelliteStats.SatelliteControllerParams.Builder()
+                .setCountOfSatelliteServiceEnablementsSuccess(2)
+                .setIsProvisioned(false)
+                .build();
+        mSatelliteStats.onSatelliteControllerMetrics(param);
+
+        captor = ArgumentCaptor.forClass(SatelliteController.class);
+        verify(mPersistAtomsStorage, times(3)).addSatelliteControllerStats(captor.capture());
+        stats = captor.getValue();
+        // count should be added
+        assertEquals(2, stats.countOfSatelliteServiceEnablementsSuccess);
+        // isProvisioned should be updated
+        assertEquals(false, stats.isProvisioned);
 
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
@@ -292,6 +350,8 @@
                         .setIsMultiSim(false)
                         .setRecommendingHandoverType(0)
                         .setIsSatelliteAllowedInCurrentLocation(true)
+                        .setIsWifiConnected(true)
+                        .setCarrierId(1)
                         .build();
 
         mSatelliteStats.onSatelliteSosMessageRecommender(param);
@@ -309,6 +369,8 @@
         assertEquals(param.getRecommendingHandoverType(), stats.recommendingHandoverType);
         assertEquals(param.isSatelliteAllowedInCurrentLocation(),
                 stats.isSatelliteAllowedInCurrentLocation);
+        assertEquals(param.isWifiConnected(), stats.isWifiConnected);
+        assertEquals(param.getCarrierId(), stats.carrierId);
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
 
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 e51cdc7..21ee476 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramDispatcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramDispatcherTest.java
@@ -16,11 +16,12 @@
 
 package com.android.internal.telephony.satellite;
 
+import static android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_MODEM_TIMEOUT;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;
 
-import static com.android.internal.telephony.satellite.DatagramController.SATELLITE_ALIGN_TIMEOUT;
 import static com.android.internal.telephony.SmsDispatchersController.PendingRequest;
+import static com.android.internal.telephony.satellite.DatagramController.SATELLITE_ALIGN_TIMEOUT;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -176,6 +177,7 @@
         when(mMockDatagramController.isPollingInIdleState()).thenReturn(true);
         when(mMockSatelliteController.getSatellitePhone()).thenReturn(mPhone);
         when(mPhone.getSmsDispatchersController()).thenReturn(mMockSmsDispatchersController);
+        when(mMockSatelliteController.getSatelliteCarrierId()).thenReturn(UNKNOWN_CARRIER_ID);
         mPendingSms = createPendingRequest();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramReceiverTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramReceiverTest.java
index 947661b..bf1a8bd 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramReceiverTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/DatagramReceiverTest.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony.satellite;
 
+import static android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID;
+
 import static com.android.internal.telephony.satellite.DatagramController.SATELLITE_ALIGN_TIMEOUT;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -144,6 +146,7 @@
         when(mMockDatagramController.isPollingInIdleState()).thenReturn(true);
         when(mMockDatagramController.needsWaitingForSatelliteConnected(
                 eq(SatelliteManager.DATAGRAM_TYPE_UNKNOWN))).thenReturn(false);
+        when(mMockSatelliteController.getSatelliteCarrierId()).thenReturn(UNKNOWN_CARRIER_ID);
         processAllMessages();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/DemoSimulatorTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/DemoSimulatorTest.java
index 319e39f..2b18468 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/DemoSimulatorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/DemoSimulatorTest.java
@@ -119,7 +119,7 @@
         moveToNotConnectedState();
 
         verify(mISatelliteListener).onSatelliteModemStateChanged(
-                SatelliteModemState.SATELLITE_MODEM_STATE_NOT_CONNECTED);
+                SatelliteModemState.SATELLITE_MODEM_STATE_OUT_OF_SERVICE);
         ArgumentCaptor<NtnSignalStrength> ntnSignalStrength = ArgumentCaptor.forClass(
                 NtnSignalStrength.class);
         verify(mISatelliteListener).onNtnSignalStrengthChanged(ntnSignalStrength.capture());
@@ -156,9 +156,9 @@
         moveToConnectedState();
 
         verify(mISatelliteListener).onSatelliteModemStateChanged(
-                SatelliteModemState.SATELLITE_MODEM_STATE_NOT_CONNECTED);
+                SatelliteModemState.SATELLITE_MODEM_STATE_OUT_OF_SERVICE);
         verify(mISatelliteListener).onSatelliteModemStateChanged(
-                SatelliteModemState.SATELLITE_MODEM_STATE_CONNECTED);
+                SatelliteModemState.SATELLITE_MODEM_STATE_IN_SERVICE);
         ArgumentCaptor<NtnSignalStrength> ntnSignalStrength = ArgumentCaptor.forClass(
                 NtnSignalStrength.class);
         verify(mISatelliteListener, times(2))
diff --git a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
index 607a35f..a9775c0 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteControllerTest.java
@@ -49,8 +49,10 @@
 import static android.telephony.satellite.SatelliteManager.SATELLITE_COMMUNICATION_RESTRICTION_REASON_GEOLOCATION;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_COMMUNICATION_RESTRICTION_REASON_USER;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_NOT_CONNECTED;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_OFF;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_DISABLE_IN_PROGRESS;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_EMERGENCY_CALL_IN_PROGRESS;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_ERROR;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_INVALID_ARGUMENTS;
@@ -61,6 +63,7 @@
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_NOT_SUPPORTED;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_NO_RESOURCES;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_REQUEST_ABORTED;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_REQUEST_IN_PROGRESS;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SERVICE_NOT_PROVISIONED;
@@ -212,6 +215,7 @@
     private PersistableBundle mCarrierConfigBundle;
     private ServiceState mServiceState2;
 
+    @Mock private SatelliteController mMockSatelliteController;
     @Mock private DatagramController mMockDatagramController;
     @Mock private SatelliteModemInterface mMockSatelliteModemInterface;
     @Mock private SatelliteSessionController mMockSatelliteSessionController;
@@ -515,6 +519,8 @@
         MockitoAnnotations.initMocks(this);
         logd(TAG + " Setup!");
 
+        replaceInstance(SatelliteController.class, "sInstance", null,
+                mMockSatelliteController);
         replaceInstance(DatagramController.class, "sInstance", null,
                 mMockDatagramController);
         replaceInstance(SatelliteModemInterface.class, "sInstance", null,
@@ -536,6 +542,8 @@
                 null, mMockTelephonyConfigUpdateInstallReceiver);
         replaceInstance(DemoSimulator.class, "sInstance", null, mMockDemoSimulator);
 
+        doNothing().when(mMockSatelliteController).moveSatelliteToOffStateAndCleanUpResources(
+                SATELLITE_RESULT_REQUEST_ABORTED);
         mServiceState2 = mock(ServiceState.class);
         when(mPhone.getServiceState()).thenReturn(mServiceState);
         when(mPhone.getSubId()).thenReturn(SUB_ID);
@@ -598,12 +606,16 @@
                 .when(mMockSessionMetricsStats).setSessionDurationSec(anyInt());
         doReturn(mMockSessionMetricsStats)
                 .when(mMockSessionMetricsStats).setIsDemoMode(anyBoolean());
+        doReturn(mMockSessionMetricsStats)
+                .when(mMockSessionMetricsStats).setCarrierId(anyInt());
         doNothing().when(mMockSessionMetricsStats).reportSessionMetrics();
 
         doReturn(mMockProvisionMetricsStats).when(mMockProvisionMetricsStats)
                 .setResultCode(anyInt());
         doReturn(mMockProvisionMetricsStats).when(mMockProvisionMetricsStats)
                 .setIsProvisionRequest(anyBoolean());
+        doReturn(mMockProvisionMetricsStats).when(mMockProvisionMetricsStats)
+                .setCarrierId(anyInt());
         doNothing().when(mMockProvisionMetricsStats).reportProvisionMetrics();
         doNothing().when(mMockControllerMetricsStats).reportDeprovisionCount(anyInt());
         when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
@@ -913,8 +925,8 @@
 
         // Fail to enable satellite when SatelliteController is not fully loaded yet.
         mIIntegerConsumerResults.clear();
-        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false,
-                mIIntegerConsumer);
+        mIIntegerConsumerSemaphore.drainPermits();
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false, mIIntegerConsumer);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         assertEquals(SATELLITE_RESULT_INVALID_TELEPHONY_STATE,
@@ -922,26 +934,24 @@
 
         // Fail to enable satellite when the device does not support satellite.
         mIIntegerConsumerResults.clear();
+        mIIntegerConsumerSemaphore.drainPermits();
         setUpResponseForRequestIsSatelliteSupported(false, SATELLITE_RESULT_SUCCESS);
         verifySatelliteSupported(false, SATELLITE_RESULT_SUCCESS);
-        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false, mIIntegerConsumer);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         assertEquals(SATELLITE_RESULT_NOT_SUPPORTED, (long) mIIntegerConsumerResults.get(0));
 
         // Fail to enable satellite when the device is not provisioned yet.
         mIIntegerConsumerResults.clear();
+        mIIntegerConsumerSemaphore.drainPermits();
         resetSatelliteControllerUT();
         verify(mMockSatelliteSessionController, times(1)).onSatelliteEnabledStateChanged(eq(false));
-        verify(mMockSatelliteSessionController, times(1)).setDemoMode(eq(false));
-        verify(mMockDatagramController, times(1)).setDemoMode(eq(false));
         setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
         verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
         setUpResponseForRequestIsSatelliteProvisioned(false, SATELLITE_RESULT_SUCCESS);
         verifySatelliteProvisioned(false, SATELLITE_RESULT_SUCCESS);
-        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false, mIIntegerConsumer);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         assertEquals(SATELLITE_RESULT_SERVICE_NOT_PROVISIONED,
@@ -953,12 +963,12 @@
 
         // Fail to enable satellite when the emergency call is in progress
         mIIntegerConsumerResults.clear();
+        mIIntegerConsumerSemaphore.drainPermits();
         mSatelliteControllerUT.setSettingsKeyForSatelliteModeCalled = false;
         mSatelliteControllerUT.setSettingsKeyToAllowDeviceRotationCalled = false;
         setUpResponseForRequestSatelliteEnabled(true, false, false, SATELLITE_RESULT_SUCCESS);
         doReturn(true).when(mTelecomManager).isInEmergencyCall();
-        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false, mIIntegerConsumer);
         mSatelliteControllerUT.setSatelliteSessionController(mMockSatelliteSessionController);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
@@ -968,17 +978,17 @@
 
         // Successfully enable satellite
         mIIntegerConsumerResults.clear();
+        mIIntegerConsumerSemaphore.drainPermits();
         mSatelliteControllerUT.setSettingsKeyForSatelliteModeCalled = false;
         mSatelliteControllerUT.setSettingsKeyToAllowDeviceRotationCalled = false;
-        setUpResponseForRequestSatelliteEnabled(true, false, false, SATELLITE_RESULT_SUCCESS);
-        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false,
-                mIIntegerConsumer);
+        setUpResponseForRequestSatelliteEnabled(true, false, true, SATELLITE_RESULT_SUCCESS);
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, true, mIIntegerConsumer);
         mSatelliteControllerUT.setSatelliteSessionController(mMockSatelliteSessionController);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
         verifySatelliteEnabled(true, SATELLITE_RESULT_SUCCESS);
-        verify(mMockSatelliteSessionController, times(2)).onEmergencyModeChanged(eq(false));
+        verify(mMockSatelliteSessionController, times(1)).onEmergencyModeChanged(eq(true));
         assertTrue(mSatelliteControllerUT.setSettingsKeyForSatelliteModeCalled);
         assertTrue(mSatelliteControllerUT.setSettingsKeyToAllowDeviceRotationCalled);
         assertEquals(
@@ -990,6 +1000,10 @@
         verify(mMockControllerMetricsStats, times(1)).reportServiceEnablementSuccessCount();
 
         // Successfully disable satellite when radio is turned off.
+        clearInvocations(mMockSatelliteSessionController);
+        clearInvocations(mMockDatagramController);
+        mSatelliteControllerUT.setSatelliteSessionController(mMockSatelliteSessionController);
+        when(mMockSatelliteSessionController.isInDisablingState()).thenReturn(true);
         mSatelliteControllerUT.setSettingsKeyForSatelliteModeCalled = false;
         mSatelliteControllerUT.setSettingsKeyToAllowDeviceRotationCalled = false;
         setUpResponseForRequestSatelliteEnabled(false, false, false, SATELLITE_RESULT_SUCCESS);
@@ -999,21 +1013,22 @@
         sendSatelliteModemStateChangedEvent(SATELLITE_MODEM_STATE_OFF, null);
         processAllMessages();
         verifySatelliteEnabled(false, SATELLITE_RESULT_SUCCESS);
-        verify(mMockSatelliteSessionController, times(3)).onEmergencyModeChanged(eq(false));
+        verify(mMockSatelliteSessionController, times(1)).onEmergencyModeChanged(eq(false));
         assertTrue(mSatelliteControllerUT.setSettingsKeyForSatelliteModeCalled);
         assertTrue(mSatelliteControllerUT.setSettingsKeyToAllowDeviceRotationCalled);
         assertEquals(
                 SATELLITE_MODE_ENABLED_FALSE, mSatelliteControllerUT.satelliteModeSettingValue);
         verify(mMockSatelliteSessionController, times(2)).onSatelliteEnabledStateChanged(eq(false));
-        verify(mMockSatelliteSessionController, times(3)).setDemoMode(eq(false));
-        verify(mMockDatagramController, times(3)).setDemoMode(eq(false));
+        verify(mMockSatelliteSessionController, times(2)).setDemoMode(eq(false));
+        verify(mMockDatagramController, times(2)).setDemoMode(eq(false));
         verify(mMockControllerMetricsStats, times(1)).onSatelliteDisabled();
+        when(mMockSatelliteSessionController.isInDisablingState()).thenReturn(false);
 
         // Fail to enable satellite when radio is off.
         mIIntegerConsumerResults.clear();
+        mIIntegerConsumerSemaphore.drainPermits();
         setUpResponseForRequestSatelliteEnabled(true, false, false, SATELLITE_RESULT_SUCCESS);
-        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false, mIIntegerConsumer);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         // Radio is not on, can not enable satellite
@@ -1025,13 +1040,13 @@
 
         // Fail to enable satellite with an error response from modem when radio is on.
         mIIntegerConsumerResults.clear();
+        mIIntegerConsumerSemaphore.drainPermits();
         clearInvocations(mMockPointingAppController);
         mSatelliteControllerUT.setSettingsKeyForSatelliteModeCalled = false;
         mSatelliteControllerUT.setSettingsKeyToAllowDeviceRotationCalled = false;
         setUpResponseForRequestSatelliteEnabled(true, false, false,
                 SATELLITE_RESULT_INVALID_MODEM_STATE);
-        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false, mIIntegerConsumer);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         assertEquals(SATELLITE_RESULT_INVALID_MODEM_STATE, (long) mIIntegerConsumerResults.get(0));
@@ -1044,11 +1059,11 @@
 
         // Successfully enable satellite when radio is on.
         mIIntegerConsumerResults.clear();
+        mIIntegerConsumerSemaphore.drainPermits();
         mSatelliteControllerUT.setSettingsKeyForSatelliteModeCalled = false;
         mSatelliteControllerUT.setSettingsKeyToAllowDeviceRotationCalled = false;
         setUpResponseForRequestSatelliteEnabled(true, false, false, SATELLITE_RESULT_SUCCESS);
-        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false, mIIntegerConsumer);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
@@ -1056,16 +1071,16 @@
         assertTrue(mSatelliteControllerUT.setSettingsKeyForSatelliteModeCalled);
         assertTrue(mSatelliteControllerUT.setSettingsKeyToAllowDeviceRotationCalled);
         assertEquals(SATELLITE_MODE_ENABLED_TRUE, mSatelliteControllerUT.satelliteModeSettingValue);
-        verify(mMockSatelliteSessionController, times(2)).onSatelliteEnabledStateChanged(eq(true));
-        verify(mMockSatelliteSessionController, times(4)).setDemoMode(eq(false));
-        verify(mMockDatagramController, times(4)).setDemoMode(eq(false));
+        verify(mMockSatelliteSessionController, times(1)).onSatelliteEnabledStateChanged(eq(true));
+        verify(mMockSatelliteSessionController, times(3)).setDemoMode(eq(false));
+        verify(mMockDatagramController, times(3)).setDemoMode(eq(false));
         verify(mMockControllerMetricsStats, times(2)).onSatelliteEnabled();
         verify(mMockControllerMetricsStats, times(2)).reportServiceEnablementSuccessCount();
 
         // Successfully enable satellite when it is already enabled.
         mIIntegerConsumerResults.clear();
-        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false,
-                mIIntegerConsumer);
+        mIIntegerConsumerSemaphore.drainPermits();
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false, mIIntegerConsumer);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
@@ -1073,8 +1088,8 @@
 
         // Fail to enable satellite with a different demo mode when it is already enabled.
         mIIntegerConsumerResults.clear();
-        mSatelliteControllerUT.requestSatelliteEnabled(true, true, false,
-                mIIntegerConsumer);
+        mIIntegerConsumerSemaphore.drainPermits();
+        mSatelliteControllerUT.requestSatelliteEnabled(true, true, false, mIIntegerConsumer);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         assertEquals(SATELLITE_RESULT_INVALID_ARGUMENTS, (long) mIIntegerConsumerResults.get(0));
@@ -1082,9 +1097,9 @@
 
         // Successfully disable satellite.
         mIIntegerConsumerResults.clear();
+        mIIntegerConsumerSemaphore.drainPermits();
         setUpResponseForRequestSatelliteEnabled(false, false, false, SATELLITE_RESULT_SUCCESS);
-        mSatelliteControllerUT.requestSatelliteEnabled(false, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(false, false, false, mIIntegerConsumer);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
@@ -1092,8 +1107,8 @@
 
         // Disable satellite when satellite is already disabled.
         mIIntegerConsumerResults.clear();
-        mSatelliteControllerUT.requestSatelliteEnabled(false, false, false,
-                mIIntegerConsumer);
+        mIIntegerConsumerSemaphore.drainPermits();
+        mSatelliteControllerUT.requestSatelliteEnabled(false, false, false, mIIntegerConsumer);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
@@ -1101,8 +1116,8 @@
 
         // Disable satellite with a different demo mode when satellite is already disabled.
         mIIntegerConsumerResults.clear();
-        mSatelliteControllerUT.requestSatelliteEnabled(false, true, false,
-                mIIntegerConsumer);
+        mIIntegerConsumerSemaphore.drainPermits();
+        mSatelliteControllerUT.requestSatelliteEnabled(false, true, false, mIIntegerConsumer);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
@@ -1110,18 +1125,18 @@
 
         // Send a second request while the first request in progress
         mIIntegerConsumerResults.clear();
+        mIIntegerConsumerSemaphore.drainPermits();
         setUpNoResponseForRequestSatelliteEnabled(true, false, false);
-        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false, mIIntegerConsumer);
         processAllMessages();
         assertFalse(waitForIIntegerConsumerResult(1));
-        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false, mIIntegerConsumer);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         assertEquals(SATELLITE_RESULT_REQUEST_IN_PROGRESS, (long) mIIntegerConsumerResults.get(0));
 
         mIIntegerConsumerResults.clear();
+        mIIntegerConsumerSemaphore.drainPermits();
         resetSatelliteControllerUT();
         setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
         setProvisionedState(false);
@@ -1129,81 +1144,86 @@
         setProvisionedState(true);
         processAllMessages();
         verifySatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
-        // Should receive callback for the above request when satellite modem is turned off.
+        // The enable request should be aborted when satellite modem move to OFF state.
         assertTrue(waitForIIntegerConsumerResult(1));
-        assertEquals(SATELLITE_RESULT_INVALID_MODEM_STATE, (long) mIIntegerConsumerResults.get(0));
+        assertEquals(SATELLITE_RESULT_REQUEST_ABORTED, (long) mIIntegerConsumerResults.get(0));
+
+        // Successfully enable satellite
+        mIIntegerConsumerResults.clear();
+        mIIntegerConsumerSemaphore.drainPermits();
+        setUpResponseForRequestSatelliteEnabled(true, false, false, SATELLITE_RESULT_SUCCESS);
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
+        verifySatelliteEnabled(true, SATELLITE_RESULT_SUCCESS);
 
         // Move to satellite-disabling in progress.
+        mIIntegerConsumerResults.clear();
+        mIIntegerConsumerSemaphore.drainPermits();
         setUpNoResponseForRequestSatelliteEnabled(false, false, false);
-        mSatelliteControllerUT.requestSatelliteEnabled(false, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(false, false, false, mIIntegerConsumer);
         processAllMessages();
         assertFalse(waitForIIntegerConsumerResult(1));
 
         // Disable is in progress. Thus, a new request to enable satellite will be rejected.
         mIIntegerConsumerResults.clear();
-        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false,
-                mIIntegerConsumer);
+        mIIntegerConsumerSemaphore.drainPermits();
+        mSatelliteControllerUT.setSatelliteSessionController(mMockSatelliteSessionController);
+        when(mMockSatelliteSessionController.isInDisablingState()).thenReturn(true);
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false, mIIntegerConsumer);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
-        assertEquals(SATELLITE_RESULT_ERROR, (long) mIIntegerConsumerResults.get(0));
+        assertEquals(SATELLITE_RESULT_DISABLE_IN_PROGRESS, (long) mIIntegerConsumerResults.get(0));
 
         mIIntegerConsumerResults.clear();
+        mIIntegerConsumerSemaphore.drainPermits();
         resetSatelliteControllerUTToOffAndProvisionedState();
-        // Should receive callback for the above request when satellite modem is turned off.
-        assertTrue(waitForIIntegerConsumerResult(1));
-        assertEquals(SATELLITE_RESULT_INVALID_MODEM_STATE, (long) mIIntegerConsumerResults.get(0));
-
-        verify(mMockSessionMetricsStats, times(17)).setInitializationResult(anyInt());
-        verify(mMockSessionMetricsStats, times(17)).setSatelliteTechnology(anyInt());
-        verify(mMockSessionMetricsStats, times(3)).setInitializationProcessingTime(anyLong());
-        verify(mMockSessionMetricsStats, times(2)).setTerminationResult(anyInt());
-        verify(mMockSessionMetricsStats, times(2)).setTerminationProcessingTime(anyLong());
-        verify(mMockSessionMetricsStats, times(2)).setSessionDurationSec(anyInt());
-        verify(mMockSessionMetricsStats, times(17)).reportSessionMetrics();
+        when(mMockSatelliteSessionController.isInDisablingState()).thenReturn(false);
 
         /**
          * Make areAllRadiosDisabled return false and move mWaitingForRadioDisabled to true, which
          * will lead to no response for requestSatelliteEnabled.
          */
         mSatelliteControllerUT.allRadiosDisabled = false;
+        mIIntegerConsumerResults.clear();
+        mIIntegerConsumerSemaphore.drainPermits();
         setUpResponseForRequestSatelliteEnabled(true, false, false, SATELLITE_RESULT_SUCCESS);
-        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false, mIIntegerConsumer);
         processAllMessages();
         assertFalse(waitForIIntegerConsumerResult(1));
 
-        resetSatelliteControllerUTEnabledState();
         mIIntegerConsumerResults.clear();
+        mIIntegerConsumerSemaphore.drainPermits();
         setUpResponseForRequestSatelliteEnabled(false, false, false, SATELLITE_RESULT_SUCCESS);
-        mSatelliteControllerUT.requestSatelliteEnabled(false, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(false, false, false, mIIntegerConsumer);
         processAllMessages();
         // We should receive 2 callbacks for the above 2 requests.
         assertTrue(waitForIIntegerConsumerResult(2));
+        // Successful result for disable request
         assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
-        assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(1));
+        // The enable request should be aborted after getting the successful confirmation of the
+        // disable request.
+        assertEquals(SATELLITE_RESULT_REQUEST_ABORTED, (long) mIIntegerConsumerResults.get(1));
 
         resetSatelliteControllerUTToOffAndProvisionedState();
 
         // Repeat the same test as above but with error response from modem for the second request
         mSatelliteControllerUT.allRadiosDisabled = false;
         setUpResponseForRequestSatelliteEnabled(true, false, false, SATELLITE_RESULT_SUCCESS);
-        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false, mIIntegerConsumer);
         processAllMessages();
+        // No response for the enable request because all radios are not disabled yet
         assertFalse(waitForIIntegerConsumerResult(1));
 
-        resetSatelliteControllerUTEnabledState();
         mIIntegerConsumerResults.clear();
+        mIIntegerConsumerSemaphore.drainPermits();
         setUpResponseForRequestSatelliteEnabled(false, false, false, SATELLITE_RESULT_NO_RESOURCES);
-        mSatelliteControllerUT.requestSatelliteEnabled(false, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(false, false, false, mIIntegerConsumer);
         processAllMessages();
-        // We should receive 2 callbacks for the above 2 requests.
-        assertTrue(waitForIIntegerConsumerResult(2));
-        assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
-        assertEquals(SATELLITE_RESULT_NO_RESOURCES, (long) mIIntegerConsumerResults.get(1));
+        // We should receive result for the disable request.
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_RESULT_NO_RESOURCES, (long) mIIntegerConsumerResults.get(0));
         mSatelliteControllerUT.allRadiosDisabled = true;
 
         resetSatelliteControllerUTToOnAndProvisionedState();
@@ -1218,9 +1238,9 @@
         // Successfully disable satellite.
         when(mFeatureFlags.oemEnabledSatelliteFlag()).thenReturn(true);
         mIIntegerConsumerResults.clear();
+        mIIntegerConsumerSemaphore.drainPermits();
         setUpResponseForRequestSatelliteEnabled(false, false, false, SATELLITE_RESULT_SUCCESS);
-        mSatelliteControllerUT.requestSatelliteEnabled(false, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(false, false, false, mIIntegerConsumer);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
@@ -1228,10 +1248,10 @@
 
         // Fail to enable satellite when radio is being powered off.
         mIIntegerConsumerResults.clear();
+        mIIntegerConsumerSemaphore.drainPermits();
         setUpResponseForRequestSatelliteEnabled(true, false, false, SATELLITE_RESULT_SUCCESS);
         mSatelliteControllerUT.onSetCellularRadioPowerStateRequested(false);
-        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false, mIIntegerConsumer);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         // Radio is being powered off, can not enable satellite
@@ -1242,15 +1262,50 @@
 
         // Successfully enable satellite when radio is on.
         mIIntegerConsumerResults.clear();
+        mIIntegerConsumerSemaphore.drainPermits();
         mSatelliteControllerUT.setSettingsKeyForSatelliteModeCalled = false;
         mSatelliteControllerUT.setSettingsKeyToAllowDeviceRotationCalled = false;
         setUpResponseForRequestSatelliteEnabled(true, false, false, SATELLITE_RESULT_SUCCESS);
-        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false, mIIntegerConsumer);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
         verifySatelliteEnabled(true, SATELLITE_RESULT_SUCCESS);
+
+        // Clean up all previous resources
+        processAllFutureMessages();
+        mIIntegerConsumerSemaphore.drainPermits();
+
+        // Successfully disable satellite.
+        mIIntegerConsumerResults.clear();
+        mIIntegerConsumerSemaphore.drainPermits();
+        setUpResponseForRequestSatelliteEnabled(false, false, false, SATELLITE_RESULT_SUCCESS);
+        mSatelliteControllerUT.requestSatelliteEnabled(false, false, false, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(1));
+        assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
+        verifySatelliteEnabled(false, SATELLITE_RESULT_SUCCESS);
+
+        // Move to satellite-enabling in progress.
+        setUpNoResponseForRequestSatelliteEnabled(true, false, false);
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false, mIIntegerConsumer);
+        processAllMessages();
+        assertFalse(waitForIIntegerConsumerResult(1));
+
+        // Successfully disable satellite.
+        mIIntegerConsumerResults.clear();
+        mIIntegerConsumerSemaphore.drainPermits();
+        setUpResponseForRequestSatelliteEnabled(false, false, false, SATELLITE_RESULT_SUCCESS);
+        mSatelliteControllerUT.requestSatelliteEnabled(false, false, false, mIIntegerConsumer);
+        processAllMessages();
+        assertTrue(waitForIIntegerConsumerResult(2));
+        // Should get success result for the disable request
+        assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
+        // The enable request should be aborted
+        assertEquals(SATELLITE_RESULT_REQUEST_ABORTED, (long) mIIntegerConsumerResults.get(1));
+        // All timers waiting for enablement response should be stopped
+        assertFalse(mSatelliteControllerUT.isAnyWaitForSatelliteEnablingResponseTimerStarted());
+        verifySatelliteEnabled(false, SATELLITE_RESULT_SUCCESS);
     }
 
     @Test
@@ -1274,7 +1329,7 @@
         setUpResponseForRequestSatelliteEnabled(true, false, true/*emergency*/,
                 SATELLITE_RESULT_SUCCESS);
         // Request satellite enabling for emergency
-        mSatelliteControllerUT.requestSatelliteEnabled(true, false, true/*isEmergency*/,
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, true /*isEmergency*/,
                 mIIntegerConsumer);
         mSatelliteControllerUT.setSatelliteSessionController(mMockSatelliteSessionController);
         processAllMessages();
@@ -1529,6 +1584,7 @@
 
     @Test
     public void testIsSatelliteEnabled() {
+        logd("testIsSatelliteEnabled: starting");
         setUpResponseForRequestIsSatelliteEnabled(true, SATELLITE_RESULT_SUCCESS);
         assertFalse(mSatelliteControllerUT.isSatelliteEnabled());
         mIsSatelliteEnabledSemaphore.drainPermits();
@@ -1539,7 +1595,9 @@
                 SATELLITE_RESULT_INVALID_TELEPHONY_STATE, mQueriedIsSatelliteEnabledResultCode);
 
 
+        logd("testIsSatelliteEnabled: setUpResponseForRequestIsSatelliteSupported");
         setUpResponseForRequestIsSatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
+        logd("testIsSatelliteEnabled: verifySatelliteSupported");
         verifySatelliteSupported(true, SATELLITE_RESULT_SUCCESS);
         mSatelliteControllerUT.requestIsSatelliteEnabled(mIsSatelliteEnabledReceiver);
         processAllMessages();
@@ -2482,16 +2540,23 @@
         clearInvocations(mMockDatagramController);
         sendSatelliteModemStateChangedEvent(SATELLITE_MODEM_STATE_UNAVAILABLE, null);
         processAllMessages();
-        verify(mMockSatelliteSessionController, times(1)).onSatelliteEnabledStateChanged(eq(false));
-        verify(mMockSatelliteSessionController, times(1)).setDemoMode(eq(false));
-        verify(mMockDatagramController, times(1)).setDemoMode(eq(false));
+        verify(mMockSatelliteSessionController, times(1)).onSatelliteModemStateChanged(
+                eq(SATELLITE_MODEM_STATE_OFF));
 
         clearInvocations(mMockSatelliteSessionController);
         clearInvocations(mMockDatagramController);
-        sendSatelliteModemStateChangedEvent(SATELLITE_MODEM_STATE_CONNECTED, null);
+        when(mMockSatelliteSessionController.isInDisablingState()).thenReturn(true);
+        sendSatelliteModemStateChangedEvent(SATELLITE_MODEM_STATE_NOT_CONNECTED, null);
         processAllMessages();
         verify(mMockSatelliteSessionController, times(1)).onSatelliteModemStateChanged(
-                SATELLITE_MODEM_STATE_CONNECTED);
+                SATELLITE_MODEM_STATE_NOT_CONNECTED);
+
+        clearInvocations(mMockSatelliteSessionController);
+        when(mMockSatelliteSessionController.isInDisablingState()).thenReturn(false);
+        sendSatelliteModemStateChangedEvent(SATELLITE_MODEM_STATE_NOT_CONNECTED, null);
+        processAllMessages();
+        verify(mMockSatelliteSessionController, never()).onSatelliteModemStateChanged(
+                SATELLITE_MODEM_STATE_NOT_CONNECTED);
     }
 
     @Test
@@ -3578,8 +3643,7 @@
         // Successfully disable satellite
         mIIntegerConsumerResults.clear();
         setUpResponseForRequestSatelliteEnabled(false, false, false, SATELLITE_RESULT_SUCCESS);
-        mSatelliteControllerUT.requestSatelliteEnabled(false, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(false, false, false, mIIntegerConsumer);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
@@ -3592,8 +3656,7 @@
         mIIntegerConsumerResults.clear();
         setUpNoResponseForRequestSatelliteEnabled(true, false, false);
         clearInvocations(mMockSatelliteModemInterface);
-        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false, mIIntegerConsumer);
         processAllMessages();
         assertFalse(waitForIIntegerConsumerResult(1));
         verify(mMockSatelliteModemInterface).requestSatelliteEnabled(
@@ -3624,8 +3687,7 @@
         // Successfully enable satellite
         mIIntegerConsumerResults.clear();
         setUpResponseForRequestSatelliteEnabled(true, false, false, SATELLITE_RESULT_SUCCESS);
-        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false, mIIntegerConsumer);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
@@ -3636,8 +3698,7 @@
         mIIntegerConsumerResults.clear();
         clearInvocations(mMockSatelliteModemInterface);
         setUpNoResponseForRequestSatelliteEnabled(false, false, false);
-        mSatelliteControllerUT.requestSatelliteEnabled(false, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(false, false, false, mIIntegerConsumer);
         processAllMessages();
         assertFalse(waitForIIntegerConsumerResult(1));
         verify(mMockSatelliteModemInterface).requestSatelliteEnabled(
@@ -3686,8 +3747,7 @@
         mSatelliteControllerUT.setSettingsKeyForSatelliteModeCalled = false;
         mSatelliteControllerUT.setSettingsKeyToAllowDeviceRotationCalled = false;
         setUpResponseForRequestSatelliteEnabled(true, false, false, SATELLITE_RESULT_SUCCESS);
-        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false, mIIntegerConsumer);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
@@ -3702,8 +3762,7 @@
         // Ignore request ntn signal strength for redundant enable request
         reset(mMockSatelliteModemInterface);
         doReturn(true).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
-        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false, mIIntegerConsumer);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
@@ -3716,8 +3775,7 @@
         reset(mMockSatelliteModemInterface);
         doReturn(true).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
         setUpResponseForRequestSatelliteEnabled(false, false, false, SATELLITE_RESULT_SUCCESS);
-        mSatelliteControllerUT.requestSatelliteEnabled(false, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(false, false, false, mIIntegerConsumer);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
@@ -3731,8 +3789,7 @@
         doReturn(true).when(mMockSatelliteModemInterface).isSatelliteServiceSupported();
         mIIntegerConsumerResults.clear();
         setUpResponseForRequestSatelliteEnabled(false, false, false, SATELLITE_RESULT_SUCCESS);
-        mSatelliteControllerUT.requestSatelliteEnabled(false, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(false, false, false, mIIntegerConsumer);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
@@ -3747,8 +3804,7 @@
         mSatelliteControllerUT.setSettingsKeyForSatelliteModeCalled = false;
         mSatelliteControllerUT.setSettingsKeyToAllowDeviceRotationCalled = false;
         setUpResponseForRequestSatelliteEnabled(true, false, false, SATELLITE_RESULT_SUCCESS);
-        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false, mIIntegerConsumer);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
@@ -3824,8 +3880,7 @@
         verifySatelliteProvisioned(true, SATELLITE_RESULT_SUCCESS);
         mIIntegerConsumerResults.clear();
         setUpResponseForRequestSatelliteEnabled(true, false, false, SATELLITE_RESULT_SUCCESS);
-        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false, mIIntegerConsumer);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
@@ -4555,6 +4610,8 @@
         resetSatelliteControllerUTToSupportedAndProvisionedState();
         // Clean up pending resources and move satellite controller to OFF state.
         sendSatelliteModemStateChangedEvent(SATELLITE_MODEM_STATE_UNAVAILABLE, null);
+        mSatelliteControllerUT.moveSatelliteToOffStateAndCleanUpResources(
+                SATELLITE_RESULT_REQUEST_ABORTED);
         processAllMessages();
         verifySatelliteEnabled(false, SATELLITE_RESULT_SUCCESS);
     }
@@ -4564,9 +4621,9 @@
         setRadioPower(true);
         processAllMessages();
 
+        mIIntegerConsumerResults.clear();
         setUpResponseForRequestSatelliteEnabled(true, false, false, SATELLITE_RESULT_SUCCESS);
-        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false,
-                mIIntegerConsumer);
+        mSatelliteControllerUT.requestSatelliteEnabled(true, false, false, mIIntegerConsumer);
         processAllMessages();
         assertTrue(waitForIIntegerConsumerResult(1));
         assertEquals(SATELLITE_RESULT_SUCCESS, (long) mIIntegerConsumerResults.get(0));
@@ -5229,6 +5286,7 @@
 
         @Override
         protected boolean areAllRadiosDisabled() {
+            logd("areAllRadiosDisabled: " + allRadiosDisabled);
             return allRadiosDisabled;
         }
 
@@ -5315,5 +5373,9 @@
         public String getStringFromOverlayConfigTest(int resourceId) {
             return getStringFromOverlayConfig(resourceId);
         }
+
+        public boolean isAnyWaitForSatelliteEnablingResponseTimerStarted() {
+            return hasMessages(EVENT_WAIT_FOR_SATELLITE_ENABLING_RESPONSE_TIMED_OUT);
+        }
     }
 }
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 b95fd4e..95924dd 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSessionControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/satellite/SatelliteSessionControllerTest.java
@@ -16,9 +16,9 @@
 
 package com.android.internal.telephony.satellite;
 
-import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ESOS_INACTIVITY_TIMEOUT_SEC_INT;
-import static android.telephony.CarrierConfigManager.KEY_SATELLITE_P2P_SMS_INACTIVITY_TIMEOUT_SEC_INT;
-import static android.telephony.CarrierConfigManager.KEY_SATELLITE_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT;
+import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ROAMING_ESOS_INACTIVITY_TIMEOUT_SEC_INT;
+import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ROAMING_P2P_SMS_INACTIVITY_TIMEOUT_SEC_INT;
+import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ROAMING_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_SUCCESS;
@@ -27,8 +27,6 @@
 import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_WAITING_TO_CONNECT;
 
-import static com.android.internal.telephony.satellite.SatelliteSessionController.EVENT_SCREEN_OFF_INACTIVITY_TIMER_TIMED_OUT;
-
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -201,7 +199,7 @@
                 eq(mTestSatelliteSessionController.getHandler()), anyInt(), any());
         when(mMockSatelliteController.getRequestIsEmergency()).thenReturn(false);
         PersistableBundle bundle = new PersistableBundle();
-        bundle.putInt(KEY_SATELLITE_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT,
+        bundle.putInt(KEY_SATELLITE_ROAMING_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT,
                 SCREEN_OFF_INACTIVITY_TIMEOUT_SEC);
         when(mMockSatelliteController.getPersistableBundle(anyInt())).thenReturn(bundle);
 
@@ -239,7 +237,7 @@
         // Satellite enabling request is for an emergency.
         when(mMockSatelliteController.getRequestIsEmergency()).thenReturn(true);
         PersistableBundle bundle = new PersistableBundle();
-        bundle.putInt(KEY_SATELLITE_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT,
+        bundle.putInt(KEY_SATELLITE_ROAMING_SCREEN_OFF_INACTIVITY_TIMEOUT_SEC_INT,
                 SCREEN_OFF_INACTIVITY_TIMEOUT_SEC);
         when(mMockSatelliteController.getPersistableBundle(anyInt())).thenReturn(bundle);
 
@@ -291,7 +289,7 @@
                 anyInt())).thenReturn(true);
         when(mMockSatelliteController.isInCarrierRoamingNbIotNtn()).thenReturn(true);
         PersistableBundle bundle = new PersistableBundle();
-        bundle.putInt(KEY_SATELLITE_P2P_SMS_INACTIVITY_TIMEOUT_SEC_INT,
+        bundle.putInt(KEY_SATELLITE_ROAMING_P2P_SMS_INACTIVITY_TIMEOUT_SEC_INT,
                 P2P_SMS_INACTIVITY_TIMEOUT_SEC);
         when(mMockSatelliteController.getPersistableBundle(anyInt())).thenReturn(bundle);
 
@@ -334,7 +332,7 @@
         when(mMockSatelliteController.getRequestIsEmergency()).thenReturn(true);
         when(mMockSatelliteController.isSatelliteEsosSupported(anyInt())).thenReturn(true);
         PersistableBundle bundle = new PersistableBundle();
-        bundle.putInt(KEY_SATELLITE_ESOS_INACTIVITY_TIMEOUT_SEC_INT,
+        bundle.putInt(KEY_SATELLITE_ROAMING_ESOS_INACTIVITY_TIMEOUT_SEC_INT,
                 ESOS_INACTIVITY_TIMEOUT_SEC);
         when(mMockSatelliteController.getPersistableBundle(anyInt())).thenReturn(bundle);
 
@@ -672,8 +670,8 @@
         processAllMessages();
 
         // SatelliteSessionController should move to CONNECTED state
-        assertSuccessfulModemStateChangedCallback(
-                mTestSatelliteModemStateCallback, SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED);
+        assertSuccessfulModemStateChangedCallback(mTestSatelliteModemStateCallback,
+                SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED);
         assertEquals(STATE_CONNECTED, mTestSatelliteSessionController.getCurrentStateName());
         assertTrue(mTestSatelliteSessionController.isNbIotInactivityTimerStarted());
         verify(mMockDatagramController).onSatelliteModemStateChanged(
@@ -830,8 +828,8 @@
         processAllMessages();
 
         // SatelliteSessionController should move to CONNECTED state
-        assertSuccessfulModemStateChangedCallback(
-                mTestSatelliteModemStateCallback, SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED);
+        assertSuccessfulModemStateChangedCallback(mTestSatelliteModemStateCallback,
+                SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED);
         assertEquals(STATE_CONNECTED, mTestSatelliteSessionController.getCurrentStateName());
         verify(mMockDatagramController).onSatelliteModemStateChanged(
                 SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED);
@@ -856,8 +854,8 @@
         processAllMessages();
 
         // SatelliteSessionController should move to CONNECTED state
-        assertSuccessfulModemStateChangedCallback(
-                mTestSatelliteModemStateCallback, SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED);
+        assertSuccessfulModemStateChangedCallback(mTestSatelliteModemStateCallback,
+                SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED);
         assertEquals(STATE_CONNECTED, mTestSatelliteSessionController.getCurrentStateName());
         verify(mMockDatagramController).onSatelliteModemStateChanged(
                 SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED);
@@ -892,8 +890,8 @@
         processAllMessages();
 
         // SatelliteSessionController should move to CONNECTED state
-        assertSuccessfulModemStateChangedCallback(
-                mTestSatelliteModemStateCallback, SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED);
+        assertSuccessfulModemStateChangedCallback(mTestSatelliteModemStateCallback,
+                SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED);
         assertEquals(STATE_CONNECTED, mTestSatelliteSessionController.getCurrentStateName());
 
         // Wait for timeout
@@ -1106,7 +1104,7 @@
         moveSatelliteToEnablingState();
 
         // Satellite enablement has failed
-        mTestSatelliteSessionController.onSatelliteEnablementFailed();
+        mTestSatelliteSessionController.onSatelliteEnablementFailed(true);
         processAllMessages();
 
         // Satellite should move back to POWER_OFF state
@@ -1338,8 +1336,8 @@
         processAllMessages();
 
         // SatelliteSessionController should move to CONNECTED state
-        assertSuccessfulModemStateChangedCallback(
-                mTestSatelliteModemStateCallback, SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED);
+        assertSuccessfulModemStateChangedCallback(mTestSatelliteModemStateCallback,
+                SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED);
         assertEquals(STATE_CONNECTED, mTestSatelliteSessionController.getCurrentStateName());
         verify(mMockDatagramController).onSatelliteModemStateChanged(
                 SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED);
@@ -1361,7 +1359,7 @@
         moveSatelliteToDisablingState();
 
         // Satellite disabled request failed
-        mTestSatelliteSessionController.onSatelliteEnablementFailed();
+        mTestSatelliteSessionController.onSatelliteEnablementFailed(false);
         processAllMessages();
 
         // Satellite should stay in previous state as satellite disable request failed
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccPortTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccPortTest.java
index 5c1993f..a2b42af 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccPortTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccPortTest.java
@@ -29,7 +29,6 @@
 import static org.mockito.Mockito.verify;
 
 import android.os.Binder;
-import android.platform.test.flag.junit.SetFlagsRule;
 import android.telephony.TelephonyManager;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -38,11 +37,9 @@
 
 import com.android.internal.telephony.IccLogicalChannelRequest;
 import com.android.internal.telephony.TelephonyTest;
-import com.android.internal.telephony.flags.Flags;
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -61,13 +58,9 @@
 
     private int mPhoneId = 0;
 
-    @Rule
-    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
-
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mSetFlagsRule.enableFlags(Flags.FLAG_CLEANUP_OPEN_LOGICAL_CHANNEL_RECORD_ON_DISPOSE);
         mUiccCard = mock(UiccCard.class);
         mIccCardStatus = mock(IccCardStatus.class);
         /* initially there are no application available */