diff --git a/src/com/android/services/telephony/domainselection/NormalCallDomainSelector.java b/src/com/android/services/telephony/domainselection/NormalCallDomainSelector.java
new file mode 100644
index 0000000..82057d3
--- /dev/null
+++ b/src/com/android/services/telephony/domainselection/NormalCallDomainSelector.java
@@ -0,0 +1,299 @@
+/*
+ * Copyright (C) 2022 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.services.telephony.domainselection;
+
+import static android.telephony.DomainSelectionService.SELECTOR_TYPE_CALLING;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.os.Looper;
+import android.telephony.Annotation.DisconnectCauses;
+import android.telephony.DisconnectCause;
+import android.telephony.DomainSelectionService.SelectionAttributes;
+import android.telephony.NetworkRegistrationInfo;
+import android.telephony.ServiceState;
+import android.telephony.SubscriptionManager;
+import android.telephony.TransportSelectorCallback;
+import android.telephony.ims.ImsReasonInfo;
+
+/**
+ * Implements domain selector for outgoing non-emergency calls.
+ */
+public class NormalCallDomainSelector extends DomainSelectorBase implements
+        ImsStateTracker.ImsStateListener, ImsStateTracker.ServiceStateListener {
+
+    private static final String LOG_TAG = "NCDS";
+
+    private boolean mStopDomainSelection = true;
+    private ServiceState mServiceState;
+    private boolean mImsRegStateReceived;
+    private boolean mMmTelCapabilitiesReceived;
+    private boolean mReselectDomain;
+
+    public NormalCallDomainSelector(Context context, int slotId, int subId, @NonNull Looper looper,
+                                    @NonNull ImsStateTracker imsStateTracker,
+                                    @NonNull DestroyListener destroyListener) {
+        super(context, slotId, subId, looper, imsStateTracker, destroyListener, LOG_TAG);
+
+        if (SubscriptionManager.isValidSubscriptionId(subId)) {
+            logd("Subscribing to state callbacks. Subid:" + subId);
+            mImsStateTracker.addServiceStateListener(this);
+            mImsStateTracker.addImsStateListener(this);
+        } else {
+            loge("Invalid Subscription. Subid:" + subId);
+        }
+    }
+
+    @Override
+    public void selectDomain(SelectionAttributes attributes, TransportSelectorCallback callback) {
+        mSelectionAttributes = attributes;
+        mTransportSelectorCallback = callback;
+        mStopDomainSelection = false;
+
+        if (callback == null) {
+            loge("Invalid params: TransportSelectorCallback is null");
+            return;
+        }
+
+        if (attributes == null) {
+            loge("Invalid params: SelectionAttributes are null");
+            notifySelectionTerminated(DisconnectCause.OUTGOING_FAILURE);
+            return;
+        }
+
+        int subId = attributes.getSubId();
+        boolean validSubscriptionId = SubscriptionManager.isValidSubscriptionId(subId);
+        if (attributes.getSelectorType() != SELECTOR_TYPE_CALLING || attributes.isEmergency()
+                || !validSubscriptionId) {
+            loge("Domain Selection stopped. SelectorType:" + attributes.getSelectorType()
+                    + ", isEmergency:" + attributes.isEmergency()
+                    + ", ValidSubscriptionId:" + validSubscriptionId);
+
+            notifySelectionTerminated(DisconnectCause.OUTGOING_FAILURE);
+            return;
+        }
+
+        if (subId == getSubId()) {
+            logd("NormalCallDomainSelection triggered. Sub-id:" + subId);
+            post(() -> selectDomain());
+        } else {
+            loge("Subscription-ids doesn't match. This instance is associated with sub-id:"
+                    + getSubId() + ", requested sub-id:" + subId);
+            // TODO: Throw anamoly here. This condition should never occur.
+        }
+    }
+
+    @Override
+    public void reselectDomain(SelectionAttributes attributes) {
+        logd("reselectDomain called");
+        mReselectDomain = true;
+        selectDomain(attributes, mTransportSelectorCallback);
+    }
+
+    @Override
+    public synchronized void finishSelection() {
+        logd("finishSelection");
+        mStopDomainSelection = true;
+        mImsStateTracker.removeServiceStateListener(this);
+        mImsStateTracker.removeImsStateListener(this);
+        mSelectionAttributes = null;
+        mTransportSelectorCallback = null;
+    }
+
+    /**
+     * 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;
+        mReselectDomain = false;
+        if (mTransportSelectorCallback != null) {
+            mTransportSelectorCallback.onSelectionTerminated(DisconnectCause.OUTGOING_CANCELED);
+        }
+        finishSelection();
+    }
+
+    @Override
+    public void onImsRegistrationStateChanged() {
+        logd("onImsRegistrationStateChanged");
+        mImsRegStateReceived = true;
+        selectDomain();
+    }
+
+    @Override
+    public void onImsMmTelCapabilitiesChanged() {
+        logd("onImsMmTelCapabilitiesChanged");
+        mMmTelCapabilitiesReceived = true;
+        selectDomain();
+    }
+
+    @Override
+    public void onImsMmTelFeatureAvailableChanged() {
+        logd("onImsMmTelFeatureAvailableChanged");
+        selectDomain();
+    }
+
+    @Override
+    public void onServiceStateUpdated(ServiceState serviceState) {
+        logd("onServiceStateUpdated");
+        mServiceState = serviceState;
+        selectDomain();
+    }
+
+    private void notifyPsSelected() {
+        logd("notifyPsSelected");
+        mStopDomainSelection = true;
+        if (mImsStateTracker.isImsRegisteredOverWlan()) {
+            logd("WLAN selected");
+            mTransportSelectorCallback.onWlanSelected();
+        } else {
+            if (mWwanSelectorCallback == null) {
+                mTransportSelectorCallback.onWwanSelected((callback) -> {
+                    mWwanSelectorCallback = callback;
+                    notifyPsSelectedInternal();
+                });
+            } else {
+                notifyPsSelectedInternal();
+            }
+        }
+    }
+
+    private void notifyPsSelectedInternal() {
+        if (mWwanSelectorCallback != null) {
+            logd("notifyPsSelected - onWwanSelected");
+            mWwanSelectorCallback.onDomainSelected(NetworkRegistrationInfo.DOMAIN_PS);
+        } else {
+            loge("wwanSelectorCallback is null");
+            mTransportSelectorCallback.onSelectionTerminated(DisconnectCause.OUTGOING_FAILURE);
+        }
+    }
+
+    private void notifyCsSelected() {
+        logd("notifyCsSelected");
+        mStopDomainSelection = true;
+        if (mWwanSelectorCallback == null) {
+            mTransportSelectorCallback.onWwanSelected((callback) -> {
+                mWwanSelectorCallback = callback;
+                notifyCsSelectedInternal();
+            });
+        } else {
+            notifyCsSelectedInternal();
+        }
+    }
+
+    private void notifyCsSelectedInternal() {
+        if (mWwanSelectorCallback != null) {
+            logd("wwanSelectorCallback -> onDomainSelected(DOMAIN_CS)");
+            mWwanSelectorCallback.onDomainSelected(NetworkRegistrationInfo.DOMAIN_CS);
+        } else {
+            loge("wwanSelectorCallback is null");
+            mTransportSelectorCallback.onSelectionTerminated(DisconnectCause.OUTGOING_FAILURE);
+        }
+    }
+
+    private void notifySelectionTerminated(@DisconnectCauses int cause) {
+        mStopDomainSelection = true;
+        if (mTransportSelectorCallback != null) {
+            mTransportSelectorCallback.onSelectionTerminated(cause);
+            finishSelection();
+        }
+    }
+
+    private synchronized void selectDomain() {
+        if (mStopDomainSelection || mSelectionAttributes == null
+                || mTransportSelectorCallback == null) {
+            logd("Domain Selection is stopped.");
+            return;
+        }
+
+        if (mServiceState == null) {
+            logd("Waiting for ServiceState callback.");
+            return;
+        } else if (mServiceState.getState() == ServiceState.STATE_OUT_OF_SERVICE
+                || mServiceState.getState() == ServiceState.STATE_POWER_OFF
+                || mServiceState.getState() == ServiceState.STATE_EMERGENCY_ONLY) {
+            loge("Cannot place call in current ServiceState: " + mServiceState.getState());
+            notifySelectionTerminated(DisconnectCause.OUT_OF_SERVICE);
+            return;
+        }
+
+        // Check if this is a re-dial scenario
+        // IMS -> CS
+        ImsReasonInfo imsReasonInfo = mSelectionAttributes.getPsDisconnectCause();
+        if (mReselectDomain && imsReasonInfo != null) {
+            logd("PsDisconnectCause:" + imsReasonInfo.mCode);
+            mReselectDomain = false;
+            if (imsReasonInfo.mCode == ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED) {
+                logd("Redialing over CS");
+                notifyCsSelected();
+                return;
+            } else {
+                logd("Redialing cancelled.");
+                // Not a valid redial
+                notifySelectionTerminated(DisconnectCause.NOT_VALID);
+                return;
+            }
+        }
+
+        // CS -> IMS
+        // TODO: @PreciseDisconnectCauses doesn't contain cause code related to redial on IMS.
+        if (mReselectDomain /*mSelectionAttributes.getCsDisconnectCause() == IMS_REDIAL_CODE*/) {
+            logd("Redialing cancelled.");
+            // Not a valid redial
+            notifySelectionTerminated(DisconnectCause.NOT_VALID);
+            return;
+        }
+
+        if (mImsStateTracker.isMmTelFeatureAvailable()) {
+
+            if (!mImsRegStateReceived || !mMmTelCapabilitiesReceived) {
+                loge("Waiting for ImsState and MmTelCapabilities callbacks");
+                return;
+            }
+
+            if (!mImsStateTracker.isImsRegistered()) {
+                logd("IMS is NOT registered");
+                notifyCsSelected();
+                return;
+            }
+
+            if (mSelectionAttributes.isVideoCall()) {
+                logd("It's a video call");
+                if (mImsStateTracker.isImsVideoCapable()) {
+                    logd("IMS is video capable");
+                    notifyPsSelected();
+                } else {
+                    logd("IMS is not video capable. Ending the call");
+                    notifySelectionTerminated(DisconnectCause.OUTGOING_FAILURE);
+                }
+            } else if (mImsStateTracker.isImsVoiceCapable()) {
+                logd("IMS is voice capable");
+                // Voice call over PS
+                notifyPsSelected();
+            } else {
+                logd("IMS is not voice capable");
+                // Voice call CS fallback
+                notifyCsSelected();
+            }
+        } else {
+            logd("IMS is not registered or unavailable");
+            notifyCsSelected();
+        }
+    }
+}
diff --git a/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionService.java b/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionService.java
index 6f47ee6..13db06b 100644
--- a/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionService.java
+++ b/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionService.java
@@ -91,9 +91,8 @@
                         selector = new EmergencyCallDomainSelector(context, slotId, subId, looper,
                                 imsStateTracker, listener);
                     } else {
-                        // TODO(ag/20024470) uncomment when normal call domain selector is ready.
-                        /*selector = new NormalCallDomainSelector(context, slotId, subId, looper,
-                                imsStateTracker, listener);*/
+                        selector = new NormalCallDomainSelector(context, slotId, subId, looper,
+                                imsStateTracker, listener);
                     }
                     break;
                 case SELECTOR_TYPE_SMS:
diff --git a/tests/src/com/android/services/telephony/domainselection/NormalCallDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/NormalCallDomainSelectorTest.java
new file mode 100644
index 0000000..832e480
--- /dev/null
+++ b/tests/src/com/android/services/telephony/domainselection/NormalCallDomainSelectorTest.java
@@ -0,0 +1,408 @@
+/*
+ * Copyright (C) 2022 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.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;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.os.CancellationSignal;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.telephony.AccessNetworkConstants;
+import android.telephony.DisconnectCause;
+import android.telephony.DomainSelectionService;
+import android.telephony.DomainSelector;
+import android.telephony.EmergencyRegResult;
+import android.telephony.NetworkRegistrationInfo;
+import android.telephony.ServiceState;
+import android.telephony.SubscriptionManager;
+import android.telephony.TransportSelectorCallback;
+import android.telephony.WwanSelectorCallback;
+import android.telephony.ims.ImsManager;
+import android.telephony.ims.ImsMmTelManager;
+import android.telephony.ims.ImsReasonInfo;
+import android.util.Log;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.List;
+import java.util.concurrent.Executors;
+import java.util.function.Consumer;
+
+/**
+ * Unit tests for DomainSelectorBase.
+ */
+@RunWith(AndroidJUnit4.class)
+public class NormalCallDomainSelectorTest {
+    private static final String TAG = "NormalCallDomainSelectorTest";
+
+    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 HandlerThread mHandlerThread;
+    private NormalCallDomainSelector mNormalCallDomainSelector;
+
+    @Mock private Context mMockContext;
+    @Mock private ImsManager mMockImsManager;
+    @Mock private ImsMmTelManager mMockMmTelManager;
+    @Mock private ServiceState mMockServiceState;
+    @Mock private ImsStateTracker mMockImsStateTracker;
+    @Mock private DomainSelectorBase.DestroyListener mMockDestroyListener;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        doReturn(Context.TELEPHONY_IMS_SERVICE).when(mMockContext)
+                .getSystemServiceName(ImsManager.class);
+        doReturn(mMockImsManager).when(mMockContext)
+                .getSystemService(Context.TELEPHONY_IMS_SERVICE);
+        doReturn(mMockMmTelManager).when(mMockImsManager).getImsMmTelManager(SUB_ID_1);
+        doReturn(mMockMmTelManager).when(mMockImsManager).getImsMmTelManager(SUB_ID_2);
+        doNothing().when(mMockImsStateTracker).removeServiceStateListener(any());
+        doNothing().when(mMockImsStateTracker).removeImsStateListener(any());
+        doReturn(true).when(mMockImsStateTracker).isMmTelFeatureAvailable();
+
+        // Set up the looper if it does not exist on the test thread.
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+
+        mHandlerThread = new HandlerThread(
+                NormalCallDomainSelectorTest.class.getSimpleName());
+        mHandlerThread.start();
+
+        mNormalCallDomainSelector = new NormalCallDomainSelector(mMockContext, SLOT_ID, SUB_ID_1,
+                mHandlerThread.getLooper(), mMockImsStateTracker, mMockDestroyListener);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        if (mHandlerThread != null) {
+            mHandlerThread.quit();
+        }
+    }
+
+    private void initialize(ServiceState serviceState, boolean isImsRegistered,
+                            boolean isImsRegisteredOverWlan, boolean isImsVoiceCapable,
+                            boolean isImsVideoCapable) {
+        if (serviceState != null) mNormalCallDomainSelector.onServiceStateUpdated(serviceState);
+        doReturn(isImsRegistered).when(mMockImsStateTracker).isImsStateReady();
+        doReturn(isImsRegistered).when(mMockImsStateTracker).isImsRegistered();
+        doReturn(isImsVoiceCapable).when(mMockImsStateTracker).isImsVoiceCapable();
+        doReturn(isImsVideoCapable).when(mMockImsStateTracker).isImsVideoCapable();
+        doReturn(isImsRegisteredOverWlan).when(mMockImsStateTracker).isImsRegisteredOverWlan();
+        mNormalCallDomainSelector.onImsRegistrationStateChanged();
+        mNormalCallDomainSelector.onImsMmTelCapabilitiesChanged();
+    }
+
+    @Test
+    public void testInit() {
+        assertEquals(SLOT_ID, mNormalCallDomainSelector.getSlotId());
+        assertEquals(SUB_ID_1, mNormalCallDomainSelector.getSubId());
+    }
+
+    @Test
+    public void testSelectDomainInputParams() {
+        MockTransportSelectorCallback transportSelectorCallback =
+                new MockTransportSelectorCallback();
+
+        DomainSelectionService.SelectionAttributes attributes =
+                new DomainSelectionService.SelectionAttributes.Builder(
+                        SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING)
+                        .setCallId(TEST_CALLID)
+                        .setEmergency(false)
+                        .setVideoCall(true)
+                        .setExitedFromAirplaneMode(false)
+                        .build();
+        mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
+
+
+        // Case 1: null inputs
+        try {
+            mNormalCallDomainSelector.selectDomain(null, null);
+        } catch (Exception e) {
+            fail("Invalid input params not handled.");
+        }
+
+        // Case 2: null TransportSelectorCallback
+        try {
+            mNormalCallDomainSelector.selectDomain(attributes, null);
+        } catch (Exception e) {
+            fail("Invalid params (SelectionAttributes) not handled.");
+        }
+
+        // Case 3: null SelectionAttributes
+        transportSelectorCallback.mSelectionTerminated = false;
+        try {
+            mNormalCallDomainSelector.selectDomain(null, transportSelectorCallback);
+        } catch (Exception e) {
+            fail("Invalid params (SelectionAttributes) not handled.");
+        }
+
+        assertTrue(transportSelectorCallback
+                .verifyOnSelectionTerminated(DisconnectCause.OUTGOING_FAILURE));
+
+        // Case 4: Invalid Subscription-id
+        attributes = new DomainSelectionService.SelectionAttributes.Builder(
+                SLOT_ID, SubscriptionManager.INVALID_SUBSCRIPTION_ID, SELECTOR_TYPE_CALLING)
+                .setCallId(TEST_CALLID)
+                .setEmergency(false)
+                .setVideoCall(true)
+                .setExitedFromAirplaneMode(false)
+                .build();
+        try {
+            mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
+        } catch (Exception e) {
+            fail("Invalid params (SelectionAttributes) not handled.");
+        }
+
+        assertTrue(transportSelectorCallback
+                .verifyOnSelectionTerminated(DisconnectCause.OUTGOING_FAILURE));
+
+        // Case 5: Invalid SELECTOR_TYPE
+        attributes =
+                new DomainSelectionService.SelectionAttributes.Builder(
+                        SLOT_ID, SUB_ID_1, SELECTOR_TYPE_UT)
+                        .setCallId(TEST_CALLID)
+                        .setEmergency(false)
+                        .setVideoCall(true)
+                        .setExitedFromAirplaneMode(false)
+                        .build();
+        try {
+            mNormalCallDomainSelector.selectDomain(null, transportSelectorCallback);
+        } catch (Exception e) {
+            fail("Invalid params (SelectionAttributes) not handled.");
+        }
+
+        assertTrue(transportSelectorCallback
+                .verifyOnSelectionTerminated(DisconnectCause.OUTGOING_FAILURE));
+
+        // Case 6: Emergency Call
+        attributes = new DomainSelectionService.SelectionAttributes.Builder(
+                SLOT_ID, SUB_ID_1, SELECTOR_TYPE_UT)
+                .setCallId(TEST_CALLID)
+                .setEmergency(true)
+                .setVideoCall(true)
+                .setExitedFromAirplaneMode(false)
+                .build();
+        try {
+            mNormalCallDomainSelector.selectDomain(null, transportSelectorCallback);
+        } catch (Exception e) {
+            fail("Invalid params (SelectionAttributes) not handled.");
+        }
+
+        assertTrue(transportSelectorCallback
+                .verifyOnSelectionTerminated(DisconnectCause.OUTGOING_FAILURE));
+    }
+
+    @Test
+    public void testOutOfService() {
+        MockTransportSelectorCallback transportSelectorCallback =
+                new MockTransportSelectorCallback();
+        DomainSelectionService.SelectionAttributes attributes =
+                new DomainSelectionService.SelectionAttributes.Builder(
+                        SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING)
+                        .setCallId(TEST_CALLID)
+                        .setEmergency(false)
+                        .setVideoCall(true)
+                        .setExitedFromAirplaneMode(false)
+                        .build();
+        mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
+        ServiceState serviceState = new ServiceState();
+        serviceState.setStateOutOfService();
+        mNormalCallDomainSelector.onServiceStateUpdated(serviceState);
+        assertTrue(transportSelectorCallback
+                .verifyOnSelectionTerminated(DisconnectCause.OUT_OF_SERVICE));
+    }
+
+    @Test
+    public void testDomainSelection() {
+        MockTransportSelectorCallback transportSelectorCallback =
+                new MockTransportSelectorCallback();
+        DomainSelectionService.SelectionAttributes attributes =
+                new DomainSelectionService.SelectionAttributes.Builder(
+                        SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING)
+                        .setCallId(TEST_CALLID)
+                        .setEmergency(false)
+                        .setVideoCall(false)
+                        .setExitedFromAirplaneMode(false)
+                        .build();
+
+        // Case 1: WLAN
+        ServiceState serviceState = new ServiceState();
+        serviceState.setState(ServiceState.STATE_IN_SERVICE);
+        initialize(serviceState, true, true, true, true);
+        mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
+        assertTrue(transportSelectorCallback.verifyOnWlanSelected());
+
+        // Case 2: 5G
+        mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
+        initialize(serviceState, true, false, true, true);
+        mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
+        assertTrue(transportSelectorCallback.verifyOnWwanSelected());
+        assertTrue(transportSelectorCallback
+                .verifyOnDomainSelected(NetworkRegistrationInfo.DOMAIN_PS));
+
+        // Case 3: PS -> CS redial
+        ImsReasonInfo imsReasonInfo = new ImsReasonInfo();
+        imsReasonInfo.mCode = ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED;
+        attributes = new DomainSelectionService.SelectionAttributes.Builder(
+                SLOT_ID, SUB_ID_1, SELECTOR_TYPE_CALLING)
+                .setCallId(TEST_CALLID)
+                .setEmergency(false)
+                .setVideoCall(false)
+                .setExitedFromAirplaneMode(false)
+                .setPsDisconnectCause(imsReasonInfo)
+                .build();
+        mNormalCallDomainSelector.reselectDomain(attributes);
+        assertTrue(transportSelectorCallback
+                .verifyOnDomainSelected(NetworkRegistrationInfo.DOMAIN_CS));
+
+        // Case 4: CS call
+        NetworkRegistrationInfo nwRegistrationInfo = new NetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME,
+                AccessNetworkConstants.AccessNetworkType.UTRAN, 0, false,
+                null, null, null, false, 0, 0, 0);
+        serviceState.addNetworkRegistrationInfo(nwRegistrationInfo);
+        mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
+        initialize(serviceState, false, false, false, false);
+        mNormalCallDomainSelector.selectDomain(attributes, transportSelectorCallback);
+        assertTrue(transportSelectorCallback.verifyOnWwanSelected());
+        assertTrue(transportSelectorCallback
+                .verifyOnDomainSelected(NetworkRegistrationInfo.DOMAIN_CS));
+    }
+
+    class MockTransportSelectorCallback implements TransportSelectorCallback, WwanSelectorCallback {
+        public boolean mCreated = false;
+        public boolean mWlanSelected = false;
+        public boolean mWwanSelected = false;
+        public boolean mSelectionTerminated = false;
+        int mCauseCode = 0;
+        int mSelectedDomain = 0;
+
+        @Override
+        public synchronized void onCreated(DomainSelector selector) {
+            Log.d(TAG, "onCreated");
+            mCreated = true;
+            notifyAll();
+        }
+
+        public boolean verifyOnCreated() {
+            mCreated = false;
+            Log.d(TAG, "verifyOnCreated");
+            waitForCallback();
+            return mCreated;
+        }
+
+        @Override
+        public synchronized void onWlanSelected() {
+            Log.d(TAG, "onWlanSelected");
+            mWlanSelected = true;
+            notifyAll();
+        }
+
+        public boolean verifyOnWlanSelected() {
+            Log.d(TAG, "verifyOnWlanSelected");
+            waitForCallback();
+            return mWlanSelected;
+        }
+
+        @Override
+        public synchronized WwanSelectorCallback onWwanSelected() {
+            mWwanSelected = true;
+            notifyAll();
+            return (WwanSelectorCallback) this;
+        }
+
+        @Override
+        public void onWwanSelected(final Consumer<WwanSelectorCallback> consumer) {
+            mWwanSelected = true;
+            Executors.newSingleThreadExecutor().execute(() -> {
+                consumer.accept(this);
+            });
+        }
+
+        public boolean verifyOnWwanSelected() {
+            waitForCallback();
+            return mWwanSelected;
+        }
+
+        @Override
+        public synchronized void onSelectionTerminated(int cause) {
+            Log.i(TAG, "onSelectionTerminated - called");
+            mCauseCode = cause;
+            mSelectionTerminated = true;
+            notifyAll();
+        }
+
+        public boolean verifyOnSelectionTerminated(int cause) {
+            Log.i(TAG, "verifyOnSelectionTerminated - called");
+            if (!mSelectionTerminated) {
+                waitForCallback();
+            }
+            return (mSelectionTerminated && cause == mCauseCode);
+        }
+
+        private synchronized void waitForCallback() {
+            try {
+                wait(1000);
+            } catch (Exception e) {
+                return;
+            }
+        }
+
+        @Override
+        public void onRequestEmergencyNetworkScan(@NonNull List<Integer> preferredNetworks,
+                                                  int scanType,
+                                                  @NonNull CancellationSignal signal,
+                                                  @NonNull Consumer<EmergencyRegResult> consumer) {
+            Log.i(TAG, "onRequestEmergencyNetworkScan - called");
+
+        }
+
+        public synchronized void onDomainSelected(@NetworkRegistrationInfo.Domain int domain) {
+            Log.i(TAG, "onDomainSelected - called");
+            mSelectedDomain = domain;
+            notifyAll();
+        }
+
+        public boolean verifyOnDomainSelected(int domain) {
+            Log.i(TAG, "verifyOnDomainSelected - called");
+            waitForCallback();
+            return (domain == mSelectedDomain);
+        }
+    }
+}
