Merge "Support emergency SMS domain selection in NR network" into main
diff --git a/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelector.java b/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelector.java
index aef193b..a2f986f 100644
--- a/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelector.java
+++ b/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelector.java
@@ -18,12 +18,17 @@
 
 import android.annotation.NonNull;
 import android.content.Context;
+import android.os.CancellationSignal;
 import android.os.Looper;
+import android.os.Message;
 import android.os.PersistableBundle;
 import android.telephony.AccessNetworkConstants;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
 import android.telephony.BarringInfo;
 import android.telephony.CarrierConfigManager;
 import android.telephony.DataSpecificRegistrationInfo;
+import android.telephony.DomainSelectionService;
+import android.telephony.EmergencyRegResult;
 import android.telephony.NetworkRegistrationInfo;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
@@ -31,11 +36,14 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 
+import java.util.List;
+
 /**
  * Implements an emergency SMS domain selector for sending an emergency SMS.
  */
 public class EmergencySmsDomainSelector extends SmsDomainSelector implements
         ImsStateTracker.BarringInfoListener, ImsStateTracker.ServiceStateListener {
+    protected static final int EVENT_EMERGENCY_NETWORK_SCAN_RESULT = 201;
     /**
      * Stores the configuration value of
      * {@link CarrierConfigManager#KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL}.
@@ -46,6 +54,8 @@
     private boolean mServiceStateReceived;
     private BarringInfo mBarringInfo;
     private boolean mBarringInfoReceived;
+    private boolean mEmergencyNetworkScanInProgress;
+    private CancellationSignal mEmergencyNetworkScanSignal;
 
     public EmergencySmsDomainSelector(Context context, int slotId, int subId,
             @NonNull Looper looper, @NonNull ImsStateTracker imsStateTracker,
@@ -68,6 +78,18 @@
     }
 
     @Override
+    public void handleMessage(@NonNull Message msg) {
+        switch (msg.what) {
+            case EVENT_EMERGENCY_NETWORK_SCAN_RESULT:
+                handleEmergencyNetworkScanResult((EmergencyRegResult) msg.obj);
+                break;
+            default:
+                super.handleMessage(msg);
+                break;
+        }
+    }
+
+    @Override
     public void finishSelection() {
         super.finishSelection();
         mServiceStateReceived = false;
@@ -75,6 +97,12 @@
         mBarringInfoReceived = false;
         mBarringInfo = null;
         mEmergencySmsOverImsSupportedByConfig = null;
+
+        mEmergencyNetworkScanInProgress = false;
+        if (mEmergencyNetworkScanSignal != null) {
+            mEmergencyNetworkScanSignal.cancel();
+            mEmergencyNetworkScanSignal = null;
+        }
     }
 
     @Override
@@ -111,7 +139,7 @@
              * when {@link CarrierConfigManager#KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL} is set
              * to true.
              */
-            if (isEmergencySmsOverImsSupportedIfLteLimitedOrInService()) {
+            if (isEmergencySmsOverImsSupportedIfNetworkLimitedOrInService()) {
                 /**
                  * Emergency SMS should be supported via emergency PDN.
                  * If this condition is false, then need to fallback to CS network
@@ -139,60 +167,132 @@
             return;
         }
 
+        if (mEmergencyNetworkScanInProgress) {
+            logi("Emergency network scan is in progress.");
+            return;
+        }
+
         logi("selectDomain: " + mImsStateTracker.imsStateToString());
 
         if (isSmsOverImsAvailable()) {
-            boolean isEmergencySmsOverImsSupportedIfLteLimitedOrInService =
-                    isEmergencySmsOverImsSupportedIfLteLimitedOrInService();
+            boolean isEmergencySmsOverImsSupportedIfNetworkLimitedOrInService =
+                    isEmergencySmsOverImsSupportedIfNetworkLimitedOrInService();
 
             if (mImsStateTracker.isImsRegisteredOverWlan()) {
                 /**
                  * When {@link CarrierConfigManager#KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL}
-                 * is set to true, the emergency SMS supports on the LTE network using the
+                 * is set to true, the emergency SMS supports on the LTE/NR network using the
                  * emergency PDN. As of now, since the emergency SMS doesn't use the emergency PDN
                  * over WLAN, the domain selector reports the domain as WLAN only if
-                 * {@code isEmergencySmsOverImsSupportedIfLteLimitedOrInService} is set to false
+                 * {@code isEmergencySmsOverImsSupportedIfNetworkLimitedOrInService} is set to false
                  * and IMS is registered over WLAN.
                  * Otherwise, the domain selector reports the domain as WWAN.
                  */
-                if (!isEmergencySmsOverImsSupportedIfLteLimitedOrInService) {
+                if (!isEmergencySmsOverImsSupportedIfNetworkLimitedOrInService) {
                     notifyWlanSelected(false);
                     return;
                 }
 
                 logi("DomainSelected: WLAN >> WWAN");
             }
-            notifyWwanSelected(NetworkRegistrationInfo.DOMAIN_PS,
-                    isEmergencySmsOverImsSupportedIfLteLimitedOrInService);
+
+            /**
+             * The request of emergency network scan triggers the modem to request the emergency
+             * service fallback because NR network doesn't support the emergency service.
+             */
+            if (isEmergencySmsOverImsSupportedIfNetworkLimitedOrInService
+                    && isNrEmergencyServiceFallbackRequired()) {
+                requestEmergencyNetworkScan(List.of(AccessNetworkType.EUTRAN));
+            } else {
+                notifyWwanSelected(NetworkRegistrationInfo.DOMAIN_PS,
+                        isEmergencySmsOverImsSupportedIfNetworkLimitedOrInService);
+            }
         } else {
             notifyWwanSelected(NetworkRegistrationInfo.DOMAIN_CS, false);
         }
     }
 
+    private void requestEmergencyNetworkScan(List<Integer> preferredNetworks) {
+        mEmergencyNetworkScanInProgress = true;
+
+        if (mWwanSelectorCallback == null) {
+            mTransportSelectorCallback.onWwanSelected((callback) -> {
+                mWwanSelectorCallback = callback;
+                requestEmergencyNetworkScanInternal(preferredNetworks);
+            });
+        } else {
+            requestEmergencyNetworkScanInternal(preferredNetworks);
+        }
+    }
+
+    private void requestEmergencyNetworkScanInternal(List<Integer> preferredNetworks) {
+        logi("requestEmergencyNetworkScan: preferredNetworks=" + preferredNetworks);
+        mEmergencyNetworkScanSignal = new CancellationSignal();
+        mWwanSelectorCallback.onRequestEmergencyNetworkScan(
+                preferredNetworks,
+                DomainSelectionService.SCAN_TYPE_FULL_SERVICE,
+                mEmergencyNetworkScanSignal,
+                (regResult) -> {
+                    logi("requestEmergencyNetworkScan-onComplete");
+                    obtainMessage(EVENT_EMERGENCY_NETWORK_SCAN_RESULT, regResult).sendToTarget();
+                });
+    }
+
+    /**
+     * Handles the emergency network scan result.
+     *
+     * This triggers the emergency service fallback to modem when the emergency service is not
+     * supported but the emergency service fallback is supported in the current network.
+     *
+     * @param regResult The emergency registration result that is triggered
+     *                  by the emergency network scan.
+     */
+    private void handleEmergencyNetworkScanResult(EmergencyRegResult regResult) {
+        logi("handleEmergencyNetworkScanResult: " + regResult);
+
+        mEmergencyNetworkScanInProgress = false;
+        mEmergencyNetworkScanSignal = null;
+
+        int accessNetworkType = regResult.getAccessNetwork();
+        int domain = NetworkRegistrationInfo.DOMAIN_CS;
+
+        if (accessNetworkType == AccessNetworkType.NGRAN) {
+            domain = NetworkRegistrationInfo.DOMAIN_PS;
+        } else if (accessNetworkType == AccessNetworkType.EUTRAN) {
+            if (regResult.getDomain() == NetworkRegistrationInfo.DOMAIN_CS) {
+                logi("PS emergency service is not supported in LTE network.");
+            } else {
+                domain = NetworkRegistrationInfo.DOMAIN_PS;
+            }
+        }
+
+        notifyWwanSelected(domain, (domain == NetworkRegistrationInfo.DOMAIN_PS));
+    }
+
     /**
      * Checks if the emergency SMS messages over IMS is available according to the carrier
      * configuration and the current network states.
      */
     private boolean isImsEmergencySmsAvailable() {
-        boolean isEmergencySmsOverImsSupportedIfLteLimitedOrInService =
-                isEmergencySmsOverImsSupportedIfLteLimitedOrInService();
+        boolean isEmergencySmsOverImsSupportedIfNetworkLimitedOrInService =
+                isEmergencySmsOverImsSupportedIfNetworkLimitedOrInService();
         boolean networkAvailable = isNetworkAvailableForImsEmergencySms();
 
         logi("isImsEmergencySmsAvailable: "
-                + "emergencySmsOverIms=" + isEmergencySmsOverImsSupportedIfLteLimitedOrInService
+                + "emergencySmsOverIms=" + isEmergencySmsOverImsSupportedIfNetworkLimitedOrInService
                 + ", mmTelFeatureAvailable=" + mImsStateTracker.isMmTelFeatureAvailable()
                 + ", networkAvailable=" + networkAvailable);
 
-        return isEmergencySmsOverImsSupportedIfLteLimitedOrInService
+        return isEmergencySmsOverImsSupportedIfNetworkLimitedOrInService
                 && mImsStateTracker.isMmTelFeatureAvailable()
                 && networkAvailable;
     }
 
     /**
-     * Checks if sending emergency SMS messages over IMS is supported when in LTE/limited LTE
-     * (Emergency only) service mode from the carrier configuration.
+     * Checks if sending emergency SMS messages over IMS is supported when in the network(LTE/NR)
+     * normal/limited(Emergency only) service mode from the carrier configuration.
      */
-    private boolean isEmergencySmsOverImsSupportedIfLteLimitedOrInService() {
+    private boolean isEmergencySmsOverImsSupportedIfNetworkLimitedOrInService() {
         if (mEmergencySmsOverImsSupportedByConfig == null) {
             CarrierConfigManager ccm = mContext.getSystemService(CarrierConfigManager.class);
 
@@ -257,7 +357,8 @@
      */
     private boolean isNetworkAvailableForImsEmergencySms() {
         return isLteEmergencyAvailableInService()
-                || isLteEmergencyAvailableInLimitedService();
+                || isLteEmergencyAvailableInLimitedService()
+                || isNrEmergencyAvailable();
     }
 
     /**
@@ -280,6 +381,22 @@
     }
 
     /**
+     * Checks if the emergency service fallback is supported by the network.
+     *
+     * @return {@code true} if the emergency service fallback is supported by the network,
+     *         {@code false} otherwise.
+     */
+    private boolean isEmergencyServiceFallbackSupported(@NonNull NetworkRegistrationInfo regInfo) {
+        final DataSpecificRegistrationInfo dsRegInfo = regInfo.getDataSpecificInfo();
+        if (dsRegInfo != null) {
+            final VopsSupportInfo vopsSupportInfo = dsRegInfo.getVopsSupportInfo();
+            return vopsSupportInfo != null
+                    && vopsSupportInfo.isEmergencyServiceFallbackSupported();
+        }
+        return false;
+    }
+
+    /**
      * Checks if the emergency service is allowed (not barred) by the network.
      *
      * This checks if SystemInformationBlockType2 includes the ac-BarringInfo and
@@ -297,4 +414,45 @@
                 mBarringInfo.getBarringServiceInfo(BarringInfo.BARRING_SERVICE_TYPE_EMERGENCY);
         return !bsi.isBarred();
     }
+
+    /**
+     * Checks if the emergency service fallback is available in the NR network
+     * because the emergency service is not supported.
+     */
+    private boolean isNrEmergencyServiceFallbackRequired() {
+        if (mServiceState == null) {
+            return false;
+        }
+
+        final NetworkRegistrationInfo regInfo = mServiceState.getNetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+
+        if (regInfo != null
+                && regInfo.getAccessNetworkTechnology() == TelephonyManager.NETWORK_TYPE_NR
+                && regInfo.isRegistered()) {
+            return !isEmergencyServiceSupported(regInfo)
+                    && isEmergencyServiceFallbackSupported(regInfo);
+        }
+        return false;
+    }
+
+    /**
+     * Checks if the emergency service is available in the NR network.
+     */
+    private boolean isNrEmergencyAvailable() {
+        if (mServiceState == null) {
+            return false;
+        }
+
+        final NetworkRegistrationInfo regInfo = mServiceState.getNetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+
+        if (regInfo != null
+                && regInfo.getAccessNetworkTechnology() == TelephonyManager.NETWORK_TYPE_NR
+                && regInfo.isRegistered()) {
+            return isEmergencyServiceSupported(regInfo)
+                    || isEmergencyServiceFallbackSupported(regInfo);
+        }
+        return false;
+    }
 }
diff --git a/tests/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelectorTest.java
index ed064cb..2af0b3f 100644
--- a/tests/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelectorTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelectorTest.java
@@ -39,6 +39,7 @@
 import android.telephony.CarrierConfigManager;
 import android.telephony.DataSpecificRegistrationInfo;
 import android.telephony.DomainSelectionService.SelectionAttributes;
+import android.telephony.EmergencyRegResult;
 import android.telephony.NetworkRegistrationInfo;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
@@ -92,6 +93,7 @@
     private ImsStateTracker.BarringInfoListener mBarringInfoListener;
     private ImsStateTracker.ServiceStateListener mServiceStateListener;
     private EmergencySmsDomainSelector mDomainSelector;
+    private EmergencyRegResult mEmergencyRegResult;
 
     @Before
     public void setUp() throws Exception {
@@ -151,6 +153,7 @@
             mLooper = null;
         }
 
+        mEmergencyRegResult = null;
         mDomainSelector = null;
         mNetworkRegistrationInfo = null;
         mVopsSupportInfo = null;
@@ -246,6 +249,26 @@
 
     @Test
     @SmallTest
+    public void testIsSmsOverImsAvailableWhenImsRegisteredAndConfigEnabledAndNrAvailable() {
+        setUpImsStateTracker(AccessNetworkType.NGRAN);
+        setUpCarrierConfig(true);
+        setUpNrInService(false, false, true, false);
+
+        assertTrue(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenImsRegisteredAndConfigEnabledAndNrNotAvailable() {
+        setUpImsStateTracker(AccessNetworkType.NGRAN);
+        setUpCarrierConfig(true);
+        setUpNrInService(false, false, false, false);
+
+        assertFalse(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
     public void testIsSmsOverImsAvailableWhenCarrierConfigManagerIsNull() {
         setUpImsStateTracker(AccessNetworkType.UNKNOWN);
         mCarrierConfigManagerNullTest = true;
@@ -291,7 +314,7 @@
 
     @Test
     @SmallTest
-    public void testIsSmsOverImsAvailableWhenNoLte() {
+    public void testIsSmsOverImsAvailableWhenNoLteOrNr() {
         setUpImsStateTracker(AccessNetworkType.UNKNOWN);
         setUpCarrierConfig(true);
         mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
@@ -395,6 +418,56 @@
 
     @Test
     @SmallTest
+    public void testIsSmsOverImsAvailableWhenNrNotRegisteredOrEmergencyNotEnabled() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpCarrierConfig(true);
+        setUpNrInService(false, false, false, false);
+
+        assertFalse(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenNrInServiceAndNoDataSpecificRegistrationInfo() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpCarrierConfig(true);
+        setUpNrInService(true, true, false, false);
+
+        assertFalse(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenNrInServiceAndNoVopsSupportInfo() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpCarrierConfig(true);
+        setUpNrInService(false, true, false, false);
+
+        assertFalse(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenNrInServiceAndEmergencyServiceSupported() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpCarrierConfig(true);
+        setUpNrInService(false, false, true, false);
+
+        assertTrue(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenNrInServiceAndEmergencyServiceFallbackSupported() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpCarrierConfig(true);
+        setUpNrInService(false, false, false, true);
+
+        assertTrue(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
     public void testSelectDomainWhilePreviousRequestInProgress() {
         setUpImsStateTracker(AccessNetworkType.EUTRAN);
         setUpWwanSelectorCallback();
@@ -675,6 +748,115 @@
                 eq(true));
     }
 
+    @Test
+    @SmallTest
+    public void testSelectDomainWhileEmergencyNetworkScanInProgress() {
+        setUpImsStateTracker(AccessNetworkType.NGRAN);
+        setUpEmergencyRegResult(AccessNetworkType.NGRAN, NetworkRegistrationInfo.DOMAIN_PS, 1, 0);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpNrInService(false, false, false, true);
+        setUpImsStateListener(true, true, true);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        // Call the domain selection before completing the emergency network scan.
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // onRequestEmergencyNetworkScan is invoked only once.
+        verify(mWwanSelectorCallback).onRequestEmergencyNetworkScan(any(), anyInt(), any(), any());
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenNrEmergencyServiceSupported() {
+        setUpImsStateTracker(AccessNetworkType.NGRAN);
+        setUpEmergencyRegResult(AccessNetworkType.NGRAN, NetworkRegistrationInfo.DOMAIN_PS, 1, 0);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpNrInService(false, false, true, false);
+        setUpImsStateListener(true, true, true);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // Expected: PS network
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS),
+                eq(true));
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenEmergencyRegistrationResultNgranAndPsDomain() {
+        setUpImsStateTracker(AccessNetworkType.NGRAN);
+        setUpEmergencyRegResult(AccessNetworkType.NGRAN, NetworkRegistrationInfo.DOMAIN_PS, 1, 0);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpNrInService(false, false, false, true);
+        setUpImsStateListener(true, true, true);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // Expected: PS network
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS),
+                eq(true));
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenEmergencyRegistrationResultEutranAndPsDomain() {
+        setUpImsStateTracker(AccessNetworkType.NGRAN);
+        setUpEmergencyRegResult(AccessNetworkType.EUTRAN, NetworkRegistrationInfo.DOMAIN_PS, 0, 0);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpNrInService(false, false, false, true);
+        setUpImsStateListener(true, true, true);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // Expected: PS network
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS),
+                eq(true));
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenEmergencyRegistrationResultEutranAndCsDomain() {
+        setUpImsStateTracker(AccessNetworkType.NGRAN);
+        setUpEmergencyRegResult(AccessNetworkType.EUTRAN, NetworkRegistrationInfo.DOMAIN_CS, 0, 0);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpNrInService(false, false, false, true);
+        setUpImsStateListener(true, true, true);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // Expected: CS network
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS),
+                eq(false));
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenEmergencyRegistrationResultUtranAndCsDomain() {
+        setUpImsStateTracker(AccessNetworkType.NGRAN);
+        setUpEmergencyRegResult(AccessNetworkType.UTRAN, NetworkRegistrationInfo.DOMAIN_CS, 0, 0);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpNrInService(false, false, false, true);
+        setUpImsStateListener(true, true, true);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // Expected: CS network
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS),
+                eq(false));
+    }
+
     private void setUpCarrierConfig(boolean supported) {
         PersistableBundle b = new PersistableBundle();
         b.putBoolean(CarrierConfigManager.KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL, supported);
@@ -760,6 +942,29 @@
         mBarringInfoListener.onBarringInfoUpdated(barringInfo);
     }
 
+    private void setUpNrInService(boolean noDataSpecificRegistrationInfo,
+            boolean noVopsSupportInfo, boolean emergencyServiceSupported,
+            boolean emergencyServiceFallbackSupported) {
+        DataSpecificRegistrationInfo dsri = noDataSpecificRegistrationInfo
+                ? null : new DataSpecificRegistrationInfo(
+                        8, false, false, false, noVopsSupportInfo ? null : mVopsSupportInfo);
+
+        mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
+                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_NR)
+                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
+                .setDataSpecificInfo(dsri)
+                .build();
+        when(mServiceState.getNetworkRegistrationInfo(
+                anyInt(), eq(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)))
+                .thenReturn(mNetworkRegistrationInfo);
+        when(mVopsSupportInfo.isEmergencyServiceSupported()).thenReturn(emergencyServiceSupported);
+        when(mVopsSupportInfo.isEmergencyServiceFallbackSupported())
+                .thenReturn(emergencyServiceFallbackSupported);
+
+        mServiceStateListener.onServiceStateUpdated(mServiceState);
+        mBarringInfoListener.onBarringInfoUpdated(null);
+    }
+
     private void setUpImsStateTracker(@RadioAccessNetworkType int accessNetworkType) {
         setUpImsStateTracker(accessNetworkType, true, true);
     }
@@ -783,6 +988,22 @@
             callback.accept(mWwanSelectorCallback);
             return null;
         }).when(mTransportSelectorCallback).onWwanSelected(any(Consumer.class));
+
+        doAnswer((invocation) -> {
+            Object[] args = invocation.getArguments();
+            final Consumer<EmergencyRegResult> result = (Consumer<EmergencyRegResult>) args[3];
+            result.accept(mEmergencyRegResult);
+            return null;
+        }).when(mWwanSelectorCallback).onRequestEmergencyNetworkScan(
+                any(), anyInt(), any(), any());
+    }
+
+    private void setUpEmergencyRegResult(
+            @AccessNetworkConstants.RadioAccessNetworkType int accessNetwork,
+            @NetworkRegistrationInfo.Domain int domain, int nrEs, int nrEsfb) {
+        mEmergencyRegResult = new EmergencyRegResult(accessNetwork,
+                NetworkRegistrationInfo.REGISTRATION_STATE_HOME,
+                domain, true, true, nrEs, nrEsfb, "001", "01", "");
     }
 
     private void setUpImsStateListener(boolean notifyMmTelFeatureAvailable,