Merge "Replace callId with Connection instance" into main
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index b2548f1..9f4922a 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -172,6 +172,9 @@
     <!-- 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"/>
+
     <application android:name="PhoneApp"
             android:persistent="true"
             android:label="@string/phoneAppLabel"
@@ -575,6 +578,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/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/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 30621ff..e53a674 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -12876,26 +12876,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
@@ -13787,6 +13787,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
@@ -13837,7 +13893,7 @@
      * @hide
      */
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
-    public void setEnableNullCipherNotifications(boolean enable) {
+    public void setNullCipherNotificationsEnabled(boolean enable) {
         enforceModifyPermission();
         checkForNullCipherNotificationSupport();
 
diff --git a/src/com/android/phone/TelephonyShellCommand.java b/src/com/android/phone/TelephonyShellCommand.java
index f7a3640d..3e3d31d 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;
@@ -202,6 +203,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 +387,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:
@@ -456,6 +463,7 @@
         onHelpRadio();
         onHelpImei();
         onHelpSatellite();
+        onHelpDomainSelection();
     }
 
     private void onHelpD2D() {
@@ -843,6 +851,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) {
@@ -3744,6 +3761,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..c846c43
--- /dev/null
+++ b/src/com/android/phone/security/SafetySourceReceiver.java
@@ -0,0 +1,44 @@
+/*
+ * 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 com.android.phone.PhoneGlobals;
+
+public final class SafetySourceReceiver extends BroadcastReceiver {
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        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;
+        }
+
+        PhoneGlobals.getPhone().refreshSafetySources(refreshBroadcastId);
+    }
+}
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 7a259e5..9344c21 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -1105,6 +1105,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))
@@ -1212,8 +1213,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(
@@ -2387,7 +2389,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();
@@ -2436,7 +2438,7 @@
                 }
                 if (result == android.telephony.DisconnectCause.NOT_DISCONNECTED) {
                     createEmergencyConnection(phone, (TelephonyConnection) resultConnection,
-                            numberToDial, request, needToTurnOnRadio,
+                            numberToDial, isTestEmergencyNumber, request, needToTurnOnRadio,
                             mEmergencyStateTracker.getEmergencyRegResult());
                 } else {
                     mEmergencyConnection = null;
@@ -2458,6 +2460,7 @@
     @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) {
         Log.i(this, "createEmergencyConnection");
@@ -2499,7 +2502,8 @@
         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(
@@ -2606,7 +2610,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);
@@ -2873,7 +2877,7 @@
                                 phone.getPhoneId(),
                                 phone.getSubId(), false,
                                 c.getTelecomCallId(),
-                                c.getAddress().getSchemeSpecificPart(),
+                                c.getAddress().getSchemeSpecificPart(), isTestEmergencyNumber,
                                 0, null, mEmergencyStateTracker.getEmergencyRegResult());
 
                 CompletableFuture<Integer> domainFuture =
diff --git a/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java b/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
index 074fa64..dfbadfc 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;
@@ -79,11 +80,9 @@
 import android.telephony.DomainSelectionService.SelectionAttributes;
 import android.telephony.EmergencyRegResult;
 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;
 
 /**
@@ -160,7 +157,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 +179,7 @@
     private boolean mRequiresImsRegistration;
     private boolean mRequiresVoLteEnabled;
     private boolean mLtePreferredAfterNrFailure;
+    private boolean mScanLimitedOnlyAfterVolteFailure;
 
     // Members for states
     private boolean mIsMonitoringConnectivity;
@@ -286,7 +283,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 +298,7 @@
         removeMessages(MSG_NETWORK_SCAN_TIMEOUT);
         onWwanNetworkTypeSelected(getAccessNetworkType(result));
         mCancelSignal = null;
+        maybeModifyScanType(mLastNetworkType);
     }
 
     /**
@@ -327,12 +325,6 @@
     }
 
     @Override
-    public void cancelSelection() {
-        logi("cancelSelection");
-        finishSelection();
-    }
-
-    @Override
     public void reselectDomain(SelectionAttributes attr) {
         logi("reselectDomain attr=" + attr);
         mSelectionAttributes = attr;
@@ -345,7 +337,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 +350,6 @@
             return;
         }
 
-        if (mIsTestEmergencyNumber) {
-            selectDomainForTestEmergencyNumber();
-            return;
-        }
-
         if (mTryCsWhenPsFails) {
             mTryCsWhenPsFails = false;
             // Initial state was CSFB available and dial PS failed.
@@ -438,7 +424,6 @@
         logi("selectDomain attr=" + attr);
         mTransportSelectorCallback = cb;
         mSelectionAttributes = attr;
-        mIsTestEmergencyNumber = isTestEmergencyNumber(attr.getNumber());
 
         TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
         mModemCount = tm.getActiveModemCount();
@@ -525,6 +510,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 +547,7 @@
                 + ", requiresImsReg=" + mRequiresImsRegistration
                 + ", requiresVoLteEnabled=" + mRequiresVoLteEnabled
                 + ", ltePreferredAfterNr=" + mLtePreferredAfterNrFailure
+                + ", scanLimitedOnly=" + mScanLimitedOnlyAfterVolteFailure
                 + ", cdmaPreferredNumbers=" + arrayToString(numbers));
 
         mCdmaPreferredNumbers = Arrays.asList(numbers);
@@ -648,11 +636,6 @@
     }
 
     private void selectDomainFromInitialState() {
-        if (mIsTestEmergencyNumber) {
-            selectDomainForTestEmergencyNumber();
-            return;
-        }
-
         boolean csInService = isCsInService();
         boolean psInService = isPsInService();
 
@@ -669,6 +652,7 @@
             } else {
                 requestScan(true);
             }
+            maybeModifyScanType(mLastNetworkType);
             return;
         }
 
@@ -723,6 +707,7 @@
                 requestScan(true);
             }
         }
+        maybeModifyScanType(mLastNetworkType);
     }
 
     /**
@@ -763,14 +748,15 @@
         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));
@@ -976,6 +962,10 @@
      * @return The network type of the CS network.
      */
     private @RadioAccessNetworkType int getSelectableCsNetworkType() {
+        List<Integer> domains = getDomainPreference();
+        if (domains.indexOf(DOMAIN_CS) == NOT_SUPPORTED) {
+            return UNKNOWN;
+        }
         EmergencyRegResult regResult = mSelectionAttributes.getEmergencyRegResult();
         logi("getSelectableCsNetworkType regResult=" + regResult);
         if (regResult == null) return UNKNOWN;
@@ -1022,6 +1012,10 @@
      * @return The network type if the network supports emergency services over PS network.
      */
     private @RadioAccessNetworkType int getSelectablePsNetworkType(boolean inService) {
+        List<Integer> domains = getDomainPreference();
+        if (domains.indexOf(DOMAIN_PS_3GPP) == NOT_SUPPORTED) {
+            return UNKNOWN;
+        }
         EmergencyRegResult regResult = mSelectionAttributes.getEmergencyRegResult();
         logi("getSelectablePsNetworkType regResult=" + regResult);
         if (regResult == null) return UNKNOWN;
@@ -1188,7 +1182,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));
@@ -1224,7 +1219,7 @@
             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;
         }
 
@@ -1380,7 +1375,7 @@
             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());
@@ -1436,8 +1431,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 +1448,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 +1564,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..5adca5a 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.EmergencyRegResult;
 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((EmergencyRegResult) 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(EmergencyRegResult 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..ede2af4 100644
--- a/src/com/android/services/telephony/domainselection/NormalCallDomainSelector.java
+++ b/src/com/android/services/telephony/domainselection/NormalCallDomainSelector.java
@@ -42,8 +42,13 @@
 
     private static final String LOG_TAG = "NCDS";
 
-    private boolean mStopDomainSelection = true;
-    private boolean mDestroyed = false;
+    private enum SelectorState {
+        ACTIVE,
+        INACTIVE,
+        DESTROYED
+    };
+
+    private SelectorState mSelectorState = SelectorState.INACTIVE;
     private ServiceState mServiceState;
     private boolean mImsRegStateReceived;
     private boolean mMmTelCapabilitiesReceived;
@@ -67,7 +72,7 @@
     public void selectDomain(SelectionAttributes attributes, TransportSelectorCallback callback) {
         mSelectionAttributes = attributes;
         mTransportSelectorCallback = callback;
-        mStopDomainSelection = false;
+        mSelectorState = SelectorState.ACTIVE;
 
         if (callback == null) {
             loge("Invalid params: TransportSelectorCallback is null");
@@ -80,7 +85,7 @@
             return;
         }
 
-        int subId = attributes.getSubId();
+        int subId = attributes.getSubscriptionId();
         boolean validSubscriptionId = SubscriptionManager.isValidSubscriptionId(subId);
         if (attributes.getSelectorType() != SELECTOR_TYPE_CALLING || attributes.isEmergency()
                 || !validSubscriptionId) {
@@ -112,31 +117,33 @@
     @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;
+        if (mSelectorState == SelectorState.INACTIVE) {
+            mSelectorState = SelectorState.DESTROYED;
             super.destroy();
         }
     }
 
-    /**
-     * 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 +182,7 @@
 
     private void notifyPsSelected() {
         logd("notifyPsSelected");
-        mStopDomainSelection = true;
+        mSelectorState = SelectorState.INACTIVE;
         if (mImsStateTracker.isImsRegisteredOverWlan()) {
             logd("WLAN selected");
             mTransportSelectorCallback.onWlanSelected(false);
@@ -203,7 +210,7 @@
 
     private void notifyCsSelected() {
         logd("notifyCsSelected");
-        mStopDomainSelection = true;
+        mSelectorState = SelectorState.INACTIVE;
         if (mWwanSelectorCallback == null) {
             mTransportSelectorCallback.onWwanSelected((callback) -> {
                 mWwanSelectorCallback = callback;
@@ -225,7 +232,7 @@
     }
 
     private void notifySelectionTerminated(@DisconnectCauses int cause) {
-        mStopDomainSelection = true;
+        mSelectorState = SelectorState.INACTIVE;
         if (mTransportSelectorCallback != null) {
             mTransportSelectorCallback.onSelectionTerminated(cause);
             finishSelection();
@@ -243,7 +250,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 +278,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 +296,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 +394,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();
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..c86eff9 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();
+        onCreateExecutor();
 
         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 onCreateExecutor() {
+        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/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/values/donottranslate_strings.xml b/testapps/TestSatelliteApp/res/values/donottranslate_strings.xml
index 8ebe5f3..6c707dd 100644
--- a/testapps/TestSatelliteApp/res/values/donottranslate_strings.xml
+++ b/testapps/TestSatelliteApp/res/values/donottranslate_strings.xml
@@ -65,6 +65,13 @@
     <string name="registerForSatelliteCapabilitiesChanged">registerForSatelliteCapabilitiesChanged</string>
     <string name="unregisterForSatelliteCapabilitiesChanged">unregisterForSatelliteCapabilitiesChanged</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>
 </resources>
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/SatelliteControl.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteControl.java
index 2d01aec..9df5d94 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,8 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.OutcomeReceiver;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
 import android.telephony.satellite.SatelliteCapabilities;
 import android.telephony.satellite.SatelliteManager;
 import android.telephony.satellite.stub.SatelliteResult;
@@ -28,6 +30,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 +43,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 +68,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) {
@@ -270,4 +287,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/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/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/PhoneInterfaceManagerTest.java b/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
index df1091f..2d338f2 100644
--- a/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
+++ b/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
@@ -294,59 +294,59 @@
     }
 
     @Test
-    public void setEnableNullCipherNotifications_allReqsMet_successfullyEnabled() {
+    public void setNullCipherNotificationsEnabled_allReqsMet_successfullyEnabled() {
         setModemSupportsNullCipherNotification(true);
         doNothing().when(mPhoneInterfaceManager).enforceModifyPermission();
         doReturn(202).when(mPhoneInterfaceManager).getHalVersion(anyInt());
         assertFalse(mSharedPreferences.contains(Phone.PREF_NULL_CIPHER_NOTIFICATIONS_ENABLED));
 
-        mPhoneInterfaceManager.setEnableNullCipherNotifications(true);
+        mPhoneInterfaceManager.setNullCipherNotificationsEnabled(true);
 
         assertTrue(
                 mSharedPreferences.getBoolean(Phone.PREF_NULL_CIPHER_NOTIFICATIONS_ENABLED, false));
     }
 
     @Test
-    public void setEnableNullCipherNotifications_allReqsMet_successfullyDisabled() {
+    public void setNullCipherNotificationsEnabled_allReqsMet_successfullyDisabled() {
         setModemSupportsNullCipherNotification(true);
         doNothing().when(mPhoneInterfaceManager).enforceModifyPermission();
         doReturn(202).when(mPhoneInterfaceManager).getHalVersion(anyInt());
         assertFalse(mSharedPreferences.contains(Phone.PREF_NULL_CIPHER_NOTIFICATIONS_ENABLED));
 
-        mPhoneInterfaceManager.setEnableNullCipherNotifications(false);
+        mPhoneInterfaceManager.setNullCipherNotificationsEnabled(false);
 
         assertFalse(
                 mSharedPreferences.getBoolean(Phone.PREF_NULL_CIPHER_NOTIFICATIONS_ENABLED, true));
     }
 
     @Test
-    public void setEnableNullCipherNotifications_lackingNecessaryHal_throwsException() {
+    public void setNullCipherNotificationsEnabled_lackingNecessaryHal_throwsException() {
         setModemSupportsNullCipherNotification(true);
         doNothing().when(mPhoneInterfaceManager).enforceModifyPermission();
         doReturn(102).when(mPhoneInterfaceManager).getHalVersion(anyInt());
 
         assertThrows(UnsupportedOperationException.class,
-                () -> mPhoneInterfaceManager.setEnableNullCipherNotifications(true));
+                () -> mPhoneInterfaceManager.setNullCipherNotificationsEnabled(true));
     }
 
     @Test
-    public void setEnableNullCipherNotifications_lackingModemSupport_throwsException() {
+    public void setNullCipherNotificationsEnabled_lackingModemSupport_throwsException() {
         setModemSupportsNullCipherNotification(false);
         doNothing().when(mPhoneInterfaceManager).enforceModifyPermission();
         doReturn(202).when(mPhoneInterfaceManager).getHalVersion(anyInt());
 
         assertThrows(UnsupportedOperationException.class,
-                () -> mPhoneInterfaceManager.setEnableNullCipherNotifications(true));
+                () -> mPhoneInterfaceManager.setNullCipherNotificationsEnabled(true));
     }
 
     @Test
-    public void setEnableNullCipherNotifications_lackingPermissions_throwsException() {
+    public void setNullCipherNotificationsEnabled_lackingPermissions_throwsException() {
         setModemSupportsNullCipherNotification(true);
         doReturn(202).when(mPhoneInterfaceManager).getHalVersion(anyInt());
         doThrow(SecurityException.class).when(mPhoneInterfaceManager).enforceModifyPermission();
 
         assertThrows(SecurityException.class, () ->
-                mPhoneInterfaceManager.setEnableNullCipherNotifications(true));
+                mPhoneInterfaceManager.setNullCipherNotificationsEnabled(true));
     }
 
     @Test
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
index f49b428..131b8ac 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
@@ -2752,7 +2752,7 @@
 
         DomainSelectionService.SelectionAttributes attr = attrCaptor.getValue();
 
-        assertEquals(mPhone1.getPhoneId(), attr.getSlotId());
+        assertEquals(mPhone1.getPhoneId(), attr.getSlotIndex());
     }
 
     @Test
@@ -2798,7 +2798,7 @@
 
         DomainSelectionService.SelectionAttributes attr = attrCaptor.getValue();
 
-        assertEquals(mPhone1.getPhoneId(), attr.getSlotId());
+        assertEquals(mPhone1.getPhoneId(), attr.getSlotIndex());
     }
 
     @Test
@@ -3285,6 +3285,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();
@@ -3345,6 +3346,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(
diff --git a/tests/src/com/android/services/telephony/domainselection/DomainSelectorBaseTest.java b/tests/src/com/android/services/telephony/domainselection/DomainSelectorBaseTest.java
index 74c3311..a5d463d 100644
--- a/tests/src/com/android/services/telephony/domainselection/DomainSelectorBaseTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/DomainSelectorBaseTest.java
@@ -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..987beb4 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,7 @@
 import android.content.res.Resources;
 import android.net.ConnectivityManager;
 import android.net.NetworkRequest;
+import android.net.Uri;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IPowerManager;
@@ -90,6 +94,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;
@@ -104,7 +109,6 @@
 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;
@@ -124,10 +128,7 @@
 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 +139,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;
@@ -254,7 +255,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 +269,11 @@
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
                 mAccessNetwork = (List<Integer>) invocation.getArguments()[0];
-                mResultConsumer = (Consumer<EmergencyRegResult>) invocation.getArguments()[3];
+                mResultConsumer = (Consumer<EmergencyRegResult>) 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 +297,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));
     }
 
@@ -322,6 +322,45 @@
     }
 
     @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);
+
+        EmergencyRegResult 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 testNullEmergencyRegResult() 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);
@@ -390,7 +429,7 @@
 
         verify(mTransportSelectorCallback, times(1)).onWwanSelected(any());
         verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
-                any(), anyInt(), any(), any());
+                any(), anyInt(), anyBoolean(), any(), any());
     }
 
     @Test
@@ -498,6 +537,7 @@
         //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);
@@ -542,6 +582,24 @@
     }
 
     @Test
+    public void testDefaultCombinedImsNotRegisteredDeactivatedSimSelectPs() throws Exception {
+        doReturn(SIM_ACTIVATION_STATE_DEACTIVATED).when(mTelephonyManager).getDataActivationState();
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegResult 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);
@@ -568,7 +626,7 @@
                 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)
                 .setExitedFromAirplaneMode(true)
@@ -595,7 +653,7 @@
                 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)
                 .setExitedFromAirplaneMode(true)
@@ -869,6 +927,87 @@
     }
 
     @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);
+
+        EmergencyRegResult 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);
+
+        EmergencyRegResult 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);
+
+        EmergencyRegResult 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);
@@ -1225,6 +1364,51 @@
     }
 
     @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);
+
+        EmergencyRegResult 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);
+
+        EmergencyRegResult 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);
@@ -1566,18 +1750,41 @@
         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);
+
+        EmergencyRegResult 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);
@@ -1597,14 +1804,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,6 +2064,36 @@
     }
 
     @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);
+
+        EmergencyRegResult 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);
@@ -1875,16 +2113,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);
@@ -1911,6 +2139,7 @@
         verifyCsDialed();
 
         attr = new SelectionAttributes.Builder(SLOT_0, SLOT_0_SUB_ID, SELECTOR_TYPE_CALLING)
+                .setAddress(TEST_URI)
                 .setEmergency(true)
                 .setEmergencyRegResult(regResult)
                 .setCsDisconnectCause(PreciseDisconnectCause.EMERGENCY_TEMP_FAILURE)
@@ -1939,6 +2168,7 @@
         verifyCsDialed();
 
         attr = new SelectionAttributes.Builder(SLOT_0, SLOT_0_SUB_ID, SELECTOR_TYPE_CALLING)
+                .setAddress(TEST_URI)
                 .setEmergency(true)
                 .setEmergencyRegResult(regResult)
                 .setCsDisconnectCause(PreciseDisconnectCause.EMERGENCY_PERM_FAILURE)
@@ -2025,6 +2255,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);
@@ -2091,6 +2343,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 +2365,85 @@
         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);
+
+        EmergencyRegResult 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());
     }
 
@@ -2202,7 +2534,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));
@@ -2228,7 +2560,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));
@@ -2252,7 +2584,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));
@@ -2279,7 +2611,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));
@@ -2304,6 +2636,38 @@
     }
 
     @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);
+
+        EmergencyRegResult 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);
@@ -2321,87 +2685,54 @@
 
     @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,
+        EmergencyRegResult 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,
                 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);
+        EmergencyRegResult 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
@@ -2573,7 +2904,7 @@
         processAllMessages();
 
         verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
-                any(), anyInt(), any(), any());
+                any(), anyInt(), anyBoolean(), any(), any());
         assertNotNull(mResultConsumer);
     }
 
@@ -2607,7 +2938,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));
     }
 
@@ -2749,12 +3080,18 @@
         return bundle;
     }
 
-    public static SelectionAttributes getSelectionAttributes(int slotId, int subId,
+    private static SelectionAttributes getSelectionAttributes(int slotId, int subId,
             EmergencyRegResult regResult) {
+        return getSelectionAttributes(slotId, subId, false, regResult);
+    }
+
+    private static SelectionAttributes getSelectionAttributes(int slotId, int subId,
+            boolean isTestEmergencyNumber, EmergencyRegResult regResult) {
         SelectionAttributes.Builder builder =
                 new SelectionAttributes.Builder(slotId, subId, SELECTOR_TYPE_CALLING)
-                .setNumber(TEST_EMERGENCY_NUMBER)
+                .setAddress(TEST_URI)
                 .setEmergency(true)
+                .setTestEmergencyNumber(isTestEmergencyNumber)
                 .setEmergencyRegResult(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..e10e9bd 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,6 +40,7 @@
 import android.telephony.CarrierConfigManager;
 import android.telephony.DataSpecificRegistrationInfo;
 import android.telephony.DomainSelectionService.SelectionAttributes;
+import android.telephony.EmergencyRegResult;
 import android.telephony.NetworkRegistrationInfo;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
@@ -92,6 +94,7 @@
     private ImsStateTracker.BarringInfoListener mBarringInfoListener;
     private ImsStateTracker.ServiceStateListener mServiceStateListener;
     private EmergencySmsDomainSelector mDomainSelector;
+    private EmergencyRegResult mEmergencyRegResult;
 
     @Before
     public void setUp() throws Exception {
@@ -151,6 +154,7 @@
             mLooper = null;
         }
 
+        mEmergencyRegResult = 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,22 @@
             callback.accept(mWwanSelectorCallback);
             return null;
         }).when(mTransportSelectorCallback).onWwanSelected(any(Consumer.class));
+
+        doAnswer((invocation) -> {
+            Object[] args = invocation.getArguments();
+            final Consumer<EmergencyRegResult> result = (Consumer<EmergencyRegResult>) args[4];
+            result.accept(mEmergencyRegResult);
+            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) {
+        mEmergencyRegResult = new EmergencyRegResult(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/NormalCallDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/NormalCallDomainSelectorTest.java
index 002c7d5..d6e701a 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,10 +27,12 @@
 
 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;
@@ -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;
@@ -157,6 +160,7 @@
         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)
@@ -193,6 +197,7 @@
         // 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)
@@ -211,6 +216,7 @@
         attributes =
                 new DomainSelectionService.SelectionAttributes.Builder(
                         SLOT_ID, SUB_ID_1, SELECTOR_TYPE_UT)
+                        .setAddress(TEST_URI)
                         .setCallId(TEST_CALLID)
                         .setEmergency(false)
                         .setVideoCall(true)
@@ -228,6 +234,7 @@
         // 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)
@@ -250,6 +257,7 @@
         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)
@@ -270,6 +278,7 @@
         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)
@@ -296,6 +305,7 @@
         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)
@@ -334,7 +344,7 @@
         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)
@@ -378,6 +388,7 @@
         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)
@@ -451,13 +462,6 @@
         }
 
         @Override
-        public synchronized WwanSelectorCallback onWwanSelected() {
-            mWwanSelected = true;
-            notifyAll();
-            return (WwanSelectorCallback) this;
-        }
-
-        @Override
         public void onWwanSelected(final Consumer<WwanSelectorCallback> consumer) {
             mWwanSelected = true;
             Executors.newSingleThreadExecutor().execute(() -> {
@@ -500,6 +504,7 @@
         @Override
         public void onRequestEmergencyNetworkScan(@NonNull List<Integer> preferredNetworks,
                                                   int scanType,
+                                                  boolean resetScan,
                                                   @NonNull CancellationSignal signal,
                                                   @NonNull Consumer<EmergencyRegResult> consumer) {
             Log.i(TAG, "onRequestEmergencyNetworkScan - called");
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..38e058b 100644
--- a/tests/src/com/android/services/telephony/domainselection/SmsDomainSelectorTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/SmsDomainSelectorTest.java
@@ -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..53bbce9 100644
--- a/tests/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionServiceTest.java
@@ -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;