diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 0e32e40..32733cc 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -516,7 +516,6 @@
         <activity android:name="com.android.phone.settings.VoicemailSettingsActivity"
             android:label="@string/voicemail"
             android:configChanges="orientation|screenSize|keyboardHidden|screenLayout"
-            android:screenOrientation="portrait"
             android:exported="true"
             android:theme="@style/CallSettingsWithoutDividerTheme">
             <intent-filter >
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index 44375bb..397ed35 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -80,6 +80,7 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
 
 /**
@@ -194,6 +195,14 @@
     // requested the dump.
     private static final String DUMP_ARG_REQUESTING_PACKAGE = "--requesting-package";
 
+    // Configs that should always be included when clients calls getConfig[ForSubId] with specified
+    // keys (even configs are not explicitly specified). Those configs have special purpose for the
+    // carrier config APIs to work correctly.
+    private static final String[] CONFIG_SUBSET_METADATA_KEYS = new String[] {
+            CarrierConfigManager.KEY_CARRIER_CONFIG_VERSION_STRING,
+            CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL
+    };
+
     // Handler to process various events.
     //
     // For each phoneId, the event sequence should be:
@@ -1329,6 +1338,52 @@
     }
 
     @Override
+    @NonNull
+    public PersistableBundle getConfigSubsetForSubIdWithFeature(int subscriptionId,
+            @NonNull String callingPackage, @Nullable String callingFeatureId,
+            @NonNull String[] keys) {
+        Objects.requireNonNull(callingPackage, "Calling package must be non-null");
+        Objects.requireNonNull(keys, "Config keys must be non-null");
+        enforceCallerIsSystemOrRequestingPackage(callingPackage);
+
+        // Permission check is performed inside and an empty bundle will return on failure.
+        // No SecurityException thrown here since most clients expect to retrieve the overridden
+        // value if present or use default one if not
+        PersistableBundle allConfigs = getConfigForSubIdWithFeature(subscriptionId, callingPackage,
+                callingFeatureId);
+        if (allConfigs.isEmpty()) {
+            return allConfigs;
+        }
+        for (String key : keys) {
+            Objects.requireNonNull(key, "Config key must be non-null");
+            // TODO(b/261776046): validate provided key which may has no default value.
+            // For now, return empty bundle if any required key is not supported
+            if (!allConfigs.containsKey(key)) {
+                return new PersistableBundle();
+            }
+        }
+
+        PersistableBundle configSubset = new PersistableBundle(
+                keys.length + CONFIG_SUBSET_METADATA_KEYS.length);
+        for (String carrierConfigKey : keys) {
+            Object value = allConfigs.get(carrierConfigKey);
+            // Config value itself could be PersistableBundle which requires different API to put
+            if (value instanceof PersistableBundle) {
+                configSubset.putPersistableBundle(carrierConfigKey, (PersistableBundle) value);
+            } else {
+                configSubset.putObject(carrierConfigKey, value);
+            }
+        }
+
+        // Configs in CONFIG_SUBSET_ALWAYS_INCLUDED_KEYS should always be included
+        for (String generalKey : CONFIG_SUBSET_METADATA_KEYS) {
+            configSubset.putObject(generalKey, allConfigs.get(generalKey));
+        }
+
+        return configSubset;
+    }
+
+    @Override
     public void overrideConfig(int subscriptionId, @Nullable PersistableBundle overrides,
             boolean persistent) {
         mContext.enforceCallingOrSelfPermission(
diff --git a/src/com/android/services/telephony/PstnIncomingCallNotifier.java b/src/com/android/services/telephony/PstnIncomingCallNotifier.java
index f78a9b9..d58c211 100644
--- a/src/com/android/services/telephony/PstnIncomingCallNotifier.java
+++ b/src/com/android/services/telephony/PstnIncomingCallNotifier.java
@@ -393,8 +393,9 @@
      */
     private PhoneAccountHandle findCorrectPhoneAccountHandle() {
         TelecomAccountRegistry telecomAccountRegistry = TelecomAccountRegistry.getInstance(null);
-        // Check to see if a the SIM PhoneAccountHandle Exists for the Call.
-        PhoneAccountHandle handle = PhoneUtils.makePstnPhoneAccountHandle(mPhone);
+        // Check to see if a SIM PhoneAccountHandle Exists for the Call.
+        PhoneAccountHandle handle = telecomAccountRegistry.getPhoneAccountHandleForSubId(
+                mPhone.getSubId());
         if (telecomAccountRegistry.hasAccountEntryForPhoneAccount(handle)) {
             return handle;
         }
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 962053c..9d36c48 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -48,11 +48,13 @@
 import android.telephony.ServiceState.RilRadioTechnology;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.telephony.emergency.EmergencyNumber;
 import android.telephony.ims.ImsCallProfile;
 import android.telephony.ims.ImsReasonInfo;
 import android.telephony.ims.ImsStreamMediaProfile;
 import android.telephony.ims.RtpHeaderExtension;
 import android.telephony.ims.RtpHeaderExtensionType;
+import android.telephony.ims.feature.MmTelFeature;
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Pair;
@@ -801,6 +803,13 @@
             Log.i(this, "onReceivedDtmfDigit: digit=%c", digit);
             mDtmfTransport.onDtmfReceived(digit);
         }
+
+        @Override
+        public void onAudioModeIsVoipChanged(int imsAudioHandler) {
+            boolean isVoip = imsAudioHandler == MmTelFeature.AUDIO_HANDLER_ANDROID;
+            Log.i(this, "onAudioModeIsVoipChanged isVoip =" + isVoip);
+            setAudioModeIsVoip(isVoip);
+        }
     };
 
     private TelephonyConnectionService mTelephonyConnectionService;
@@ -925,6 +934,8 @@
     private final Set<TelephonyConnectionListener> mTelephonyListeners = Collections.newSetFromMap(
             new ConcurrentHashMap<TelephonyConnectionListener, Boolean>(8, 0.9f, 1));
 
+    private Integer mEmergencyServiceCategory = null;
+
     protected TelephonyConnection(com.android.internal.telephony.Connection originalConnection,
             String callId, @android.telecom.Call.Details.CallDirection int callDirection) {
         setCallDirection(callDirection);
@@ -2158,7 +2169,7 @@
         mPhoneForEvents = null;
     }
 
-    @VisibleForTesting
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED)
     public void hangup(int telephonyDisconnectCode) {
         if (mOriginalConnection != null) {
             mHangupDisconnectCause = telephonyDisconnectCode;
@@ -2184,6 +2195,7 @@
                 Log.e(this, e, "Call to Connection.hangup failed with exception");
             }
         } else {
+            mTelephonyConnectionService.onLocalHangup(this);
             if (getState() == STATE_DISCONNECTED) {
                 Log.i(this, "hangup called on an already disconnected call!");
                 close();
@@ -2444,6 +2456,29 @@
                     setTelephonyConnectionRinging();
                     break;
                 case DISCONNECTED:
+                    if (mTelephonyConnectionService != null) {
+                        ImsReasonInfo reasonInfo = null;
+                        if (isImsConnection()) {
+                            ImsPhoneConnection imsPhoneConnection =
+                                    (ImsPhoneConnection) mOriginalConnection;
+                            reasonInfo = imsPhoneConnection.getImsReasonInfo();
+                            if (reasonInfo != null && reasonInfo.getCode()
+                                    == ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL) {
+                                EmergencyNumber emergencyNumber =
+                                        imsPhoneConnection.getEmergencyNumberInfo();
+                                if (emergencyNumber != null) {
+                                    mEmergencyServiceCategory =
+                                            emergencyNumber.getEmergencyServiceCategoryBitmask();
+                                }
+                            }
+                        }
+
+                        if (mTelephonyConnectionService.maybeReselectDomain(this,
+                                  mOriginalConnection.getPreciseDisconnectCause(), reasonInfo)) {
+                            break;
+                        }
+                    }
+
                     if (shouldTreatAsEmergencyCall()
                             && (cause
                             == android.telephony.DisconnectCause.EMERGENCY_TEMP_FAILURE
@@ -3831,4 +3866,21 @@
     public List<TelephonyConnectionListener> getTelephonyConnectionListeners() {
         return new ArrayList<>(mTelephonyListeners);
     }
+
+    /**
+     * @return An {@link Integer} instance of the emergency service category.
+     */
+    public @Nullable Integer getEmergencyServiceCategory() {
+        return mEmergencyServiceCategory;
+    }
+
+    /**
+     * Sets the emergency service category.
+     *
+     * @param eccCategory The emergency service category.
+     */
+    @VisibleForTesting
+    public void setEmergencyServiceCategory(int eccCategory) {
+        mEmergencyServiceCategory = eccCategory;
+    }
 }
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index e86a1ae..172407a 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -16,6 +16,7 @@
 
 package com.android.services.telephony;
 
+import static android.telephony.DomainSelectionService.SELECTOR_TYPE_CALLING;
 import static android.telephony.TelephonyManager.HAL_SERVICE_VOICE;
 
 import android.annotation.NonNull;
@@ -40,17 +41,23 @@
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
 import android.telecom.VideoProfile;
+import android.telephony.Annotation.DisconnectCauses;
 import android.telephony.CarrierConfigManager;
+import android.telephony.DomainSelectionService;
+import android.telephony.EmergencyRegResult;
+import android.telephony.NetworkRegistrationInfo;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.RadioAccessFamily;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.emergency.EmergencyNumber;
+import android.telephony.ims.ImsReasonInfo;
 import android.text.TextUtils;
 import android.util.Pair;
 import android.view.WindowManager;
 
+import com.android.ims.ImsManager;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.Call;
 import com.android.internal.telephony.CallStateException;
@@ -64,6 +71,10 @@
 import com.android.internal.telephony.SubscriptionController;
 import com.android.internal.telephony.d2d.Communicator;
 import com.android.internal.telephony.data.PhoneSwitcher;
+import com.android.internal.telephony.domainselection.DomainSelectionConnection;
+import com.android.internal.telephony.domainselection.DomainSelectionResolver;
+import com.android.internal.telephony.domainselection.EmergencyCallDomainSelectionConnection;
+import com.android.internal.telephony.emergency.EmergencyStateTracker;
 import com.android.internal.telephony.imsphone.ImsExternalCallTracker;
 import com.android.internal.telephony.imsphone.ImsPhone;
 import com.android.internal.telephony.imsphone.ImsPhoneConnection;
@@ -89,6 +100,7 @@
 import java.util.Queue;
 import java.util.Set;
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
 import java.util.function.Consumer;
 import java.util.regex.Pattern;
 
@@ -179,6 +191,13 @@
     @VisibleForTesting
     public Pair<WeakReference<TelephonyConnection>, Queue<Phone>> mEmergencyRetryCache;
     private DeviceState mDeviceState = new DeviceState();
+    private EmergencyStateTracker mEmergencyStateTracker;
+    private DomainSelectionResolver mDomainSelectionResolver;
+    private EmergencyCallDomainSelectionConnection mEmergencyCallDomainSelectionConnection;
+    private TelephonyConnection mEmergencyConnection;
+    private String mEmergencyCallId = null;
+    private Executor mDomainSelectionMainExecutor;
+    private ImsManager mImsManager = null;
 
     /**
      * Keeps track of the status of a SIM slot.
@@ -504,6 +523,42 @@
     }
 
     /**
+     * A listener for emergency calls.
+     */
+    private final TelephonyConnection.TelephonyConnectionListener mEmergencyConnectionListener =
+            new TelephonyConnection.TelephonyConnectionListener() {
+        @Override
+        public void onStateChanged(Connection connection, @Connection.ConnectionState int state) {
+            if (connection != null) {
+                TelephonyConnection c = (TelephonyConnection) connection;
+                Log.i(this, "onStateChanged callId=" + c.getTelecomCallId() + ", state=" + state);
+                if (c.getState() == Connection.STATE_ACTIVE) {
+                    mEmergencyStateTracker.onEmergencyCallStateChanged(
+                            c.getOriginalConnection().getState(), c.getTelecomCallId());
+                    c.removeTelephonyConnectionListener(mEmergencyConnectionListener);
+                    releaseEmergencyCallDomainSelection(false);
+                }
+            }
+        }
+    };
+
+    private final DomainSelectionConnection.DomainSelectionConnectionCallback
+            mEmergencyDomainSelectionConnectionCallback =
+                    new DomainSelectionConnection.DomainSelectionConnectionCallback() {
+        @Override
+        public void onSelectionTerminated(@DisconnectCauses int cause) {
+            if (mEmergencyCallDomainSelectionConnection != null) {
+                Log.i(this, "onSelectionTerminated cause=" + cause);
+                mEmergencyCallDomainSelectionConnection = null;
+                if (mEmergencyConnection != null) {
+                    mEmergencyConnection.hangup(android.telephony.DisconnectCause.OUT_OF_NETWORK);
+                    mEmergencyConnection = null;
+                }
+            }
+        }
+    };
+
+    /**
      * A listener to actionable events specific to the TelephonyConnection.
      */
     private final TelephonyConnection.TelephonyConnectionListener mTelephonyConnectionListener =
@@ -542,6 +597,8 @@
         TelecomAccountRegistry.getInstance(this).setTelephonyConnectionService(this);
         mHoldTracker = new HoldTracker();
         mIsTtyEnabled = mDeviceState.isTtyModeEnabled(this);
+        mDomainSelectionMainExecutor = getApplicationContext().getMainExecutor();
+        mDomainSelectionResolver = DomainSelectionResolver.getInstance();
 
         IntentFilter intentFilter = new IntentFilter(
                 TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED);
@@ -809,6 +866,16 @@
                 /* Note: when not an emergency, handle can be null for unknown callers */
                 handle == null ? null : handle.getSchemeSpecificPart());
 
+        if (mDomainSelectionResolver.isDomainSelectionSupported()) {
+            if (isEmergencyNumber) {
+                final Connection resultConnection =
+                        placeEmergencyConnection(phone,
+                                request, numberToDial, isTestEmergencyNumber,
+                                handle, needToTurnOnRadio);
+                if (resultConnection != null) return resultConnection;
+            }
+        }
+
         if (needToTurnOnRadio) {
             final Uri resultHandle = handle;
             final int originalPhoneType = phone.getPhoneType();
@@ -1715,6 +1782,10 @@
                 }
                 updatePhoneAccount(c, newPhoneToUse);
             }
+            if (mDomainSelectionResolver.isDomainSelectionSupported()) {
+                onEmergencyRedial(c, newPhoneToUse);
+                return;
+            }
             placeOutgoingConnection(c, newPhoneToUse, videoState, connExtras);
         } else {
             // We have run out of Phones to use. Disconnect the call and destroy the connection.
@@ -1770,6 +1841,7 @@
         try {
             if (phone != null) {
                 boolean isEmergency = mTelephonyManagerProxy.isCurrentEmergencyNumber(number);
+                Log.i(this, "placeOutgoingConnection isEmergency=" + isEmergency);
                 if (isEmergency) {
                     if (!getAllConnections().isEmpty()) {
                         if (!shouldHoldForEmergencyCall(phone)) {
@@ -1862,6 +1934,366 @@
         }
     }
 
+    @SuppressWarnings("FutureReturnValueIgnored")
+    private Connection placeEmergencyConnection(
+            final Phone phone, final ConnectionRequest request,
+            final String numberToDial, final boolean isTestEmergencyNumber,
+            final Uri handle, final boolean needToTurnOnRadio) {
+
+        final Connection resultConnection =
+                getTelephonyConnection(request, numberToDial, true, handle, phone);
+
+        if (resultConnection instanceof TelephonyConnection) {
+            Log.i(this, "placeEmergencyConnection");
+
+            mIsEmergencyCallPending = true;
+            ((TelephonyConnection) resultConnection).addTelephonyConnectionListener(
+                    mEmergencyConnectionListener);
+
+            if (mEmergencyStateTracker == null) {
+                mEmergencyStateTracker = EmergencyStateTracker.getInstance();
+            }
+
+            mEmergencyCallId = resultConnection.getTelecomCallId();
+            CompletableFuture<Integer> future = mEmergencyStateTracker.startEmergencyCall(
+                    phone, mEmergencyCallId, isTestEmergencyNumber);
+            future.thenAccept((result) -> {
+                Log.d(this, "startEmergencyCall-complete result=" + result);
+                if (result == android.telephony.DisconnectCause.NOT_DISCONNECTED) {
+                    createEmergencyConnection(phone, (TelephonyConnection) resultConnection,
+                            numberToDial, request, needToTurnOnRadio,
+                            mEmergencyStateTracker.getEmergencyRegResult());
+                } else {
+                    mEmergencyConnection = null;
+                    String reason = "Couldn't setup emergency call";
+                    if (result == android.telephony.DisconnectCause.POWER_OFF) {
+                        reason = "Failed to turn on radio.";
+                    }
+                    ((TelephonyConnection) resultConnection).setTelephonyConnectionDisconnected(
+                            mDisconnectCauseFactory.toTelecomDisconnectCause(result, reason));
+                    ((TelephonyConnection) resultConnection).close();
+                    mIsEmergencyCallPending = false;
+                }
+            });
+            mEmergencyConnection = (TelephonyConnection) resultConnection;
+            return resultConnection;
+        }
+        Log.i(this, "placeEmergencyConnection returns null");
+        return null;
+    }
+
+    @SuppressWarnings("FutureReturnValueIgnored")
+    private void createEmergencyConnection(final Phone phone,
+            final TelephonyConnection resultConnection, final String number,
+            final ConnectionRequest request, boolean needToTurnOnRadio,
+            final EmergencyRegResult regResult) {
+        Log.i(this, "createEmergencyConnection");
+
+        if (phone.getImsPhone() == null) {
+            // Dialing emergency calls over IMS is not available without ImsPhone instance.
+            Log.w(this, "createEmergencyConnection no ImsPhone");
+            dialCsEmergencyCall(phone, resultConnection, request);
+            return;
+        }
+
+        ImsManager imsManager = mImsManager;
+        if (imsManager == null) {
+            // mImsManager is not null only while unit test.
+            imsManager = ImsManager.getInstance(phone.getContext(), phone.getPhoneId());
+        }
+        if (!imsManager.isNonTtyOrTtyOnVolteEnabled()) {
+            Log.w(this, "createEmergencyConnection - TTY on VoLTE is not supported.");
+            dialCsEmergencyCall(phone, resultConnection, request);
+            return;
+        }
+
+        DomainSelectionConnection selectConnection =
+                mDomainSelectionResolver.getDomainSelectionConnection(
+                        phone, SELECTOR_TYPE_CALLING, true);
+
+        if (selectConnection == null) {
+            // While the domain selection service is enabled, the valid
+            // {@link DomainSelectionConnection} is not available.
+            // This can happen when the domain selection service is not available.
+            Log.w(this, "createEmergencyConnection - no selectionConnection");
+            dialCsEmergencyCall(phone, resultConnection, request);
+            return;
+        }
+
+        mEmergencyCallDomainSelectionConnection =
+                (EmergencyCallDomainSelectionConnection) selectConnection;
+
+        DomainSelectionService.SelectionAttributes attr =
+                EmergencyCallDomainSelectionConnection.getSelectionAttributes(
+                        phone.getPhoneId(), phone.getSubId(), needToTurnOnRadio,
+                        request.getTelecomCallId(), number, 0, null, regResult);
+
+        CompletableFuture<Integer> future =
+                mEmergencyCallDomainSelectionConnection.createEmergencyConnection(
+                        attr, mEmergencyDomainSelectionConnectionCallback);
+        future.thenAcceptAsync((result) -> {
+            Log.d(this, "createEmergencyConnection-complete result=" + result);
+            Bundle extras = request.getExtras();
+            extras.putInt(PhoneConstants.EXTRA_DIAL_DOMAIN, result);
+            placeOutgoingConnection(request, resultConnection, phone);
+            mIsEmergencyCallPending = false;
+        }, mDomainSelectionMainExecutor);
+    }
+
+    private void dialCsEmergencyCall(final Phone phone,
+            final TelephonyConnection resultConnection, final ConnectionRequest request) {
+        Log.d(this, "dialCsEmergencyCall");
+        Bundle extras = request.getExtras();
+        extras.putInt(PhoneConstants.EXTRA_DIAL_DOMAIN, NetworkRegistrationInfo.DOMAIN_CS);
+        mDomainSelectionMainExecutor.execute(
+                () -> placeOutgoingConnection(request, resultConnection, phone));
+    }
+
+    private void releaseEmergencyCallDomainSelection(boolean cancel) {
+        if (mEmergencyCallDomainSelectionConnection != null) {
+            if (cancel) mEmergencyCallDomainSelectionConnection.cancelSelection();
+            else mEmergencyCallDomainSelectionConnection.finishSelection();
+            mEmergencyCallDomainSelectionConnection = null;
+        }
+        mIsEmergencyCallPending = false;
+        mEmergencyConnection = null;
+    }
+
+    /**
+     * Determine whether reselection of domain is required or not.
+     * @param c the {@link Connection} instance.
+     * @param callFailCause the reason why CS call is disconnected. Allowed values are defined in
+     * {@link com.android.internal.telephony.CallFailCause}.
+     * @param reasonInfo the reason why PS call is disconnected.
+     * @return {@code true} if reselection of domain is required.
+     */
+    public boolean maybeReselectDomain(final TelephonyConnection c,
+            int callFailCause, ImsReasonInfo reasonInfo) {
+        if (!mDomainSelectionResolver.isDomainSelectionSupported()) return false;
+
+        Log.i(this, "maybeReselectDomain csCause=" +  callFailCause + ", psCause=" + reasonInfo);
+        if (TextUtils.equals(mEmergencyCallId, c.getTelecomCallId())) {
+            if (mEmergencyCallDomainSelectionConnection != null) {
+                return maybeReselectDomainForEmergencyCall(c, callFailCause, reasonInfo);
+            }
+            Log.i(this, "maybeReselectDomain endCall()");
+            mEmergencyStateTracker.endCall(c.getTelecomCallId());
+            mEmergencyCallId = null;
+            return false;
+        }
+
+        if (reasonInfo != null
+                && reasonInfo.getCode() == ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL) {
+            onEmergencyRedial(c, c.getPhone());
+            return true;
+        }
+
+        return false;
+    }
+
+    private boolean maybeReselectDomainForEmergencyCall(final TelephonyConnection c,
+            int callFailCause, ImsReasonInfo reasonInfo) {
+        Log.i(this, "maybeReselectDomainForEmergencyCall "
+                + "csCause=" +  callFailCause + ", psCause=" + reasonInfo);
+
+        // EMERGENCY_TEMP_FAILURE and EMERGENCY_PERM_FAILURE shall be handled after
+        // reselecting new {@link Phone} in {@link #retryOutgoingOriginalConnection()}.
+        if (c.getOriginalConnection() != null
+                && c.getOriginalConnection().getDisconnectCause()
+                        != android.telephony.DisconnectCause.EMERGENCY_TEMP_FAILURE
+                && c.getOriginalConnection().getDisconnectCause()
+                        != android.telephony.DisconnectCause.EMERGENCY_PERM_FAILURE
+                && c.getOriginalConnection().getDisconnectCause()
+                        != android.telephony.DisconnectCause.LOCAL
+                && c.getOriginalConnection().getDisconnectCause()
+                        != android.telephony.DisconnectCause.POWER_OFF) {
+
+            DomainSelectionService.SelectionAttributes attr =
+                    EmergencyCallDomainSelectionConnection.getSelectionAttributes(
+                            c.getPhone().getPhoneId(), c.getPhone().getSubId(), false,
+                            c.getTelecomCallId(), c.getAddress().getSchemeSpecificPart(),
+                            callFailCause, reasonInfo, null);
+
+            CompletableFuture<Integer> future =
+                    mEmergencyCallDomainSelectionConnection.reselectDomain(attr);
+            if (future != null) {
+                future.thenAcceptAsync((result) -> {
+                    Log.d(this, "reselectDomain-complete");
+                    onEmergencyRedialOnDomain(c, c.getPhone(), result);
+                }, mDomainSelectionMainExecutor);
+                return true;
+            }
+        }
+
+        Log.i(this, "maybeReselectDomainForEmergencyCall endCall()");
+        c.removeTelephonyConnectionListener(mEmergencyConnectionListener);
+        mEmergencyStateTracker.endCall(c.getTelecomCallId());
+        releaseEmergencyCallDomainSelection(true);
+
+        return false;
+    }
+
+    private void onEmergencyRedialOnDomain(TelephonyConnection connection,
+            final Phone phone, @NetworkRegistrationInfo.Domain int domain) {
+        Log.i(this, "onEmergencyRedialOnDomain phoneId=" + phone.getPhoneId()
+                + ", domain=" + DomainSelectionService.getDomainName(domain));
+
+        String number = connection.getAddress().getSchemeSpecificPart();
+
+        // Indicates undetectable emergency number with DialArgs
+        boolean isEmergency = false;
+        int eccCategory = EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED;
+        if (connection.getEmergencyServiceCategory() != null) {
+            isEmergency = true;
+            eccCategory = connection.getEmergencyServiceCategory();
+            Log.i(this, "onEmergencyRedialOnDomain eccCategory=" + eccCategory);
+        }
+
+        Bundle extras = new Bundle();
+        extras.putInt(PhoneConstants.EXTRA_DIAL_DOMAIN, domain);
+
+        com.android.internal.telephony.Connection originalConnection =
+                connection.getOriginalConnection();
+        try {
+            if (phone != null) {
+                originalConnection = phone.dial(number, new ImsPhone.ImsDialArgs.Builder()
+                        .setVideoState(VideoProfile.STATE_AUDIO_ONLY)
+                        .setIntentExtras(extras)
+                        .setRttTextStream(connection.getRttTextStream())
+                        .setIsEmergency(isEmergency)
+                        .setEccCategory(eccCategory)
+                        .build(),
+                        connection::registerForCallEvents);
+            }
+        } catch (CallStateException e) {
+            Log.e(this, e, "onEmergencyRedialOnDomain, exception: " + e);
+        }
+        if (originalConnection == null) {
+            Log.d(this, "onEmergencyRedialOnDomain, phone.dial returned null");
+            connection.setDisconnected(
+                    mDisconnectCauseFactory.toTelecomDisconnectCause(
+                                android.telephony.DisconnectCause.ERROR_UNSPECIFIED,
+                                "unknown error"));
+        } else {
+            connection.setOriginalConnection(originalConnection);
+        }
+    }
+
+    @SuppressWarnings("FutureReturnValueIgnored")
+    private void onEmergencyRedial(final TelephonyConnection c, final Phone phone) {
+        Log.i(this, "onEmergencyRedial phoneId=" + phone.getPhoneId());
+
+        final String number = c.getAddress().getSchemeSpecificPart();
+        final boolean isTestEmergencyNumber = isEmergencyNumberTestNumber(number);
+
+        mIsEmergencyCallPending = true;
+        c.addTelephonyConnectionListener(mEmergencyConnectionListener);
+
+        if (mEmergencyStateTracker == null) {
+            mEmergencyStateTracker = EmergencyStateTracker.getInstance();
+        }
+
+        mEmergencyCallId = c.getTelecomCallId();
+        CompletableFuture<Integer> future = mEmergencyStateTracker.startEmergencyCall(
+                phone, mEmergencyCallId, isTestEmergencyNumber);
+        future.thenAccept((result) -> {
+            Log.d(this, "onEmergencyRedial-complete result=" + result);
+            if (result == android.telephony.DisconnectCause.NOT_DISCONNECTED) {
+
+                DomainSelectionConnection selectConnection =
+                        mDomainSelectionResolver.getDomainSelectionConnection(
+                                phone, SELECTOR_TYPE_CALLING, true);
+
+                if (selectConnection == null) {
+                    Log.w(this, "onEmergencyRedial no selectionConnection, dial CS emergency call");
+                    mIsEmergencyCallPending = false;
+                    mDomainSelectionMainExecutor.execute(
+                            () -> recreateEmergencyConnection(c, phone,
+                                    NetworkRegistrationInfo.DOMAIN_CS));
+                    return;
+                }
+
+                mEmergencyCallDomainSelectionConnection =
+                        (EmergencyCallDomainSelectionConnection) selectConnection;
+
+                mEmergencyConnection = c;
+
+                DomainSelectionService.SelectionAttributes attr =
+                        EmergencyCallDomainSelectionConnection.getSelectionAttributes(
+                                phone.getPhoneId(),
+                                phone.getSubId(), false,
+                                c.getTelecomCallId(),
+                                c.getAddress().getSchemeSpecificPart(),
+                                0, null, mEmergencyStateTracker.getEmergencyRegResult());
+
+                CompletableFuture<Integer> domainFuture =
+                        mEmergencyCallDomainSelectionConnection.createEmergencyConnection(
+                                attr, mEmergencyDomainSelectionConnectionCallback);
+                domainFuture.thenAcceptAsync((domain) -> {
+                    Log.d(this, "onEmergencyRedial-createEmergencyConnection-complete domain="
+                            + domain);
+                    recreateEmergencyConnection(c, phone, domain);
+                    mIsEmergencyCallPending = false;
+                }, mDomainSelectionMainExecutor);
+            } else {
+                c.setTelephonyConnectionDisconnected(
+                        mDisconnectCauseFactory.toTelecomDisconnectCause(result, "unknown error"));
+                c.close();
+                mIsEmergencyCallPending = false;
+            }
+        });
+    }
+
+    private void recreateEmergencyConnection(final TelephonyConnection connection,
+            final Phone phone, final @NetworkRegistrationInfo.Domain int result) {
+        Log.d(this, "recreateEmergencyConnection result=" + result);
+        if (!getAllConnections().isEmpty()) {
+            if (!shouldHoldForEmergencyCall(phone)) {
+                // If we do not support holding ongoing calls for an outgoing
+                // emergency call, disconnect the ongoing calls.
+                for (Connection c : getAllConnections()) {
+                    if (!c.equals(connection)
+                            && c.getState() != Connection.STATE_DISCONNECTED
+                            && c instanceof TelephonyConnection) {
+                        ((TelephonyConnection) c).hangup(
+                                android.telephony.DisconnectCause
+                                        .OUTGOING_EMERGENCY_CALL_PLACED);
+                    }
+                }
+                for (Conference c : getAllConferences()) {
+                    if (c.getState() != Connection.STATE_DISCONNECTED) {
+                        c.onDisconnect();
+                    }
+                }
+            } else if (!isVideoCallHoldAllowed(phone)) {
+                // If we do not support holding ongoing video call for an outgoing
+                // emergency call, disconnect the ongoing video call.
+                for (Connection c : getAllConnections()) {
+                    if (!c.equals(connection)
+                            && c.getState() == Connection.STATE_ACTIVE
+                            && VideoProfile.isVideo(c.getVideoState())
+                            && c instanceof TelephonyConnection) {
+                        ((TelephonyConnection) c).hangup(
+                                android.telephony.DisconnectCause
+                                        .OUTGOING_EMERGENCY_CALL_PLACED);
+                        break;
+                    }
+                }
+            }
+        }
+        onEmergencyRedialOnDomain(connection, phone, result);
+    }
+
+    protected void onLocalHangup(TelephonyConnection c) {
+        if (TextUtils.equals(mEmergencyCallId, c.getTelecomCallId())) {
+            Log.i(this, "onLocalHangup " + mEmergencyCallId);
+            c.removeTelephonyConnectionListener(mEmergencyConnectionListener);
+            mEmergencyStateTracker.endCall(c.getTelecomCallId());
+            releaseEmergencyCallDomainSelection(true);
+            mEmergencyCallId = null;
+        }
+    }
+
     private boolean isVideoCallHoldAllowed(Phone phone) {
          CarrierConfigManager cfgManager = (CarrierConfigManager)
                 phone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
index 85be48d..1208ee2 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
@@ -16,6 +16,13 @@
 
 package com.android.services.telephony;
 
+import static android.telephony.DisconnectCause.NOT_DISCONNECTED;
+import static android.telephony.DomainSelectionService.SELECTOR_TYPE_CALLING;
+import static android.telephony.NetworkRegistrationInfo.DOMAIN_CS;
+import static android.telephony.NetworkRegistrationInfo.DOMAIN_PS;
+import static android.telephony.emergency.EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE;
+import static android.telephony.ims.ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL;
+
 import static com.android.internal.telephony.RILConstants.GSM_PHONE;
 
 import static junit.framework.Assert.assertEquals;
@@ -25,14 +32,15 @@
 import static junit.framework.Assert.fail;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -46,26 +54,33 @@
 import android.telecom.DisconnectCause;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
-import android.telephony.CarrierConfigManager;
 import android.telephony.RadioAccessFamily;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.emergency.EmergencyNumber;
+import android.telephony.ims.ImsReasonInfo;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.TelephonyTestBase;
+import com.android.ims.ImsManager;
 import com.android.internal.telecom.IConnectionService;
 import com.android.internal.telephony.Call;
 import com.android.internal.telephony.CallStateException;
 import com.android.internal.telephony.Connection;
 import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.PhoneInternalInterface.DialArgs;
 import com.android.internal.telephony.ServiceStateTracker;
 import com.android.internal.telephony.data.PhoneSwitcher;
+import com.android.internal.telephony.domainselection.DomainSelectionResolver;
+import com.android.internal.telephony.domainselection.EmergencyCallDomainSelectionConnection;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
+import com.android.internal.telephony.emergency.EmergencyStateTracker;
 import com.android.internal.telephony.gsm.SuppServiceNotification;
+import com.android.internal.telephony.imsphone.ImsPhone;
 
 import org.junit.After;
 import org.junit.Before;
@@ -73,11 +88,14 @@
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
 
 /**
  * Unit tests for TelephonyConnectionService.
@@ -116,6 +134,8 @@
     private static final PhoneAccountHandle PHONE_ACCOUNT_HANDLE_2 = new PhoneAccountHandle(
             TEST_COMPONENT_NAME, TEST_ACCOUNT_ID2);
     private static final Uri TEST_ADDRESS = Uri.parse("tel:+16505551212");
+    private static final String TELECOM_CALL_ID1 = "TC1";
+    private static final String TEST_EMERGENCY_NUMBER = "911";
     private android.telecom.Connection mConnection;
 
     @Mock TelephonyConnectionService.TelephonyManagerProxy mTelephonyManagerProxy;
@@ -135,6 +155,10 @@
     @Mock Call mCall2;
     @Mock com.android.internal.telephony.Connection mInternalConnection;
     @Mock com.android.internal.telephony.Connection mInternalConnection2;
+    @Mock DomainSelectionResolver mDomainSelectionResolver;
+    @Mock EmergencyCallDomainSelectionConnection mEmergencyCallDomainSelectionConnection;
+    @Mock ImsPhone mImsPhone;
+    private EmergencyStateTracker mEmergencyStateTracker;
     private Phone mPhone0;
     private Phone mPhone1;
 
@@ -180,6 +204,20 @@
         mTestConnectionService.setDisconnectCauseFactory(mDisconnectCauseFactory);
         mTestConnectionService.onCreate();
         mTestConnectionService.setTelephonyManagerProxy(mTelephonyManagerProxy);
+        DomainSelectionResolver.setDomainSelectionResolver(mDomainSelectionResolver);
+        replaceInstance(TelephonyConnectionService.class, "mDomainSelectionResolver",
+                mTestConnectionService, mDomainSelectionResolver);
+        mEmergencyStateTracker = Mockito.mock(EmergencyStateTracker.class);
+        replaceInstance(TelephonyConnectionService.class, "mEmergencyStateTracker",
+                mTestConnectionService, mEmergencyStateTracker);
+        doReturn(CompletableFuture.completedFuture(NOT_DISCONNECTED))
+                .when(mEmergencyStateTracker)
+                .startEmergencyCall(any(), anyString(), eq(false));
+        replaceInstance(TelephonyConnectionService.class,
+                "mDomainSelectionMainExecutor", mTestConnectionService, getExecutor());
+        doReturn(false).when(mDomainSelectionResolver).isDomainSelectionSupported();
+        doReturn(null).when(mDomainSelectionResolver).getDomainSelectionConnection(
+                any(), anyInt(), anyBoolean());
         mBinderStub = (IConnectionService.Stub) mTestConnectionService.onBind(null);
     }
 
@@ -1107,221 +1145,6 @@
     }
 
     /**
-     * Test that the TelephonyConnectionService successfully performs a DDS switch before a call
-     * when we are not roaming and the carrier only supports SUPL over the data plane.
-     */
-    @Test
-    @SmallTest
-    public void testCreateOutgoingEmergencyConnection_delayDial_carrierconfig_dds() {
-        // Setup test to not support SUPL on the non-DDS subscription
-        doReturn(true).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any());
-        getTestContext().getCarrierConfig(0 /*subId*/).putStringArray(
-                CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY,
-                null);
-        getTestContext().getCarrierConfig(0 /*subId*/).putInt(
-                CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
-                CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_DP_ONLY);
-        getTestContext().getCarrierConfig(0 /*subId*/).putString(
-                CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "150");
-
-        Phone testPhone = setupConnectionServiceForDelayDial(
-                false /* isRoaming */, false /* setOperatorName */, null /* operator long name*/,
-                        null /* operator short name */, null /* operator numeric name */);
-        verify(mPhoneSwitcher).overrideDefaultDataForEmergency(eq(0) /*phoneId*/ ,
-                eq(150) /*extensionTime*/, any());
-    }
-
-    /**
-     * Test that the TelephonyConnectionService successfully turns radio on before placing the
-     * emergency call.
-     */
-    @Test
-    @SmallTest
-    public void testCreateOutgoingEmerge_exitingApm_disconnected() {
-        when(mDeviceState.isAirplaneModeOn(any())).thenReturn(true);
-        Phone testPhone = setupConnectionServiceInApm();
-
-        ArgumentCaptor<RadioOnStateListener.Callback> callback =
-                ArgumentCaptor.forClass(RadioOnStateListener.Callback.class);
-        verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true),
-                eq(testPhone), eq(false));
-
-        assertFalse(callback.getValue().isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE));
-        when(mSST.isRadioOn()).thenReturn(true);
-        assertTrue(callback.getValue().isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE));
-
-        mConnection.setDisconnected(null);
-        callback.getValue().onComplete(null, true);
-        for (Phone phone : mPhoneFactoryProxy.getPhones()) {
-            verify(phone).setRadioPower(true, false, false, true);
-        }
-    }
-
-    /**
-     * Test that the TelephonyConnectionService successfully turns radio on before placing the
-     * emergency call.
-     */
-    @Test
-    @SmallTest
-    public void testCreateOutgoingEmergencyConnection_exitingApm_placeCall() {
-        when(mDeviceState.isAirplaneModeOn(any())).thenReturn(true);
-        Phone testPhone = setupConnectionServiceInApm();
-
-        ArgumentCaptor<RadioOnStateListener.Callback> callback =
-                ArgumentCaptor.forClass(RadioOnStateListener.Callback.class);
-        verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true),
-                eq(testPhone), eq(false));
-
-        assertFalse(callback.getValue().isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE));
-        when(mSST.isRadioOn()).thenReturn(true);
-        assertTrue(callback.getValue().isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE));
-
-        callback.getValue().onComplete(null, true);
-
-        try {
-            doAnswer(invocation -> null).when(mContext).startActivity(any());
-            verify(testPhone).dial(anyString(), any(), any());
-        } catch (CallStateException e) {
-            // This shouldn't happen
-            fail();
-        }
-    }
-
-    /**
-     * Test that the TelephonyConnectionService does not perform a DDS switch when the carrier
-     * supports control-plane fallback.
-     */
-    @Test
-    @SmallTest
-    public void testCreateOutgoingEmergencyConnection_delayDial_nocarrierconfig() {
-        // Setup test to not support SUPL on the non-DDS subscription
-        doReturn(true).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any());
-        getTestContext().getCarrierConfig(0 /*subId*/).putStringArray(
-                CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY,
-                null);
-        getTestContext().getCarrierConfig(0 /*subId*/).putInt(
-                CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
-                CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_CP_FALLBACK);
-        getTestContext().getCarrierConfig(0 /*subId*/).putString(
-                CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0");
-
-        Phone testPhone = setupConnectionServiceForDelayDial(
-                false /* isRoaming */, false /* setOperatorName */, null /* operator long name*/,
-                        null /* operator short name */, null /* operator numeric name */);
-        verify(mPhoneSwitcher, never()).overrideDefaultDataForEmergency(anyInt(), anyInt(), any());
-    }
-
-    /**
-     * Test that the TelephonyConnectionService does not perform a DDS switch when the carrier
-     * supports control-plane fallback.
-     */
-    @Test
-    @SmallTest
-    public void testCreateOutgoingEmergencyConnection_delayDial_supportsuplondds() {
-        // If the non-DDS supports SUPL, dont switch data
-        doReturn(false).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any());
-        getTestContext().getCarrierConfig(0 /*subId*/).putStringArray(
-                CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY,
-                null);
-        getTestContext().getCarrierConfig(0 /*subId*/).putInt(
-                CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
-                CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_DP_ONLY);
-        getTestContext().getCarrierConfig(0 /*subId*/).putString(
-                CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0");
-
-        Phone testPhone = setupConnectionServiceForDelayDial(
-                false /* isRoaming */, false /* setOperatorName */, null /* operator long name*/,
-                         null /* operator short name */, null /* operator numeric name */);
-        verify(mPhoneSwitcher, never()).overrideDefaultDataForEmergency(anyInt(), anyInt(), any());
-    }
-
-    /**
-     * Test that the TelephonyConnectionService does not perform a DDS switch when the carrier does
-     * not support control-plane fallback CarrierConfig while roaming.
-     */
-    @Test
-    @SmallTest
-    public void testCreateOutgoingEmergencyConnection_delayDial_roaming_nocarrierconfig() {
-        // Setup test to not support SUPL on the non-DDS subscription
-        doReturn(true).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any());
-        getTestContext().getCarrierConfig(0 /*subId*/).putStringArray(
-                CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY,
-                null);
-        getTestContext().getCarrierConfig(0 /*subId*/).putInt(
-                CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
-                CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_DP_ONLY);
-        getTestContext().getCarrierConfig(0 /*subId*/).putString(
-                CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0");
-
-        Phone testPhone = setupConnectionServiceForDelayDial(
-                true /* isRoaming */, false /* setOperatorName */, null /* operator long name*/,
-                         null /* operator short name */, null /* operator numeric name */);
-        verify(mPhoneSwitcher, never()).overrideDefaultDataForEmergency(anyInt(), anyInt(), any());
-    }
-
-    /**
-     * Test that the TelephonyConnectionService does perform a DDS switch even though the carrier
-     * supports control-plane fallback CarrierConfig and the roaming partner is configured to look
-     * like a home network.
-     */
-    @Test
-    @SmallTest
-    public void testCreateOutgoingEmergencyConnection_delayDial_roamingcarrierconfig() {
-        doReturn(true).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any());
-        // Setup voice roaming scenario
-        String testRoamingOperator = "001001";
-        // Setup test to not support SUPL on the non-DDS subscription
-        String[] roamingPlmns = new String[1];
-        roamingPlmns[0] = testRoamingOperator;
-        getTestContext().getCarrierConfig(0 /*subId*/).putStringArray(
-                CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY,
-                roamingPlmns);
-        getTestContext().getCarrierConfig(0 /*subId*/).putInt(
-                CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
-                CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_CP_FALLBACK);
-        getTestContext().getCarrierConfig(0 /*subId*/).putString(
-                CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0");
-
-        Phone testPhone = setupConnectionServiceForDelayDial(
-                false /* isRoaming */, true /* setOperatorName */,
-                        "TestTel" /* operator long name*/, "TestTel" /* operator short name */,
-                                testRoamingOperator /* operator numeric name */);
-        verify(mPhoneSwitcher).overrideDefaultDataForEmergency(eq(0) /*phoneId*/ ,
-                eq(0) /*extensionTime*/, any());
-    }
-
-    /**
-     * Test that the TelephonyConnectionService does perform a DDS switch even though the carrier
-     * supports control-plane fallback CarrierConfig if we are roaming and the roaming partner is
-     * configured to use data plane only SUPL.
-     */
-    @Test
-    @SmallTest
-    public void testCreateOutgoingEmergencyConnection_delayDial__roaming_roamingcarrierconfig() {
-        // Setup test to not support SUPL on the non-DDS subscription
-        doReturn(true).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any());
-        // Setup voice roaming scenario
-        String testRoamingOperator = "001001";
-        String[] roamingPlmns = new String[1];
-        roamingPlmns[0] = testRoamingOperator;
-        getTestContext().getCarrierConfig(0 /*subId*/).putStringArray(
-                CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY,
-                roamingPlmns);
-        getTestContext().getCarrierConfig(0 /*subId*/).putInt(
-                CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
-                CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_CP_FALLBACK);
-        getTestContext().getCarrierConfig(0 /*subId*/).putString(
-                CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0");
-
-        Phone testPhone = setupConnectionServiceForDelayDial(
-                false /* isRoaming */, true /* setOperatorName */,
-                        "TestTel" /* operator long name*/, "TestTel" /* operator short name */,
-                                testRoamingOperator /* operator numeric name */);
-        verify(mPhoneSwitcher).overrideDefaultDataForEmergency(eq(0) /*phoneId*/ ,
-                eq(0) /*extensionTime*/, any());
-    }
-
-    /**
      * Verifies for an incoming call on the same SIM that we don't set
      * {@link android.telecom.Connection#EXTRA_ANSWERING_DROPS_FG_CALL} on the incoming call extras.
      * @throws Exception
@@ -1545,6 +1368,277 @@
                 .isCurrentEmergencyNumber(TEST_ADDRESS.getSchemeSpecificPart());
     }
 
+    @Test
+    public void testDomainSelectionCs() throws Exception {
+        setupForCallTest();
+
+        int selectedDomain = DOMAIN_CS;
+
+        setupForDialForDomainSelection(mPhone0, selectedDomain, true);
+
+        mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1,
+                createConnectionRequest(PHONE_ACCOUNT_HANDLE_1,
+                        TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1));
+
+        verify(mDomainSelectionResolver)
+                .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
+        verify(mEmergencyStateTracker)
+                .startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+        verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
+
+        ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
+
+        verify(mPhone0).dial(anyString(), argsCaptor.capture(), any());
+        DialArgs dialArgs = argsCaptor.getValue();
+        assertNotNull("DialArgs param is null", dialArgs);
+        assertNotNull("intentExtras is null", dialArgs.intentExtras);
+        assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN));
+        assertEquals(selectedDomain,
+                dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1));
+    }
+
+    @Test
+    public void testDomainSelectionPs() throws Exception {
+        setupForCallTest();
+
+        int selectedDomain = DOMAIN_PS;
+
+        setupForDialForDomainSelection(mPhone0, selectedDomain, true);
+
+        mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1,
+                createConnectionRequest(PHONE_ACCOUNT_HANDLE_1,
+                        TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1));
+
+        verify(mDomainSelectionResolver)
+                .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
+        verify(mEmergencyStateTracker)
+                .startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+        verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
+
+        ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
+
+        verify(mPhone0).dial(anyString(), argsCaptor.capture(), any());
+        DialArgs dialArgs = argsCaptor.getValue();
+        assertNotNull("DialArgs param is null", dialArgs);
+        assertNotNull("intentExtras is null", dialArgs.intentExtras);
+        assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN));
+        assertEquals(selectedDomain,
+                dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1));
+    }
+
+    @Test
+    public void testDomainSelectionCsForTty() throws Exception {
+        setupForCallTest();
+
+        ImsManager imsManager = Mockito.mock(ImsManager.class);
+        doReturn(false).when(imsManager).isNonTtyOrTtyOnVolteEnabled();
+        replaceInstance(TelephonyConnectionService.class,
+                "mImsManager", mTestConnectionService, imsManager);
+
+        setupForDialForDomainSelection(mPhone0, DOMAIN_PS, true);
+
+        mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1,
+                createConnectionRequest(PHONE_ACCOUNT_HANDLE_1,
+                        TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1));
+
+        verify(mEmergencyStateTracker, times(1))
+                .startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+        verify(mDomainSelectionResolver, times(0))
+                .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
+        verify(mEmergencyCallDomainSelectionConnection, times(0))
+                .createEmergencyConnection(any(), any());
+
+        ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
+
+        verify(mPhone0).dial(anyString(), argsCaptor.capture(), any());
+        DialArgs dialArgs = argsCaptor.getValue();
+        assertNotNull("DialArgs param is null", dialArgs);
+        assertNotNull("intentExtras is null", dialArgs.intentExtras);
+        assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN));
+        assertEquals(DOMAIN_CS, dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1));
+    }
+
+    @Test
+    public void testDomainSelectionRedialCs() throws Exception {
+        setupForCallTest();
+
+        int preciseDisconnectCause = com.android.internal.telephony.CallFailCause.ERROR_UNSPECIFIED;
+        int disconnectCause = android.telephony.DisconnectCause.ERROR_UNSPECIFIED;
+        int selectedDomain = DOMAIN_CS;
+
+        TestTelephonyConnection c = setupForReDialForDomainSelection(
+                mPhone0, selectedDomain, preciseDisconnectCause, disconnectCause, true);
+
+        assertTrue(mTestConnectionService.maybeReselectDomain(c, preciseDisconnectCause, null));
+        verify(mEmergencyCallDomainSelectionConnection).reselectDomain(any());
+
+        ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
+
+        Connection nc = Mockito.mock(Connection.class);
+        doReturn(nc).when(mPhone0).dial(anyString(), any(), any());
+
+        verify(mPhone0).dial(anyString(), argsCaptor.capture(), any());
+        DialArgs dialArgs = argsCaptor.getValue();
+        assertNotNull("DialArgs param is null", dialArgs);
+        assertNotNull("intentExtras is null", dialArgs.intentExtras);
+        assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN));
+        assertEquals(selectedDomain,
+                dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1));
+    }
+
+    @Test
+    public void testDomainSelectionRedialPs() throws Exception {
+        setupForCallTest();
+
+        int preciseDisconnectCause = com.android.internal.telephony.CallFailCause.ERROR_UNSPECIFIED;
+        int disconnectCause = android.telephony.DisconnectCause.ERROR_UNSPECIFIED;
+        int selectedDomain = DOMAIN_PS;
+
+        TestTelephonyConnection c = setupForReDialForDomainSelection(
+                mPhone0, selectedDomain, preciseDisconnectCause, disconnectCause, true);
+
+        assertTrue(mTestConnectionService.maybeReselectDomain(c, preciseDisconnectCause, null));
+        verify(mEmergencyCallDomainSelectionConnection).reselectDomain(any());
+
+        ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
+
+        Connection nc = Mockito.mock(Connection.class);
+        doReturn(nc).when(mPhone0).dial(anyString(), any(), any());
+
+        verify(mPhone0).dial(anyString(), argsCaptor.capture(), any());
+        DialArgs dialArgs = argsCaptor.getValue();
+        assertNotNull("DialArgs param is null", dialArgs);
+        assertNotNull("intentExtras is null", dialArgs.intentExtras);
+        assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN));
+        assertEquals(selectedDomain,
+                dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1));
+    }
+
+    @Test
+    public void testDomainSelectionNormalToEmergencyCs() throws Exception {
+        setupForCallTest();
+
+        int preciseDisconnectCause = com.android.internal.telephony.CallFailCause.ERROR_UNSPECIFIED;
+        int disconnectCause = android.telephony.DisconnectCause.ERROR_UNSPECIFIED;
+        int eccCategory = EMERGENCY_SERVICE_CATEGORY_POLICE;
+        int selectedDomain = DOMAIN_CS;
+
+        setupForDialForDomainSelection(mPhone0, selectedDomain, true);
+
+        TestTelephonyConnection c = setupForReDialForDomainSelection(
+                mPhone0, selectedDomain, preciseDisconnectCause, disconnectCause, false);
+        c.setEmergencyServiceCategory(eccCategory);
+        c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED);
+
+        ImsReasonInfo reasonInfo = new ImsReasonInfo(CODE_SIP_ALTERNATE_EMERGENCY_CALL, 0, null);
+        assertTrue(mTestConnectionService.maybeReselectDomain(c,
+                  preciseDisconnectCause, reasonInfo));
+
+        verify(mDomainSelectionResolver)
+                .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
+        verify(mEmergencyStateTracker)
+                .startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+        verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
+
+        ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
+
+        verify(mPhone0).dial(anyString(), argsCaptor.capture(), any());
+        DialArgs dialArgs = argsCaptor.getValue();
+        assertNotNull("DialArgs param is null", dialArgs);
+        assertNotNull("intentExtras is null", dialArgs.intentExtras);
+        assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN));
+        assertEquals(selectedDomain,
+                dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1));
+        assertTrue(dialArgs.isEmergency);
+        assertEquals(eccCategory, dialArgs.eccCategory);
+    }
+
+    @Test
+    public void testDomainSelectionNormalToEmergencyPs() throws Exception {
+        setupForCallTest();
+
+        int preciseDisconnectCause = com.android.internal.telephony.CallFailCause.ERROR_UNSPECIFIED;
+        int disconnectCause = android.telephony.DisconnectCause.ERROR_UNSPECIFIED;
+        int eccCategory = EMERGENCY_SERVICE_CATEGORY_POLICE;
+        int selectedDomain = DOMAIN_PS;
+
+        setupForDialForDomainSelection(mPhone0, selectedDomain, true);
+
+        TestTelephonyConnection c = setupForReDialForDomainSelection(
+                mPhone0, selectedDomain, preciseDisconnectCause, disconnectCause, false);
+        c.setEmergencyServiceCategory(eccCategory);
+        c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED);
+
+        ImsReasonInfo reasonInfo = new ImsReasonInfo(CODE_SIP_ALTERNATE_EMERGENCY_CALL, 0, null);
+        assertTrue(mTestConnectionService.maybeReselectDomain(c,
+                  preciseDisconnectCause, reasonInfo));
+
+        verify(mDomainSelectionResolver)
+                .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
+        verify(mEmergencyStateTracker)
+                .startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+        verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
+
+        ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
+
+        verify(mPhone0).dial(anyString(), argsCaptor.capture(), any());
+        DialArgs dialArgs = argsCaptor.getValue();
+        assertNotNull("DialArgs param is null", dialArgs);
+        assertNotNull("intentExtras is null", dialArgs.intentExtras);
+        assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN));
+        assertEquals(selectedDomain,
+                dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1));
+        assertTrue(dialArgs.isEmergency);
+        assertEquals(eccCategory, dialArgs.eccCategory);
+    }
+
+    private void setupForDialForDomainSelection(Phone mockPhone, int domain, boolean isEmergency) {
+        if (isEmergency) {
+            doReturn(mEmergencyCallDomainSelectionConnection).when(mDomainSelectionResolver)
+                    .getDomainSelectionConnection(any(), anyInt(), eq(true));
+            doReturn(CompletableFuture.completedFuture(domain))
+                    .when(mEmergencyCallDomainSelectionConnection)
+                    .createEmergencyConnection(any(), any());
+            doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(anyString());
+        }
+
+        doReturn(true).when(mDomainSelectionResolver).isDomainSelectionSupported();
+        doReturn(mImsPhone).when(mockPhone).getImsPhone();
+    }
+
+    private TestTelephonyConnection setupForReDialForDomainSelection(
+            Phone mockPhone, int domain, int preciseDisconnectCause,
+            int disconnectCause, boolean fromEmergency) throws Exception {
+        try {
+            if (fromEmergency) {
+                doReturn(CompletableFuture.completedFuture(domain))
+                        .when(mEmergencyCallDomainSelectionConnection)
+                        .reselectDomain(any());
+                replaceInstance(TelephonyConnectionService.class,
+                        "mEmergencyCallDomainSelectionConnection",
+                        mTestConnectionService, mEmergencyCallDomainSelectionConnection);
+                replaceInstance(TelephonyConnectionService.class, "mEmergencyCallId",
+                        mTestConnectionService, TELECOM_CALL_ID1);
+            }
+        } catch (Exception e) {
+            // This shouldn't happen
+            fail();
+        }
+
+        doReturn(true).when(mDomainSelectionResolver).isDomainSelectionSupported();
+
+        TestTelephonyConnection c = new TestTelephonyConnection();
+        c.setTelecomCallId(TELECOM_CALL_ID1);
+        c.setMockPhone(mockPhone);
+        c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED);
+
+        Connection oc = c.getOriginalConnection();
+        doReturn(disconnectCause).when(oc).getDisconnectCause();
+        doReturn(preciseDisconnectCause).when(oc).getPreciseDisconnectCause();
+
+        return c;
+    }
+
     private SimpleTelephonyConnection createTestConnection(PhoneAccountHandle handle,
             int properties, boolean isEmergency) {
         SimpleTelephonyConnection connection = new SimpleTelephonyConnection();
@@ -1760,4 +1854,18 @@
             fail();
         }
     }
+
+    private ConnectionRequest createConnectionRequest(
+            PhoneAccountHandle accountHandle, String address, String callId) {
+        return new ConnectionRequest.Builder()
+                .setAccountHandle(accountHandle)
+                .setAddress(Uri.parse("tel:" + address))
+                .setExtras(new Bundle())
+                .setTelecomCallId(callId)
+                .build();
+    }
+
+    private Executor getExecutor() {
+        return Runnable::run;
+    }
 }
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionTest.java
index c996e5f..3c309ba 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionTest.java
@@ -1,5 +1,7 @@
 package com.android.services.telephony;
 
+import static android.telecom.Connection.STATE_DISCONNECTED;
+
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertNull;
@@ -7,6 +9,9 @@
 import static junit.framework.Assert.fail;
 import static junit.framework.TestCase.assertFalse;
 
+import static org.junit.Assert.assertNotEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
@@ -26,7 +31,6 @@
 import com.android.internal.telephony.d2d.DtmfTransport;
 import com.android.internal.telephony.d2d.RtpTransport;
 import com.android.internal.telephony.imsphone.ImsPhoneConnection;
-import com.android.phone.PhoneGlobals;
 import com.android.phone.R;
 
 import org.junit.Before;
@@ -39,6 +43,8 @@
 public class TelephonyConnectionTest {
     @Mock
     private ImsPhoneConnection mImsPhoneConnection;
+    @Mock
+    private TelephonyConnectionService mTelephonyConnectionService;
 
     @Before
     public void setUp() throws Exception {
@@ -257,4 +263,44 @@
         assertTrue(c.isRttMergeSupported(c.getCarrierConfig()));
     }
 
+    @Test
+    public void testDomainSelectionDisconnected() {
+        TestTelephonyConnection c = new TestTelephonyConnection();
+        c.setOriginalConnection(mImsPhoneConnection);
+        doReturn(Call.State.DISCONNECTED).when(mImsPhoneConnection)
+                .getState();
+        c.setTelephonyConnectionService(mTelephonyConnectionService);
+        c.updateState();
+
+        verify(mTelephonyConnectionService)
+                .maybeReselectDomain(any(), anyInt(), any());
+    }
+
+    @Test
+    public void testDomainSelectionDisconnected_NoRedial() {
+        TestTelephonyConnection c = new TestTelephonyConnection();
+        c.setOriginalConnection(mImsPhoneConnection);
+        doReturn(Call.State.DISCONNECTED).when(mImsPhoneConnection)
+                .getState();
+        c.setTelephonyConnectionService(mTelephonyConnectionService);
+        doReturn(false).when(mTelephonyConnectionService)
+                .maybeReselectDomain(any(), anyInt(), any());
+        c.updateState();
+
+        assertEquals(STATE_DISCONNECTED, c.getState());
+    }
+
+    @Test
+    public void testDomainSelectionDisconnected_Redial() {
+        TestTelephonyConnection c = new TestTelephonyConnection();
+        c.setOriginalConnection(mImsPhoneConnection);
+        doReturn(Call.State.DISCONNECTED).when(mImsPhoneConnection)
+                .getState();
+        c.setTelephonyConnectionService(mTelephonyConnectionService);
+        doReturn(true).when(mTelephonyConnectionService)
+                .maybeReselectDomain(any(), anyInt(), any());
+        c.updateState();
+
+        assertNotEquals(STATE_DISCONNECTED, c.getState());
+    }
 }
