Merge "Listen for SimultaneousCallingTracker updates in TelecomAccountRegistry." into main
diff --git a/Android.bp b/Android.bp
index a943299..c717d86 100644
--- a/Android.bp
+++ b/Android.bp
@@ -83,6 +83,8 @@
     proto: {
         type: "lite",
     },
+
+    generate_product_characteristics_rro: true,
 }
 
 // Allow other applications to use public constants from SlicePurchaseController
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index b2548f1..074de4a 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -172,6 +172,12 @@
     <!-- Needed to bind the domain selection service. -->
     <uses-permission android:name="android.permission.BIND_DOMAIN_SELECTION_SERVICE" />
 
+    <!-- Needed to send safety center updates for cellular transparency features   -->
+    <uses-permission android:name="android.permission.SEND_SAFETY_CENTER_UPDATE"/>
+
+    <!-- Needed because the DISPLAY_EMERGENCY_MESSAGE ConnectionEvent contains a PendingIntent to activate the satellite feature. -->
+    <uses-permission android:name="com.google.android.apps.stargate.permission.SEND_EMERGENCY_INTENTS"/>
+
     <application android:name="PhoneApp"
             android:persistent="true"
             android:label="@string/phoneAppLabel"
@@ -575,6 +581,14 @@
             android:name="com.android.internal.telephony.uicc.ShowInstallAppNotificationReceiver"
             android:exported="false"/>
 
+        <receiver
+            android:name=".security.SafetySourceReceiver"
+            android:exported="false">
+            <intent-filter>
+                <action android:name="android.safetycenter.action.REFRESH_SAFETY_SOURCES"/>
+            </intent-filter>
+        </receiver>
+
         <activity
             android:name="com.android.phone.settings.PickSmsSubscriptionActivity"
             android:exported="false"
diff --git a/OWNERS b/OWNERS
index 53b9401..96033ab 100644
--- a/OWNERS
+++ b/OWNERS
@@ -2,4 +2,4 @@
 
 per-file *SimPhonebookProvider* = file:platform/packages/apps/Contacts:/OWNERS
 
-per-file config.xml=hwangoo@google.com,forestchoi@google.com,avinashmp@google.com,mkoon@google.com,seheele@google.com,radhikaagrawal@google.com
+per-file config.xml=hwangoo@google.com,forestchoi@google.com,avinashmp@google.com,mkoon@google.com,seheele@google.com,radhikaagrawal@google.com,jdyou@google.com
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index b4c7573..0f4321a 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -674,7 +674,7 @@
     <string name="sim_description_emergency_calls" msgid="5146872803938897296">"အရေးပေါ် ခေါ်ဆိုမှုသာလျှင်"</string>
     <string name="sim_description_default" msgid="7474671114363724971">"SIM ကတ်၊ အပေါက်: <xliff:g id="SLOT_ID">%s</xliff:g>"</string>
     <string name="accessibility_settings_activity_title" msgid="7883415189273700298">"အများသုံးနိုင်မှု"</string>
-    <string name="status_hint_label_incoming_wifi_call" msgid="2606052595898044071">"အောက်ပါမှ Wi-Fi ခေါ်ခြင်း"</string>
+    <string name="status_hint_label_incoming_wifi_call" msgid="2606052595898044071">"Wi-Fi ဖုန်းခေါ်နေသည်"</string>
     <string name="status_hint_label_wifi_call" msgid="942993035689809853">"Wi-Fi ခေါ်ဆိုမှု"</string>
     <string name="message_decode_error" msgid="1061856591500290887">"စာကို ကုဒ်ဖွင့်နေစဉ် အမှားရှိခဲ့သည်။"</string>
     <string name="callFailed_cdma_activation" msgid="5392057031552253550">"SIM ကဒ်သည် သင့် ဖုန်းဝန်ဆောင်မှုအား အသက်သွင်းခဲ့ပြီး သင့်ဖုန်း၏ ကွန်ယက်ပြင်ပဒေတာသုံးနိုင်စွမ်းအား ပြင်ဆင်မွမ်းမံပြီးဖြစ်၏။"</string>
diff --git a/res/values/config.xml b/res/values/config.xml
index 7cd4e18..f8aeb5e 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -337,6 +337,15 @@
         <item>de</item>
     </string-array>
 
+    <!-- Array of countries that a normal service capable subscription is preferred
+         for emergency calls. Values should be ISO3166 country codes in lowercase. -->
+    <string-array name="config_countries_prefer_normal_service_capable_subscription"
+            translatable="false">
+        <!-- b/317945295 -->
+        <item>in</item>
+        <item>sg</item>
+    </string-array>
+
     <!-- The component name(a flattened ComponentName string) for the telephony domain selection
          service. The device should fallback to the modem based domain selection architecture
          if this is not configured. -->
diff --git a/src/com/android/phone/DiagnosticDataCollector.java b/src/com/android/phone/DiagnosticDataCollector.java
index bdd9ce9..e0b1dac 100644
--- a/src/com/android/phone/DiagnosticDataCollector.java
+++ b/src/com/android/phone/DiagnosticDataCollector.java
@@ -74,16 +74,16 @@
     }
 
     public void persistEmergencyDianosticData(@NonNull DataCollectorConfig.Adapter dc,
-            @NonNull TelephonyManager.EmergencyCallDiagnosticParams edp, @NonNull String tag) {
+            @NonNull TelephonyManager.EmergencyCallDiagnosticData ecdData, @NonNull String tag) {
 
-        if (edp.isTelephonyDumpSysCollectionEnabled()) {
+        if (ecdData.isTelephonyDumpsysCollectionEnabled()) {
             persistTelephonyState(dc, tag);
         }
-        if (edp.isTelecomDumpSysCollectionEnabled()) {
+        if (ecdData.isTelecomDumpsysCollectionEnabled()) {
             persistTelecomState(dc, tag);
         }
-        if (edp.isLogcatCollectionEnabled()) {
-            persistLogcat(dc, tag, edp.getLogcatCollectionStartTimeMillis());
+        if (ecdData.isLogcatCollectionEnabled()) {
+            persistLogcat(dc, tag, ecdData.getLogcatCollectionStartTimeMillis());
         }
     }
 
diff --git a/src/com/android/phone/PhoneApp.java b/src/com/android/phone/PhoneApp.java
index df151bf..bb663dc 100644
--- a/src/com/android/phone/PhoneApp.java
+++ b/src/com/android/phone/PhoneApp.java
@@ -38,7 +38,11 @@
             mPhoneGlobals = new PhoneGlobals(this);
             mPhoneGlobals.onCreate();
 
-            TelecomAccountRegistry.getInstance(this).setupOnBoot();
+            TelecomAccountRegistry telecomAccountRegistry =
+                    TelecomAccountRegistry.getInstance(this);
+            if (telecomAccountRegistry != null) {
+                telecomAccountRegistry.setupOnBoot();
+            }
         }
     }
 }
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 7fba651..2ae39df 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -241,14 +241,14 @@
     private final CarrierVvmPackageInstalledReceiver mCarrierVvmPackageInstalledReceiver =
             new CarrierVvmPackageInstalledReceiver();
 
-    private final SettingsObserver mSettingsObserver;
+    private SettingsObserver mSettingsObserver;
     private BinderCallsStats.SettingsObserver mBinderCallsSettingsObserver;
 
     // Mapping of phone ID to the associated TelephonyCallback. These should be registered without
     // fine or coarse location since we only use ServiceState for
     private PhoneAppCallback[] mTelephonyCallbacks;
 
-    private FeatureFlags mFeatureFlags;
+    private FeatureFlags mFeatureFlags = new FeatureFlagsImpl();
 
     private class PhoneAppCallback extends TelephonyCallback implements
             TelephonyCallback.ServiceStateListener {
@@ -462,7 +462,13 @@
     public PhoneGlobals(Context context) {
         super(context);
         sMe = this;
-        mSettingsObserver = new SettingsObserver(context, mHandler);
+        if (mFeatureFlags.enforceTelephonyFeatureMappingForPublicApis()) {
+            if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+                mSettingsObserver = new SettingsObserver(context, mHandler);
+            }
+        } else {
+            mSettingsObserver = new SettingsObserver(context, mHandler);
+        }
     }
 
     public void onCreate() {
@@ -470,6 +476,13 @@
 
         ContentResolver resolver = getContentResolver();
 
+        if (mFeatureFlags.enforceTelephonyFeatureMappingForPublicApis()) {
+            if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+                Log.v(LOG_TAG, "onCreate()... but not defined FEATURE_TELEPHONY");
+                return;
+            }
+        }
+
         // Initialize the shim from frameworks/opt/telephony into packages/services/Telephony.
         TelephonyLocalConnection.setInstance(new LocalConnectionImpl(this));
 
@@ -499,7 +512,6 @@
             DomainSelectionResolver.make(this, dssComponentName);
 
             // Initialize the telephony framework
-            mFeatureFlags = new FeatureFlagsImpl();
             PhoneFactory.makeDefaultPhones(this, mFeatureFlags);
 
             // Initialize the DomainSelectionResolver after creating the Phone instance
@@ -1173,7 +1185,8 @@
             msg.arg1 = mDefaultDataSubId;
             msg.sendToTarget();
         } else if (dataAllowed && dataIsNowRoaming(mDefaultDataSubId)) {
-            if (!shouldShowRoamingNotification(roamingOperatorNumeric)) {
+            if (!shouldShowRoamingNotification(roamingOperatorNumeric != null
+                        ? roamingOperatorNumeric : phone.getServiceState().getOperatorNumeric())) {
                 Log.d(LOG_TAG, "Skip showing roaming connected notification.");
                 return;
             }
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 43011e8..839d8cb 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -25,6 +25,7 @@
 import static android.telephony.TelephonyManager.HAL_SERVICE_RADIO;
 import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_COMMUNICATION_ALLOWED;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_ACCESS_BARRED;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED;
 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;
 
 import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_CDMA;
@@ -9453,17 +9454,17 @@
             enforceModifyPermission();
         }
 
-        if (reason == TelephonyManager.DATA_ENABLED_REASON_USER && enabled
-                && null != callingPackage && opEnableMobileDataByUser()) {
-            mAppOps.noteOp(AppOpsManager.OPSTR_ENABLE_MOBILE_DATA_BY_USER, Binder.getCallingUid(),
-                    callingPackage, null, null);
-        }
-
         enforceTelephonyFeatureWithException(callingPackage,
                 PackageManager.FEATURE_TELEPHONY_DATA, "setDataEnabledForReason");
 
+        int callingUid = Binder.getCallingUid();
         final long identity = Binder.clearCallingIdentity();
         try {
+            if (reason == TelephonyManager.DATA_ENABLED_REASON_USER && enabled
+                    && null != callingPackage && opEnableMobileDataByUser()) {
+                mAppOps.noteOp(AppOpsManager.OPSTR_ENABLE_MOBILE_DATA_BY_USER,
+                        callingUid, callingPackage, null, null);
+            }
             Phone phone = getPhone(subId);
             if (phone != null) {
                 if (reason == TelephonyManager.DATA_ENABLED_REASON_CARRIER) {
@@ -12876,26 +12877,26 @@
             long logcatStartTimestampMillis, boolean enableTelecomDump,
             boolean enableTelephonyDump) {
         DropBoxManager db = mApp.getSystemService(DropBoxManager.class);
-        TelephonyManager.EmergencyCallDiagnosticParams.Builder edpBuilder =
-                new TelephonyManager.EmergencyCallDiagnosticParams.Builder();
-        edpBuilder
-                .setTelecomDumpSysCollectionEnabled(enableTelecomDump)
-                .setTelephonyDumpSysCollectionEnabled(enableTelephonyDump);
+        TelephonyManager.EmergencyCallDiagnosticData.Builder ecdDataBuilder =
+                new TelephonyManager.EmergencyCallDiagnosticData.Builder();
+        ecdDataBuilder
+                .setTelecomDumpsysCollectionEnabled(enableTelecomDump)
+                .setTelephonyDumpsysCollectionEnabled(enableTelephonyDump);
         if (enableLogcat) {
-            edpBuilder.setLogcatCollectionStartTimeMillis(logcatStartTimestampMillis);
+            ecdDataBuilder.setLogcatCollectionStartTimeMillis(logcatStartTimestampMillis);
         }
-        TelephonyManager.EmergencyCallDiagnosticParams edp = edpBuilder.build();
-        Log.d(LOG_TAG, "persisting with Params " + edp.toString());
+        TelephonyManager.EmergencyCallDiagnosticData ecdData = ecdDataBuilder.build();
+        Log.d(LOG_TAG, "persisting with Params " + ecdData.toString());
         DiagnosticDataCollector ddc = new DiagnosticDataCollector(Runtime.getRuntime(),
                 Executors.newCachedThreadPool(), db,
                 mApp.getSystemService(ActivityManager.class).isLowRamDevice());
-        ddc.persistEmergencyDianosticData(new DataCollectorConfig.Adapter(), edp, dropboxTag);
+        ddc.persistEmergencyDianosticData(new DataCollectorConfig.Adapter(), ecdData, dropboxTag);
     }
 
     /**
      * Request telephony to persist state for debugging emergency call failures.
      *
-     * @param dropBoxTag                 Tag to use when persisting data to dropbox service.
+     * @param dropboxTag                 Tag to use when persisting data to dropbox service.
      * @param enableLogcat               whether to collect logcat output
      * @param logcatStartTimestampMillis timestamp from when logcat buffers would be persisted
      * @param enableTelecomDump          whether to collect telecom dumpsys
@@ -13000,13 +13001,14 @@
      * @param enableSatellite {@code true} to enable the satellite modem and
      *                        {@code false} to disable.
      * @param enableDemoMode {@code true} to enable demo mode and {@code false} to disable.
+     * @param isEmergency {@code true} to enable emergency mode, {@code false} otherwise.
      * @param callback The callback to get the result of the request.
      *
      * @throws SecurityException if the caller doesn't have the required permission.
      */
     @Override
     public void requestSatelliteEnabled(int subId, boolean enableSatellite, boolean enableDemoMode,
-            @NonNull IIntegerConsumer callback) {
+            boolean isEmergency, @NonNull IIntegerConsumer callback) {
         enforceSatelliteCommunicationPermission("requestSatelliteEnabled");
         if (enableSatellite) {
             ResultReceiver resultReceiver = new ResultReceiver(mMainThreadHandler) {
@@ -13077,6 +13079,22 @@
     }
 
     /**
+     * Request to get whether the satellite service is enabled with emergency mode.
+     *
+     * @param subId The subId of the subscription to check whether the satellite demo mode
+     *              is enabled for.
+     * @param result The result receiver that returns whether the satellite emergency mode is
+     *               enabled if the request is successful or an error code if the request failed.
+     *
+     * @throws SecurityException if the caller doesn't have the required permission.
+     */
+    @Override
+    public void requestIsEmergencyModeEnabled(int subId, @NonNull ResultReceiver result) {
+        enforceSatelliteCommunicationPermission("requestIsEmergencyModeEnabled");
+        result.send(SATELLITE_RESULT_REQUEST_NOT_SUPPORTED, null);
+    }
+
+    /**
      * Request to get whether the satellite service is supported on the device.
      *
      * @param subId The subId of the subscription to check satellite service support for.
@@ -13652,20 +13670,43 @@
     }
 
     /**
-     * This API can be used by only CTS to update the timeout duration in milliseconds whether
-     * the device is aligned with the satellite for demo mode
+     * This API can be used by only CTS to override the timeout durations used by the
+     * DatagramController module.
      *
      * @param timeoutMillis The timeout duration in millisecond.
      * @return {@code true} if the timeout duration is set successfully, {@code false} otherwise.
      */
-    public boolean setSatelliteDeviceAlignedTimeoutDuration(long timeoutMillis) {
-        Log.d(LOG_TAG, "setDeviceAlignedTimeoutDuration - " + timeoutMillis);
+    public boolean setDatagramControllerTimeoutDuration(
+            boolean reset, int timeoutType, long timeoutMillis) {
+        Log.d(LOG_TAG, "setDatagramControllerTimeoutDuration - " + timeoutMillis + ", reset="
+                + reset + ", timeoutMillis=" + timeoutMillis);
         TelephonyPermissions.enforceShellOnly(
-                Binder.getCallingUid(), "setDeviceAlignedTimeoutDuration");
+                Binder.getCallingUid(), "setDatagramControllerTimeoutDuration");
         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
-                "setDeviceAlignedTimeoutDuration");
-        return mSatelliteController.setSatelliteDeviceAlignedTimeoutDuration(timeoutMillis);
+                "setDatagramControllerTimeoutDuration");
+        return mSatelliteController.setDatagramControllerTimeoutDuration(
+                reset, timeoutType, timeoutMillis);
+    }
+
+    /**
+     * This API can be used by only CTS to override the timeout durations used by the
+     * SatelliteController module.
+     *
+     * @param timeoutMillis The timeout duration in millisecond.
+     * @return {@code true} if the timeout duration is set successfully, {@code false} otherwise.
+     */
+    public boolean setSatelliteControllerTimeoutDuration(
+            boolean reset, int timeoutType, long timeoutMillis) {
+        Log.d(LOG_TAG, "setSatelliteControllerTimeoutDuration - " + timeoutMillis + ", reset="
+                + reset + ", timeoutMillis=" + timeoutMillis);
+        TelephonyPermissions.enforceShellOnly(
+                Binder.getCallingUid(), "setSatelliteControllerTimeoutDuration");
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+                "setSatelliteControllerTimeoutDuration");
+        return mSatelliteController.setSatelliteControllerTimeoutDuration(
+                reset, timeoutType, timeoutMillis);
     }
 
     /**
@@ -13787,6 +13828,62 @@
     }
 
     /**
+     * Sets the service defined in ComponentName to be bound.
+     *
+     * This should only be used for testing.
+     * @return {@code true} if the DomainSelectionService to bind to was set,
+     *         {@code false} otherwise.
+     */
+    @Override
+    public boolean setDomainSelectionServiceOverride(ComponentName componentName) {
+        Log.i(LOG_TAG, "setDomainSelectionServiceOverride component=" + componentName);
+
+        TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
+                "setDomainSelectionServiceOverride");
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
+                getDefaultSubscription(), "setDomainSelectionServiceOverride");
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
+                return DomainSelectionResolver.getInstance()
+                        .setDomainSelectionServiceOverride(componentName);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+        return false;
+    }
+
+    /**
+     * Clears the DomainSelectionService override.
+     *
+     * This should only be used for testing.
+     * @return {@code true} if the DomainSelectionService override was cleared,
+     *         {@code false} otherwise.
+     */
+    @Override
+    public boolean clearDomainSelectionServiceOverride() {
+        Log.i(LOG_TAG, "clearDomainSelectionServiceOverride");
+
+        TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
+                "clearDomainSelectionServiceOverride");
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
+                getDefaultSubscription(), "clearDomainSelectionServiceOverride");
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
+                return DomainSelectionResolver.getInstance()
+                        .clearDomainSelectionServiceOverride();
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+        return false;
+    }
+
+    /**
      * Enable or disable notifications sent for cellular identifier disclosure events.
      *
      * Disclosure events are defined as instances where a device has sent a cellular identifier
diff --git a/src/com/android/phone/TelephonyShellCommand.java b/src/com/android/phone/TelephonyShellCommand.java
index f7a3640d..c55cc6c 100644
--- a/src/com/android/phone/TelephonyShellCommand.java
+++ b/src/com/android/phone/TelephonyShellCommand.java
@@ -26,6 +26,7 @@
 import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.ComponentName;
 import android.content.Context;
 import android.net.Uri;
 import android.os.Binder;
@@ -190,8 +191,11 @@
             "set-satellite-listening-timeout-duration";
     private static final String SET_SATELLITE_POINTING_UI_CLASS_NAME =
             "set-satellite-pointing-ui-class-name";
-    private static final String SET_SATELLITE_DEVICE_ALIGNED_TIMEOUT_DURATION =
-            "set-satellite-device-aligned-timeout-duration";
+    private static final String SET_DATAGRAM_CONTROLLER_TIMEOUT_DURATION =
+            "set-datagram-controller-timeout-duration";
+
+    private static final String SET_SATELLITE_CONTROLLER_TIMEOUT_DURATION =
+            "set-satellite-controller-timeout-duration";
     private static final String SET_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE =
             "set-emergency-call-to-satellite-handover-type";
     private static final String SET_COUNTRY_CODES = "set-country-codes";
@@ -202,6 +206,10 @@
     private static final String SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE =
             "set-should-send-datagram-to-modem-in-demo-mode";
 
+    private static final String DOMAIN_SELECTION_SUBCOMMAND = "domainselection";
+    private static final String DOMAIN_SELECTION_SET_SERVICE_OVERRIDE = "set-dss-override";
+    private static final String DOMAIN_SELECTION_CLEAR_SERVICE_OVERRIDE = "clear-dss-override";
+
     private static final String INVALID_ENTRY_ERROR = "An emergency number (only allow '0'-'9', "
             + "'*', '#' or '+') needs to be specified after -a in the command ";
 
@@ -382,6 +390,8 @@
                 return setCarrierServicePackageOverride();
             case CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE:
                 return clearCarrierServicePackageOverride();
+            case DOMAIN_SELECTION_SUBCOMMAND:
+                return handleDomainSelectionCommand();
             case SET_SATELLITE_SERVICE_PACKAGE_NAME:
                 return handleSetSatelliteServicePackageNameCommand();
             case SET_SATELLITE_GATEWAY_SERVICE_PACKAGE_NAME:
@@ -390,8 +400,10 @@
                 return handleSetSatelliteListeningTimeoutDuration();
             case SET_SATELLITE_POINTING_UI_CLASS_NAME:
                 return handleSetSatellitePointingUiClassNameCommand();
-            case SET_SATELLITE_DEVICE_ALIGNED_TIMEOUT_DURATION:
-                return handleSettSatelliteDeviceAlignedTimeoutDuration();
+            case SET_DATAGRAM_CONTROLLER_TIMEOUT_DURATION:
+                return handleSetDatagramControllerTimeoutDuration();
+            case SET_SATELLITE_CONTROLLER_TIMEOUT_DURATION:
+                return handleSetSatelliteControllerTimeoutDuration();
             case SET_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE:
                 return handleSetEmergencyCallToSatelliteHandoverType();
             case SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE:
@@ -456,6 +468,7 @@
         onHelpRadio();
         onHelpImei();
         onHelpSatellite();
+        onHelpDomainSelection();
     }
 
     private void onHelpD2D() {
@@ -843,6 +856,15 @@
         pw.println("          is specified, it will choose the default voice SIM slot.");
     }
 
+    private void onHelpDomainSelection() {
+        PrintWriter pw = getOutPrintWriter();
+        pw.println("Domain Selection Commands:");
+        pw.println("  domainselection set-dss-override COMPONENT_NAME");
+        pw.println("    Sets the service defined in COMPONENT_NAME to be bound");
+        pw.println("  domainselection clear-dss-override");
+        pw.println("    Clears DomainSelectionService override.");
+    }
+
     private int handleImsCommand() {
         String arg = getNextArg();
         if (arg == null) {
@@ -3351,31 +3373,85 @@
         return 0;
     }
 
-    private int handleSettSatelliteDeviceAlignedTimeoutDuration() {
+    private int handleSetDatagramControllerTimeoutDuration() {
         PrintWriter errPw = getErrPrintWriter();
+        boolean reset = false;
+        int timeoutType = 0;
         long timeoutMillis = 0;
 
         String opt;
         while ((opt = getNextOption()) != null) {
             switch (opt) {
-                case "-t": {
+                case "-d": {
                     timeoutMillis = Long.parseLong(getNextArgRequired());
                     break;
                 }
+                case "-r": {
+                    reset = true;
+                    break;
+                }
+                case "-t": {
+                    timeoutType = Integer.parseInt(getNextArgRequired());
+                    break;
+                }
             }
         }
-        Log.d(LOG_TAG, "handleSettSatelliteDeviceAlignedTimeoutDuration: timeoutMillis="
-                + timeoutMillis);
+        Log.d(LOG_TAG, "setDatagramControllerTimeoutDuration: timeoutMillis="
+                + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
 
         try {
-            boolean result = mInterface.setSatelliteDeviceAlignedTimeoutDuration(timeoutMillis);
+            boolean result = mInterface.setDatagramControllerTimeoutDuration(
+                    reset, timeoutType, timeoutMillis);
             if (VDBG) {
-                Log.v(LOG_TAG, "setSatelliteDeviceAlignedTimeoutDuration " + timeoutMillis
+                Log.v(LOG_TAG, "setDatagramControllerTimeoutDuration " + timeoutMillis
                         + ", result = " + result);
             }
             getOutPrintWriter().println(result);
         } catch (RemoteException e) {
-            Log.w(LOG_TAG, "setSatelliteDeviceAlignedTimeoutDuration: " + timeoutMillis
+            Log.w(LOG_TAG, "setDatagramControllerTimeoutDuration: " + timeoutMillis
+                    + ", error = " + e.getMessage());
+            errPw.println("Exception: " + e.getMessage());
+            return -1;
+        }
+        return 0;
+    }
+
+    private int handleSetSatelliteControllerTimeoutDuration() {
+        PrintWriter errPw = getErrPrintWriter();
+        boolean reset = false;
+        int timeoutType = 0;
+        long timeoutMillis = 0;
+
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            switch (opt) {
+                case "-d": {
+                    timeoutMillis = Long.parseLong(getNextArgRequired());
+                    break;
+                }
+                case "-r": {
+                    reset = true;
+                    break;
+                }
+                case "-t": {
+                    timeoutType = Integer.parseInt(getNextArgRequired());
+                    break;
+                }
+            }
+        }
+        Log.d(LOG_TAG, "setSatelliteControllerTimeoutDuration: timeoutMillis="
+                + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
+
+        try {
+            boolean result = mInterface.setSatelliteControllerTimeoutDuration(
+                    reset, timeoutType, timeoutMillis);
+            if (VDBG) {
+                Log.v(LOG_TAG, "setSatelliteControllerTimeoutDuration " + timeoutMillis
+                        + ", result = " + result);
+            }
+            getOutPrintWriter().println(result);
+        } catch (RemoteException e) {
+            Log.w(LOG_TAG, "setSatelliteControllerTimeoutDuration: " + timeoutMillis
                     + ", error = " + e.getMessage());
             errPw.println("Exception: " + e.getMessage());
             return -1;
@@ -3744,6 +3820,66 @@
         return 0;
     }
 
+    private int handleDomainSelectionCommand() {
+        String arg = getNextArg();
+        if (arg == null) {
+            onHelpDomainSelection();
+            return 0;
+        }
+
+        switch (arg) {
+            case DOMAIN_SELECTION_SET_SERVICE_OVERRIDE: {
+                return handleDomainSelectionSetServiceOverrideCommand();
+            }
+            case DOMAIN_SELECTION_CLEAR_SERVICE_OVERRIDE: {
+                return handleDomainSelectionClearServiceOverrideCommand();
+            }
+        }
+
+        return -1;
+    }
+
+    // domainselection set-dss-override
+    private int handleDomainSelectionSetServiceOverrideCommand() {
+        PrintWriter errPw = getErrPrintWriter();
+
+        String componentName = getNextArg();
+
+        try {
+            boolean result = mInterface.setDomainSelectionServiceOverride(
+                    ComponentName.unflattenFromString(componentName));
+            if (VDBG) {
+                Log.v(LOG_TAG, "domainselection set-dss-override "
+                        + componentName + ", result=" + result);
+            }
+            getOutPrintWriter().println(result);
+        } catch (Exception e) {
+            Log.w(LOG_TAG, "domainselection set-dss-override "
+                    + componentName + ", error=" + e.getMessage());
+            errPw.println("Exception: " + e.getMessage());
+            return -1;
+        }
+        return 0;
+    }
+
+    // domainselection clear-dss-override
+    private int handleDomainSelectionClearServiceOverrideCommand() {
+        PrintWriter errPw = getErrPrintWriter();
+
+        try {
+            boolean result = mInterface.clearDomainSelectionServiceOverride();
+            if (VDBG) {
+                Log.v(LOG_TAG, "domainselection clear-dss-override result=" + result);
+            }
+            getOutPrintWriter().println(result);
+        } catch (RemoteException e) {
+            Log.w(LOG_TAG, "domainselection clear-dss-override error=" + e.getMessage());
+            errPw.println("Exception: " + e.getMessage());
+            return -1;
+        }
+        return 0;
+    }
+
     /**
      * Building the string that can be used to build the JsonObject which supports to stub the data
      * in CarrierAllowListInfo for CTS testing. sample format is like
diff --git a/src/com/android/phone/security/SafetySourceReceiver.java b/src/com/android/phone/security/SafetySourceReceiver.java
new file mode 100644
index 0000000..d2be1a1
--- /dev/null
+++ b/src/com/android/phone/security/SafetySourceReceiver.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone.security;
+
+import static android.safetycenter.SafetyCenterManager.ACTION_REFRESH_SAFETY_SOURCES;
+import static android.safetycenter.SafetyCenterManager.EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.flags.Flags;
+import com.android.phone.PhoneGlobals;
+
+public class SafetySourceReceiver extends BroadcastReceiver {
+    @Override
+    public void onReceive(Context context, Intent intent) {
+
+        // If none of the features that depend on this receiver are enabled, there's no reason
+        // to progress.
+        if (!Flags.enableIdentifierDisclosureTransparencyUnsolEvents()
+                || !Flags.enableModemCipherTransparencyUnsolEvents()) {
+            return;
+        }
+
+        String action = intent.getAction();
+        if (!ACTION_REFRESH_SAFETY_SOURCES.equals(action)) {
+            return;
+        }
+
+        String refreshBroadcastId =
+                intent.getStringExtra(EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID);
+        if (refreshBroadcastId == null) {
+            return;
+        }
+
+        if (Flags.enforceTelephonyFeatureMappingForPublicApis()) {
+            if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+                refreshSafetySources(refreshBroadcastId);
+            }
+        } else {
+            refreshSafetySources(refreshBroadcastId);
+        }
+    }
+
+    private void refreshSafetySources(String refreshBroadcastId) {
+        Phone phone = getDefaultPhone();
+        // It's possible that phones have not been created yet. Safety center may send a refresh
+        // broadcast very early on.
+        if (phone != null) {
+            phone.refreshSafetySources(refreshBroadcastId);
+        }
+
+    }
+
+    @VisibleForTesting
+    public Phone getDefaultPhone() {
+        return PhoneGlobals.getPhone();
+    }
+}
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index 09194a0..a246a1c 100644
--- a/src/com/android/services/telephony/TelecomAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecomAccountRegistry.java
@@ -1323,7 +1323,18 @@
      */
     public static synchronized TelecomAccountRegistry getInstance(Context context) {
         if (sInstance == null && context != null) {
-            sInstance = new TelecomAccountRegistry(context);
+            if (Flags.enforceTelephonyFeatureMappingForPublicApis()) {
+                PackageManager pm = context.getPackageManager();
+                if (pm != null && pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
+                        && pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CALLING)) {
+                    sInstance = new TelecomAccountRegistry(context);
+                } else {
+                    Log.d(LOG_TAG, "Not initializing TelecomAccountRegistry: "
+                            + "missing telephony/calling feature(s)");
+                }
+            } else {
+                sInstance = new TelecomAccountRegistry(context);
+            }
         }
         return sInstance;
     }
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 9fe73e2..7749a2c 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -964,7 +964,7 @@
     private Integer mEmergencyServiceCategory = null;
 
     protected TelephonyConnection(com.android.internal.telephony.Connection originalConnection,
-            String callId, @android.telecom.Call.Details.CallDirection int callDirection) {
+            String callId, int callDirection) {
         setCallDirection(callDirection);
         setTelecomCallId(callId);
         if (originalConnection != null) {
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 8a0382a..a510e51 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -37,7 +37,6 @@
 import android.os.Bundle;
 import android.os.ParcelUuid;
 import android.os.PersistableBundle;
-import android.provider.DeviceConfig;
 import android.telecom.Conference;
 import android.telecom.Conferenceable;
 import android.telecom.Connection;
@@ -54,7 +53,7 @@
 import android.telephony.DataSpecificRegistrationInfo;
 import android.telephony.DomainSelectionService;
 import android.telephony.DomainSelectionService.SelectionAttributes;
-import android.telephony.EmergencyRegResult;
+import android.telephony.EmergencyRegistrationResult;
 import android.telephony.NetworkRegistrationInfo;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.RadioAccessFamily;
@@ -141,8 +140,6 @@
     // Timeout before we terminate the outgoing DSDA call if HOLD did not complete in time on the
     // existing call.
     private static final int DEFAULT_DSDA_OUTGOING_CALL_HOLD_TIMEOUT_MS = 2000;
-    private static final String KEY_DOMAIN_COMPARE_FEATURE_ENABLED_FLAG =
-            "is_domain_selection_compare_feature_enabled";
 
     // If configured, reject attempts to dial numbers matching this pattern.
     private static final Pattern CDMA_ACTIVATION_CODE_REGEX_PATTERN =
@@ -231,7 +228,6 @@
     private DomainSelectionResolver mDomainSelectionResolver;
     private EmergencyCallDomainSelectionConnection mEmergencyCallDomainSelectionConnection;
     private TelephonyConnection mEmergencyConnection;
-    private String mEmergencyCallId = null;
     private Executor mDomainSelectionMainExecutor;
     private ImsManager mImsManager = null;
     private DomainSelectionConnection mDomainSelectionConnection;
@@ -576,8 +572,7 @@
                     }
                     // Update the domain in the case that it changes,for example during initial
                     // setup or when there was an srvcc or internal redial.
-                    mEmergencyStateTracker.onEmergencyCallDomainUpdated(
-                            origConn.getPhoneType(), c.getTelecomCallId());
+                    mEmergencyStateTracker.onEmergencyCallDomainUpdated(origConn.getPhoneType(), c);
                 }
 
                 @Override
@@ -590,8 +585,8 @@
                             + ", state=" + state);
                     if (c.getState() == Connection.STATE_ACTIVE) {
                         mEmergencyStateTracker.onEmergencyCallStateChanged(
-                                c.getOriginalConnection().getState(), c.getTelecomCallId());
-                        releaseEmergencyCallDomainSelection(false);
+                                c.getOriginalConnection().getState(), c);
+                        releaseEmergencyCallDomainSelection(false, true);
                     }
                 }
 
@@ -609,8 +604,8 @@
                         return;
                     }
                     Log.i(this, "onConnectionPropertiesChanged prop=" + connectionProperties);
-                    mEmergencyStateTracker.onEmergencyCallPropertiesChanged(connectionProperties,
-                            c.getTelecomCallId());
+                    mEmergencyStateTracker.onEmergencyCallPropertiesChanged(
+                            connectionProperties, c);
                 }
             };
 
@@ -734,9 +729,8 @@
                         Phone phone = mEmergencyCallDomainSelectionConnection.getPhone();
                         mEmergencyConnection.removeTelephonyConnectionListener(
                                 mEmergencyConnectionListener);
-                        releaseEmergencyCallDomainSelection(true);
-                        mEmergencyStateTracker.endCall(mEmergencyCallId);
-                        mEmergencyCallId = null;
+                        releaseEmergencyCallDomainSelection(true, false);
+                        mEmergencyStateTracker.endCall(c);
                         retryOutgoingOriginalConnection(c, phone, isPermanentFailure);
                         return;
                     }
@@ -1108,6 +1102,7 @@
         final Phone phone = getPhoneForAccount(request.getAccountHandle(), isEmergencyNumber,
                 /* Note: when not an emergency, handle can be null for unknown callers */
                 handle == null ? null : handle.getSchemeSpecificPart());
+        ImsPhone imsPhone = phone != null ? (ImsPhone) phone.getImsPhone() : null;
 
         boolean isPhoneWifiCallingEnabled = phone != null && phone.isWifiCallingEnabled();
         boolean needToTurnOnRadio = (isEmergencyNumber && (!isRadioOn() || isAirplaneModeOn))
@@ -1215,8 +1210,9 @@
             }
 
             if (!isEmergencyNumber) {
-                if (mSatelliteController.isSatelliteEnabled()
-                        || isCallDisallowedDueToSatellite(phone)) {
+                if ((mSatelliteController.isSatelliteEnabled()
+                        || isCallDisallowedDueToSatellite(phone))
+                        && (imsPhone == null || !imsPhone.canMakeWifiCall())) {
                     Log.d(this, "onCreateOutgoingConnection, cannot make call in satellite mode.");
                     return Connection.createFailedConnection(
                             mDisconnectCauseFactory.toTelecomDisconnectCause(
@@ -2228,6 +2224,10 @@
             }
         } catch (CallStateException e) {
             Log.e(this, e, "placeOutgoingConnection, phone.dial exception: " + e);
+            if (mDomainSelectionResolver.isDomainSelectionSupported()) {
+                // Notify EmergencyStateTracker and DomainSelector of the cancellation by exception
+                onLocalHangup(connection);
+            }
             connection.unregisterForCallEvents();
             handleCallStateException(e, connection, phone);
             return;
@@ -2285,14 +2285,6 @@
                 extras = new Bundle();
             }
             extras.putInt(PhoneConstants.EXTRA_DIAL_DOMAIN, domain);
-            // Add flag to bundle for comparing legacy and new domain selection results. When
-            // EXTRA_COMPARE_DOMAIN flag is true, legacy domain selection result is used for
-            // placing the call and if both the results are not same then bug report is generated.
-            DeviceConfig.Properties properties = //read all telephony properties
-                    DeviceConfig.getProperties(DeviceConfig.NAMESPACE_TELEPHONY);
-            boolean compareDomainSelection =
-                    properties.getBoolean(KEY_DOMAIN_COMPARE_FEATURE_ENABLED_FLAG, false);
-            extras.putBoolean(PhoneConstants.EXTRA_COMPARE_DOMAIN, compareDomainSelection);
 
             if (phone != null) {
                 Log.v(LOG_TAG, "Call dialing. Domain: " + domain);
@@ -2390,7 +2382,7 @@
         SelectionAttributes selectionAttributes =
                 new SelectionAttributes.Builder(phone.getPhoneId(), phone.getSubId(),
                         SELECTOR_TYPE_CALLING)
-                        .setNumber(number)
+                        .setAddress(Uri.fromParts(PhoneAccount.SCHEME_TEL, number, null))
                         .setEmergency(false)
                         .setVideoCall(VideoProfile.isVideo(videoState))
                         .build();
@@ -2428,19 +2420,19 @@
                 mEmergencyStateTracker = EmergencyStateTracker.getInstance();
             }
 
-            mEmergencyCallId = resultConnection.getTelecomCallId();
+            mEmergencyConnection = (TelephonyConnection) resultConnection;
             CompletableFuture<Integer> future = mEmergencyStateTracker.startEmergencyCall(
-                    phone, mEmergencyCallId, isTestEmergencyNumber);
+                    phone, resultConnection, isTestEmergencyNumber);
             future.thenAccept((result) -> {
                 Log.d(this, "startEmergencyCall-complete result=" + result);
-                if (mEmergencyCallId == null) {
+                if (mEmergencyConnection == null) {
                     Log.i(this, "startEmergencyCall-complete dialing canceled");
                     return;
                 }
                 if (result == android.telephony.DisconnectCause.NOT_DISCONNECTED) {
                     createEmergencyConnection(phone, (TelephonyConnection) resultConnection,
-                            numberToDial, request, needToTurnOnRadio,
-                            mEmergencyStateTracker.getEmergencyRegResult());
+                            numberToDial, isTestEmergencyNumber, request, needToTurnOnRadio,
+                            mEmergencyStateTracker.getEmergencyRegistrationResult());
                 } else {
                     mEmergencyConnection = null;
                     String reason = "Couldn't setup emergency call";
@@ -2453,18 +2445,17 @@
                     mIsEmergencyCallPending = false;
                 }
             });
-            mEmergencyConnection = (TelephonyConnection) resultConnection;
-            return resultConnection;
         }
-        Log.i(this, "placeEmergencyConnection returns null");
-        return null;
+        // Non TelephonyConnection type instance means dialing failure.
+        return resultConnection;
     }
 
     @SuppressWarnings("FutureReturnValueIgnored")
     private void createEmergencyConnection(final Phone phone,
             final TelephonyConnection resultConnection, final String number,
+            final boolean isTestEmergencyNumber,
             final ConnectionRequest request, boolean needToTurnOnRadio,
-            final EmergencyRegResult regResult) {
+            final EmergencyRegistrationResult regResult) {
         Log.i(this, "createEmergencyConnection");
 
         if (phone.getImsPhone() == null) {
@@ -2504,14 +2495,15 @@
         DomainSelectionService.SelectionAttributes attr =
                 EmergencyCallDomainSelectionConnection.getSelectionAttributes(
                         phone.getPhoneId(), phone.getSubId(), needToTurnOnRadio,
-                        request.getTelecomCallId(), number, 0, null, regResult);
+                        request.getTelecomCallId(), number, isTestEmergencyNumber,
+                        0, null, regResult);
 
         CompletableFuture<Integer> future =
                 mEmergencyCallDomainSelectionConnection.createEmergencyConnection(
                         attr, mEmergencyDomainSelectionConnectionCallback);
         future.thenAcceptAsync((result) -> {
             Log.d(this, "createEmergencyConnection-complete result=" + result);
-            if (mEmergencyCallId == null) {
+            if (mEmergencyConnection == null) {
                 Log.i(this, "createEmergencyConnection-complete dialing canceled");
                 return;
             }
@@ -2529,7 +2521,7 @@
         extras.putInt(PhoneConstants.EXTRA_DIAL_DOMAIN, NetworkRegistrationInfo.DOMAIN_CS);
         mDomainSelectionMainExecutor.execute(
                 () -> {
-                    if (mEmergencyCallId == null) {
+                    if (mEmergencyConnection == null) {
                         Log.i(this, "dialCsEmergencyCall dialing canceled");
                         return;
                     }
@@ -2537,14 +2529,16 @@
                 });
     }
 
-    private void releaseEmergencyCallDomainSelection(boolean cancel) {
+    private void releaseEmergencyCallDomainSelection(boolean cancel, boolean isActive) {
         if (mEmergencyCallDomainSelectionConnection != null) {
             if (cancel) mEmergencyCallDomainSelectionConnection.cancelSelection();
             else mEmergencyCallDomainSelectionConnection.finishSelection();
             mEmergencyCallDomainSelectionConnection = null;
         }
         mIsEmergencyCallPending = false;
-        mEmergencyConnection = null;
+        if (!isActive) {
+            mEmergencyConnection = null;
+        }
     }
 
     /**
@@ -2564,14 +2558,14 @@
         int callFailCause = c.getOriginalConnection().getPreciseDisconnectCause();
 
         Log.i(this, "maybeReselectDomain csCause=" +  callFailCause + ", psCause=" + reasonInfo);
-        if (TextUtils.equals(mEmergencyCallId, c.getTelecomCallId())) {
+        if (mEmergencyConnection == c) {
             if (mEmergencyCallDomainSelectionConnection != null) {
                 return maybeReselectDomainForEmergencyCall(c, callFailCause, reasonInfo);
             }
             Log.i(this, "maybeReselectDomain endCall()");
             c.removeTelephonyConnectionListener(mEmergencyConnectionListener);
-            mEmergencyStateTracker.endCall(c.getTelecomCallId());
-            mEmergencyCallId = null;
+            releaseEmergencyCallDomainSelection(false, false);
+            mEmergencyStateTracker.endCall(c);
             return false;
         }
 
@@ -2609,7 +2603,7 @@
                     EmergencyCallDomainSelectionConnection.getSelectionAttributes(
                             c.getPhone().getPhoneId(), c.getPhone().getSubId(), false,
                             c.getTelecomCallId(), c.getAddress().getSchemeSpecificPart(),
-                            callFailCause, reasonInfo, null);
+                            false, callFailCause, reasonInfo, null);
 
             CompletableFuture<Integer> future =
                     mEmergencyCallDomainSelectionConnection.reselectDomain(attr);
@@ -2618,7 +2612,7 @@
             if (future != null) {
                 future.thenAcceptAsync((result) -> {
                     Log.d(this, "reselectDomain-complete");
-                    if (mEmergencyCallId == null) {
+                    if (mEmergencyConnection == null) {
                         Log.i(this, "reselectDomain-complete dialing canceled");
                         return;
                     }
@@ -2630,9 +2624,8 @@
 
         Log.i(this, "maybeReselectDomainForEmergencyCall endCall()");
         c.removeTelephonyConnectionListener(mEmergencyConnectionListener);
-        releaseEmergencyCallDomainSelection(true);
-        mEmergencyStateTracker.endCall(c.getTelecomCallId());
-        mEmergencyCallId = null;
+        releaseEmergencyCallDomainSelection(true, false);
+        mEmergencyStateTracker.endCall(c);
         return false;
     }
 
@@ -2846,12 +2839,12 @@
             mEmergencyStateTracker = EmergencyStateTracker.getInstance();
         }
 
-        mEmergencyCallId = c.getTelecomCallId();
+        mEmergencyConnection = c;
         CompletableFuture<Integer> future = mEmergencyStateTracker.startEmergencyCall(
-                phone, mEmergencyCallId, isTestEmergencyNumber);
+                phone, c, isTestEmergencyNumber);
         future.thenAccept((result) -> {
             Log.d(this, "onEmergencyRedial-complete result=" + result);
-            if (mEmergencyCallId == null) {
+            if (mEmergencyConnection == null) {
                 Log.i(this, "onEmergencyRedial-complete dialing canceled");
                 return;
             }
@@ -2872,15 +2865,13 @@
                 mEmergencyCallDomainSelectionConnection =
                         (EmergencyCallDomainSelectionConnection) selectConnection;
 
-                mEmergencyConnection = c;
-
                 DomainSelectionService.SelectionAttributes attr =
                         EmergencyCallDomainSelectionConnection.getSelectionAttributes(
                                 phone.getPhoneId(),
                                 phone.getSubId(), false,
                                 c.getTelecomCallId(),
-                                c.getAddress().getSchemeSpecificPart(),
-                                0, null, mEmergencyStateTracker.getEmergencyRegResult());
+                                c.getAddress().getSchemeSpecificPart(), isTestEmergencyNumber,
+                                0, null, mEmergencyStateTracker.getEmergencyRegistrationResult());
 
                 CompletableFuture<Integer> domainFuture =
                         mEmergencyCallDomainSelectionConnection.createEmergencyConnection(
@@ -2892,6 +2883,7 @@
                     mIsEmergencyCallPending = false;
                 }, mDomainSelectionMainExecutor);
             } else {
+                mEmergencyConnection = null;
                 c.setTelephonyConnectionDisconnected(
                         mDisconnectCauseFactory.toTelecomDisconnectCause(result, "unknown error"));
                 c.close();
@@ -2903,7 +2895,7 @@
     private void recreateEmergencyConnection(final TelephonyConnection connection,
             final Phone phone, final @NetworkRegistrationInfo.Domain int result) {
         Log.d(this, "recreateEmergencyConnection result=" + result);
-        if (mEmergencyCallId == null) {
+        if (mEmergencyConnection == null) {
             Log.i(this, "recreateEmergencyConnection dialing canceled");
             return;
         }
@@ -2954,15 +2946,6 @@
 
         Bundle extras = new Bundle();
         extras.putInt(PhoneConstants.EXTRA_DIAL_DOMAIN, domain);
-        // Add flag to bundle for comparing legacy and new domain selection results. When
-        // EXTRA_COMPARE_DOMAIN flag is true, legacy domain selection result is used for
-        // placing the call and if both the results are not same then bug report is generated.
-        DeviceConfig.Properties properties = //read all telephony properties
-                DeviceConfig.getProperties(DeviceConfig.NAMESPACE_TELEPHONY);
-        boolean compareDomainSelection =
-                properties.getBoolean(KEY_DOMAIN_COMPARE_FEATURE_ENABLED_FLAG, false);
-        extras.putBoolean(PhoneConstants.EXTRA_COMPARE_DOMAIN, compareDomainSelection);
-
         com.android.internal.telephony.Connection originalConnection =
                 connection.getOriginalConnection();
         if (originalConnection instanceof ImsPhoneConnection) {
@@ -2997,16 +2980,25 @@
     }
 
     protected void onLocalHangup(TelephonyConnection c) {
-        if (TextUtils.equals(mEmergencyCallId, c.getTelecomCallId())) {
-            Log.i(this, "onLocalHangup " + mEmergencyCallId);
+        if (mEmergencyConnection == c) {
+            Log.i(this, "onLocalHangup " + c.getTelecomCallId());
             c.removeTelephonyConnectionListener(mEmergencyConnectionListener);
-            releaseEmergencyCallDomainSelection(true);
-            mEmergencyStateTracker.endCall(c.getTelecomCallId());
-            mEmergencyCallId = null;
+            releaseEmergencyCallDomainSelection(true, false);
+            mEmergencyStateTracker.endCall(c);
         }
     }
 
     @VisibleForTesting
+    public TelephonyConnection getEmergencyConnection() {
+        return mEmergencyConnection;
+    }
+
+    @VisibleForTesting
+    public void setEmergencyConnection(TelephonyConnection c) {
+        mEmergencyConnection = c;
+    }
+
+    @VisibleForTesting
     public TelephonyConnection.TelephonyConnectionListener getEmergencyConnectionListener() {
         return mEmergencyConnectionListener;
     }
diff --git a/src/com/android/services/telephony/domainselection/CrossSimRedialingController.java b/src/com/android/services/telephony/domainselection/CrossSimRedialingController.java
index 44904f4..d368d46 100644
--- a/src/com/android/services/telephony/domainselection/CrossSimRedialingController.java
+++ b/src/com/android/services/telephony/domainselection/CrossSimRedialingController.java
@@ -29,9 +29,12 @@
 import android.os.Message;
 import android.os.PersistableBundle;
 import android.os.SystemProperties;
+import android.telephony.AccessNetworkConstants;
 import android.telephony.Annotation.PreciseDisconnectCauses;
 import android.telephony.CarrierConfigManager;
+import android.telephony.NetworkRegistrationInfo;
 import android.telephony.PhoneNumberUtils;
+import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.emergency.EmergencyNumber;
@@ -144,7 +147,7 @@
      * @param selector The instance of {@link EmergencyCallDomainSelector}.
      * @param callId The call identifier.
      * @param number The dialing number.
-     * @param inService Indiates that normal service is available.
+     * @param inService Indicates that normal service is available.
      * @param roaming Indicates that it's in roaming or non-domestic network.
      * @param modemCount The number of active modem count
      */
@@ -228,12 +231,26 @@
     }
 
     /**
+     * Returns whether there is another slot with which normal service is available.
+     *
+     * @return {@code true} if there is another slot with which normal service is available.
+     *         {@code false} otherwise.
+     */
+    public boolean isThereOtherSlotInService() {
+        return isThereOtherSlot(true);
+    }
+
+    /**
      * Returns whether there is another slot emergency capable.
      *
      * @return {@code true} if there is another slot emergency capable,
      *         {@code false} otherwise.
      */
     public boolean isThereOtherSlot() {
+        return isThereOtherSlot(false);
+    }
+
+    private boolean isThereOtherSlot(boolean networkRegisteredOnly) {
         logi("isThereOtherSlot modemCount=" + mModemCount);
         if (mModemCount < 2) return false;
 
@@ -254,7 +271,13 @@
             int subId = SubscriptionManager.getSubscriptionId(i);
             if (mEmergencyNumberHelper.isEmergencyNumber(subId, mNumber)) {
                 logi("isThereOtherSlot index=" + i + "(" + subId + "), found");
-                return true;
+                if (networkRegisteredOnly) {
+                    if (isNetworkRegistered(subId)) {
+                        return true;
+                    }
+                } else {
+                    return true;
+                }
             } else {
                 logi("isThereOtherSlot index=" + i + "(" + subId + "), not emergency number");
             }
@@ -263,6 +286,31 @@
         return false;
     }
 
+    private boolean isNetworkRegistered(int subId) {
+        if (!SubscriptionManager.isValidSubscriptionId(subId)) return false;
+
+        TelephonyManager tm = mTelephonyManager.createForSubscriptionId(subId);
+        ServiceState ss = tm.getServiceState();
+        if (ss != null) {
+            NetworkRegistrationInfo nri = ss.getNetworkRegistrationInfo(
+                    NetworkRegistrationInfo.DOMAIN_PS,
+                    AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+            if (nri != null && nri.isNetworkRegistered()) {
+                // PS is IN_SERVICE state.
+                return true;
+            }
+            nri = ss.getNetworkRegistrationInfo(
+                    NetworkRegistrationInfo.DOMAIN_CS,
+                    AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+            if (nri != null && nri.isNetworkRegistered()) {
+                // CS is IN_SERVICE state.
+                return true;
+            }
+        }
+        logi("isNetworkRegistered subId=" + subId + " not network registered");
+        return false;
+    }
+
     /**
      * Caches the configuration.
      */
diff --git a/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java b/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
index 074fa64..05ae1f0 100644
--- a/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
+++ b/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
@@ -45,6 +45,7 @@
 import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_MAXIMUM_CELLULAR_SEARCH_TIMER_SEC_INT;
 import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_MAXIMUM_NUMBER_OF_EMERGENCY_TRIES_OVER_VOWIFI_INT;
 import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_PREFER_IMS_EMERGENCY_WHEN_VOICE_CALLS_ON_CS_BOOL;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_SCAN_LIMITED_SERVICE_AFTER_VOLTE_FAILURE_BOOL;
 import static android.telephony.CarrierConfigManager.ImsEmergency.SCAN_TYPE_FULL_SERVICE_FOLLOWED_BY_LIMITED_SERVICE;
 import static android.telephony.CarrierConfigManager.ImsEmergency.VOWIFI_REQUIRES_SETTING_ENABLED;
 import static android.telephony.CarrierConfigManager.ImsEmergency.VOWIFI_REQUIRES_VALID_EID;
@@ -77,13 +78,11 @@
 import android.telephony.DisconnectCause;
 import android.telephony.DomainSelectionService;
 import android.telephony.DomainSelectionService.SelectionAttributes;
-import android.telephony.EmergencyRegResult;
+import android.telephony.EmergencyRegistrationResult;
 import android.telephony.NetworkRegistrationInfo;
-import android.telephony.PhoneNumberUtils;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.TransportSelectorCallback;
-import android.telephony.emergency.EmergencyNumber;
 import android.telephony.ims.ImsManager;
 import android.telephony.ims.ImsMmTelManager;
 import android.telephony.ims.ProvisioningManager;
@@ -95,9 +94,7 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 import java.util.function.IntFunction;
 
 /**
@@ -121,6 +118,7 @@
     private static final LocalLog sLocalLog = new LocalLog(LOG_SIZE);
 
     private static List<String> sSimReadyAllowList;
+    private static List<String> sPreferSlotWithNormalServiceList;
 
     /**
      * Network callback used to determine whether Wi-Fi is connected or not.
@@ -160,7 +158,6 @@
     private @TransportType int mLastTransportType = TRANSPORT_TYPE_INVALID;
     private @DomainSelectionService.EmergencyScanType int mScanType;
     private @RadioAccessNetworkType List<Integer> mLastPreferredNetworks;
-    private boolean mIsTestEmergencyNumber;
 
     private CancellationSignal mCancelSignal;
 
@@ -183,6 +180,7 @@
     private boolean mRequiresImsRegistration;
     private boolean mRequiresVoLteEnabled;
     private boolean mLtePreferredAfterNrFailure;
+    private boolean mScanLimitedOnlyAfterVolteFailure;
 
     // Members for states
     private boolean mIsMonitoringConnectivity;
@@ -249,7 +247,7 @@
                 break;
 
             case MSG_NETWORK_SCAN_RESULT:
-                handleScanResult((EmergencyRegResult) msg.obj);
+                handleScanResult((EmergencyRegistrationResult) msg.obj);
                 break;
 
             case MSG_MAX_CELLULAR_TIMEOUT:
@@ -267,7 +265,7 @@
      *
      * @param result The scan result.
      */
-    private void handleScanResult(EmergencyRegResult result) {
+    private void handleScanResult(EmergencyRegistrationResult result) {
         logi("handleScanResult result=" + result);
 
         if (mLastTransportType == TRANSPORT_TYPE_WLAN) {
@@ -286,7 +284,7 @@
                       && (mScanType == DomainSelectionService.SCAN_TYPE_FULL_SERVICE)) {
                 mScanType = DomainSelectionService.SCAN_TYPE_LIMITED_SERVICE;
                 mWwanSelectorCallback.onRequestEmergencyNetworkScan(
-                        mLastPreferredNetworks, mScanType, mCancelSignal,
+                        mLastPreferredNetworks, mScanType, false, mCancelSignal,
                         (regResult) -> {
                             logi("requestScan-onComplete");
                             sendMessage(obtainMessage(MSG_NETWORK_SCAN_RESULT, regResult));
@@ -301,6 +299,7 @@
         removeMessages(MSG_NETWORK_SCAN_TIMEOUT);
         onWwanNetworkTypeSelected(getAccessNetworkType(result));
         mCancelSignal = null;
+        maybeModifyScanType(mLastNetworkType);
     }
 
     /**
@@ -309,7 +308,7 @@
      * @param result The result of network scan.
      * @return The selected network type.
      */
-    private @RadioAccessNetworkType int getAccessNetworkType(EmergencyRegResult result) {
+    private @RadioAccessNetworkType int getAccessNetworkType(EmergencyRegistrationResult result) {
         int accessNetworkType = result.getAccessNetwork();
         if (accessNetworkType != EUTRAN) return accessNetworkType;
 
@@ -327,12 +326,6 @@
     }
 
     @Override
-    public void cancelSelection() {
-        logi("cancelSelection");
-        finishSelection();
-    }
-
-    @Override
     public void reselectDomain(SelectionAttributes attr) {
         logi("reselectDomain attr=" + attr);
         mSelectionAttributes = attr;
@@ -345,7 +338,6 @@
         int cause = mSelectionAttributes.getCsDisconnectCause();
         mCrossSimRedialingController.notifyCallFailure(cause);
 
-        // TODO(b/258112541) make EMERGENCY_PERM_FAILURE and EMERGENCY_TEMP_FAILURE public api
         if (cause == EMERGENCY_PERM_FAILURE
                 || cause == EMERGENCY_TEMP_FAILURE) {
             logi("reselectDomain should redial on the other subscription");
@@ -359,11 +351,6 @@
             return;
         }
 
-        if (mIsTestEmergencyNumber) {
-            selectDomainForTestEmergencyNumber();
-            return;
-        }
-
         if (mTryCsWhenPsFails) {
             mTryCsWhenPsFails = false;
             // Initial state was CSFB available and dial PS failed.
@@ -409,6 +396,7 @@
 
     private void reselectDomainInternal() {
         post(() -> {
+            if (mDestroyed) return;
             requestScan(true, false, true);
             mDomainSelected = false;
         });
@@ -438,7 +426,6 @@
         logi("selectDomain attr=" + attr);
         mTransportSelectorCallback = cb;
         mSelectionAttributes = attr;
-        mIsTestEmergencyNumber = isTestEmergencyNumber(attr.getNumber());
 
         TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
         mModemCount = tm.getActiveModemCount();
@@ -525,6 +512,8 @@
         mRequiresVoLteEnabled = b.getBoolean(KEY_EMERGENCY_REQUIRES_VOLTE_ENABLED_BOOL);
         mLtePreferredAfterNrFailure = b.getBoolean(
                 KEY_EMERGENCY_LTE_PREFERRED_AFTER_NR_FAILED_BOOL);
+        mScanLimitedOnlyAfterVolteFailure = b.getBoolean(
+                KEY_SCAN_LIMITED_SERVICE_AFTER_VOLTE_FAILURE_BOOL);
         String[] numbers = b.getStringArray(KEY_EMERGENCY_CDMA_PREFERRED_NUMBERS_STRING_ARRAY);
 
         if (mImsRatsConfig == null) mImsRatsConfig = new int[0];
@@ -560,6 +549,7 @@
                 + ", requiresImsReg=" + mRequiresImsRegistration
                 + ", requiresVoLteEnabled=" + mRequiresVoLteEnabled
                 + ", ltePreferredAfterNr=" + mLtePreferredAfterNrFailure
+                + ", scanLimitedOnly=" + mScanLimitedOnlyAfterVolteFailure
                 + ", cdmaPreferredNumbers=" + arrayToString(numbers));
 
         mCdmaPreferredNumbers = Arrays.asList(numbers);
@@ -587,26 +577,43 @@
      * Caches the resource configuration.
      */
     private void readResourceConfiguration() {
-        if (sSimReadyAllowList != null) return;
+        if (sSimReadyAllowList == null) {
+            sSimReadyAllowList = readResourceConfiguration(
+                    R.array.config_countries_require_sim_for_emergency);
+        }
+        logi("readResourceConfiguration simReadyCountries=" + sSimReadyAllowList);
+
+        if (sPreferSlotWithNormalServiceList == null) {
+            sPreferSlotWithNormalServiceList = readResourceConfiguration(
+                    R.array.config_countries_prefer_normal_service_capable_subscription);
+        }
+        logi("readResourceConfiguration preferNormalServiceCountries="
+                + sPreferSlotWithNormalServiceList);
+    }
+
+    private List<String> readResourceConfiguration(int id) {
+        logi("readResourceConfiguration id=" + id);
+
+        List<String> resource = null;
         try {
-            sSimReadyAllowList = Arrays.asList(mContext.getResources().getStringArray(
-                    R.array.config_countries_require_sim_for_emergency));
+            resource = Arrays.asList(mContext.getResources().getStringArray(id));
         } catch (Resources.NotFoundException nfe) {
             loge("readResourceConfiguration exception=" + nfe);
         } catch (NullPointerException npe) {
             loge("readResourceConfiguration exception=" + npe);
         } finally {
-            if (sSimReadyAllowList == null) {
-                sSimReadyAllowList = new ArrayList<String>();
+            if (resource == null) {
+                resource = new ArrayList<String>();
             }
         }
-        logi("readResourceConfiguration simReadyCountries=" + sSimReadyAllowList);
+        return resource;
     }
 
     /** For test purpose only */
     @VisibleForTesting
     public void clearResourceConfiguration() {
         sSimReadyAllowList = null;
+        sPreferSlotWithNormalServiceList = null;
     }
 
     private void selectDomain() {
@@ -628,7 +635,7 @@
         // Reset mDomainSelectionRequested to avoid redundant execution of selectDomain().
         mDomainSelectionRequested = false;
 
-        if (!allowEmergencyCalls(mSelectionAttributes.getEmergencyRegResult())) {
+        if (!allowEmergencyCalls(mSelectionAttributes.getEmergencyRegistrationResult())) {
             // Detected the country and found that emergency calls are not allowed with this slot.
             terminateSelectionPermanentlyForSlot();
             return;
@@ -648,15 +655,15 @@
     }
 
     private void selectDomainFromInitialState() {
-        if (mIsTestEmergencyNumber) {
-            selectDomainForTestEmergencyNumber();
-            return;
-        }
+        if (mDestroyed) return;
 
         boolean csInService = isCsInService();
         boolean psInService = isPsInService();
 
         if (!csInService && !psInService) {
+            if (maybeRedialOnTheOtherSlotInNormalService()) {
+                return;
+            }
             mCsNetworkType = getSelectableCsNetworkType();
             mPsNetworkType = getSelectablePsNetworkType(false);
             logi("selectDomain limited service ps=" + accessNetworkTypeToString(mPsNetworkType)
@@ -669,6 +676,7 @@
             } else {
                 requestScan(true);
             }
+            maybeModifyScanType(mLastNetworkType);
             return;
         }
 
@@ -723,6 +731,7 @@
                 requestScan(true);
             }
         }
+        maybeModifyScanType(mLastNetworkType);
     }
 
     /**
@@ -757,20 +766,21 @@
 
         mCancelSignal = new CancellationSignal();
         // In case dialing over Wi-Fi has failed, do not the change the domain preference.
-        if (!wifiFailed) {
+        if (!wifiFailed || mLastPreferredNetworks == null) {
             mLastPreferredNetworks = getNextPreferredNetworks(csPreferred, mTryEpsFallback);
         }
         mTryEpsFallback = false;
 
         if (isInRoaming()
-                && (mPreferredNetworkScanType == DomainSelectionService.SCAN_TYPE_FULL_SERVICE)) {
+                && (mPreferredNetworkScanType
+                        == CarrierConfigManager.ImsEmergency.SCAN_TYPE_FULL_SERVICE)) {
             // FULL_SERVICE only preference is available only when not in roaming.
             mScanType = DomainSelectionService.SCAN_TYPE_NO_PREFERENCE;
         }
 
         mIsScanRequested = true;
         mWwanSelectorCallback.onRequestEmergencyNetworkScan(
-                mLastPreferredNetworks, mScanType, mCancelSignal,
+                mLastPreferredNetworks, mScanType, false, mCancelSignal,
                 (result) -> {
                     logi("requestScan-onComplete");
                     sendMessage(obtainMessage(MSG_NETWORK_SCAN_RESULT, result));
@@ -956,7 +966,8 @@
      * @return {@code true} if CS is in service.
      */
     private boolean isCsInService() {
-        EmergencyRegResult regResult = mSelectionAttributes.getEmergencyRegResult();
+        EmergencyRegistrationResult regResult =
+                mSelectionAttributes.getEmergencyRegistrationResult();
         if (regResult == null) return false;
 
         int regState = regResult.getRegState();
@@ -976,7 +987,12 @@
      * @return The network type of the CS network.
      */
     private @RadioAccessNetworkType int getSelectableCsNetworkType() {
-        EmergencyRegResult regResult = mSelectionAttributes.getEmergencyRegResult();
+        List<Integer> domains = getDomainPreference();
+        if (domains.indexOf(DOMAIN_CS) == NOT_SUPPORTED) {
+            return UNKNOWN;
+        }
+        EmergencyRegistrationResult regResult =
+                mSelectionAttributes.getEmergencyRegistrationResult();
         logi("getSelectableCsNetworkType regResult=" + regResult);
         if (regResult == null) return UNKNOWN;
 
@@ -1001,7 +1017,8 @@
      * @return {@code true} if PS is in service.
      */
     private boolean isPsInService() {
-        EmergencyRegResult regResult = mSelectionAttributes.getEmergencyRegResult();
+        EmergencyRegistrationResult regResult =
+                mSelectionAttributes.getEmergencyRegistrationResult();
         if (regResult == null) return false;
 
         int regState = regResult.getRegState();
@@ -1022,7 +1039,12 @@
      * @return The network type if the network supports emergency services over PS network.
      */
     private @RadioAccessNetworkType int getSelectablePsNetworkType(boolean inService) {
-        EmergencyRegResult regResult = mSelectionAttributes.getEmergencyRegResult();
+        List<Integer> domains = getDomainPreference();
+        if (domains.indexOf(DOMAIN_PS_3GPP) == NOT_SUPPORTED) {
+            return UNKNOWN;
+        }
+        EmergencyRegistrationResult regResult =
+                mSelectionAttributes.getEmergencyRegistrationResult();
         logi("getSelectablePsNetworkType regResult=" + regResult);
         if (regResult == null) return UNKNOWN;
         if (mRequiresVoLteEnabled && !isAdvancedCallingSettingEnabled()) {
@@ -1052,7 +1074,8 @@
     }
 
     private boolean isEpsFallbackAvailable() {
-        EmergencyRegResult regResult = mSelectionAttributes.getEmergencyRegResult();
+        EmergencyRegistrationResult regResult =
+                mSelectionAttributes.getEmergencyRegistrationResult();
         if (regResult == null) return false;
 
         List<Integer> ratList = getImsNetworkTypeConfiguration();
@@ -1188,7 +1211,8 @@
         }
 
         if (!mCdmaPreferredNumbers.isEmpty()) {
-            if (mCdmaPreferredNumbers.contains(mSelectionAttributes.getNumber())) {
+            String number = mSelectionAttributes.getAddress().getSchemeSpecificPart();
+            if (mCdmaPreferredNumbers.contains(number)) {
                 // The number will be dialed over CDMA.
                 ratList.clear();
                 ratList.add(new Integer(CDMA2000));
@@ -1219,12 +1243,13 @@
         tm = tm.createForSubscriptionId(getSubId());
         String netIso = tm.getNetworkCountryIso();
 
-        EmergencyRegResult regResult = mSelectionAttributes.getEmergencyRegResult();
+        EmergencyRegistrationResult regResult =
+                mSelectionAttributes.getEmergencyRegistrationResult();
         if (regResult != null) {
             if (regResult.getRegState() == REGISTRATION_STATE_HOME) return false;
             if (regResult.getRegState() == REGISTRATION_STATE_ROAMING) return true;
 
-            String iso = regResult.getIso();
+            String iso = regResult.getCountryIso();
             if (!TextUtils.isEmpty(iso)) netIso = iso;
         }
 
@@ -1373,14 +1398,14 @@
         }
     }
 
-    private boolean allowEmergencyCalls(EmergencyRegResult regResult) {
+    private boolean allowEmergencyCalls(EmergencyRegistrationResult regResult) {
         if (mModemCount < 2) return true;
         if (regResult == null) {
             loge("allowEmergencyCalls null regResult");
             return true;
         }
 
-        String iso = regResult.getIso();
+        String iso = regResult.getCountryIso();
         if (sSimReadyAllowList.contains(iso)) {
             TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
             int simState = tm.getSimState(getSlotId());
@@ -1396,6 +1421,20 @@
         return true;
     }
 
+    private boolean maybeRedialOnTheOtherSlotInNormalService() {
+        EmergencyRegistrationResult regResult =
+                mSelectionAttributes.getEmergencyRegistrationResult();
+        if (regResult == null) return false;
+
+        String iso = regResult.getCountryIso();
+        if (sPreferSlotWithNormalServiceList.contains(iso)
+                && mCrossSimRedialingController.isThereOtherSlotInService()) {
+            terminateSelectionForCrossSimRedialing(false);
+            return true;
+        }
+        return false;
+    }
+
     private void terminateSelectionPermanentlyForSlot() {
         logi("terminateSelectionPermanentlyForSlot");
         terminateSelection(true);
@@ -1410,11 +1449,6 @@
         mTransportSelectorCallback.onSelectionTerminated(permanent
                 ? DisconnectCause.EMERGENCY_PERM_FAILURE
                 : DisconnectCause.EMERGENCY_TEMP_FAILURE);
-
-        if (mIsScanRequested && mCancelSignal != null) {
-            mCancelSignal.cancel();
-            mCancelSignal = null;
-        }
     }
 
     /** Starts the cross stack timer. */
@@ -1424,7 +1458,8 @@
 
         if (mModemCount == 1) return;
 
-        EmergencyRegResult regResult = mSelectionAttributes.getEmergencyRegResult();
+        EmergencyRegistrationResult regResult =
+                mSelectionAttributes.getEmergencyRegistrationResult();
         if (regResult != null) {
             int regState = regResult.getRegState();
 
@@ -1436,8 +1471,9 @@
             inRoaming = (regState == REGISTRATION_STATE_ROAMING) || isInRoaming();
         }
 
+        String number = mSelectionAttributes.getAddress().getSchemeSpecificPart();
         mCrossSimRedialingController.startTimer(mContext, this, mSelectionAttributes.getCallId(),
-                mSelectionAttributes.getNumber(), inService, inRoaming, mModemCount);
+                number, inService, inRoaming, mModemCount);
     }
 
     /** Notifies that the cross stack redilaing timer has been expired. */
@@ -1452,6 +1488,15 @@
         terminateSelectionForCrossSimRedialing(false);
     }
 
+    private void maybeModifyScanType(int selectedNetworkType) {
+        if ((mPreferredNetworkScanType
+                != CarrierConfigManager.ImsEmergency.SCAN_TYPE_FULL_SERVICE)
+                && mScanLimitedOnlyAfterVolteFailure
+                && (selectedNetworkType == EUTRAN)) {
+            mScanType = DomainSelectionService.SCAN_TYPE_LIMITED_SERVICE;
+        }
+    }
+
     private static String arrayToString(int[] intArray, IntFunction<String> func) {
         int length = intArray.length;
         StringBuilder sb = new StringBuilder("{");
@@ -1559,42 +1604,6 @@
                 && mEcbmHelper.getDataConnectionState(getSlotId()) == DATA_CONNECTED;
     }
 
-    private void selectDomainForTestEmergencyNumber() {
-        logi("selectDomainForTestEmergencyNumber");
-        if (isImsRegisteredWithVoiceCapability()) {
-            if (isImsRegisteredOverWifi()
-                    || isImsRegisteredOverCrossSim()) {
-                mTransportSelectorCallback.onWlanSelected(mVoWifiOverEmergencyPdn);
-            } else {
-                onWwanNetworkTypeSelected(EUTRAN);
-            }
-        } else {
-            onWwanNetworkTypeSelected(UTRAN);
-        }
-    }
-
-    private boolean isTestEmergencyNumber(String number) {
-        number = PhoneNumberUtils.stripSeparators(number);
-        Map<Integer, List<EmergencyNumber>> list = new HashMap<>();
-        try {
-            TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
-            list = tm.getEmergencyNumberList();
-        } catch (IllegalStateException ise) {
-            loge("isTestEmergencyNumber ise=" + ise);
-        }
-
-        for (Integer sub : list.keySet()) {
-            for (EmergencyNumber eNumber : list.get(sub)) {
-                if (number.equals(eNumber.getNumber())
-                        && eNumber.isFromSources(EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST)) {
-                    logd("isTestEmergencyNumber: " + number + " is a test emergency number.");
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
     @Override
     protected void logi(String msg) {
         super.logi(msg);
diff --git a/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelector.java b/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelector.java
index aef193b..7f28b04 100644
--- a/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelector.java
+++ b/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelector.java
@@ -18,12 +18,17 @@
 
 import android.annotation.NonNull;
 import android.content.Context;
+import android.os.CancellationSignal;
 import android.os.Looper;
+import android.os.Message;
 import android.os.PersistableBundle;
 import android.telephony.AccessNetworkConstants;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
 import android.telephony.BarringInfo;
 import android.telephony.CarrierConfigManager;
 import android.telephony.DataSpecificRegistrationInfo;
+import android.telephony.DomainSelectionService;
+import android.telephony.EmergencyRegistrationResult;
 import android.telephony.NetworkRegistrationInfo;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
@@ -31,11 +36,14 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 
+import java.util.List;
+
 /**
  * Implements an emergency SMS domain selector for sending an emergency SMS.
  */
 public class EmergencySmsDomainSelector extends SmsDomainSelector implements
         ImsStateTracker.BarringInfoListener, ImsStateTracker.ServiceStateListener {
+    protected static final int EVENT_EMERGENCY_NETWORK_SCAN_RESULT = 201;
     /**
      * Stores the configuration value of
      * {@link CarrierConfigManager#KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL}.
@@ -46,6 +54,8 @@
     private boolean mServiceStateReceived;
     private BarringInfo mBarringInfo;
     private boolean mBarringInfoReceived;
+    private boolean mEmergencyNetworkScanInProgress;
+    private CancellationSignal mEmergencyNetworkScanSignal;
 
     public EmergencySmsDomainSelector(Context context, int slotId, int subId,
             @NonNull Looper looper, @NonNull ImsStateTracker imsStateTracker,
@@ -68,6 +78,18 @@
     }
 
     @Override
+    public void handleMessage(@NonNull Message msg) {
+        switch (msg.what) {
+            case EVENT_EMERGENCY_NETWORK_SCAN_RESULT:
+                handleEmergencyNetworkScanResult((EmergencyRegistrationResult) msg.obj);
+                break;
+            default:
+                super.handleMessage(msg);
+                break;
+        }
+    }
+
+    @Override
     public void finishSelection() {
         super.finishSelection();
         mServiceStateReceived = false;
@@ -75,6 +97,12 @@
         mBarringInfoReceived = false;
         mBarringInfo = null;
         mEmergencySmsOverImsSupportedByConfig = null;
+
+        mEmergencyNetworkScanInProgress = false;
+        if (mEmergencyNetworkScanSignal != null) {
+            mEmergencyNetworkScanSignal.cancel();
+            mEmergencyNetworkScanSignal = null;
+        }
     }
 
     @Override
@@ -111,7 +139,7 @@
              * when {@link CarrierConfigManager#KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL} is set
              * to true.
              */
-            if (isEmergencySmsOverImsSupportedIfLteLimitedOrInService()) {
+            if (isEmergencySmsOverImsSupportedIfNetworkLimitedOrInService()) {
                 /**
                  * Emergency SMS should be supported via emergency PDN.
                  * If this condition is false, then need to fallback to CS network
@@ -139,60 +167,132 @@
             return;
         }
 
+        if (mEmergencyNetworkScanInProgress) {
+            logi("Emergency network scan is in progress.");
+            return;
+        }
+
         logi("selectDomain: " + mImsStateTracker.imsStateToString());
 
         if (isSmsOverImsAvailable()) {
-            boolean isEmergencySmsOverImsSupportedIfLteLimitedOrInService =
-                    isEmergencySmsOverImsSupportedIfLteLimitedOrInService();
+            boolean isEmergencySmsOverImsSupportedIfNetworkLimitedOrInService =
+                    isEmergencySmsOverImsSupportedIfNetworkLimitedOrInService();
 
             if (mImsStateTracker.isImsRegisteredOverWlan()) {
                 /**
                  * When {@link CarrierConfigManager#KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL}
-                 * is set to true, the emergency SMS supports on the LTE network using the
+                 * is set to true, the emergency SMS supports on the LTE/NR network using the
                  * emergency PDN. As of now, since the emergency SMS doesn't use the emergency PDN
                  * over WLAN, the domain selector reports the domain as WLAN only if
-                 * {@code isEmergencySmsOverImsSupportedIfLteLimitedOrInService} is set to false
+                 * {@code isEmergencySmsOverImsSupportedIfNetworkLimitedOrInService} is set to false
                  * and IMS is registered over WLAN.
                  * Otherwise, the domain selector reports the domain as WWAN.
                  */
-                if (!isEmergencySmsOverImsSupportedIfLteLimitedOrInService) {
+                if (!isEmergencySmsOverImsSupportedIfNetworkLimitedOrInService) {
                     notifyWlanSelected(false);
                     return;
                 }
 
                 logi("DomainSelected: WLAN >> WWAN");
             }
-            notifyWwanSelected(NetworkRegistrationInfo.DOMAIN_PS,
-                    isEmergencySmsOverImsSupportedIfLteLimitedOrInService);
+
+            /**
+             * The request of emergency network scan triggers the modem to request the emergency
+             * service fallback because NR network doesn't support the emergency service.
+             */
+            if (isEmergencySmsOverImsSupportedIfNetworkLimitedOrInService
+                    && isNrEmergencyServiceFallbackRequired()) {
+                requestEmergencyNetworkScan(List.of(AccessNetworkType.EUTRAN));
+            } else {
+                notifyWwanSelected(NetworkRegistrationInfo.DOMAIN_PS,
+                        isEmergencySmsOverImsSupportedIfNetworkLimitedOrInService);
+            }
         } else {
             notifyWwanSelected(NetworkRegistrationInfo.DOMAIN_CS, false);
         }
     }
 
+    private void requestEmergencyNetworkScan(List<Integer> preferredNetworks) {
+        mEmergencyNetworkScanInProgress = true;
+
+        if (mWwanSelectorCallback == null) {
+            mTransportSelectorCallback.onWwanSelected((callback) -> {
+                mWwanSelectorCallback = callback;
+                requestEmergencyNetworkScanInternal(preferredNetworks);
+            });
+        } else {
+            requestEmergencyNetworkScanInternal(preferredNetworks);
+        }
+    }
+
+    private void requestEmergencyNetworkScanInternal(List<Integer> preferredNetworks) {
+        logi("requestEmergencyNetworkScan: preferredNetworks=" + preferredNetworks);
+        mEmergencyNetworkScanSignal = new CancellationSignal();
+        mWwanSelectorCallback.onRequestEmergencyNetworkScan(
+                preferredNetworks,
+                DomainSelectionService.SCAN_TYPE_FULL_SERVICE, false,
+                mEmergencyNetworkScanSignal,
+                (regResult) -> {
+                    logi("requestEmergencyNetworkScan-onComplete");
+                    obtainMessage(EVENT_EMERGENCY_NETWORK_SCAN_RESULT, regResult).sendToTarget();
+                });
+    }
+
+    /**
+     * Handles the emergency network scan result.
+     *
+     * This triggers the emergency service fallback to modem when the emergency service is not
+     * supported but the emergency service fallback is supported in the current network.
+     *
+     * @param regResult The emergency registration result that is triggered
+     *                  by the emergency network scan.
+     */
+    private void handleEmergencyNetworkScanResult(EmergencyRegistrationResult regResult) {
+        logi("handleEmergencyNetworkScanResult: " + regResult);
+
+        mEmergencyNetworkScanInProgress = false;
+        mEmergencyNetworkScanSignal = null;
+
+        int accessNetworkType = regResult.getAccessNetwork();
+        int domain = NetworkRegistrationInfo.DOMAIN_CS;
+
+        if (accessNetworkType == AccessNetworkType.NGRAN) {
+            domain = NetworkRegistrationInfo.DOMAIN_PS;
+        } else if (accessNetworkType == AccessNetworkType.EUTRAN) {
+            if (regResult.getDomain() == NetworkRegistrationInfo.DOMAIN_CS) {
+                logi("PS emergency service is not supported in LTE network.");
+            } else {
+                domain = NetworkRegistrationInfo.DOMAIN_PS;
+            }
+        }
+
+        notifyWwanSelected(domain, (domain == NetworkRegistrationInfo.DOMAIN_PS));
+    }
+
     /**
      * Checks if the emergency SMS messages over IMS is available according to the carrier
      * configuration and the current network states.
      */
     private boolean isImsEmergencySmsAvailable() {
-        boolean isEmergencySmsOverImsSupportedIfLteLimitedOrInService =
-                isEmergencySmsOverImsSupportedIfLteLimitedOrInService();
+        boolean isEmergencySmsOverImsSupportedIfNetworkLimitedOrInService =
+                isEmergencySmsOverImsSupportedIfNetworkLimitedOrInService();
         boolean networkAvailable = isNetworkAvailableForImsEmergencySms();
 
         logi("isImsEmergencySmsAvailable: "
-                + "emergencySmsOverIms=" + isEmergencySmsOverImsSupportedIfLteLimitedOrInService
+                + "emergencySmsOverIms=" + isEmergencySmsOverImsSupportedIfNetworkLimitedOrInService
                 + ", mmTelFeatureAvailable=" + mImsStateTracker.isMmTelFeatureAvailable()
                 + ", networkAvailable=" + networkAvailable);
 
-        return isEmergencySmsOverImsSupportedIfLteLimitedOrInService
+        return isEmergencySmsOverImsSupportedIfNetworkLimitedOrInService
                 && mImsStateTracker.isMmTelFeatureAvailable()
                 && networkAvailable;
     }
 
     /**
-     * Checks if sending emergency SMS messages over IMS is supported when in LTE/limited LTE
-     * (Emergency only) service mode from the carrier configuration.
+     * Checks if sending emergency SMS messages over IMS is supported when in the network(LTE/NR)
+     * normal/limited(Emergency only) service mode from the carrier configuration.
      */
-    private boolean isEmergencySmsOverImsSupportedIfLteLimitedOrInService() {
+    private boolean isEmergencySmsOverImsSupportedIfNetworkLimitedOrInService() {
         if (mEmergencySmsOverImsSupportedByConfig == null) {
             CarrierConfigManager ccm = mContext.getSystemService(CarrierConfigManager.class);
 
@@ -257,7 +357,8 @@
      */
     private boolean isNetworkAvailableForImsEmergencySms() {
         return isLteEmergencyAvailableInService()
-                || isLteEmergencyAvailableInLimitedService();
+                || isLteEmergencyAvailableInLimitedService()
+                || isNrEmergencyAvailable();
     }
 
     /**
@@ -280,6 +381,22 @@
     }
 
     /**
+     * Checks if the emergency service fallback is supported by the network.
+     *
+     * @return {@code true} if the emergency service fallback is supported by the network,
+     *         {@code false} otherwise.
+     */
+    private boolean isEmergencyServiceFallbackSupported(@NonNull NetworkRegistrationInfo regInfo) {
+        final DataSpecificRegistrationInfo dsRegInfo = regInfo.getDataSpecificInfo();
+        if (dsRegInfo != null) {
+            final VopsSupportInfo vopsSupportInfo = dsRegInfo.getVopsSupportInfo();
+            return vopsSupportInfo != null
+                    && vopsSupportInfo.isEmergencyServiceFallbackSupported();
+        }
+        return false;
+    }
+
+    /**
      * Checks if the emergency service is allowed (not barred) by the network.
      *
      * This checks if SystemInformationBlockType2 includes the ac-BarringInfo and
@@ -297,4 +414,45 @@
                 mBarringInfo.getBarringServiceInfo(BarringInfo.BARRING_SERVICE_TYPE_EMERGENCY);
         return !bsi.isBarred();
     }
+
+    /**
+     * Checks if the emergency service fallback is available in the NR network
+     * because the emergency service is not supported.
+     */
+    private boolean isNrEmergencyServiceFallbackRequired() {
+        if (mServiceState == null) {
+            return false;
+        }
+
+        final NetworkRegistrationInfo regInfo = mServiceState.getNetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+
+        if (regInfo != null
+                && regInfo.getAccessNetworkTechnology() == TelephonyManager.NETWORK_TYPE_NR
+                && regInfo.isRegistered()) {
+            return !isEmergencyServiceSupported(regInfo)
+                    && isEmergencyServiceFallbackSupported(regInfo);
+        }
+        return false;
+    }
+
+    /**
+     * Checks if the emergency service is available in the NR network.
+     */
+    private boolean isNrEmergencyAvailable() {
+        if (mServiceState == null) {
+            return false;
+        }
+
+        final NetworkRegistrationInfo regInfo = mServiceState.getNetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+
+        if (regInfo != null
+                && regInfo.getAccessNetworkTechnology() == TelephonyManager.NETWORK_TYPE_NR
+                && regInfo.isRegistered()) {
+            return isEmergencyServiceSupported(regInfo)
+                    || isEmergencyServiceFallbackSupported(regInfo);
+        }
+        return false;
+    }
 }
diff --git a/src/com/android/services/telephony/domainselection/NormalCallDomainSelector.java b/src/com/android/services/telephony/domainselection/NormalCallDomainSelector.java
index cd70793..31a1cc2 100644
--- a/src/com/android/services/telephony/domainselection/NormalCallDomainSelector.java
+++ b/src/com/android/services/telephony/domainselection/NormalCallDomainSelector.java
@@ -34,6 +34,8 @@
 import android.telephony.TransportSelectorCallback;
 import android.telephony.ims.ImsReasonInfo;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 /**
  * Implements domain selector for outgoing non-emergency calls.
  */
@@ -42,9 +44,15 @@
 
     private static final String LOG_TAG = "NCDS";
 
-    private boolean mStopDomainSelection = true;
-    private boolean mDestroyed = false;
-    private ServiceState mServiceState;
+    @VisibleForTesting
+    protected enum SelectorState {
+        ACTIVE,
+        INACTIVE,
+        DESTROYED
+    };
+
+    protected SelectorState mSelectorState = SelectorState.INACTIVE;
+    protected ServiceState mServiceState;
     private boolean mImsRegStateReceived;
     private boolean mMmTelCapabilitiesReceived;
     private boolean mReselectDomain;
@@ -67,9 +75,10 @@
     public void selectDomain(SelectionAttributes attributes, TransportSelectorCallback callback) {
         mSelectionAttributes = attributes;
         mTransportSelectorCallback = callback;
-        mStopDomainSelection = false;
+        mSelectorState = SelectorState.ACTIVE;
 
         if (callback == null) {
+            mSelectorState = SelectorState.INACTIVE;
             loge("Invalid params: TransportSelectorCallback is null");
             return;
         }
@@ -80,7 +89,7 @@
             return;
         }
 
-        int subId = attributes.getSubId();
+        int subId = attributes.getSubscriptionId();
         boolean validSubscriptionId = SubscriptionManager.isValidSubscriptionId(subId);
         if (attributes.getSelectorType() != SELECTOR_TYPE_CALLING || attributes.isEmergency()
                 || !validSubscriptionId) {
@@ -96,6 +105,7 @@
             logd("NormalCallDomainSelection triggered. Sub-id:" + subId);
             post(() -> selectDomain());
         } else {
+            mSelectorState = SelectorState.INACTIVE;
             loge("Subscription-ids doesn't match. This instance is associated with sub-id:"
                     + getSubId() + ", requested sub-id:" + subId);
             // TODO: Throw anamoly here. This condition should never occur.
@@ -112,31 +122,44 @@
     @Override
     public synchronized void finishSelection() {
         logd("finishSelection");
-        mStopDomainSelection = true;
-        mImsStateTracker.removeServiceStateListener(this);
-        mImsStateTracker.removeImsStateListener(this);
-        mSelectionAttributes = null;
-        mTransportSelectorCallback = null;
-        destroy();
+        if (mSelectorState == SelectorState.ACTIVE) {
+            // This is cancel selection case.
+            cancelSelection();
+            return;
+        }
+
+        if (mSelectorState != SelectorState.DESTROYED) {
+            mImsStateTracker.removeServiceStateListener(this);
+            mImsStateTracker.removeImsStateListener(this);
+            mSelectionAttributes = null;
+            mTransportSelectorCallback = null;
+            destroy();
+        }
     }
 
     @Override
     public void destroy() {
         logd("destroy");
-        if (!mDestroyed) {
-            mDestroyed = true;
-            super.destroy();
+        switch (mSelectorState) {
+            case INACTIVE:
+                mSelectorState = SelectorState.DESTROYED;
+                super.destroy();
+                break;
+
+            case ACTIVE:
+                loge("destroy is called when selector state is in ACTIVE state");
+                cancelSelection();
+                break;
+
+            case DESTROYED:
+                super.destroy();
+                break;
         }
     }
 
-    /**
-     * Cancel an ongoing selection operation. It is up to the DomainSelectionService
-     * to clean up all ongoing operations with the framework.
-     */
-    @Override
     public void cancelSelection() {
         logd("cancelSelection");
-        mStopDomainSelection = true;
+        mSelectorState = SelectorState.INACTIVE;
         mReselectDomain = false;
         if (mTransportSelectorCallback != null) {
             mTransportSelectorCallback.onSelectionTerminated(DisconnectCause.OUTGOING_CANCELED);
@@ -175,7 +198,7 @@
 
     private void notifyPsSelected() {
         logd("notifyPsSelected");
-        mStopDomainSelection = true;
+        mSelectorState = SelectorState.INACTIVE;
         if (mImsStateTracker.isImsRegisteredOverWlan()) {
             logd("WLAN selected");
             mTransportSelectorCallback.onWlanSelected(false);
@@ -203,7 +226,7 @@
 
     private void notifyCsSelected() {
         logd("notifyCsSelected");
-        mStopDomainSelection = true;
+        mSelectorState = SelectorState.INACTIVE;
         if (mWwanSelectorCallback == null) {
             mTransportSelectorCallback.onWwanSelected((callback) -> {
                 mWwanSelectorCallback = callback;
@@ -225,7 +248,7 @@
     }
 
     private void notifySelectionTerminated(@DisconnectCauses int cause) {
-        mStopDomainSelection = true;
+        mSelectorState = SelectorState.INACTIVE;
         if (mTransportSelectorCallback != null) {
             mTransportSelectorCallback.onSelectionTerminated(cause);
             finishSelection();
@@ -243,7 +266,7 @@
 
         PersistableBundle config = null;
         if (configManager != null) {
-            config = configManager.getConfigForSubId(mSelectionAttributes.getSubId(),
+            config = configManager.getConfigForSubId(mSelectionAttributes.getSubscriptionId(),
                     new String[] {CarrierConfigManager.KEY_SUPPORT_WPS_OVER_IMS_BOOL});
         }
 
@@ -271,7 +294,7 @@
 
         PersistableBundle config = null;
         if (configManager != null) {
-            config = configManager.getConfigForSubId(mSelectionAttributes.getSubId(),
+            config = configManager.getConfigForSubId(mSelectionAttributes.getSubscriptionId(),
                     new String[] {CarrierConfigManager.KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL});
         }
 
@@ -289,7 +312,7 @@
     }
 
     private synchronized void selectDomain() {
-        if (mStopDomainSelection || mSelectionAttributes == null
+        if (mSelectorState != SelectorState.ACTIVE || mSelectionAttributes == null
                 || mTransportSelectorCallback == null) {
             logd("Domain Selection is stopped.");
             return;
@@ -387,7 +410,8 @@
         // Handle voice call.
         if (mImsStateTracker.isImsVoiceCapable()) {
             logd("IMS is voice capable");
-            if (PhoneNumberUtils.isWpsCallNumber(mSelectionAttributes.getNumber())) {
+            String number = mSelectionAttributes.getAddress().getSchemeSpecificPart();
+            if (PhoneNumberUtils.isWpsCallNumber(number)) {
                 handleWpsCall();
             } else {
                 notifyPsSelected();
@@ -403,4 +427,9 @@
             }
         }
     }
+
+    @VisibleForTesting
+    public SelectorState getSelectorState() {
+        return mSelectorState;
+    }
 }
diff --git a/src/com/android/services/telephony/domainselection/OWNERS b/src/com/android/services/telephony/domainselection/OWNERS
index b9112be..2a76770 100644
--- a/src/com/android/services/telephony/domainselection/OWNERS
+++ b/src/com/android/services/telephony/domainselection/OWNERS
@@ -6,3 +6,4 @@
 mkoon@google.com
 seheele@google.com
 radhikaagrawal@google.com
+jdyou@google.com
diff --git a/src/com/android/services/telephony/domainselection/SmsDomainSelector.java b/src/com/android/services/telephony/domainselection/SmsDomainSelector.java
index 95b04e2..4e41e43 100644
--- a/src/com/android/services/telephony/domainselection/SmsDomainSelector.java
+++ b/src/com/android/services/telephony/domainselection/SmsDomainSelector.java
@@ -71,12 +71,6 @@
     }
 
     @Override
-    public void cancelSelection() {
-        logi("cancelSelection");
-        finishSelection();
-    }
-
-    @Override
     public void reselectDomain(@NonNull SelectionAttributes attr) {
         if (isDomainSelectionRequested()) {
             // The domain selection is already requested,
diff --git a/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionService.java b/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionService.java
index fca5966..d79a260 100644
--- a/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionService.java
+++ b/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionService.java
@@ -18,7 +18,6 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.SuppressLint;
 import android.content.Context;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -227,7 +226,7 @@
         mContext = getApplicationContext();
 
         // Create a worker thread for this domain selection service.
-        getExecutor();
+        getCreateExecutor();
 
         TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
         int activeModemCount = (tm != null) ? tm.getActiveModemCount() : 1;
@@ -317,8 +316,8 @@
     @Override
     public void onDomainSelection(@NonNull SelectionAttributes attr,
             @NonNull TransportSelectorCallback callback) {
-        final int slotId = attr.getSlotId();
-        final int subId = attr.getSubId();
+        final int slotId = attr.getSlotIndex();
+        final int subId = attr.getSubscriptionId();
         final int selectorType = attr.getSelectorType();
         final boolean isEmergency = attr.isEmergency();
         ImsStateTracker ist = getImsStateTracker(slotId);
@@ -385,8 +384,15 @@
     /**
      *  Returns an Executor used to execute methods called remotely by the framework.
      */
-    @SuppressLint("OnNameExpected")
     @Override
+    public @NonNull Executor getCreateExecutor() {
+        return getExecutor();
+    }
+
+    /**
+     *  Returns an Executor used to execute methods called remotely by the framework.
+     */
+    @VisibleForTesting
     public @NonNull Executor getExecutor() {
         if (mServiceHandler == null) {
             HandlerThread handlerThread = new HandlerThread(TAG);
@@ -506,7 +512,6 @@
         switch (selectorType) {
             case SELECTOR_TYPE_CALLING: return "CALLING";
             case SELECTOR_TYPE_SMS: return "SMS";
-            case SELECTOR_TYPE_UT: return "UT";
             default: return Integer.toString(selectorType);
         }
     }
diff --git a/testapps/GbaTestApp/res/values-eu/strings.xml b/testapps/GbaTestApp/res/values-eu/strings.xml
index 6774d99..c192a56 100644
--- a/testapps/GbaTestApp/res/values-eu/strings.xml
+++ b/testapps/GbaTestApp/res/values-eu/strings.xml
@@ -20,10 +20,10 @@
     <string name="request_naf_url" msgid="4487793541217737042">"Sareko aplikazioaren funtzioaren (NAF) URLa"</string>
     <string name="request_force_bootstrapping" msgid="206043602616214325">"Bootstrapping-a erabiltzera behartu nahi duzu?"</string>
     <string name="request_org" msgid="8416693445448308975">"Erakundearen kodea"</string>
-    <string name="request_security_protocol" msgid="1444164827561010482">"UA segurtasun-protokoloaren IDa"</string>
+    <string name="request_security_protocol" msgid="1444164827561010482">"UA segurtasun-protokoloaren identifikatzailea"</string>
     <string name="request_tls_cipher_suite" msgid="6659854717595308404">"TLS Cipher Suite ID"</string>
     <string name="response_success" msgid="2469204471244527663">"Burutu da GBA autentifikazioa?"</string>
-    <string name="response_fail_reason" msgid="3401426967253202496">"Hutsegitearen arrazoiaren IDa"</string>
+    <string name="response_fail_reason" msgid="3401426967253202496">"Hutsegitearen arrazoiaren identifikatzailea"</string>
     <string name="response_key" msgid="8839847772051686309">"GBA-ko gakoa (CK + IK)"</string>
     <string name="response_btid" msgid="2550216722679350756">"Bootstrapping Transaction Identifier (B-TID)"</string>
     <string name="sample_naf" msgid="255371174145881001">"3GPP-bootstrapping@naf1.operator.com"</string>
diff --git a/testapps/TestSatelliteApp/res/layout/activity_SatelliteControl.xml b/testapps/TestSatelliteApp/res/layout/activity_SatelliteControl.xml
index 40e3c69..6a79412 100644
--- a/testapps/TestSatelliteApp/res/layout/activity_SatelliteControl.xml
+++ b/testapps/TestSatelliteApp/res/layout/activity_SatelliteControl.xml
@@ -15,7 +15,7 @@
   ~ limitations under the License
   -->
 
-<LinearLayout
+<ScrollView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
@@ -84,6 +84,42 @@
             android:paddingRight="4dp"
             android:text="@string/requestTimeForNextSatelliteVisibility"/>
          <Button
+            android:id="@+id/removeUserRestrictReason"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/removeUserRestrictReason"/>
+         <Button
+            android:id="@+id/addUserRestrictReason"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/addUserRestrictReason"/>
+         <Button
+            android:id="@+id/getSatellitePlmn"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/getSatellitePlmn"/>
+         <Button
+            android:id="@+id/getAllSatellitePlmn"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/getAllSatellitePlmn"/>
+         <Button
+            android:id="@+id/isSatelliteEnabledForCarrier"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/isSatelliteEnabledForCarrier"/>
+         <Button
+            android:id="@+id/isRequestIsSatelliteEnabledForCarrier"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/isRequestIsSatelliteEnabledForCarrier"/>
+         <Button
             android:id="@+id/Back"
             android:onClick="Back"
             android:textColor="@android:color/holo_blue_dark"
@@ -102,4 +138,4 @@
             android:layout_centerVertical="true"
             android:textSize="15dp" />
     </LinearLayout>
-</LinearLayout>
+</ScrollView>
diff --git a/testapps/TestSatelliteApp/res/layout/activity_TestSatelliteWrapper.xml b/testapps/TestSatelliteApp/res/layout/activity_TestSatelliteWrapper.xml
index c136ce7..7f2f026 100644
--- a/testapps/TestSatelliteApp/res/layout/activity_TestSatelliteWrapper.xml
+++ b/testapps/TestSatelliteApp/res/layout/activity_TestSatelliteWrapper.xml
@@ -14,91 +14,157 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License
   -->
-
-<LinearLayout
+<ScrollView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="vertical"
-    android:gravity="center"
-    android:paddingStart="4dp">
+    android:layout_height="match_parent">
 
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="0dp"
-        android:layout_weight="0"
-        android:textColor="@android:color/holo_blue_dark"
-        android:textSize="20dp"
-        android:text="Satellite Wrapper Test"/>
-    <Button
-        android:id="@+id/requestNtnSignalStrength"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingRight="4dp"
-        android:text="@string/requestNtnSignalStrength"/>
-    <Button
-        android:id="@+id/registerForNtnSignalStrengthChanged"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingRight="4dp"
-        android:text="@string/registerForNtnSignalStrengthChanged"/>
-    <Button
-        android:id="@+id/unregisterForNtnSignalStrengthChanged"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingRight="4dp"
-        android:text="@string/unregisterForNtnSignalStrengthChanged"/>
-    <Button
-        android:id="@+id/isOnlyNonTerrestrialNetworkSubscription"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingRight="4dp"
-        android:text="@string/isOnlyNonTerrestrialNetworkSubscription"/>
-    <Button
-        android:id="@+id/registerForSatelliteCapabilitiesChanged"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingRight="4dp"
-        android:text="@string/registerForSatelliteCapabilitiesChanged"/>
-    <Button
-        android:id="@+id/unregisterForSatelliteCapabilitiesChanged"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingRight="4dp"
-        android:text="@string/unregisterForSatelliteCapabilitiesChanged"/>
     <LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:orientation="horizontal">
-         <Button
-            android:id="@+id/Back"
-            android:onClick="Back"
+        android:orientation="vertical"
+        android:gravity="center"
+        android:paddingStart="4dp">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="0dp"
+            android:layout_weight="0"
             android:textColor="@android:color/holo_blue_dark"
-            android:layout_marginTop="10dp"
-            android:layout_marginBottom="10dp"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:paddingRight="4dp"
-            android:text="@string/Back"/>
+            android:textSize="20dp"
+            android:text="Satellite Wrapper Test"/>
         <Button
-            android:id="@+id/ClearLog"
-            android:onClick="ClearLog"
-            android:textColor="@android:color/holo_blue_dark"
-            android:layout_marginTop="10dp"
-            android:layout_marginBottom="10dp"
-            android:layout_width="0dp"
+            android:id="@+id/requestNtnSignalStrength"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_weight="1"
             android:paddingRight="4dp"
-            android:text="@string/ClearLog"/>
+            android:text="@string/requestNtnSignalStrength"/>
+        <Button
+            android:id="@+id/registerForNtnSignalStrengthChanged"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/registerForNtnSignalStrengthChanged"/>
+        <Button
+            android:id="@+id/unregisterForNtnSignalStrengthChanged"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/unregisterForNtnSignalStrengthChanged"/>
+        <Button
+            android:id="@+id/isOnlyNonTerrestrialNetworkSubscription"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/isOnlyNonTerrestrialNetworkSubscription"/>
+        <Button
+            android:id="@+id/registerForSatelliteCapabilitiesChanged"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/registerForSatelliteCapabilitiesChanged"/>
+        <Button
+            android:id="@+id/unregisterForSatelliteCapabilitiesChanged"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/unregisterForSatelliteCapabilitiesChanged"/>
+        <Button
+            android:id="@+id/isNonTerrestrialNetwork"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/isNonTerrestrialNetwork"/>
+        <Button
+            android:id="@+id/getAvailableServices"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/getAvailableServices"/>
+        <Button
+            android:id="@+id/isUsingNonTerrestrialNetwork"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/isUsingNonTerrestrialNetwork"/>
+        <Button
+            android:id="@+id/requestAttachEnabledForCarrier_enable"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/requestAttachEnabledForCarrier_enable"/>
+        <Button
+            android:id="@+id/requestAttachEnabledForCarrier_disable"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/requestAttachEnabledForCarrier_disable"/>
+        <Button
+            android:id="@+id/requestIsAttachEnabledForCarrier"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/requestIsAttachEnabledForCarrier"/>
+        <Button
+            android:id="@+id/addAttachRestrictionForCarrier"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/addAttachRestrictionForCarrier"/>
+        <Button
+            android:id="@+id/removeAttachRestrictionForCarrier"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/removeAttachRestrictionForCarrier"/>
+        <Button
+            android:id="@+id/getAttachRestrictionReasonsForCarrier"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/getAttachRestrictionReasonsForCarrier"/>
+        <Button
+            android:id="@+id/getSatellitePlmnsForCarrier"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/getSatellitePlmnsForCarrier"/>
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+             <Button
+                android:id="@+id/Back"
+                android:onClick="Back"
+                android:textColor="@android:color/holo_blue_dark"
+                android:layout_marginTop="10dp"
+                android:layout_marginBottom="10dp"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:paddingRight="4dp"
+                android:text="@string/Back"/>
+            <Button
+                android:id="@+id/ClearLog"
+                android:onClick="ClearLog"
+                android:textColor="@android:color/holo_blue_dark"
+                android:layout_marginTop="10dp"
+                android:layout_marginBottom="10dp"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:paddingRight="4dp"
+                android:text="@string/ClearLog"/>
+        </LinearLayout>
+        <ListView
+            android:id="@+id/logListView"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:capitalize="characters"
+            android:textColor="@android:color/holo_blue_light"
+            android:layout_centerVertical="true"
+            android:textSize="8dp" />
     </LinearLayout>
-    <ListView
-        android:id="@+id/logListView"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:capitalize="characters"
-        android:textColor="@android:color/holo_blue_light"
-        android:layout_centerVertical="true"
-        android:textSize="8dp" />
-</LinearLayout>
+
+</ScrollView>
\ No newline at end of file
diff --git a/testapps/TestSatelliteApp/res/values/donottranslate_strings.xml b/testapps/TestSatelliteApp/res/values/donottranslate_strings.xml
index 8ebe5f3..20f5ca8 100644
--- a/testapps/TestSatelliteApp/res/values/donottranslate_strings.xml
+++ b/testapps/TestSatelliteApp/res/values/donottranslate_strings.xml
@@ -64,6 +64,23 @@
     <string name="isOnlyNonTerrestrialNetworkSubscription">isOnlyNonTerrestrialNetworkSubscription</string>
     <string name="registerForSatelliteCapabilitiesChanged">registerForSatelliteCapabilitiesChanged</string>
     <string name="unregisterForSatelliteCapabilitiesChanged">unregisterForSatelliteCapabilitiesChanged</string>
+    <string name="isNonTerrestrialNetwork">isNonTerrestrialNetwork</string>
+    <string name="getAvailableServices">getAvailableServices</string>
+    <string name="isUsingNonTerrestrialNetwork">isUsingNonTerrestrialNetwork</string>
+    <string name="requestAttachEnabledForCarrier_enable">requestAttachEnabledForCarrier_enable</string>
+    <string name="requestAttachEnabledForCarrier_disable">requestAttachEnabledForCarrier_disable</string>
+    <string name="requestIsAttachEnabledForCarrier">requestIsAttachEnabledForCarrier</string>
+    <string name="addAttachRestrictionForCarrier">addAttachRestrictionForCarrier</string>
+    <string name="removeAttachRestrictionForCarrier">removeAttachRestrictionForCarrier</string>
+    <string name="getAttachRestrictionReasonsForCarrier">getAttachRestrictionReasonsForCarrier</string>
+    <string name="getSatellitePlmnsForCarrier">getSatellitePlmnsForCarrier</string>
+
+    <string name="removeUserRestrictReason">removeUserRestrictReason</string>
+    <string name="addUserRestrictReason">addUserRestrictReason</string>
+    <string name="getSatellitePlmn">getSatellitePlmn</string>
+    <string name="getAllSatellitePlmn">getAllSatellitePlmn</string>
+    <string name="isSatelliteEnabledForCarrier">isSatelliteEnabledForCarrier</string>
+    <string name="isRequestIsSatelliteEnabledForCarrier">isRequestIsSatelliteEnabledForCarrier</string>
 
     <string name="Back">Back</string>
     <string name="ClearLog">Clear Log</string>
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/Datagram.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/Datagram.java
index 015ddcd..9ea1b44 100644
--- a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/Datagram.java
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/Datagram.java
@@ -29,6 +29,7 @@
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.os.Bundle;
+import android.telephony.satellite.EnableRequestAttributes;
 import android.telephony.satellite.PointingInfo;
 import android.telephony.satellite.SatelliteDatagram;
 import android.telephony.satellite.SatelliteDatagramCallback;
@@ -169,7 +170,9 @@
     private void startTransmissionUpdatesApp(View view) {
         TextView textView = findViewById(R.id.text_id);
         LinkedBlockingQueue<Integer> error = new LinkedBlockingQueue<>(1);
-        mSatelliteManager.requestEnabled(true, true, Runnable::run, error::offer);
+        mSatelliteManager.requestEnabled(
+                new EnableRequestAttributes.Builder(true).setDemoMode(true).build(),
+                Runnable::run, error::offer);
         TextView showErrorStatusTextView = findViewById(R.id.showErrorStatus);
         try {
             Integer value = error.poll(TIMEOUT, TimeUnit.MILLISECONDS);
@@ -228,7 +231,9 @@
         if (SatelliteTestApp.getTestSatelliteService() != null) {
             SatelliteTestApp.getTestSatelliteService().sendOnPendingDatagrams();
         }
-        mSatelliteManager.requestEnabled(true, true, Runnable::run, resultListener::offer);
+        mSatelliteManager.requestEnabled(
+                new EnableRequestAttributes.Builder(true).setDemoMode(true).build(),
+                Runnable::run, resultListener::offer);
         try {
             Integer value = resultListener.poll(TIMEOUT, TimeUnit.MILLISECONDS);
             if (value == null) {
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/ILocalSatelliteListener.aidl b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/ILocalSatelliteListener.aidl
index 2c320c8..0a32432 100644
--- a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/ILocalSatelliteListener.aidl
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/ILocalSatelliteListener.aidl
@@ -64,4 +64,10 @@
      * enableCellularModemWhileSatelliteModeIsOn from Telephony.
      */
     void onEnableCellularModemWhileSatelliteModeIsOn(in boolean enable);
+
+    /**
+     * Indicates that MockSatelliteService has just received the request
+     * setSatellitePlmn from Telephony.
+     */
+    void onSetSatellitePlmn();
 }
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/MultipleSendReceive.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/MultipleSendReceive.java
index 0e5ab4f..723f690 100644
--- a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/MultipleSendReceive.java
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/MultipleSendReceive.java
@@ -19,6 +19,7 @@
 import android.app.Activity;
 import android.content.Intent;
 import android.os.Bundle;
+import android.telephony.satellite.EnableRequestAttributes;
 import android.telephony.satellite.SatelliteDatagram;
 import android.telephony.satellite.SatelliteManager;
 import android.util.Log;
@@ -66,7 +67,9 @@
         SatelliteTestApp.getTestSatelliteService().sendOnSatelliteDatagramReceived(
                 mReceivedDatagram, 4);
         LinkedBlockingQueue<Integer> resultListener = new LinkedBlockingQueue<>(1);
-        mSatelliteManager.requestEnabled(true, true, Runnable::run, resultListener::offer);
+        mSatelliteManager.requestEnabled(
+                new EnableRequestAttributes.Builder(true).setDemoMode(true).build(),
+                Runnable::run, resultListener::offer);
         mSatelliteManager.pollPendingDatagrams(Runnable::run, resultListener::offer);
         SatelliteTestApp.getTestSatelliteService().sendOnSatelliteDatagramReceived(
                 mReceivedDatagram, 3);
@@ -127,7 +130,9 @@
     private void multipleSendReceiveSatelliteDatagramApp(View view) {
         mSatelliteManager.setDeviceAlignedWithSatellite(true);
         LinkedBlockingQueue<Integer> resultListener = new LinkedBlockingQueue<>(1);
-        mSatelliteManager.requestEnabled(true, true, Runnable::run, resultListener::offer);
+        mSatelliteManager.requestEnabled(
+                new EnableRequestAttributes.Builder(true).setDemoMode(true).build(),
+                Runnable::run, resultListener::offer);
         String mText = "This is a test datagram message";
         SatelliteDatagram datagram = new SatelliteDatagram(mText.getBytes());
         mSatelliteManager.sendDatagram(SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE,
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteControl.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteControl.java
index 2d01aec..dd7b825 100644
--- a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteControl.java
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteControl.java
@@ -20,6 +20,9 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.OutcomeReceiver;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.satellite.EnableRequestAttributes;
 import android.telephony.satellite.SatelliteCapabilities;
 import android.telephony.satellite.SatelliteManager;
 import android.telephony.satellite.stub.SatelliteResult;
@@ -28,6 +31,7 @@
 import android.widget.TextView;
 
 import java.time.Duration;
+import java.util.List;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
@@ -40,11 +44,13 @@
     private static final long TIMEOUT = 3000;
 
     private SatelliteManager mSatelliteManager;
+    private SubscriptionManager mSubscriptionManager;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         mSatelliteManager = getSystemService(SatelliteManager.class);
+        mSubscriptionManager = getSystemService(SubscriptionManager.class);
 
         setContentView(R.layout.activity_SatelliteControl);
         findViewById(R.id.enableSatellite)
@@ -63,6 +69,18 @@
                 .setOnClickListener(this::requestIsCommunicationAllowedForCurrentLocationApp);
         findViewById(R.id.requestTimeForNextSatelliteVisibility)
                 .setOnClickListener(this::requestTimeForNextSatelliteVisibilityApp);
+        findViewById(R.id.removeUserRestrictReason)
+                .setOnClickListener(this::removeUserRestrictReasonApp);
+        findViewById(R.id.addUserRestrictReason)
+                .setOnClickListener(this::addUserRestrictReasonApp);
+        findViewById(R.id.getSatellitePlmn)
+                .setOnClickListener(this::getSatellitePlmnApp);
+        findViewById(R.id.getAllSatellitePlmn)
+                .setOnClickListener(this::getAllSatellitePlmnApp);
+        findViewById(R.id.isSatelliteEnabledForCarrier)
+                .setOnClickListener(this::isSatelliteEnabledForCarrierApp);
+        findViewById(R.id.isRequestIsSatelliteEnabledForCarrier)
+                .setOnClickListener(this::isRequestIsSatelliteEnabledForCarrierApp);
         findViewById(R.id.Back).setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View view) {
@@ -73,7 +91,9 @@
 
     private void enableSatelliteApp(View view) {
         LinkedBlockingQueue<Integer> error = new LinkedBlockingQueue<>(1);
-        mSatelliteManager.requestEnabled(true, true, Runnable::run, error::offer);
+        mSatelliteManager.requestEnabled(
+                new EnableRequestAttributes.Builder(true).setDemoMode(true).build(),
+                Runnable::run, error::offer);
         TextView textView = findViewById(R.id.text_id);
         try {
             Integer value = error.poll(TIMEOUT, TimeUnit.MILLISECONDS);
@@ -92,7 +112,8 @@
 
     private void disableSatelliteApp(View view) {
         LinkedBlockingQueue<Integer> error = new LinkedBlockingQueue<>(1);
-        mSatelliteManager.requestEnabled(false, true, Runnable::run, error::offer);
+        mSatelliteManager.requestEnabled(new EnableRequestAttributes.Builder(false).build(),
+                Runnable::run, error::offer);
         TextView textView = findViewById(R.id.text_id);
         try {
             Integer value = error.poll(TIMEOUT, TimeUnit.MILLISECONDS);
@@ -270,4 +291,87 @@
         };
         mSatelliteManager.requestTimeForNextSatelliteVisibility(Runnable::run, receiver);
     }
+
+    private void removeUserRestrictReasonApp(View view) {
+        TextView textView = findViewById(R.id.text_id);
+        LinkedBlockingQueue<Integer> error = new LinkedBlockingQueue<>(1);
+        List<SubscriptionInfo> infoList = mSubscriptionManager.getAvailableSubscriptionInfoList();
+        List<Integer> subIdList = infoList.stream()
+                .map(SubscriptionInfo::getSubscriptionId)
+                .toList();
+        for (int subId : subIdList) {
+            mSatelliteManager.removeAttachRestrictionForCarrier(subId,
+                    SatelliteManager.SATELLITE_COMMUNICATION_RESTRICTION_REASON_USER,
+                    Runnable::run, error::offer);
+        }
+
+        try {
+            Integer value = error.poll(TIMEOUT, TimeUnit.MILLISECONDS);
+            if (value == null) {
+                textView.setText("Timed out to removeAttachRestrictionForCarrier");
+            } else if (value != SatelliteResult.SATELLITE_RESULT_SUCCESS) {
+                textView.setText("Failed to removeAttachRestrictionForCarrier with error = "
+                        + SatelliteErrorUtils.mapError(value));
+            } else {
+                textView.setText(subIdList == null || subIdList.isEmpty() ? "no active subId list" :
+                        "removeAttachRestrictionForCarrier for all subIdList=" + subIdList);
+            }
+        } catch (InterruptedException e) {
+            textView.setText("removeAttachRestrictionForCarrier exception caught =" + e);
+        }
+    }
+
+    private void addUserRestrictReasonApp(View view) {
+        TextView textView = findViewById(R.id.text_id);
+        LinkedBlockingQueue<Integer> error = new LinkedBlockingQueue<>(1);
+        List<SubscriptionInfo> infoList = mSubscriptionManager.getAvailableSubscriptionInfoList();
+        List<Integer> subIdList = infoList.stream()
+                .map(SubscriptionInfo::getSubscriptionId)
+                .toList();
+        for (int subId : subIdList) {
+            mSatelliteManager.addAttachRestrictionForCarrier(subId,
+                    SatelliteManager.SATELLITE_COMMUNICATION_RESTRICTION_REASON_USER,
+                    Runnable::run, error::offer);
+        }
+
+        try {
+            Integer value = error.poll(TIMEOUT, TimeUnit.MILLISECONDS);
+            if (value == null) {
+                textView.setText("Timed out to addAttachRestrictionForCarrier");
+            } else if (value != SatelliteResult.SATELLITE_RESULT_SUCCESS) {
+                textView.setText("Failed to addAttachRestrictionForCarrier with error = "
+                        + SatelliteErrorUtils.mapError(value));
+            } else {
+                textView.setText(subIdList == null || subIdList.isEmpty() ? "no active subId list" :
+                        "addAttachRestrictionForCarrier for all subIdList=" + subIdList);
+            }
+        } catch (InterruptedException e) {
+            textView.setText("addAttachRestrictionForCarrier exception caught =" + e);
+        }
+    }
+
+    private void getSatellitePlmnApp(View view) {
+        TextView textView = findViewById(R.id.text_id);
+        textView.setText("[SatelliteService] getSatellitePlmnApp = "
+                + SatelliteTestApp.getTestSatelliteService().getCarrierPlmnList());
+    }
+
+    private void getAllSatellitePlmnApp(View view) {
+        TextView textView = findViewById(R.id.text_id);
+        textView.setText("[SatelliteService] getAllSatellitePlmnApp = "
+                + SatelliteTestApp.getTestSatelliteService().getAllSatellitePlmnList());
+    }
+
+    private void isSatelliteEnabledForCarrierApp(View view) {
+        TextView textView = findViewById(R.id.text_id);
+        textView.setText("[SatelliteService] isSatelliteEnabledForCarrier= "
+                + SatelliteTestApp.getTestSatelliteService().isSatelliteEnabledForCarrier());
+    }
+
+    private void isRequestIsSatelliteEnabledForCarrierApp(View view) {
+        TextView textView = findViewById(R.id.text_id);
+        textView.setText("[SatelliteService] isRequestIsSatelliteEnabledForCarrier= "
+                + SatelliteTestApp.getTestSatelliteService()
+                .isRequestIsSatelliteEnabledForCarrier());
+    }
 }
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteErrorUtils.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteErrorUtils.java
index ffdabdf..ef0c85c 100644
--- a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteErrorUtils.java
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteErrorUtils.java
@@ -16,7 +16,31 @@
 
 package com.android.phone.testapps.satellitetestapp;
 
-import android.telephony.satellite.stub.SatelliteResult;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_ACCESS_BARRED;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_ERROR;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_ILLEGAL_STATE;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_INVALID_TELEPHONY_STATE;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_MODEM_BUSY;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_MODEM_ERROR;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_NETWORK_ERROR;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_NETWORK_TIMEOUT;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_NOT_AUTHORIZED;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_NOT_REACHABLE;
+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_FAILED;
+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_SERVER_ERROR;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SERVICE_NOT_PROVISIONED;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SERVICE_PROVISION_IN_PROGRESS;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_INVALID_MODEM_STATE;
+import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_INVALID_ARGUMENTS;
+
 import android.util.Log;
 
 /**
@@ -31,44 +55,54 @@
      */
     public static String mapError(int error) {
         switch (error) {
-            case SatelliteResult.SATELLITE_RESULT_SUCCESS:
+            case SATELLITE_RESULT_SUCCESS:
                 return "SATELLITE_RESULT_SUCCESS";
-            case SatelliteResult.SATELLITE_RESULT_ERROR:
+            case SATELLITE_RESULT_ERROR:
                 return "SATELLITE_RESULT_ERROR";
-            case SatelliteResult.SATELLITE_RESULT_SERVER_ERROR:
+            case SATELLITE_RESULT_SERVER_ERROR:
                 return "SATELLITE_RESULT_SERVER_ERROR";
-            case SatelliteResult.SATELLITE_RESULT_SERVICE_ERROR:
+            case SATELLITE_RESULT_SERVICE_ERROR:
                 return "SATELLITE_RESULT_SERVICE_ERROR";
-            case SatelliteResult.SATELLITE_RESULT_MODEM_ERROR:
+            case SATELLITE_RESULT_MODEM_ERROR:
                 return "SATELLITE_RESULT_MODEM_ERROR";
-            case SatelliteResult.SATELLITE_RESULT_NETWORK_ERROR:
+            case SATELLITE_RESULT_NETWORK_ERROR:
                 return "SATELLITE_RESULT_NETWORK_ERROR";
-            case SatelliteResult.SATELLITE_RESULT_INVALID_MODEM_STATE:
+            case SATELLITE_RESULT_INVALID_TELEPHONY_STATE:
+                return "SATELLITE_RESULT_INVALID_TELEPHONY_STATE";
+            case SATELLITE_RESULT_INVALID_MODEM_STATE:
                 return "SATELLITE_RESULT_INVALID_MODEM_STATE";
-            case SatelliteResult.SATELLITE_RESULT_INVALID_ARGUMENTS:
+            case SATELLITE_RESULT_INVALID_ARGUMENTS:
                 return "SATELLITE_RESULT_INVALID_ARGUMENTS";
-            case SatelliteResult.SATELLITE_RESULT_REQUEST_FAILED:
+            case SATELLITE_RESULT_REQUEST_FAILED:
                 return "SATELLITE_RESULT_REQUEST_FAILED";
-            case SatelliteResult.SATELLITE_RESULT_RADIO_NOT_AVAILABLE:
+            case SATELLITE_RESULT_RADIO_NOT_AVAILABLE:
                 return "SATELLITE_RESULT_RADIO_NOT_AVAILABLE";
-            case SatelliteResult.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED:
+            case SATELLITE_RESULT_REQUEST_NOT_SUPPORTED:
                 return "SATELLITE_RESULT_REQUEST_NOT_SUPPORTED";
-            case SatelliteResult.SATELLITE_RESULT_NO_RESOURCES:
+            case SATELLITE_RESULT_NO_RESOURCES:
                 return "SATELLITE_RESULT_NO_RESOURCES";
-            case SatelliteResult.SATELLITE_RESULT_SERVICE_NOT_PROVISIONED:
+            case SATELLITE_RESULT_SERVICE_NOT_PROVISIONED:
                 return "SATELLITE_RESULT_SERVICE_NOT_PROVISIONED";
-            case SatelliteResult.SATELLITE_RESULT_SERVICE_PROVISION_IN_PROGRESS:
+            case SATELLITE_RESULT_SERVICE_PROVISION_IN_PROGRESS:
                 return "SATELLITE_RESULT_SERVICE_PROVISION_IN_PROGRESS";
-            case SatelliteResult.SATELLITE_RESULT_REQUEST_ABORTED:
+            case SATELLITE_RESULT_REQUEST_ABORTED:
                 return "SATELLITE_RESULT_REQUEST_ABORTED";
-            case SatelliteResult.SATELLITE_RESULT_ACCESS_BARRED:
+            case SATELLITE_RESULT_ACCESS_BARRED:
                 return "SATELLITE_RESULT_ACCESS_BARRED";
-            case SatelliteResult.SATELLITE_RESULT_NETWORK_TIMEOUT:
+            case SATELLITE_RESULT_NETWORK_TIMEOUT:
                 return "SATELLITE_RESULT_NETWORK_TIMEOUT";
-            case SatelliteResult.SATELLITE_RESULT_NOT_REACHABLE:
+            case SATELLITE_RESULT_NOT_REACHABLE:
                 return "SATELLITE_RESULT_NOT_REACHABLE";
-            case SatelliteResult.SATELLITE_RESULT_NOT_AUTHORIZED:
+            case SATELLITE_RESULT_NOT_AUTHORIZED:
                 return "SATELLITE_RESULT_NOT_AUTHORIZED";
+            case SATELLITE_RESULT_NOT_SUPPORTED:
+                return "SATELLITE_RESULT_NOT_SUPPORTED";
+            case SATELLITE_RESULT_REQUEST_IN_PROGRESS:
+                return "SATELLITE_RESULT_REQUEST_IN_PROGRESS";
+            case SATELLITE_RESULT_MODEM_BUSY:
+                return "SATELLITE_RESULT_MODEM_BUSY";
+            case SATELLITE_RESULT_ILLEGAL_STATE:
+                return "SATELLITE_RESULT_ILLEGAL_STATE";
         }
         Log.d(TAG, "Received invalid satellite service error: " + error);
         return "SATELLITE_RESULT_SERVICE_ERROR";
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteTestApp.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteTestApp.java
index ced9a06..c8ee5fa 100644
--- a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteTestApp.java
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteTestApp.java
@@ -138,6 +138,11 @@
                 public void onEnableCellularModemWhileSatelliteModeIsOn(boolean enable) {
                     Log.d(TAG, "onEnableCellularModemWhileSatelliteModeIsOn");
                 }
+
+                @Override
+                public void onSetSatellitePlmn() {
+                    Log.d(TAG, "onSetSatellitePlmn");
+                }
             };
 
     private class TestSatelliteServiceConnection implements ServiceConnection {
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SendReceive.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SendReceive.java
index b5e82b1..ab7b1c4 100644
--- a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SendReceive.java
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SendReceive.java
@@ -21,6 +21,7 @@
 import android.os.Bundle;
 import android.os.CancellationSignal;
 import android.os.OutcomeReceiver;
+import android.telephony.satellite.EnableRequestAttributes;
 import android.telephony.satellite.PointingInfo;
 import android.telephony.satellite.SatelliteCapabilities;
 import android.telephony.satellite.SatelliteDatagram;
@@ -157,7 +158,9 @@
         if (SatelliteTestApp.getTestSatelliteService() != null) {
             SatelliteTestApp.getTestSatelliteService().sendOnPendingDatagrams();
         }
-        mSatelliteManager.requestEnabled(true, true, Runnable::run, resultListener::offer);
+        mSatelliteManager.requestEnabled(
+                new EnableRequestAttributes.Builder(true).setDemoMode(true).build(),
+                Runnable::run, resultListener::offer);
         try {
             Integer value = resultListener.poll(TIMEOUT, TimeUnit.MILLISECONDS);
             if (value == null) {
@@ -238,7 +241,9 @@
         //Satellite Position
         SatelliteTransmissionUpdateCallbackTestApp callback =
                 new SatelliteTransmissionUpdateCallbackTestApp();
-        mSatelliteManager.requestEnabled(true, true, Runnable::run, error::offer);
+        mSatelliteManager.requestEnabled(
+                new EnableRequestAttributes.Builder(true).setDemoMode(true).build(),
+                Runnable::run, error::offer);
         try {
             Integer value = error.poll(TIMEOUT, TimeUnit.MILLISECONDS);
             if (value == null) {
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteService.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteService.java
index 9bea30c..af37611 100644
--- a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteService.java
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteService.java
@@ -41,7 +41,9 @@
 import com.android.internal.util.FunctionalUtils;
 import com.android.telephony.Rlog;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Executor;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -94,6 +96,10 @@
     private boolean mIsSupported;
     private int mModemState;
     private boolean mIsCellularModemEnabledMode;
+    private List<String> mCarrierPlmnList = new ArrayList<>();
+    private List<String> mAllPlmnList = new ArrayList<>();
+    private boolean mIsSatelliteEnabledForCarrier;
+    private boolean mIsRequestIsSatelliteEnabledForCarrier;
 
     /**
      * Create TestSatelliteService using the Executor specified for methods being called from
@@ -109,6 +115,8 @@
         mIsSupported = true;
         mModemState = SatelliteModemState.SATELLITE_MODEM_STATE_OFF;
         mIsCellularModemEnabledMode = false;
+        mIsSatelliteEnabledForCarrier = false;
+        mIsRequestIsSatelliteEnabledForCarrier = false;
     }
 
     /**
@@ -389,6 +397,55 @@
         runWithExecutor(() -> callback.accept(SATELLITE_ALWAYS_VISIBLE));
     }
 
+    @Override
+    public void setSatellitePlmn(int simLogicalSlotIndex, List<String> carrierPlmnList,
+            List<String> allSatellitePlmnList, IIntegerConsumer resultCallback) {
+        logd("setSatellitePlmn: simLogicalSlotIndex=" + simLogicalSlotIndex + " , carrierPlmnList="
+                + carrierPlmnList + " , allSatellitePlmnList=" + allSatellitePlmnList);
+        if (mErrorCode != SatelliteResult.SATELLITE_RESULT_SUCCESS) {
+            runWithExecutor(() -> resultCallback.accept(mErrorCode));
+            return;
+        }
+        runWithExecutor(() -> resultCallback.accept(SatelliteResult.SATELLITE_RESULT_SUCCESS));
+
+        mCarrierPlmnList = carrierPlmnList;
+        mAllPlmnList = allSatellitePlmnList;
+
+        if (mLocalListener != null) {
+            runWithExecutor(() -> mLocalListener.onSetSatellitePlmn());
+        } else {
+            loge("setSatellitePlmn: mLocalListener is null");
+        }
+    }
+
+    @Override
+    public void setSatelliteEnabledForCarrier(int simLogicalSlotIndex, boolean satelliteEnabled,
+            IIntegerConsumer callback) {
+        logd("setSatelliteEnabledForCarrier: simLogicalSlotIndex=" + simLogicalSlotIndex
+                + ", satelliteEnabled=" + satelliteEnabled);
+        if (mErrorCode != SatelliteResult.SATELLITE_RESULT_SUCCESS) {
+            runWithExecutor(() -> callback.accept(mErrorCode));
+            return;
+        }
+
+        mIsSatelliteEnabledForCarrier = satelliteEnabled;
+        runWithExecutor(() -> callback.accept(SatelliteResult.SATELLITE_RESULT_SUCCESS));
+    }
+
+    @Override
+    public void requestIsSatelliteEnabledForCarrier(int simLogicalSlotIndex,
+            IIntegerConsumer resultCallback, IBooleanConsumer callback) {
+        logd("requestIsSatelliteEnabledForCarrier: simLogicalSlotIndex=" + simLogicalSlotIndex);
+        if (mErrorCode != SatelliteResult.SATELLITE_RESULT_SUCCESS) {
+            runWithExecutor(() -> resultCallback.accept(mErrorCode));
+            mIsRequestIsSatelliteEnabledForCarrier = false;
+            return;
+        }
+
+        runWithExecutor(() -> callback.accept(mIsSatelliteEnabledForCarrier));
+        mIsRequestIsSatelliteEnabledForCarrier = true;
+    }
+
     public void setLocalSatelliteListener(@NonNull ILocalSatelliteListener listener) {
         logd("setLocalSatelliteListener: listener=" + listener);
         mLocalListener = listener;
@@ -508,6 +565,22 @@
         }
     }
 
+    public List<String> getCarrierPlmnList() {
+        return mCarrierPlmnList;
+    }
+
+    public List<String> getAllSatellitePlmnList() {
+        return mAllPlmnList;
+    }
+
+    public boolean isSatelliteEnabledForCarrier() {
+        return mIsSatelliteEnabledForCarrier;
+    }
+
+    public boolean isRequestIsSatelliteEnabledForCarrier() {
+        return mIsRequestIsSatelliteEnabledForCarrier;
+    }
+
     /**
      * Log the message to the radio buffer with {@code DEBUG} priority.
      *
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteWrapper.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteWrapper.java
index e4c2005..4f0679d 100644
--- a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteWrapper.java
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteWrapper.java
@@ -36,8 +36,10 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.function.Consumer;
 import java.util.stream.Collectors;
 
 /**
@@ -53,6 +55,7 @@
     private NtnSignalStrengthCallback mNtnSignalStrengthCallback = null;
     private SatelliteCapabilitiesCallbackWrapper mSatelliteCapabilitiesCallback;
     private SubscriptionManager mSubscriptionManager;
+    private int mSubId;
 
     private ListView mLogListView;
 
@@ -61,6 +64,7 @@
         super.onCreate(savedInstanceState);
         mSatelliteManagerWrapper = SatelliteManagerWrapper.getInstance(this);
         mSubscriptionManager = getSystemService(SubscriptionManager.class);
+        mSubId = getActiveSubId();
 
         setContentView(R.layout.activity_TestSatelliteWrapper);
         findViewById(R.id.requestNtnSignalStrength)
@@ -75,6 +79,26 @@
                 .setOnClickListener(this::registerForCapabilitiesChanged);
         findViewById(R.id.unregisterForSatelliteCapabilitiesChanged)
                 .setOnClickListener(this::unregisterForCapabilitiesChanged);
+        findViewById(R.id.isNonTerrestrialNetwork)
+                .setOnClickListener(this::isNonTerrestrialNetwork);
+        findViewById(R.id.getAvailableServices)
+                .setOnClickListener(this::getAvailableServices);
+        findViewById(R.id.isUsingNonTerrestrialNetwork)
+                .setOnClickListener(this::isUsingNonTerrestrialNetwork);
+        findViewById(R.id.requestAttachEnabledForCarrier_enable)
+                .setOnClickListener(this::requestAttachEnabledForCarrier_enable);
+        findViewById(R.id.requestAttachEnabledForCarrier_disable)
+                .setOnClickListener(this::requestAttachEnabledForCarrier_disable);
+        findViewById(R.id.requestIsAttachEnabledForCarrier)
+                .setOnClickListener(this::requestIsAttachEnabledForCarrier);
+        findViewById(R.id.addAttachRestrictionForCarrier)
+                .setOnClickListener(this::addAttachRestrictionForCarrier);
+        findViewById(R.id.removeAttachRestrictionForCarrier)
+                .setOnClickListener(this::removeAttachRestrictionForCarrier);
+        findViewById(R.id.getAttachRestrictionReasonsForCarrier)
+                .setOnClickListener(this::getAttachRestrictionReasonsForCarrier);
+        findViewById(R.id.getSatellitePlmnsForCarrier)
+                .setOnClickListener(this::getSatellitePlmnsForCarrier);
         findViewById(R.id.Back).setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View view) {
@@ -107,21 +131,24 @@
 
         if (mSatelliteManagerWrapper != null) {
             if (mNtnSignalStrengthCallback != null) {
-                Log.d(TAG, "unregisterForNtnSignalStrengthChanged()");
+                logd("unregisterForNtnSignalStrengthChanged()");
                 mSatelliteManagerWrapper.unregisterForNtnSignalStrengthChanged(
                         mNtnSignalStrengthCallback);
             }
             if (mSatelliteCapabilitiesCallback != null) {
-                Log.d(TAG, "unregisterForCapabilitiesChanged()");
+                logd("unregisterForCapabilitiesChanged()");
                 mSatelliteManagerWrapper.unregisterForCapabilitiesChanged(
                         mSatelliteCapabilitiesCallback);
             }
         }
+        mSubscriptionManager = null;
+        mSatelliteManagerWrapper = null;
+        mExecutor.shutdown();
     }
 
     private void requestNtnSignalStrength(View view) {
         addLogMessage("requestNtnSignalStrength");
-        Log.d(TAG, "requestNtnSignalStrength");
+        logd("requestNtnSignalStrength");
         OutcomeReceiver<NtnSignalStrengthWrapper,
                 SatelliteManagerWrapper.SatelliteExceptionWrapper> receiver =
                 new OutcomeReceiver<>() {
@@ -138,7 +165,7 @@
                         if (exception != null) {
                             String onError = "requestNtnSignalStrength exception: "
                                     + translateResultCodeToString(exception.getErrorCode());
-                            Log.d(TAG, onError);
+                            logd(onError);
                             addLogMessage(onError);
                         }
                     }
@@ -148,16 +175,16 @@
             mSatelliteManagerWrapper.requestNtnSignalStrength(mExecutor, receiver);
         } catch (SecurityException ex) {
             String errorMessage = "requestNtnSignalStrength: " + ex.getMessage();
-            Log.d(TAG, errorMessage);
+            logd(errorMessage);
             addLogMessage(errorMessage);
         }
     }
 
     private void registerForNtnSignalStrengthChanged(View view) {
         addLogMessage("registerForNtnSignalStrengthChanged");
-        Log.d(TAG, "registerForNtnSignalStrengthChanged()");
+        logd("registerForNtnSignalStrengthChanged()");
         if (mNtnSignalStrengthCallback == null) {
-            Log.d(TAG, "create new NtnSignalStrengthCallback instance.");
+            logd("create new NtnSignalStrengthCallback instance.");
             mNtnSignalStrengthCallback = new NtnSignalStrengthCallback();
         }
 
@@ -166,7 +193,7 @@
                     mNtnSignalStrengthCallback);
         } catch (Exception ex) {
             String errorMessage = "registerForNtnSignalStrengthChanged: " + ex.getMessage();
-            Log.d(TAG, errorMessage);
+            logd(errorMessage);
             addLogMessage(errorMessage);
             mNtnSignalStrengthCallback = null;
         }
@@ -174,7 +201,7 @@
 
     private void unregisterForNtnSignalStrengthChanged(View view) {
         addLogMessage("unregisterForNtnSignalStrengthChanged");
-        Log.d(TAG, "unregisterForNtnSignalStrengthChanged()");
+        logd("unregisterForNtnSignalStrengthChanged()");
         if (mNtnSignalStrengthCallback != null) {
             mSatelliteManagerWrapper.unregisterForNtnSignalStrengthChanged(
                     mNtnSignalStrengthCallback);
@@ -187,7 +214,7 @@
 
     private void isOnlyNonTerrestrialNetworkSubscription(View view) {
         addLogMessage("isOnlyNonTerrestrialNetworkSubscription");
-        Log.d(TAG, "isOnlyNonTerrestrialNetworkSubscription()");
+        logd("isOnlyNonTerrestrialNetworkSubscription()");
         List<SubscriptionInfo> infoList = mSubscriptionManager.getAvailableSubscriptionInfoList();
         List<Integer> subIdList = infoList.stream()
                 .map(SubscriptionInfo::getSubscriptionId)
@@ -214,13 +241,13 @@
 
     private void registerForCapabilitiesChanged(View view) {
         addLogMessage("registerForCapabilitiesChanged");
-        Log.d(TAG, "registerForCapabilitiesChanged()");
+        logd("registerForCapabilitiesChanged()");
         if (mSatelliteCapabilitiesCallback == null) {
             mSatelliteCapabilitiesCallback =
                     SatelliteCapabilities -> {
                         String message = "Received SatelliteCapabillities : "
                                 + SatelliteCapabilities;
-                        Log.d(TAG, message);
+                        logd(message);
                         runOnUiThread(() -> addLogMessage(message));
                     };
         }
@@ -229,7 +256,7 @@
                 mSatelliteCapabilitiesCallback);
         if (result != SatelliteManagerWrapper.SATELLITE_RESULT_SUCCESS) {
             String onError = translateResultCodeToString(result);
-            Log.d(TAG, onError);
+            logd(onError);
             addLogMessage(onError);
             mSatelliteCapabilitiesCallback = null;
         }
@@ -237,7 +264,7 @@
 
     private void unregisterForCapabilitiesChanged(View view) {
         addLogMessage("unregisterForCapabilitiesChanged");
-        Log.d(TAG, "unregisterForCapabilitiesChanged()");
+        logd("unregisterForCapabilitiesChanged()");
         if (mSatelliteCapabilitiesCallback != null) {
             mSatelliteManagerWrapper.unregisterForCapabilitiesChanged(
                     mSatelliteCapabilitiesCallback);
@@ -253,11 +280,238 @@
         public void onNtnSignalStrengthChanged(
                 @NonNull NtnSignalStrengthWrapper ntnSignalStrength) {
             String message = "Received NTN SignalStrength : " + ntnSignalStrength.getLevel();
-            Log.d(TAG, message);
+            logd(message);
             runOnUiThread(() -> addLogMessage(message));
         }
     }
 
+    private void isNonTerrestrialNetwork(View view) {
+        boolean isNonTerrestrialNetwork = mSatelliteManagerWrapper.isNonTerrestrialNetwork(mSubId);
+        addLogMessage("isNonTerrestrialNetwork=" + isNonTerrestrialNetwork);
+        logd("isNonTerrestrialNetwork=" + isNonTerrestrialNetwork);
+    }
+
+    private void getAvailableServices(View view) {
+        List<Integer> as = mSatelliteManagerWrapper.getAvailableServices(mSubId);
+        String availableServices = as.stream().map(Object::toString).collect(
+                Collectors.joining(", "));
+        addLogMessage("getAvailableServices=" + availableServices);
+        logd("getAvailableServices=" + availableServices);
+    }
+
+    private void isUsingNonTerrestrialNetwork(View view) {
+        boolean isUsingNonTerrestrialNetwork =
+                mSatelliteManagerWrapper.isUsingNonTerrestrialNetwork(mSubId);
+        addLogMessage("isUsingNonTerrestrialNetwork=" + isUsingNonTerrestrialNetwork);
+        logd("isUsingNonTerrestrialNetwork=" + isUsingNonTerrestrialNetwork);
+    }
+
+    private void requestAttachEnabledForCarrier_enable(View view) {
+        addLogMessage("requestAttachEnabledForCarrier");
+        logd("requestAttachEnabledForCarrier");
+
+        if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            addLogMessage("requestAttachEnabledForCarrier: Subscription ID is invalid");
+            logd("requestAttachEnabledForCarrier: Subscription ID is invalid");
+            return;
+        }
+
+        Consumer<Integer> callback = result -> {
+            runOnUiThread(() -> addLogMessage("requestAttachEnabledForCarrier result: " + result));
+            logd("requestAttachEnabledForCarrier result: " + result);
+        };
+
+        try {
+            mSatelliteManagerWrapper.requestAttachEnabledForCarrier(mSubId, true, mExecutor,
+                    callback);
+        } catch (SecurityException | IllegalArgumentException ex) {
+            String errorMessage = "requestAttachEnabledForCarrier: " + ex.getMessage();
+            logd(errorMessage);
+            addLogMessage(errorMessage);
+        }
+    }
+
+    private void requestAttachEnabledForCarrier_disable(View view) {
+        addLogMessage("requestAttachEnabledForCarrier");
+        logd("requestAttachEnabledForCarrier");
+
+        if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            addLogMessage("requestAttachEnabledForCarrier: Subscription ID is invalid");
+            logd("requestAttachEnabledForCarrier: Subscription ID is invalid");
+            return;
+        }
+
+        Consumer<Integer> callback = result -> {
+            runOnUiThread(() -> addLogMessage("requestAttachEnabledForCarrier result: " + result));
+            logd("requestAttachEnabledForCarrier result: " + result);
+        };
+
+        try {
+            mSatelliteManagerWrapper.requestAttachEnabledForCarrier(mSubId, false, mExecutor,
+                    callback);
+        } catch (SecurityException | IllegalArgumentException ex) {
+            String errorMessage = "requestAttachEnabledForCarrier: " + ex.getMessage();
+            logd(errorMessage);
+            addLogMessage(errorMessage);
+        }
+    }
+
+    private void requestIsAttachEnabledForCarrier(View view) {
+        logd("requestIsAttachEnabledForCarrier");
+        addLogMessage("requestIsAttachEnabledForCarrier");
+
+        if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            addLogMessage("requestIsAttachEnabledForCarrier: Subscription ID is invalid");
+            logd("requestIsAttachEnabledForCarrier: Subscription ID is invalid");
+            return;
+        }
+
+        OutcomeReceiver<Boolean,
+                SatelliteManagerWrapper.SatelliteExceptionWrapper> receiver =
+                new OutcomeReceiver<>() {
+                    @Override
+                    public void onResult(Boolean result) {
+                        logd("requestIsAttachEnabledForCarrier: onResult=" + result);
+                        addLogMessage("requestIsAttachEnabledForCarrier: onResult=" + result);
+                    }
+
+                    @Override
+                    public void onError(
+                            SatelliteManagerWrapper.SatelliteExceptionWrapper exception) {
+                        if (exception != null) {
+                            String onError = "requestIsAttachEnabledForCarrier exception: "
+                                    + translateResultCodeToString(exception.getErrorCode());
+                            logd(onError);
+                            addLogMessage(onError);
+                        }
+                    }
+                };
+
+        try {
+            mSatelliteManagerWrapper.requestIsAttachEnabledForCarrier(mSubId, mExecutor, receiver);
+        } catch (SecurityException | IllegalStateException | IllegalArgumentException ex) {
+            String errorMessage = "requestIsAttachEnabledForCarrier: " + ex.getMessage();
+            logd(errorMessage);
+            addLogMessage(errorMessage);
+        }
+    }
+
+    private void addAttachRestrictionForCarrier(View view) {
+        addLogMessage("addAttachRestrictionForCarrier");
+        logd("addAttachRestrictionForCarrier");
+
+        if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            addLogMessage("addAttachRestrictionForCarrier: Subscription ID is invalid");
+            logd("addAttachRestrictionForCarrier: Subscription ID is invalid");
+            return;
+        }
+
+        int reason = SatelliteManagerWrapper.SATELLITE_COMMUNICATION_RESTRICTION_REASON_USER;
+
+        Consumer<Integer> callback = result -> {
+            runOnUiThread(() -> addLogMessage("addAttachRestrictionForCarrier result: " + result));
+            logd("addAttachRestrictionForCarrier result: " + result);
+        };
+
+        try {
+            mSatelliteManagerWrapper.addAttachRestrictionForCarrier(mSubId, reason, mExecutor,
+                    callback);
+        } catch (SecurityException | IllegalArgumentException ex) {
+            String errorMessage = "addAttachRestrictionForCarrier: " + ex.getMessage();
+            logd(errorMessage);
+            addLogMessage(errorMessage);
+        }
+    }
+
+    private void removeAttachRestrictionForCarrier(View view) {
+        addLogMessage("removeAttachRestrictionForCarrier");
+        logd("removeAttachRestrictionForCarrier");
+
+        if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            addLogMessage("removeAttachRestrictionForCarrier: Subscription ID is invalid");
+            logd("removeAttachRestrictionForCarrier: Subscription ID is invalid");
+            return;
+        }
+
+        int reason = SatelliteManagerWrapper.SATELLITE_COMMUNICATION_RESTRICTION_REASON_USER;
+
+        Consumer<Integer> callback = result -> {
+            runOnUiThread(
+                    () -> addLogMessage("removeAttachRestrictionForCarrier result: " + result));
+            logd("removeAttachRestrictionForCarrier result: " + result);
+        };
+
+        try {
+            mSatelliteManagerWrapper.removeAttachRestrictionForCarrier(mSubId, reason, mExecutor,
+                    callback);
+        } catch (SecurityException | IllegalArgumentException ex) {
+            String errorMessage = "removeAttachRestrictionForCarrier: " + ex.getMessage();
+            logd(errorMessage);
+            addLogMessage(errorMessage);
+        }
+    }
+
+    private void getAttachRestrictionReasonsForCarrier(View view) {
+        addLogMessage("getAttachRestrictionReasonsForCarrier");
+        logd("getAttachRestrictionReasonsForCarrier");
+
+        if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            addLogMessage("getAttachRestrictionReasonsForCarrier: Subscription ID is invalid");
+            logd("getAttachRestrictionReasonsForCarrier: Subscription ID is invalid");
+            return;
+        }
+
+        try {
+            Set<Integer> reasons = mSatelliteManagerWrapper.getAttachRestrictionReasonsForCarrier(
+                    mSubId);
+            String stringReasons = reasons.stream().map(Object::toString).collect(
+                    Collectors.joining(", "));
+            logd("getAttachRestrictionReasonsForCarrier=" + stringReasons);
+            addLogMessage("getAttachRestrictionReasonsForCarrier=" + stringReasons);
+        } catch (SecurityException | IllegalArgumentException ex) {
+            String errorMessage = "getAttachRestrictionReasonsForCarrier: " + ex.getMessage();
+            logd(errorMessage);
+            addLogMessage(errorMessage);
+        }
+    }
+
+    private void getSatellitePlmnsForCarrier(View view) {
+        addLogMessage("getSatellitePlmnsForCarrier");
+        logd("getSatellitePlmnsForCarrier");
+
+        if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            addLogMessage("getSatellitePlmnsForCarrier: Subscription ID is invalid");
+            logd("getSatellitePlmnsForCarrier: Subscription ID is invalid");
+            return;
+        }
+
+        try {
+            List<String> reasons = mSatelliteManagerWrapper.getSatellitePlmnsForCarrier(
+                    mSubId);
+            String stringReasons = reasons.stream().collect(Collectors.joining(", "));
+            logd("getSatellitePlmnsForCarrier=" + stringReasons);
+            addLogMessage("getSatellitePlmnsForCarrier=" + stringReasons);
+        } catch (SecurityException | IllegalArgumentException ex) {
+            String errorMessage = "getSatellitePlmnsForCarrier: " + ex.getMessage();
+            logd(errorMessage);
+            addLogMessage(errorMessage);
+        }
+    }
+
+    private int getActiveSubId() {
+        int subId;
+        List<SubscriptionInfo> subscriptionInfoList =
+                mSubscriptionManager.getActiveSubscriptionInfoList();
+
+        if (subscriptionInfoList != null && subscriptionInfoList.size() > 0) {
+            subId = subscriptionInfoList.get(0).getSubscriptionId();
+        } else {
+            subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+        }
+        logd("getActiveSubId() returns " + subId);
+        return subId;
+    }
+
     private String translateResultCodeToString(
             @SatelliteManagerWrapper.SatelliteResult int result) {
         switch (result) {
@@ -319,4 +573,10 @@
         mAdapter.notifyDataSetChanged();
         mLogListView.setSelection(mAdapter.getCount() - 1);
     }
+
+    private static void logd(String message) {
+        if (message != null) {
+            Log.d(TAG, message);
+        }
+    }
 }
diff --git a/tests/src/com/android/phone/DiagnosticDataCollectorTest.java b/tests/src/com/android/phone/DiagnosticDataCollectorTest.java
index 2ca04b9..983d135 100644
--- a/tests/src/com/android/phone/DiagnosticDataCollectorTest.java
+++ b/tests/src/com/android/phone/DiagnosticDataCollectorTest.java
@@ -95,34 +95,37 @@
 
     @Test
     public void testPersistForTelecomDumpsys() throws IOException, InterruptedException {
-        TelephonyManager.EmergencyCallDiagnosticParams.Builder callDiagnosticBuilder =
-                new TelephonyManager.EmergencyCallDiagnosticParams.Builder();
-        TelephonyManager.EmergencyCallDiagnosticParams dp =
-                callDiagnosticBuilder.setTelecomDumpSysCollectionEnabled(true).build();
-        mDiagnosticDataCollector.persistEmergencyDianosticData(mConfig, dp, "test_tag_telecom");
+        TelephonyManager.EmergencyCallDiagnosticData.Builder callDiagnosticBuilder =
+                new TelephonyManager.EmergencyCallDiagnosticData.Builder();
+        TelephonyManager.EmergencyCallDiagnosticData ecdData =
+                callDiagnosticBuilder.setTelecomDumpsysCollectionEnabled(true).build();
+        mDiagnosticDataCollector.persistEmergencyDianosticData(
+                mConfig, ecdData, "test_tag_telecom");
 
         verifyCmdAndDropboxTag(TELECOM_DUMPSYS_COMMAND, "test_tag_telecom", false);
     }
 
     @Test
     public void testPersistForTelephonyDumpsys() throws IOException, InterruptedException {
-        TelephonyManager.EmergencyCallDiagnosticParams.Builder callDiagnosticBuilder =
-                new TelephonyManager.EmergencyCallDiagnosticParams.Builder();
-        TelephonyManager.EmergencyCallDiagnosticParams dp =
-                callDiagnosticBuilder.setTelephonyDumpSysCollectionEnabled(true).build();
-        mDiagnosticDataCollector.persistEmergencyDianosticData(mConfig, dp, "test_tag_telephony");
+        TelephonyManager.EmergencyCallDiagnosticData.Builder callDiagnosticBuilder =
+                new TelephonyManager.EmergencyCallDiagnosticData.Builder();
+        TelephonyManager.EmergencyCallDiagnosticData ecdData =
+                callDiagnosticBuilder.setTelephonyDumpsysCollectionEnabled(true).build();
+        mDiagnosticDataCollector.persistEmergencyDianosticData(
+                mConfig, ecdData, "test_tag_telephony");
 
         verifyCmdAndDropboxTag(TELEPHONY_DUMPSYS_COMMAND, "test_tag_telephony", false);
     }
 
     @Test
     public void testPersistForLogcat() throws IOException, InterruptedException {
-        TelephonyManager.EmergencyCallDiagnosticParams.Builder callDiagnosticBuilder =
-                new TelephonyManager.EmergencyCallDiagnosticParams.Builder();
-        TelephonyManager.EmergencyCallDiagnosticParams dp =
+        TelephonyManager.EmergencyCallDiagnosticData.Builder callDiagnosticBuilder =
+                new TelephonyManager.EmergencyCallDiagnosticData.Builder();
+        TelephonyManager.EmergencyCallDiagnosticData ecdData =
                 callDiagnosticBuilder.setLogcatCollectionStartTimeMillis(
                         SystemClock.elapsedRealtime()).build();
-        mDiagnosticDataCollector.persistEmergencyDianosticData(mConfig, dp, "test_tag_logcat");
+        mDiagnosticDataCollector.persistEmergencyDianosticData(
+                mConfig, ecdData, "test_tag_logcat");
 
         verifyCmdAndDropboxTag(LOGCAT_BINARY, "test_tag_logcat", true);
     }
diff --git a/tests/src/com/android/phone/ImsProvisioningControllerTest.java b/tests/src/com/android/phone/ImsProvisioningControllerTest.java
index db83cca..e12be53 100644
--- a/tests/src/com/android/phone/ImsProvisioningControllerTest.java
+++ b/tests/src/com/android/phone/ImsProvisioningControllerTest.java
@@ -68,10 +68,11 @@
 import android.telephony.ims.feature.RcsFeature.RcsImsCapabilities;
 import android.telephony.ims.stub.ImsConfigImplBase;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.TestableLooper;
 import android.util.Log;
 
+import androidx.test.filters.SmallTest;
+
 import com.android.ims.FeatureConnector;
 import com.android.ims.ImsConfig;
 import com.android.ims.ImsManager;
diff --git a/tests/src/com/android/phone/ImsProvisioningLoaderTest.java b/tests/src/com/android/phone/ImsProvisioningLoaderTest.java
index 61cab1d..207e454 100644
--- a/tests/src/com/android/phone/ImsProvisioningLoaderTest.java
+++ b/tests/src/com/android/phone/ImsProvisioningLoaderTest.java
@@ -28,10 +28,10 @@
 import android.telephony.ims.feature.MmTelFeature;
 import android.telephony.ims.feature.RcsFeature;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
 
 import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
 
 import org.junit.After;
 import org.junit.Before;
diff --git a/tests/src/com/android/phone/ImsStateCallbackControllerTest.java b/tests/src/com/android/phone/ImsStateCallbackControllerTest.java
index 2bd87be..c86502b 100644
--- a/tests/src/com/android/phone/ImsStateCallbackControllerTest.java
+++ b/tests/src/com/android/phone/ImsStateCallbackControllerTest.java
@@ -48,10 +48,11 @@
 import android.os.Looper;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyRegistryManager;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.TestableLooper;
 import android.util.Log;
 
+import androidx.test.filters.SmallTest;
+
 import com.android.TelephonyTestBase;
 import com.android.ims.FeatureConnector;
 import com.android.ims.ImsManager;
diff --git a/tests/src/com/android/phone/RcsProvisioningMonitorTest.java b/tests/src/com/android/phone/RcsProvisioningMonitorTest.java
index 57f9f6b..fe13d56 100644
--- a/tests/src/com/android/phone/RcsProvisioningMonitorTest.java
+++ b/tests/src/com/android/phone/RcsProvisioningMonitorTest.java
@@ -61,10 +61,11 @@
 import android.telephony.ims.aidl.IRcsConfigCallback;
 import android.test.mock.MockContentProvider;
 import android.test.mock.MockContentResolver;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.TestableLooper;
 import android.util.Log;
 
+import androidx.test.filters.SmallTest;
+
 import com.android.ims.FeatureConnector;
 import com.android.ims.RcsFeatureManager;
 import com.android.internal.telephony.ITelephony;
diff --git a/tests/src/com/android/phone/ServiceStateProviderTest.java b/tests/src/com/android/phone/ServiceStateProviderTest.java
index 4bbde79..1d2ca74 100644
--- a/tests/src/com/android/phone/ServiceStateProviderTest.java
+++ b/tests/src/com/android/phone/ServiceStateProviderTest.java
@@ -64,9 +64,9 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.test.mock.MockContentResolver;
-import android.test.suitebuilder.annotation.SmallTest;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
 
 import libcore.junit.util.compat.CoreCompatChangeRule;
 
diff --git a/tests/src/com/android/phone/security/SafetySourceReceiverTest.java b/tests/src/com/android/phone/security/SafetySourceReceiverTest.java
new file mode 100644
index 0000000..de1f101
--- /dev/null
+++ b/tests/src/com/android/phone/security/SafetySourceReceiverTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone.security;
+
+import static android.safetycenter.SafetyCenterManager.ACTION_REFRESH_SAFETY_SOURCES;
+import static android.safetycenter.SafetyCenterManager.EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.platform.test.flag.junit.SetFlagsRule;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.flags.Flags;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+public class SafetySourceReceiverTest {
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+    Context mContext;
+
+    SafetySourceReceiver mSafetySourceReceiver;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        SafetySourceReceiver receiver = new SafetySourceReceiver();
+        mSafetySourceReceiver = spy(receiver);
+    }
+
+    @Test
+    public void testOnReceive() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_IDENTIFIER_DISCLOSURE_TRANSPARENCY_UNSOL_EVENTS,
+                Flags.FLAG_ENABLE_MODEM_CIPHER_TRANSPARENCY_UNSOL_EVENTS);
+        Phone mockPhone = mock(Phone.class);
+        when(mSafetySourceReceiver.getDefaultPhone()).thenReturn(mockPhone);
+
+        Intent intent = new Intent(ACTION_REFRESH_SAFETY_SOURCES);
+        intent.putExtra(EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID, "aBroadcastId");
+        mSafetySourceReceiver.onReceive(mContext, intent);
+
+        verify(mockPhone, times(1)).refreshSafetySources("aBroadcastId");
+    }
+
+    @Test
+    public void testOnReceive_featureFlagsOff() {
+        mSetFlagsRule.disableFlags(
+                Flags.FLAG_ENABLE_IDENTIFIER_DISCLOSURE_TRANSPARENCY_UNSOL_EVENTS,
+                Flags.FLAG_ENABLE_MODEM_CIPHER_TRANSPARENCY_UNSOL_EVENTS);
+
+        Intent intent = new Intent(ACTION_REFRESH_SAFETY_SOURCES);
+        intent.putExtra(EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID, "aBroadcastId");
+        mSafetySourceReceiver.onReceive(mContext, intent);
+
+        verify(mSafetySourceReceiver, never()).getDefaultPhone();
+    }
+
+    @Test
+    public void testOnReceive_phoneNotReadyYet() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_IDENTIFIER_DISCLOSURE_TRANSPARENCY_UNSOL_EVENTS,
+                Flags.FLAG_ENABLE_MODEM_CIPHER_TRANSPARENCY_UNSOL_EVENTS,
+                Flags.FLAG_ENFORCE_TELEPHONY_FEATURE_MAPPING_FOR_PUBLIC_APIS);
+        when(mSafetySourceReceiver.getDefaultPhone()).thenReturn(null);
+
+        when(mContext.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_TELEPHONY)).thenReturn(true);
+
+        Intent intent = new Intent(ACTION_REFRESH_SAFETY_SOURCES);
+        intent.putExtra(EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID, "aBroadcastId");
+
+        // this call succeeding without a NPE means this test has passed. There are no observable
+        // side effects to a null Phone, because all side effects happen on the Phone instance.
+        mSafetySourceReceiver.onReceive(mContext, intent);
+    }
+
+    @Test
+    public void testOnReceive_noTelephonyFeature() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_IDENTIFIER_DISCLOSURE_TRANSPARENCY_UNSOL_EVENTS,
+                Flags.FLAG_ENABLE_MODEM_CIPHER_TRANSPARENCY_UNSOL_EVENTS,
+                Flags.FLAG_ENFORCE_TELEPHONY_FEATURE_MAPPING_FOR_PUBLIC_APIS);
+
+        when(mContext.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_TELEPHONY)).thenReturn(false);
+
+        Phone mockPhone = mock(Phone.class);
+        when(mSafetySourceReceiver.getDefaultPhone()).thenReturn(mockPhone);
+
+        Intent intent = new Intent(ACTION_REFRESH_SAFETY_SOURCES);
+        intent.putExtra(EXTRA_REFRESH_SAFETY_SOURCES_BROADCAST_ID, "aBroadcastId");
+        mSafetySourceReceiver.onReceive(mContext, intent);
+
+        verify(mockPhone, never()).refreshSafetySources(any());
+    }
+
+}
diff --git a/tests/src/com/android/services/telephony/ImsConferenceControllerTest.java b/tests/src/com/android/services/telephony/ImsConferenceControllerTest.java
index a9207e6..b1572f1 100644
--- a/tests/src/com/android/services/telephony/ImsConferenceControllerTest.java
+++ b/tests/src/com/android/services/telephony/ImsConferenceControllerTest.java
@@ -27,7 +27,8 @@
 import android.content.ComponentName;
 import android.os.Looper;
 import android.telecom.PhoneAccountHandle;
-import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.filters.SmallTest;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/src/com/android/services/telephony/ImsConferenceTest.java b/tests/src/com/android/services/telephony/ImsConferenceTest.java
index e2a199b..ca16bc7 100644
--- a/tests/src/com/android/services/telephony/ImsConferenceTest.java
+++ b/tests/src/com/android/services/telephony/ImsConferenceTest.java
@@ -40,7 +40,8 @@
 import android.telecom.StatusHints;
 import android.telecom.TelecomManager;
 import android.telephony.TelephonyManager;
-import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.filters.SmallTest;
 
 import com.android.ims.internal.ConferenceParticipant;
 
diff --git a/tests/src/com/android/services/telephony/TelephonyConferenceControllerTest.java b/tests/src/com/android/services/telephony/TelephonyConferenceControllerTest.java
index b7fe988..c7080b4 100644
--- a/tests/src/com/android/services/telephony/TelephonyConferenceControllerTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConferenceControllerTest.java
@@ -28,7 +28,8 @@
 import android.telecom.Conference;
 import android.telecom.Connection;
 import android.telecom.PhoneAccount;
-import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.filters.SmallTest;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
index 129b6f4..f0e900a 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
@@ -46,6 +46,7 @@
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
@@ -80,9 +81,9 @@
 import android.telephony.emergency.EmergencyNumber;
 import android.telephony.ims.ImsReasonInfo;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.util.ArrayMap;
 
+import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.TelephonyTestBase;
@@ -308,7 +309,7 @@
                 anyString(), anyInt());
         doReturn(CompletableFuture.completedFuture(NOT_DISCONNECTED))
                 .when(mEmergencyStateTracker)
-                .startEmergencyCall(any(), anyString(), eq(false));
+                .startEmergencyCall(any(), any(), eq(false));
         replaceInstance(TelephonyConnectionService.class,
                 "mDomainSelectionMainExecutor", mTestConnectionService, getExecutor());
         doReturn(false).when(mDomainSelectionResolver).isDomainSelectionSupported();
@@ -2141,13 +2142,22 @@
                 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1,
                         TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1));
 
+        ArgumentCaptor<android.telecom.Connection> connectionCaptor =
+                ArgumentCaptor.forClass(android.telecom.Connection.class);
+
         verify(mDomainSelectionResolver)
                 .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
         verify(mEmergencyStateTracker)
-                .startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+                .startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false));
         verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
         verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
 
+        android.telecom.Connection tc = connectionCaptor.getValue();
+
+        assertNotNull(tc);
+        assertEquals(TELECOM_CALL_ID1, tc.getTelecomCallId());
+        assertEquals(mTestConnectionService.getEmergencyConnection(), tc);
+
         ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
 
         verify(mPhone0).dial(anyString(), argsCaptor.capture(), any());
@@ -2171,13 +2181,22 @@
                 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1,
                         TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1));
 
+        ArgumentCaptor<android.telecom.Connection> connectionCaptor =
+                ArgumentCaptor.forClass(android.telecom.Connection.class);
+
         verify(mDomainSelectionResolver)
                 .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
         verify(mEmergencyStateTracker)
-                .startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+                .startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false));
         verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
         verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
 
+        android.telecom.Connection tc = connectionCaptor.getValue();
+
+        assertNotNull(tc);
+        assertEquals(TELECOM_CALL_ID1, tc.getTelecomCallId());
+        assertEquals(mTestConnectionService.getEmergencyConnection(), tc);
+
         ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
 
         verify(mPhone0).dial(anyString(), argsCaptor.capture(), any());
@@ -2204,14 +2223,23 @@
                 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1,
                         TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1));
 
+        ArgumentCaptor<android.telecom.Connection> connectionCaptor =
+                ArgumentCaptor.forClass(android.telecom.Connection.class);
+
         verify(mEmergencyStateTracker, times(1))
-                .startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+                .startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false));
         verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
         verify(mDomainSelectionResolver, times(0))
                 .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
         verify(mEmergencyCallDomainSelectionConnection, times(0))
                 .createEmergencyConnection(any(), any());
 
+        android.telecom.Connection tc = connectionCaptor.getValue();
+
+        assertNotNull(tc);
+        assertEquals(TELECOM_CALL_ID1, tc.getTelecomCallId());
+        assertEquals(mTestConnectionService.getEmergencyConnection(), tc);
+
         ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
 
         verify(mPhone0).dial(anyString(), argsCaptor.capture(), any());
@@ -2341,13 +2369,22 @@
                 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1,
                         TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1));
 
+        ArgumentCaptor<android.telecom.Connection> connectionCaptor =
+                ArgumentCaptor.forClass(android.telecom.Connection.class);
+
         verify(mDomainSelectionResolver)
                 .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
         verify(mEmergencyStateTracker)
-                .startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+                .startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false));
         verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
         verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
 
+        android.telecom.Connection tc = connectionCaptor.getValue();
+
+        assertNotNull(tc);
+        assertEquals(TELECOM_CALL_ID1, tc.getTelecomCallId());
+        assertEquals(mTestConnectionService.getEmergencyConnection(), tc);
+
         ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
 
         verify(mPhone0).dial(anyString(), argsCaptor.capture(), any());
@@ -2594,13 +2631,22 @@
         assertTrue(mTestConnectionService.maybeReselectDomain(c, reasonInfo, true,
                 android.telephony.DisconnectCause.NOT_VALID));
 
+        ArgumentCaptor<android.telecom.Connection> connectionCaptor =
+                ArgumentCaptor.forClass(android.telecom.Connection.class);
+
         verify(mDomainSelectionResolver)
                 .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
         verify(mEmergencyStateTracker)
-                .startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+                .startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false));
         verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
         verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
 
+        android.telecom.Connection tc = connectionCaptor.getValue();
+
+        assertNotNull(tc);
+        assertEquals(TELECOM_CALL_ID1, tc.getTelecomCallId());
+        assertEquals(mTestConnectionService.getEmergencyConnection(), tc);
+
         ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
 
         verify(mPhone0).dial(anyString(), argsCaptor.capture(), any());
@@ -2635,13 +2681,22 @@
         assertTrue(mTestConnectionService.maybeReselectDomain(c, reasonInfo, true,
                 android.telephony.DisconnectCause.NOT_VALID));
 
+        ArgumentCaptor<android.telecom.Connection> connectionCaptor =
+                ArgumentCaptor.forClass(android.telecom.Connection.class);
+
         verify(mDomainSelectionResolver)
                 .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
         verify(mEmergencyStateTracker)
-                .startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+                .startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false));
         verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
         verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
 
+        android.telecom.Connection tc = connectionCaptor.getValue();
+
+        assertNotNull(tc);
+        assertEquals(TELECOM_CALL_ID1, tc.getTelecomCallId());
+        assertEquals(mTestConnectionService.getEmergencyConnection(), tc);
+
         ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
 
         verify(mPhone0).dial(anyString(), argsCaptor.capture(), any());
@@ -2698,7 +2753,7 @@
 
         DomainSelectionService.SelectionAttributes attr = attrCaptor.getValue();
 
-        assertEquals(mPhone1.getPhoneId(), attr.getSlotId());
+        assertEquals(mPhone1.getPhoneId(), attr.getSlotIndex());
     }
 
     @Test
@@ -2744,7 +2799,7 @@
 
         DomainSelectionService.SelectionAttributes attr = attrCaptor.getValue();
 
-        assertEquals(mPhone1.getPhoneId(), attr.getSlotId());
+        assertEquals(mPhone1.getPhoneId(), attr.getSlotIndex());
     }
 
     @Test
@@ -2763,6 +2818,10 @@
                 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1,
                         TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1));
 
+        android.telecom.Connection c = mTestConnectionService.getEmergencyConnection();
+
+        assertNotNull(c);
+
         ArgumentCaptor<DomainSelectionConnection.DomainSelectionConnectionCallback> callbackCaptor =
                 ArgumentCaptor.forClass(
                         DomainSelectionConnection.DomainSelectionConnectionCallback.class);
@@ -2778,7 +2837,29 @@
         callback.onSelectionTerminated(ERROR_UNSPECIFIED);
 
         verify(mEmergencyCallDomainSelectionConnection).cancelSelection();
-        verify(mEmergencyStateTracker).endCall(eq(TELECOM_CALL_ID1));
+        verify(mEmergencyStateTracker).endCall(eq(c));
+    }
+
+    @Test
+    public void testDomainSelectionDialFailedByException() throws Exception {
+        setupForCallTest();
+
+        int selectedDomain = DOMAIN_CS;
+
+        setupForDialForDomainSelection(mPhone0, selectedDomain, true);
+
+        CallStateException cse = new CallStateException(CallStateException.ERROR_CALLING_DISABLED,
+                "Calling disabled via ro.telephony.disable-call property");
+        doThrow(cse).when(mPhone0).dial(anyString(), any(), any());
+
+        mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1,
+                createConnectionRequest(PHONE_ACCOUNT_HANDLE_1,
+                        TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1));
+
+        verify(mEmergencyStateTracker)
+                .startEmergencyCall(any(), any(), anyBoolean());
+        verify(mEmergencyCallDomainSelectionConnection).cancelSelection();
+        verify(mEmergencyStateTracker).endCall(any());
     }
 
     @Test
@@ -2791,26 +2872,23 @@
 
         CompletableFuture<Integer> future = new CompletableFuture<>();
         doReturn(future).when(mEmergencyStateTracker)
-                .startEmergencyCall(any(), anyString(), eq(false));
+                .startEmergencyCall(any(), any(), eq(false));
 
         mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1,
                 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1,
                         TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1));
 
         verify(mEmergencyStateTracker)
-                .startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
-
-        TelephonyConnection c = new TestTelephonyConnection();
-        c.setTelecomCallId(TELECOM_CALL_ID1);
+                .startEmergencyCall(eq(mPhone0), any(), eq(false));
 
         // dialing is canceled
-        mTestConnectionService.onLocalHangup(c);
+        mTestConnectionService.onLocalHangup(mTestConnectionService.getEmergencyConnection());
 
         // startEmergencyCall has completed
         future.complete(NOT_DISCONNECTED);
 
         // verify that createEmergencyConnection is discarded
-        verify(mEmergencyCallDomainSelectionConnection, times(0))
+        verify(mEmergencyCallDomainSelectionConnection, never())
                 .createEmergencyConnection(any(), any());
     }
 
@@ -2832,17 +2910,14 @@
 
         verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
 
-        TelephonyConnection c = new TestTelephonyConnection();
-        c.setTelecomCallId(TELECOM_CALL_ID1);
-
         // dialing is canceled
-        mTestConnectionService.onLocalHangup(c);
+        mTestConnectionService.onLocalHangup(mTestConnectionService.getEmergencyConnection());
 
         // domain selection has completed
         future.complete(selectedDomain);
 
         // verify that dialing is discarded
-        verify(mPhone0, times(0)).dial(anyString(), any(), any());
+        verify(mPhone0, never()).dial(anyString(), any(), any());
     }
 
     @Test
@@ -2855,7 +2930,6 @@
 
         TestTelephonyConnection c = setupForReDialForDomainSelection(
                 mPhone0, selectedDomain, preciseDisconnectCause, disconnectCause, true);
-        c.setTelecomCallId(TELECOM_CALL_ID1);
 
         CompletableFuture<Integer> future = new CompletableFuture<>();
         doReturn(future).when(mEmergencyCallDomainSelectionConnection)
@@ -2892,20 +2966,28 @@
                 mImsPhone, selectedDomain, preciseDisconnectCause, disconnectCause, false);
         c.setEmergencyServiceCategory(eccCategory);
         c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED);
-        c.setTelecomCallId(TELECOM_CALL_ID1);
 
         CompletableFuture<Integer> future = new CompletableFuture<>();
         doReturn(future).when(mEmergencyStateTracker)
-                .startEmergencyCall(any(), anyString(), eq(false));
+                .startEmergencyCall(any(), any(), eq(false));
 
         ImsReasonInfo reasonInfo = new ImsReasonInfo(CODE_SIP_ALTERNATE_EMERGENCY_CALL, 0, null);
         assertTrue(mTestConnectionService.maybeReselectDomain(c, reasonInfo, true,
                 android.telephony.DisconnectCause.NOT_VALID));
 
+        ArgumentCaptor<android.telecom.Connection> connectionCaptor =
+                ArgumentCaptor.forClass(android.telecom.Connection.class);
+
         verify(mEmergencyStateTracker)
-                .startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+                .startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false));
         verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
 
+        android.telecom.Connection tc = connectionCaptor.getValue();
+
+        assertNotNull(tc);
+        assertEquals(TELECOM_CALL_ID1, tc.getTelecomCallId());
+        assertEquals(mTestConnectionService.getEmergencyConnection(), tc);
+
         // dialing is canceled
         mTestConnectionService.onLocalHangup(c);
 
@@ -2934,7 +3016,6 @@
                 mImsPhone, selectedDomain, preciseDisconnectCause, disconnectCause, false);
         c.setEmergencyServiceCategory(eccCategory);
         c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED);
-        c.setTelecomCallId(TELECOM_CALL_ID1);
 
         CompletableFuture<Integer> future = new CompletableFuture<>();
         doReturn(future).when(mEmergencyCallDomainSelectionConnection)
@@ -2953,7 +3034,7 @@
         future.complete(selectedDomain);
 
         // verify that dialing is discarded
-        verify(mPhone0, times(0)).dial(anyString(), any(), any());
+        verify(mPhone0, never()).dial(anyString(), any(), any());
     }
 
     @Test
@@ -2968,15 +3049,25 @@
                 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1,
                         TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1));
 
+        ArgumentCaptor<android.telecom.Connection> connectionCaptor =
+                ArgumentCaptor.forClass(android.telecom.Connection.class);
+
         verify(mDomainSelectionResolver)
                 .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
         verify(mEmergencyStateTracker)
-                .startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+                .startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false));
         verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
         verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
         verify(mPhone0).dial(anyString(), any(), any());
 
+        android.telecom.Connection tc = connectionCaptor.getValue();
+
+        assertNotNull(tc);
+        assertEquals(TELECOM_CALL_ID1, tc.getTelecomCallId());
+        assertEquals(mTestConnectionService.getEmergencyConnection(), tc);
+
         TestTelephonyConnection c = new TestTelephonyConnection();
+        mTestConnectionService.setEmergencyConnection(c);
         c.setTelecomCallId(TELECOM_CALL_ID1);
         c.setIsImsConnection(true);
         Connection orgConn = c.getOriginalConnection();
@@ -2990,10 +3081,10 @@
         connectionListener.onOriginalConnectionConfigured(c);
 
         verify(mEmergencyStateTracker, times(1)).onEmergencyCallDomainUpdated(
-                eq(PhoneConstants.PHONE_TYPE_IMS), eq(TELECOM_CALL_ID1));
+                eq(PhoneConstants.PHONE_TYPE_IMS), eq(c));
 
         verify(mEmergencyStateTracker, times(0)).onEmergencyCallStateChanged(
-                any(), eq(TELECOM_CALL_ID1));
+                any(), eq(c));
         verify(mSatelliteSOSMessageRecommender, times(0))
                 .onEmergencyCallConnectionStateChanged(eq(TELECOM_CALL_ID1), anyInt());
 
@@ -3004,7 +3095,7 @@
 
         // ACTIVE sate is notified
         verify(mEmergencyStateTracker, times(1)).onEmergencyCallStateChanged(
-                eq(Call.State.ACTIVE), eq(TELECOM_CALL_ID1));
+                eq(Call.State.ACTIVE), eq(c));
         verify(mSatelliteSOSMessageRecommender, times(1))
                 .onEmergencyCallConnectionStateChanged(eq(TELECOM_CALL_ID1),
                         eq(android.telecom.Connection.STATE_ACTIVE));
@@ -3017,7 +3108,7 @@
 
         // state change not notified any more after CONNECTED once
         verify(mEmergencyStateTracker, times(1)).onEmergencyCallStateChanged(
-                any(), eq(TELECOM_CALL_ID1));
+                any(), eq(c));
         verify(mSatelliteSOSMessageRecommender, times(1))
                 .onEmergencyCallConnectionStateChanged(eq(TELECOM_CALL_ID1), anyInt());
 
@@ -3029,7 +3120,7 @@
 
         // state change not notified any more after CONNECTED once
         verify(mEmergencyStateTracker, times(1)).onEmergencyCallStateChanged(
-                any(), eq(TELECOM_CALL_ID1));
+                any(), eq(c));
         verify(mSatelliteSOSMessageRecommender, times(1))
                 .onEmergencyCallConnectionStateChanged(eq(TELECOM_CALL_ID1), anyInt());
 
@@ -3041,7 +3132,7 @@
 
          // domain change notified
         verify(mEmergencyStateTracker, times(1)).onEmergencyCallDomainUpdated(
-                eq(PhoneConstants.PHONE_TYPE_GSM), eq(TELECOM_CALL_ID1));
+                eq(PhoneConstants.PHONE_TYPE_GSM), eq(c));
 
         // state change to DISCONNECTED
         c.setDisconnected(null);
@@ -3051,7 +3142,7 @@
 
         // state change not notified
         verify(mEmergencyStateTracker, times(1)).onEmergencyCallStateChanged(
-                any(), eq(TELECOM_CALL_ID1));
+                any(), eq(c));
         verify(mSatelliteSOSMessageRecommender, times(1))
                 .onEmergencyCallConnectionStateChanged(eq(TELECOM_CALL_ID1), anyInt());
     }
@@ -3068,15 +3159,24 @@
                 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1,
                         TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1));
 
+        ArgumentCaptor<android.telecom.Connection> connectionCaptor =
+                ArgumentCaptor.forClass(android.telecom.Connection.class);
+
         verify(mDomainSelectionResolver)
                 .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
         verify(mEmergencyStateTracker)
-                .startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+                .startEmergencyCall(eq(mPhone0), connectionCaptor.capture(), eq(false));
         verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
         verify(mPhone0).dial(anyString(), any(), any());
 
+        android.telecom.Connection tc = connectionCaptor.getValue();
+
+        assertNotNull(tc);
+        assertEquals(TELECOM_CALL_ID1, tc.getTelecomCallId());
+        assertEquals(mTestConnectionService.getEmergencyConnection(), tc);
+
         TestTelephonyConnection c = new TestTelephonyConnection();
-        c.setTelecomCallId(TELECOM_CALL_ID1);
+        mTestConnectionService.setEmergencyConnection(c);
         c.setIsImsConnection(true);
         Connection orgConn = c.getOriginalConnection();
         doReturn(PhoneConstants.PHONE_TYPE_IMS).when(orgConn).getPhoneType();
@@ -3088,18 +3188,18 @@
         connectionListener.onConnectionPropertiesChanged(c, PROPERTY_WIFI);
 
         verify(mEmergencyStateTracker, times(0)).onEmergencyCallPropertiesChanged(
-                anyInt(), anyString());
+                anyInt(), any());
 
         doReturn(Call.State.ACTIVE).when(orgConn).getState();
         connectionListener.onConnectionPropertiesChanged(c, PROPERTY_WIFI);
 
         verify(mEmergencyStateTracker, times(1)).onEmergencyCallPropertiesChanged(
-                eq(PROPERTY_WIFI), eq(TELECOM_CALL_ID1));
+                eq(PROPERTY_WIFI), eq(c));
 
         connectionListener.onConnectionPropertiesChanged(c, 0);
 
         verify(mEmergencyStateTracker, times(1)).onEmergencyCallPropertiesChanged(
-                eq(0), eq(TELECOM_CALL_ID1));
+                eq(0), eq(c));
     }
 
     @Test
@@ -3208,6 +3308,7 @@
     public void testNormalCallSatelliteEnabled() {
         setupForCallTest();
         doReturn(true).when(mSatelliteController).isSatelliteEnabled();
+
         mConnection = mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1,
                 createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, "1234", TELECOM_CALL_ID1));
         DisconnectCause disconnectCause = mConnection.getDisconnectCause();
@@ -3268,6 +3369,30 @@
     }
 
     @Test
+    public void testNormalCallUsingNonTerrestrialNetwork_canMakeWifiCall() throws Exception {
+        mSetFlagsRule.enableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG);
+
+        setupForCallTest();
+        // Call is not supported while using satellite
+        NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder()
+                .setIsNonTerrestrialNetwork(true)
+                .setAvailableServices(List.of(NetworkRegistrationInfo.SERVICE_TYPE_DATA))
+                .build();
+        ServiceState ss = new ServiceState();
+        ss.addNetworkRegistrationInfo(nri);
+        when(mPhone0.getServiceState()).thenReturn(ss);
+        // Wi-Fi call is possible
+        doReturn(true).when(mImsPhone).canMakeWifiCall();
+        when(mPhone0.getImsPhone()).thenReturn(mImsPhone);
+
+        mConnection = mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1,
+                createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, "1234", TELECOM_CALL_ID1));
+        DisconnectCause disconnectCause = mConnection.getDisconnectCause();
+        assertNotEquals(android.telephony.DisconnectCause.SATELLITE_ENABLED,
+                disconnectCause.getTelephonyDisconnectCause());
+    }
+
+    @Test
     public void testIsAvailableForEmergencyCallsNotForCrossSim() {
         Phone mockPhone = Mockito.mock(Phone.class);
         when(mockPhone.getImsRegistrationTech()).thenReturn(
@@ -3528,6 +3653,7 @@
     private TestTelephonyConnection setupForReDialForDomainSelection(
             Phone mockPhone, int domain, int preciseDisconnectCause,
             int disconnectCause, boolean fromEmergency) throws Exception {
+        TestTelephonyConnection c = new TestTelephonyConnection();
         try {
             if (fromEmergency) {
                 doReturn(CompletableFuture.completedFuture(domain))
@@ -3536,8 +3662,8 @@
                 replaceInstance(TelephonyConnectionService.class,
                         "mEmergencyCallDomainSelectionConnection",
                         mTestConnectionService, mEmergencyCallDomainSelectionConnection);
-                replaceInstance(TelephonyConnectionService.class, "mEmergencyCallId",
-                        mTestConnectionService, TELECOM_CALL_ID1);
+                replaceInstance(TelephonyConnectionService.class, "mEmergencyConnection",
+                        mTestConnectionService, c);
             } else {
                 doReturn(CompletableFuture.completedFuture(domain))
                         .when(mNormalCallDomainSelectionConnection).reselectDomain(any());
@@ -3551,7 +3677,6 @@
 
         doReturn(true).when(mDomainSelectionResolver).isDomainSelectionSupported();
 
-        TestTelephonyConnection c = new TestTelephonyConnection();
         c.setTelecomCallId(TELECOM_CALL_ID1);
         c.setMockPhone(mockPhone);
         c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED);
diff --git a/tests/src/com/android/services/telephony/domainselection/DomainSelectorBaseTest.java b/tests/src/com/android/services/telephony/domainselection/DomainSelectorBaseTest.java
index 74c3311..872238c 100644
--- a/tests/src/com/android/services/telephony/domainselection/DomainSelectorBaseTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/DomainSelectorBaseTest.java
@@ -26,8 +26,8 @@
 import android.os.Looper;
 import android.telephony.DomainSelectionService.SelectionAttributes;
 import android.telephony.TransportSelectorCallback;
-import android.test.suitebuilder.annotation.SmallTest;
 
+import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.TestContext;
@@ -52,11 +52,6 @@
         }
 
         @Override
-        public void cancelSelection() {
-            // No operations.
-        }
-
-        @Override
         public void reselectDomain(@NonNull SelectionAttributes attr) {
             // No operations.
         }
diff --git a/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
index 6217a92..b8b3359 100644
--- a/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
@@ -42,6 +42,7 @@
 import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_MAXIMUM_CELLULAR_SEARCH_TIMER_SEC_INT;
 import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_MAXIMUM_NUMBER_OF_EMERGENCY_TRIES_OVER_VOWIFI_INT;
 import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_PREFER_IMS_EMERGENCY_WHEN_VOICE_CALLS_ON_CS_BOOL;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_SCAN_LIMITED_SERVICE_AFTER_VOLTE_FAILURE_BOOL;
 import static android.telephony.CarrierConfigManager.ImsEmergency.SCAN_TYPE_FULL_SERVICE;
 import static android.telephony.CarrierConfigManager.ImsEmergency.SCAN_TYPE_FULL_SERVICE_FOLLOWED_BY_LIMITED_SERVICE;
 import static android.telephony.CarrierConfigManager.ImsEmergency.SCAN_TYPE_NO_PREFERENCE;
@@ -53,9 +54,11 @@
 import static android.telephony.NetworkRegistrationInfo.DOMAIN_CS;
 import static android.telephony.NetworkRegistrationInfo.DOMAIN_PS;
 import static android.telephony.NetworkRegistrationInfo.REGISTRATION_STATE_HOME;
+import static android.telephony.NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING;
 import static android.telephony.NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN;
 import static android.telephony.PreciseDisconnectCause.SERVICE_OPTION_NOT_AVAILABLE;
 import static android.telephony.TelephonyManager.DATA_CONNECTED;
+import static android.telephony.TelephonyManager.SIM_ACTIVATION_STATE_DEACTIVATED;
 
 import static com.android.services.telephony.domainselection.EmergencyCallDomainSelector.MSG_MAX_CELLULAR_TIMEOUT;
 import static com.android.services.telephony.domainselection.EmergencyCallDomainSelector.MSG_NETWORK_SCAN_TIMEOUT;
@@ -83,6 +86,8 @@
 import android.content.res.Resources;
 import android.net.ConnectivityManager;
 import android.net.NetworkRequest;
+import android.net.Uri;
+import android.os.CancellationSignal;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IPowerManager;
@@ -90,6 +95,7 @@
 import android.os.Looper;
 import android.os.PersistableBundle;
 import android.os.PowerManager;
+import android.telecom.PhoneAccount;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.BarringInfo;
 import android.telephony.CarrierConfigManager;
@@ -97,37 +103,35 @@
 import android.telephony.DisconnectCause;
 import android.telephony.DomainSelectionService;
 import android.telephony.DomainSelectionService.SelectionAttributes;
-import android.telephony.EmergencyRegResult;
+import android.telephony.EmergencyRegistrationResult;
 import android.telephony.NetworkRegistrationInfo;
 import android.telephony.PreciseDisconnectCause;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.TransportSelectorCallback;
 import android.telephony.WwanSelectorCallback;
-import android.telephony.emergency.EmergencyNumber;
 import android.telephony.ims.ImsManager;
 import android.telephony.ims.ImsMmTelManager;
 import android.telephony.ims.ProvisioningManager;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.TestableLooper;
 import android.util.Log;
 import android.util.SparseArray;
 
+import androidx.test.filters.SmallTest;
+
 import com.android.TestContext;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
 import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 import java.util.function.Consumer;
 
 /**
@@ -138,7 +142,7 @@
 
     private static final int SLOT_0 = 0;
     private static final int SLOT_0_SUB_ID = 1;
-    private static final String TEST_EMERGENCY_NUMBER = "911";
+    private static final Uri TEST_URI = Uri.fromParts(PhoneAccount.SCHEME_TEL, "911", null);
 
     @Mock private CarrierConfigManager mCarrierConfigManager;
     @Mock private ConnectivityManager mConnectivityManager;
@@ -163,7 +167,7 @@
     private @AccessNetworkConstants.RadioAccessNetworkType List<Integer> mAccessNetwork;
     private PowerManager mPowerManager;
     private ConnectivityManager.NetworkCallback mNetworkCallback;
-    private Consumer<EmergencyRegResult> mResultConsumer;
+    private Consumer<EmergencyRegistrationResult> mResultConsumer;
 
     @Before
     public void setUp() throws Exception {
@@ -254,7 +258,6 @@
         doReturn(mProvisioningManager).when(imsManager).getProvisioningManager(anyInt());
         doReturn(null).when(mProvisioningManager).getProvisioningStringValue(anyInt());
 
-        when(mTransportSelectorCallback.onWwanSelected()).thenReturn(mWwanSelectorCallback);
         doAnswer(new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
@@ -269,11 +272,12 @@
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 mAccessNetwork = (List<Integer>) invocation.getArguments()[0];
-                mResultConsumer = (Consumer<EmergencyRegResult>) invocation.getArguments()[3];
+                mResultConsumer =
+                        (Consumer<EmergencyRegistrationResult>) invocation.getArguments()[4];
                 return null;
             }
         }).when(mWwanSelectorCallback).onRequestEmergencyNetworkScan(
-                any(), anyInt(), any(), any());
+                any(), anyInt(), anyBoolean(), any(), any());
 
         when(mResources.getStringArray(anyInt())).thenReturn(null);
     }
@@ -297,7 +301,7 @@
         createSelector(SLOT_0_SUB_ID);
 
         verify(mWwanSelectorCallback, times(0)).onRequestEmergencyNetworkScan(
-                any(), anyInt(), any(), any());
+                any(), anyInt(), anyBoolean(), any(), any());
         verify(mWwanSelectorCallback, times(0)).onDomainSelected(anyInt(), eq(true));
     }
 
@@ -305,7 +309,8 @@
     public void testDestroyed() throws Exception {
         createSelector(SLOT_0_SUB_ID);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(UTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(UTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -322,11 +327,51 @@
     }
 
     @Test
+    public void testDomainPreferenceConfigurationError() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        int[] domainPreference = new int[] {
+                CarrierConfigManager.ImsEmergency.DOMAIN_PS_NON_3GPP,
+                };
+        bundle.putIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY, domainPreference);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(bundle);
+
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(
+                UNKNOWN, REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyScanCsPreferred();
+    }
+
+    @Test
+    public void testNullEmergencyRegistrationResult() throws Exception {
+        doReturn(2).when(mTelephonyManager).getActiveModemCount();
+
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, null);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyScanPsPreferred();
+    }
+
+    @Test
     public void testNoRedundantDomainSelectionFromInitialState() throws Exception {
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -356,7 +401,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -377,7 +423,7 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(
                 UNKNOWN, REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
         mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
@@ -390,7 +436,7 @@
 
         verify(mTransportSelectorCallback, times(1)).onWwanSelected(any());
         verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
-                any(), anyInt(), any(), any());
+                any(), anyInt(), anyBoolean(), any(), any());
     }
 
     @Test
@@ -403,7 +449,7 @@
         doReturn(true).when(mCsrdCtrl).isThereOtherSlot();
         doReturn(new String[] {"jp"}).when(mResources).getStringArray(anyInt());
 
-        EmergencyRegResult regResult = getEmergencyRegResult(
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(
                 UNKNOWN, REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "", "", "jp");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
         mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
@@ -422,7 +468,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -439,7 +486,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -456,7 +504,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -479,7 +528,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -498,9 +548,10 @@
         //Extended service request failed
         SelectionAttributes.Builder builder =
                 new SelectionAttributes.Builder(SLOT_0, SLOT_0_SUB_ID, SELECTOR_TYPE_CALLING)
+                .setAddress(TEST_URI)
                 .setCsDisconnectCause(SERVICE_OPTION_NOT_AVAILABLE)
                 .setEmergency(true)
-                .setEmergencyRegResult(regResult);
+                .setEmergencyRegistrationResult(regResult);
         attr = builder.build();
         mDomainSelector.reselectDomain(attr);
         processAllMessages();
@@ -514,7 +565,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -533,7 +585,7 @@
         SelectionAttributes.Builder builder =
                 new SelectionAttributes.Builder(SLOT_0, SLOT_0_SUB_ID, SELECTOR_TYPE_CALLING)
                 .setEmergency(true)
-                .setEmergencyRegResult(regResult);
+                .setEmergencyRegistrationResult(regResult);
         attr = builder.build();
         mDomainSelector.reselectDomain(attr);
         processAllMessages();
@@ -542,11 +594,31 @@
     }
 
     @Test
+    public void testDefaultCombinedImsNotRegisteredDeactivatedSimSelectPs() throws Exception {
+        doReturn(SIM_ACTIVATION_STATE_DEACTIVATED).when(mTelephonyManager).getDataActivationState();
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
+                true, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyPsDialed();
+    }
+
+    @Test
     public void testDefaultCombinedImsNotRegisteredSelectCs() throws Exception {
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -563,14 +635,15 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = new SelectionAttributes.Builder(
                         SLOT_0, SLOT_0_SUB_ID, SELECTOR_TYPE_CALLING)
-                .setNumber(TEST_EMERGENCY_NUMBER)
+                .setAddress(TEST_URI)
                 .setEmergency(true)
-                .setEmergencyRegResult(regResult)
+                .setEmergencyRegistrationResult(regResult)
                 .setExitedFromAirplaneMode(true)
                 .build();
         mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
@@ -590,14 +663,15 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = new SelectionAttributes.Builder(
                         SLOT_0, SLOT_0_SUB_ID, SELECTOR_TYPE_CALLING)
-                .setNumber(TEST_EMERGENCY_NUMBER)
+                .setAddress(TEST_URI)
                 .setEmergency(true)
-                .setEmergencyRegResult(regResult)
+                .setEmergencyRegistrationResult(regResult)
                 .setExitedFromAirplaneMode(true)
                 .build();
         mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
@@ -618,7 +692,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -635,7 +710,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -652,7 +728,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
                 true, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -669,7 +746,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
                 true, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -686,7 +764,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
                 true, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -703,7 +782,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
                 true, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -720,7 +800,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
                 false, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -737,7 +818,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
                 false, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -754,7 +836,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
                 false, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -771,7 +854,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
                 false, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -788,7 +872,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
                 false, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -805,7 +890,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
                 false, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -822,7 +908,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
                 false, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -839,7 +926,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
                 false, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -856,7 +944,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(UTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(UTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -869,11 +958,96 @@
     }
 
     @Test
+    public void testNotSupportPsEmergency() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        int[] domainPreference = new int[] {
+                CarrierConfigManager.ImsEmergency.DOMAIN_CS
+                };
+        bundle.putIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY, domainPreference);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(bundle);
+
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(UTRAN,
+                REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_CS,
+                false, false, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyCsDialed();
+
+        mDomainSelector.reselectDomain(attr);
+        processAllMessages();
+
+        verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
+                any(), anyInt(), anyBoolean(), any(), any());
+        assertEquals(2, mAccessNetwork.size());
+        assertEquals(UTRAN, (int) mAccessNetwork.get(0));
+        assertEquals(GERAN, (int) mAccessNetwork.get(1));
+    }
+
+    @Test
+    public void testNotSupportPsCombinedImsRegisteredSelectCs() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        int[] domainPreference = new int[] {
+                CarrierConfigManager.ImsEmergency.DOMAIN_CS
+                };
+        bundle.putIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY, domainPreference);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(bundle);
+
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
+                true, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsService();
+
+        verifyCsDialed();
+    }
+
+    @Test
+    public void testNotSupportCsCombinedImsNotRegisteredSelectPs() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        int[] domainPreference = new int[] {
+                CarrierConfigManager.ImsEmergency.DOMAIN_PS_3GPP
+                };
+        bundle.putIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY, domainPreference);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(bundle);
+
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
+                true, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyPsDialed();
+    }
+
+    @Test
     public void testDefaultEpsImsRegisteredBarredScanPsPreferred() throws Exception {
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_PS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -890,7 +1064,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_PS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -907,7 +1082,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_PS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -924,7 +1100,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_PS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -941,7 +1118,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_PS,
                 true, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -958,7 +1136,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_PS,
                 true, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -975,7 +1154,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_PS,
                 true, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -992,7 +1172,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_PS,
                 true, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -1009,7 +1190,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_PS,
                 false, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -1026,7 +1208,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_PS,
                 false, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -1043,7 +1226,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_PS,
                 false, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -1060,7 +1244,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_PS,
                 false, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -1077,7 +1262,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_PS,
                 false, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -1094,7 +1280,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_PS,
                 false, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -1111,7 +1298,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_PS,
                 false, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -1128,7 +1316,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_PS,
                 false, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -1145,7 +1334,7 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(
                 UNKNOWN, REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
         mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
@@ -1165,7 +1354,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_PS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -1190,7 +1380,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_PS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -1212,7 +1403,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_PS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -1225,6 +1417,53 @@
     }
 
     @Test
+    public void testRequiresRegEpsImsNotRegisteredDeactivatedSimSelectPs() throws Exception {
+        doReturn(SIM_ACTIVATION_STATE_DEACTIVATED).when(mTelephonyManager).getDataActivationState();
+
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        bundle.putBoolean(KEY_EMERGENCY_REQUIRES_IMS_REGISTRATION_BOOL, true);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(bundle);
+
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                true, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyPsDialed();
+    }
+
+    @Test
+    public void testRequiresRegEpsImsNotRegisteredEmcNotSupportedScanCsPreferred()
+            throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        bundle.putBoolean(KEY_EMERGENCY_REQUIRES_IMS_REGISTRATION_BOOL, true);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(bundle);
+
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                true, false, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyScanCsPreferred();
+    }
+
+    @Test
     public void testDefaultEpsImsRegisteredBarredScanTimeoutWifi() throws Exception {
         PersistableBundle bundle = getDefaultPersistableBundle();
         bundle.putBoolean(KEY_EMERGENCY_CALL_OVER_EMERGENCY_PDN_BOOL, true);
@@ -1234,7 +1473,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_PS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -1276,7 +1516,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_PS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -1300,7 +1541,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_PS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -1339,7 +1581,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_PS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -1372,7 +1615,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_PS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -1405,7 +1649,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_PS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -1443,7 +1688,8 @@
         doReturn(true).when(mCsrdCtrl).isThereOtherSlot();
         doReturn(new String[] {"jp"}).when(mResources).getStringArray(anyInt());
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_UNKNOWN,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_UNKNOWN,
                 0, false, false, 0, 0, "", "", "jp");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
         mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
@@ -1466,7 +1712,8 @@
         doReturn(true).when(mCsrdCtrl).isThereOtherSlot();
         doReturn(new String[] {"jp"}).when(mResources).getStringArray(anyInt());
 
-        EmergencyRegResult regResult = getEmergencyRegResult(UNKNOWN, REGISTRATION_STATE_UNKNOWN,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(UNKNOWN,
+                REGISTRATION_STATE_UNKNOWN,
                 0, false, false, 0, 0, "", "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
         mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
@@ -1496,7 +1743,8 @@
         doReturn(false).when(mCsrdCtrl).isThereOtherSlot();
         doReturn(new String[] {"jp"}).when(mResources).getStringArray(anyInt());
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_UNKNOWN,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_UNKNOWN,
                 0, false, false, 0, 0, "", "", "jp");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
         mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
@@ -1511,10 +1759,33 @@
     }
 
     @Test
+    public void testDualSimNormalServiceOnTheOtherSubscription() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+        doReturn(2).when(mTelephonyManager).getActiveModemCount();
+        doReturn(true).when(mCsrdCtrl).isThereOtherSlotInService();
+        doReturn(new String[] {"in"}).when(mResources).getStringArray(anyInt());
+
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_UNKNOWN,
+                0, false, false, 0, 0, "", "", "in");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+        processAllMessages();
+
+        verify(mTransportSelectorCallback, times(1))
+                .onSelectionTerminated(eq(DisconnectCause.EMERGENCY_TEMP_FAILURE));
+    }
+
+    @Test
     public void testEutranWithCsDomainOnly() throws Exception {
         setupForHandleScanResult();
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 DOMAIN_CS, false, false, 0, 0, "", "");
         mResultConsumer.accept(regResult);
         processAllMessages();
@@ -1526,7 +1797,8 @@
     public void testEutranWithPsDomainOnly() throws Exception {
         setupForHandleScanResult();
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
                 DOMAIN_PS, false, false, 0, 0, "", "");
         mResultConsumer.accept(regResult);
         processAllMessages();
@@ -1538,7 +1810,8 @@
     public void testUtran() throws Exception {
         setupForHandleScanResult();
 
-        EmergencyRegResult regResult = getEmergencyRegResult(UTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(UTRAN,
+                REGISTRATION_STATE_HOME,
                 DOMAIN_CS, false, false, 0, 0, "", "");
         mResultConsumer.accept(regResult);
         processAllMessages();
@@ -1556,7 +1829,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(UNKNOWN, REGISTRATION_STATE_UNKNOWN,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(UNKNOWN,
+                REGISTRATION_STATE_UNKNOWN,
                 0, false, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
         mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
@@ -1566,18 +1840,42 @@
         processAllMessages();
 
         verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
-                any(), eq(DomainSelectionService.SCAN_TYPE_FULL_SERVICE), any(), any());
+                any(), eq(DomainSelectionService.SCAN_TYPE_FULL_SERVICE), eq(false), any(), any());
         assertNotNull(mResultConsumer);
 
         mResultConsumer.accept(regResult);
         processAllMessages();
 
         verify(mWwanSelectorCallback, times(2)).onRequestEmergencyNetworkScan(
-                any(), eq(DomainSelectionService.SCAN_TYPE_FULL_SERVICE), any(), any());
+                any(), eq(DomainSelectionService.SCAN_TYPE_FULL_SERVICE), eq(false), any(), any());
     }
 
     @Test
-    public void testFullServiceThenLimtedService() throws Exception {
+    public void testFullServiceInRoaming() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        bundle.putInt(KEY_EMERGENCY_NETWORK_SCAN_TYPE_INT, SCAN_TYPE_FULL_SERVICE);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(bundle);
+
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(true);
+
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_ROAMING,
+                0, true, false, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+        processAllMessages();
+
+        verify(mWwanSelectorCallback).onRequestEmergencyNetworkScan(
+                any(), eq(DomainSelectionService.SCAN_TYPE_NO_PREFERENCE),
+                anyBoolean(), any(), any());
+    }
+
+    @Test
+    public void testFullServiceThenLimitedService() throws Exception {
         PersistableBundle bundle = getDefaultPersistableBundle();
         bundle.putInt(KEY_EMERGENCY_NETWORK_SCAN_TYPE_INT,
                 SCAN_TYPE_FULL_SERVICE_FOLLOWED_BY_LIMITED_SERVICE);
@@ -1587,7 +1885,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(UNKNOWN, REGISTRATION_STATE_UNKNOWN,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(UNKNOWN,
+                REGISTRATION_STATE_UNKNOWN,
                 0, false, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
         mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
@@ -1597,14 +1896,15 @@
         processAllMessages();
 
         verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
-                any(), eq(DomainSelectionService.SCAN_TYPE_FULL_SERVICE), any(), any());
+                any(), eq(DomainSelectionService.SCAN_TYPE_FULL_SERVICE), eq(false), any(), any());
         assertNotNull(mResultConsumer);
 
         mResultConsumer.accept(regResult);
         processAllMessages();
 
         verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
-                any(), eq(DomainSelectionService.SCAN_TYPE_LIMITED_SERVICE), any(), any());
+                any(), eq(DomainSelectionService.SCAN_TYPE_LIMITED_SERVICE),
+                eq(false), any(), any());
     }
 
     @Test
@@ -1856,12 +2156,43 @@
     }
 
     @Test
+    public void testScanLimitedOnlyAfterVoLteFailure() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        bundle.putBoolean(KEY_SCAN_LIMITED_SERVICE_AFTER_VOLTE_FAILURE_BOOL,
+                true);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(bundle);
+
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                true, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsService();
+        processAllMessages();
+
+        verify(mWwanSelectorCallback).onDomainSelected(eq(DOMAIN_PS), anyBoolean());
+
+        mDomainSelector.reselectDomain(attr);
+        processAllMessages();
+
+        verify(mWwanSelectorCallback).onRequestEmergencyNetworkScan(
+                any(), eq(DomainSelectionService.SCAN_TYPE_LIMITED_SERVICE),
+                anyBoolean(), any(), any());
+    }
+
+    @Test
     public void testStartCrossStackTimer() throws Exception {
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
         doReturn(2).when(mTelephonyManager).getActiveModemCount();
 
-        EmergencyRegResult regResult = getEmergencyRegResult(
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(
                 UNKNOWN, REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
         mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
@@ -1875,16 +2206,6 @@
     }
 
     @Test
-    public void testStopCrossStackTimerOnCancel() throws Exception {
-        createSelector(SLOT_0_SUB_ID);
-        unsolBarringInfoChanged(false);
-
-        mDomainSelector.cancelSelection();
-
-        verify(mCsrdCtrl).stopTimer();
-    }
-
-    @Test
     public void testStopCrossStackTimerOnFinish() throws Exception {
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
@@ -1899,7 +2220,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(UTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(UTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -1911,8 +2233,9 @@
         verifyCsDialed();
 
         attr = new SelectionAttributes.Builder(SLOT_0, SLOT_0_SUB_ID, SELECTOR_TYPE_CALLING)
+                .setAddress(TEST_URI)
                 .setEmergency(true)
-                .setEmergencyRegResult(regResult)
+                .setEmergencyRegistrationResult(regResult)
                 .setCsDisconnectCause(PreciseDisconnectCause.EMERGENCY_TEMP_FAILURE)
                 .build();
 
@@ -1927,7 +2250,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(UTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(UTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -1939,8 +2263,9 @@
         verifyCsDialed();
 
         attr = new SelectionAttributes.Builder(SLOT_0, SLOT_0_SUB_ID, SELECTOR_TYPE_CALLING)
+                .setAddress(TEST_URI)
                 .setEmergency(true)
-                .setEmergencyRegResult(regResult)
+                .setEmergencyRegistrationResult(regResult)
                 .setCsDisconnectCause(PreciseDisconnectCause.EMERGENCY_PERM_FAILURE)
                 .build();
 
@@ -1955,20 +2280,31 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(
                 UNKNOWN, REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
         mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
         processAllMessages();
 
         bindImsServiceUnregistered();
+        processAllMessages();
 
-        verifyScanPsPreferred();
+        ArgumentCaptor<CancellationSignal> cancelCaptor =
+                ArgumentCaptor.forClass(CancellationSignal.class);
+
+        verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
+                any(), eq(DomainSelectionService.SCAN_TYPE_NO_PREFERENCE),
+                anyBoolean(), cancelCaptor.capture(), any());
+        assertEquals(EUTRAN, (int) mAccessNetwork.get(0));
 
         mDomainSelector.notifyCrossStackTimerExpired();
 
         verify(mTransportSelectorCallback)
                 .onSelectionTerminated(eq(DisconnectCause.EMERGENCY_TEMP_FAILURE));
+
+        CancellationSignal cancelSignal = cancelCaptor.getValue();
+        assertNotNull(cancelSignal);
+        assertFalse(cancelSignal.isCanceled());
     }
 
     @Test
@@ -1976,7 +2312,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(UTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(UTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -2025,6 +2362,28 @@
     }
 
     @Test
+    public void testMaxCellularTimeoutWifiNotAvailable() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        bundle.putBoolean(KEY_EMERGENCY_CALL_OVER_EMERGENCY_PDN_BOOL, true);
+        bundle.putInt(KEY_MAXIMUM_CELLULAR_SEARCH_TIMER_SEC_INT, 20);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(bundle);
+
+        setupForHandleScanResult();
+
+        assertTrue(mDomainSelector.hasMessages(MSG_NETWORK_SCAN_TIMEOUT));
+        assertTrue(mDomainSelector.hasMessages(MSG_MAX_CELLULAR_TIMEOUT));
+
+        verify(mTransportSelectorCallback, never()).onWlanSelected(anyBoolean());
+
+        // Max cellular timer expired
+        mDomainSelector.removeMessages(MSG_MAX_CELLULAR_TIMEOUT);
+        mDomainSelector.handleMessage(mDomainSelector.obtainMessage(MSG_MAX_CELLULAR_TIMEOUT));
+
+        assertTrue(mDomainSelector.hasMessages(MSG_NETWORK_SCAN_TIMEOUT));
+        verify(mTransportSelectorCallback, never()).onWlanSelected(anyBoolean());
+    }
+
+    @Test
     public void testSimLockNoMaxCellularTimeout() throws Exception {
         when(mTelephonyManager.getSimState(anyInt())).thenReturn(
                 TelephonyManager.SIM_STATE_PIN_REQUIRED);
@@ -2074,7 +2433,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(UTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(UTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -2091,6 +2451,8 @@
         mDomainSelector.reselectDomain(attr);
         processAllMessages();
 
+        verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
+                any(), anyInt(), anyBoolean(), any(), any());
         assertTrue(mDomainSelector.hasMessages(MSG_NETWORK_SCAN_TIMEOUT));
         assertTrue(mDomainSelector.hasMessages(MSG_MAX_CELLULAR_TIMEOUT));
 
@@ -2111,7 +2473,86 @@
         mDomainSelector.reselectDomain(attr);
         processAllMessages();
 
+        verify(mWwanSelectorCallback, times(2)).onRequestEmergencyNetworkScan(
+                any(), anyInt(), anyBoolean(), any(), any());
+    }
+
+    @Test
+    public void testMaxCellularTimeoutWhileDialingOnCellularWhileDialing() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        bundle.putBoolean(KEY_EMERGENCY_CALL_OVER_EMERGENCY_PDN_BOOL, true);
+        bundle.putInt(KEY_MAXIMUM_CELLULAR_SEARCH_TIMER_SEC_INT, 5);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(bundle);
+
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(UTRAN,
+                REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_CS,
+                true, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyCsDialed();
+
+        assertFalse(mDomainSelector.hasMessages(MSG_NETWORK_SCAN_TIMEOUT));
         assertFalse(mDomainSelector.hasMessages(MSG_MAX_CELLULAR_TIMEOUT));
+
+        mResultConsumer = null;
+        mDomainSelector.reselectDomain(attr);
+        processAllMessages();
+
+        verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
+                any(), anyInt(), anyBoolean(), any(), any());
+        assertTrue(mDomainSelector.hasMessages(MSG_NETWORK_SCAN_TIMEOUT));
+        assertTrue(mDomainSelector.hasMessages(MSG_MAX_CELLULAR_TIMEOUT));
+
+        assertNotNull(mResultConsumer);
+
+        // Scan result received and redialing on cellular
+        mResultConsumer.accept(regResult);
+        processAllMessages();
+
+        // Wi-Fi is connected.
+        mNetworkCallback.onAvailable(null);
+        processAllMessages();
+
+        verify(mTransportSelectorCallback, times(0)).onWlanSelected(anyBoolean());
+
+        // Max cellular timer expired
+        mDomainSelector.removeMessages(MSG_MAX_CELLULAR_TIMEOUT);
+        mDomainSelector.handleMessage(mDomainSelector.obtainMessage(MSG_MAX_CELLULAR_TIMEOUT));
+        processAllMessages();
+
+        assertFalse(mDomainSelector.hasMessages(MSG_MAX_CELLULAR_TIMEOUT));
+
+        // Waiting for reselectDomain since there is a dialing on going.
+        verify(mTransportSelectorCallback, times(0)).onWlanSelected(anyBoolean());
+
+        // Wi-Fi is disconnected.
+        mNetworkCallback.onUnavailable();
+        processAllMessages();
+
+        mResultConsumer = null;
+        mDomainSelector.reselectDomain(attr);
+        processAllMessages();
+
+        verify(mTransportSelectorCallback, times(0)).onWlanSelected(anyBoolean());
+        verify(mWwanSelectorCallback, times(2)).onRequestEmergencyNetworkScan(
+                any(), anyInt(), anyBoolean(), any(), any());
+
+        // Wi-Fi is re-connected.
+        mNetworkCallback.onAvailable(null);
+        processAllMessages();
+
+        mResultConsumer = null;
+        mDomainSelector.reselectDomain(attr);
+        processAllMessages();
+
         verify(mTransportSelectorCallback, times(1)).onWlanSelected(anyBoolean());
     }
 
@@ -2165,7 +2606,8 @@
         verify(mTransportSelectorCallback, times(1)).onWlanSelected(anyBoolean());
         assertFalse(mDomainSelector.hasMessages(MSG_MAX_CELLULAR_TIMEOUT));
 
-        EmergencyRegResult regResult = getEmergencyRegResult(UTRAN, REGISTRATION_STATE_HOME,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(UTRAN,
+                REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.DOMAIN_CS,
                 true, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
@@ -2192,7 +2634,7 @@
         when(mTelephonyManager.getSimState(anyInt())).thenReturn(
                 TelephonyManager.SIM_STATE_PIN_REQUIRED);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(
                 UNKNOWN, REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
         mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
@@ -2202,7 +2644,7 @@
         processAllMessages();
 
         verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
-                any(), anyInt(), any(), any());
+                any(), anyInt(), anyBoolean(), any(), any());
         assertEquals(4, mAccessNetwork.size());
         assertEquals(EUTRAN, (int) mAccessNetwork.get(0));
         assertEquals(NGRAN, (int) mAccessNetwork.get(1));
@@ -2218,7 +2660,7 @@
         when(mTelephonyManager.getSimState(anyInt())).thenReturn(
                 TelephonyManager.SIM_STATE_PIN_REQUIRED);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(
                 UNKNOWN, REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
         mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
@@ -2228,7 +2670,7 @@
         processAllMessages();
 
         verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
-                any(), anyInt(), any(), any());
+                any(), anyInt(), anyBoolean(), any(), any());
         assertEquals(4, mAccessNetwork.size());
         assertEquals(EUTRAN, (int) mAccessNetwork.get(0));
         assertEquals(UTRAN, (int) mAccessNetwork.get(1));
@@ -2241,7 +2683,7 @@
         createSelector(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(
                 UNKNOWN, REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0,
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID, regResult);
@@ -2252,7 +2694,7 @@
         processAllMessages();
 
         verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
-                any(), anyInt(), any(), any());
+                any(), anyInt(), anyBoolean(), any(), any());
         assertEquals(4, mAccessNetwork.size());
         assertEquals(EUTRAN, (int) mAccessNetwork.get(0));
         assertEquals(UTRAN, (int) mAccessNetwork.get(1));
@@ -2268,7 +2710,7 @@
         // The last valid subscription supported NR.
         doReturn(true).when(mCarrierConfigHelper).isVoNrEmergencySupported(eq(SLOT_0));
 
-        EmergencyRegResult regResult = getEmergencyRegResult(
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(
                 UNKNOWN, REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0,
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID, regResult);
@@ -2279,7 +2721,7 @@
         processAllMessages();
 
         verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
-                any(), anyInt(), any(), any());
+                any(), anyInt(), anyBoolean(), any(), any());
         assertEquals(4, mAccessNetwork.size());
         assertEquals(EUTRAN, (int) mAccessNetwork.get(0));
         assertEquals(NGRAN, (int) mAccessNetwork.get(1));
@@ -2292,7 +2734,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_UNKNOWN,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_UNKNOWN,
                 0, false, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
         mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
@@ -2304,11 +2747,45 @@
     }
 
     @Test
+    public void testScanLtePreferredAfterNgranFailure() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        bundle.putIntArray(KEY_EMERGENCY_OVER_IMS_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY,
+                new int[] { NGRAN, EUTRAN });
+        bundle.putBoolean(KEY_EMERGENCY_LTE_PREFERRED_AFTER_NR_FAILED_BOOL, true);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(bundle);
+
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(NGRAN,
+                REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS, true, false, 1, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyPsDialed();
+
+        mDomainSelector.reselectDomain(attr);
+        processAllMessages();
+
+        verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
+                any(), anyInt(), anyBoolean(), any(), any());
+        assertEquals(3, mAccessNetwork.size());
+        assertEquals(EUTRAN, (int) mAccessNetwork.get(0));
+        assertEquals(UTRAN, (int) mAccessNetwork.get(1));
+        assertEquals(GERAN, (int) mAccessNetwork.get(2));
+    }
+
+    @Test
     public void testDefaultLimitedServiceNgran() throws Exception {
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(NGRAN, REGISTRATION_STATE_UNKNOWN,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(NGRAN,
+                REGISTRATION_STATE_UNKNOWN,
                 0, false, true, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
         mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
@@ -2321,87 +2798,57 @@
 
     @Test
     public void testTestEmergencyNumberOverCs() throws Exception {
-        EmergencyNumber num = new EmergencyNumber(TEST_EMERGENCY_NUMBER, "us", "",
-                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE, new ArrayList<String>(),
-                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
-                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
-
-        Map<Integer, List<EmergencyNumber>> lists = new HashMap<>();
-        List<EmergencyNumber> list = new ArrayList<>();
-        list.add(num);
-        lists.put(SLOT_0_SUB_ID, list);
-
-        doReturn(lists).when(mTelephonyManager).getEmergencyNumberList();
-
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_UNKNOWN,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(UTRAN,
+                REGISTRATION_STATE_UNKNOWN,
                 0, false, true, 0, 0, "", "");
-        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID,
+                true /*isTestEmergencyNumber*/, regResult);
         mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
         processAllMessages();
 
-        bindImsServiceUnregistered();
+        bindImsService();
 
         verifyCsDialed();
     }
 
     @Test
     public void testTestEmergencyNumberOverPs() throws Exception {
-        EmergencyNumber num = new EmergencyNumber(TEST_EMERGENCY_NUMBER, "us", "",
-                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE, new ArrayList<String>(),
-                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
-                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
-
-        Map<Integer, List<EmergencyNumber>> lists = new HashMap<>();
-        List<EmergencyNumber> list = new ArrayList<>();
-        list.add(num);
-        lists.put(SLOT_0_SUB_ID, list);
-
-        doReturn(lists).when(mTelephonyManager).getEmergencyNumberList();
-
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_UNKNOWN,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_UNKNOWN,
                 0, false, true, 0, 0, "", "");
-        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID,
+                true /*isTestEmergencyNumber*/, regResult);
         mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
         processAllMessages();
 
-        bindImsService();
+        bindImsServiceUnregistered();
 
         verifyPsDialed();
     }
 
     @Test
-    public void testTestEmergencyNumberOverWifi() throws Exception {
-        EmergencyNumber num = new EmergencyNumber(TEST_EMERGENCY_NUMBER, "us", "",
-                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE, new ArrayList<String>(),
-                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
-                EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
-
-        Map<Integer, List<EmergencyNumber>> lists = new HashMap<>();
-        List<EmergencyNumber> list = new ArrayList<>();
-        list.add(num);
-        lists.put(SLOT_0_SUB_ID, list);
-
-        doReturn(lists).when(mTelephonyManager).getEmergencyNumberList();
-
+    public void testTestEmergencyNumberScanRequest() throws Exception {
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_UNKNOWN,
-                0, false, true, 0, 0, "", "");
-        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(UNKNOWN,
+                REGISTRATION_STATE_UNKNOWN,
+                0, false, false, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID,
+                true /*isTestEmergencyNumber*/, regResult);
         mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
         processAllMessages();
 
         bindImsService(true);
         processAllMessages();
 
-        verify(mTransportSelectorCallback, times(1)).onWlanSelected(anyBoolean());
+        verifyScanPsPreferred();
     }
 
     @Test
@@ -2409,7 +2856,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(UTRAN, REGISTRATION_STATE_UNKNOWN,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(UTRAN,
+                REGISTRATION_STATE_UNKNOWN,
                 0, false, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
         mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
@@ -2429,7 +2877,8 @@
         doReturn(TRANSPORT_TYPE_WWAN).when(mEcbmHelper).getTransportType(anyInt());
         doReturn(DATA_CONNECTED).when(mEcbmHelper).getDataConnectionState(anyInt());
 
-        EmergencyRegResult regResult = getEmergencyRegResult(UNKNOWN, REGISTRATION_STATE_UNKNOWN,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(UNKNOWN,
+                REGISTRATION_STATE_UNKNOWN,
                 0, false, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
         mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
@@ -2451,7 +2900,8 @@
         doReturn(TRANSPORT_TYPE_WLAN).when(mEcbmHelper).getTransportType(anyInt());
         doReturn(DATA_CONNECTED).when(mEcbmHelper).getDataConnectionState(anyInt());
 
-        EmergencyRegResult regResult = getEmergencyRegResult(UNKNOWN, REGISTRATION_STATE_UNKNOWN,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(UNKNOWN,
+                REGISTRATION_STATE_UNKNOWN,
                 0, false, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
         mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
@@ -2472,7 +2922,8 @@
         doReturn(true).when(mEcbmHelper).isInEmergencyCallbackMode(anyInt());
         doReturn(TRANSPORT_TYPE_WLAN).when(mEcbmHelper).getTransportType(anyInt());
 
-        EmergencyRegResult regResult = getEmergencyRegResult(UNKNOWN, REGISTRATION_STATE_UNKNOWN,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(UNKNOWN,
+                REGISTRATION_STATE_UNKNOWN,
                 0, false, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
         mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
@@ -2494,7 +2945,8 @@
         doReturn(TRANSPORT_TYPE_WLAN).when(mEcbmHelper).getTransportType(anyInt());
         doReturn(DATA_CONNECTED).when(mEcbmHelper).getDataConnectionState(anyInt());
 
-        EmergencyRegResult regResult = getEmergencyRegResult(UNKNOWN, REGISTRATION_STATE_UNKNOWN,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(UNKNOWN,
+                REGISTRATION_STATE_UNKNOWN,
                 0, false, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
         mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
@@ -2516,7 +2968,8 @@
 
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_UNKNOWN,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_UNKNOWN,
                 0, false, false, 0, 0, "", "");
         if (psFailed) {
             regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
@@ -2563,7 +3016,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(true);
 
-        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_UNKNOWN,
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(EUTRAN,
+                REGISTRATION_STATE_UNKNOWN,
                 0, false, false, 0, 0, "", "");
         SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
         mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
@@ -2573,7 +3027,7 @@
         processAllMessages();
 
         verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
-                any(), anyInt(), any(), any());
+                any(), anyInt(), anyBoolean(), any(), any());
         assertNotNull(mResultConsumer);
     }
 
@@ -2607,7 +3061,7 @@
     private void verifyScanPreferred(int scanType, int expectedPreferredAccessNetwork) {
         processAllMessages();
         verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
-                any(), eq(scanType), any(), any());
+                any(), eq(scanType), anyBoolean(), any(), any());
         assertEquals(expectedPreferredAccessNetwork, (int) mAccessNetwork.get(0));
     }
 
@@ -2639,7 +3093,7 @@
         mDomainSelector.onImsMmTelCapabilitiesChanged();
     }
 
-    private static EmergencyRegResult getEmergencyRegResult(
+    private static EmergencyRegistrationResult getEmergencyRegResult(
             @AccessNetworkConstants.RadioAccessNetworkType int accessNetwork,
             @NetworkRegistrationInfo.RegistrationState int regState,
             @NetworkRegistrationInfo.Domain int domain,
@@ -2649,13 +3103,13 @@
                 isEmcBearerSupported, emc, emf, mcc, mnc, "");
     }
 
-    private static EmergencyRegResult getEmergencyRegResult(
+    private static EmergencyRegistrationResult getEmergencyRegResult(
             @AccessNetworkConstants.RadioAccessNetworkType int accessNetwork,
             @NetworkRegistrationInfo.RegistrationState int regState,
             @NetworkRegistrationInfo.Domain int domain,
             boolean isVopsSupported, boolean isEmcBearerSupported, int emc, int emf,
             @NonNull String mcc, @NonNull String mnc, @NonNull String iso) {
-        return new EmergencyRegResult(accessNetwork, regState,
+        return new EmergencyRegistrationResult(accessNetwork, regState,
                 domain, isVopsSupported, isEmcBearerSupported,
                 emc, emf, mcc, mnc, iso);
     }
@@ -2749,13 +3203,19 @@
         return bundle;
     }
 
-    public static SelectionAttributes getSelectionAttributes(int slotId, int subId,
-            EmergencyRegResult regResult) {
+    private static SelectionAttributes getSelectionAttributes(int slotId, int subId,
+            EmergencyRegistrationResult regResult) {
+        return getSelectionAttributes(slotId, subId, false, regResult);
+    }
+
+    private static SelectionAttributes getSelectionAttributes(int slotId, int subId,
+            boolean isTestEmergencyNumber, EmergencyRegistrationResult regResult) {
         SelectionAttributes.Builder builder =
                 new SelectionAttributes.Builder(slotId, subId, SELECTOR_TYPE_CALLING)
-                .setNumber(TEST_EMERGENCY_NUMBER)
+                .setAddress(TEST_URI)
                 .setEmergency(true)
-                .setEmergencyRegResult(regResult);
+                .setTestEmergencyNumber(isTestEmergencyNumber)
+                .setEmergencyRegistrationResult(regResult);
         return builder.build();
     }
 
diff --git a/tests/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelectorTest.java
index ed064cb..a900fda 100644
--- a/tests/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelectorTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelectorTest.java
@@ -22,6 +22,7 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
@@ -39,16 +40,17 @@
 import android.telephony.CarrierConfigManager;
 import android.telephony.DataSpecificRegistrationInfo;
 import android.telephony.DomainSelectionService.SelectionAttributes;
+import android.telephony.EmergencyRegistrationResult;
 import android.telephony.NetworkRegistrationInfo;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
 import android.telephony.TransportSelectorCallback;
 import android.telephony.VopsSupportInfo;
 import android.telephony.WwanSelectorCallback;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.TestableLooper;
 import android.util.SparseArray;
 
+import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.TestContext;
@@ -92,6 +94,7 @@
     private ImsStateTracker.BarringInfoListener mBarringInfoListener;
     private ImsStateTracker.ServiceStateListener mServiceStateListener;
     private EmergencySmsDomainSelector mDomainSelector;
+    private EmergencyRegistrationResult mEmergencyRegistrationResult;
 
     @Before
     public void setUp() throws Exception {
@@ -151,6 +154,7 @@
             mLooper = null;
         }
 
+        mEmergencyRegistrationResult = null;
         mDomainSelector = null;
         mNetworkRegistrationInfo = null;
         mVopsSupportInfo = null;
@@ -246,6 +250,26 @@
 
     @Test
     @SmallTest
+    public void testIsSmsOverImsAvailableWhenImsRegisteredAndConfigEnabledAndNrAvailable() {
+        setUpImsStateTracker(AccessNetworkType.NGRAN);
+        setUpCarrierConfig(true);
+        setUpNrInService(false, false, true, false);
+
+        assertTrue(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenImsRegisteredAndConfigEnabledAndNrNotAvailable() {
+        setUpImsStateTracker(AccessNetworkType.NGRAN);
+        setUpCarrierConfig(true);
+        setUpNrInService(false, false, false, false);
+
+        assertFalse(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
     public void testIsSmsOverImsAvailableWhenCarrierConfigManagerIsNull() {
         setUpImsStateTracker(AccessNetworkType.UNKNOWN);
         mCarrierConfigManagerNullTest = true;
@@ -291,7 +315,7 @@
 
     @Test
     @SmallTest
-    public void testIsSmsOverImsAvailableWhenNoLte() {
+    public void testIsSmsOverImsAvailableWhenNoLteOrNr() {
         setUpImsStateTracker(AccessNetworkType.UNKNOWN);
         setUpCarrierConfig(true);
         mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
@@ -395,6 +419,56 @@
 
     @Test
     @SmallTest
+    public void testIsSmsOverImsAvailableWhenNrNotRegisteredOrEmergencyNotEnabled() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpCarrierConfig(true);
+        setUpNrInService(false, false, false, false);
+
+        assertFalse(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenNrInServiceAndNoDataSpecificRegistrationInfo() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpCarrierConfig(true);
+        setUpNrInService(true, true, false, false);
+
+        assertFalse(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenNrInServiceAndNoVopsSupportInfo() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpCarrierConfig(true);
+        setUpNrInService(false, true, false, false);
+
+        assertFalse(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenNrInServiceAndEmergencyServiceSupported() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpCarrierConfig(true);
+        setUpNrInService(false, false, true, false);
+
+        assertTrue(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenNrInServiceAndEmergencyServiceFallbackSupported() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpCarrierConfig(true);
+        setUpNrInService(false, false, false, true);
+
+        assertTrue(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
     public void testSelectDomainWhilePreviousRequestInProgress() {
         setUpImsStateTracker(AccessNetworkType.EUTRAN);
         setUpWwanSelectorCallback();
@@ -675,6 +749,116 @@
                 eq(true));
     }
 
+    @Test
+    @SmallTest
+    public void testSelectDomainWhileEmergencyNetworkScanInProgress() {
+        setUpImsStateTracker(AccessNetworkType.NGRAN);
+        setUpEmergencyRegResult(AccessNetworkType.NGRAN, NetworkRegistrationInfo.DOMAIN_PS, 1, 0);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpNrInService(false, false, false, true);
+        setUpImsStateListener(true, true, true);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        // Call the domain selection before completing the emergency network scan.
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // onRequestEmergencyNetworkScan is invoked only once.
+        verify(mWwanSelectorCallback).onRequestEmergencyNetworkScan(any(), anyInt(),
+                anyBoolean(), any(), any());
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenNrEmergencyServiceSupported() {
+        setUpImsStateTracker(AccessNetworkType.NGRAN);
+        setUpEmergencyRegResult(AccessNetworkType.NGRAN, NetworkRegistrationInfo.DOMAIN_PS, 1, 0);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpNrInService(false, false, true, false);
+        setUpImsStateListener(true, true, true);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // Expected: PS network
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS),
+                eq(true));
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenEmergencyRegistrationResultNgranAndPsDomain() {
+        setUpImsStateTracker(AccessNetworkType.NGRAN);
+        setUpEmergencyRegResult(AccessNetworkType.NGRAN, NetworkRegistrationInfo.DOMAIN_PS, 1, 0);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpNrInService(false, false, false, true);
+        setUpImsStateListener(true, true, true);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // Expected: PS network
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS),
+                eq(true));
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenEmergencyRegistrationResultEutranAndPsDomain() {
+        setUpImsStateTracker(AccessNetworkType.NGRAN);
+        setUpEmergencyRegResult(AccessNetworkType.EUTRAN, NetworkRegistrationInfo.DOMAIN_PS, 0, 0);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpNrInService(false, false, false, true);
+        setUpImsStateListener(true, true, true);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // Expected: PS network
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS),
+                eq(true));
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenEmergencyRegistrationResultEutranAndCsDomain() {
+        setUpImsStateTracker(AccessNetworkType.NGRAN);
+        setUpEmergencyRegResult(AccessNetworkType.EUTRAN, NetworkRegistrationInfo.DOMAIN_CS, 0, 0);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpNrInService(false, false, false, true);
+        setUpImsStateListener(true, true, true);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // Expected: CS network
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS),
+                eq(false));
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenEmergencyRegistrationResultUtranAndCsDomain() {
+        setUpImsStateTracker(AccessNetworkType.NGRAN);
+        setUpEmergencyRegResult(AccessNetworkType.UTRAN, NetworkRegistrationInfo.DOMAIN_CS, 0, 0);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpNrInService(false, false, false, true);
+        setUpImsStateListener(true, true, true);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // Expected: CS network
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS),
+                eq(false));
+    }
+
     private void setUpCarrierConfig(boolean supported) {
         PersistableBundle b = new PersistableBundle();
         b.putBoolean(CarrierConfigManager.KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL, supported);
@@ -760,6 +944,29 @@
         mBarringInfoListener.onBarringInfoUpdated(barringInfo);
     }
 
+    private void setUpNrInService(boolean noDataSpecificRegistrationInfo,
+            boolean noVopsSupportInfo, boolean emergencyServiceSupported,
+            boolean emergencyServiceFallbackSupported) {
+        DataSpecificRegistrationInfo dsri = noDataSpecificRegistrationInfo
+                ? null : new DataSpecificRegistrationInfo(
+                        8, false, false, false, noVopsSupportInfo ? null : mVopsSupportInfo);
+
+        mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
+                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_NR)
+                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
+                .setDataSpecificInfo(dsri)
+                .build();
+        when(mServiceState.getNetworkRegistrationInfo(
+                anyInt(), eq(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)))
+                .thenReturn(mNetworkRegistrationInfo);
+        when(mVopsSupportInfo.isEmergencyServiceSupported()).thenReturn(emergencyServiceSupported);
+        when(mVopsSupportInfo.isEmergencyServiceFallbackSupported())
+                .thenReturn(emergencyServiceFallbackSupported);
+
+        mServiceStateListener.onServiceStateUpdated(mServiceState);
+        mBarringInfoListener.onBarringInfoUpdated(null);
+    }
+
     private void setUpImsStateTracker(@RadioAccessNetworkType int accessNetworkType) {
         setUpImsStateTracker(accessNetworkType, true, true);
     }
@@ -783,6 +990,23 @@
             callback.accept(mWwanSelectorCallback);
             return null;
         }).when(mTransportSelectorCallback).onWwanSelected(any(Consumer.class));
+
+        doAnswer((invocation) -> {
+            Object[] args = invocation.getArguments();
+            final Consumer<EmergencyRegistrationResult> result =
+                    (Consumer<EmergencyRegistrationResult>) args[4];
+            result.accept(mEmergencyRegistrationResult);
+            return null;
+        }).when(mWwanSelectorCallback).onRequestEmergencyNetworkScan(
+                any(), anyInt(), anyBoolean(), any(), any());
+    }
+
+    private void setUpEmergencyRegResult(
+            @AccessNetworkConstants.RadioAccessNetworkType int accessNetwork,
+            @NetworkRegistrationInfo.Domain int domain, int nrEs, int nrEsfb) {
+        mEmergencyRegistrationResult = new EmergencyRegistrationResult(accessNetwork,
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME,
+                domain, true, true, nrEs, nrEsfb, "001", "01", "");
     }
 
     private void setUpImsStateListener(boolean notifyMmTelFeatureAvailable,
diff --git a/tests/src/com/android/services/telephony/domainselection/ImsStateTrackerTest.java b/tests/src/com/android/services/telephony/domainselection/ImsStateTrackerTest.java
index 6519835..f9a56a8 100644
--- a/tests/src/com/android/services/telephony/domainselection/ImsStateTrackerTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/ImsStateTrackerTest.java
@@ -47,8 +47,8 @@
 import android.telephony.ims.RegistrationManager;
 import android.telephony.ims.feature.MmTelFeature.MmTelCapabilities;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
-import android.test.suitebuilder.annotation.SmallTest;
 
+import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.TestContext;
diff --git a/tests/src/com/android/services/telephony/domainselection/NormalCallDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/NormalCallDomainSelectorTest.java
index 002c7d5..6e438bf 100644
--- a/tests/src/com/android/services/telephony/domainselection/NormalCallDomainSelectorTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/NormalCallDomainSelectorTest.java
@@ -17,7 +17,6 @@
 package com.android.services.telephony.domainselection;
 
 import static android.telephony.DomainSelectionService.SELECTOR_TYPE_CALLING;
-import static android.telephony.DomainSelectionService.SELECTOR_TYPE_UT;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
@@ -28,17 +27,19 @@
 
 import android.annotation.NonNull;
 import android.content.Context;
+import android.net.Uri;
 import android.os.CancellationSignal;
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.PersistableBundle;
+import android.telecom.PhoneAccount;
 import android.telecom.TelecomManager;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.CarrierConfigManager;
 import android.telephony.DisconnectCause;
 import android.telephony.DomainSelectionService;
 import android.telephony.DomainSelector;
-import android.telephony.EmergencyRegResult;
+import android.telephony.EmergencyRegistrationResult;
 import android.telephony.NetworkRegistrationInfo;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
@@ -69,10 +70,12 @@
 public class NormalCallDomainSelectorTest {
     private static final String TAG = "NormalCallDomainSelectorTest";
 
+    private static final int SELECTOR_TYPE_UT = 3;
     private static final int SLOT_ID = 0;
     private static final int SUB_ID_1 = 1;
     private static final int SUB_ID_2 = 2;
     private static final String TEST_CALLID = "01234";
+    private static final Uri TEST_URI = Uri.fromParts(PhoneAccount.SCHEME_TEL, "123456789", null);
 
     private HandlerThread mHandlerThread;
     private NormalCallDomainSelector mNormalCallDomainSelector;
@@ -150,13 +153,54 @@
     }
 
     @Test
-    public void testSelectDomainInputParams() {
+    public void testInitialState() {
+        assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                NormalCallDomainSelector.SelectorState.INACTIVE);
+    }
+
+    @Test
+    public void testDestroyedState() {
+        mNormalCallDomainSelector.destroy();
+
+        assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                NormalCallDomainSelector.SelectorState.DESTROYED);
+    }
+
+    @Test
+    public void testDestroyedDuringActiveState() {
         MockTransportSelectorCallback transportSelectorCallback =
-                new MockTransportSelectorCallback();
+                new MockTransportSelectorCallback(mNormalCallDomainSelector);
 
         DomainSelectionService.SelectionAttributes attributes =
                 new DomainSelectionService.SelectionAttributes.Builder(
                         SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING)
+                        .setAddress(TEST_URI)
+                        .setCallId(TEST_CALLID)
+                        .setEmergency(false)
+                        .setVideoCall(true)
+                        .setExitedFromAirplaneMode(false)
+                        .build();
+
+        mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
+
+        assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                NormalCallDomainSelector.SelectorState.ACTIVE);
+
+        mNormalCallDomainSelector.destroy();
+
+        assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                NormalCallDomainSelector.SelectorState.DESTROYED);
+    }
+
+    @Test
+    public void testSelectDomainInputParams() {
+        MockTransportSelectorCallback transportSelectorCallback =
+                new MockTransportSelectorCallback(mNormalCallDomainSelector);
+
+        DomainSelectionService.SelectionAttributes attributes =
+                new DomainSelectionService.SelectionAttributes.Builder(
+                        SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING)
+                        .setAddress(TEST_URI)
                         .setCallId(TEST_CALLID)
                         .setEmergency(false)
                         .setVideoCall(true)
@@ -164,6 +208,8 @@
                         .build();
         mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
 
+        assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                NormalCallDomainSelector.SelectorState.ACTIVE);
 
         // Case 1: null inputs
         try {
@@ -172,6 +218,9 @@
             fail("Invalid input params not handled." + e.getMessage());
         }
 
+        assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                NormalCallDomainSelector.SelectorState.INACTIVE);
+
         // Case 2: null TransportSelectorCallback
         try {
             mNormalCallDomainSelector.selectDomain(attributes, null);
@@ -179,6 +228,9 @@
             fail("Invalid params (SelectionAttributes) not handled." + e.getMessage());
         }
 
+        assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                NormalCallDomainSelector.SelectorState.INACTIVE);
+
         // Case 3: null SelectionAttributes
         transportSelectorCallback.mSelectionTerminated = false;
         try {
@@ -190,9 +242,13 @@
         assertTrue(transportSelectorCallback
                 .verifyOnSelectionTerminated(DisconnectCause.OUTGOING_FAILURE));
 
+        assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                NormalCallDomainSelector.SelectorState.DESTROYED);
+
         // Case 4: Invalid Subscription-id
         attributes = new DomainSelectionService.SelectionAttributes.Builder(
                 SLOT_ID, SubscriptionManager.INVALID_SUBSCRIPTION_ID, SELECTOR_TYPE_CALLING)
+                .setAddress(TEST_URI)
                 .setCallId(TEST_CALLID)
                 .setEmergency(false)
                 .setVideoCall(true)
@@ -207,10 +263,14 @@
         assertTrue(transportSelectorCallback
                 .verifyOnSelectionTerminated(DisconnectCause.OUTGOING_FAILURE));
 
+        assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                NormalCallDomainSelector.SelectorState.DESTROYED);
+
         // Case 5: Invalid SELECTOR_TYPE
         attributes =
                 new DomainSelectionService.SelectionAttributes.Builder(
                         SLOT_ID, SUB_ID_1, SELECTOR_TYPE_UT)
+                        .setAddress(TEST_URI)
                         .setCallId(TEST_CALLID)
                         .setEmergency(false)
                         .setVideoCall(true)
@@ -225,9 +285,13 @@
         assertTrue(transportSelectorCallback
                 .verifyOnSelectionTerminated(DisconnectCause.OUTGOING_FAILURE));
 
+        assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                NormalCallDomainSelector.SelectorState.DESTROYED);
+
         // Case 6: Emergency Call
         attributes = new DomainSelectionService.SelectionAttributes.Builder(
                 SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING)
+                .setAddress(TEST_URI)
                 .setCallId(TEST_CALLID)
                 .setEmergency(true)
                 .setVideoCall(true)
@@ -239,6 +303,9 @@
             fail("Invalid params (SelectionAttributes) not handled." + e.getMessage());
         }
 
+        assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                NormalCallDomainSelector.SelectorState.DESTROYED);
+
         assertTrue(transportSelectorCallback
                 .verifyOnSelectionTerminated(DisconnectCause.OUTGOING_FAILURE));
     }
@@ -246,30 +313,38 @@
     @Test
     public void testOutOfService() {
         MockTransportSelectorCallback transportSelectorCallback =
-                new MockTransportSelectorCallback();
+                new MockTransportSelectorCallback(mNormalCallDomainSelector);
         DomainSelectionService.SelectionAttributes attributes =
                 new DomainSelectionService.SelectionAttributes.Builder(
                         SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING)
+                        .setAddress(TEST_URI)
                         .setCallId(TEST_CALLID)
                         .setEmergency(false)
                         .setVideoCall(true)
                         .setExitedFromAirplaneMode(false)
                         .build();
+
         ServiceState serviceState = new ServiceState();
         serviceState.setStateOutOfService();
         initialize(serviceState, false, false, false, false);
+
         mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
+
         assertTrue(transportSelectorCallback
                 .verifyOnSelectionTerminated(DisconnectCause.OUT_OF_SERVICE));
+
+        assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                NormalCallDomainSelector.SelectorState.DESTROYED);
     }
 
     @Test
     public void testDomainSelection() {
         MockTransportSelectorCallback transportSelectorCallback =
-                new MockTransportSelectorCallback();
+                new MockTransportSelectorCallback(mNormalCallDomainSelector);
         DomainSelectionService.SelectionAttributes attributes =
                 new DomainSelectionService.SelectionAttributes.Builder(
                         SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING)
+                        .setAddress(TEST_URI)
                         .setCallId(TEST_CALLID)
                         .setEmergency(false)
                         .setVideoCall(false)
@@ -280,32 +355,49 @@
         ServiceState serviceState = new ServiceState();
         serviceState.setState(ServiceState.STATE_IN_SERVICE);
         initialize(serviceState, true, true, true, true);
+
         mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
+
         assertTrue(transportSelectorCallback.verifyOnWlanSelected());
 
+        assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                NormalCallDomainSelector.SelectorState.INACTIVE);
+
         // Case 2: 5G
         mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
+
         initialize(serviceState, true, false, true, true);
         mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
+
         assertTrue(transportSelectorCallback.verifyOnWwanSelected());
+
         assertTrue(transportSelectorCallback
                 .verifyOnDomainSelected(NetworkRegistrationInfo.DOMAIN_PS));
 
+        assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                NormalCallDomainSelector.SelectorState.INACTIVE);
+
         // Case 3: PS -> CS redial
         ImsReasonInfo imsReasonInfo = new ImsReasonInfo();
         imsReasonInfo.mCode = ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED;
         attributes = new DomainSelectionService.SelectionAttributes.Builder(
                 SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING)
+                .setAddress(TEST_URI)
                 .setCallId(TEST_CALLID)
                 .setEmergency(false)
                 .setVideoCall(false)
                 .setExitedFromAirplaneMode(false)
                 .setPsDisconnectCause(imsReasonInfo)
                 .build();
+
         mNormalCallDomainSelector.reselectDomain(attributes);
+
         assertTrue(transportSelectorCallback
                 .verifyOnDomainSelected(NetworkRegistrationInfo.DOMAIN_CS));
 
+        assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                NormalCallDomainSelector.SelectorState.INACTIVE);
+
         // Case 4: CS call
         NetworkRegistrationInfo nwRegistrationInfo = new NetworkRegistrationInfo(
                 NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
@@ -313,28 +405,40 @@
                 AccessNetworkConstants.AccessNetworkType.UTRAN, 0, false,
                 null, null, null, false, 0, 0, 0);
         serviceState.addNetworkRegistrationInfo(nwRegistrationInfo);
+
         mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
+
         initialize(serviceState, false, false, false, false);
         mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
+
         assertTrue(transportSelectorCallback.verifyOnWwanSelected());
+
         assertTrue(transportSelectorCallback
                 .verifyOnDomainSelected(NetworkRegistrationInfo.DOMAIN_CS));
 
+        assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                NormalCallDomainSelector.SelectorState.INACTIVE);
+
         //Case 5: Backup calling
         serviceState.setStateOutOfService();
         initialize(serviceState, true, true, true, true);
+
         mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
+
         assertTrue(transportSelectorCallback.verifyOnWlanSelected());
+
+        assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                NormalCallDomainSelector.SelectorState.ACTIVE);
     }
 
     @Test
     public void testWPSCallDomainSelection() {
         MockTransportSelectorCallback transportSelectorCallback =
-                new MockTransportSelectorCallback();
+                new MockTransportSelectorCallback(mNormalCallDomainSelector);
         DomainSelectionService.SelectionAttributes attributes =
                 new DomainSelectionService.SelectionAttributes.Builder(
                         SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING)
-                        .setNumber("*272121")
+                        .setAddress(Uri.fromParts(PhoneAccount.SCHEME_TEL, "*272121", null))
                         .setCallId(TEST_CALLID)
                         .setEmergency(false)
                         .setVideoCall(false)
@@ -346,38 +450,57 @@
         config.putBoolean(CarrierConfigManager.KEY_SUPPORT_WPS_OVER_IMS_BOOL, false);
         doReturn(config).when(mMockCarrierConfigMgr).getConfigForSubId(SUB_ID_1,
                 new String[]{CarrierConfigManager.KEY_SUPPORT_WPS_OVER_IMS_BOOL});
+
         ServiceState serviceState = new ServiceState();
         serviceState.setState(ServiceState.STATE_IN_SERVICE);
         initialize(serviceState, true, true, true, true);
+
         mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
+
         assertTrue(transportSelectorCallback.verifyOnWwanSelected());
+
         assertTrue(transportSelectorCallback
                 .verifyOnDomainSelected(NetworkRegistrationInfo.DOMAIN_CS));
 
+        assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                NormalCallDomainSelector.SelectorState.INACTIVE);
+
         //Case 2: WPS supported by IMS and WLAN registered
         config.putBoolean(CarrierConfigManager.KEY_SUPPORT_WPS_OVER_IMS_BOOL, true);
         serviceState.setState(ServiceState.STATE_IN_SERVICE);
         initialize(serviceState, true, true, true, true);
+
         mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
+
         assertTrue(transportSelectorCallback.verifyOnWlanSelected());
 
+        assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                NormalCallDomainSelector.SelectorState.INACTIVE);
+
         //Case 2: WPS supported by IMS and LTE registered
         config.putBoolean(CarrierConfigManager.KEY_SUPPORT_WPS_OVER_IMS_BOOL, true);
         serviceState.setState(ServiceState.STATE_IN_SERVICE);
         initialize(serviceState, true, false, true, true);
+
         mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
+
         assertTrue(transportSelectorCallback.verifyOnWwanSelected());
+
         assertTrue(transportSelectorCallback
                 .verifyOnDomainSelected(NetworkRegistrationInfo.DOMAIN_PS));
+
+        assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                NormalCallDomainSelector.SelectorState.INACTIVE);
     }
 
     @Test
     public void testTtyCallDomainSelection() {
         MockTransportSelectorCallback transportSelectorCallback =
-                new MockTransportSelectorCallback();
+                new MockTransportSelectorCallback(mNormalCallDomainSelector);
         DomainSelectionService.SelectionAttributes attributes =
                 new DomainSelectionService.SelectionAttributes.Builder(
                         SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING)
+                        .setAddress(TEST_URI)
                         .setCallId(TEST_CALLID)
                         .setEmergency(false)
                         .setVideoCall(false)
@@ -390,29 +513,48 @@
         config.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL, false);
         doReturn(config).when(mMockCarrierConfigMgr).getConfigForSubId(SUB_ID_1,
                 new String[]{CarrierConfigManager.KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL});
+
         ServiceState serviceState = new ServiceState();
         serviceState.setState(ServiceState.STATE_IN_SERVICE);
         initialize(serviceState, true, false, true, true);
+
         mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
+
         assertTrue(transportSelectorCallback.verifyOnWwanSelected());
+
         assertTrue(transportSelectorCallback
                 .verifyOnDomainSelected(NetworkRegistrationInfo.DOMAIN_CS));
 
+        assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                NormalCallDomainSelector.SelectorState.INACTIVE);
+
         //Case 2: TTY supported by IMS and TTY enabled
         config.putBoolean(CarrierConfigManager.KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL, true);
         mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
+
         assertTrue(transportSelectorCallback.verifyOnWwanSelected());
+
         assertTrue(transportSelectorCallback
                 .verifyOnDomainSelected(NetworkRegistrationInfo.DOMAIN_PS));
 
+        assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                NormalCallDomainSelector.SelectorState.INACTIVE);
+
         //Case 3: TTY supported by IMS and TTY disabled
         doReturn(TelecomManager.TTY_MODE_OFF).when(mMockTelecomManager).getCurrentTtyMode();
         mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
+
         assertTrue(transportSelectorCallback.verifyOnWwanSelected());
+
         assertTrue(transportSelectorCallback
                 .verifyOnDomainSelected(NetworkRegistrationInfo.DOMAIN_PS));
+
+        assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                NormalCallDomainSelector.SelectorState.INACTIVE);
     }
 
+
+
     static class MockTransportSelectorCallback implements TransportSelectorCallback,
             WwanSelectorCallback {
         public boolean mCreated;
@@ -422,11 +564,20 @@
         public boolean mDomainSelected;
         int mCauseCode;
         int mSelectedDomain;
+        NormalCallDomainSelector mNormalCallDomainSelector;
+
+        MockTransportSelectorCallback(NormalCallDomainSelector normalCallDomainSelector) {
+            mNormalCallDomainSelector = normalCallDomainSelector;
+        }
 
         @Override
         public synchronized void onCreated(DomainSelector selector) {
             Log.d(TAG, "onCreated");
             mCreated = true;
+
+            assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                    NormalCallDomainSelector.SelectorState.INACTIVE);
+
             notifyAll();
         }
 
@@ -441,6 +592,10 @@
         public synchronized void onWlanSelected(boolean useEmergencyPdn) {
             Log.d(TAG, "onWlanSelected");
             mWlanSelected = true;
+
+            assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                    NormalCallDomainSelector.SelectorState.INACTIVE);
+
             notifyAll();
         }
 
@@ -451,18 +606,14 @@
         }
 
         @Override
-        public synchronized WwanSelectorCallback onWwanSelected() {
-            mWwanSelected = true;
-            notifyAll();
-            return (WwanSelectorCallback) this;
-        }
-
-        @Override
         public void onWwanSelected(final Consumer<WwanSelectorCallback> consumer) {
             mWwanSelected = true;
             Executors.newSingleThreadExecutor().execute(() -> {
                 consumer.accept(this);
             });
+
+            assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                    NormalCallDomainSelector.SelectorState.INACTIVE);
         }
 
         public boolean verifyOnWwanSelected() {
@@ -475,6 +626,10 @@
             Log.i(TAG, "onSelectionTerminated - called");
             mCauseCode = cause;
             mSelectionTerminated = true;
+
+            assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                    NormalCallDomainSelector.SelectorState.INACTIVE);
+
             notifyAll();
         }
 
@@ -499,9 +654,10 @@
 
         @Override
         public void onRequestEmergencyNetworkScan(@NonNull List<Integer> preferredNetworks,
-                                                  int scanType,
-                                                  @NonNull CancellationSignal signal,
-                                                  @NonNull Consumer<EmergencyRegResult> consumer) {
+                int scanType,
+                boolean resetScan,
+                @NonNull CancellationSignal signal,
+                @NonNull Consumer<EmergencyRegistrationResult> consumer) {
             Log.i(TAG, "onRequestEmergencyNetworkScan - called");
 
         }
@@ -511,6 +667,10 @@
             Log.i(TAG, "onDomainSelected - called");
             mSelectedDomain = domain;
             mDomainSelected = true;
+
+            assertEquals(mNormalCallDomainSelector.getSelectorState(),
+                    NormalCallDomainSelector.SelectorState.INACTIVE);
+
             notifyAll();
         }
 
diff --git a/tests/src/com/android/services/telephony/domainselection/OWNERS b/tests/src/com/android/services/telephony/domainselection/OWNERS
index b9112be..2a76770 100644
--- a/tests/src/com/android/services/telephony/domainselection/OWNERS
+++ b/tests/src/com/android/services/telephony/domainselection/OWNERS
@@ -6,3 +6,4 @@
 mkoon@google.com
 seheele@google.com
 radhikaagrawal@google.com
+jdyou@google.com
diff --git a/tests/src/com/android/services/telephony/domainselection/SmsDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/SmsDomainSelectorTest.java
index 8f78a58..fc577c4 100644
--- a/tests/src/com/android/services/telephony/domainselection/SmsDomainSelectorTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/SmsDomainSelectorTest.java
@@ -37,9 +37,9 @@
 import android.telephony.NetworkRegistrationInfo;
 import android.telephony.TransportSelectorCallback;
 import android.telephony.WwanSelectorCallback;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.TestableLooper;
 
+import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.TestContext;
@@ -190,21 +190,6 @@
 
     @Test
     @SmallTest
-    public void testCancelSelection() {
-        setUpImsStateTracker(AccessNetworkType.EUTRAN);
-
-        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
-
-        assertTrue(mDomainSelector.isDomainSelectionRequested());
-
-        mDomainSelector.cancelSelection();
-
-        assertFalse(mDomainSelector.isDomainSelectionRequested());
-        verify(mDomainSelectorDestroyListener).onDomainSelectorDestroyed(eq(mDomainSelector));
-    }
-
-    @Test
-    @SmallTest
     public void testFinishSelection() {
         setUpImsStateTracker(AccessNetworkType.EUTRAN);
 
diff --git a/tests/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionServiceTest.java b/tests/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionServiceTest.java
index d9c737e..e0f7ffb 100644
--- a/tests/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionServiceTest.java
@@ -40,9 +40,9 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
 import android.telephony.TransportSelectorCallback;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.TestableLooper;
 
+import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.TestContext;
@@ -86,8 +86,7 @@
                         @NonNull EmergencyCallbackModeHelper ecbmHelper) {
                     switch (selectorType) {
                         case DomainSelectionService.SELECTOR_TYPE_CALLING: // fallthrough
-                        case DomainSelectionService.SELECTOR_TYPE_SMS: // fallthrough
-                        case DomainSelectionService.SELECTOR_TYPE_UT:
+                        case DomainSelectionService.SELECTOR_TYPE_SMS:
                             mDomainSelectorDestroyListener = listener;
                             if (subId == SUB_1) {
                                 return mDomainSelectorBase1;