Wait for the disconnection of ePDN after VoNR fails

EmergencyCallDomainSelector waits for the disconnection of ePDN
before requesting network scan after VoNR fails.

Replace EmergencyCallbackModeHelper with DataConnectionStateHelper,
and make DataConnectionStateHelper inform the state of ePDN
to the EmergencyCallDomainSelector.

Bug: 330299585
Test: atest EmergencyCallDomainSelectorTest
Change-Id: I6df56793705252f577265a8062201b3e3d8009fe
diff --git a/src/com/android/services/telephony/domainselection/EmergencyCallbackModeHelper.java b/src/com/android/services/telephony/domainselection/DataConnectionStateHelper.java
similarity index 77%
rename from src/com/android/services/telephony/domainselection/EmergencyCallbackModeHelper.java
rename to src/com/android/services/telephony/domainselection/DataConnectionStateHelper.java
index cdf2225..8fbf7e3 100644
--- a/src/com/android/services/telephony/domainselection/EmergencyCallbackModeHelper.java
+++ b/src/com/android/services/telephony/domainselection/DataConnectionStateHelper.java
@@ -16,7 +16,6 @@
 
 package com.android.services.telephony.domainselection;
 
-import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_CALLBACK_MODE_SUPPORTED_BOOL;
 import static android.telephony.SubscriptionManager.EXTRA_SLOT_INDEX;
 import static android.telephony.SubscriptionManager.INVALID_SIM_SLOT_INDEX;
 import static android.telephony.TelephonyManager.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED;
@@ -29,11 +28,11 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
-import android.os.PersistableBundle;
 import android.os.SystemProperties;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.CarrierConfigManager;
 import android.telephony.PreciseDataConnectionState;
+import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyCallback;
 import android.telephony.TelephonyManager;
 import android.telephony.data.ApnSetting;
@@ -41,8 +40,8 @@
 import android.util.Log;
 
 /** Helper class to cache emergency data connection state. */
-public class EmergencyCallbackModeHelper extends Handler {
-    private static final String TAG = "EmergencyCallbackModeHelper";
+public class DataConnectionStateHelper extends Handler {
+    private static final String TAG = "DataConnectionStateHelper";
     private static final boolean DBG = (SystemProperties.getInt("ro.debuggable", 0) == 1);
 
     /**
@@ -53,14 +52,19 @@
 
         private final Handler mHandler;
         private final TelephonyManager mTelephonyManager;
+        private final DataConnectionStateHelper mOwner;
         private final int mSubId;
+        private final int mSlotIndex;
         private int mTransportType = AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
         private int mState = TelephonyManager.DATA_UNKNOWN;
 
-        DataConnectionStateListener(Handler handler, TelephonyManager tm, int subId) {
+        DataConnectionStateListener(Handler handler, TelephonyManager tm,
+                DataConnectionStateHelper owner, int subId, int slotIndex) {
             mHandler = handler;
             mTelephonyManager = tm;
+            mOwner = owner;
             mSubId = subId;
+            mSlotIndex = slotIndex;
         }
 
         @Override
@@ -73,16 +77,19 @@
             }
             mTransportType = dataConnectionState.getTransportType();
             mState = dataConnectionState.getState();
+            mOwner.notifyDataConnectionStateChange(mSlotIndex, mState);
             Log.i(TAG, "onPreciseDataConnectionStateChanged ePDN state=" + mState
-                    + ", transport=" + mTransportType);
+                    + ", transport=" + mTransportType + ", subId=" + mSubId);
         }
 
         public void registerTelephonyCallback() {
+            Log.i(TAG, "registerTelephonyCallback subId=" + mSubId);
             TelephonyManager tm = mTelephonyManager.createForSubscriptionId(mSubId);
             tm.registerTelephonyCallback(mHandler::post, this);
         }
 
         public void unregisterTelephonyCallback() {
+            Log.i(TAG, "unregisterTelephonyCallback subId=" + mSubId);
             mTelephonyManager.unregisterTelephonyCallback(this);
         }
 
@@ -110,13 +117,15 @@
             (slotIndex, subId, carrierId, specificCarrierId) -> onCarrierConfigChanged(
                     slotIndex, subId, carrierId);
 
+    private EmergencyCallDomainSelector mSelector;
+
     /**
      * Creates an instance.
      *
      * @param context The Context this is associated with.
-     * @param looper The Looper to run the EmergencyCallbackModeHelper.
+     * @param looper The Looper to run the DataConnectionStateHelper.
      */
-    public EmergencyCallbackModeHelper(@NonNull Context context, @NonNull Looper looper) {
+    public DataConnectionStateHelper(@NonNull Context context, @NonNull Looper looper) {
         super(looper);
 
         mContext = context;
@@ -133,10 +142,6 @@
      * @return true if it is in emergency callback mode.
      */
     public boolean isInEmergencyCallbackMode(int slotIndex) {
-        DataConnectionStateListener listener =
-                mDataConnectionStateListeners.get(Integer.valueOf(slotIndex));
-        if (listener == null) return false;
-
         Intent intent = mContext.registerReceiver(null,
                 new IntentFilter(ACTION_EMERGENCY_CALLBACK_MODE_CHANGED));
         if (intent != null
@@ -177,6 +182,24 @@
         return listener.getState();
     }
 
+    /**
+     * Sets the EmergencyCallDomainSelector instance.
+     *
+     * @param selector The instance of {@link EmergencyCallDomainSelector}.
+     */
+    public void setEmergencyCallDomainSelector(EmergencyCallDomainSelector selector) {
+        mSelector = selector;
+    }
+
+    private void notifyDataConnectionStateChange(int slotIndex, int state) {
+        EmergencyCallDomainSelector selector = mSelector;
+        if (selector != null) {
+            Log.i(TAG, "notifyDataConnectionStateChange slot=" + slotIndex + ", state=" + state);
+            selector.notifyDataConnectionStateChange(slotIndex, state);
+        }
+    }
+
+
     @Override
     public void handleMessage(Message msg) {
         switch(msg.what) {
@@ -194,35 +217,22 @@
             return;
         }
 
-        PersistableBundle b = mConfigManager.getConfigForSubId(subId,
-                KEY_EMERGENCY_CALLBACK_MODE_SUPPORTED_BOOL);
+        DataConnectionStateListener listener =
+                mDataConnectionStateListeners.get(Integer.valueOf(slotIndex));
 
-        if (b.getBoolean(KEY_EMERGENCY_CALLBACK_MODE_SUPPORTED_BOOL)) {
-            // ECBM supported
-            DataConnectionStateListener listener =
-                    mDataConnectionStateListeners.get(Integer.valueOf(slotIndex));
+        // Remove stale listener.
+        if (listener != null && listener.getSubId() != subId) {
+            listener.unregisterTelephonyCallback();
+            mDataConnectionStateListeners.remove(Integer.valueOf(slotIndex));
+            listener = null;
+        }
 
-            // Remove stale listener.
-            if (listener != null && listener.getSubId() != subId) {
-                listener.unregisterTelephonyCallback();
-                listener = null;
-            }
-
-            if (listener == null) {
-                listener = new DataConnectionStateListener(this, mTelephonyManager, subId);
-                listener.registerTelephonyCallback();
-                mDataConnectionStateListeners.put(Integer.valueOf(slotIndex), listener);
-                Log.i(TAG, "onCarrierConfigChanged register callback");
-            }
-        } else {
-            // ECBM not supported
-            DataConnectionStateListener listener =
-                    mDataConnectionStateListeners.get(Integer.valueOf(slotIndex));
-            if (listener != null) {
-                listener.unregisterTelephonyCallback();
-                mDataConnectionStateListeners.remove(Integer.valueOf(slotIndex));
-                Log.i(TAG, "onCarrierConfigChanged unregister callback");
-            }
+        if (listener == null
+                && SubscriptionManager.isValidSubscriptionId(subId)) {
+            listener = new DataConnectionStateListener(this, mTelephonyManager,
+                    this, subId, slotIndex);
+            listener.registerTelephonyCallback();
+            mDataConnectionStateListeners.put(Integer.valueOf(slotIndex), listener);
         }
     }
 
diff --git a/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java b/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
index 1161e50..a073397 100644
--- a/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
+++ b/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
@@ -58,6 +58,9 @@
 import static android.telephony.PreciseDisconnectCause.NO_VALID_SIM;
 import static android.telephony.PreciseDisconnectCause.SERVICE_OPTION_NOT_AVAILABLE;
 import static android.telephony.TelephonyManager.DATA_CONNECTED;
+import static android.telephony.TelephonyManager.DATA_DISCONNECTED;
+import static android.telephony.TelephonyManager.DATA_DISCONNECTING;
+import static android.telephony.TelephonyManager.DATA_UNKNOWN;
 
 import android.annotation.NonNull;
 import android.content.Context;
@@ -110,12 +113,20 @@
     private static final boolean DBG = (SystemProperties.getInt("ro.debuggable", 0) == 1);
     private static final int LOG_SIZE = 50;
 
+    /**
+     * Timeout before we requests network scan without waiting for the disconnection
+     * of ePDN.
+     */
+    private static final int DEFAULT_DATA_DISCONNECTION_TIMEOUT_MS = 2 * 1000; // 2 seconds
+
     private static final int MSG_START_DOMAIN_SELECTION = 11;
     @VisibleForTesting
     public static final int MSG_NETWORK_SCAN_TIMEOUT = 12;
     private static final int MSG_NETWORK_SCAN_RESULT = 13;
     @VisibleForTesting
     public static final int MSG_MAX_CELLULAR_TIMEOUT = 14;
+    @VisibleForTesting
+    public static final int MSG_WAIT_DISCONNECTION_TIMEOUT = 15;
 
     private static final int NOT_SUPPORTED = -1;
 
@@ -200,7 +211,8 @@
     private boolean mWiFiAvailable;
     private boolean mWasCsfbAfterPsFailure;
     private boolean mTryCsWhenPsFails;
-    private boolean mTryEpsFallback;
+    private boolean mTryEsFallback;
+    private boolean mIsWaitingForDataDisconnection;
     private int mModemCount;
 
     /** Indicates whether this instance is deactivated. */
@@ -222,14 +234,14 @@
 
     private final PowerManager.WakeLock mPartialWakeLock;
     private final CrossSimRedialingController mCrossSimRedialingController;
-    private final EmergencyCallbackModeHelper mEcbmHelper;
+    private final DataConnectionStateHelper mEpdnHelper;
 
     /** Constructor. */
     public EmergencyCallDomainSelector(Context context, int slotId, int subId,
             @NonNull Looper looper, @NonNull ImsStateTracker imsStateTracker,
             @NonNull DestroyListener destroyListener,
             @NonNull CrossSimRedialingController csrController,
-            @NonNull EmergencyCallbackModeHelper ecbmHelper) {
+            @NonNull DataConnectionStateHelper epdnHelper) {
         super(context, slotId, subId, looper, imsStateTracker, destroyListener, TAG);
 
         mImsStateTracker.addBarringInfoListener(this);
@@ -239,7 +251,8 @@
         mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
 
         mCrossSimRedialingController = csrController;
-        mEcbmHelper = ecbmHelper;
+        mEpdnHelper = epdnHelper;
+        epdnHelper.setEmergencyCallDomainSelector(this);
         acquireWakeLock();
     }
 
@@ -264,6 +277,10 @@
                 handleMaxCellularTimeout();
                 break;
 
+            case MSG_WAIT_DISCONNECTION_TIMEOUT:
+                requestScanDelayed();
+                break;
+
             default:
                 super.handleMessage(msg);
                 break;
@@ -400,6 +417,25 @@
             }
         }
 
+        if (mLastTransportType == TRANSPORT_TYPE_WWAN) {
+            if (mLastNetworkType == NGRAN && (!mTryEsFallback) && mLtePreferredAfterNrFailure) {
+                int state = mEpdnHelper.getDataConnectionState(getSlotId());
+                if (state != DATA_DISCONNECTED && state != DATA_UNKNOWN) {
+                    mIsWaitingForDataDisconnection = true;
+                    // If deactivation of ePDN has been started, then wait for the disconnection
+                    // with the timeout of 2 seconds and then request network scan.
+                    // If deactivation of ePDN hasn't been started yet, then wait for the start
+                    // of the deactivation with the timeout of 2 seconds.
+                    // The timer shall be restarted in notifyDataConnectionStateChange()
+                    // when starting the deactivation.
+                    sendEmptyMessageDelayed(MSG_WAIT_DISCONNECTION_TIMEOUT,
+                            DEFAULT_DATA_DISCONNECTION_TIMEOUT_MS);
+                    mDomainSelected = false;
+                    return;
+                }
+            }
+        }
+
         if (mLastTransportType == TRANSPORT_TYPE_WLAN) {
             // Dialing over Wi-Fi failed. Try scanning cellular networks.
             onWwanSelected(this::reselectDomainInternal);
@@ -460,6 +496,15 @@
         });
     }
 
+    private void requestScanDelayed() {
+        logi("requestScanDelayed waiting=" + mIsWaitingForDataDisconnection);
+        if (!mDestroyed && mIsWaitingForDataDisconnection) {
+            requestScan(true);
+            removeMessages(MSG_WAIT_DISCONNECTION_TIMEOUT);
+        }
+        mIsWaitingForDataDisconnection = false;
+    }
+
     @Override
     public void finishSelection() {
         logi("finishSelection");
@@ -800,7 +845,7 @@
                 onWwanNetworkTypeSelected(mCsNetworkType);
             }
         } else if (psAvailable) {
-            mTryEpsFallback = (mPsNetworkType == NGRAN) && isEpsFallbackAvailable();
+            mTryEsFallback = (mPsNetworkType == NGRAN) && isEsFallbackAvailable();
             if (mSelectionAttributes.isExitedFromAirplaneMode()
                     || !mRequiresImsRegistration || isImsRegisteredWithVoiceCapability()) {
                 onWwanNetworkTypeSelected(mPsNetworkType);
@@ -810,7 +855,7 @@
             } else {
                 // Carrier configuration requires IMS registration for emergency services over PS,
                 // but not registered. Try CS emergency call.
-                mTryEpsFallback = false;
+                mTryEsFallback = false;
                 requestScan(true, true);
             }
         } else if (csAvailable) {
@@ -823,7 +868,7 @@
                 // but not registered. Try CS emergency call.
                 requestScan(true, true);
             } else {
-                mTryEpsFallback = isEpsFallbackAvailable();
+                mTryEsFallback = isEsFallbackAvailable();
                 requestScan(true);
             }
         }
@@ -863,9 +908,9 @@
         mCancelSignal = new CancellationSignal();
         // In case dialing over Wi-Fi has failed, do not the change the domain preference.
         if (!wifiFailed || mLastPreferredNetworks == null) {
-            mLastPreferredNetworks = getNextPreferredNetworks(csPreferred, mTryEpsFallback);
+            mLastPreferredNetworks = getNextPreferredNetworks(csPreferred, mTryEsFallback);
         }
-        mTryEpsFallback = false;
+        mTryEsFallback = false;
 
         if (isInRoaming()
                 && (mPreferredNetworkScanType
@@ -901,12 +946,12 @@
      * Gets the list of preferred network type for the new scan request.
      *
      * @param csPreferred Indicates whether CS preferred scan is requested.
-     * @param tryEpsFallback Indicates whether scan requested for EPS fallback.
+     * @param tryEsFallback Indicates whether scan requested for ES fallback.
      * @return The list of preferred network types.
      */
     @VisibleForTesting
     public @RadioAccessNetworkType List<Integer> getNextPreferredNetworks(boolean csPreferred,
-            boolean tryEpsFallback) {
+            boolean tryEsFallback) {
         if (mRequiresVoLteEnabled && !isAdvancedCallingSettingEnabled()) {
             // Emergency call over IMS is not supported.
             logi("getNextPreferredNetworks VoLte setting is not enabled.");
@@ -919,10 +964,10 @@
         int psPriority = domains.indexOf(DOMAIN_PS_3GPP);
         int csPriority = domains.indexOf(DOMAIN_CS);
         logi("getNextPreferredNetworks psPriority=" + psPriority + ", csPriority=" + csPriority
-                + ", csPreferred=" + csPreferred + ", epsFallback=" + tryEpsFallback
+                + ", csPreferred=" + csPreferred + ", esFallback=" + tryEsFallback
                 + ", lastNetworkType=" + accessNetworkTypeToString(mLastNetworkType));
 
-        if (!csPreferred && (mLastNetworkType == UNKNOWN || tryEpsFallback)) {
+        if (!csPreferred && (mLastNetworkType == UNKNOWN || tryEsFallback)) {
             // Generate the list per the domain preference.
 
             if (psPriority == NOT_SUPPORTED && csPriority == NOT_SUPPORTED) {
@@ -946,7 +991,7 @@
             }
 
             // Make NGRAN have the lowest priority
-            if (tryEpsFallback && preferredNetworks.contains(NGRAN)) {
+            if (tryEsFallback && preferredNetworks.contains(NGRAN)) {
                 preferredNetworks.remove(Integer.valueOf(NGRAN));
                 preferredNetworks.add(NGRAN);
             }
@@ -1172,7 +1217,7 @@
         return UNKNOWN;
     }
 
-    private boolean isEpsFallbackAvailable() {
+    private boolean isEsFallbackAvailable() {
         EmergencyRegistrationResult regResult =
                 mSelectionAttributes.getEmergencyRegistrationResult();
         if (regResult == null) return false;
@@ -1603,9 +1648,25 @@
             // When reselecting domain, terminateSelection will be called.
             return;
         }
+        mIsWaitingForDataDisconnection = false;
+        removeMessages(MSG_WAIT_DISCONNECTION_TIMEOUT);
         terminateSelectionForCrossSimRedialing(false);
     }
 
+    /** Notifies the ePDN connection state changes. */
+    public void notifyDataConnectionStateChange(int slotId, int state) {
+        if (slotId == getSlotId() && mIsWaitingForDataDisconnection) {
+            if (state == DATA_DISCONNECTED || state == DATA_UNKNOWN) {
+                requestScanDelayed();
+            } else if (state == DATA_DISCONNECTING) {
+                logi("notifyDataConnectionStateChange deactivation starting, restart timer");
+                removeMessages(MSG_WAIT_DISCONNECTION_TIMEOUT);
+                sendEmptyMessageDelayed(MSG_WAIT_DISCONNECTION_TIMEOUT,
+                        DEFAULT_DATA_DISCONNECTION_TIMEOUT_MS);
+            }
+        }
+    }
+
     private void maybeModifyScanType(int selectedNetworkType) {
         if ((mPreferredNetworkScanType
                 != CarrierConfigManager.ImsEmergency.SCAN_TYPE_FULL_SERVICE)
@@ -1685,6 +1746,7 @@
     public void destroy() {
         if (DBG) logd("destroy");
 
+        mEpdnHelper.setEmergencyCallDomainSelector(null);
         mCrossSimRedialingController.stopTimer();
         releaseWakeLock();
 
@@ -1717,15 +1779,15 @@
     }
 
     private boolean isInEmergencyCallbackModeOnWlan() {
-        return mEcbmHelper.isInEmergencyCallbackMode(getSlotId())
-                && mEcbmHelper.getTransportType(getSlotId()) == TRANSPORT_TYPE_WLAN
-                && mEcbmHelper.getDataConnectionState(getSlotId()) == DATA_CONNECTED;
+        return mEpdnHelper.isInEmergencyCallbackMode(getSlotId())
+                && mEpdnHelper.getTransportType(getSlotId()) == TRANSPORT_TYPE_WLAN
+                && mEpdnHelper.getDataConnectionState(getSlotId()) == DATA_CONNECTED;
     }
 
     private boolean isInEmergencyCallbackModeOnPsWwan() {
-        return mEcbmHelper.isInEmergencyCallbackMode(getSlotId())
-                && mEcbmHelper.getTransportType(getSlotId()) == TRANSPORT_TYPE_WWAN
-                && mEcbmHelper.getDataConnectionState(getSlotId()) == DATA_CONNECTED;
+        return mEpdnHelper.isInEmergencyCallbackMode(getSlotId())
+                && mEpdnHelper.getTransportType(getSlotId()) == TRANSPORT_TYPE_WWAN
+                && mEpdnHelper.getDataConnectionState(getSlotId()) == DATA_CONNECTED;
     }
 
     @Override
diff --git a/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionService.java b/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionService.java
index 8f1a319..7e1a2e6 100644
--- a/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionService.java
+++ b/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionService.java
@@ -73,7 +73,7 @@
                 @NonNull ImsStateTracker imsStateTracker,
                 @NonNull DomainSelectorBase.DestroyListener listener,
                 @NonNull CrossSimRedialingController crossSimRedialingController,
-                @NonNull EmergencyCallbackModeHelper emergencyCallbackModeHelper);
+                @NonNull DataConnectionStateHelper dataConnectionStateHelper);
     }
 
     private static final class DefaultDomainSelectorFactory implements DomainSelectorFactory {
@@ -83,7 +83,7 @@
                 @NonNull ImsStateTracker imsStateTracker,
                 @NonNull DomainSelectorBase.DestroyListener listener,
                 @NonNull CrossSimRedialingController crossSimRedialingController,
-                @NonNull EmergencyCallbackModeHelper emergencyCallbackModeHelper) {
+                @NonNull DataConnectionStateHelper dataConnectionStateHelper) {
             DomainSelectorBase selector = null;
 
             logi("create-DomainSelector: slotId=" + slotId + ", subId=" + subId
@@ -95,7 +95,7 @@
                     if (isEmergency) {
                         selector = new EmergencyCallDomainSelector(context, slotId, subId, looper,
                                 imsStateTracker, listener, crossSimRedialingController,
-                                emergencyCallbackModeHelper);
+                                dataConnectionStateHelper);
                     } else {
                         selector = new NormalCallDomainSelector(context, slotId, subId, looper,
                                 imsStateTracker, listener);
@@ -199,7 +199,7 @@
     private final DomainSelectorFactory mDomainSelectorFactory;
     private Handler mServiceHandler;
     private CrossSimRedialingController mCrossSimRedialingController;
-    private EmergencyCallbackModeHelper mEmergencyCallbackModeHelper;
+    private DataConnectionStateHelper mDataConnectionStateHelper;
 
     /** Default constructor. */
     public TelephonyDomainSelectionService() {
@@ -210,9 +210,10 @@
     protected TelephonyDomainSelectionService(
             @NonNull ImsStateTrackerFactory imsStateTrackerFactory,
             @NonNull DomainSelectorFactory domainSelectorFactory,
-            @Nullable EmergencyCallbackModeHelper ecbmHelper) {
+            @Nullable DataConnectionStateHelper dataConnectionStateHelper) {
         mImsStateTrackerFactory = imsStateTrackerFactory;
         mDomainSelectorFactory = domainSelectorFactory;
+        mDataConnectionStateHelper = dataConnectionStateHelper;
     }
 
     @Override
@@ -237,8 +238,8 @@
         }
 
         mCrossSimRedialingController = new CrossSimRedialingController(mContext, getLooper());
-        if (mEmergencyCallbackModeHelper == null) {
-            mEmergencyCallbackModeHelper = new EmergencyCallbackModeHelper(mContext, getLooper());
+        if (mDataConnectionStateHelper == null) {
+            mDataConnectionStateHelper = new DataConnectionStateHelper(mContext, getLooper());
         }
 
         logi("TelephonyDomainSelectionService created");
@@ -283,9 +284,9 @@
             mCrossSimRedialingController = null;
         }
 
-        if (mEmergencyCallbackModeHelper != null) {
-            mEmergencyCallbackModeHelper.destroy();
-            mEmergencyCallbackModeHelper = null;
+        if (mDataConnectionStateHelper != null) {
+            mDataConnectionStateHelper.destroy();
+            mDataConnectionStateHelper = null;
         }
 
         if (mServiceHandler != null) {
@@ -310,7 +311,7 @@
         ImsStateTracker ist = getImsStateTracker(slotId);
         DomainSelectorBase selector = mDomainSelectorFactory.create(mContext, slotId, subId,
                 selectorType, isEmergency, getLooper(), ist, mDestroyListener,
-                mCrossSimRedialingController, mEmergencyCallbackModeHelper);
+                mCrossSimRedialingController, mDataConnectionStateHelper);
 
         if (selector != null) {
             // Ensures that ImsStateTracker is started before selecting the domain if not started
diff --git a/tests/src/com/android/services/telephony/domainselection/DataConnectionStateHelperTest.java b/tests/src/com/android/services/telephony/domainselection/DataConnectionStateHelperTest.java
new file mode 100644
index 0000000..8d950c2
--- /dev/null
+++ b/tests/src/com/android/services/telephony/domainselection/DataConnectionStateHelperTest.java
@@ -0,0 +1,376 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony.domainselection;
+
+import static android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.assertNotNull;
+
+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.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.LinkProperties;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.telephony.CarrierConfigManager;
+import android.telephony.PreciseDataConnectionState;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyCallback;
+import android.telephony.TelephonyManager;
+import android.telephony.data.ApnSetting;
+import android.testing.TestableLooper;
+import android.util.Log;
+
+import com.android.TestContext;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Unit tests for DataConnectionStateHelper
+ */
+public class DataConnectionStateHelperTest {
+    private static final String TAG = "DataConnectionStateHelperTest";
+
+    private static final int SLOT_0 = 0;
+    private static final int SLOT_1 = 1;
+    private static final int SUB_1 = 1;
+    private static final int SUB_2 = 2;
+
+    @Mock private TelephonyManager mTm1;
+    @Mock private TelephonyManager mTm2;
+    @Mock private EmergencyCallDomainSelector mDomainSelector;
+
+    private Context mContext;
+    private HandlerThread mHandlerThread;
+    private TestableLooper mLooper;
+    private DataConnectionStateHelper mEpdnHelper;
+    private CarrierConfigManager mCarrierConfigManager;
+    private TelephonyManager mTelephonyManager;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mContext = new TestContext() {
+            private Intent mIntent;
+
+            @Override
+            public String getSystemServiceName(Class<?> serviceClass) {
+                if (serviceClass == TelephonyManager.class) {
+                    return Context.TELEPHONY_SERVICE;
+                } else if (serviceClass == CarrierConfigManager.class) {
+                    return Context.CARRIER_CONFIG_SERVICE;
+                }
+                return super.getSystemServiceName(serviceClass);
+            }
+
+            @Override
+            public String getOpPackageName() {
+                return "";
+            }
+
+            @Override
+            public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
+                return mIntent;
+            }
+
+            @Override
+            public void sendStickyBroadcast(Intent intent) {
+                mIntent = intent;
+            }
+        };
+
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+
+        mHandlerThread = new HandlerThread("DataConnectionStateHelperTest");
+        mHandlerThread.start();
+
+        try {
+            mLooper = new TestableLooper(mHandlerThread.getLooper());
+        } catch (Exception e) {
+            logd("Unable to create looper from handler.");
+        }
+
+        mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
+        mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
+        doReturn(mTm1).when(mTelephonyManager).createForSubscriptionId(eq(SUB_1));
+        doReturn(mTm2).when(mTelephonyManager).createForSubscriptionId(eq(SUB_2));
+
+        mEpdnHelper = new DataConnectionStateHelper(mContext, mHandlerThread.getLooper());
+        mEpdnHelper.setEmergencyCallDomainSelector(mDomainSelector);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        if (mEpdnHelper != null) {
+            mEpdnHelper.destroy();
+            mEpdnHelper = null;
+        }
+
+        if (mLooper != null) {
+            mLooper.destroy();
+            mLooper = null;
+        }
+    }
+
+    @Test
+    public void testInit() throws Exception {
+        ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> callbackCaptor =
+                ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
+        ArgumentCaptor<Executor> executorCaptor = ArgumentCaptor.forClass(Executor.class);
+
+        verify(mCarrierConfigManager).registerCarrierConfigChangeListener(executorCaptor.capture(),
+                callbackCaptor.capture());
+        assertNotNull(executorCaptor.getValue());
+        assertNotNull(callbackCaptor.getValue());
+    }
+
+    @Test
+    public void testCarrierConfigChanged() throws Exception {
+        ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> callbackCaptor =
+                ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
+
+        verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
+                callbackCaptor.capture());
+
+        CarrierConfigManager.CarrierConfigChangeListener callback = callbackCaptor.getValue();
+
+        assertNotNull(callback);
+
+        callback.onCarrierConfigChanged(SLOT_0, SUB_1, 0, 0);
+
+        verify(mTelephonyManager).createForSubscriptionId(eq(SUB_1));
+
+        ArgumentCaptor<TelephonyCallback> telephonyCallbackCaptor1 =
+                ArgumentCaptor.forClass(TelephonyCallback.class);
+
+        // TelephonyCallback for SUB_1 registered
+        verify(mTm1).registerTelephonyCallback(any(), telephonyCallbackCaptor1.capture());
+
+        assertNotNull(telephonyCallbackCaptor1.getValue());
+
+        callback.onCarrierConfigChanged(SLOT_1, SUB_2, 0, 0);
+
+        verify(mTelephonyManager).createForSubscriptionId(eq(SUB_2));
+
+        ArgumentCaptor<TelephonyCallback> telephonyCallbackCaptor2 =
+                ArgumentCaptor.forClass(TelephonyCallback.class);
+
+        // TelephonyCallback for SUB_2 registered
+        verify(mTm2).registerTelephonyCallback(any(), telephonyCallbackCaptor2.capture());
+
+        assertNotNull(telephonyCallbackCaptor2.getValue());
+
+        verify(mTm1, never()).unregisterTelephonyCallback(any());
+        verify(mTm2, never()).unregisterTelephonyCallback(any());
+    }
+
+    @Test
+    public void testSubscriptionChangedOnTheSameSlot() throws Exception {
+        ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> callbackCaptor =
+                ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
+
+        verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
+                callbackCaptor.capture());
+
+        CarrierConfigManager.CarrierConfigChangeListener callback = callbackCaptor.getValue();
+
+        assertNotNull(callback);
+
+        callback.onCarrierConfigChanged(SLOT_0, SUB_1, 0, 0);
+
+        verify(mTelephonyManager).createForSubscriptionId(eq(SUB_1));
+
+        ArgumentCaptor<TelephonyCallback> telephonyCallbackCaptor1 =
+                ArgumentCaptor.forClass(TelephonyCallback.class);
+
+        // TelephonyCallback for SUB_1 registered
+        verify(mTm1).registerTelephonyCallback(any(), telephonyCallbackCaptor1.capture());
+
+        TelephonyCallback telephonyCallback1 = telephonyCallbackCaptor1.getValue();
+
+        assertNotNull(telephonyCallback1);
+
+        // Subscription changed
+        callback.onCarrierConfigChanged(SLOT_0, SUB_2, 0, 0);
+
+        // TelephonyCallback for SUB_1 unregistered
+        verify(mTelephonyManager).unregisterTelephonyCallback(eq(telephonyCallback1));
+
+        verify(mTelephonyManager).createForSubscriptionId(eq(SUB_2));
+
+        ArgumentCaptor<TelephonyCallback> telephonyCallbackCaptor2 =
+                ArgumentCaptor.forClass(TelephonyCallback.class);
+
+        // TelephonyCallback for SUB_2 registered
+        verify(mTm2).registerTelephonyCallback(any(), telephonyCallbackCaptor2.capture());
+
+        TelephonyCallback telephonyCallback2 = telephonyCallbackCaptor2.getValue();
+
+        assertNotNull(telephonyCallback2);
+    }
+
+    @Test
+    public void testDataConnectionStateChanged() throws Exception {
+        ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> callbackCaptor =
+                ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
+
+        verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
+                callbackCaptor.capture());
+
+        CarrierConfigManager.CarrierConfigChangeListener callback = callbackCaptor.getValue();
+
+        assertNotNull(callback);
+
+        callback.onCarrierConfigChanged(SLOT_0, SUB_1, 0, 0);
+
+        verify(mTelephonyManager).createForSubscriptionId(eq(SUB_1));
+
+        ArgumentCaptor<TelephonyCallback> telephonyCallbackCaptor1 =
+                ArgumentCaptor.forClass(TelephonyCallback.class);
+
+        // TelephonyCallback for SUB_1 registered
+        verify(mTm1).registerTelephonyCallback(any(), telephonyCallbackCaptor1.capture());
+
+        TelephonyCallback cb1 = telephonyCallbackCaptor1.getValue();
+
+        assertNotNull(cb1);
+        assertTrue(cb1 instanceof TelephonyCallback.PreciseDataConnectionStateListener);
+
+        callback.onCarrierConfigChanged(SLOT_1, SUB_2, 0, 0);
+
+        verify(mTelephonyManager).createForSubscriptionId(eq(SUB_2));
+
+        ArgumentCaptor<TelephonyCallback> telephonyCallbackCaptor2 =
+                ArgumentCaptor.forClass(TelephonyCallback.class);
+
+        // TelephonyCallback for SUB_2 registered
+        verify(mTm2).registerTelephonyCallback(any(), telephonyCallbackCaptor2.capture());
+
+        TelephonyCallback cb2 = telephonyCallbackCaptor2.getValue();
+
+        assertNotNull(cb2);
+        assertTrue(cb2 instanceof TelephonyCallback.PreciseDataConnectionStateListener);
+
+        TelephonyCallback.PreciseDataConnectionStateListener listener1 =
+                (TelephonyCallback.PreciseDataConnectionStateListener) cb1;
+        TelephonyCallback.PreciseDataConnectionStateListener listener2 =
+                (TelephonyCallback.PreciseDataConnectionStateListener) cb2;
+
+        PreciseDataConnectionState state = getPreciseDataConnectionState(
+                ApnSetting.TYPE_DEFAULT, TelephonyManager.DATA_CONNECTED);
+        listener1.onPreciseDataConnectionStateChanged(state);
+        listener2.onPreciseDataConnectionStateChanged(state);
+
+        verify(mDomainSelector, never()).notifyDataConnectionStateChange(anyInt(), anyInt());
+        verify(mDomainSelector, never()).notifyDataConnectionStateChange(anyInt(), anyInt());
+
+        state = getPreciseDataConnectionState(
+                ApnSetting.TYPE_EMERGENCY, TelephonyManager.DATA_CONNECTED);
+        listener1.onPreciseDataConnectionStateChanged(state);
+        listener2.onPreciseDataConnectionStateChanged(state);
+
+        verify(mDomainSelector, times(1)).notifyDataConnectionStateChange(
+                eq(SLOT_0), eq(TelephonyManager.DATA_CONNECTED));
+        verify(mDomainSelector, times(1)).notifyDataConnectionStateChange(
+                eq(SLOT_1), eq(TelephonyManager.DATA_CONNECTED));
+
+        state = getPreciseDataConnectionState(
+                ApnSetting.TYPE_EMERGENCY, TelephonyManager.DATA_DISCONNECTING);
+        listener1.onPreciseDataConnectionStateChanged(state);
+        listener2.onPreciseDataConnectionStateChanged(state);
+
+        verify(mDomainSelector, times(1)).notifyDataConnectionStateChange(
+                eq(SLOT_0), eq(TelephonyManager.DATA_DISCONNECTING));
+        verify(mDomainSelector, times(1)).notifyDataConnectionStateChange(
+                eq(SLOT_1), eq(TelephonyManager.DATA_DISCONNECTING));
+
+        state = getPreciseDataConnectionState(
+                ApnSetting.TYPE_EMERGENCY, TelephonyManager.DATA_DISCONNECTED);
+        listener1.onPreciseDataConnectionStateChanged(state);
+        listener2.onPreciseDataConnectionStateChanged(state);
+
+        verify(mDomainSelector, times(1)).notifyDataConnectionStateChange(
+                eq(SLOT_0), eq(TelephonyManager.DATA_DISCONNECTED));
+        verify(mDomainSelector, times(1)).notifyDataConnectionStateChange(
+                eq(SLOT_1), eq(TelephonyManager.DATA_DISCONNECTED));
+    }
+
+    @Test
+    public void testEmergencyCallbackModeEnter() throws Exception {
+        // Enter ECBM on slot 1
+        mContext.sendStickyBroadcast(getIntent(true, SLOT_1));
+
+        assertFalse(mEpdnHelper.isInEmergencyCallbackMode(SLOT_0));
+        assertTrue(mEpdnHelper.isInEmergencyCallbackMode(SLOT_1));
+    }
+
+    @Test
+    public void testEmergencyCallbackModeExit() throws Exception {
+        // Exit ECBM
+        mContext.sendStickyBroadcast(getIntent(false, SLOT_0));
+
+        assertFalse(mEpdnHelper.isInEmergencyCallbackMode(SLOT_0));
+    }
+
+    private static Intent getIntent(boolean inEcm, int slotIndex) {
+        Intent intent = new Intent(TelephonyManager.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
+        intent.putExtra(TelephonyManager.EXTRA_PHONE_IN_ECM_STATE, inEcm);
+        intent.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, slotIndex);
+        return intent;
+    }
+
+    private static PreciseDataConnectionState getPreciseDataConnectionState(
+            int apnType, int state) {
+        return new PreciseDataConnectionState.Builder()
+                .setTransportType(TRANSPORT_TYPE_WWAN)
+                .setId(1)
+                .setState(state)
+                .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
+                .setApnSetting(new ApnSetting.Builder()
+                        .setApnTypeBitmask(apnType)
+                        .setApnName("default")
+                        .setEntryName("default")
+                        .build())
+                .setLinkProperties(new LinkProperties())
+                .setFailCause(0)
+                .build();
+    }
+
+    private static void logd(String str) {
+        Log.d(TAG, str);
+    }
+}
diff --git a/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
index ef2b055..a1d4162 100644
--- a/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
@@ -59,10 +59,13 @@
 import static android.telephony.NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN;
 import static android.telephony.PreciseDisconnectCause.SERVICE_OPTION_NOT_AVAILABLE;
 import static android.telephony.TelephonyManager.DATA_CONNECTED;
+import static android.telephony.TelephonyManager.DATA_DISCONNECTED;
+import static android.telephony.TelephonyManager.DATA_DISCONNECTING;
 import static android.telephony.TelephonyManager.SIM_ACTIVATION_STATE_DEACTIVATED;
 
 import static com.android.services.telephony.domainselection.EmergencyCallDomainSelector.MSG_MAX_CELLULAR_TIMEOUT;
 import static com.android.services.telephony.domainselection.EmergencyCallDomainSelector.MSG_NETWORK_SCAN_TIMEOUT;
+import static com.android.services.telephony.domainselection.EmergencyCallDomainSelector.MSG_WAIT_DISCONNECTION_TIMEOUT;
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
@@ -157,7 +160,7 @@
     @Mock private DomainSelectorBase.DestroyListener mDestroyListener;
     @Mock private ProvisioningManager mProvisioningManager;
     @Mock private CrossSimRedialingController mCsrdCtrl;
-    @Mock private EmergencyCallbackModeHelper mEcbmHelper;
+    @Mock private DataConnectionStateHelper mEpdnHelper;
     @Mock private Resources mResources;
 
     private Context mContext;
@@ -307,6 +310,7 @@
         verify(mWwanSelectorCallback, times(0)).onRequestEmergencyNetworkScan(
                 any(), anyInt(), anyBoolean(), any(), any());
         verify(mWwanSelectorCallback, times(0)).onDomainSelected(anyInt(), eq(true));
+        verify(mEpdnHelper).setEmergencyCallDomainSelector(eq(mDomainSelector));
     }
 
     @Test
@@ -328,6 +332,7 @@
         unsolBarringInfoChanged(false);
 
         verify(mTransportSelectorCallback, never()).onWwanSelected(any());
+        verify(mEpdnHelper).setEmergencyCallDomainSelector(eq(null));
     }
 
     @Test
@@ -2922,12 +2927,51 @@
     }
 
     @Test
-    public void testScanLtePreferredAfterNgranFailure() throws Exception {
+    public void testScanLtePreferredAfterNgranFailureSupportEmf() throws Exception {
         PersistableBundle bundle = getDefaultPersistableBundle();
         bundle.putIntArray(KEY_EMERGENCY_OVER_IMS_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY,
                 new int[] { NGRAN, EUTRAN });
         bundle.putBoolean(KEY_EMERGENCY_LTE_PREFERRED_AFTER_NR_FAILED_BOOL, true);
         when(mCarrierConfigManager.getConfigForSubId(anyInt(), anyVararg())).thenReturn(bundle);
+        doReturn(DATA_CONNECTED).when(mEpdnHelper).getDataConnectionState(anyInt());
+
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(NGRAN,
+                REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS, true, false, 1, 1, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyPsDialed();
+
+        mDomainSelector.reselectDomain(attr);
+        processAllMessages();
+
+        // Verify not waiting for the disconnection in case EMF is supported.
+        assertFalse(mDomainSelector.hasMessages(MSG_WAIT_DISCONNECTION_TIMEOUT));
+
+        verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
+                any(), anyInt(), anyBoolean(), any(), any());
+        assertEquals(4, mAccessNetwork.size());
+        assertEquals(EUTRAN, (int) mAccessNetwork.get(0));
+        assertEquals(UTRAN, (int) mAccessNetwork.get(1));
+        assertEquals(GERAN, (int) mAccessNetwork.get(2));
+        assertEquals(NGRAN, (int) mAccessNetwork.get(3));
+    }
+
+    @Test
+    public void testScanLtePreferredAfterNgranFailureNotSupportEmf() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        bundle.putIntArray(KEY_EMERGENCY_OVER_IMS_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY,
+                new int[] { NGRAN, EUTRAN });
+        bundle.putBoolean(KEY_EMERGENCY_LTE_PREFERRED_AFTER_NR_FAILED_BOOL, true);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt(), anyVararg())).thenReturn(bundle);
+        doReturn(DATA_CONNECTED).when(mEpdnHelper).getDataConnectionState(anyInt());
 
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
@@ -2946,6 +2990,176 @@
         mDomainSelector.reselectDomain(attr);
         processAllMessages();
 
+        // Verify waiting for the disconnection in case EMF is supported.
+        assertTrue(mDomainSelector.hasMessages(MSG_WAIT_DISCONNECTION_TIMEOUT));
+
+        mDomainSelector.removeMessages(MSG_WAIT_DISCONNECTION_TIMEOUT);
+        processAllMessages();
+
+        verify(mWwanSelectorCallback, never()).onRequestEmergencyNetworkScan(
+                any(), anyInt(), anyBoolean(), any(), any());
+
+        mDomainSelector.sendEmptyMessage(MSG_WAIT_DISCONNECTION_TIMEOUT);
+        processAllMessages();
+
+        verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
+                any(), anyInt(), anyBoolean(), any(), any());
+        assertEquals(4, mAccessNetwork.size());
+        assertEquals(EUTRAN, (int) mAccessNetwork.get(0));
+        assertEquals(UTRAN, (int) mAccessNetwork.get(1));
+        assertEquals(GERAN, (int) mAccessNetwork.get(2));
+        assertEquals(NGRAN, (int) mAccessNetwork.get(3));
+    }
+
+    @Test
+    public void testScanLtePreferredAfterNgranFailureRestartWaitingTimer() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        bundle.putIntArray(KEY_EMERGENCY_OVER_IMS_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY,
+                new int[] { NGRAN, EUTRAN });
+        bundle.putBoolean(KEY_EMERGENCY_LTE_PREFERRED_AFTER_NR_FAILED_BOOL, true);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt(), anyVararg())).thenReturn(bundle);
+        doReturn(DATA_CONNECTED).when(mEpdnHelper).getDataConnectionState(anyInt());
+
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(NGRAN,
+                REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS, true, false, 1, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyPsDialed();
+
+        mDomainSelector.reselectDomain(attr);
+        processAllMessages();
+
+        assertTrue(mDomainSelector.hasMessages(MSG_WAIT_DISCONNECTION_TIMEOUT));
+
+        mDomainSelector.removeMessages(MSG_WAIT_DISCONNECTION_TIMEOUT);
+
+        assertFalse(mDomainSelector.hasMessages(MSG_WAIT_DISCONNECTION_TIMEOUT));
+
+        mDomainSelector.notifyDataConnectionStateChange(SLOT_0, DATA_DISCONNECTING);
+
+        assertTrue(mDomainSelector.hasMessages(MSG_WAIT_DISCONNECTION_TIMEOUT));
+    }
+
+    @Test
+    public void testScanLtePreferredAfterNgranFailureDataDisconnected() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        bundle.putIntArray(KEY_EMERGENCY_OVER_IMS_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY,
+                new int[] { NGRAN, EUTRAN });
+        bundle.putBoolean(KEY_EMERGENCY_LTE_PREFERRED_AFTER_NR_FAILED_BOOL, true);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt(), anyVararg())).thenReturn(bundle);
+        doReturn(DATA_CONNECTED).when(mEpdnHelper).getDataConnectionState(anyInt());
+
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(NGRAN,
+                REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS, true, false, 1, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyPsDialed();
+
+        mDomainSelector.reselectDomain(attr);
+        processAllMessages();
+
+        assertTrue(mDomainSelector.hasMessages(MSG_WAIT_DISCONNECTION_TIMEOUT));
+
+        mDomainSelector.removeMessages(MSG_WAIT_DISCONNECTION_TIMEOUT);
+        processAllMessages();
+
+        verify(mWwanSelectorCallback, never()).onRequestEmergencyNetworkScan(
+                any(), anyInt(), anyBoolean(), any(), any());
+
+        mDomainSelector.notifyDataConnectionStateChange(SLOT_0, DATA_DISCONNECTED);
+
+        verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
+                any(), anyInt(), anyBoolean(), any(), any());
+        assertEquals(4, mAccessNetwork.size());
+        assertEquals(EUTRAN, (int) mAccessNetwork.get(0));
+        assertEquals(UTRAN, (int) mAccessNetwork.get(1));
+        assertEquals(GERAN, (int) mAccessNetwork.get(2));
+        assertEquals(NGRAN, (int) mAccessNetwork.get(3));
+    }
+
+    @Test
+    public void testDefaultAfterNgranFailureNotSupportEmf() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        bundle.putIntArray(KEY_EMERGENCY_OVER_IMS_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY,
+                new int[] { NGRAN, EUTRAN });
+        when(mCarrierConfigManager.getConfigForSubId(anyInt(), anyVararg())).thenReturn(bundle);
+        doReturn(DATA_CONNECTED).when(mEpdnHelper).getDataConnectionState(anyInt());
+
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(NGRAN,
+                REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS, true, false, 1, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyPsDialed();
+
+        mDomainSelector.reselectDomain(attr);
+        processAllMessages();
+
+        // Verify not waiting for the disconnection
+        // in case KEY_EMERGENCY_LTE_PREFERRED_AFTER_NR_FAILED_BOOL is false.
+        assertFalse(mDomainSelector.hasMessages(MSG_WAIT_DISCONNECTION_TIMEOUT));
+
+        verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
+                any(), anyInt(), anyBoolean(), any(), any());
+        assertEquals(4, mAccessNetwork.size());
+        assertEquals(UTRAN, (int) mAccessNetwork.get(0));
+        assertEquals(GERAN, (int) mAccessNetwork.get(1));
+        assertEquals(NGRAN, (int) mAccessNetwork.get(2));
+        assertEquals(EUTRAN, (int) mAccessNetwork.get(3));
+    }
+
+    @Test
+    public void testDefaultAfterNgranFailureSupportEmf() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        bundle.putIntArray(KEY_EMERGENCY_OVER_IMS_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY,
+                new int[] { NGRAN, EUTRAN });
+        when(mCarrierConfigManager.getConfigForSubId(anyInt(), anyVararg())).thenReturn(bundle);
+        doReturn(DATA_CONNECTED).when(mEpdnHelper).getDataConnectionState(anyInt());
+
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(NGRAN,
+                REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS, true, false, 1, 1, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyPsDialed();
+
+        mDomainSelector.reselectDomain(attr);
+        processAllMessages();
+
+        // Verify not waiting for the disconnection
+        // in case KEY_EMERGENCY_LTE_PREFERRED_AFTER_NR_FAILED_BOOL is false.
+        assertFalse(mDomainSelector.hasMessages(MSG_WAIT_DISCONNECTION_TIMEOUT));
+
         verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
                 any(), anyInt(), anyBoolean(), any(), any());
         assertEquals(4, mAccessNetwork.size());
@@ -3049,9 +3263,9 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        doReturn(true).when(mEcbmHelper).isInEmergencyCallbackMode(anyInt());
-        doReturn(TRANSPORT_TYPE_WWAN).when(mEcbmHelper).getTransportType(anyInt());
-        doReturn(DATA_CONNECTED).when(mEcbmHelper).getDataConnectionState(anyInt());
+        doReturn(true).when(mEpdnHelper).isInEmergencyCallbackMode(anyInt());
+        doReturn(TRANSPORT_TYPE_WWAN).when(mEpdnHelper).getTransportType(anyInt());
+        doReturn(DATA_CONNECTED).when(mEpdnHelper).getDataConnectionState(anyInt());
 
         doAnswer(new Answer<Void>() {
             @Override
@@ -3083,9 +3297,9 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        doReturn(true).when(mEcbmHelper).isInEmergencyCallbackMode(anyInt());
-        doReturn(TRANSPORT_TYPE_WLAN).when(mEcbmHelper).getTransportType(anyInt());
-        doReturn(DATA_CONNECTED).when(mEcbmHelper).getDataConnectionState(anyInt());
+        doReturn(true).when(mEpdnHelper).isInEmergencyCallbackMode(anyInt());
+        doReturn(TRANSPORT_TYPE_WLAN).when(mEpdnHelper).getTransportType(anyInt());
+        doReturn(DATA_CONNECTED).when(mEpdnHelper).getDataConnectionState(anyInt());
 
         EmergencyRegistrationResult regResult = getEmergencyRegResult(UNKNOWN,
                 REGISTRATION_STATE_UNKNOWN,
@@ -3106,8 +3320,8 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        doReturn(true).when(mEcbmHelper).isInEmergencyCallbackMode(anyInt());
-        doReturn(TRANSPORT_TYPE_WLAN).when(mEcbmHelper).getTransportType(anyInt());
+        doReturn(true).when(mEpdnHelper).isInEmergencyCallbackMode(anyInt());
+        doReturn(TRANSPORT_TYPE_WLAN).when(mEpdnHelper).getTransportType(anyInt());
 
         EmergencyRegistrationResult regResult = getEmergencyRegResult(UNKNOWN,
                 REGISTRATION_STATE_UNKNOWN,
@@ -3128,9 +3342,9 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        doReturn(false).when(mEcbmHelper).isInEmergencyCallbackMode(anyInt());
-        doReturn(TRANSPORT_TYPE_WLAN).when(mEcbmHelper).getTransportType(anyInt());
-        doReturn(DATA_CONNECTED).when(mEcbmHelper).getDataConnectionState(anyInt());
+        doReturn(false).when(mEpdnHelper).isInEmergencyCallbackMode(anyInt());
+        doReturn(TRANSPORT_TYPE_WLAN).when(mEpdnHelper).getTransportType(anyInt());
+        doReturn(DATA_CONNECTED).when(mEpdnHelper).getDataConnectionState(anyInt());
 
         EmergencyRegistrationResult regResult = getEmergencyRegResult(UNKNOWN,
                 REGISTRATION_STATE_UNKNOWN,
@@ -3151,9 +3365,9 @@
         createSelector(SLOT_0_SUB_ID);
         unsolBarringInfoChanged(false);
 
-        doReturn(false).when(mEcbmHelper).isInEmergencyCallbackMode(anyInt());
-        doReturn(TRANSPORT_TYPE_WLAN).when(mEcbmHelper).getTransportType(anyInt());
-        doReturn(DATA_CONNECTED).when(mEcbmHelper).getDataConnectionState(anyInt());
+        doReturn(false).when(mEpdnHelper).isInEmergencyCallbackMode(anyInt());
+        doReturn(TRANSPORT_TYPE_WLAN).when(mEpdnHelper).getTransportType(anyInt());
+        doReturn(DATA_CONNECTED).when(mEpdnHelper).getDataConnectionState(anyInt());
 
         doAnswer(new Answer<Void>() {
             @Override
@@ -3498,7 +3712,7 @@
     private void createSelector(int subId) throws Exception {
         mDomainSelector = new EmergencyCallDomainSelector(
                 mContext, SLOT_0, subId, mHandlerThread.getLooper(),
-                mImsStateTracker, mDestroyListener, mCsrdCtrl, mEcbmHelper);
+                mImsStateTracker, mDestroyListener, mCsrdCtrl, mEpdnHelper);
         mDomainSelector.clearResourceConfiguration();
         replaceInstance(DomainSelectorBase.class,
                 "mWwanSelectorCallback", mDomainSelector, mWwanSelectorCallback);
diff --git a/tests/src/com/android/services/telephony/domainselection/EmergencyCallbackModeHelperTest.java b/tests/src/com/android/services/telephony/domainselection/EmergencyCallbackModeHelperTest.java
deleted file mode 100644
index 9a4e0d8..0000000
--- a/tests/src/com/android/services/telephony/domainselection/EmergencyCallbackModeHelperTest.java
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.services.telephony.domainselection;
-
-import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_CALLBACK_MODE_SUPPORTED_BOOL;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-import static junit.framework.Assert.assertNotNull;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.PersistableBundle;
-import android.telephony.CarrierConfigManager;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyCallback;
-import android.telephony.TelephonyManager;
-import android.testing.TestableLooper;
-import android.util.Log;
-
-import com.android.TestContext;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.MockitoAnnotations;
-
-import java.util.concurrent.Executor;
-
-/**
- * Unit tests for EmergencyCallbackModeHelper
- */
-public class EmergencyCallbackModeHelperTest {
-    private static final String TAG = "EmergencyCallbackModeHelperTest";
-
-    private static final int SLOT_0 = 0;
-    private static final int SLOT_1 = 1;
-    private static final int SUB_1 = 1;
-    private static final int SUB_2 = 2;
-
-    private Context mContext;
-    private HandlerThread mHandlerThread;
-    private TestableLooper mLooper;
-    private EmergencyCallbackModeHelper mEcbmHelper;
-    private CarrierConfigManager mCarrierConfigManager;
-    private TelephonyManager mTelephonyManager;
-
-    @Before
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        mContext = new TestContext() {
-            private Intent mIntent;
-
-            @Override
-            public String getSystemServiceName(Class<?> serviceClass) {
-                if (serviceClass == TelephonyManager.class) {
-                    return Context.TELEPHONY_SERVICE;
-                } else if (serviceClass == CarrierConfigManager.class) {
-                    return Context.CARRIER_CONFIG_SERVICE;
-                }
-                return super.getSystemServiceName(serviceClass);
-            }
-
-            @Override
-            public String getOpPackageName() {
-                return "";
-            }
-
-            @Override
-            public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
-                return mIntent;
-            }
-
-            @Override
-            public void sendStickyBroadcast(Intent intent) {
-                mIntent = intent;
-            }
-        };
-
-        if (Looper.myLooper() == null) {
-            Looper.prepare();
-        }
-
-        mHandlerThread = new HandlerThread("EmergencyCallbackModeHelperTest");
-        mHandlerThread.start();
-
-        try {
-            mLooper = new TestableLooper(mHandlerThread.getLooper());
-        } catch (Exception e) {
-            logd("Unable to create looper from handler.");
-        }
-
-        mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
-        mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
-        doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(anyInt());
-
-        mEcbmHelper = new EmergencyCallbackModeHelper(mContext, mHandlerThread.getLooper());
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        if (mEcbmHelper != null) {
-            mEcbmHelper.destroy();
-            mEcbmHelper = null;
-        }
-
-        if (mLooper != null) {
-            mLooper.destroy();
-            mLooper = null;
-        }
-    }
-
-    @Test
-    public void testInit() throws Exception {
-        ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> callbackCaptor =
-                ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
-        ArgumentCaptor<Executor> executorCaptor = ArgumentCaptor.forClass(Executor.class);
-
-        verify(mCarrierConfigManager).registerCarrierConfigChangeListener(executorCaptor.capture(),
-                callbackCaptor.capture());
-        assertNotNull(executorCaptor.getValue());
-        assertNotNull(callbackCaptor.getValue());
-    }
-
-    @Test
-    public void testEmergencyCallbackModeNotSupported() throws Exception {
-        ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> callbackCaptor =
-                ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
-
-        verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
-                callbackCaptor.capture());
-
-        CarrierConfigManager.CarrierConfigChangeListener callback = callbackCaptor.getValue();
-
-        assertNotNull(callback);
-
-        // ECBM not supported
-        PersistableBundle b = getPersistableBundle(false);
-        doReturn(b).when(mCarrierConfigManager).getConfigForSubId(anyInt(), anyString());
-        callback.onCarrierConfigChanged(SLOT_0, SUB_1, 0, 0);
-
-        // No TelephonyCallback registered
-        verify(mTelephonyManager, never()).registerTelephonyCallback(any(), any());
-    }
-
-    @Test
-    public void testEmergencyCallbackModeSupported() throws Exception {
-        ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> callbackCaptor =
-                ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
-
-        verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
-                callbackCaptor.capture());
-
-        CarrierConfigManager.CarrierConfigChangeListener callback = callbackCaptor.getValue();
-
-        assertNotNull(callback);
-
-        // ECBM supported
-        PersistableBundle b = getPersistableBundle(true);
-        doReturn(b).when(mCarrierConfigManager).getConfigForSubId(anyInt(), anyString());
-        callback.onCarrierConfigChanged(SLOT_0, SUB_1, 0, 0);
-
-        verify(mTelephonyManager).createForSubscriptionId(eq(SUB_1));
-
-        ArgumentCaptor<TelephonyCallback> telephonyCallbackCaptor =
-                ArgumentCaptor.forClass(TelephonyCallback.class);
-
-        // TelephonyCallback registered
-        verify(mTelephonyManager).registerTelephonyCallback(any(),
-                telephonyCallbackCaptor.capture());
-
-        assertNotNull(telephonyCallbackCaptor.getValue());
-    }
-
-    @Test
-    public void testEmergencyCallbackModeChanged() throws Exception {
-        ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> callbackCaptor =
-                ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
-
-        verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
-                callbackCaptor.capture());
-
-        CarrierConfigManager.CarrierConfigChangeListener callback = callbackCaptor.getValue();
-
-        assertNotNull(callback);
-
-        // ECBM supported
-        PersistableBundle b = getPersistableBundle(true);
-        doReturn(b).when(mCarrierConfigManager).getConfigForSubId(anyInt(), anyString());
-        callback.onCarrierConfigChanged(SLOT_0, SUB_1, 0, 0);
-
-        verify(mTelephonyManager).createForSubscriptionId(eq(SUB_1));
-
-        ArgumentCaptor<TelephonyCallback> telephonyCallbackCaptor =
-                ArgumentCaptor.forClass(TelephonyCallback.class);
-
-        // TelephonyCallback registered
-        verify(mTelephonyManager).registerTelephonyCallback(any(),
-                telephonyCallbackCaptor.capture());
-
-        TelephonyCallback telephonyCallback = telephonyCallbackCaptor.getValue();
-
-        assertNotNull(telephonyCallback);
-
-        // Carrier config changes, ECBM not supported
-        b = getPersistableBundle(false);
-        doReturn(b).when(mCarrierConfigManager).getConfigForSubId(anyInt(), anyString());
-        callback.onCarrierConfigChanged(SLOT_0, SUB_1, 0, 0);
-
-        // TelephonyCallback unregistered
-        verify(mTelephonyManager).unregisterTelephonyCallback(eq(telephonyCallback));
-    }
-
-    @Test
-    public void testEmergencyCallbackModeEnter() throws Exception {
-        ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> callbackCaptor =
-                ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
-
-        verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
-                callbackCaptor.capture());
-
-        CarrierConfigManager.CarrierConfigChangeListener callback = callbackCaptor.getValue();
-
-        assertNotNull(callback);
-
-        // ECBM supported
-        PersistableBundle b = getPersistableBundle(true);
-        doReturn(b).when(mCarrierConfigManager).getConfigForSubId(anyInt(), anyString());
-        callback.onCarrierConfigChanged(SLOT_0, SUB_1, 0, 0);
-        callback.onCarrierConfigChanged(SLOT_1, SUB_2, 0, 0);
-
-        // Enter ECBM on slot 1
-        mContext.sendStickyBroadcast(getIntent(true, SLOT_1));
-
-        assertFalse(mEcbmHelper.isInEmergencyCallbackMode(SLOT_0));
-        assertTrue(mEcbmHelper.isInEmergencyCallbackMode(SLOT_1));
-    }
-
-    @Test
-    public void testEmergencyCallbackModeExit() throws Exception {
-        ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> callbackCaptor =
-                ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
-
-        verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
-                callbackCaptor.capture());
-
-        CarrierConfigManager.CarrierConfigChangeListener callback = callbackCaptor.getValue();
-
-        assertNotNull(callback);
-
-        // ECBM supported
-        PersistableBundle b = getPersistableBundle(true);
-        doReturn(b).when(mCarrierConfigManager).getConfigForSubId(anyInt(), anyString());
-        callback.onCarrierConfigChanged(SLOT_0, SUB_1, 0, 0);
-
-        // Exit ECBM
-        mContext.sendStickyBroadcast(getIntent(false, SLOT_0));
-
-        assertFalse(mEcbmHelper.isInEmergencyCallbackMode(SLOT_0));
-    }
-
-    private static Intent getIntent(boolean inEcm, int slotIndex) {
-        Intent intent = new Intent(TelephonyManager.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
-        intent.putExtra(TelephonyManager.EXTRA_PHONE_IN_ECM_STATE, inEcm);
-        intent.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, slotIndex);
-        return intent;
-    }
-
-    private static PersistableBundle getPersistableBundle(boolean supported) {
-        PersistableBundle bundle  = new PersistableBundle();
-        bundle.putBoolean(KEY_EMERGENCY_CALLBACK_MODE_SUPPORTED_BOOL, supported);
-        return bundle;
-    }
-
-    private static void logd(String str) {
-        Log.d(TAG, str);
-    }
-}
diff --git a/tests/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionServiceTest.java b/tests/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionServiceTest.java
index 40a4616..7031bf3 100644
--- a/tests/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionServiceTest.java
@@ -82,7 +82,7 @@
                         @NonNull Looper looper, @NonNull ImsStateTracker imsStateTracker,
                         @NonNull DomainSelectorBase.DestroyListener listener,
                         @NonNull CrossSimRedialingController crossSimRedialingController,
-                        @NonNull EmergencyCallbackModeHelper ecbmHelper) {
+                        @NonNull DataConnectionStateHelper dataConnectionStateHelper) {
                     switch (selectorType) {
                         case DomainSelectionService.SELECTOR_TYPE_CALLING: // fallthrough
                         case DomainSelectionService.SELECTOR_TYPE_SMS:
@@ -104,8 +104,9 @@
         TestTelephonyDomainSelectionService(Context context,
                 @NonNull ImsStateTrackerFactory imsStateTrackerFactory,
                 @NonNull DomainSelectorFactory domainSelectorFactory,
-                @Nullable EmergencyCallbackModeHelper ecbmHelper) {
-            super(imsStateTrackerFactory, domainSelectorFactory, ecbmHelper);
+                @Nullable DataConnectionStateHelper dataConnectionStateHelper) {
+            super(imsStateTrackerFactory, domainSelectorFactory,
+                    dataConnectionStateHelper);
             mContext = context;
         }
 
@@ -129,7 +130,7 @@
     @Mock private TransportSelectorCallback mSelectorCallback1;
     @Mock private TransportSelectorCallback mSelectorCallback2;
     @Mock private ImsStateTracker mImsStateTracker;
-    @Mock private EmergencyCallbackModeHelper mEcbmHelper;
+    @Mock private DataConnectionStateHelper mDataConnectionStateHelper;
 
     private final ServiceState mServiceState = new ServiceState();
     private final BarringInfo mBarringInfo = new BarringInfo();
@@ -151,7 +152,8 @@
 
         mContext = new TestContext();
         mDomainSelectionService = new TestTelephonyDomainSelectionService(mContext,
-                mImsStateTrackerFactory, mDomainSelectorFactory, mEcbmHelper);
+                mImsStateTrackerFactory, mDomainSelectorFactory,
+                mDataConnectionStateHelper);
         mDomainSelectionService.onCreate();
         mServiceHandler = new Handler(mDomainSelectionService.getLooper());
         mTestableLooper = new TestableLooper(mDomainSelectionService.getLooper());