diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 0e32e40..32733cc 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -516,7 +516,6 @@
         <activity android:name="com.android.phone.settings.VoicemailSettingsActivity"
             android:label="@string/voicemail"
             android:configChanges="orientation|screenSize|keyboardHidden|screenLayout"
-            android:screenOrientation="portrait"
             android:exported="true"
             android:theme="@style/CallSettingsWithoutDividerTheme">
             <intent-filter >
diff --git a/res/values/config.xml b/res/values/config.xml
index 19252c0..ba65302 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -317,4 +317,8 @@
     <!-- The package names which can request thermal mitigation. -->
     <string-array name="thermal_mitigation_allowlisted_packages" translatable="false">
     </string-array>
+
+    <!-- Flag specifying whether the AOSP domain selection is enabled or
+         the device should fallback to the modem based domain selection architecture. -->
+    <bool name="config_enable_aosp_domain_selection">false</bool>
 </resources>
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index 44375bb..ede0015 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -52,6 +52,7 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyFrameworkInitializer;
 import android.telephony.TelephonyManager;
+import android.telephony.TelephonyRegistryManager;
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.LocalLog;
@@ -80,6 +81,7 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
 
 /**
@@ -194,6 +196,14 @@
     // requested the dump.
     private static final String DUMP_ARG_REQUESTING_PACKAGE = "--requesting-package";
 
+    // Configs that should always be included when clients calls getConfig[ForSubId] with specified
+    // keys (even configs are not explicitly specified). Those configs have special purpose for the
+    // carrier config APIs to work correctly.
+    private static final String[] CONFIG_SUBSET_METADATA_KEYS = new String[] {
+            CarrierConfigManager.KEY_CARRIER_CONFIG_VERSION_STRING,
+            CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL
+    };
+
     // Handler to process various events.
     //
     // For each phoneId, the event sequence should be:
@@ -799,33 +809,39 @@
     }
 
     private void broadcastConfigChangedIntent(int phoneId, boolean addSubIdExtra) {
+        int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+        int carrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
+        int specificCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
+
         Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT |
                 Intent.FLAG_RECEIVER_FOREGROUND);
         if (addSubIdExtra) {
-            int simApplicationState = TelephonyManager.SIM_STATE_UNKNOWN;
-            int subId = SubscriptionManager.getSubscriptionId(phoneId);
-            if (SubscriptionManager.isValidSubscriptionId(subId)) {
-                TelephonyManager telMgr = TelephonyManager.from(mContext)
-                        .createForSubscriptionId(subId);
-                simApplicationState = telMgr.getSimApplicationState();
-            }
-            logd("Broadcast CARRIER_CONFIG_CHANGED for phone " + phoneId
-                    + " simApplicationState " + simApplicationState);
+            int simApplicationState = getSimApplicationStateForPhone(phoneId);
             // Include subId/carrier id extra only if SIM records are loaded
             if (simApplicationState != TelephonyManager.SIM_STATE_UNKNOWN
                     && simApplicationState != TelephonyManager.SIM_STATE_NOT_READY) {
+                subId = SubscriptionManager.getSubscriptionId(phoneId);
+                carrierId = getCarrierIdForPhoneId(phoneId);
+                specificCarrierId = getSpecificCarrierIdForPhoneId(phoneId);
+                intent.putExtra(TelephonyManager.EXTRA_SPECIFIC_CARRIER_ID, specificCarrierId);
                 SubscriptionManager.putPhoneIdAndSubIdExtra(intent, phoneId);
-                intent.putExtra(TelephonyManager.EXTRA_SPECIFIC_CARRIER_ID,
-                        getSpecificCarrierIdForPhoneId(phoneId));
-                intent.putExtra(TelephonyManager.EXTRA_CARRIER_ID, getCarrierIdForPhoneId(phoneId));
+                intent.putExtra(TelephonyManager.EXTRA_CARRIER_ID, carrierId);
             }
         }
         intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, phoneId);
         intent.putExtra(CarrierConfigManager.EXTRA_REBROADCAST_ON_UNLOCK,
                 mFromSystemUnlocked[phoneId]);
+
+        TelephonyRegistryManager trm = mContext.getSystemService(TelephonyRegistryManager.class);
+        // Unlike broadcast, we wouldn't notify registrants on carrier config change when device is
+        // unlocked. Only real carrier config change will send the notification to registrants.
+        if (trm != null && !mFromSystemUnlocked[phoneId]) {
+            trm.notifyCarrierConfigChanged(phoneId, subId, carrierId, specificCarrierId);
+        }
+
         mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
-        int subId = SubscriptionManager.getSubscriptionId(phoneId);
+
         if (SubscriptionManager.isValidSubscriptionId(subId)) {
             logd("Broadcast CARRIER_CONFIG_CHANGED for phone " + phoneId + ", subId=" + subId);
         } else {
@@ -835,6 +851,17 @@
         mFromSystemUnlocked[phoneId] = false;
     }
 
+    private int getSimApplicationStateForPhone(int phoneId) {
+        int simApplicationState = TelephonyManager.SIM_STATE_UNKNOWN;
+        int subId = SubscriptionManager.getSubscriptionId(phoneId);
+        if (SubscriptionManager.isValidSubscriptionId(subId)) {
+            TelephonyManager telMgr = TelephonyManager.from(mContext)
+                    .createForSubscriptionId(subId);
+            simApplicationState = telMgr.getSimApplicationState();
+        }
+        return simApplicationState;
+    }
+
     /** Binds to the default or carrier config app. */
     private boolean bindToConfigPackage(@NonNull String pkgName, int phoneId, int eventId) {
         logdWithLocalLog("Binding to " + pkgName + " for phone " + phoneId);
@@ -1329,6 +1356,53 @@
     }
 
     @Override
+    @NonNull
+    public PersistableBundle getConfigSubsetForSubIdWithFeature(int subscriptionId,
+            @NonNull String callingPackage, @Nullable String callingFeatureId,
+            @NonNull String[] keys) {
+        Objects.requireNonNull(callingPackage, "Calling package must be non-null");
+        Objects.requireNonNull(keys, "Config keys must be non-null");
+        enforceCallerIsSystemOrRequestingPackage(callingPackage);
+
+        // Permission check is performed inside and an empty bundle will return on failure.
+        // No SecurityException thrown here since most clients expect to retrieve the overridden
+        // value if present or use default one if not
+        PersistableBundle allConfigs = getConfigForSubIdWithFeature(subscriptionId, callingPackage,
+                callingFeatureId);
+        if (allConfigs.isEmpty()) {
+            return allConfigs;
+        }
+        for (String key : keys) {
+            Objects.requireNonNull(key, "Config key must be non-null");
+        }
+
+        PersistableBundle configSubset = new PersistableBundle(
+                keys.length + CONFIG_SUBSET_METADATA_KEYS.length);
+        for (String carrierConfigKey : keys) {
+            Object value = allConfigs.get(carrierConfigKey);
+            if (value == null) {
+                // Filter out keys without values.
+                // In history, many AOSP or OEMs/carriers private configs didn't provide default
+                // values. We have to continue supporting them for now. See b/261776046 for details.
+                continue;
+            }
+            // Config value itself could be PersistableBundle which requires different API to put
+            if (value instanceof PersistableBundle) {
+                configSubset.putPersistableBundle(carrierConfigKey, (PersistableBundle) value);
+            } else {
+                configSubset.putObject(carrierConfigKey, value);
+            }
+        }
+
+        // Configs in CONFIG_SUBSET_ALWAYS_INCLUDED_KEYS should always be included
+        for (String generalKey : CONFIG_SUBSET_METADATA_KEYS) {
+            configSubset.putObject(generalKey, allConfigs.get(generalKey));
+        }
+
+        return configSubset;
+    }
+
+    @Override
     public void overrideConfig(int subscriptionId, @Nullable PersistableBundle overrides,
             boolean persistent) {
         mContext.enforceCallingOrSelfPermission(
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index bc6a7ae..78a734a 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -69,6 +69,8 @@
 import com.android.internal.telephony.TelephonyComponentFactory;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.data.DataEvaluation.DataDisallowedReason;
+import com.android.internal.telephony.domainselection.DomainSelectionResolver;
+import com.android.internal.telephony.emergency.EmergencyStateTracker;
 import com.android.internal.telephony.ims.ImsResolver;
 import com.android.internal.telephony.imsphone.ImsPhone;
 import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
@@ -77,6 +79,7 @@
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.phone.settings.SettingsConstants;
 import com.android.phone.vvm.CarrierVvmPackageInstalledReceiver;
+import com.android.services.telephony.domainselection.TelephonyDomainSelectionService;
 import com.android.services.telephony.rcs.TelephonyRcsService;
 
 import java.io.FileDescriptor;
@@ -159,6 +162,7 @@
     public ImsStateCallbackController mImsStateCallbackController;
     public ImsProvisioningController mImsProvisioningController;
     CarrierConfigLoader configLoader;
+    TelephonyDomainSelectionService mDomainSelectionService;
 
     private Phone phoneInEcm;
 
@@ -442,9 +446,27 @@
             // Inject telephony component factory if configured using other jars.
             XmlResourceParser parser = getResources().getXml(R.xml.telephony_injection);
             TelephonyComponentFactory.getInstance().injectTheComponentFactory(parser);
+
+            // Create DomainSelectionResolver always, but it MUST be initialized only when
+            // the device supports AOSP domain selection architecture and
+            // has new IRadio that supports its related HAL APIs.
+            DomainSelectionResolver.make(this,
+                    getResources().getBoolean(R.bool.config_enable_aosp_domain_selection));
+
             // Initialize the telephony framework
             PhoneFactory.makeDefaultPhones(this);
 
+            // Initialize the DomainSelectionResolver after creating the Phone instance
+            // to check the Radio HAL version.
+            if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
+                mDomainSelectionService = new TelephonyDomainSelectionService(this);
+                DomainSelectionResolver.getInstance().initialize(mDomainSelectionService);
+                // Initialize EmergencyStateTracker if domain selection is supported
+                boolean isSuplDdsSwitchRequiredForEmergencyCall = getResources()
+                        .getBoolean(R.bool.config_gnss_supl_requires_default_data_for_emergency);
+                EmergencyStateTracker.make(this, isSuplDdsSwitchRequiredForEmergencyCall);
+            }
+
             // Only bring up ImsResolver if the device supports having an IMS stack.
             if (getPackageManager().hasSystemFeature(
                     PackageManager.FEATURE_TELEPHONY_IMS)) {
@@ -1086,6 +1108,19 @@
         } catch (Exception e) {
             e.printStackTrace();
         }
+        pw.println("DomainSelectionResolver:");
+        pw.increaseIndent();
+        try {
+            if (DomainSelectionResolver.getInstance() != null) {
+                DomainSelectionResolver.getInstance().dump(fd, pw, args);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        pw.decreaseIndent();
+        if (mDomainSelectionService != null) {
+            mDomainSelectionService.dump(fd, pw, args);
+        }
         pw.decreaseIndent();
         pw.println("mPrevRoamingOperatorNumerics:" + mPrevRoamingOperatorNumerics);
         pw.println("------- End PhoneGlobals -------");
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 1ed6350..ffc67e2 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -17,6 +17,7 @@
 package com.android.phone;
 
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.telephony.TelephonyManager.HAL_SERVICE_NETWORK;
 import static android.telephony.TelephonyManager.HAL_SERVICE_RADIO;
 
 import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_CDMA;
@@ -378,6 +379,9 @@
     private static final int SELECT_P2 = 0;
     private static final int SELECT_P3 = 0x10;
 
+    // Toggling null cipher and integrity support was added in IRadioNetwork 2.1
+    private static final int MIN_NULL_CIPHER_AND_INTEGRITY_VERSION = 201;
+
     /** The singleton instance. */
     private static PhoneInterfaceManager sInstance;
     private static List<String> sThermalMitigationAllowlistedPackages = new ArrayList<>();
@@ -2419,6 +2423,11 @@
         publish();
     }
 
+    @VisibleForTesting
+    public SharedPreferences getSharedPreferences() {
+        return mTelephonySharedPreferences;
+    }
+
     private Phone getDefaultPhone() {
         Phone thePhone = getPhone(getDefaultSubscription());
         return (thePhone != null) ? thePhone : PhoneFactory.getDefaultPhone();
@@ -3635,10 +3644,21 @@
      *
      * @throws SecurityException if the caller does not have the required permission
      */
-    private void enforceModifyPermission() {
+    @VisibleForTesting
+    public void enforceModifyPermission() {
         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
     }
 
+    /**
+     * Make sure the caller has the MODIFY_PHONE_STATE permission.
+     *
+     * @throws SecurityException if the caller does not have the required permission
+     */
+    @VisibleForTesting
+    public void enforceReadPermission() {
+        mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE, null);
+    }
+
     private void enforceActiveEmergencySessionPermission() {
         mApp.enforceCallingOrSelfPermission(
                 android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION, null);
@@ -11655,6 +11675,57 @@
     }
 
     /**
+     * Set whether the device is able to connect with null ciphering or integrity
+     * algorithms. This is a global setting and will apply to all active subscriptions
+     * and all new subscriptions after this.
+     *
+     * @param enabled when true, null  cipher and integrity algorithms are allowed.
+     * @hide
+     */
+    @Override
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public void setNullCipherAndIntegrityEnabled(boolean enabled) {
+        enforceModifyPermission();
+        checkForNullCipherAndIntegritySupport();
+
+        // Persist the state of our preference. Each GsmCdmaPhone instance is responsible
+        // for listening to these preference changes and applying them immediately.
+        SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
+        editor.putBoolean(Phone.PREF_NULL_CIPHER_AND_INTEGRITY_ENABLED, enabled);
+        editor.apply();
+
+        for (Phone phone: PhoneFactory.getPhones()) {
+            phone.handleNullCipherEnabledChange();
+        }
+    }
+
+
+    /**
+     * Get whether the device is able to connect with null ciphering or integrity
+     * algorithms. Note that this retrieves the phone-global preference and not
+     * the state of the radio.
+     *
+     * @throws SecurityException if {@link permission#MODIFY_PHONE_STATE} is not satisfied
+     * @throws UnsupportedOperationException if the device does not support the minimum HAL
+     * version for this feature.
+     * @hide
+     */
+    @Override
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    public boolean isNullCipherAndIntegrityPreferenceEnabled() {
+        enforceReadPermission();
+        checkForNullCipherAndIntegritySupport();
+        return getDefaultPhone().getNullCipherAndIntegrityEnabledPreference();
+    }
+
+    private void checkForNullCipherAndIntegritySupport() {
+        if (getHalVersion(HAL_SERVICE_NETWORK) < MIN_NULL_CIPHER_AND_INTEGRITY_VERSION) {
+            throw new UnsupportedOperationException(
+                    "Null cipher and integrity operations require HAL 2.1 or above");
+        }
+    }
+
+    /**
      * Get the SIM state for the slot index.
      * For Remote-SIMs, this method returns {@link IccCardConstants.State#UNKNOWN}
      *
diff --git a/src/com/android/phone/slice/SlicePurchaseController.java b/src/com/android/phone/slice/SlicePurchaseController.java
index ead6b8c..64261e1 100644
--- a/src/com/android/phone/slice/SlicePurchaseController.java
+++ b/src/com/android/phone/slice/SlicePurchaseController.java
@@ -31,6 +31,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.SharedPreferences;
 import android.net.ConnectivityManager;
 import android.os.AsyncResult;
 import android.os.Handler;
@@ -57,6 +58,9 @@
 import java.net.MalformedURLException;
 import java.net.URISyntaxException;
 import java.net.URL;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.time.format.DateTimeParseException;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -115,8 +119,8 @@
     private static final int EVENT_PURCHASE_UNTHROTTLED = 1;
     /** Slicing config changed. */
     private static final int EVENT_SLICING_CONFIG_CHANGED = 2;
-    /** Display booster notification. */
-    private static final int EVENT_DISPLAY_BOOSTER_NOTIFICATION = 3;
+    /** Start slice purchase application. */
+    private static final int EVENT_START_SLICE_PURCHASE_APP = 3;
     /**
      * Premium capability was not purchased within the timeout specified by
      * {@link CarrierConfigManager#KEY_PREMIUM_CAPABILITY_NOTIFICATION_DISPLAY_TIMEOUT_MILLIS_LONG}.
@@ -170,6 +174,9 @@
     /** Action indicating the purchase request was successful. */
     private static final String ACTION_SLICE_PURCHASE_APP_RESPONSE_SUCCESS =
             "com.android.phone.slice.action.SLICE_PURCHASE_APP_RESPONSE_SUCCESS";
+    /** Action indicating the slice purchase application showed the network boost notification. */
+    private static final String ACTION_SLICE_PURCHASE_APP_RESPONSE_NOTIFICATION_SHOWN =
+            "com.android.phone.slice.action.SLICE_PURCHASE_APP_RESPONSE_NOTIFICATION_SHOWN";
 
     /** Extra for the phone index to send to the slice purchase application. */
     public static final String EXTRA_PHONE_ID = "com.android.phone.slice.extra.PHONE_ID";
@@ -235,12 +242,35 @@
      */
     public static final String EXTRA_INTENT_SUCCESS =
             "com.android.phone.slice.extra.INTENT_SUCCESS";
+    /**
+     * Extra for the PendingIntent that the slice purchase application can send to indicate
+     * that it displayed the network boost notification to the user.
+     * Sends {@link #ACTION_SLICE_PURCHASE_APP_RESPONSE_NOTIFICATION_SHOWN}.
+     */
+    public static final String EXTRA_INTENT_NOTIFICATION_SHOWN =
+            "com.android.phone.slice.extra.NOTIFICATION_SHOWN";
 
-    /** Component name to send an explicit broadcast to SlicePurchaseBroadcastReceiver. */
+    /** Component name for the SlicePurchaseBroadcastReceiver. */
     private static final ComponentName SLICE_PURCHASE_APP_COMPONENT_NAME =
             ComponentName.unflattenFromString(
                     "com.android.carrierdefaultapp/.SlicePurchaseBroadcastReceiver");
 
+    /** Shared preference name for network boost notification preferences. */
+    private static final String NETWORK_BOOST_NOTIFICATION_PREFERENCES =
+            "network_boost_notification_preferences";
+    /** Shared preference key for daily count of network boost notifications. */
+    private static final String KEY_DAILY_NOTIFICATION_COUNT = "daily_notification_count";
+    /** Shared preference key for monthly count of network boost notifications. */
+    private static final String KEY_MONTHLY_NOTIFICATION_COUNT = "monthly_notification_count";
+    /**
+     * Shared preference key for the date the daily or monthly counts of network boost notifications
+     * were last reset.
+     * A String with ISO-8601 format {@code YYYY-MM-DD}, from {@link LocalDate#toString}.
+     * For example, if the count was last updated on December 25, 2020, this would be `2020-12-25`.
+     */
+    private static final String KEY_NOTIFICATION_COUNT_LAST_RESET_DATE =
+            "notification_count_last_reset_date";
+
     /** Map of phone ID -> SlicePurchaseController instances. */
     @NonNull private static final Map<Integer, SlicePurchaseController> sInstances =
             new HashMap<>();
@@ -261,21 +291,37 @@
             mSlicePurchaseControllerBroadcastReceivers = new HashMap<>();
     /** The current network slicing configuration. */
     @Nullable private NetworkSlicingConfig mSlicingConfig;
-    /** Premium network entitlement query API */
+    /** Premium network entitlement query API. */
     @NonNull private final PremiumNetworkEntitlementApi mPremiumNetworkEntitlementApi;
+    /** LocalDate to use when resetting notification counts. {@code null} except when testing. */
+    @Nullable private LocalDate mLocalDate;
+    /** The number of times the network boost notification has been shown today. */
+    private int mDailyCount;
+    /** The number of times the network boost notification has been shown this month. */
+    private int mMonthlyCount;
 
     /**
      * BroadcastReceiver to receive responses from the slice purchase application.
      */
-    @VisibleForTesting
-    public class SlicePurchaseControllerBroadcastReceiver extends BroadcastReceiver {
+    private class SlicePurchaseControllerBroadcastReceiver extends BroadcastReceiver {
         @TelephonyManager.PremiumCapability private final int mCapability;
 
+        /**
+         * Create a SlicePurchaseControllerBroadcastReceiver for the given capability
+         *
+         * @param capability The requested capability to listen to response for.
+         */
         SlicePurchaseControllerBroadcastReceiver(
                 @TelephonyManager.PremiumCapability int capability) {
             mCapability = capability;
         }
 
+        /**
+         * Process responses from the slice purchase application.
+         *
+         * @param context The Context in which the receiver is running.
+         * @param intent The Intent being received.
+         */
         @Override
         public void onReceive(@NonNull Context context, @NonNull Intent intent) {
             String action = intent.getAction();
@@ -340,6 +386,10 @@
                             capability, duration);
                     break;
                 }
+                case ACTION_SLICE_PURCHASE_APP_RESPONSE_NOTIFICATION_SHOWN: {
+                    SlicePurchaseController.getInstance(phoneId).onNotificationShown();
+                    break;
+                }
                 default:
                     reportAnomaly(UUID_UNKNOWN_ACTION, "SlicePurchaseControllerBroadcastReceiver("
                             + TelephonyManager.convertPremiumCapabilityToString(mCapability)
@@ -381,6 +431,7 @@
 
     /**
      * Create a SlicePurchaseController for the given phone on the given looper.
+     *
      * @param phone The Phone to create the SlicePurchaseController for.
      * @param looper The Looper to run the SlicePurchaseController on.
      */
@@ -390,8 +441,19 @@
         mPhone = phone;
         // TODO: Create a cached value for slicing config in DataIndication and initialize here
         mPhone.mCi.registerForSlicingConfigChanged(this, EVENT_SLICING_CONFIG_CHANGED, null);
-        mPremiumNetworkEntitlementApi = new PremiumNetworkEntitlementApi(mPhone,
-                getCarrierConfigs());
+        mPremiumNetworkEntitlementApi =
+                new PremiumNetworkEntitlementApi(mPhone, getCarrierConfigs());
+        updateNotificationCounts();
+    }
+
+    /**
+     * Set the LocalDate to use for resetting daily and monthly notification counts.
+     *
+     * @param localDate The LocalDate instance to use.
+     */
+    @VisibleForTesting
+    public void setLocalDate(@NonNull LocalDate localDate) {
+        mLocalDate = localDate;
     }
 
     @Override
@@ -412,12 +474,12 @@
                 onSlicingConfigChanged();
                 break;
             }
-            case EVENT_DISPLAY_BOOSTER_NOTIFICATION: {
+            case EVENT_START_SLICE_PURCHASE_APP: {
                 int capability = msg.arg1;
                 String appName = (String) msg.obj;
-                logd("EVENT_DISPLAY_BOOSTER_NOTIFICATION: " + appName + " requests capability "
+                logd("EVENT_START_SLICE_PURCHASE_APP: " + appName + " requests capability "
                         + TelephonyManager.convertPremiumCapabilityToString(capability));
-                onDisplayBoosterNotification(capability, appName);
+                onStartSlicePurchaseApplication(capability, appName);
                 break;
             }
             case EVENT_PURCHASE_TIMEOUT: {
@@ -531,10 +593,10 @@
             return;
         }
 
-        // All state checks passed. Mark purchase pending and display the booster notification to
-        // prompt user purchase. Process through the handler since this method is synchronized.
+        // All state checks passed. Mark purchase pending and start the slice purchase application.
+        // Process through the handler since this method is synchronized.
         mPendingPurchaseCapabilities.put(capability, onComplete);
-        sendMessage(obtainMessage(EVENT_DISPLAY_BOOSTER_NOTIFICATION, capability, 0 /* unused */,
+        sendMessage(obtainMessage(EVENT_START_SLICE_PURCHASE_APP, capability, 0 /* unused */,
                 appName));
     }
 
@@ -594,7 +656,7 @@
         }
     }
 
-    private void onDisplayBoosterNotification(@TelephonyManager.PremiumCapability int capability,
+    private void onStartSlicePurchaseApplication(@TelephonyManager.PremiumCapability int capability,
             @NonNull String appName) {
         PremiumNetworkEntitlementResponse premiumNetworkEntitlementResponse =
                 mPremiumNetworkEntitlementApi.checkEntitlementStatus(capability);
@@ -627,6 +689,17 @@
             return;
         }
 
+        updateNotificationCounts();
+        if (mMonthlyCount >= getCarrierConfigs().getInt(
+                CarrierConfigManager.KEY_PREMIUM_CAPABILITY_MAXIMUM_MONTHLY_NOTIFICATION_COUNT_INT)
+                || mDailyCount >= getCarrierConfigs().getInt(
+                CarrierConfigManager.KEY_PREMIUM_CAPABILITY_MAXIMUM_DAILY_NOTIFICATION_COUNT_INT)) {
+            logd("Reached maximum number of network boost notifications.");
+            handlePurchaseResult(capability,
+                    TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED, false);
+            return;
+        }
+
         // Start timeout for purchase completion.
         long timeout = getCarrierConfigs().getLong(CarrierConfigManager
                 .KEY_PREMIUM_CAPABILITY_NOTIFICATION_DISPLAY_TIMEOUT_MILLIS_LONG);
@@ -653,6 +726,8 @@
                 false));
         intent.putExtra(EXTRA_INTENT_SUCCESS, createPendingIntent(
                 ACTION_SLICE_PURCHASE_APP_RESPONSE_SUCCESS, capability, true));
+        intent.putExtra(EXTRA_INTENT_NOTIFICATION_SHOWN, createPendingIntent(
+                ACTION_SLICE_PURCHASE_APP_RESPONSE_NOTIFICATION_SHOWN, capability, false));
         logd("Broadcasting start intent to SlicePurchaseBroadcastReceiver.");
         mPhone.getContext().sendBroadcast(intent);
 
@@ -665,6 +740,7 @@
         filter.addAction(ACTION_SLICE_PURCHASE_APP_RESPONSE_REQUEST_FAILED);
         filter.addAction(ACTION_SLICE_PURCHASE_APP_RESPONSE_NOT_DEFAULT_DATA_SUBSCRIPTION);
         filter.addAction(ACTION_SLICE_PURCHASE_APP_RESPONSE_SUCCESS);
+        filter.addAction(ACTION_SLICE_PURCHASE_APP_RESPONSE_NOTIFICATION_SHOWN);
         mPhone.getContext().registerReceiver(
                 mSlicePurchaseControllerBroadcastReceivers.get(capability), filter);
     }
@@ -742,6 +818,73 @@
         }
     }
 
+    private void onNotificationShown() {
+        SharedPreferences sp =
+                mPhone.getContext().getSharedPreferences(NETWORK_BOOST_NOTIFICATION_PREFERENCES, 0);
+        mDailyCount = sp.getInt((KEY_DAILY_NOTIFICATION_COUNT + mPhone.getPhoneId()), 0) + 1;
+        mMonthlyCount = sp.getInt((KEY_MONTHLY_NOTIFICATION_COUNT + mPhone.getPhoneId()), 0) + 1;
+        logd("Network boost notification was shown " + mDailyCount + " times today and "
+                + mMonthlyCount + " times this month.");
+
+        SharedPreferences.Editor editor = sp.edit();
+        editor.putInt((KEY_DAILY_NOTIFICATION_COUNT + mPhone.getPhoneId()), mDailyCount);
+        editor.putInt((KEY_MONTHLY_NOTIFICATION_COUNT + mPhone.getPhoneId()), mMonthlyCount);
+        editor.apply();
+
+        // Don't call updateNotificationCounts here because it will be called whenever a new
+        // purchase request comes in or when SlicePurchaseController is initialized.
+    }
+
+    /**
+     * Update the current daily and monthly network boost notification counts.
+     * If it has been at least a day since the last daily reset or at least a month since the last
+     * monthly reset, reset the current daily or monthly notification counts.
+     */
+    @VisibleForTesting
+    public void updateNotificationCounts() {
+        SharedPreferences sp =
+                mPhone.getContext().getSharedPreferences(NETWORK_BOOST_NOTIFICATION_PREFERENCES, 0);
+        mDailyCount = sp.getInt((KEY_DAILY_NOTIFICATION_COUNT + mPhone.getPhoneId()), 0);
+        mMonthlyCount = sp.getInt((KEY_MONTHLY_NOTIFICATION_COUNT + mPhone.getPhoneId()), 0);
+
+        if (mLocalDate == null) {
+            // Standardize to UTC to prevent default time zone dependency
+            mLocalDate = LocalDate.now(ZoneId.of("UTC"));
+        }
+        LocalDate lastLocalDate = LocalDate.of(1, 1, 1);
+        String lastLocalDateString = sp.getString(
+                (KEY_NOTIFICATION_COUNT_LAST_RESET_DATE + mPhone.getPhoneId()), "");
+        if (!TextUtils.isEmpty(lastLocalDateString)) {
+            try {
+                lastLocalDate = LocalDate.parse(lastLocalDateString);
+            } catch (DateTimeParseException e) {
+                loge("Error parsing LocalDate from SharedPreferences: " + e);
+            }
+        }
+        logd("updateNotificationCounts: mDailyCount=" + mDailyCount + ", mMonthlyCount="
+                + mMonthlyCount + ", mLocalDate=" + mLocalDate + ", lastLocalDate="
+                + lastLocalDate);
+
+        boolean resetMonthly = lastLocalDate.getYear() != mLocalDate.getYear()
+                || lastLocalDate.getMonthValue() != mLocalDate.getMonthValue();
+        boolean resetDaily = resetMonthly
+                || lastLocalDate.getDayOfMonth() != mLocalDate.getDayOfMonth();
+        if (resetDaily) {
+            logd("Resetting daily" + (resetMonthly ? " and monthly" : "") + " notification count.");
+            SharedPreferences.Editor editor = sp.edit();
+            if (resetMonthly) {
+                mMonthlyCount = 0;
+                editor.putInt((KEY_MONTHLY_NOTIFICATION_COUNT + mPhone.getPhoneId()),
+                        mMonthlyCount);
+            }
+            mDailyCount = 0;
+            editor.putInt((KEY_DAILY_NOTIFICATION_COUNT + mPhone.getPhoneId()), mDailyCount);
+            editor.putString((KEY_NOTIFICATION_COUNT_LAST_RESET_DATE + mPhone.getPhoneId()),
+                    mLocalDate.toString());
+            editor.apply();
+        }
+    }
+
     @Nullable private PersistableBundle getCarrierConfigs() {
         return mPhone.getContext().getSystemService(CarrierConfigManager.class)
                 .getConfigForSubId(mPhone.getSubId());
@@ -813,7 +956,6 @@
         }
         int capabilityServiceType = getSliceServiceType(capability);
         for (NetworkSliceInfo sliceInfo : mSlicingConfig.getSliceInfo()) {
-            // TODO: check if TrafficDescriptor has realtime capability slice
             if (sliceInfo.getSliceServiceType() == capabilityServiceType
                     && sliceInfo.getStatus() == NetworkSliceInfo.SLICE_STATUS_ALLOWED) {
                 return true;
@@ -824,7 +966,9 @@
 
     @NetworkSliceInfo.SliceServiceType private int getSliceServiceType(
             @TelephonyManager.PremiumCapability int capability) {
-        // TODO: Implement properly -- potentially need to add new slice service types?
+        if (capability == TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY) {
+            return NetworkSliceInfo.SLICE_SERVICE_TYPE_URLLC;
+        }
         return NetworkSliceInfo.SLICE_SERVICE_TYPE_NONE;
     }
 
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 962053c..9d36c48 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -48,11 +48,13 @@
 import android.telephony.ServiceState.RilRadioTechnology;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.telephony.emergency.EmergencyNumber;
 import android.telephony.ims.ImsCallProfile;
 import android.telephony.ims.ImsReasonInfo;
 import android.telephony.ims.ImsStreamMediaProfile;
 import android.telephony.ims.RtpHeaderExtension;
 import android.telephony.ims.RtpHeaderExtensionType;
+import android.telephony.ims.feature.MmTelFeature;
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Pair;
@@ -801,6 +803,13 @@
             Log.i(this, "onReceivedDtmfDigit: digit=%c", digit);
             mDtmfTransport.onDtmfReceived(digit);
         }
+
+        @Override
+        public void onAudioModeIsVoipChanged(int imsAudioHandler) {
+            boolean isVoip = imsAudioHandler == MmTelFeature.AUDIO_HANDLER_ANDROID;
+            Log.i(this, "onAudioModeIsVoipChanged isVoip =" + isVoip);
+            setAudioModeIsVoip(isVoip);
+        }
     };
 
     private TelephonyConnectionService mTelephonyConnectionService;
@@ -925,6 +934,8 @@
     private final Set<TelephonyConnectionListener> mTelephonyListeners = Collections.newSetFromMap(
             new ConcurrentHashMap<TelephonyConnectionListener, Boolean>(8, 0.9f, 1));
 
+    private Integer mEmergencyServiceCategory = null;
+
     protected TelephonyConnection(com.android.internal.telephony.Connection originalConnection,
             String callId, @android.telecom.Call.Details.CallDirection int callDirection) {
         setCallDirection(callDirection);
@@ -2158,7 +2169,7 @@
         mPhoneForEvents = null;
     }
 
-    @VisibleForTesting
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED)
     public void hangup(int telephonyDisconnectCode) {
         if (mOriginalConnection != null) {
             mHangupDisconnectCause = telephonyDisconnectCode;
@@ -2184,6 +2195,7 @@
                 Log.e(this, e, "Call to Connection.hangup failed with exception");
             }
         } else {
+            mTelephonyConnectionService.onLocalHangup(this);
             if (getState() == STATE_DISCONNECTED) {
                 Log.i(this, "hangup called on an already disconnected call!");
                 close();
@@ -2444,6 +2456,29 @@
                     setTelephonyConnectionRinging();
                     break;
                 case DISCONNECTED:
+                    if (mTelephonyConnectionService != null) {
+                        ImsReasonInfo reasonInfo = null;
+                        if (isImsConnection()) {
+                            ImsPhoneConnection imsPhoneConnection =
+                                    (ImsPhoneConnection) mOriginalConnection;
+                            reasonInfo = imsPhoneConnection.getImsReasonInfo();
+                            if (reasonInfo != null && reasonInfo.getCode()
+                                    == ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL) {
+                                EmergencyNumber emergencyNumber =
+                                        imsPhoneConnection.getEmergencyNumberInfo();
+                                if (emergencyNumber != null) {
+                                    mEmergencyServiceCategory =
+                                            emergencyNumber.getEmergencyServiceCategoryBitmask();
+                                }
+                            }
+                        }
+
+                        if (mTelephonyConnectionService.maybeReselectDomain(this,
+                                  mOriginalConnection.getPreciseDisconnectCause(), reasonInfo)) {
+                            break;
+                        }
+                    }
+
                     if (shouldTreatAsEmergencyCall()
                             && (cause
                             == android.telephony.DisconnectCause.EMERGENCY_TEMP_FAILURE
@@ -3831,4 +3866,21 @@
     public List<TelephonyConnectionListener> getTelephonyConnectionListeners() {
         return new ArrayList<>(mTelephonyListeners);
     }
+
+    /**
+     * @return An {@link Integer} instance of the emergency service category.
+     */
+    public @Nullable Integer getEmergencyServiceCategory() {
+        return mEmergencyServiceCategory;
+    }
+
+    /**
+     * Sets the emergency service category.
+     *
+     * @param eccCategory The emergency service category.
+     */
+    @VisibleForTesting
+    public void setEmergencyServiceCategory(int eccCategory) {
+        mEmergencyServiceCategory = eccCategory;
+    }
 }
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index e86a1ae..172407a 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -16,6 +16,7 @@
 
 package com.android.services.telephony;
 
+import static android.telephony.DomainSelectionService.SELECTOR_TYPE_CALLING;
 import static android.telephony.TelephonyManager.HAL_SERVICE_VOICE;
 
 import android.annotation.NonNull;
@@ -40,17 +41,23 @@
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
 import android.telecom.VideoProfile;
+import android.telephony.Annotation.DisconnectCauses;
 import android.telephony.CarrierConfigManager;
+import android.telephony.DomainSelectionService;
+import android.telephony.EmergencyRegResult;
+import android.telephony.NetworkRegistrationInfo;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.RadioAccessFamily;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.emergency.EmergencyNumber;
+import android.telephony.ims.ImsReasonInfo;
 import android.text.TextUtils;
 import android.util.Pair;
 import android.view.WindowManager;
 
+import com.android.ims.ImsManager;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.Call;
 import com.android.internal.telephony.CallStateException;
@@ -64,6 +71,10 @@
 import com.android.internal.telephony.SubscriptionController;
 import com.android.internal.telephony.d2d.Communicator;
 import com.android.internal.telephony.data.PhoneSwitcher;
+import com.android.internal.telephony.domainselection.DomainSelectionConnection;
+import com.android.internal.telephony.domainselection.DomainSelectionResolver;
+import com.android.internal.telephony.domainselection.EmergencyCallDomainSelectionConnection;
+import com.android.internal.telephony.emergency.EmergencyStateTracker;
 import com.android.internal.telephony.imsphone.ImsExternalCallTracker;
 import com.android.internal.telephony.imsphone.ImsPhone;
 import com.android.internal.telephony.imsphone.ImsPhoneConnection;
@@ -89,6 +100,7 @@
 import java.util.Queue;
 import java.util.Set;
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
 import java.util.function.Consumer;
 import java.util.regex.Pattern;
 
@@ -179,6 +191,13 @@
     @VisibleForTesting
     public Pair<WeakReference<TelephonyConnection>, Queue<Phone>> mEmergencyRetryCache;
     private DeviceState mDeviceState = new DeviceState();
+    private EmergencyStateTracker mEmergencyStateTracker;
+    private DomainSelectionResolver mDomainSelectionResolver;
+    private EmergencyCallDomainSelectionConnection mEmergencyCallDomainSelectionConnection;
+    private TelephonyConnection mEmergencyConnection;
+    private String mEmergencyCallId = null;
+    private Executor mDomainSelectionMainExecutor;
+    private ImsManager mImsManager = null;
 
     /**
      * Keeps track of the status of a SIM slot.
@@ -504,6 +523,42 @@
     }
 
     /**
+     * A listener for emergency calls.
+     */
+    private final TelephonyConnection.TelephonyConnectionListener mEmergencyConnectionListener =
+            new TelephonyConnection.TelephonyConnectionListener() {
+        @Override
+        public void onStateChanged(Connection connection, @Connection.ConnectionState int state) {
+            if (connection != null) {
+                TelephonyConnection c = (TelephonyConnection) connection;
+                Log.i(this, "onStateChanged callId=" + c.getTelecomCallId() + ", state=" + state);
+                if (c.getState() == Connection.STATE_ACTIVE) {
+                    mEmergencyStateTracker.onEmergencyCallStateChanged(
+                            c.getOriginalConnection().getState(), c.getTelecomCallId());
+                    c.removeTelephonyConnectionListener(mEmergencyConnectionListener);
+                    releaseEmergencyCallDomainSelection(false);
+                }
+            }
+        }
+    };
+
+    private final DomainSelectionConnection.DomainSelectionConnectionCallback
+            mEmergencyDomainSelectionConnectionCallback =
+                    new DomainSelectionConnection.DomainSelectionConnectionCallback() {
+        @Override
+        public void onSelectionTerminated(@DisconnectCauses int cause) {
+            if (mEmergencyCallDomainSelectionConnection != null) {
+                Log.i(this, "onSelectionTerminated cause=" + cause);
+                mEmergencyCallDomainSelectionConnection = null;
+                if (mEmergencyConnection != null) {
+                    mEmergencyConnection.hangup(android.telephony.DisconnectCause.OUT_OF_NETWORK);
+                    mEmergencyConnection = null;
+                }
+            }
+        }
+    };
+
+    /**
      * A listener to actionable events specific to the TelephonyConnection.
      */
     private final TelephonyConnection.TelephonyConnectionListener mTelephonyConnectionListener =
@@ -542,6 +597,8 @@
         TelecomAccountRegistry.getInstance(this).setTelephonyConnectionService(this);
         mHoldTracker = new HoldTracker();
         mIsTtyEnabled = mDeviceState.isTtyModeEnabled(this);
+        mDomainSelectionMainExecutor = getApplicationContext().getMainExecutor();
+        mDomainSelectionResolver = DomainSelectionResolver.getInstance();
 
         IntentFilter intentFilter = new IntentFilter(
                 TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED);
@@ -809,6 +866,16 @@
                 /* Note: when not an emergency, handle can be null for unknown callers */
                 handle == null ? null : handle.getSchemeSpecificPart());
 
+        if (mDomainSelectionResolver.isDomainSelectionSupported()) {
+            if (isEmergencyNumber) {
+                final Connection resultConnection =
+                        placeEmergencyConnection(phone,
+                                request, numberToDial, isTestEmergencyNumber,
+                                handle, needToTurnOnRadio);
+                if (resultConnection != null) return resultConnection;
+            }
+        }
+
         if (needToTurnOnRadio) {
             final Uri resultHandle = handle;
             final int originalPhoneType = phone.getPhoneType();
@@ -1715,6 +1782,10 @@
                 }
                 updatePhoneAccount(c, newPhoneToUse);
             }
+            if (mDomainSelectionResolver.isDomainSelectionSupported()) {
+                onEmergencyRedial(c, newPhoneToUse);
+                return;
+            }
             placeOutgoingConnection(c, newPhoneToUse, videoState, connExtras);
         } else {
             // We have run out of Phones to use. Disconnect the call and destroy the connection.
@@ -1770,6 +1841,7 @@
         try {
             if (phone != null) {
                 boolean isEmergency = mTelephonyManagerProxy.isCurrentEmergencyNumber(number);
+                Log.i(this, "placeOutgoingConnection isEmergency=" + isEmergency);
                 if (isEmergency) {
                     if (!getAllConnections().isEmpty()) {
                         if (!shouldHoldForEmergencyCall(phone)) {
@@ -1862,6 +1934,366 @@
         }
     }
 
+    @SuppressWarnings("FutureReturnValueIgnored")
+    private Connection placeEmergencyConnection(
+            final Phone phone, final ConnectionRequest request,
+            final String numberToDial, final boolean isTestEmergencyNumber,
+            final Uri handle, final boolean needToTurnOnRadio) {
+
+        final Connection resultConnection =
+                getTelephonyConnection(request, numberToDial, true, handle, phone);
+
+        if (resultConnection instanceof TelephonyConnection) {
+            Log.i(this, "placeEmergencyConnection");
+
+            mIsEmergencyCallPending = true;
+            ((TelephonyConnection) resultConnection).addTelephonyConnectionListener(
+                    mEmergencyConnectionListener);
+
+            if (mEmergencyStateTracker == null) {
+                mEmergencyStateTracker = EmergencyStateTracker.getInstance();
+            }
+
+            mEmergencyCallId = resultConnection.getTelecomCallId();
+            CompletableFuture<Integer> future = mEmergencyStateTracker.startEmergencyCall(
+                    phone, mEmergencyCallId, isTestEmergencyNumber);
+            future.thenAccept((result) -> {
+                Log.d(this, "startEmergencyCall-complete result=" + result);
+                if (result == android.telephony.DisconnectCause.NOT_DISCONNECTED) {
+                    createEmergencyConnection(phone, (TelephonyConnection) resultConnection,
+                            numberToDial, request, needToTurnOnRadio,
+                            mEmergencyStateTracker.getEmergencyRegResult());
+                } else {
+                    mEmergencyConnection = null;
+                    String reason = "Couldn't setup emergency call";
+                    if (result == android.telephony.DisconnectCause.POWER_OFF) {
+                        reason = "Failed to turn on radio.";
+                    }
+                    ((TelephonyConnection) resultConnection).setTelephonyConnectionDisconnected(
+                            mDisconnectCauseFactory.toTelecomDisconnectCause(result, reason));
+                    ((TelephonyConnection) resultConnection).close();
+                    mIsEmergencyCallPending = false;
+                }
+            });
+            mEmergencyConnection = (TelephonyConnection) resultConnection;
+            return resultConnection;
+        }
+        Log.i(this, "placeEmergencyConnection returns null");
+        return null;
+    }
+
+    @SuppressWarnings("FutureReturnValueIgnored")
+    private void createEmergencyConnection(final Phone phone,
+            final TelephonyConnection resultConnection, final String number,
+            final ConnectionRequest request, boolean needToTurnOnRadio,
+            final EmergencyRegResult regResult) {
+        Log.i(this, "createEmergencyConnection");
+
+        if (phone.getImsPhone() == null) {
+            // Dialing emergency calls over IMS is not available without ImsPhone instance.
+            Log.w(this, "createEmergencyConnection no ImsPhone");
+            dialCsEmergencyCall(phone, resultConnection, request);
+            return;
+        }
+
+        ImsManager imsManager = mImsManager;
+        if (imsManager == null) {
+            // mImsManager is not null only while unit test.
+            imsManager = ImsManager.getInstance(phone.getContext(), phone.getPhoneId());
+        }
+        if (!imsManager.isNonTtyOrTtyOnVolteEnabled()) {
+            Log.w(this, "createEmergencyConnection - TTY on VoLTE is not supported.");
+            dialCsEmergencyCall(phone, resultConnection, request);
+            return;
+        }
+
+        DomainSelectionConnection selectConnection =
+                mDomainSelectionResolver.getDomainSelectionConnection(
+                        phone, SELECTOR_TYPE_CALLING, true);
+
+        if (selectConnection == null) {
+            // While the domain selection service is enabled, the valid
+            // {@link DomainSelectionConnection} is not available.
+            // This can happen when the domain selection service is not available.
+            Log.w(this, "createEmergencyConnection - no selectionConnection");
+            dialCsEmergencyCall(phone, resultConnection, request);
+            return;
+        }
+
+        mEmergencyCallDomainSelectionConnection =
+                (EmergencyCallDomainSelectionConnection) selectConnection;
+
+        DomainSelectionService.SelectionAttributes attr =
+                EmergencyCallDomainSelectionConnection.getSelectionAttributes(
+                        phone.getPhoneId(), phone.getSubId(), needToTurnOnRadio,
+                        request.getTelecomCallId(), number, 0, null, regResult);
+
+        CompletableFuture<Integer> future =
+                mEmergencyCallDomainSelectionConnection.createEmergencyConnection(
+                        attr, mEmergencyDomainSelectionConnectionCallback);
+        future.thenAcceptAsync((result) -> {
+            Log.d(this, "createEmergencyConnection-complete result=" + result);
+            Bundle extras = request.getExtras();
+            extras.putInt(PhoneConstants.EXTRA_DIAL_DOMAIN, result);
+            placeOutgoingConnection(request, resultConnection, phone);
+            mIsEmergencyCallPending = false;
+        }, mDomainSelectionMainExecutor);
+    }
+
+    private void dialCsEmergencyCall(final Phone phone,
+            final TelephonyConnection resultConnection, final ConnectionRequest request) {
+        Log.d(this, "dialCsEmergencyCall");
+        Bundle extras = request.getExtras();
+        extras.putInt(PhoneConstants.EXTRA_DIAL_DOMAIN, NetworkRegistrationInfo.DOMAIN_CS);
+        mDomainSelectionMainExecutor.execute(
+                () -> placeOutgoingConnection(request, resultConnection, phone));
+    }
+
+    private void releaseEmergencyCallDomainSelection(boolean cancel) {
+        if (mEmergencyCallDomainSelectionConnection != null) {
+            if (cancel) mEmergencyCallDomainSelectionConnection.cancelSelection();
+            else mEmergencyCallDomainSelectionConnection.finishSelection();
+            mEmergencyCallDomainSelectionConnection = null;
+        }
+        mIsEmergencyCallPending = false;
+        mEmergencyConnection = null;
+    }
+
+    /**
+     * Determine whether reselection of domain is required or not.
+     * @param c the {@link Connection} instance.
+     * @param callFailCause the reason why CS call is disconnected. Allowed values are defined in
+     * {@link com.android.internal.telephony.CallFailCause}.
+     * @param reasonInfo the reason why PS call is disconnected.
+     * @return {@code true} if reselection of domain is required.
+     */
+    public boolean maybeReselectDomain(final TelephonyConnection c,
+            int callFailCause, ImsReasonInfo reasonInfo) {
+        if (!mDomainSelectionResolver.isDomainSelectionSupported()) return false;
+
+        Log.i(this, "maybeReselectDomain csCause=" +  callFailCause + ", psCause=" + reasonInfo);
+        if (TextUtils.equals(mEmergencyCallId, c.getTelecomCallId())) {
+            if (mEmergencyCallDomainSelectionConnection != null) {
+                return maybeReselectDomainForEmergencyCall(c, callFailCause, reasonInfo);
+            }
+            Log.i(this, "maybeReselectDomain endCall()");
+            mEmergencyStateTracker.endCall(c.getTelecomCallId());
+            mEmergencyCallId = null;
+            return false;
+        }
+
+        if (reasonInfo != null
+                && reasonInfo.getCode() == ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL) {
+            onEmergencyRedial(c, c.getPhone());
+            return true;
+        }
+
+        return false;
+    }
+
+    private boolean maybeReselectDomainForEmergencyCall(final TelephonyConnection c,
+            int callFailCause, ImsReasonInfo reasonInfo) {
+        Log.i(this, "maybeReselectDomainForEmergencyCall "
+                + "csCause=" +  callFailCause + ", psCause=" + reasonInfo);
+
+        // EMERGENCY_TEMP_FAILURE and EMERGENCY_PERM_FAILURE shall be handled after
+        // reselecting new {@link Phone} in {@link #retryOutgoingOriginalConnection()}.
+        if (c.getOriginalConnection() != null
+                && c.getOriginalConnection().getDisconnectCause()
+                        != android.telephony.DisconnectCause.EMERGENCY_TEMP_FAILURE
+                && c.getOriginalConnection().getDisconnectCause()
+                        != android.telephony.DisconnectCause.EMERGENCY_PERM_FAILURE
+                && c.getOriginalConnection().getDisconnectCause()
+                        != android.telephony.DisconnectCause.LOCAL
+                && c.getOriginalConnection().getDisconnectCause()
+                        != android.telephony.DisconnectCause.POWER_OFF) {
+
+            DomainSelectionService.SelectionAttributes attr =
+                    EmergencyCallDomainSelectionConnection.getSelectionAttributes(
+                            c.getPhone().getPhoneId(), c.getPhone().getSubId(), false,
+                            c.getTelecomCallId(), c.getAddress().getSchemeSpecificPart(),
+                            callFailCause, reasonInfo, null);
+
+            CompletableFuture<Integer> future =
+                    mEmergencyCallDomainSelectionConnection.reselectDomain(attr);
+            if (future != null) {
+                future.thenAcceptAsync((result) -> {
+                    Log.d(this, "reselectDomain-complete");
+                    onEmergencyRedialOnDomain(c, c.getPhone(), result);
+                }, mDomainSelectionMainExecutor);
+                return true;
+            }
+        }
+
+        Log.i(this, "maybeReselectDomainForEmergencyCall endCall()");
+        c.removeTelephonyConnectionListener(mEmergencyConnectionListener);
+        mEmergencyStateTracker.endCall(c.getTelecomCallId());
+        releaseEmergencyCallDomainSelection(true);
+
+        return false;
+    }
+
+    private void onEmergencyRedialOnDomain(TelephonyConnection connection,
+            final Phone phone, @NetworkRegistrationInfo.Domain int domain) {
+        Log.i(this, "onEmergencyRedialOnDomain phoneId=" + phone.getPhoneId()
+                + ", domain=" + DomainSelectionService.getDomainName(domain));
+
+        String number = connection.getAddress().getSchemeSpecificPart();
+
+        // Indicates undetectable emergency number with DialArgs
+        boolean isEmergency = false;
+        int eccCategory = EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED;
+        if (connection.getEmergencyServiceCategory() != null) {
+            isEmergency = true;
+            eccCategory = connection.getEmergencyServiceCategory();
+            Log.i(this, "onEmergencyRedialOnDomain eccCategory=" + eccCategory);
+        }
+
+        Bundle extras = new Bundle();
+        extras.putInt(PhoneConstants.EXTRA_DIAL_DOMAIN, domain);
+
+        com.android.internal.telephony.Connection originalConnection =
+                connection.getOriginalConnection();
+        try {
+            if (phone != null) {
+                originalConnection = phone.dial(number, new ImsPhone.ImsDialArgs.Builder()
+                        .setVideoState(VideoProfile.STATE_AUDIO_ONLY)
+                        .setIntentExtras(extras)
+                        .setRttTextStream(connection.getRttTextStream())
+                        .setIsEmergency(isEmergency)
+                        .setEccCategory(eccCategory)
+                        .build(),
+                        connection::registerForCallEvents);
+            }
+        } catch (CallStateException e) {
+            Log.e(this, e, "onEmergencyRedialOnDomain, exception: " + e);
+        }
+        if (originalConnection == null) {
+            Log.d(this, "onEmergencyRedialOnDomain, phone.dial returned null");
+            connection.setDisconnected(
+                    mDisconnectCauseFactory.toTelecomDisconnectCause(
+                                android.telephony.DisconnectCause.ERROR_UNSPECIFIED,
+                                "unknown error"));
+        } else {
+            connection.setOriginalConnection(originalConnection);
+        }
+    }
+
+    @SuppressWarnings("FutureReturnValueIgnored")
+    private void onEmergencyRedial(final TelephonyConnection c, final Phone phone) {
+        Log.i(this, "onEmergencyRedial phoneId=" + phone.getPhoneId());
+
+        final String number = c.getAddress().getSchemeSpecificPart();
+        final boolean isTestEmergencyNumber = isEmergencyNumberTestNumber(number);
+
+        mIsEmergencyCallPending = true;
+        c.addTelephonyConnectionListener(mEmergencyConnectionListener);
+
+        if (mEmergencyStateTracker == null) {
+            mEmergencyStateTracker = EmergencyStateTracker.getInstance();
+        }
+
+        mEmergencyCallId = c.getTelecomCallId();
+        CompletableFuture<Integer> future = mEmergencyStateTracker.startEmergencyCall(
+                phone, mEmergencyCallId, isTestEmergencyNumber);
+        future.thenAccept((result) -> {
+            Log.d(this, "onEmergencyRedial-complete result=" + result);
+            if (result == android.telephony.DisconnectCause.NOT_DISCONNECTED) {
+
+                DomainSelectionConnection selectConnection =
+                        mDomainSelectionResolver.getDomainSelectionConnection(
+                                phone, SELECTOR_TYPE_CALLING, true);
+
+                if (selectConnection == null) {
+                    Log.w(this, "onEmergencyRedial no selectionConnection, dial CS emergency call");
+                    mIsEmergencyCallPending = false;
+                    mDomainSelectionMainExecutor.execute(
+                            () -> recreateEmergencyConnection(c, phone,
+                                    NetworkRegistrationInfo.DOMAIN_CS));
+                    return;
+                }
+
+                mEmergencyCallDomainSelectionConnection =
+                        (EmergencyCallDomainSelectionConnection) selectConnection;
+
+                mEmergencyConnection = c;
+
+                DomainSelectionService.SelectionAttributes attr =
+                        EmergencyCallDomainSelectionConnection.getSelectionAttributes(
+                                phone.getPhoneId(),
+                                phone.getSubId(), false,
+                                c.getTelecomCallId(),
+                                c.getAddress().getSchemeSpecificPart(),
+                                0, null, mEmergencyStateTracker.getEmergencyRegResult());
+
+                CompletableFuture<Integer> domainFuture =
+                        mEmergencyCallDomainSelectionConnection.createEmergencyConnection(
+                                attr, mEmergencyDomainSelectionConnectionCallback);
+                domainFuture.thenAcceptAsync((domain) -> {
+                    Log.d(this, "onEmergencyRedial-createEmergencyConnection-complete domain="
+                            + domain);
+                    recreateEmergencyConnection(c, phone, domain);
+                    mIsEmergencyCallPending = false;
+                }, mDomainSelectionMainExecutor);
+            } else {
+                c.setTelephonyConnectionDisconnected(
+                        mDisconnectCauseFactory.toTelecomDisconnectCause(result, "unknown error"));
+                c.close();
+                mIsEmergencyCallPending = false;
+            }
+        });
+    }
+
+    private void recreateEmergencyConnection(final TelephonyConnection connection,
+            final Phone phone, final @NetworkRegistrationInfo.Domain int result) {
+        Log.d(this, "recreateEmergencyConnection result=" + result);
+        if (!getAllConnections().isEmpty()) {
+            if (!shouldHoldForEmergencyCall(phone)) {
+                // If we do not support holding ongoing calls for an outgoing
+                // emergency call, disconnect the ongoing calls.
+                for (Connection c : getAllConnections()) {
+                    if (!c.equals(connection)
+                            && c.getState() != Connection.STATE_DISCONNECTED
+                            && c instanceof TelephonyConnection) {
+                        ((TelephonyConnection) c).hangup(
+                                android.telephony.DisconnectCause
+                                        .OUTGOING_EMERGENCY_CALL_PLACED);
+                    }
+                }
+                for (Conference c : getAllConferences()) {
+                    if (c.getState() != Connection.STATE_DISCONNECTED) {
+                        c.onDisconnect();
+                    }
+                }
+            } else if (!isVideoCallHoldAllowed(phone)) {
+                // If we do not support holding ongoing video call for an outgoing
+                // emergency call, disconnect the ongoing video call.
+                for (Connection c : getAllConnections()) {
+                    if (!c.equals(connection)
+                            && c.getState() == Connection.STATE_ACTIVE
+                            && VideoProfile.isVideo(c.getVideoState())
+                            && c instanceof TelephonyConnection) {
+                        ((TelephonyConnection) c).hangup(
+                                android.telephony.DisconnectCause
+                                        .OUTGOING_EMERGENCY_CALL_PLACED);
+                        break;
+                    }
+                }
+            }
+        }
+        onEmergencyRedialOnDomain(connection, phone, result);
+    }
+
+    protected void onLocalHangup(TelephonyConnection c) {
+        if (TextUtils.equals(mEmergencyCallId, c.getTelecomCallId())) {
+            Log.i(this, "onLocalHangup " + mEmergencyCallId);
+            c.removeTelephonyConnectionListener(mEmergencyConnectionListener);
+            mEmergencyStateTracker.endCall(c.getTelecomCallId());
+            releaseEmergencyCallDomainSelection(true);
+            mEmergencyCallId = null;
+        }
+    }
+
     private boolean isVideoCallHoldAllowed(Phone phone) {
          CarrierConfigManager cfgManager = (CarrierConfigManager)
                 phone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
diff --git a/src/com/android/services/telephony/domainselection/DomainSelectorBase.java b/src/com/android/services/telephony/domainselection/DomainSelectorBase.java
new file mode 100644
index 0000000..1a7c992
--- /dev/null
+++ b/src/com/android/services/telephony/domainselection/DomainSelectorBase.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony.domainselection;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
+import android.telephony.DomainSelectionService.SelectionAttributes;
+import android.telephony.DomainSelector;
+import android.telephony.TransportSelectorCallback;
+import android.telephony.WwanSelectorCallback;
+import android.util.IndentingPrintWriter;
+import android.util.LocalLog;
+import android.util.Log;
+
+import com.android.internal.annotations.Keep;
+
+import java.io.PrintWriter;
+
+/**
+ * An abstract base class to implement domain selector for a specific use case.
+ */
+@Keep
+public abstract class DomainSelectorBase extends Handler implements DomainSelector {
+    /**
+     * A listener used to inform the DomainSelectorService that this DomainSelector has been
+     * destroyed.
+     */
+    public interface DestroyListener {
+        /**
+         * Called when the specified domain selector is being destroyed.
+         * This MUST be called when this domain selector is no longer available after
+         * {@link DomainSelector#finishSelection} called.
+         */
+        void onDomainSelectorDestroyed(DomainSelectorBase selector);
+    }
+
+    // Persistent Logging
+    protected final LocalLog mEventLog = new LocalLog(30);
+    protected final Context mContext;
+    protected final ImsStateTracker mImsStateTracker;
+    protected SelectionAttributes mSelectionAttributes;
+    protected TransportSelectorCallback mTransportSelectorCallback;
+    protected WwanSelectorCallback mWwanSelectorCallback;
+    private final int mSlotId;
+    private final int mSubId;
+    private final DestroyListener mDestroyListener;
+    private final String mLogTag;
+
+    public DomainSelectorBase(Context context, int slotId, int subId, @NonNull Looper looper,
+            @NonNull ImsStateTracker imsStateTracker, @NonNull DestroyListener destroyListener,
+            String logTag) {
+        super(looper);
+        mContext = context;
+        mImsStateTracker = imsStateTracker;
+        mSlotId = slotId;
+        mSubId = subId;
+        mDestroyListener = destroyListener;
+        mLogTag = logTag;
+    }
+
+    /**
+     * Selects a domain for the specified attributes and callback.
+     *
+     * @param attr The attributes required to determine the domain.
+     * @param callback The callback called when the transport selection is completed.
+     */
+    public abstract void selectDomain(SelectionAttributes attr, TransportSelectorCallback callback);
+
+    /**
+     * Destroys this domain selector.
+     */
+    protected void destroy() {
+        removeCallbacksAndMessages(null);
+        notifyDomainSelectorDestroyed();
+    }
+
+    /**
+     * Notifies the application that this domain selector is being destroyed.
+     */
+    protected void notifyDomainSelectorDestroyed() {
+        if (mDestroyListener != null) {
+            mDestroyListener.onDomainSelectorDestroyed(this);
+        }
+    }
+
+    /**
+     * Returns the slot index for this domain selector.
+     */
+    protected int getSlotId() {
+        return mSlotId;
+    }
+
+    /**
+     * Returns the subscription index for this domain selector.
+     */
+    protected int getSubId() {
+        return mSubId;
+    }
+
+    /**
+     * Dumps this instance into a readable format for dumpsys usage.
+     */
+    protected void dump(@NonNull PrintWriter pw) {
+        IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
+        ipw.println(mLogTag + ":");
+        ipw.increaseIndent();
+        ipw.println("SlotId: " + getSlotId());
+        ipw.println("SubId: " + getSubId());
+        mEventLog.dump(ipw);
+        ipw.decreaseIndent();
+    }
+
+    protected void logd(String s) {
+        Log.d(mLogTag, "[" + getSlotId() + "|" + getSubId() + "] " + s);
+    }
+
+    protected void logi(String s) {
+        Log.i(mLogTag, "[" + getSlotId() + "|" + getSubId() + "] " + s);
+        mEventLog.log("[" + getSlotId() + "|" + getSubId() + "] " + s);
+    }
+
+    protected void loge(String s) {
+        Log.e(mLogTag, "[" + getSlotId() + "|" + getSubId() + "] " + s);
+        mEventLog.log("[" + getSlotId() + "|" + getSubId() + "] " + s);
+    }
+}
diff --git a/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java b/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
new file mode 100644
index 0000000..9aaf6da
--- /dev/null
+++ b/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
@@ -0,0 +1,1047 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony.domainselection;
+
+import static android.telephony.AccessNetworkConstants.AccessNetworkType.CDMA2000;
+import static android.telephony.AccessNetworkConstants.AccessNetworkType.EUTRAN;
+import static android.telephony.AccessNetworkConstants.AccessNetworkType.NGRAN;
+import static android.telephony.AccessNetworkConstants.AccessNetworkType.UNKNOWN;
+import static android.telephony.AccessNetworkConstants.AccessNetworkType.UTRAN;
+import static android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
+import static android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WLAN;
+import static android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
+import static android.telephony.BarringInfo.BARRING_SERVICE_TYPE_EMERGENCY;
+import static android.telephony.CarrierConfigManager.ImsEmergency.DOMAIN_CS;
+import static android.telephony.CarrierConfigManager.ImsEmergency.DOMAIN_PS_3GPP;
+import static android.telephony.CarrierConfigManager.ImsEmergency.DOMAIN_PS_NON_3GPP;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_CALL_SETUP_TIMER_ON_CURRENT_NETWORK_SEC_INT;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_CDMA_PREFERRED_NUMBERS_STRING_ARRAY;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_DOMAIN_PREFERENCE_ROAMING_INT_ARRAY;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_LTE_PREFERRED_AFTER_NR_FAILED_BOOL;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_NETWORK_SCAN_TYPE_INT;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_OVER_CS_ROAMING_SUPPORTED_ACCESS_NETWORK_TYPES_INT_ARRAY;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_OVER_CS_SUPPORTED_ACCESS_NETWORK_TYPES_INT_ARRAY;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_OVER_IMS_ROAMING_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_OVER_IMS_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_REQUIRES_IMS_REGISTRATION_BOOL;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_REQUIRES_VOLTE_ENABLED_BOOL;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_SCAN_TIMER_SEC_INT;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_MAXIMUM_NUMBER_OF_EMERGENCY_TRIES_OVER_VOWIFI_INT;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_PREFER_IMS_EMERGENCY_WHEN_VOICE_CALLS_ON_CS_BOOL;
+import static android.telephony.CarrierConfigManager.ImsEmergency.SCAN_TYPE_FULL_SERVICE_FOLLOWED_BY_LIMITED_SERVICE;
+import static android.telephony.NetworkRegistrationInfo.REGISTRATION_STATE_HOME;
+import static android.telephony.NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING;
+
+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.os.PowerManager;
+import android.os.SystemProperties;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
+import android.telephony.AccessNetworkConstants.RadioAccessNetworkType;
+import android.telephony.AccessNetworkConstants.TransportType;
+import android.telephony.BarringInfo;
+import android.telephony.CarrierConfigManager;
+import android.telephony.DomainSelectionService;
+import android.telephony.DomainSelectionService.SelectionAttributes;
+import android.telephony.EmergencyRegResult;
+import android.telephony.NetworkRegistrationInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.telephony.TransportSelectorCallback;
+import android.telephony.ims.ImsManager;
+import android.telephony.ims.ImsMmTelManager;
+import android.text.TextUtils;
+import android.util.LocalLog;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.IntFunction;
+
+/**
+ * Selects the domain for emergency calling.
+ */
+public class EmergencyCallDomainSelector extends DomainSelectorBase
+        implements ImsStateTracker.BarringInfoListener, ImsStateTracker.ImsStateListener {
+    private static final String TAG = "DomainSelector-EmergencyCall";
+    private static final boolean DBG = (SystemProperties.getInt("ro.debuggable", 0) == 1);
+    private static final int LOG_SIZE = 50;
+
+    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;
+
+    private static final int NOT_SUPPORTED = -1;
+
+    private static final LocalLog sLocalLog = new LocalLog(LOG_SIZE);
+
+    private boolean mIsEmergencyBarred;
+    private boolean mImsRegistered;
+    private boolean mIsVoiceCapable;
+    private boolean mBarringInfoReceived;
+    private boolean mImsRegStateReceived;
+    private boolean mMmTelCapabilitiesReceived;
+    private int mVoWifiTrialCount = 0;
+
+    private @RadioAccessNetworkType int mCsNetworkType = UNKNOWN;
+    private @RadioAccessNetworkType int mPsNetworkType = UNKNOWN;
+    private @RadioAccessNetworkType int mLastNetworkType = UNKNOWN;
+    private @TransportType int mLastTransportType = TRANSPORT_TYPE_INVALID;
+    private @DomainSelectionService.EmergencyScanType int mScanType;
+    private @RadioAccessNetworkType List<Integer> mLastPreferredNetworks;
+
+    private CancellationSignal mCancelSignal;
+
+    private @RadioAccessNetworkType int[] mImsRatsConfig;
+    private @RadioAccessNetworkType int[] mCsRatsConfig;
+    private @RadioAccessNetworkType int[] mImsRoamRatsConfig;
+    private @RadioAccessNetworkType int[] mCsRoamRatsConfig;
+    private @CarrierConfigManager.ImsEmergency.EmergencyDomain int[] mDomainPreference;
+    private @CarrierConfigManager.ImsEmergency.EmergencyDomain int[] mDomainPreferenceRoam;
+    private List<String> mCdmaPreferredNumbers;
+    private boolean mPreferImsWhenCallsOnCs;
+    private int mScanTimeout;
+    private int mMaxNumOfVoWifiTries;
+    private @CarrierConfigManager.ImsEmergency.EmergencyScanType int mPreferredNetworkScanType;
+    private int mCallSetupTimerOnCurrentRatSec;
+    private boolean mRequiresImsRegistration;
+    private boolean mRequiresVoLteEnabled;
+    private boolean mLtePreferredAfterNrFailure;
+    private boolean mTryCsWhenPsFails;
+
+    /** Indicates whether this instance is deactivated. */
+    private boolean mDestroyed = false;
+    /** Indicates whether emergency network scan is requested. */
+    private boolean mIsScanRequested = false;
+    /** Indicates whether selected domain has been notified. */
+    private boolean mDomainSelected = false;
+    /**
+     * Indicates whether {@link #selectDomain(SelectionAttributes, TransportSelectionCallback)}
+     * is called or not.
+     */
+    private boolean mDomainSelectionRequested = false;
+
+    private final PowerManager.WakeLock mPartialWakeLock;
+
+    /** Constructor. */
+    public EmergencyCallDomainSelector(Context context, int slotId, int subId,
+            @NonNull Looper looper, @NonNull ImsStateTracker imsStateTracker,
+            @NonNull DestroyListener destroyListener) {
+        super(context, slotId, subId, looper, imsStateTracker, destroyListener, TAG);
+
+        mImsStateTracker.addBarringInfoListener(this);
+        mImsStateTracker.addImsStateListener(this);
+
+        PowerManager pm = context.getSystemService(PowerManager.class);
+        mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+
+        acquireWakeLock();
+    }
+
+    @Override
+    public void handleMessage(Message msg) {
+        if (mDestroyed) return;
+
+        switch(msg.what) {
+            case MSG_START_DOMAIN_SELECTION:
+                startDomainSelection();
+                break;
+
+            case MSG_NETWORK_SCAN_TIMEOUT:
+                handleNetworkScanTimeout();
+                break;
+
+            case MSG_NETWORK_SCAN_RESULT:
+                handleScanResult((EmergencyRegResult) msg.obj);
+                break;
+
+            default:
+                super.handleMessage(msg);
+                break;
+        }
+    }
+
+    /**
+     * Handles the scan result.
+     *
+     * @param result The scan result.
+     */
+    private void handleScanResult(EmergencyRegResult result) {
+        logi("handleScanResult result=" + result);
+
+        if (result.getAccessNetwork() == UNKNOWN) {
+            if ((mPreferredNetworkScanType == SCAN_TYPE_FULL_SERVICE_FOLLOWED_BY_LIMITED_SERVICE)
+                      || (mScanType == DomainSelectionService.SCAN_TYPE_FULL_SERVICE)) {
+                mScanType = DomainSelectionService.SCAN_TYPE_LIMITED_SERVICE;
+                mWwanSelectorCallback.onRequestEmergencyNetworkScan(
+                        mLastPreferredNetworks, mScanType, mCancelSignal,
+                        (regResult) -> {
+                            logi("requestScan-onComplete");
+                            sendMessage(obtainMessage(MSG_NETWORK_SCAN_RESULT, regResult));
+                        });
+            } else {
+                // Continuous scan, do not start a new timer.
+                requestScan(false);
+            }
+            return;
+        }
+
+        removeMessages(MSG_NETWORK_SCAN_TIMEOUT);
+        onWwanNetworkTypeSelected(result.getAccessNetwork());
+        mIsScanRequested = false;
+    }
+
+    @Override
+    public void cancelSelection() {
+        logi("cancelSelection");
+        finishSelection();
+    }
+
+    @Override
+    public void reselectDomain(SelectionAttributes attr) {
+        logi("reselectDomain tryCsWhenPsFails=" + mTryCsWhenPsFails + ", attr=" + attr);
+        mSelectionAttributes = attr;
+        if (mTryCsWhenPsFails) {
+            mTryCsWhenPsFails = false;
+            mCsNetworkType = getSelectableCsNetworkType();
+            logi("reselectDomain tryCs=" + accessNetworkTypeToString(mCsNetworkType));
+            if (mCsNetworkType != UNKNOWN) {
+                onWwanNetworkTypeSelected(mCsNetworkType);
+                return;
+            }
+        } else if (getImsNetworkTypeConfiguration().isEmpty()
+                || (mRequiresVoLteEnabled && !isAdvancedCallingSettingEnabled())) {
+            // Emergency call over IMS is not supported.
+            mCsNetworkType = UTRAN;
+            onWwanNetworkTypeSelected(mCsNetworkType);
+            return;
+        }
+
+        if (mLastTransportType == TRANSPORT_TYPE_WLAN) {
+            // Dialing over Wi-Fi failed. Try scanning cellular networks.
+            onWwanSelected(() -> {
+                requestScan(true, false, true);
+                mDomainSelected = false;
+            });
+            return;
+        }
+
+        requestScan(true);
+        mDomainSelected = false;
+    }
+
+    @Override
+    public void finishSelection() {
+        logi("finishSelection");
+        destroy();
+    }
+
+    @Override
+    public void onBarringInfoUpdated(BarringInfo barringInfo) {
+        if (mDestroyed) return;
+
+        mBarringInfoReceived = true;
+        BarringInfo.BarringServiceInfo serviceInfo =
+                barringInfo.getBarringServiceInfo(BARRING_SERVICE_TYPE_EMERGENCY);
+        mIsEmergencyBarred = serviceInfo.isBarred();
+        logi("onBarringInfoUpdated emergencyBarred=" + mIsEmergencyBarred
+                + ", serviceInfo=" + serviceInfo);
+        selectDomain();
+    }
+
+    @Override
+    public void selectDomain(SelectionAttributes attr, TransportSelectorCallback cb) {
+        logi("selectDomain attr=" + attr);
+        mTransportSelectorCallback = cb;
+        mSelectionAttributes = attr;
+
+        sendEmptyMessage(MSG_START_DOMAIN_SELECTION);
+    }
+
+    private void startDomainSelection() {
+        logi("startDomainSelection");
+        updateCarrierConfiguration();
+        mDomainSelectionRequested = true;
+        if (SubscriptionManager.isValidSubscriptionId(getSubId())) {
+            selectDomain();
+        } else {
+            logi("startDomainSelection invalid subId");
+            onImsRegistrationStateChanged();
+            onImsMmTelCapabilitiesChanged();
+        }
+    }
+
+    @Override
+    public void onImsMmTelFeatureAvailableChanged() {
+        // DOMAIN_CS shall be selected when ImsService is not available.
+        // TODO(b/258289015) Recover the temporary failure in ImsService connection.
+    }
+
+    @Override
+    public void onImsRegistrationStateChanged() {
+        mImsRegStateReceived = true;
+        mImsRegistered = mImsStateTracker.isImsRegistered();
+        logi("onImsRegistrationStateChanged " + mImsRegistered);
+        selectDomain();
+    }
+
+    @Override
+    public void onImsMmTelCapabilitiesChanged() {
+        mMmTelCapabilitiesReceived = true;
+        mIsVoiceCapable = mImsStateTracker.isImsVoiceCapable();
+        logi("onImsMmTelCapabilitiesChanged " + mIsVoiceCapable);
+        selectDomain();
+    }
+
+    /**
+     * Caches the configuration.
+     */
+    private void updateCarrierConfiguration() {
+        CarrierConfigManager configMgr = mContext.getSystemService(CarrierConfigManager.class);
+        PersistableBundle b = configMgr.getConfigForSubId(getSubId());
+        if (b == null) {
+            b = CarrierConfigManager.getDefaultConfig();
+        }
+
+        mImsRatsConfig =
+                b.getIntArray(KEY_EMERGENCY_OVER_IMS_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY);
+        mImsRoamRatsConfig = b.getIntArray(
+                KEY_EMERGENCY_OVER_IMS_ROAMING_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY);
+        if (!SubscriptionManager.isValidSubscriptionId(getSubId())) {
+            // Default configuration includes only EUTRAN . In case of no SIM, add NGRAN.
+            mImsRatsConfig = new int[] { EUTRAN, NGRAN };
+            mImsRoamRatsConfig = new int[] { EUTRAN, NGRAN };
+        }
+
+        mCsRatsConfig =
+                b.getIntArray(KEY_EMERGENCY_OVER_CS_SUPPORTED_ACCESS_NETWORK_TYPES_INT_ARRAY);
+        mCsRoamRatsConfig = b.getIntArray(
+                KEY_EMERGENCY_OVER_CS_ROAMING_SUPPORTED_ACCESS_NETWORK_TYPES_INT_ARRAY);
+        mDomainPreference = b.getIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY);
+        mDomainPreferenceRoam = b.getIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_ROAMING_INT_ARRAY);
+        mPreferImsWhenCallsOnCs = b.getBoolean(
+                KEY_PREFER_IMS_EMERGENCY_WHEN_VOICE_CALLS_ON_CS_BOOL);
+        mScanTimeout = b.getInt(KEY_EMERGENCY_SCAN_TIMER_SEC_INT);
+        mMaxNumOfVoWifiTries = b.getInt(KEY_MAXIMUM_NUMBER_OF_EMERGENCY_TRIES_OVER_VOWIFI_INT);
+        mPreferredNetworkScanType = b.getInt(KEY_EMERGENCY_NETWORK_SCAN_TYPE_INT);
+        mCallSetupTimerOnCurrentRatSec = b.getInt(
+                KEY_EMERGENCY_CALL_SETUP_TIMER_ON_CURRENT_NETWORK_SEC_INT);
+        mRequiresImsRegistration = b.getBoolean(KEY_EMERGENCY_REQUIRES_IMS_REGISTRATION_BOOL);
+        mRequiresVoLteEnabled = b.getBoolean(KEY_EMERGENCY_REQUIRES_VOLTE_ENABLED_BOOL);
+        mLtePreferredAfterNrFailure = b.getBoolean(
+                KEY_EMERGENCY_LTE_PREFERRED_AFTER_NR_FAILED_BOOL);
+        String[] numbers = b.getStringArray(KEY_EMERGENCY_CDMA_PREFERRED_NUMBERS_STRING_ARRAY);
+
+        if (mImsRatsConfig == null) mImsRatsConfig = new int[0];
+        if (mCsRatsConfig == null) mCsRatsConfig = new int[0];
+        if (mImsRoamRatsConfig == null) mImsRoamRatsConfig = new int[0];
+        if (mCsRoamRatsConfig == null) mCsRoamRatsConfig = new int[0];
+        if (mDomainPreference == null) mDomainPreference = new int[0];
+        if (mDomainPreferenceRoam == null) mDomainPreferenceRoam = new int[0];
+        if (numbers == null) numbers = new String[0];
+
+        logi("updateCarrierConfiguration "
+                + "imsRats=" + arrayToString(mImsRatsConfig,
+                        EmergencyCallDomainSelector::accessNetworkTypeToString)
+                + ", csRats=" + arrayToString(mCsRatsConfig,
+                        EmergencyCallDomainSelector::accessNetworkTypeToString)
+                + ", imsRoamRats=" + arrayToString(mImsRoamRatsConfig,
+                        EmergencyCallDomainSelector::accessNetworkTypeToString)
+                + ", csRoamRats=" + arrayToString(mCsRoamRatsConfig,
+                        EmergencyCallDomainSelector::accessNetworkTypeToString)
+                + ", domainPref=" + arrayToString(mDomainPreference,
+                        EmergencyCallDomainSelector::domainPreferenceToString)
+                + ", domainPrefRoam=" + arrayToString(mDomainPreferenceRoam,
+                        EmergencyCallDomainSelector::domainPreferenceToString)
+                + ", preferImsOnCs=" + mPreferImsWhenCallsOnCs
+                + ", scanTimeout=" + mScanTimeout
+                + ", maxNumOfVoWifiTries=" + mMaxNumOfVoWifiTries
+                + ", preferredScanType=" + carrierConfigNetworkScanTypeToString(
+                        mPreferredNetworkScanType)
+                + ", callSetupTimer=" + mCallSetupTimerOnCurrentRatSec
+                + ", requiresImsReg=" + mRequiresImsRegistration
+                + ", requiresVoLteEnabled=" + mRequiresVoLteEnabled
+                + ", ltePreferredAfterNr=" + mLtePreferredAfterNrFailure
+                + ", cdmaPreferredNumbers=" + arrayToString(numbers));
+
+        mCdmaPreferredNumbers = Arrays.asList(numbers);
+
+        if ((mPreferredNetworkScanType == CarrierConfigManager.ImsEmergency.SCAN_TYPE_FULL_SERVICE)
+                || (mPreferredNetworkScanType
+                        == SCAN_TYPE_FULL_SERVICE_FOLLOWED_BY_LIMITED_SERVICE)) {
+            mScanType = DomainSelectionService.SCAN_TYPE_FULL_SERVICE;
+        } else {
+            mScanType = DomainSelectionService.SCAN_TYPE_NO_PREFERENCE;
+        }
+    }
+
+    private void selectDomain() {
+        // State updated right after creation.
+        if (!mDomainSelectionRequested) return;
+
+        // Emergency network scan requested has not been completed.
+        if (mIsScanRequested) return;
+
+        // Domain selection completed, {@link #reselectDomain()} will restart domain selection.
+        if (mDomainSelected) return;
+
+        if (!mBarringInfoReceived || !mImsRegStateReceived || !mMmTelCapabilitiesReceived) {
+            logi("selectDomain not received"
+                    + " BarringInfo, IMS registration state, or MMTEL capabilities");
+            return;
+        }
+
+        if (isWifiPreferred()) {
+            onWlanSelected();
+            return;
+        }
+
+        onWwanSelected(this::selectDomainInternal);
+    }
+
+    private void selectDomainInternal() {
+        if (getImsNetworkTypeConfiguration().isEmpty()
+                || (mRequiresVoLteEnabled && !isAdvancedCallingSettingEnabled())) {
+            // Emergency call over IMS is not supported.
+            mCsNetworkType = UTRAN;
+            onWwanNetworkTypeSelected(mCsNetworkType);
+            return;
+        }
+
+        boolean csInService = isCsInService();
+        boolean psInService = isPsInService();
+
+        if (!csInService && !psInService) {
+            mPsNetworkType = getSelectablePsNetworkType(false);
+            logi("selectDomain limited service ps=" + accessNetworkTypeToString(mPsNetworkType));
+            if (mPsNetworkType == UNKNOWN) {
+                requestScan(true);
+            } else {
+                onWwanNetworkTypeSelected(mPsNetworkType);
+            }
+            return;
+        }
+
+        // Domain selection per 3GPP TS 23.167 Table H.1.
+        // PS is preferred in case selection between CS and PS is implementation option.
+        mCsNetworkType = UNKNOWN;
+        mPsNetworkType = UNKNOWN;
+        if (csInService) mCsNetworkType = getSelectableCsNetworkType();
+        if (psInService) mPsNetworkType = getSelectablePsNetworkType(true);
+
+        boolean csAvailable = mCsNetworkType != UNKNOWN;
+        boolean psAvailable = mPsNetworkType != UNKNOWN;
+
+        logi("selectDomain CS={" + csInService + ", " + accessNetworkTypeToString(mCsNetworkType)
+                + "}, PS={" + psInService + ", " + accessNetworkTypeToString(mPsNetworkType) + "}");
+        if (csAvailable && psAvailable) {
+            if (mPreferImsWhenCallsOnCs || isImsRegisteredWithVoiceCapability()) {
+                mTryCsWhenPsFails = true;
+                onWwanNetworkTypeSelected(mPsNetworkType);
+            } else if (isDeactivatedSim()) {
+                // Deactivated SIM but PS is in service and supports emergency calls.
+                onWwanNetworkTypeSelected(mPsNetworkType);
+            } else {
+                onWwanNetworkTypeSelected(mCsNetworkType);
+            }
+        } else if (psAvailable) {
+            if (!mRequiresImsRegistration || isImsRegisteredWithVoiceCapability()) {
+                onWwanNetworkTypeSelected(mPsNetworkType);
+            } else if (isDeactivatedSim()) {
+                // Deactivated SIM but PS is in service and supports emergency calls.
+                onWwanNetworkTypeSelected(mPsNetworkType);
+            } else {
+                // Carrier configuration requires IMS registration for emergency services over PS,
+                // but not registered. Try CS emergency call.
+                requestScan(true, true);
+            }
+        } else if (csAvailable) {
+            onWwanNetworkTypeSelected(mCsNetworkType);
+        } else {
+            // PS is in service but not supports emergency calls.
+            if (mRequiresImsRegistration && !isImsRegisteredWithVoiceCapability()) {
+                // Carrier configuration requires IMS registration for emergency services over PS,
+                // but not registered. Try CS emergency call.
+                requestScan(true, true);
+            } else {
+                requestScan(true);
+            }
+        }
+    }
+
+    /**
+     * Requests network scan.
+     *
+     * @param startVoWifiTimer Indicates whether a VoWifi timer will be started.
+     */
+    private void requestScan(boolean startVoWifiTimer) {
+        requestScan(startVoWifiTimer, false);
+    }
+
+    /**
+     * Requests network scan.
+     *
+     * @param startVoWifiTimer Indicates whether a VoWifi timer will be started.
+     * @param csPreferred Indicates whether CS preferred scan is requested.
+     */
+    private void requestScan(boolean startVoWifiTimer, boolean csPreferred) {
+        requestScan(startVoWifiTimer, csPreferred, false);
+    }
+
+    /**
+     * Requests network scan.
+     *
+     * @param startVoWifiTimer Indicates whether a VoWifi timer will be started.
+     * @param csPreferred Indicates whether CS preferred scan is requested.
+     * @param wifiFailed Indicates dialing over Wi-Fi has failed.
+     */
+    private void requestScan(boolean startVoWifiTimer, boolean csPreferred, boolean wifiFailed) {
+        logi("requestScan timer=" + startVoWifiTimer + ", csPreferred=" + csPreferred
+                + ", wifiFailed=" + wifiFailed);
+
+        mCancelSignal = new CancellationSignal();
+        // In case dialing over Wi-Fi has failed, do not the change the domain preference.
+        if (!wifiFailed) mLastPreferredNetworks = getNextPreferredNetworks(csPreferred);
+
+        if (isInRoaming()
+                && (mPreferredNetworkScanType == DomainSelectionService.SCAN_TYPE_FULL_SERVICE)) {
+            // FULL_SERVICE only preference is available only when not in roaming.
+            mScanType = DomainSelectionService.SCAN_TYPE_NO_PREFERENCE;
+        }
+
+        mIsScanRequested = true;
+        mWwanSelectorCallback.onRequestEmergencyNetworkScan(
+                mLastPreferredNetworks, mScanType, mCancelSignal,
+                (result) -> {
+                    logi("requestScan-onComplete");
+                    sendMessage(obtainMessage(MSG_NETWORK_SCAN_RESULT, result));
+                });
+
+        if (startVoWifiTimer && SubscriptionManager.isValidSubscriptionId(getSubId())) {
+            if (isEmcOverWifiSupported()
+                    && mScanTimeout > 0 && mVoWifiTrialCount < mMaxNumOfVoWifiTries) {
+                logi("requestScan start scan timer");
+                // remove any pending timers.
+                removeMessages(MSG_NETWORK_SCAN_TIMEOUT);
+                sendEmptyMessageDelayed(MSG_NETWORK_SCAN_TIMEOUT, mScanTimeout);
+            }
+        }
+    }
+
+    /**
+     * Gets the list of preferred network type for the new scan request.
+     *
+     * @param csPreferred Indicates whether CS preferred scan is requested.
+     * @return The list of preferred network types.
+     */
+    private @RadioAccessNetworkType List<Integer> getNextPreferredNetworks(boolean csPreferred) {
+        List<Integer> preferredNetworks = new ArrayList<>();
+
+        List<Integer> domains = getDomainPreference();
+        int psPriority = domains.indexOf(DOMAIN_PS_3GPP);
+        int csPriority = domains.indexOf(DOMAIN_CS);
+        logi("getNextPreferredNetworks psPriority=" + psPriority + ", csPriority=" + csPriority
+                + ", csPreferred=" + csPreferred
+                + ", lastNetworkType=" + accessNetworkTypeToString(mLastNetworkType));
+
+        if (!csPreferred && mLastNetworkType == UNKNOWN) {
+            // Generate the list per the domain preference.
+
+            if (psPriority == NOT_SUPPORTED && csPriority == NOT_SUPPORTED) {
+                // should not reach here.
+            } else if (psPriority == NOT_SUPPORTED && csPriority > NOT_SUPPORTED) {
+                // CS networks only.
+                preferredNetworks = generatePreferredNetworks(getCsNetworkTypeConfiguration());
+            } else if (psPriority > NOT_SUPPORTED && csPriority == NOT_SUPPORTED) {
+                // PS networks only.
+                preferredNetworks = generatePreferredNetworks(getImsNetworkTypeConfiguration());
+            } else if (psPriority < csPriority) {
+                // PS preferred.
+                preferredNetworks = generatePreferredNetworks(getImsNetworkTypeConfiguration(),
+                        getCsNetworkTypeConfiguration());
+            } else {
+                // CS preferred.
+                generatePreferredNetworks(getCsNetworkTypeConfiguration(),
+                        getImsNetworkTypeConfiguration());
+            }
+        } else if (csPreferred || mLastNetworkType == EUTRAN || mLastNetworkType == NGRAN) {
+            if (!csPreferred && mLastNetworkType == NGRAN && mLtePreferredAfterNrFailure) {
+                // LTE is preferred after dialing over NR failed.
+                List<Integer> imsRats = getImsNetworkTypeConfiguration();
+                imsRats.remove(new Integer(NGRAN));
+                preferredNetworks = generatePreferredNetworks(imsRats,
+                        getCsNetworkTypeConfiguration());
+            } else  if (csPriority > NOT_SUPPORTED) {
+                // PS tried, generate the list with CS preferred.
+                preferredNetworks = generatePreferredNetworks(getCsNetworkTypeConfiguration(),
+                        getImsNetworkTypeConfiguration());
+            } else {
+                // CS not suppored.
+                generatePreferredNetworks(getImsNetworkTypeConfiguration());
+            }
+        } else {
+            // CS tried, generate the list with PS preferred.
+            if (psPriority > NOT_SUPPORTED) {
+                preferredNetworks = generatePreferredNetworks(getImsNetworkTypeConfiguration(),
+                        getCsNetworkTypeConfiguration());
+            } else {
+                // PS not suppored.
+                preferredNetworks = generatePreferredNetworks(getCsNetworkTypeConfiguration());
+            }
+        }
+
+        return preferredNetworks;
+    }
+
+    private @RadioAccessNetworkType List<Integer> generatePreferredNetworks(List<Integer>...lists) {
+        List<Integer> preferredNetworks = new ArrayList<>();
+        for (List<Integer> list : lists) {
+            preferredNetworks.addAll(list);
+        }
+
+        return preferredNetworks;
+    }
+
+    private void handleNetworkScanTimeout() {
+        if (isImsRegisteredWithVoiceCapability()
+                && isImsRegisteredOverWifi()) {
+            if (mCancelSignal != null) {
+                mCancelSignal.cancel();
+                mCancelSignal = null;
+            }
+            onWlanSelected();
+        }
+    }
+
+    /**
+     * Determines whether CS is in service.
+     *
+     * @return {@code true} if CS is in service.
+     */
+    private boolean isCsInService() {
+        EmergencyRegResult regResult = mSelectionAttributes.getEmergencyRegResult();
+        if (regResult == null) return false;
+
+        int regState = regResult.getRegState();
+        int domain = regResult.getDomain();
+
+        if ((regState == REGISTRATION_STATE_HOME || regState == REGISTRATION_STATE_ROAMING)
+                && ((domain & NetworkRegistrationInfo.DOMAIN_CS) > 0)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Determines the network type of the circuit-switched(CS) network.
+     *
+     * @return The network type of the CS network.
+     */
+    private @RadioAccessNetworkType int getSelectableCsNetworkType() {
+        EmergencyRegResult regResult = mSelectionAttributes.getEmergencyRegResult();
+        logi("getSelectableCsNetworkType regResult=" + regResult);
+        if (regResult == null) return UNKNOWN;
+
+        int accessNetwork = regResult.getAccessNetwork();
+
+        List<Integer> ratList = getCsNetworkTypeConfiguration();
+        if (ratList.contains(accessNetwork)) {
+            return accessNetwork;
+        }
+
+        if ((regResult.getAccessNetwork() == EUTRAN)
+                && ((regResult.getDomain() & NetworkRegistrationInfo.DOMAIN_CS) > 0)) {
+            return UTRAN;
+        }
+
+        return UNKNOWN;
+    }
+
+    /**
+     * Determines whether PS is in service.
+     *
+     * @return {@code true} if PS is in service.
+     */
+    private boolean isPsInService() {
+        EmergencyRegResult regResult = mSelectionAttributes.getEmergencyRegResult();
+        if (regResult == null) return false;
+
+        int regState = regResult.getRegState();
+        int domain = regResult.getDomain();
+
+        if ((regState == REGISTRATION_STATE_HOME || regState == REGISTRATION_STATE_ROAMING)
+                && ((domain & NetworkRegistrationInfo.DOMAIN_PS) > 0)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Determines the network type supporting emergency services over packet-switched(PS) network.
+     *
+     * @param inService Indicates whether PS is IN_SERVICE state.
+     * @return The network type if the network supports emergency services over PS network.
+     */
+    private @RadioAccessNetworkType int getSelectablePsNetworkType(boolean inService) {
+        EmergencyRegResult regResult = mSelectionAttributes.getEmergencyRegResult();
+        logi("getSelectablePsNetworkType regResult=" + regResult);
+        if (regResult == null) return UNKNOWN;
+
+        int accessNetwork = regResult.getAccessNetwork();
+        List<Integer> ratList = getImsNetworkTypeConfiguration();
+        if (ratList.contains(accessNetwork)) {
+            if (mIsEmergencyBarred) {
+                logi("sgetSelectablePsNetworkType barred");
+                return UNKNOWN;
+            }
+            if (accessNetwork == NGRAN) {
+                return (regResult.getNwProvidedEmc() > 0 && regResult.isVopsSupported())
+                        ? NGRAN : UNKNOWN;
+            } else if (accessNetwork == EUTRAN) {
+                return (regResult.isEmcBearerSupported()
+                                && (regResult.isVopsSupported() || !inService))
+                        ? EUTRAN : UNKNOWN;
+            }
+        }
+
+        return UNKNOWN;
+    }
+
+    /**
+     * Determines whether the SIM is a deactivated one.
+     *
+     * @return {@code true} if the SIM is a deactivated one.
+     */
+    private boolean isDeactivatedSim() {
+        if (SubscriptionManager.isValidSubscriptionId(getSubId())) {
+            TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
+            tm = tm.createForSubscriptionId(getSubId());
+            int state = tm.getDataActivationState();
+            logi("isDeactivatedSim state=" + state);
+            return (state == TelephonyManager.SIM_ACTIVATION_STATE_DEACTIVATED);
+        }
+        return false;
+    }
+
+    /**
+     * Determines whether emergency call over Wi-Fi is allowed.
+     *
+     * @return {@code true} if emergency call over Wi-Fi allowed.
+     */
+    private boolean isEmcOverWifiSupported() {
+        if (SubscriptionManager.isValidSubscriptionId(getSubId())) {
+            List<Integer> domains = getDomainPreference();
+            return domains.contains(DOMAIN_PS_NON_3GPP);
+        }
+        return false;
+    }
+
+    /**
+     * Determines whether Wi-Fi is preferred when IMS registered over Wi-Fi.
+     *
+     * @return {@code true} if Wi-Fi is preferred when IMS registered over Wi-Fi.
+     */
+    private boolean isWifiPreferred() {
+        if (SubscriptionManager.isValidSubscriptionId(getSubId())) {
+            List<Integer> domains = getDomainPreference();
+            int priority = domains.indexOf(DOMAIN_PS_NON_3GPP);
+            logi("isWifiPreferred priority=" + priority);
+
+            if ((priority == 0)
+                    && isImsRegisteredWithVoiceCapability()
+                    && isImsRegisteredOverWifi()) {
+                logi("isWifiPreferred try emergency call over Wi-Fi");
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    private boolean isAdvancedCallingSettingEnabled() {
+        try {
+            if (SubscriptionManager.isValidSubscriptionId(getSubId())) {
+                ImsManager imsMngr = mContext.getSystemService(ImsManager.class);
+                ImsMmTelManager mmTelManager = imsMngr.getImsMmTelManager(getSubId());
+                boolean result = mmTelManager.isAdvancedCallingSettingEnabled();
+                logi("isAdvancedCallingSettingEnabled " + result);
+                return result;
+            }
+        } catch (Exception e) {
+            logi("isAdvancedCallingSettingEnabled e=" + e);
+        }
+        return true;
+    }
+
+    private @NonNull List<Integer> getImsNetworkTypeConfiguration() {
+        int[] rats = mImsRatsConfig;
+        if (isInRoaming()) rats = mImsRoamRatsConfig;
+
+        List<Integer> ratList = new ArrayList<Integer>();
+        for (int i = 0; i < rats.length; i++) {
+            ratList.add(rats[i]);
+        }
+        return ratList;
+    }
+
+    private @NonNull List<Integer> getCsNetworkTypeConfiguration() {
+        int[] rats = mCsRatsConfig;
+        if (isInRoaming()) rats = mCsRoamRatsConfig;
+
+        List<Integer> ratList = new ArrayList<Integer>();
+        for (int i = 0; i < rats.length; i++) {
+            ratList.add(rats[i]);
+        }
+
+        if (!mCdmaPreferredNumbers.isEmpty()) {
+            if (mCdmaPreferredNumbers.contains(mSelectionAttributes.getNumber())) {
+                // The number will be dialed over CDMA.
+                ratList.clear();
+                ratList.add(new Integer(CDMA2000));
+            } else {
+                // The number will be dialed over UTRAN or GERAN.
+                ratList.remove(new Integer(CDMA2000));
+            }
+        }
+
+        return ratList;
+    }
+
+    private @NonNull List<Integer> getDomainPreference() {
+        int[] domains = mDomainPreference;
+        if (isInRoaming()) domains = mDomainPreferenceRoam;
+
+        List<Integer> domainList = new ArrayList<Integer>();
+        for (int i = 0; i < domains.length; i++) {
+            domainList.add(domains[i]);
+        }
+        return domainList;
+    }
+
+    private boolean isInRoaming() {
+        if (!SubscriptionManager.isValidSubscriptionId(getSubId())) return false;
+
+        TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
+        tm = tm.createForSubscriptionId(getSubId());
+        String netIso = tm.getNetworkCountryIso();
+
+        EmergencyRegResult regResult = mSelectionAttributes.getEmergencyRegResult();
+        if (regResult != null) {
+            if (regResult.getRegState() == REGISTRATION_STATE_HOME) return false;
+            if (regResult.getRegState() == REGISTRATION_STATE_ROAMING) return true;
+
+            String iso = regResult.getIso();
+            if (!TextUtils.isEmpty(iso)) netIso = iso;
+        }
+
+        String simIso = tm.getSimCountryIso();
+        logi("isInRoaming simIso=" + simIso + ", netIso=" + netIso);
+
+        if (TextUtils.isEmpty(simIso)) return false;
+        if (TextUtils.isEmpty(netIso)) return false;
+
+        return !(TextUtils.equals(simIso, netIso));
+    }
+
+    /**
+     * Determines whether IMS is registered over Wi-Fi.
+     *
+     * @return {@code true} if IMS is registered over Wi-Fi.
+     */
+    private boolean isImsRegisteredOverWifi() {
+        boolean ret = false;
+        if (SubscriptionManager.isValidSubscriptionId(getSubId())) {
+            ret = mImsStateTracker.isImsRegisteredOverWlan();
+        }
+
+        logi("isImsRegisteredOverWifi " + ret);
+        return ret;
+    }
+
+    /**
+     * Determines whether IMS is registered with voice capability.
+     *
+     * @return {@code true} if IMS is registered with voice capability.
+     */
+    private boolean isImsRegisteredWithVoiceCapability() {
+        boolean ret = mImsRegistered && mIsVoiceCapable;
+
+        logi("isImsRegisteredWithVoiceCapability " + ret);
+        return ret;
+    }
+
+    private void onWlanSelected() {
+        logi("onWlanSelected");
+        mLastTransportType = TRANSPORT_TYPE_WLAN;
+        mVoWifiTrialCount++;
+        mTransportSelectorCallback.onWlanSelected();
+        mWwanSelectorCallback = null;
+    }
+
+    private void onWwanSelected(Runnable runnable) {
+        logi("onWwanSelected");
+        if (mLastTransportType == TRANSPORT_TYPE_WWAN
+                && mWwanSelectorCallback != null) {
+            logi("onWwanSelected already notified");
+            runnable.run();
+            return;
+        }
+
+        mLastTransportType = TRANSPORT_TYPE_WWAN;
+        mTransportSelectorCallback.onWwanSelected((callback) -> {
+            mWwanSelectorCallback = callback;
+            runnable.run();
+        });
+    }
+
+    private void onWwanNetworkTypeSelected(@RadioAccessNetworkType int accessNetworkType) {
+        logi("onWwanNetworkTypeSelected " + accessNetworkTypeToString(accessNetworkType));
+        if (mWwanSelectorCallback == null) {
+            logi("onWwanNetworkTypeSelected callback is null");
+            return;
+        }
+
+        mDomainSelected = true;
+        mLastNetworkType = accessNetworkType;
+        int domain = NetworkRegistrationInfo.DOMAIN_CS;
+        if (accessNetworkType == EUTRAN || accessNetworkType == NGRAN) {
+            domain = NetworkRegistrationInfo.DOMAIN_PS;
+        }
+        mWwanSelectorCallback.onDomainSelected(domain);
+    }
+
+    private static String arrayToString(int[] intArray, IntFunction<String> func) {
+        int length = intArray.length;
+        StringBuilder sb = new StringBuilder("{");
+        if (length > 0) {
+            int i = 0;
+            sb.append(func.apply(intArray[i++]));
+            while (i < length) {
+                sb.append(", ").append(func.apply(intArray[i++]));
+            }
+        }
+        sb.append("}");
+        return sb.toString();
+    }
+
+    private static String arrayToString(String[] stringArray) {
+        StringBuilder sb;
+        int length = stringArray.length;
+        sb = new StringBuilder("{");
+        if (length > 0) {
+            int i = 0;
+            sb.append(stringArray[i++]);
+            while (i < length) {
+                sb.append(", ").append(stringArray[i++]);
+            }
+        }
+        sb.append("}");
+        return sb.toString();
+    }
+
+    private static String domainPreferenceToString(
+            @CarrierConfigManager.ImsEmergency.EmergencyDomain int domain) {
+        switch (domain) {
+            case DOMAIN_CS: return "CS";
+            case DOMAIN_PS_3GPP: return "PS_3GPP";
+            case DOMAIN_PS_NON_3GPP: return "PS_NON_3GPP";
+            default: return "UNKNOWN";
+        }
+    }
+
+    private static String carrierConfigNetworkScanTypeToString(
+            @CarrierConfigManager.ImsEmergency.EmergencyScanType int scanType) {
+        switch (scanType) {
+            case CarrierConfigManager.ImsEmergency.SCAN_TYPE_NO_PREFERENCE: return "NO_PREF";
+            case CarrierConfigManager.ImsEmergency.SCAN_TYPE_FULL_SERVICE: return "FULL";
+            case SCAN_TYPE_FULL_SERVICE_FOLLOWED_BY_LIMITED_SERVICE: return "FULL_N_LIMITED";
+            default: return "UNKNOWN";
+        }
+    }
+
+    private static String accessNetworkTypeToString(
+            @RadioAccessNetworkType int accessNetworkType) {
+        switch (accessNetworkType) {
+            case AccessNetworkType.UNKNOWN: return "UNKNOWN";
+            case AccessNetworkType.GERAN: return "GERAN";
+            case AccessNetworkType.UTRAN: return "UTRAN";
+            case AccessNetworkType.EUTRAN: return "EUTRAN";
+            case AccessNetworkType.CDMA2000: return "CDMA2000";
+            case AccessNetworkType.IWLAN: return "IWLAN";
+            case AccessNetworkType.NGRAN: return "NGRAN";
+            default: return Integer.toString(accessNetworkType);
+        }
+    }
+
+    /**
+     * Destroys the instance.
+     */
+    @VisibleForTesting
+    public void destroy() {
+        if (DBG) logd("destroy");
+
+        releaseWakeLock();
+
+        mDestroyed = true;
+        mImsStateTracker.removeBarringInfoListener(this);
+        mImsStateTracker.removeImsStateListener(this);
+
+        super.destroy();
+    }
+
+    private void acquireWakeLock() {
+        if (mPartialWakeLock != null) {
+            synchronized (mPartialWakeLock) {
+                logi("acquireWakeLock");
+                mPartialWakeLock.acquire();
+            }
+        }
+    }
+
+    private void releaseWakeLock() {
+        if (mPartialWakeLock != null) {
+            synchronized (mPartialWakeLock) {
+                if (mPartialWakeLock.isHeld()) {
+                    logi("releaseWakeLock");
+                    mPartialWakeLock.release();
+                }
+            }
+        }
+    }
+
+    @Override
+    protected void logi(String msg) {
+        super.logi(msg);
+        sLocalLog.log(msg);
+    }
+
+    @Override
+    protected void loge(String msg) {
+        super.loge(msg);
+        sLocalLog.log(msg);
+    }
+}
diff --git a/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelector.java b/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelector.java
new file mode 100644
index 0000000..cd588e1
--- /dev/null
+++ b/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelector.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony.domainselection;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.os.Looper;
+import android.os.PersistableBundle;
+import android.telephony.AccessNetworkConstants;
+import android.telephony.BarringInfo;
+import android.telephony.CarrierConfigManager;
+import android.telephony.DataSpecificRegistrationInfo;
+import android.telephony.NetworkRegistrationInfo;
+import android.telephony.ServiceState;
+import android.telephony.TelephonyManager;
+import android.telephony.VopsSupportInfo;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * Implements an emergency SMS domain selector for sending an emergency SMS.
+ */
+public class EmergencySmsDomainSelector extends SmsDomainSelector implements
+        ImsStateTracker.BarringInfoListener, ImsStateTracker.ServiceStateListener {
+    /**
+     * Stores the configuration value of
+     * {@link CarrierConfigManager#KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL}.
+     * This value is always updated whenever the domain selection is requested.
+     */
+    private Boolean mEmergencySmsOverImsSupportedByConfig;
+    private ServiceState mServiceState;
+    private boolean mServiceStateReceived;
+    private BarringInfo mBarringInfo;
+    private boolean mBarringInfoReceived;
+
+    public EmergencySmsDomainSelector(Context context, int slotId, int subId,
+            @NonNull Looper looper, @NonNull ImsStateTracker imsStateTracker,
+            @NonNull DestroyListener listener) {
+        super(context, slotId, subId, looper, imsStateTracker, listener,
+                "DomainSelector-EmergencySMS");
+
+        mImsStateTracker.addServiceStateListener(this);
+        mImsStateTracker.addBarringInfoListener(this);
+    }
+
+    @Override
+    public void destroy() {
+        if (mDestroyed) {
+            return;
+        }
+        mImsStateTracker.removeServiceStateListener(this);
+        mImsStateTracker.removeBarringInfoListener(this);
+        super.destroy();
+    }
+
+    @Override
+    public void finishSelection() {
+        super.finishSelection();
+        mServiceStateReceived = false;
+        mServiceState = null;
+        mBarringInfoReceived = false;
+        mBarringInfo = null;
+        mEmergencySmsOverImsSupportedByConfig = null;
+    }
+
+    @Override
+    public void onBarringInfoUpdated(BarringInfo barringInfo) {
+        mBarringInfoReceived = true;
+        mBarringInfo = barringInfo;
+        sendMessageForDomainSelection();
+    }
+
+    @Override
+    public void onServiceStateUpdated(ServiceState serviceState) {
+        mServiceStateReceived = true;
+        mServiceState = serviceState;
+        sendMessageForDomainSelection();
+    }
+
+    /**
+     * Checks whether the domain selector is ready to select the domain or not.
+     * The emergency SMS requires to be updated for the {@link ServiceState} and
+     * {@link BarringInfo} to confirm that the cellular network supports to send emergency SMS
+     * messages over IMS.
+     */
+    @VisibleForTesting
+    public boolean isDomainSelectionReady() {
+        return mServiceStateReceived && mBarringInfoReceived;
+    }
+
+    @Override
+    protected boolean isSmsOverImsAvailable() {
+        if (super.isSmsOverImsAvailable()) {
+            /**
+             * Even though IMS is successfully registered, the cellular domain should be
+             * available for the emergency SMS according to the carrier's requirement
+             * when {@link CarrierConfigManager#KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL} is set
+             * to true.
+             */
+            if (isEmergencySmsOverImsSupportedByConfig()) {
+                /**
+                 * Emergency SMS should be supported via emergency PDN.
+                 * If this condition is false, then need to fallback to CS network
+                 * because the current PS network does not allow the emergency service.
+                 */
+                return isNetworkAvailableForImsEmergencySms();
+            }
+
+            // Emergency SMS is supported via IMS PDN.
+            return true;
+        }
+
+        return isImsEmergencySmsAvailable();
+    }
+
+    @Override
+    protected void selectDomain() {
+        if (!isDomainSelectionRequested()) {
+            logi("Domain selection is not requested!");
+            return;
+        }
+
+        if (!isDomainSelectionReady()) {
+            logd("Wait for the readiness of the domain selection!");
+            return;
+        }
+
+        logi("selectDomain: " + mImsStateTracker.imsStateToString());
+
+        if (isSmsOverImsAvailable()) {
+            if (mImsStateTracker.isImsRegisteredOverWlan()) {
+                if (!isEmergencySmsOverImsSupportedByConfig()) {
+                    notifyWlanSelected();
+                    return;
+                }
+
+                /**
+                 * When {@link CarrierConfigManager#KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL}
+                 * is set to true, the emergency SMS supports on the LTE network using the
+                 * emergency PDN. So, considering EUTRAN only at this point.
+                 */
+                logi("DomainSelected: WLAN >> WWAN");
+            }
+            notifyWwanSelected(NetworkRegistrationInfo.DOMAIN_PS);
+        } else {
+            notifyWwanSelected(NetworkRegistrationInfo.DOMAIN_CS);
+        }
+    }
+
+    /**
+     * Checks if the emergency SMS messages over IMS is available according to the carrier
+     * configuration and the current network states.
+     */
+    private boolean isImsEmergencySmsAvailable() {
+        boolean emergencySmsOverImsSupportedByConfig = isEmergencySmsOverImsSupportedByConfig();
+        boolean networkAvailable = isNetworkAvailableForImsEmergencySms();
+
+        logi("isImsEmergencySmsAvailable: "
+                + "emergencySmsOverIms=" + emergencySmsOverImsSupportedByConfig
+                + ", mmTelFeatureAvailable=" + mImsStateTracker.isMmTelFeatureAvailable()
+                + ", networkAvailable=" + networkAvailable);
+
+        return emergencySmsOverImsSupportedByConfig
+                && 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.
+     */
+    private boolean isEmergencySmsOverImsSupportedByConfig() {
+        if (mEmergencySmsOverImsSupportedByConfig == null) {
+            CarrierConfigManager ccm = mContext.getSystemService(CarrierConfigManager.class);
+
+            if (ccm == null) {
+                loge("CarrierConfigManager is null");
+                return false;
+            }
+
+            PersistableBundle b = ccm.getConfigForSubId(getSubId());
+
+            if (b == null) {
+                loge("PersistableBundle is null");
+                return false;
+            }
+
+            mEmergencySmsOverImsSupportedByConfig = b.getBoolean(
+                    CarrierConfigManager.KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL);
+        }
+
+        return mEmergencySmsOverImsSupportedByConfig;
+    }
+
+    /**
+     * Checks if the emergency service is available in the LTE service mode.
+     */
+    private boolean isLteEmergencyAvailableInService() {
+        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_LTE
+                && regInfo.isRegistered()) {
+            return isEmergencyServiceSupported(regInfo) && isEmergencyServiceAllowed();
+        }
+        return false;
+    }
+
+    /**
+     * Checks if the emergency service is available in the limited LTE service(Emergency only) mode.
+     */
+    private boolean isLteEmergencyAvailableInLimitedService() {
+        if (mServiceState == null) {
+            return false;
+        }
+
+        final NetworkRegistrationInfo regInfo = mServiceState.getNetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        if (regInfo != null
+                && regInfo.getAccessNetworkTechnology() == TelephonyManager.NETWORK_TYPE_LTE
+                && regInfo.isEmergencyEnabled()) {
+            return isEmergencyServiceSupported(regInfo) && isEmergencyServiceAllowed();
+        }
+        return false;
+    }
+
+    /**
+     * Checks if the network is available for the IMS emergency SMS.
+     */
+    private boolean isNetworkAvailableForImsEmergencySms() {
+        return isLteEmergencyAvailableInService()
+                || isLteEmergencyAvailableInLimitedService();
+    }
+
+    /**
+     * Checks if the emergency service is supported by the network.
+     *
+     * This checks if "Emergency bearer services indicator (EMC-BS)" field (bits) set to
+     * the "Emergency bearer services in S1 mode supported".
+     *
+     * @return {@code true} if the emergency service is supported by the network,
+     *         {@code false} otherwise.
+     */
+    private boolean isEmergencyServiceSupported(@NonNull NetworkRegistrationInfo regInfo) {
+        final DataSpecificRegistrationInfo dsRegInfo = regInfo.getDataSpecificInfo();
+        if (dsRegInfo != null) {
+            final VopsSupportInfo vopsSupportInfo = dsRegInfo.getVopsSupportInfo();
+            return vopsSupportInfo != null
+                    && vopsSupportInfo.isEmergencyServiceSupported();
+        }
+        return false;
+    }
+
+    /**
+     * Checks if the emergency service is allowed (not barred) by the network.
+     *
+     * This checks if SystemInformationBlockType2 includes the ac-BarringInfo and
+     * with the ac-BarringForEmergency set to FALSE or
+     * if the SystemInformationBlockType2 does not include the ac-BarringInfo.
+     *
+     * @return {@code true} if the emergency service is allowed by the network,
+     *         {@code false} otherwise.
+     */
+    private boolean isEmergencyServiceAllowed() {
+        if (mBarringInfo == null) {
+            return true;
+        }
+        final BarringInfo.BarringServiceInfo bsi =
+                mBarringInfo.getBarringServiceInfo(BarringInfo.BARRING_SERVICE_TYPE_EMERGENCY);
+        return !bsi.isBarred();
+    }
+}
diff --git a/src/com/android/services/telephony/domainselection/ImsStateTracker.java b/src/com/android/services/telephony/domainselection/ImsStateTracker.java
new file mode 100644
index 0000000..e1d0d31
--- /dev/null
+++ b/src/com/android/services/telephony/domainselection/ImsStateTracker.java
@@ -0,0 +1,855 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony.domainselection;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
+import android.telephony.AccessNetworkConstants.RadioAccessNetworkType;
+import android.telephony.BarringInfo;
+import android.telephony.ServiceState;
+import android.telephony.SubscriptionManager;
+import android.telephony.ims.ImsException;
+import android.telephony.ims.ImsManager;
+import android.telephony.ims.ImsMmTelManager;
+import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.ImsRegistrationAttributes;
+import android.telephony.ims.ImsStateCallback;
+import android.telephony.ims.ImsStateCallback.DisconnectedReason;
+import android.telephony.ims.RegistrationManager;
+import android.telephony.ims.feature.MmTelFeature.MmTelCapabilities;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
+import android.util.ArraySet;
+import android.util.IndentingPrintWriter;
+import android.util.LocalLog;
+import android.util.Log;
+
+import com.android.internal.annotations.Keep;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.PrintWriter;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * A class for tracking the IMS related information like IMS registration state, MMTEL capabilities.
+ * And, it also tracks the {@link ServiceState} and {@link BarringInfo} to identify the current
+ * network state to which the device is attached.
+ */
+@Keep
+public class ImsStateTracker {
+    /**
+     * A listener used to be notified of the {@link ServiceState} change.
+     */
+    public interface ServiceStateListener {
+        /**
+         * Called when the {@link ServiceState} is updated.
+         */
+        void onServiceStateUpdated(ServiceState serviceState);
+    }
+
+    /**
+     * A listener used to be notified of the {@link BarringInfo} change.
+     */
+    public interface BarringInfoListener {
+        /**
+         * Called when the {@link BarringInfo} is updated.
+         */
+        void onBarringInfoUpdated(BarringInfo barringInfo);
+    }
+
+    /**
+     * A listener used to be notified of the change for MMTEL connection state, IMS registration
+     * state, and MMTEL capabilities.
+     */
+    public interface ImsStateListener {
+        /**
+         * Called when MMTEL feature connection state is changed.
+         */
+        void onImsMmTelFeatureAvailableChanged();
+
+        /**
+         * Called when IMS registration state is changed.
+         */
+        void onImsRegistrationStateChanged();
+
+        /**
+         * Called when MMTEL capability is changed - IMS is registered
+         * and the service is currently available over IMS.
+         */
+        void onImsMmTelCapabilitiesChanged();
+    }
+
+    private static final String TAG = ImsStateTracker.class.getSimpleName();
+    /**
+     * When MMTEL feature connection is unavailable temporarily,
+     * the IMS state will be set to unavailable after waiting for this time.
+     */
+    @VisibleForTesting
+    protected static final long MMTEL_FEATURE_AVAILABLE_WAIT_TIME_MILLIS = 1000; // 1 seconds
+
+    // Persistent Logging
+    private final LocalLog mEventLog = new LocalLog(30);
+    private final Context mContext;
+    private final int mSlotId;
+    private final Handler mHandler;
+    private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+
+    /** For tracking the ServiceState and its related listeners. */
+    private ServiceState mServiceState;
+    private final Set<ServiceStateListener> mServiceStateListeners = new ArraySet<>(2);
+
+    /** For tracking the BarringInfo and its related listeners. */
+    private BarringInfo mBarringInfo;
+    private final Set<BarringInfoListener> mBarringInfoListeners = new ArraySet<>(2);
+
+    /** For tracking IMS states and callbacks. */
+    private final Set<ImsStateListener> mImsStateListeners = new ArraySet<>(5);
+    private ImsMmTelManager mMmTelManager;
+    private ImsStateCallback mImsStateCallback;
+    private RegistrationManager.RegistrationCallback mImsRegistrationCallback;
+    private ImsMmTelManager.CapabilityCallback mMmTelCapabilityCallback;
+    /** The availability of MmTelFeature. */
+    private Boolean mMmTelFeatureAvailable;
+    /** The IMS registration state and the network type that performed IMS registration. */
+    private Boolean mImsRegistered;
+    private @RadioAccessNetworkType int mImsAccessNetworkType = AccessNetworkType.UNKNOWN;
+    /** The MMTEL capabilities - Voice, Video, SMS, and Ut. */
+    private MmTelCapabilities mMmTelCapabilities;
+    private final Runnable mMmTelFeatureUnavailableRunnable = new Runnable() {
+        @Override
+        public void run() {
+            setImsStateAsUnavailable();
+            notifyImsMmTelFeatureAvailableChanged();
+        }
+    };
+
+    public ImsStateTracker(@NonNull Context context, int slotId, @NonNull Looper looper) {
+        mContext = context;
+        mSlotId = slotId;
+        mHandler = new Handler(looper);
+    }
+
+    /**
+     * Destroys this tracker.
+     */
+    public void destroy() {
+        stopListeningForImsState();
+        mHandler.removeCallbacksAndMessages(null);
+    }
+
+    /**
+     * Returns the slot index for this tracker.
+     */
+    public int getSlotId() {
+        return mSlotId;
+    }
+
+    /**
+     * Returns the current subscription index for this tracker.
+     */
+    public int getSubId() {
+        return mSubId;
+    }
+
+    /**
+     * Returns the Handler instance of this tracker.
+     */
+    @VisibleForTesting
+    public @NonNull Handler getHandler() {
+        return mHandler;
+    }
+
+    /**
+     * Starts monitoring the IMS states with the specified subscription.
+     * This method will be called whenever the subscription index for this tracker is changed.
+     * If the subscription index for this tracker is same as previously set, it will be ignored.
+     *
+     * @param subId The subscription index to be started.
+     */
+    public void start(int subId) {
+        if (mSubId == subId) {
+            if (!SubscriptionManager.isValidSubscriptionId(mSubId)) {
+                setImsStateAsUnavailable();
+                return;
+            } else if (mImsStateCallback != null) {
+                // If start() is called with the same subscription index and the ImsStateCallback
+                // was already registered, we don't need to unregister and register this callback
+                // again. So, this request should be ignored if the subscription index is same.
+                logd("start: ignored for same subscription(" + mSubId + ")");
+                return;
+            }
+        } else {
+            logi("start: subscription changed from " + mSubId + " to " + subId);
+            mSubId = subId;
+        }
+
+        stopListeningForImsState();
+        startListeningForImsState();
+    }
+
+    /**
+     * Updates the service state of the network to which the device is currently attached.
+     * This method should be run on the same thread as the Handler.
+     *
+     * @param serviceState The {@link ServiceState} to be updated.
+     */
+    public void updateServiceState(ServiceState serviceState) {
+        mServiceState = serviceState;
+
+        for (ServiceStateListener listener : mServiceStateListeners) {
+            listener.onServiceStateUpdated(serviceState);
+        }
+    }
+
+    /**
+     * Adds a listener to be notified of the {@link ServiceState} change.
+     * The newly added listener is notified if the current {@link ServiceState} is present.
+     *
+     * @param listener The listener to be added.
+     */
+    public void addServiceStateListener(@NonNull ServiceStateListener listener) {
+        mServiceStateListeners.add(listener);
+
+        final ServiceState serviceState = mServiceState;
+        if (serviceState != null) {
+            mHandler.post(() -> notifyServiceStateUpdated(listener, serviceState));
+        }
+    }
+
+    /**
+     * Removes a listener to be notified of the {@link ServiceState} change.
+     *
+     * @param listener The listener to be removed.
+     */
+    public void removeServiceStateListener(@NonNull ServiceStateListener listener) {
+        mServiceStateListeners.remove(listener);
+    }
+
+    /**
+     * Notifies the specified listener of a change to {@link ServiceState}.
+     *
+     * @param listener The listener to be notified.
+     * @param serviceState The {@link ServiceState} to be reported.
+     */
+    private void notifyServiceStateUpdated(ServiceStateListener listener,
+            ServiceState serviceState) {
+        if (!mServiceStateListeners.contains(listener)) {
+            return;
+        }
+        listener.onServiceStateUpdated(serviceState);
+    }
+
+    /**
+     * Updates the barring information received from the network to which the device is currently
+     * attached.
+     * This method should be run on the same thread as the Handler.
+     *
+     * @param barringInfo The {@link BarringInfo} to be updated.
+     */
+    public void updateBarringInfo(BarringInfo barringInfo) {
+        mBarringInfo = barringInfo;
+
+        for (BarringInfoListener listener : mBarringInfoListeners) {
+            listener.onBarringInfoUpdated(barringInfo);
+        }
+    }
+
+    /**
+     * Adds a listener to be notified of the {@link BarringInfo} change.
+     * The newly added listener is notified if the current {@link BarringInfo} is present.
+     *
+     * @param listener The listener to be added.
+     */
+    public void addBarringInfoListener(@NonNull BarringInfoListener listener) {
+        mBarringInfoListeners.add(listener);
+
+        final BarringInfo barringInfo = mBarringInfo;
+        if (barringInfo != null) {
+            mHandler.post(() -> notifyBarringInfoUpdated(listener, barringInfo));
+        }
+    }
+
+    /**
+     * Removes a listener to be notified of the {@link BarringInfo} change.
+     *
+     * @param listener The listener to be removed.
+     */
+    public void removeBarringInfoListener(@NonNull BarringInfoListener listener) {
+        mBarringInfoListeners.remove(listener);
+    }
+
+    /**
+     * Notifies the specified listener of a change to {@link BarringInfo}.
+     *
+     * @param listener The listener to be notified.
+     * @param barringInfo The {@link BarringInfo} to be reported.
+     */
+    private void notifyBarringInfoUpdated(BarringInfoListener listener, BarringInfo barringInfo) {
+        if (!mBarringInfoListeners.contains(listener)) {
+            return;
+        }
+        listener.onBarringInfoUpdated(barringInfo);
+    }
+
+    /**
+     * Adds a listener to be notified of the IMS state change.
+     * If each state was already received from the IMS service, the newly added listener
+     * is notified once.
+     *
+     * @param listener The listener to be added.
+     */
+    public void addImsStateListener(@NonNull ImsStateListener listener) {
+        mImsStateListeners.add(listener);
+        mHandler.post(() -> notifyImsStateChangeIfValid(listener));
+    }
+
+    /**
+     * Removes a listener to be notified of the IMS state change.
+     *
+     * @param listener The listener to be removed.
+     */
+    public void removeImsStateListener(@NonNull ImsStateListener listener) {
+        mImsStateListeners.remove(listener);
+    }
+
+    /**
+     * Returns {@code true} if all IMS states are ready, {@code false} otherwise.
+     */
+    @VisibleForTesting
+    public boolean isImsStateReady() {
+        return mMmTelFeatureAvailable != null
+                && mImsRegistered != null
+                && mMmTelCapabilities != null;
+    }
+
+    /**
+     * Returns {@code true} if MMTEL feature connection is available, {@code false} otherwise.
+     */
+    public boolean isMmTelFeatureAvailable() {
+        return mMmTelFeatureAvailable != null && mMmTelFeatureAvailable;
+    }
+
+    /**
+     * Returns {@code true} if IMS is registered, {@code false} otherwise.
+     */
+    public boolean isImsRegistered() {
+        return mImsRegistered != null && mImsRegistered;
+    }
+
+    /**
+     * Returns {@code true} if IMS is registered over Wi-Fi (IWLAN), {@code false} otherwise.
+     */
+    public boolean isImsRegisteredOverWlan() {
+        return mImsAccessNetworkType == AccessNetworkType.IWLAN;
+    }
+
+    /**
+     * Returns {@code true} if IMS voice call is capable, {@code false} otherwise.
+     */
+    public boolean isImsVoiceCapable() {
+        return mMmTelCapabilities != null
+                && mMmTelCapabilities.isCapable(MmTelCapabilities.CAPABILITY_TYPE_VOICE);
+    }
+
+    /**
+     * Returns {@code true} if IMS video call is capable, {@code false} otherwise.
+     */
+    public boolean isImsVideoCapable() {
+        return mMmTelCapabilities != null
+                && mMmTelCapabilities.isCapable(MmTelCapabilities.CAPABILITY_TYPE_VIDEO);
+    }
+
+    /**
+     * Returns {@code true} if IMS SMS is capable, {@code false} otherwise.
+     */
+    public boolean isImsSmsCapable() {
+        return mMmTelCapabilities != null
+                && mMmTelCapabilities.isCapable(MmTelCapabilities.CAPABILITY_TYPE_SMS);
+    }
+
+    /**
+     * Returns {@code true} if IMS UT is capable, {@code false} otherwise.
+     */
+    public boolean isImsUtCapable() {
+        return mMmTelCapabilities != null
+                && mMmTelCapabilities.isCapable(MmTelCapabilities.CAPABILITY_TYPE_UT);
+    }
+
+    /**
+     * Returns the access network type to which IMS is registered.
+     */
+    public @RadioAccessNetworkType int getImsAccessNetworkType() {
+        return mImsAccessNetworkType;
+    }
+
+    /**
+     * Sets the IMS states to the initial values.
+     */
+    private void initImsState() {
+        mMmTelFeatureAvailable = null;
+        mImsRegistered = null;
+        mImsAccessNetworkType = AccessNetworkType.UNKNOWN;
+        mMmTelCapabilities = null;
+    }
+
+    /**
+     * Sets the IMS states to unavailable to notify the readiness of the IMS state
+     * when the subscription is not valid.
+     */
+    private void setImsStateAsUnavailable() {
+        logd("setImsStateAsUnavailable");
+        setMmTelFeatureAvailable(false);
+        setImsRegistered(false);
+        setImsAccessNetworkType(AccessNetworkType.UNKNOWN);
+        setMmTelCapabilities(new MmTelCapabilities());
+    }
+
+    private void setMmTelFeatureAvailable(boolean available) {
+        if (!Objects.equals(mMmTelFeatureAvailable, Boolean.valueOf(available))) {
+            logi("setMmTelFeatureAvailable: " + mMmTelFeatureAvailable + " >> " + available);
+            mMmTelFeatureAvailable = Boolean.valueOf(available);
+        }
+    }
+
+    private void setImsRegistered(boolean registered) {
+        if (!Objects.equals(mImsRegistered, Boolean.valueOf(registered))) {
+            logi("setImsRegistered: " + mImsRegistered + " >> " + registered);
+            mImsRegistered = Boolean.valueOf(registered);
+        }
+    }
+
+    private void setImsAccessNetworkType(int accessNetworkType) {
+        if (mImsAccessNetworkType != accessNetworkType) {
+            logi("setImsAccessNetworkType: " + accessNetworkTypeToString(mImsAccessNetworkType)
+                    + " >> " + accessNetworkTypeToString(accessNetworkType));
+            mImsAccessNetworkType = accessNetworkType;
+        }
+    }
+
+    private void setMmTelCapabilities(@NonNull MmTelCapabilities capabilities) {
+        if (!Objects.equals(mMmTelCapabilities, capabilities)) {
+            logi("MMTEL capabilities: " + mMmTelCapabilities + " >> " + capabilities);
+            mMmTelCapabilities = capabilities;
+        }
+    }
+
+    /**
+     * Notifies the specified listener of the current IMS state if it's valid.
+     *
+     * @param listener The {@link ImsStateListener} to be notified.
+     */
+    private void notifyImsStateChangeIfValid(@NonNull ImsStateListener listener) {
+        if (!mImsStateListeners.contains(listener)) {
+            return;
+        }
+
+        if (mMmTelFeatureAvailable != null) {
+            listener.onImsMmTelFeatureAvailableChanged();
+        }
+
+        if (mImsRegistered != null) {
+            listener.onImsRegistrationStateChanged();
+        }
+
+        if (mMmTelCapabilities != null) {
+            listener.onImsMmTelCapabilitiesChanged();
+        }
+    }
+
+    /**
+     * Notifies the application that MMTEL feature connection state is changed.
+     */
+    private void notifyImsMmTelFeatureAvailableChanged() {
+        for (ImsStateListener l : mImsStateListeners) {
+            l.onImsMmTelFeatureAvailableChanged();
+        }
+    }
+
+    /**
+     * Notifies the application that IMS registration state is changed.
+     */
+    private void notifyImsRegistrationStateChanged() {
+        logi("ImsState: " + imsStateToString());
+        for (ImsStateListener l : mImsStateListeners) {
+            l.onImsRegistrationStateChanged();
+        }
+    }
+
+    /**
+     * Notifies the application that MMTEL capabilities is changed.
+     */
+    private void notifyImsMmTelCapabilitiesChanged() {
+        logi("ImsState: " + imsStateToString());
+        for (ImsStateListener l : mImsStateListeners) {
+            l.onImsMmTelCapabilitiesChanged();
+        }
+    }
+
+    /**
+     * Called when MMTEL feature connection state is available.
+     */
+    private void onMmTelFeatureAvailable() {
+        logd("onMmTelFeatureAvailable");
+        mHandler.removeCallbacks(mMmTelFeatureUnavailableRunnable);
+        setMmTelFeatureAvailable(true);
+        registerImsRegistrationCallback();
+        registerMmTelCapabilityCallback();
+        notifyImsMmTelFeatureAvailableChanged();
+    }
+
+    /**
+     * Called when MMTEL feature connection state is unavailable.
+     */
+    private void onMmTelFeatureUnavailable(@DisconnectedReason int reason) {
+        logd("onMmTelFeatureUnavailable: reason=" + disconnectedCauseToString(reason));
+
+        if (reason == ImsStateCallback.REASON_UNKNOWN_TEMPORARY_ERROR
+                || reason == ImsStateCallback.REASON_IMS_SERVICE_NOT_READY) {
+            // Wait for onAvailable for some times and
+            // if it's not available, the IMS state will be set to unavailable.
+            initImsState();
+            setMmTelFeatureAvailable(false);
+            mHandler.postDelayed(mMmTelFeatureUnavailableRunnable,
+                    MMTEL_FEATURE_AVAILABLE_WAIT_TIME_MILLIS);
+        } else if (reason == ImsStateCallback.REASON_UNKNOWN_PERMANENT_ERROR
+                || reason == ImsStateCallback.REASON_NO_IMS_SERVICE_CONFIGURED) {
+            // Permanently blocked for this subscription.
+            setImsStateAsUnavailable();
+            notifyImsMmTelFeatureAvailableChanged();
+        } else if (reason == ImsStateCallback.REASON_IMS_SERVICE_DISCONNECTED) {
+            // Wait for onAvailable for some times and
+            // if it's not available, the IMS state will be set to unavailable.
+            initImsState();
+            setMmTelFeatureAvailable(false);
+            unregisterImsRegistrationCallback();
+            unregisterMmTelCapabilityCallback();
+            mHandler.postDelayed(mMmTelFeatureUnavailableRunnable,
+                    MMTEL_FEATURE_AVAILABLE_WAIT_TIME_MILLIS);
+        } else if (reason == ImsStateCallback.REASON_SUBSCRIPTION_INACTIVE) {
+            // The {@link TelephonyDomainSelectionService} will call ImsStateTracker#start
+            // when the subscription changes to register new callbacks.
+            setImsStateAsUnavailable();
+            unregisterImsRegistrationCallback();
+            unregisterMmTelCapabilityCallback();
+            notifyImsMmTelFeatureAvailableChanged();
+        } else {
+            logw("onMmTelFeatureUnavailable: unexpected reason=" + reason);
+        }
+    }
+
+    /**
+     * Called when IMS is registered to the IMS network.
+     */
+    private void onImsRegistered(@NonNull ImsRegistrationAttributes attributes) {
+        logd("onImsRegistered: " + attributes);
+
+        setImsRegistered(true);
+        setImsAccessNetworkType(
+                imsRegTechToAccessNetworkType(attributes.getRegistrationTechnology()));
+        notifyImsRegistrationStateChanged();
+    }
+
+    /**
+     * Called when IMS is unregistered from the IMS network.
+     */
+    private void onImsUnregistered(@NonNull ImsReasonInfo info) {
+        logd("onImsUnregistered: " + info);
+        setImsRegistered(false);
+        setImsAccessNetworkType(AccessNetworkType.UNKNOWN);
+        setMmTelCapabilities(new MmTelCapabilities());
+        notifyImsRegistrationStateChanged();
+    }
+
+    /**
+     * Called when MMTEL capability is changed - IMS is registered
+     * and the service is currently available over IMS.
+     */
+    private void onMmTelCapabilitiesChanged(@NonNull MmTelCapabilities capabilities) {
+        logd("onMmTelCapabilitiesChanged: " + capabilities);
+        setMmTelCapabilities(capabilities);
+        notifyImsMmTelCapabilitiesChanged();
+    }
+
+    /**
+     * Starts listening to monitor the IMS states -
+     * connection state, IMS registration state, and MMTEL capabilities.
+     */
+    private void startListeningForImsState() {
+        if (!SubscriptionManager.isValidSubscriptionId(getSubId())) {
+            setImsStateAsUnavailable();
+            return;
+        }
+
+        ImsManager imsMngr = mContext.getSystemService(ImsManager.class);
+        mMmTelManager = imsMngr.getImsMmTelManager(getSubId());
+        initImsState();
+        registerImsStateCallback();
+    }
+
+    /**
+     * Stops listening to monitor the IMS states -
+     * connection state, IMS registration state, and MMTEL capabilities.
+     */
+    private void stopListeningForImsState() {
+        mHandler.removeCallbacks(mMmTelFeatureUnavailableRunnable);
+
+        if (mMmTelManager != null) {
+            unregisterMmTelCapabilityCallback();
+            unregisterImsRegistrationCallback();
+            unregisterImsStateCallback();
+            mMmTelManager = null;
+        }
+    }
+
+    private void registerImsStateCallback() {
+        if (mImsStateCallback != null) {
+            loge("ImsStateCallback is already registered for sub-" + getSubId());
+            return;
+        }
+        /**
+         * Listens to the IMS connection state change.
+         */
+        mImsStateCallback = new ImsStateCallback() {
+            @Override
+            public void onUnavailable(@DisconnectedReason int reason) {
+                onMmTelFeatureUnavailable(reason);
+            }
+
+            @Override
+            public void onAvailable() {
+                onMmTelFeatureAvailable();
+            }
+
+            @Override
+            public void onError() {
+                // This case will not be happened because this domain selection service
+                // is running on the Telephony service.
+            }
+        };
+
+        try {
+            mMmTelManager.registerImsStateCallback(mHandler::post, mImsStateCallback);
+        } catch (ImsException e) {
+            loge("Exception when registering ImsStateCallback: " + e);
+            mImsStateCallback = null;
+        }
+    }
+
+    private void unregisterImsStateCallback() {
+        if (mImsStateCallback != null) {
+            try {
+                mMmTelManager.unregisterImsStateCallback(mImsStateCallback);
+            }  catch (Exception ignored) {
+                // Ignore the runtime exception while unregistering callback.
+                logd("Exception when unregistering ImsStateCallback: " + ignored);
+            }
+            mImsStateCallback = null;
+        }
+    }
+
+    private void registerImsRegistrationCallback() {
+        if (mImsRegistrationCallback != null) {
+            logd("RegistrationCallback is already registered for sub-" + getSubId());
+            return;
+        }
+        /**
+         * Listens to the IMS registration state change.
+         */
+        mImsRegistrationCallback = new RegistrationManager.RegistrationCallback() {
+            @Override
+            public void onRegistered(@NonNull ImsRegistrationAttributes attributes) {
+                onImsRegistered(attributes);
+            }
+
+            @Override
+            public void onUnregistered(@NonNull ImsReasonInfo info) {
+                onImsUnregistered(info);
+            }
+        };
+
+        try {
+            mMmTelManager.registerImsRegistrationCallback(mHandler::post, mImsRegistrationCallback);
+        } catch (ImsException e) {
+            loge("Exception when registering RegistrationCallback: " + e);
+            mImsRegistrationCallback = null;
+        }
+    }
+
+    private void unregisterImsRegistrationCallback() {
+        if (mImsRegistrationCallback != null) {
+            try {
+                mMmTelManager.unregisterImsRegistrationCallback(mImsRegistrationCallback);
+            }  catch (Exception ignored) {
+                // Ignore the runtime exception while unregistering callback.
+                logd("Exception when unregistering RegistrationCallback: " + ignored);
+            }
+            mImsRegistrationCallback = null;
+        }
+    }
+
+    private void registerMmTelCapabilityCallback() {
+        if (mMmTelCapabilityCallback != null) {
+            logd("CapabilityCallback is already registered for sub-" + getSubId());
+            return;
+        }
+        /**
+         * Listens to the MmTel feature capabilities change.
+         */
+        mMmTelCapabilityCallback = new ImsMmTelManager.CapabilityCallback() {
+            @Override
+            public void onCapabilitiesStatusChanged(@NonNull MmTelCapabilities capabilities) {
+                onMmTelCapabilitiesChanged(capabilities);
+            }
+        };
+
+        try {
+            mMmTelManager.registerMmTelCapabilityCallback(mHandler::post, mMmTelCapabilityCallback);
+        } catch (ImsException e) {
+            loge("Exception when registering CapabilityCallback: " + e);
+            mMmTelCapabilityCallback = null;
+        }
+    }
+
+    private void unregisterMmTelCapabilityCallback() {
+        if (mMmTelCapabilityCallback != null) {
+            try {
+                mMmTelManager.unregisterMmTelCapabilityCallback(mMmTelCapabilityCallback);
+            } catch (Exception ignored) {
+                // Ignore the runtime exception while unregistering callback.
+                logd("Exception when unregistering CapabilityCallback: " + ignored);
+            }
+            mMmTelCapabilityCallback = null;
+        }
+    }
+
+    /** Returns a string representation of IMS states. */
+    public String imsStateToString() {
+        StringBuilder sb = new StringBuilder("{ ");
+        sb.append("MMTEL: featureAvailable=").append(booleanToString(mMmTelFeatureAvailable));
+        sb.append(", registered=").append(booleanToString(mImsRegistered));
+        sb.append(", accessNetworkType=").append(accessNetworkTypeToString(mImsAccessNetworkType));
+        sb.append(", capabilities=").append(mmTelCapabilitiesToString(mMmTelCapabilities));
+        sb.append(" }");
+        return sb.toString();
+    }
+
+    protected static String accessNetworkTypeToString(
+            @RadioAccessNetworkType int accessNetworkType) {
+        switch (accessNetworkType) {
+            case AccessNetworkType.UNKNOWN: return "UNKNOWN";
+            case AccessNetworkType.GERAN: return "GERAN";
+            case AccessNetworkType.UTRAN: return "UTRAN";
+            case AccessNetworkType.EUTRAN: return "EUTRAN";
+            case AccessNetworkType.CDMA2000: return "CDMA2000";
+            case AccessNetworkType.IWLAN: return "IWLAN";
+            case AccessNetworkType.NGRAN: return "NGRAN";
+            default: return Integer.toString(accessNetworkType);
+        }
+    }
+
+    /** Converts the IMS registration technology to the access network type. */
+    private static @RadioAccessNetworkType int imsRegTechToAccessNetworkType(
+            @ImsRegistrationImplBase.ImsRegistrationTech int imsRegTech) {
+        switch (imsRegTech) {
+            case ImsRegistrationImplBase.REGISTRATION_TECH_LTE:
+                return AccessNetworkType.EUTRAN;
+            case ImsRegistrationImplBase.REGISTRATION_TECH_NR:
+                return AccessNetworkType.NGRAN;
+            case ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN:
+                return AccessNetworkType.IWLAN;
+            default:
+                return AccessNetworkType.UNKNOWN;
+        }
+    }
+
+    private static String booleanToString(Boolean b) {
+        return b == null ? "null" : b.toString();
+    }
+
+    private static String mmTelCapabilitiesToString(MmTelCapabilities c) {
+        if (c == null) {
+            return "null";
+        }
+        StringBuilder sb = new StringBuilder("[");
+        sb.append("voice=").append(c.isCapable(MmTelCapabilities.CAPABILITY_TYPE_VOICE));
+        sb.append(", video=").append(c.isCapable(MmTelCapabilities.CAPABILITY_TYPE_VIDEO));
+        sb.append(", ut=").append(c.isCapable(MmTelCapabilities.CAPABILITY_TYPE_UT));
+        sb.append(", sms=").append(c.isCapable(MmTelCapabilities.CAPABILITY_TYPE_SMS));
+        sb.append("]");
+        return sb.toString();
+    }
+
+    private static String disconnectedCauseToString(@DisconnectedReason int reason) {
+        switch (reason) {
+            case ImsStateCallback.REASON_UNKNOWN_TEMPORARY_ERROR:
+                return "UNKNOWN_TEMPORARY_ERROR";
+            case ImsStateCallback.REASON_UNKNOWN_PERMANENT_ERROR:
+                return "UNKNOWN_PERMANENT_ERROR";
+            case ImsStateCallback.REASON_IMS_SERVICE_DISCONNECTED:
+                return "IMS_SERVICE_DISCONNECTED";
+            case ImsStateCallback.REASON_NO_IMS_SERVICE_CONFIGURED:
+                return "NO_IMS_SERVICE_CONFIGURED";
+            case ImsStateCallback.REASON_SUBSCRIPTION_INACTIVE:
+                return "SUBSCRIPTION_INACTIVE";
+            case ImsStateCallback.REASON_IMS_SERVICE_NOT_READY:
+                return "IMS_SERVICE_NOT_READY";
+            default:
+                return Integer.toString(reason);
+        }
+    }
+
+    /**
+     * Dumps this instance into a readable format for dumpsys usage.
+     */
+    public void dump(@NonNull PrintWriter pw) {
+        IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
+        ipw.println("ImsStateTracker:");
+        ipw.increaseIndent();
+        ipw.println("SlotId: " + getSlotId());
+        ipw.println("SubId: " + getSubId());
+        ipw.println("ServiceState: " + mServiceState);
+        ipw.println("BarringInfo: " + mBarringInfo);
+        ipw.println("ImsState: " + imsStateToString());
+        ipw.println("Event Log:");
+        ipw.increaseIndent();
+        mEventLog.dump(ipw);
+        ipw.decreaseIndent();
+        ipw.decreaseIndent();
+    }
+
+    private void logd(String s) {
+        Log.d(TAG, "[" + getSlotId() + "|" + getSubId() + "] " + s);
+    }
+
+    private void logi(String s) {
+        Log.i(TAG, "[" + getSlotId() + "|" + getSubId() + "] " + s);
+        mEventLog.log("[" + getSlotId() + "|" + getSubId() + "] " + s);
+    }
+
+    private void loge(String s) {
+        Log.e(TAG, "[" + getSlotId() + "|" + getSubId() + "] " + s);
+        mEventLog.log("[" + getSlotId() + "|" + getSubId() + "] " + s);
+    }
+
+    private void logw(String s) {
+        Log.w(TAG, "[" + getSlotId() + "|" + getSubId() + "] " + s);
+        mEventLog.log("[" + getSlotId() + "|" + getSubId() + "] " + s);
+    }
+}
diff --git a/src/com/android/services/telephony/domainselection/SmsDomainSelector.java b/src/com/android/services/telephony/domainselection/SmsDomainSelector.java
new file mode 100644
index 0000000..e7c9ac5
--- /dev/null
+++ b/src/com/android/services/telephony/domainselection/SmsDomainSelector.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony.domainselection;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.os.Looper;
+import android.os.Message;
+import android.telephony.DisconnectCause;
+import android.telephony.DomainSelectionService;
+import android.telephony.DomainSelectionService.SelectionAttributes;
+import android.telephony.NetworkRegistrationInfo;
+import android.telephony.TransportSelectorCallback;
+
+/**
+ * Implements SMS domain selector for sending MO SMS.
+ */
+public class SmsDomainSelector extends DomainSelectorBase implements
+        ImsStateTracker.ImsStateListener {
+    protected static final int EVENT_SELECT_DOMAIN = 101;
+
+    protected boolean mDestroyed = false;
+    private boolean mDomainSelectionRequested = false;
+
+    public SmsDomainSelector(Context context, int slotId, int subId, @NonNull Looper looper,
+            @NonNull ImsStateTracker imsStateTracker, @NonNull DestroyListener listener) {
+        this(context, slotId, subId, looper, imsStateTracker, listener, "DomainSelector-SMS");
+    }
+
+    protected SmsDomainSelector(Context context, int slotId, int subId, @NonNull Looper looper,
+            @NonNull ImsStateTracker imsStateTracker, @NonNull DestroyListener listener,
+            String logTag) {
+        super(context, slotId, subId, looper, imsStateTracker, listener, logTag);
+    }
+
+    @Override
+    public void destroy() {
+        if (mDestroyed) {
+            return;
+        }
+        logd("destroy");
+        mDestroyed = true;
+        mImsStateTracker.removeImsStateListener(this);
+        super.destroy();
+    }
+
+    @Override
+    public void handleMessage(@NonNull Message msg) {
+        switch (msg.what) {
+            case EVENT_SELECT_DOMAIN:
+                selectDomain();
+                break;
+            default:
+                super.handleMessage(msg);
+                break;
+        }
+    }
+
+    @Override
+    public void cancelSelection() {
+        logi("cancelSelection");
+        finishSelection();
+    }
+
+    @Override
+    public void reselectDomain(@NonNull SelectionAttributes attr) {
+        if (isDomainSelectionRequested()) {
+            // The domain selection is already requested,
+            // so we don't need to request it again before completing the previous task.
+            logi("Domain selection is already running.");
+            return;
+        }
+
+        logi("reselectDomain");
+        mSelectionAttributes = attr;
+        setDomainSelectionRequested(true);
+        obtainMessage(EVENT_SELECT_DOMAIN).sendToTarget();
+    }
+
+    @Override
+    public void finishSelection() {
+        logi("finishSelection");
+        setDomainSelectionRequested(false);
+        mSelectionAttributes = null;
+        mTransportSelectorCallback = null;
+        mWwanSelectorCallback = null;
+        destroy();
+    }
+
+    @Override
+    public void selectDomain(SelectionAttributes attr, TransportSelectorCallback callback) {
+        if (isDomainSelectionRequested()) {
+            // The domain selection is already requested,
+            // so we don't need to request it again before completing the previous task.
+            logi("Domain selection is already running.");
+            return;
+        }
+        mSelectionAttributes = attr;
+        mTransportSelectorCallback = callback;
+        setDomainSelectionRequested(true);
+        mImsStateTracker.addImsStateListener(this);
+        obtainMessage(EVENT_SELECT_DOMAIN).sendToTarget();
+    }
+
+    @Override
+    public void onImsMmTelFeatureAvailableChanged() {
+        sendMessageForDomainSelection();
+    }
+
+    @Override
+    public void onImsRegistrationStateChanged() {
+        sendMessageForDomainSelection();
+    }
+
+    @Override
+    public void onImsMmTelCapabilitiesChanged() {
+        sendMessageForDomainSelection();
+    }
+
+    protected boolean isSmsOverImsAvailable() {
+        return mImsStateTracker.isImsSmsCapable()
+                && mImsStateTracker.isImsRegistered()
+                && mImsStateTracker.isMmTelFeatureAvailable();
+    }
+
+    protected void selectDomain() {
+        if (!isDomainSelectionRequested()) {
+            logi("Domain selection is not requested!");
+            return;
+        }
+
+        logi("selectDomain: " + mImsStateTracker.imsStateToString());
+
+        if (isSmsOverImsAvailable()) {
+            if (mImsStateTracker.isImsRegisteredOverWlan()) {
+                notifyWlanSelected();
+                return;
+            }
+            notifyWwanSelected(NetworkRegistrationInfo.DOMAIN_PS);
+        } else {
+            notifyWwanSelected(NetworkRegistrationInfo.DOMAIN_CS);
+        }
+    }
+
+    protected void sendMessageForDomainSelection() {
+        // If the event is already queued to this handler,
+        // it will be removed first to avoid the duplicate operation.
+        removeMessages(EVENT_SELECT_DOMAIN);
+        // Since the IMS state may have already been posted,
+        // proceed with the domain selection after processing all pending messages.
+        obtainMessage(EVENT_SELECT_DOMAIN).sendToTarget();
+    }
+
+    protected boolean isDomainSelectionRequested() {
+        return mDomainSelectionRequested;
+    }
+
+    protected void setDomainSelectionRequested(boolean requested) {
+        if (mDomainSelectionRequested != requested) {
+            logd("DomainSelectionRequested: " + mDomainSelectionRequested + " >> " + requested);
+            mDomainSelectionRequested = requested;
+        }
+    }
+
+    protected void notifyWlanSelected() {
+        logi("DomainSelected: WLAN");
+        mTransportSelectorCallback.onWlanSelected();
+        setDomainSelectionRequested(false);
+    }
+
+    protected void notifyWwanSelected(@NetworkRegistrationInfo.Domain int domain) {
+        if (mWwanSelectorCallback == null) {
+            mTransportSelectorCallback.onWwanSelected((callback) -> {
+                mWwanSelectorCallback = callback;
+                notifyWwanSelectedInternal(domain);
+            });
+        } else {
+            notifyWwanSelectedInternal(domain);
+        }
+
+        setDomainSelectionRequested(false);
+    }
+
+    protected void notifyWwanSelectedInternal(@NetworkRegistrationInfo.Domain int domain) {
+        logi("DomainSelected: WWAN/" + DomainSelectionService.getDomainName(domain));
+
+        if (mWwanSelectorCallback != null) {
+            mWwanSelectorCallback.onDomainSelected(domain);
+        } else {
+            mTransportSelectorCallback.onSelectionTerminated(DisconnectCause.LOCAL);
+        }
+    }
+}
diff --git a/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionService.java b/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionService.java
new file mode 100644
index 0000000..6f47ee6
--- /dev/null
+++ b/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionService.java
@@ -0,0 +1,517 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony.domainselection;
+
+import android.annotation.NonNull;
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.telephony.BarringInfo;
+import android.telephony.DisconnectCause;
+import android.telephony.DomainSelectionService;
+import android.telephony.ServiceState;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
+import android.telephony.TelephonyManager;
+import android.telephony.TransportSelectorCallback;
+import android.util.IndentingPrintWriter;
+import android.util.LocalLog;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+/**
+ * Implements the telephony domain selection for various telephony features.
+ */
+public class TelephonyDomainSelectionService extends DomainSelectionService {
+    /**
+     * Testing interface for injecting mock ImsStateTracker.
+     */
+    @VisibleForTesting
+    public interface ImsStateTrackerFactory {
+        /**
+         * @return The {@link ImsStateTracker} created for the specified slot.
+         */
+        ImsStateTracker create(Context context, int slotId, @NonNull Looper looper);
+    }
+
+    /**
+     * Testing interface for injecting mock DomainSelector.
+     */
+    @VisibleForTesting
+    public interface DomainSelectorFactory {
+        /**
+         * @return The {@link DomainSelectorBase} created using the specified arguments.
+         */
+        DomainSelectorBase create(Context context, int slotId, int subId,
+                @SelectorType int selectorType, boolean isEmergency, @NonNull Looper looper,
+                @NonNull ImsStateTracker imsStateTracker,
+                @NonNull DomainSelectorBase.DestroyListener listener);
+    }
+
+    private static final class DefaultDomainSelectorFactory implements DomainSelectorFactory {
+        @Override
+        public DomainSelectorBase create(Context context, int slotId, int subId,
+                @SelectorType int selectorType, boolean isEmergency, @NonNull Looper looper,
+                @NonNull ImsStateTracker imsStateTracker,
+                @NonNull DomainSelectorBase.DestroyListener listener) {
+            DomainSelectorBase selector = null;
+
+            logi("create-DomainSelector: slotId=" + slotId + ", subId=" + subId
+                    + ", selectorType=" + selectorTypeToString(selectorType)
+                    + ", emergency=" + isEmergency);
+
+            switch (selectorType) {
+                case SELECTOR_TYPE_CALLING:
+                    if (isEmergency) {
+                        selector = new EmergencyCallDomainSelector(context, slotId, subId, looper,
+                                imsStateTracker, listener);
+                    } else {
+                        // TODO(ag/20024470) uncomment when normal call domain selector is ready.
+                        /*selector = new NormalCallDomainSelector(context, slotId, subId, looper,
+                                imsStateTracker, listener);*/
+                    }
+                    break;
+                case SELECTOR_TYPE_SMS:
+                    if (isEmergency) {
+                        selector = new EmergencySmsDomainSelector(context, slotId, subId, looper,
+                                imsStateTracker, listener);
+                    } else {
+                        selector = new SmsDomainSelector(context, slotId, subId, looper,
+                                imsStateTracker, listener);
+                    }
+                    break;
+                default:
+                    // Not reachable.
+                    break;
+            }
+
+            return selector;
+        }
+    };
+
+    /**
+     * A container class to manage the domain selector per a slot and selector type.
+     * If the domain selector is not null and reusable, the same domain selector will be used
+     * for the specific slot.
+     */
+    private static final class DomainSelectorContainer {
+        private final int mSlotId;
+        private final @SelectorType int mSelectorType;
+        private final boolean mIsEmergency;
+        private final @NonNull DomainSelectorBase mSelector;
+
+        DomainSelectorContainer(int slotId, @SelectorType int selectorType, boolean isEmergency,
+                @NonNull DomainSelectorBase selector) {
+            mSlotId = slotId;
+            mSelectorType = selectorType;
+            mIsEmergency = isEmergency;
+            mSelector = selector;
+        }
+
+        public int getSlotId() {
+            return mSlotId;
+        }
+
+        public @SelectorType int getSelectorType() {
+            return mSelectorType;
+        }
+
+        public DomainSelectorBase getDomainSelector() {
+            return mSelector;
+        }
+
+        public boolean isEmergency() {
+            return mIsEmergency;
+        }
+
+        @Override
+        public String toString() {
+            return new StringBuilder()
+                    .append("{ ")
+                    .append("slotId=").append(mSlotId)
+                    .append(", selectorType=").append(selectorTypeToString(mSelectorType))
+                    .append(", isEmergency=").append(mIsEmergency)
+                    .append(", selector=").append(mSelector)
+                    .append(" }").toString();
+        }
+    }
+
+    private final DomainSelectorBase.DestroyListener mDestroyListener =
+            new DomainSelectorBase.DestroyListener() {
+        @Override
+        public void onDomainSelectorDestroyed(DomainSelectorBase selector) {
+            logd("DomainSelector destroyed: " + selector);
+            removeDomainSelector(selector);
+        }
+    };
+
+    /**
+     * A class to listen for the subscription change for starting {@link ImsStateTracker}
+     * to monitor the IMS states.
+     */
+    private final OnSubscriptionsChangedListener mSubscriptionsChangedListener =
+            new OnSubscriptionsChangedListener() {
+                @Override
+                public void onSubscriptionsChanged() {
+                    handleSubscriptionsChanged();
+                }
+            };
+
+    private static final String TAG = TelephonyDomainSelectionService.class.getSimpleName();
+
+    // Persistent Logging
+    private static final LocalLog sEventLog = new LocalLog(20);
+    private final Context mContext;
+    // Map of slotId -> ImsStateTracker
+    private final SparseArray<ImsStateTracker> mImsStateTrackers = new SparseArray<>(2);
+    private final List<DomainSelectorContainer> mDomainSelectorContainers = new ArrayList<>();
+    private final ImsStateTrackerFactory mImsStateTrackerFactory;
+    private final DomainSelectorFactory mDomainSelectorFactory;
+    private Handler mServiceHandler;
+
+    public TelephonyDomainSelectionService(Context context) {
+        this(context, ImsStateTracker::new, new DefaultDomainSelectorFactory());
+    }
+
+    @VisibleForTesting
+    public TelephonyDomainSelectionService(Context context,
+            @NonNull ImsStateTrackerFactory imsStateTrackerFactory,
+            @NonNull DomainSelectorFactory domainSelectorFactory) {
+        mContext = context;
+        mImsStateTrackerFactory = imsStateTrackerFactory;
+        mDomainSelectorFactory = domainSelectorFactory;
+
+        // Create a worker thread for this domain selection service.
+        getExecutor();
+
+        TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
+        int activeModemCount = (tm != null) ? tm.getActiveModemCount() : 1;
+        for (int i = 0; i < activeModemCount; ++i) {
+            mImsStateTrackers.put(i, mImsStateTrackerFactory.create(mContext, i, getLooper()));
+        }
+
+        SubscriptionManager sm = mContext.getSystemService(SubscriptionManager.class);
+        if (sm != null) {
+            sm.addOnSubscriptionsChangedListener(getExecutor(), mSubscriptionsChangedListener);
+        } else {
+            loge("Adding OnSubscriptionChangedListener failed");
+        }
+
+        logi("TelephonyDomainSelectionService created");
+    }
+
+    @Override
+    public void onDestroy() {
+        logd("onDestroy");
+
+        List<DomainSelectorContainer> domainSelectorContainers;
+
+        synchronized (mDomainSelectorContainers) {
+            domainSelectorContainers = new ArrayList<>(mDomainSelectorContainers);
+            mDomainSelectorContainers.clear();
+        }
+
+        for (DomainSelectorContainer dsc : domainSelectorContainers) {
+            DomainSelectorBase selector = dsc.getDomainSelector();
+            if (selector != null) {
+                selector.destroy();
+            }
+        }
+        domainSelectorContainers.clear();
+
+        synchronized (mImsStateTrackers) {
+            for (int i = 0; i < mImsStateTrackers.size(); ++i) {
+                ImsStateTracker ist = mImsStateTrackers.get(i);
+                if (ist != null) {
+                    ist.destroy();
+                }
+            }
+            mImsStateTrackers.clear();
+        }
+
+        SubscriptionManager sm = mContext.getSystemService(SubscriptionManager.class);
+        if (sm != null) {
+            sm.removeOnSubscriptionsChangedListener(mSubscriptionsChangedListener);
+        }
+
+        if (mServiceHandler != null) {
+            mServiceHandler.getLooper().quit();
+            mServiceHandler = null;
+        }
+    }
+
+    /**
+     * Selects a domain for the given attributes and callback.
+     *
+     * @param attr required to determine the domain.
+     * @param callback the callback instance being registered.
+     */
+    @Override
+    public void onDomainSelection(@NonNull SelectionAttributes attr,
+            @NonNull TransportSelectorCallback callback) {
+        final int slotId = attr.getSlotId();
+        final int subId = attr.getSubId();
+        final int selectorType = attr.getSelectorType();
+        final boolean isEmergency = attr.isEmergency();
+        ImsStateTracker ist = getImsStateTracker(slotId);
+        DomainSelectorBase selector = mDomainSelectorFactory.create(mContext, slotId, subId,
+                selectorType, isEmergency, getLooper(), ist, mDestroyListener);
+
+        if (selector != null) {
+            // Ensures that ImsStateTracker is started before selecting the domain if not started
+            // for the specified subscription index.
+            ist.start(subId);
+            addDomainSelector(slotId, selectorType, isEmergency, selector);
+        } else {
+            loge("No proper domain selector: " + selectorTypeToString(selectorType));
+            callback.onSelectionTerminated(DisconnectCause.ERROR_UNSPECIFIED);
+            return;
+        }
+
+        // Notify the caller that the domain selector is created.
+        callback.onCreated(selector);
+
+        // Performs the domain selection.
+        selector.selectDomain(attr, callback);
+    }
+
+    /**
+     * Called when the {@link ServiceState} needs to be updated for the specified slot and
+     * subcription index.
+     *
+     * @param slotId for which the service state changed.
+     * @param subId The current subscription for a specified slot.
+     * @param serviceState The {@link ServiceState} to be updated.
+     */
+    @Override
+    public void onServiceStateUpdated(int slotId, int subId, @NonNull ServiceState serviceState) {
+        ImsStateTracker ist = getImsStateTracker(slotId);
+        if (ist != null) {
+            ist.updateServiceState(serviceState);
+        }
+    }
+
+    /**
+     * Called when the {@link BarringInfo} needs to be updated for the specified slot and
+     * subscription index.
+     *
+     * @param slotId The slot the BarringInfo is updated for.
+     * @param subId The current subscription for a specified slot.
+     * @param barringInfo The {@link BarringInfo} to be updated.
+     */
+    @Override
+    public void onBarringInfoUpdated(int slotId, int subId, @NonNull BarringInfo barringInfo) {
+        ImsStateTracker ist = getImsStateTracker(slotId);
+        if (ist != null) {
+            ist.updateBarringInfo(barringInfo);
+        }
+    }
+
+    /**
+     *  Returns an Executor used to execute methods called remotely by the framework.
+     */
+    @SuppressLint("OnNameExpected")
+    @Override
+    public @NonNull Executor getExecutor() {
+        if (mServiceHandler == null) {
+            HandlerThread handlerThread = new HandlerThread(TAG);
+            handlerThread.start();
+            mServiceHandler = new Handler(handlerThread.getLooper());
+        }
+
+        return mServiceHandler::post;
+    }
+
+    /**
+     * Returns a Looper instance.
+     */
+    @VisibleForTesting
+    public Looper getLooper() {
+        getExecutor();
+        return mServiceHandler.getLooper();
+    }
+
+    /**
+     * Handles the subscriptions change.
+     */
+    private void handleSubscriptionsChanged() {
+        SubscriptionManager sm = mContext.getSystemService(SubscriptionManager.class);
+        List<SubscriptionInfo> subsInfoList =
+                (sm != null) ? sm.getActiveSubscriptionInfoList() : null;
+
+        if (subsInfoList == null || subsInfoList.isEmpty()) {
+            logd("handleSubscriptionsChanged: No valid SubscriptionInfo");
+            return;
+        }
+
+        for (int i = 0; i < subsInfoList.size(); ++i) {
+            SubscriptionInfo subsInfo = subsInfoList.get(i);
+            int slotId = subsInfo.getSimSlotIndex();
+
+            if (slotId != SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
+                logd("handleSubscriptionsChanged: slotId=" + slotId);
+                ImsStateTracker ist = getImsStateTracker(slotId);
+                ist.start(subsInfo.getSubscriptionId());
+            }
+        }
+    }
+
+    /**
+     * Adds the {@link DomainSelectorBase} to the list of domain selector container.
+     */
+    private void addDomainSelector(int slotId, @SelectorType int selectorType,
+            boolean isEmergency, @NonNull DomainSelectorBase selector) {
+        synchronized (mDomainSelectorContainers) {
+            // If the domain selector already exists, remove the previous one first.
+            for (int i = 0; i < mDomainSelectorContainers.size(); ++i) {
+                DomainSelectorContainer dsc = mDomainSelectorContainers.get(i);
+
+                if (dsc.getSlotId() == slotId
+                        && dsc.getSelectorType() == selectorType
+                        && dsc.isEmergency() == isEmergency) {
+                    mDomainSelectorContainers.remove(i);
+                    DomainSelectorBase oldSelector = dsc.getDomainSelector();
+                    if (oldSelector != null) {
+                        logw("DomainSelector destroyed by new domain selection request: " + dsc);
+                        oldSelector.destroy();
+                    }
+                    break;
+                }
+            }
+
+            DomainSelectorContainer dsc =
+                    new DomainSelectorContainer(slotId, selectorType, isEmergency, selector);
+            mDomainSelectorContainers.add(dsc);
+
+            logi("DomainSelector added: " + dsc + ", count=" + mDomainSelectorContainers.size());
+        }
+    }
+
+    /**
+     * Removes the domain selector container that matches with the specified
+     * {@link DomainSelectorBase}.
+     */
+    private void removeDomainSelector(@NonNull DomainSelectorBase selector) {
+        synchronized (mDomainSelectorContainers) {
+            for (int i = 0; i < mDomainSelectorContainers.size(); ++i) {
+                DomainSelectorContainer dsc = mDomainSelectorContainers.get(i);
+
+                if (dsc.getDomainSelector() == selector) {
+                    mDomainSelectorContainers.remove(i);
+                    logi("DomainSelector removed: " + dsc
+                            + ", count=" + mDomainSelectorContainers.size());
+                    break;
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns the {@link ImsStateTracker} instance for the specified slot.
+     * If the {@link ImsStateTracker} does not exist for the slot, it creates new instance
+     * and returns.
+     */
+    private ImsStateTracker getImsStateTracker(int slotId) {
+        synchronized (mImsStateTrackers) {
+            ImsStateTracker ist = mImsStateTrackers.get(slotId);
+
+            if (ist == null) {
+                ist = mImsStateTrackerFactory.create(mContext, slotId, getLooper());
+                mImsStateTrackers.put(slotId, ist);
+            }
+
+            return ist;
+        }
+    }
+
+    private static String selectorTypeToString(@SelectorType int selectorType) {
+        switch (selectorType) {
+            case SELECTOR_TYPE_CALLING: return "CALLING";
+            case SELECTOR_TYPE_SMS: return "SMS";
+            case SELECTOR_TYPE_UT: return "UT";
+            default: return Integer.toString(selectorType);
+        }
+    }
+
+    private static void logd(String s) {
+        Log.d(TAG, s);
+    }
+
+    private static void logi(String s) {
+        Log.i(TAG, s);
+        sEventLog.log(s);
+    }
+
+    private static void loge(String s) {
+        Log.e(TAG, s);
+        sEventLog.log(s);
+    }
+
+    private static void logw(String s) {
+        Log.w(TAG, s);
+        sEventLog.log(s);
+    }
+
+    /**
+     * Dumps this instance into a readable format for dumpsys usage.
+     */
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
+        ipw.println("TelephonyDomainSelectionService:");
+        ipw.increaseIndent();
+        ipw.println("ImsStateTrackers:");
+        synchronized (mImsStateTrackers) {
+            for (int i = 0; i < mImsStateTrackers.size(); ++i) {
+                ImsStateTracker ist = mImsStateTrackers.valueAt(i);
+                ist.dump(ipw);
+            }
+        }
+        ipw.decreaseIndent();
+        ipw.increaseIndent();
+        synchronized (mDomainSelectorContainers) {
+            for (int i = 0; i < mDomainSelectorContainers.size(); ++i) {
+                DomainSelectorContainer dsc = mDomainSelectorContainers.get(i);
+                ipw.println("DomainSelector: " + dsc.toString());
+                ipw.increaseIndent();
+                DomainSelectorBase selector = dsc.getDomainSelector();
+                if (selector != null) {
+                    selector.dump(ipw);
+                }
+                ipw.decreaseIndent();
+            }
+        }
+        ipw.decreaseIndent();
+        ipw.increaseIndent();
+        ipw.println("Event Log:");
+        ipw.increaseIndent();
+        sEventLog.dump(ipw);
+        ipw.decreaseIndent();
+        ipw.decreaseIndent();
+        ipw.println("________________________________");
+    }
+}
diff --git a/src/com/android/services/telephony/rcs/RcsFeatureController.java b/src/com/android/services/telephony/rcs/RcsFeatureController.java
index 48c84b1..b292c35 100644
--- a/src/com/android/services/telephony/rcs/RcsFeatureController.java
+++ b/src/com/android/services/telephony/rcs/RcsFeatureController.java
@@ -17,11 +17,13 @@
 package com.android.services.telephony.rcs;
 
 import android.annotation.AnyThread;
+import android.annotation.NonNull;
 import android.content.Context;
 import android.net.Uri;
 import android.telephony.SubscriptionManager;
 import android.telephony.ims.ImsException;
 import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.ImsRegistrationAttributes;
 import android.telephony.ims.aidl.IImsCapabilityCallback;
 import android.telephony.ims.aidl.IImsRegistrationCallback;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
@@ -166,7 +168,7 @@
     private ImsRegistrationCallbackHelper.ImsRegistrationUpdate mRcsRegistrationUpdate = new
             ImsRegistrationCallbackHelper.ImsRegistrationUpdate() {
                 @Override
-                public void handleImsRegistered(int imsRadioTech) {
+                public void handleImsRegistered(@NonNull ImsRegistrationAttributes attributes) {
                 }
 
                 @Override
@@ -174,7 +176,8 @@
                 }
 
                 @Override
-                public void handleImsUnregistered(ImsReasonInfo imsReasonInfo) {
+                public void handleImsUnregistered(ImsReasonInfo imsReasonInfo,
+                        int suggestedAction) {
                 }
 
                 @Override
diff --git a/tests/src/com/android/TestContext.java b/tests/src/com/android/TestContext.java
index 7c3a842..720d235 100644
--- a/tests/src/com/android/TestContext.java
+++ b/tests/src/com/android/TestContext.java
@@ -61,7 +61,11 @@
     @Mock ImsManager mMockImsManager;
     @Mock UserManager mMockUserManager;
 
-    private SparseArray<PersistableBundle> mCarrierConfigs = new SparseArray<>();
+    private final SparseArray<PersistableBundle> mCarrierConfigs = new SparseArray<>();
+
+    private Intent mIntent;
+
+    private BroadcastReceiver mReceiver;
 
     private final HashSet<String> mPermissionTable = new HashSet<>();
 
@@ -105,28 +109,42 @@
     }
 
     @Override
+    public void sendBroadcast(Intent intent) {
+        mIntent = intent;
+    }
+
+    @Override
     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
+        mReceiver = receiver;
         return null;
     }
 
     @Override
     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, int flags) {
+        mReceiver = receiver;
         return null;
     }
 
     @Override
     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
             String broadcastPermission, Handler scheduler) {
+        mReceiver = receiver;
         return null;
     }
 
     @Override
     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
             String broadcastPermission, Handler scheduler, int flags) {
+        mReceiver = receiver;
         return null;
     }
 
     @Override
+    public void unregisterReceiver(BroadcastReceiver receiver) {
+        mReceiver = null;
+    }
+
+    @Override
     public ContentResolver getContentResolver() {
         return null;
     }
@@ -134,22 +152,22 @@
     @Override
     public Object getSystemService(String name) {
         switch (name) {
-            case (Context.CARRIER_CONFIG_SERVICE) : {
+            case Context.CARRIER_CONFIG_SERVICE: {
                 return mMockCarrierConfigManager;
             }
-            case (Context.TELECOM_SERVICE) : {
+            case Context.TELECOM_SERVICE: {
                 return mMockTelecomManager;
             }
-            case (Context.TELEPHONY_SERVICE) : {
+            case Context.TELEPHONY_SERVICE: {
                 return mMockTelephonyManager;
             }
-            case (Context.TELEPHONY_SUBSCRIPTION_SERVICE) : {
+            case Context.TELEPHONY_SUBSCRIPTION_SERVICE: {
                 return mMockSubscriptionManager;
             }
-            case(Context.TELEPHONY_IMS_SERVICE) : {
+            case Context.TELEPHONY_IMS_SERVICE: {
                 return mMockImsManager;
             }
-            case(Context.USER_SERVICE) : {
+            case Context.USER_SERVICE: {
                 return mMockUserManager;
             }
         }
@@ -170,6 +188,9 @@
         if (serviceClass == SubscriptionManager.class) {
             return Context.TELEPHONY_SUBSCRIPTION_SERVICE;
         }
+        if (serviceClass == ImsManager.class) {
+            return Context.TELEPHONY_IMS_SERVICE;
+        }
         if (serviceClass == UserManager.class) {
             return Context.USER_SERVICE;
         }
@@ -252,6 +273,14 @@
         }
     }
 
+    public Intent getBroadcast() {
+        return mIntent;
+    }
+
+    public BroadcastReceiver getBroadcastReceiver() {
+        return mReceiver;
+    }
+
     private static void logd(String s) {
         Log.d(TAG, s);
     }
diff --git a/tests/src/com/android/phone/CarrierConfigLoaderTest.java b/tests/src/com/android/phone/CarrierConfigLoaderTest.java
index 9c425d6..6807422 100644
--- a/tests/src/com/android/phone/CarrierConfigLoaderTest.java
+++ b/tests/src/com/android/phone/CarrierConfigLoaderTest.java
@@ -28,7 +28,9 @@
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
+import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.pm.PackageInfo;
@@ -44,6 +46,7 @@
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.telephony.TelephonyRegistryManager;
 import android.testing.TestableLooper;
 
 import androidx.test.InstrumentationRegistry;
@@ -85,6 +88,7 @@
     @Mock PackageInfo mPackageInfo;
     @Mock SubscriptionInfoUpdater mSubscriptionInfoUpdater;
     @Mock SharedPreferences mSharedPreferences;
+    @Mock TelephonyRegistryManager mTelephonyRegistryManager;
 
     private TelephonyManager mTelephonyManager;
     private CarrierConfigLoader mCarrierConfigLoader;
@@ -96,6 +100,7 @@
     public void setUp() throws Exception {
         super.setUp();
 
+        // TODO: replace doReturn/when with when/thenReturn which is more readable
         doReturn(mSharedPreferences).when(mContext).getSharedPreferences(anyString(), anyInt());
         doReturn(Build.FINGERPRINT).when(mSharedPreferences).getString(eq("build_fingerprint"),
                 any());
@@ -114,6 +119,10 @@
                 eq(PLATFORM_CARRIER_CONFIG_PACKAGE), eq(0) /*flags*/);
         doReturn(PLATFORM_CARRIER_CONFIG_PACKAGE_VERSION_CODE).when(
                 mPackageInfo).getLongVersionCode();
+        when(mContext.getSystemServiceName(TelephonyRegistryManager.class)).thenReturn(
+                Context.TELEPHONY_REGISTRY_SERVICE);
+        when(mContext.getSystemService(TelephonyRegistryManager.class)).thenReturn(
+                mTelephonyRegistryManager);
 
         mHandlerThread = new HandlerThread("CarrierConfigLoaderTest");
         mHandlerThread.start();
@@ -185,6 +194,11 @@
         assertThat(mCarrierConfigLoader.getNoSimConfig().getInt(CARRIER_CONFIG_EXAMPLE_KEY))
                 .isEqualTo(CARRIER_CONFIG_EXAMPLE_VALUE);
         verify(mContext).sendBroadcastAsUser(any(Intent.class), any(UserHandle.class));
+        verify(mTelephonyRegistryManager).notifyCarrierConfigChanged(
+                eq(DEFAULT_PHONE_ID),
+                eq(SubscriptionManager.INVALID_SUBSCRIPTION_ID),
+                eq(TelephonyManager.UNKNOWN_CARRIER_ID),
+                eq(TelephonyManager.UNKNOWN_CARRIER_ID));
     }
 
     /**
diff --git a/tests/src/com/android/phone/PhoneInterfaceManagerTest.java b/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
index 3b6d5ee..6e4a65f 100644
--- a/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
+++ b/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
@@ -17,15 +17,21 @@
 package com.android.phone;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
-import android.content.pm.PackageManager;
+import android.content.SharedPreferences;
 import android.content.res.Resources;
 import android.telephony.RadioAccessFamily;
 import android.telephony.TelephonyManager;
@@ -50,22 +56,24 @@
 @RunWith(AndroidJUnit4.class)
 public class PhoneInterfaceManagerTest extends TelephonyTestBase {
     private PhoneInterfaceManager mPhoneInterfaceManager;
+    private SharedPreferences mSharedPreferences;
 
     @Mock
     PhoneGlobals mPhoneGlobals;
     @Mock
     Phone mPhone;
-    @Mock
-    PackageManager mPackageManager;
 
     @Before
     @UiThreadTest
     public void setUp() throws Exception {
         super.setUp();
-        doReturn(mPackageManager).when(mPhoneGlobals).getPackageManager();
-        doReturn(false).when(mPackageManager).hasSystemFeature(
-                PackageManager.FEATURE_TELEPHONY_IMS);
-        mPhoneInterfaceManager = PhoneInterfaceManager.init(mPhoneGlobals);
+        // Note that PhoneInterfaceManager is a singleton. Calling init gives us a handle to the
+        // global singleton, but the context that is passed in is unused if the phone app is already
+        // alive on a test devices. You must use the spy to mock behavior. Mocks stemming from the
+        // passed context will remain unused.
+        mPhoneInterfaceManager = spy(PhoneInterfaceManager.init(mPhoneGlobals));
+        mSharedPreferences = mPhoneInterfaceManager.getSharedPreferences();
+        mSharedPreferences.edit().remove(Phone.PREF_NULL_CIPHER_AND_INTEGRITY_ENABLED).commit();
     }
 
     @Test
@@ -138,4 +146,81 @@
 
         assertEquals("ff-Latn-BF", resultFfBf);
     }
+
+    @Test
+    public void setNullCipherAndIntegrityEnabled_successfullyEnable() {
+        doReturn(201).when(mPhoneInterfaceManager).getHalVersion(anyInt());
+        doNothing().when(mPhoneInterfaceManager).enforceModifyPermission();
+        assertFalse(mSharedPreferences.contains(Phone.PREF_NULL_CIPHER_AND_INTEGRITY_ENABLED));
+
+        mPhoneInterfaceManager.setNullCipherAndIntegrityEnabled(true);
+
+        assertTrue(
+                mSharedPreferences.getBoolean(Phone.PREF_NULL_CIPHER_AND_INTEGRITY_ENABLED, false));
+    }
+
+    @Test
+    public void setNullCipherAndIntegrityEnabled_successfullyDisable() {
+        doReturn(201).when(mPhoneInterfaceManager).getHalVersion(anyInt());
+        doNothing().when(mPhoneInterfaceManager).enforceModifyPermission();
+        assertFalse(mSharedPreferences.contains(Phone.PREF_NULL_CIPHER_AND_INTEGRITY_ENABLED));
+
+        mPhoneInterfaceManager.setNullCipherAndIntegrityEnabled(false);
+
+        assertFalse(
+                mSharedPreferences.getBoolean(Phone.PREF_NULL_CIPHER_AND_INTEGRITY_ENABLED, true));
+    }
+
+    @Test
+    public void setNullCipherAndIntegrityEnabled_lackingNecessaryHal() {
+        doReturn(101).when(mPhoneInterfaceManager).getHalVersion(anyInt());
+        doNothing().when(mPhoneInterfaceManager).enforceModifyPermission();
+
+        assertThrows(UnsupportedOperationException.class, () -> {
+            mPhoneInterfaceManager.setNullCipherAndIntegrityEnabled(true);
+        });
+
+    }
+
+    @Test
+    public void setNullCipherAndIntegrityEnabled_lackingPermissions() {
+        doReturn(201).when(mPhoneInterfaceManager).getHalVersion(anyInt());
+        doThrow(SecurityException.class).when(mPhoneInterfaceManager).enforceModifyPermission();
+
+        assertThrows(SecurityException.class, () -> {
+            mPhoneInterfaceManager.setNullCipherAndIntegrityEnabled(true);
+        });
+    }
+
+    @Test
+    public void isNullCipherAndIntegrityPreferenceEnabled() {
+        doReturn(201).when(mPhoneInterfaceManager).getHalVersion(anyInt());
+        doNothing().when(mPhoneInterfaceManager).enforceModifyPermission();
+
+        assertTrue(mPhoneInterfaceManager.isNullCipherAndIntegrityPreferenceEnabled());
+        mPhoneInterfaceManager.setNullCipherAndIntegrityEnabled(false);
+        assertFalse(
+                mSharedPreferences.getBoolean(Phone.PREF_NULL_CIPHER_AND_INTEGRITY_ENABLED, true));
+    }
+
+    @Test
+    public void isNullCipherAndIntegrityPreferenceEnabled_lackingNecessaryHal() {
+        doReturn(101).when(mPhoneInterfaceManager).getHalVersion(anyInt());
+        doNothing().when(mPhoneInterfaceManager).enforceModifyPermission();
+
+        assertThrows(UnsupportedOperationException.class, () -> {
+            mPhoneInterfaceManager.isNullCipherAndIntegrityPreferenceEnabled();
+        });
+
+    }
+
+    @Test
+    public void isNullCipherAndIntegrityPreferenceEnabled_lackingPermissions() {
+        doReturn(201).when(mPhoneInterfaceManager).getHalVersion(anyInt());
+        doThrow(SecurityException.class).when(mPhoneInterfaceManager).enforceReadPermission();
+
+        assertThrows(SecurityException.class, () -> {
+            mPhoneInterfaceManager.isNullCipherAndIntegrityPreferenceEnabled();
+        });
+    }
 }
diff --git a/tests/src/com/android/phone/SlicePurchaseControllerTest.java b/tests/src/com/android/phone/slice/SlicePurchaseControllerTest.java
similarity index 74%
rename from tests/src/com/android/phone/SlicePurchaseControllerTest.java
rename to tests/src/com/android/phone/slice/SlicePurchaseControllerTest.java
index ebcf15d..8320807 100644
--- a/tests/src/com/android/phone/SlicePurchaseControllerTest.java
+++ b/tests/src/com/android/phone/slice/SlicePurchaseControllerTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.phone;
+package com.android.phone.slice;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -26,15 +26,19 @@
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doCallRealMethod;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.SharedPreferences;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -53,38 +57,42 @@
 import com.android.TelephonyTestBase;
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.Phone;
-import com.android.phone.slice.PremiumNetworkEntitlementApi;
-import com.android.phone.slice.PremiumNetworkEntitlementResponse;
-import com.android.phone.slice.SlicePurchaseController;
-import com.android.phone.slice.SlicePurchaseController.SlicePurchaseControllerBroadcastReceiver;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 
+import java.time.LocalDate;
 import java.util.Collections;
 import java.util.Map;
 
 @RunWith(AndroidJUnit4.class)
 public class SlicePurchaseControllerTest extends TelephonyTestBase {
     private static final String TAG = "SlicePurchaseControllerTest";
+    private static final String DAILY_NOTIFICATION_COUNT_KEY = "daily_notification_count0";
+    private static final String MONTHLY_NOTIFICATION_COUNT_KEY = "monthly_notification_count0";
+    private static final int YEAR = 2000;
+    private static final int MONTH = 6;
+    private static final int DATE = 1;
     private static final int PHONE_ID = 0;
+    private static final int DAILY_NOTIFICATION_MAX = 3;
+    private static final int MONTHLY_NOTIFICATION_MAX = 5;
     private static final long NOTIFICATION_TIMEOUT = 1000;
     private static final long PURCHASE_CONDITION_TIMEOUT = 2000;
     private static final long NETWORK_SETUP_TIMEOUT = 3000;
     private static final long THROTTLE_TIMEOUT = 4000;
 
     @Mock Phone mPhone;
-    @Mock Context mMockedContext;
     @Mock CarrierConfigManager mCarrierConfigManager;
     @Mock CommandsInterface mCommandsInterface;
     @Mock ServiceState mServiceState;
     @Mock PremiumNetworkEntitlementApi mPremiumNetworkEntitlementApi;
+    @Mock SharedPreferences mSharedPreferences;
+    @Mock SharedPreferences.Editor mEditor;
 
     private SlicePurchaseController mSlicePurchaseController;
-    private SlicePurchaseControllerBroadcastReceiver mBroadcastReceiver;
     private PersistableBundle mBundle;
     private PremiumNetworkEntitlementResponse mEntitlementResponse;
     private Handler mHandler;
@@ -106,17 +114,34 @@
         mTestableLooper = new TestableLooper(mHandler.getLooper());
 
         doReturn(PHONE_ID).when(mPhone).getPhoneId();
-        doReturn(mMockedContext).when(mPhone).getContext();
+        doReturn(mContext).when(mPhone).getContext();
         doReturn(mServiceState).when(mPhone).getServiceState();
         mPhone.mCi = mCommandsInterface;
 
-        doReturn(Context.CARRIER_CONFIG_SERVICE).when(mMockedContext)
-                .getSystemServiceName(eq(CarrierConfigManager.class));
-        doReturn(mCarrierConfigManager).when(mMockedContext)
-                .getSystemService(eq(Context.CARRIER_CONFIG_SERVICE));
+        doReturn(mCarrierConfigManager).when(mContext)
+                .getSystemService(Context.CARRIER_CONFIG_SERVICE);
         mBundle = new PersistableBundle();
+        mBundle.putInt(
+                CarrierConfigManager.KEY_PREMIUM_CAPABILITY_MAXIMUM_DAILY_NOTIFICATION_COUNT_INT,
+                DAILY_NOTIFICATION_MAX);
+        mBundle.putInt(
+                CarrierConfigManager.KEY_PREMIUM_CAPABILITY_MAXIMUM_MONTHLY_NOTIFICATION_COUNT_INT,
+                MONTHLY_NOTIFICATION_MAX);
         doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt());
 
+        doReturn(mSharedPreferences).when(mContext).getSharedPreferences(anyString(), anyInt());
+        doReturn(mEditor).when(mSharedPreferences).edit();
+        doAnswer(invocation -> {
+            doReturn(invocation.getArgument(1)).when(mSharedPreferences)
+                    .getInt(eq(invocation.getArgument(0)), anyInt());
+            return null;
+        }).when(mEditor).putInt(anyString(), anyInt());
+        doAnswer(invocation -> {
+            doReturn(invocation.getArgument(1)).when(mSharedPreferences)
+                    .getString(eq(invocation.getArgument(0)), anyString());
+            return null;
+        }).when(mEditor).putString(anyString(), anyString());
+
         // create a spy to mock final PendingIntent methods
         SlicePurchaseController slicePurchaseController =
                 new SlicePurchaseController(mPhone, mHandler.getLooper());
@@ -159,7 +184,6 @@
                 new int[]{TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY});
         mBundle.putString(CarrierConfigManager.KEY_PREMIUM_CAPABILITY_PURCHASE_URL_STRING,
                 SlicePurchaseController.SLICE_PURCHASE_TEST_FILE);
-        doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt());
         doReturn(SubscriptionManager.getDefaultDataSubscriptionId()).when(mPhone).getSubId();
 
         // retry to verify available
@@ -188,19 +212,65 @@
         };
         for (String url : invalidUrls) {
             mBundle.putString(CarrierConfigManager.KEY_PREMIUM_CAPABILITY_PURCHASE_URL_STRING, url);
-            doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt());
             assertFalse(mSlicePurchaseController.isPremiumCapabilityAvailableForPurchase(
                     TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY));
         }
 
         mBundle.putString(CarrierConfigManager.KEY_PREMIUM_CAPABILITY_PURCHASE_URL_STRING,
                 SlicePurchaseController.SLICE_PURCHASE_TEST_FILE);
-        doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt());
         assertTrue(mSlicePurchaseController.isPremiumCapabilityAvailableForPurchase(
                 TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY));
     }
 
     @Test
+    public void testUpdateNotificationCounts() {
+        mSlicePurchaseController.setLocalDate(LocalDate.of(YEAR, MONTH, DATE));
+        mSlicePurchaseController.updateNotificationCounts();
+
+        // change only date, month and year remain the same
+        Mockito.clearInvocations(mEditor);
+        mSlicePurchaseController.setLocalDate(LocalDate.of(YEAR, MONTH, DATE + 1));
+        mSlicePurchaseController.updateNotificationCounts();
+        verify(mEditor).putInt(eq(DAILY_NOTIFICATION_COUNT_KEY), eq(0));
+        verify(mEditor, never()).putInt(eq(MONTHLY_NOTIFICATION_COUNT_KEY), eq(0));
+
+        // change only month, date and year remain the same
+        Mockito.clearInvocations(mEditor);
+        mSlicePurchaseController.setLocalDate(LocalDate.of(YEAR, MONTH + 1, DATE + 1));
+        mSlicePurchaseController.updateNotificationCounts();
+        verify(mEditor).putInt(eq(DAILY_NOTIFICATION_COUNT_KEY), eq(0));
+        verify(mEditor).putInt(eq(MONTHLY_NOTIFICATION_COUNT_KEY), eq(0));
+
+        // change only year, date and month remain the same
+        Mockito.clearInvocations(mEditor);
+        mSlicePurchaseController.setLocalDate(LocalDate.of(YEAR + 1, MONTH + 1, DATE + 1));
+        mSlicePurchaseController.updateNotificationCounts();
+        verify(mEditor).putInt(eq(DAILY_NOTIFICATION_COUNT_KEY), eq(0));
+        verify(mEditor).putInt(eq(MONTHLY_NOTIFICATION_COUNT_KEY), eq(0));
+
+        // change only month and year, date remains the same
+        Mockito.clearInvocations(mEditor);
+        mSlicePurchaseController.setLocalDate(LocalDate.of(YEAR + 2, MONTH + 2, DATE + 1));
+        mSlicePurchaseController.updateNotificationCounts();
+        verify(mEditor).putInt(eq(DAILY_NOTIFICATION_COUNT_KEY), eq(0));
+        verify(mEditor).putInt(eq(MONTHLY_NOTIFICATION_COUNT_KEY), eq(0));
+
+        // change only date and year, month remains the same
+        Mockito.clearInvocations(mEditor);
+        mSlicePurchaseController.setLocalDate(LocalDate.of(YEAR + 3, MONTH + 2, DATE + 2));
+        mSlicePurchaseController.updateNotificationCounts();
+        verify(mEditor).putInt(eq(DAILY_NOTIFICATION_COUNT_KEY), eq(0));
+        verify(mEditor).putInt(eq(MONTHLY_NOTIFICATION_COUNT_KEY), eq(0));
+
+        // change only date and month, year remains the same
+        Mockito.clearInvocations(mEditor);
+        mSlicePurchaseController.setLocalDate(LocalDate.of(YEAR + 3, MONTH + 3, DATE + 3));
+        mSlicePurchaseController.updateNotificationCounts();
+        verify(mEditor).putInt(eq(DAILY_NOTIFICATION_COUNT_KEY), eq(0));
+        verify(mEditor).putInt(eq(MONTHLY_NOTIFICATION_COUNT_KEY), eq(0));
+    }
+
+    @Test
     public void testPurchasePremiumCapabilityResultFeatureNotSupported() {
         mSlicePurchaseController.purchasePremiumCapability(
                 TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY, TAG,
@@ -237,7 +307,6 @@
                 new int[]{TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY});
         mBundle.putString(CarrierConfigManager.KEY_PREMIUM_CAPABILITY_PURCHASE_URL_STRING,
                 SlicePurchaseController.SLICE_PURCHASE_TEST_FILE);
-        doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt());
 
         mSlicePurchaseController.purchasePremiumCapability(
                 TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY, TAG,
@@ -255,7 +324,6 @@
                 new int[]{TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY});
         mBundle.putString(CarrierConfigManager.KEY_PREMIUM_CAPABILITY_PURCHASE_URL_STRING,
                 SlicePurchaseController.SLICE_PURCHASE_TEST_FILE);
-        doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt());
 
         mSlicePurchaseController.purchasePremiumCapability(
                 TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY, TAG,
@@ -285,7 +353,6 @@
                 new int[]{TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY});
         mBundle.putString(CarrierConfigManager.KEY_PREMIUM_CAPABILITY_PURCHASE_URL_STRING,
                 SlicePurchaseController.SLICE_PURCHASE_TEST_FILE);
-        doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt());
         doReturn(SubscriptionManager.getDefaultDataSubscriptionId()).when(mPhone).getSubId();
 
         mSlicePurchaseController.purchasePremiumCapability(
@@ -314,7 +381,6 @@
                 new int[]{TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY});
         mBundle.putString(CarrierConfigManager.KEY_PREMIUM_CAPABILITY_PURCHASE_URL_STRING,
                 SlicePurchaseController.SLICE_PURCHASE_TEST_FILE);
-        doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt());
         doReturn(SubscriptionManager.getDefaultDataSubscriptionId()).when(mPhone).getSubId();
         doReturn(TelephonyManager.NETWORK_TYPE_NR).when(mServiceState).getDataNetworkType();
         doReturn(null).when(mPremiumNetworkEntitlementApi).checkEntitlementStatus(anyInt());
@@ -342,8 +408,6 @@
         // retry with provisioning response
         mEntitlementResponse.mProvisionStatus =
                 PremiumNetworkEntitlementResponse.PREMIUM_NETWORK_PROVISION_STATUS_IN_PROGRESS;
-        doReturn(mEntitlementResponse).when(mPremiumNetworkEntitlementApi)
-                .checkEntitlementStatus(anyInt());
 
         mSlicePurchaseController.purchasePremiumCapability(
                 TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY, TAG,
@@ -357,12 +421,9 @@
                 PremiumNetworkEntitlementResponse.PREMIUM_NETWORK_PROVISION_STATUS_NOT_PROVISIONED;
         mEntitlementResponse.mEntitlementStatus =
                 PremiumNetworkEntitlementResponse.PREMIUM_NETWORK_ENTITLEMENT_STATUS_INCOMPATIBLE;
-        doReturn(mEntitlementResponse).when(mPremiumNetworkEntitlementApi)
-                .checkEntitlementStatus(anyInt());
         mBundle.putLong(CarrierConfigManager
                 .KEY_PREMIUM_CAPABILITY_PURCHASE_CONDITION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG,
                 PURCHASE_CONDITION_TIMEOUT);
-        doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt());
 
         mSlicePurchaseController.purchasePremiumCapability(
                 TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY, TAG,
@@ -409,12 +470,13 @@
     public void testPurchasePremiumCapabilityResultSuccess() {
         sendValidPurchaseRequest();
 
+        // broadcast SUCCESS response from slice purchase application
         Intent intent = new Intent();
         intent.setAction("com.android.phone.slice.action.SLICE_PURCHASE_APP_RESPONSE_SUCCESS");
         intent.putExtra(SlicePurchaseController.EXTRA_PHONE_ID, PHONE_ID);
         intent.putExtra(SlicePurchaseController.EXTRA_PREMIUM_CAPABILITY,
                 TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY);
-        mBroadcastReceiver.onReceive(mMockedContext, intent);
+        mContext.getBroadcastReceiver().onReceive(mContext, intent);
         mTestableLooper.processAllMessages();
         assertEquals(TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_SUCCESS, mResult);
 
@@ -443,13 +505,7 @@
     public void testPurchasePremiumCapabilityResultAlreadyPurchased() {
         testPurchasePremiumCapabilityResultSuccess();
 
-        // TODO: implement slicing config logic properly
-        NetworkSlicingConfig slicingConfig = new NetworkSlicingConfig(Collections.emptyList(),
-                Collections.singletonList(new NetworkSliceInfo.Builder()
-                        .setStatus(NetworkSliceInfo.SLICE_STATUS_ALLOWED).build()));
-        mSlicePurchaseController.obtainMessage(2 /* EVENT_SLICING_CONFIG_CHANGED */,
-                new AsyncResult(null, slicingConfig, null)).sendToTarget();
-        mTestableLooper.processAllMessages();
+        sendNetworkSlicingConfig(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY, true);
 
         mSlicePurchaseController.purchasePremiumCapability(
                 TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY, TAG,
@@ -467,10 +523,7 @@
                 mResult);
 
         // retry to verify purchase expired
-        slicingConfig = new NetworkSlicingConfig(Collections.emptyList(), Collections.emptyList());
-        mSlicePurchaseController.obtainMessage(2 /* EVENT_SLICING_CONFIG_CHANGED */,
-                new AsyncResult(null, slicingConfig, null)).sendToTarget();
-        mTestableLooper.processAllMessages();
+        sendNetworkSlicingConfig(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY, false);
 
         testPurchasePremiumCapabilityResultSuccess();
     }
@@ -501,12 +554,13 @@
     public void testPurchasePremiumCapabilityResultUserCanceled() {
         sendValidPurchaseRequest();
 
+        // broadcast CANCELED response from slice purchase application
         Intent intent = new Intent();
         intent.setAction("com.android.phone.slice.action.SLICE_PURCHASE_APP_RESPONSE_CANCELED");
         intent.putExtra(SlicePurchaseController.EXTRA_PHONE_ID, PHONE_ID);
         intent.putExtra(SlicePurchaseController.EXTRA_PREMIUM_CAPABILITY,
                 TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY);
-        mBroadcastReceiver.onReceive(mMockedContext, intent);
+        mContext.getBroadcastReceiver().onReceive(mContext, intent);
         mTestableLooper.processAllMessages();
         assertEquals(TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_USER_CANCELED, mResult);
 
@@ -528,6 +582,7 @@
     public void testPurchasePremiumCapabilityResultCarrierError() {
         sendValidPurchaseRequest();
 
+        // broadcast CARRIER_ERROR response from slice purchase application
         Intent intent = new Intent();
         intent.setAction(
                 "com.android.phone.slice.action.SLICE_PURCHASE_APP_RESPONSE_CARRIER_ERROR");
@@ -536,7 +591,7 @@
                 TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY);
         intent.putExtra(SlicePurchaseController.EXTRA_FAILURE_CODE,
                 SlicePurchaseController.FAILURE_CODE_SERVER_UNREACHABLE);
-        mBroadcastReceiver.onReceive(mMockedContext, intent);
+        mContext.getBroadcastReceiver().onReceive(mContext, intent);
         mTestableLooper.processAllMessages();
         assertEquals(TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_CARRIER_ERROR, mResult);
 
@@ -558,13 +613,14 @@
     public void testPurchasePremiumCapabilityResultRequestFailed() {
         sendValidPurchaseRequest();
 
+        // broadcast REQUEST_FAILED response from slice purchase application
         Intent intent = new Intent();
         intent.setAction(
                 "com.android.phone.slice.action.SLICE_PURCHASE_APP_RESPONSE_REQUEST_FAILED");
         intent.putExtra(SlicePurchaseController.EXTRA_PHONE_ID, PHONE_ID);
         intent.putExtra(SlicePurchaseController.EXTRA_PREMIUM_CAPABILITY,
                 TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY);
-        mBroadcastReceiver.onReceive(mMockedContext, intent);
+        mContext.getBroadcastReceiver().onReceive(mContext, intent);
         mTestableLooper.processAllMessages();
         assertEquals(TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_REQUEST_FAILED, mResult);
 
@@ -582,7 +638,7 @@
         intent.putExtra(SlicePurchaseController.EXTRA_PHONE_ID, PHONE_ID);
         intent.putExtra(SlicePurchaseController.EXTRA_PREMIUM_CAPABILITY,
                 TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY);
-        mBroadcastReceiver.onReceive(mMockedContext, intent);
+        mContext.getBroadcastReceiver().onReceive(mContext, intent);
         mTestableLooper.processAllMessages();
         assertEquals(
                 TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_NOT_DEFAULT_DATA_SUBSCRIPTION,
@@ -592,8 +648,70 @@
         testPurchasePremiumCapabilityResultSuccess();
     }
 
+    @Test
+    public void testPurchasePremiumCapabilityResultNotificationThrottled() {
+        mSlicePurchaseController.setLocalDate(LocalDate.of(YEAR, MONTH, DATE));
+        mSlicePurchaseController.updateNotificationCounts();
+
+        for (int count = 1; count <= DAILY_NOTIFICATION_MAX; count++) {
+            completeSuccessfulPurchase();
+            verify(mEditor).putInt(eq(DAILY_NOTIFICATION_COUNT_KEY), eq(count));
+            verify(mEditor).putInt(eq(MONTHLY_NOTIFICATION_COUNT_KEY), eq(count));
+        }
+
+        // retry to verify throttled
+        mSlicePurchaseController.purchasePremiumCapability(
+                TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY, TAG,
+                mHandler.obtainMessage());
+        mTestableLooper.processAllMessages();
+        assertEquals(TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED, mResult);
+
+        // change the date to trigger daily reset
+        mSlicePurchaseController.setLocalDate(LocalDate.of(YEAR, MONTH, DATE + 1));
+        Mockito.clearInvocations(mEditor);
+
+        for (int count = 1; count <= (MONTHLY_NOTIFICATION_MAX - DAILY_NOTIFICATION_MAX); count++) {
+            completeSuccessfulPurchase();
+            verify(mEditor).putInt(eq(DAILY_NOTIFICATION_COUNT_KEY), eq(count));
+            verify(mEditor).putInt(eq(MONTHLY_NOTIFICATION_COUNT_KEY),
+                    eq(count + DAILY_NOTIFICATION_MAX));
+        }
+
+        // retry to verify throttled
+        mSlicePurchaseController.purchasePremiumCapability(
+                TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY, TAG,
+                mHandler.obtainMessage());
+        mTestableLooper.processAllMessages();
+        assertEquals(TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_THROTTLED, mResult);
+    }
+
+    private void completeSuccessfulPurchase() {
+        sendValidPurchaseRequest();
+
+        // broadcast NOTIFICATION_SHOWN response from slice purchase application
+        Intent intent = new Intent();
+        intent.setAction(
+                "com.android.phone.slice.action.SLICE_PURCHASE_APP_RESPONSE_NOTIFICATION_SHOWN");
+        intent.putExtra(SlicePurchaseController.EXTRA_PHONE_ID, PHONE_ID);
+        intent.putExtra(SlicePurchaseController.EXTRA_PREMIUM_CAPABILITY,
+                TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY);
+        mContext.getBroadcastReceiver().onReceive(mContext, intent);
+        mTestableLooper.processAllMessages();
+
+        // broadcast SUCCESS response from slice purchase application
+        intent.setAction("com.android.phone.slice.action.SLICE_PURCHASE_APP_RESPONSE_SUCCESS");
+        mContext.getBroadcastReceiver().onReceive(mContext, intent);
+        mTestableLooper.processAllMessages();
+        assertEquals(TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_SUCCESS, mResult);
+
+        // complete network setup
+        sendNetworkSlicingConfig(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY, true);
+        // purchase expired
+        sendNetworkSlicingConfig(TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY, false);
+    }
+
     private void sendValidPurchaseRequest() {
-        clearInvocations(mMockedContext);
+        clearInvocations(mContext);
 
         // feature supported
         doReturn((int) TelephonyManager.NETWORK_TYPE_BITMASK_NR).when(mPhone)
@@ -614,7 +732,6 @@
         mBundle.putLong(CarrierConfigManager
                 .KEY_PREMIUM_CAPABILITY_PURCHASE_CONDITION_BACKOFF_HYSTERESIS_TIME_MILLIS_LONG,
                 PURCHASE_CONDITION_TIMEOUT);
-        doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt());
         // default data subscription
         doReturn(SubscriptionManager.getDefaultDataSubscriptionId()).when(mPhone).getSubId();
         // network available
@@ -622,8 +739,6 @@
         // entitlement check passed
         mEntitlementResponse.mEntitlementStatus =
                 PremiumNetworkEntitlementResponse.PREMIUM_NETWORK_ENTITLEMENT_STATUS_ENABLED;
-        doReturn(mEntitlementResponse).when(mPremiumNetworkEntitlementApi)
-                .checkEntitlementStatus(anyInt());
 
         // send purchase request
         mSlicePurchaseController.purchasePremiumCapability(
@@ -632,18 +747,27 @@
         mTestableLooper.processAllMessages();
 
         // verify that the purchase request was sent successfully
-        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
-        verify(mMockedContext).sendBroadcast(intentCaptor.capture());
-        Intent intent = intentCaptor.getValue();
-        assertEquals(SlicePurchaseController.ACTION_START_SLICE_PURCHASE_APP, intent.getAction());
+        verify(mContext).sendBroadcast(any(Intent.class));
+        assertEquals(SlicePurchaseController.ACTION_START_SLICE_PURCHASE_APP,
+                mContext.getBroadcast().getAction());
         assertTrue(mSlicePurchaseController.hasMessages(4 /* EVENT_PURCHASE_TIMEOUT */,
                 TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY));
+        verify(mContext).registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class));
+    }
 
-        // capture the broadcast receiver to fake responses from the slice purchase application
-        ArgumentCaptor<SlicePurchaseControllerBroadcastReceiver> broadcastReceiverCaptor =
-                ArgumentCaptor.forClass(SlicePurchaseControllerBroadcastReceiver.class);
-        verify(mMockedContext).registerReceiver(
-                broadcastReceiverCaptor.capture(), any(IntentFilter.class));
-        mBroadcastReceiver = broadcastReceiverCaptor.getValue();
+    private void sendNetworkSlicingConfig(int capability, boolean configActive) {
+        int sliceServiceType = capability == TelephonyManager.PREMIUM_CAPABILITY_PRIORITIZE_LATENCY
+                ? NetworkSliceInfo.SLICE_SERVICE_TYPE_URLLC
+                : NetworkSliceInfo.SLICE_SERVICE_TYPE_NONE;
+        NetworkSliceInfo sliceInfo = new NetworkSliceInfo.Builder()
+                .setStatus(configActive ? NetworkSliceInfo.SLICE_STATUS_ALLOWED
+                        : NetworkSliceInfo.SLICE_STATUS_UNKNOWN)
+                .setSliceServiceType(sliceServiceType)
+                .build();
+        NetworkSlicingConfig slicingConfig = new NetworkSlicingConfig(Collections.emptyList(),
+                Collections.singletonList(sliceInfo));
+        mSlicePurchaseController.obtainMessage(2 /* EVENT_SLICING_CONFIG_CHANGED */,
+                new AsyncResult(null, slicingConfig, null)).sendToTarget();
+        mTestableLooper.processAllMessages();
     }
 }
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
index 85be48d..1208ee2 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
@@ -16,6 +16,13 @@
 
 package com.android.services.telephony;
 
+import static android.telephony.DisconnectCause.NOT_DISCONNECTED;
+import static android.telephony.DomainSelectionService.SELECTOR_TYPE_CALLING;
+import static android.telephony.NetworkRegistrationInfo.DOMAIN_CS;
+import static android.telephony.NetworkRegistrationInfo.DOMAIN_PS;
+import static android.telephony.emergency.EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE;
+import static android.telephony.ims.ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL;
+
 import static com.android.internal.telephony.RILConstants.GSM_PHONE;
 
 import static junit.framework.Assert.assertEquals;
@@ -25,14 +32,15 @@
 import static junit.framework.Assert.fail;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -46,26 +54,33 @@
 import android.telecom.DisconnectCause;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
-import android.telephony.CarrierConfigManager;
 import android.telephony.RadioAccessFamily;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.emergency.EmergencyNumber;
+import android.telephony.ims.ImsReasonInfo;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.TelephonyTestBase;
+import com.android.ims.ImsManager;
 import com.android.internal.telecom.IConnectionService;
 import com.android.internal.telephony.Call;
 import com.android.internal.telephony.CallStateException;
 import com.android.internal.telephony.Connection;
 import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.PhoneInternalInterface.DialArgs;
 import com.android.internal.telephony.ServiceStateTracker;
 import com.android.internal.telephony.data.PhoneSwitcher;
+import com.android.internal.telephony.domainselection.DomainSelectionResolver;
+import com.android.internal.telephony.domainselection.EmergencyCallDomainSelectionConnection;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
+import com.android.internal.telephony.emergency.EmergencyStateTracker;
 import com.android.internal.telephony.gsm.SuppServiceNotification;
+import com.android.internal.telephony.imsphone.ImsPhone;
 
 import org.junit.After;
 import org.junit.Before;
@@ -73,11 +88,14 @@
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
 
 /**
  * Unit tests for TelephonyConnectionService.
@@ -116,6 +134,8 @@
     private static final PhoneAccountHandle PHONE_ACCOUNT_HANDLE_2 = new PhoneAccountHandle(
             TEST_COMPONENT_NAME, TEST_ACCOUNT_ID2);
     private static final Uri TEST_ADDRESS = Uri.parse("tel:+16505551212");
+    private static final String TELECOM_CALL_ID1 = "TC1";
+    private static final String TEST_EMERGENCY_NUMBER = "911";
     private android.telecom.Connection mConnection;
 
     @Mock TelephonyConnectionService.TelephonyManagerProxy mTelephonyManagerProxy;
@@ -135,6 +155,10 @@
     @Mock Call mCall2;
     @Mock com.android.internal.telephony.Connection mInternalConnection;
     @Mock com.android.internal.telephony.Connection mInternalConnection2;
+    @Mock DomainSelectionResolver mDomainSelectionResolver;
+    @Mock EmergencyCallDomainSelectionConnection mEmergencyCallDomainSelectionConnection;
+    @Mock ImsPhone mImsPhone;
+    private EmergencyStateTracker mEmergencyStateTracker;
     private Phone mPhone0;
     private Phone mPhone1;
 
@@ -180,6 +204,20 @@
         mTestConnectionService.setDisconnectCauseFactory(mDisconnectCauseFactory);
         mTestConnectionService.onCreate();
         mTestConnectionService.setTelephonyManagerProxy(mTelephonyManagerProxy);
+        DomainSelectionResolver.setDomainSelectionResolver(mDomainSelectionResolver);
+        replaceInstance(TelephonyConnectionService.class, "mDomainSelectionResolver",
+                mTestConnectionService, mDomainSelectionResolver);
+        mEmergencyStateTracker = Mockito.mock(EmergencyStateTracker.class);
+        replaceInstance(TelephonyConnectionService.class, "mEmergencyStateTracker",
+                mTestConnectionService, mEmergencyStateTracker);
+        doReturn(CompletableFuture.completedFuture(NOT_DISCONNECTED))
+                .when(mEmergencyStateTracker)
+                .startEmergencyCall(any(), anyString(), eq(false));
+        replaceInstance(TelephonyConnectionService.class,
+                "mDomainSelectionMainExecutor", mTestConnectionService, getExecutor());
+        doReturn(false).when(mDomainSelectionResolver).isDomainSelectionSupported();
+        doReturn(null).when(mDomainSelectionResolver).getDomainSelectionConnection(
+                any(), anyInt(), anyBoolean());
         mBinderStub = (IConnectionService.Stub) mTestConnectionService.onBind(null);
     }
 
@@ -1107,221 +1145,6 @@
     }
 
     /**
-     * Test that the TelephonyConnectionService successfully performs a DDS switch before a call
-     * when we are not roaming and the carrier only supports SUPL over the data plane.
-     */
-    @Test
-    @SmallTest
-    public void testCreateOutgoingEmergencyConnection_delayDial_carrierconfig_dds() {
-        // Setup test to not support SUPL on the non-DDS subscription
-        doReturn(true).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any());
-        getTestContext().getCarrierConfig(0 /*subId*/).putStringArray(
-                CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY,
-                null);
-        getTestContext().getCarrierConfig(0 /*subId*/).putInt(
-                CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
-                CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_DP_ONLY);
-        getTestContext().getCarrierConfig(0 /*subId*/).putString(
-                CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "150");
-
-        Phone testPhone = setupConnectionServiceForDelayDial(
-                false /* isRoaming */, false /* setOperatorName */, null /* operator long name*/,
-                        null /* operator short name */, null /* operator numeric name */);
-        verify(mPhoneSwitcher).overrideDefaultDataForEmergency(eq(0) /*phoneId*/ ,
-                eq(150) /*extensionTime*/, any());
-    }
-
-    /**
-     * Test that the TelephonyConnectionService successfully turns radio on before placing the
-     * emergency call.
-     */
-    @Test
-    @SmallTest
-    public void testCreateOutgoingEmerge_exitingApm_disconnected() {
-        when(mDeviceState.isAirplaneModeOn(any())).thenReturn(true);
-        Phone testPhone = setupConnectionServiceInApm();
-
-        ArgumentCaptor<RadioOnStateListener.Callback> callback =
-                ArgumentCaptor.forClass(RadioOnStateListener.Callback.class);
-        verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true),
-                eq(testPhone), eq(false));
-
-        assertFalse(callback.getValue().isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE));
-        when(mSST.isRadioOn()).thenReturn(true);
-        assertTrue(callback.getValue().isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE));
-
-        mConnection.setDisconnected(null);
-        callback.getValue().onComplete(null, true);
-        for (Phone phone : mPhoneFactoryProxy.getPhones()) {
-            verify(phone).setRadioPower(true, false, false, true);
-        }
-    }
-
-    /**
-     * Test that the TelephonyConnectionService successfully turns radio on before placing the
-     * emergency call.
-     */
-    @Test
-    @SmallTest
-    public void testCreateOutgoingEmergencyConnection_exitingApm_placeCall() {
-        when(mDeviceState.isAirplaneModeOn(any())).thenReturn(true);
-        Phone testPhone = setupConnectionServiceInApm();
-
-        ArgumentCaptor<RadioOnStateListener.Callback> callback =
-                ArgumentCaptor.forClass(RadioOnStateListener.Callback.class);
-        verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true),
-                eq(testPhone), eq(false));
-
-        assertFalse(callback.getValue().isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE));
-        when(mSST.isRadioOn()).thenReturn(true);
-        assertTrue(callback.getValue().isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE));
-
-        callback.getValue().onComplete(null, true);
-
-        try {
-            doAnswer(invocation -> null).when(mContext).startActivity(any());
-            verify(testPhone).dial(anyString(), any(), any());
-        } catch (CallStateException e) {
-            // This shouldn't happen
-            fail();
-        }
-    }
-
-    /**
-     * Test that the TelephonyConnectionService does not perform a DDS switch when the carrier
-     * supports control-plane fallback.
-     */
-    @Test
-    @SmallTest
-    public void testCreateOutgoingEmergencyConnection_delayDial_nocarrierconfig() {
-        // Setup test to not support SUPL on the non-DDS subscription
-        doReturn(true).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any());
-        getTestContext().getCarrierConfig(0 /*subId*/).putStringArray(
-                CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY,
-                null);
-        getTestContext().getCarrierConfig(0 /*subId*/).putInt(
-                CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
-                CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_CP_FALLBACK);
-        getTestContext().getCarrierConfig(0 /*subId*/).putString(
-                CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0");
-
-        Phone testPhone = setupConnectionServiceForDelayDial(
-                false /* isRoaming */, false /* setOperatorName */, null /* operator long name*/,
-                        null /* operator short name */, null /* operator numeric name */);
-        verify(mPhoneSwitcher, never()).overrideDefaultDataForEmergency(anyInt(), anyInt(), any());
-    }
-
-    /**
-     * Test that the TelephonyConnectionService does not perform a DDS switch when the carrier
-     * supports control-plane fallback.
-     */
-    @Test
-    @SmallTest
-    public void testCreateOutgoingEmergencyConnection_delayDial_supportsuplondds() {
-        // If the non-DDS supports SUPL, dont switch data
-        doReturn(false).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any());
-        getTestContext().getCarrierConfig(0 /*subId*/).putStringArray(
-                CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY,
-                null);
-        getTestContext().getCarrierConfig(0 /*subId*/).putInt(
-                CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
-                CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_DP_ONLY);
-        getTestContext().getCarrierConfig(0 /*subId*/).putString(
-                CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0");
-
-        Phone testPhone = setupConnectionServiceForDelayDial(
-                false /* isRoaming */, false /* setOperatorName */, null /* operator long name*/,
-                         null /* operator short name */, null /* operator numeric name */);
-        verify(mPhoneSwitcher, never()).overrideDefaultDataForEmergency(anyInt(), anyInt(), any());
-    }
-
-    /**
-     * Test that the TelephonyConnectionService does not perform a DDS switch when the carrier does
-     * not support control-plane fallback CarrierConfig while roaming.
-     */
-    @Test
-    @SmallTest
-    public void testCreateOutgoingEmergencyConnection_delayDial_roaming_nocarrierconfig() {
-        // Setup test to not support SUPL on the non-DDS subscription
-        doReturn(true).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any());
-        getTestContext().getCarrierConfig(0 /*subId*/).putStringArray(
-                CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY,
-                null);
-        getTestContext().getCarrierConfig(0 /*subId*/).putInt(
-                CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
-                CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_DP_ONLY);
-        getTestContext().getCarrierConfig(0 /*subId*/).putString(
-                CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0");
-
-        Phone testPhone = setupConnectionServiceForDelayDial(
-                true /* isRoaming */, false /* setOperatorName */, null /* operator long name*/,
-                         null /* operator short name */, null /* operator numeric name */);
-        verify(mPhoneSwitcher, never()).overrideDefaultDataForEmergency(anyInt(), anyInt(), any());
-    }
-
-    /**
-     * Test that the TelephonyConnectionService does perform a DDS switch even though the carrier
-     * supports control-plane fallback CarrierConfig and the roaming partner is configured to look
-     * like a home network.
-     */
-    @Test
-    @SmallTest
-    public void testCreateOutgoingEmergencyConnection_delayDial_roamingcarrierconfig() {
-        doReturn(true).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any());
-        // Setup voice roaming scenario
-        String testRoamingOperator = "001001";
-        // Setup test to not support SUPL on the non-DDS subscription
-        String[] roamingPlmns = new String[1];
-        roamingPlmns[0] = testRoamingOperator;
-        getTestContext().getCarrierConfig(0 /*subId*/).putStringArray(
-                CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY,
-                roamingPlmns);
-        getTestContext().getCarrierConfig(0 /*subId*/).putInt(
-                CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
-                CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_CP_FALLBACK);
-        getTestContext().getCarrierConfig(0 /*subId*/).putString(
-                CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0");
-
-        Phone testPhone = setupConnectionServiceForDelayDial(
-                false /* isRoaming */, true /* setOperatorName */,
-                        "TestTel" /* operator long name*/, "TestTel" /* operator short name */,
-                                testRoamingOperator /* operator numeric name */);
-        verify(mPhoneSwitcher).overrideDefaultDataForEmergency(eq(0) /*phoneId*/ ,
-                eq(0) /*extensionTime*/, any());
-    }
-
-    /**
-     * Test that the TelephonyConnectionService does perform a DDS switch even though the carrier
-     * supports control-plane fallback CarrierConfig if we are roaming and the roaming partner is
-     * configured to use data plane only SUPL.
-     */
-    @Test
-    @SmallTest
-    public void testCreateOutgoingEmergencyConnection_delayDial__roaming_roamingcarrierconfig() {
-        // Setup test to not support SUPL on the non-DDS subscription
-        doReturn(true).when(mDeviceState).isSuplDdsSwitchRequiredForEmergencyCall(any());
-        // Setup voice roaming scenario
-        String testRoamingOperator = "001001";
-        String[] roamingPlmns = new String[1];
-        roamingPlmns[0] = testRoamingOperator;
-        getTestContext().getCarrierConfig(0 /*subId*/).putStringArray(
-                CarrierConfigManager.Gps.KEY_ES_SUPL_DATA_PLANE_ONLY_ROAMING_PLMN_STRING_ARRAY,
-                roamingPlmns);
-        getTestContext().getCarrierConfig(0 /*subId*/).putInt(
-                CarrierConfigManager.Gps.KEY_ES_SUPL_CONTROL_PLANE_SUPPORT_INT,
-                CarrierConfigManager.Gps.SUPL_EMERGENCY_MODE_TYPE_CP_FALLBACK);
-        getTestContext().getCarrierConfig(0 /*subId*/).putString(
-                CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, "0");
-
-        Phone testPhone = setupConnectionServiceForDelayDial(
-                false /* isRoaming */, true /* setOperatorName */,
-                        "TestTel" /* operator long name*/, "TestTel" /* operator short name */,
-                                testRoamingOperator /* operator numeric name */);
-        verify(mPhoneSwitcher).overrideDefaultDataForEmergency(eq(0) /*phoneId*/ ,
-                eq(0) /*extensionTime*/, any());
-    }
-
-    /**
      * Verifies for an incoming call on the same SIM that we don't set
      * {@link android.telecom.Connection#EXTRA_ANSWERING_DROPS_FG_CALL} on the incoming call extras.
      * @throws Exception
@@ -1545,6 +1368,277 @@
                 .isCurrentEmergencyNumber(TEST_ADDRESS.getSchemeSpecificPart());
     }
 
+    @Test
+    public void testDomainSelectionCs() throws Exception {
+        setupForCallTest();
+
+        int selectedDomain = DOMAIN_CS;
+
+        setupForDialForDomainSelection(mPhone0, selectedDomain, true);
+
+        mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1,
+                createConnectionRequest(PHONE_ACCOUNT_HANDLE_1,
+                        TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1));
+
+        verify(mDomainSelectionResolver)
+                .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
+        verify(mEmergencyStateTracker)
+                .startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+        verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
+
+        ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
+
+        verify(mPhone0).dial(anyString(), argsCaptor.capture(), any());
+        DialArgs dialArgs = argsCaptor.getValue();
+        assertNotNull("DialArgs param is null", dialArgs);
+        assertNotNull("intentExtras is null", dialArgs.intentExtras);
+        assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN));
+        assertEquals(selectedDomain,
+                dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1));
+    }
+
+    @Test
+    public void testDomainSelectionPs() throws Exception {
+        setupForCallTest();
+
+        int selectedDomain = DOMAIN_PS;
+
+        setupForDialForDomainSelection(mPhone0, selectedDomain, true);
+
+        mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1,
+                createConnectionRequest(PHONE_ACCOUNT_HANDLE_1,
+                        TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1));
+
+        verify(mDomainSelectionResolver)
+                .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
+        verify(mEmergencyStateTracker)
+                .startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+        verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
+
+        ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
+
+        verify(mPhone0).dial(anyString(), argsCaptor.capture(), any());
+        DialArgs dialArgs = argsCaptor.getValue();
+        assertNotNull("DialArgs param is null", dialArgs);
+        assertNotNull("intentExtras is null", dialArgs.intentExtras);
+        assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN));
+        assertEquals(selectedDomain,
+                dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1));
+    }
+
+    @Test
+    public void testDomainSelectionCsForTty() throws Exception {
+        setupForCallTest();
+
+        ImsManager imsManager = Mockito.mock(ImsManager.class);
+        doReturn(false).when(imsManager).isNonTtyOrTtyOnVolteEnabled();
+        replaceInstance(TelephonyConnectionService.class,
+                "mImsManager", mTestConnectionService, imsManager);
+
+        setupForDialForDomainSelection(mPhone0, DOMAIN_PS, true);
+
+        mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1,
+                createConnectionRequest(PHONE_ACCOUNT_HANDLE_1,
+                        TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1));
+
+        verify(mEmergencyStateTracker, times(1))
+                .startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+        verify(mDomainSelectionResolver, times(0))
+                .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
+        verify(mEmergencyCallDomainSelectionConnection, times(0))
+                .createEmergencyConnection(any(), any());
+
+        ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
+
+        verify(mPhone0).dial(anyString(), argsCaptor.capture(), any());
+        DialArgs dialArgs = argsCaptor.getValue();
+        assertNotNull("DialArgs param is null", dialArgs);
+        assertNotNull("intentExtras is null", dialArgs.intentExtras);
+        assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN));
+        assertEquals(DOMAIN_CS, dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1));
+    }
+
+    @Test
+    public void testDomainSelectionRedialCs() throws Exception {
+        setupForCallTest();
+
+        int preciseDisconnectCause = com.android.internal.telephony.CallFailCause.ERROR_UNSPECIFIED;
+        int disconnectCause = android.telephony.DisconnectCause.ERROR_UNSPECIFIED;
+        int selectedDomain = DOMAIN_CS;
+
+        TestTelephonyConnection c = setupForReDialForDomainSelection(
+                mPhone0, selectedDomain, preciseDisconnectCause, disconnectCause, true);
+
+        assertTrue(mTestConnectionService.maybeReselectDomain(c, preciseDisconnectCause, null));
+        verify(mEmergencyCallDomainSelectionConnection).reselectDomain(any());
+
+        ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
+
+        Connection nc = Mockito.mock(Connection.class);
+        doReturn(nc).when(mPhone0).dial(anyString(), any(), any());
+
+        verify(mPhone0).dial(anyString(), argsCaptor.capture(), any());
+        DialArgs dialArgs = argsCaptor.getValue();
+        assertNotNull("DialArgs param is null", dialArgs);
+        assertNotNull("intentExtras is null", dialArgs.intentExtras);
+        assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN));
+        assertEquals(selectedDomain,
+                dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1));
+    }
+
+    @Test
+    public void testDomainSelectionRedialPs() throws Exception {
+        setupForCallTest();
+
+        int preciseDisconnectCause = com.android.internal.telephony.CallFailCause.ERROR_UNSPECIFIED;
+        int disconnectCause = android.telephony.DisconnectCause.ERROR_UNSPECIFIED;
+        int selectedDomain = DOMAIN_PS;
+
+        TestTelephonyConnection c = setupForReDialForDomainSelection(
+                mPhone0, selectedDomain, preciseDisconnectCause, disconnectCause, true);
+
+        assertTrue(mTestConnectionService.maybeReselectDomain(c, preciseDisconnectCause, null));
+        verify(mEmergencyCallDomainSelectionConnection).reselectDomain(any());
+
+        ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
+
+        Connection nc = Mockito.mock(Connection.class);
+        doReturn(nc).when(mPhone0).dial(anyString(), any(), any());
+
+        verify(mPhone0).dial(anyString(), argsCaptor.capture(), any());
+        DialArgs dialArgs = argsCaptor.getValue();
+        assertNotNull("DialArgs param is null", dialArgs);
+        assertNotNull("intentExtras is null", dialArgs.intentExtras);
+        assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN));
+        assertEquals(selectedDomain,
+                dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1));
+    }
+
+    @Test
+    public void testDomainSelectionNormalToEmergencyCs() throws Exception {
+        setupForCallTest();
+
+        int preciseDisconnectCause = com.android.internal.telephony.CallFailCause.ERROR_UNSPECIFIED;
+        int disconnectCause = android.telephony.DisconnectCause.ERROR_UNSPECIFIED;
+        int eccCategory = EMERGENCY_SERVICE_CATEGORY_POLICE;
+        int selectedDomain = DOMAIN_CS;
+
+        setupForDialForDomainSelection(mPhone0, selectedDomain, true);
+
+        TestTelephonyConnection c = setupForReDialForDomainSelection(
+                mPhone0, selectedDomain, preciseDisconnectCause, disconnectCause, false);
+        c.setEmergencyServiceCategory(eccCategory);
+        c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED);
+
+        ImsReasonInfo reasonInfo = new ImsReasonInfo(CODE_SIP_ALTERNATE_EMERGENCY_CALL, 0, null);
+        assertTrue(mTestConnectionService.maybeReselectDomain(c,
+                  preciseDisconnectCause, reasonInfo));
+
+        verify(mDomainSelectionResolver)
+                .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
+        verify(mEmergencyStateTracker)
+                .startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+        verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
+
+        ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
+
+        verify(mPhone0).dial(anyString(), argsCaptor.capture(), any());
+        DialArgs dialArgs = argsCaptor.getValue();
+        assertNotNull("DialArgs param is null", dialArgs);
+        assertNotNull("intentExtras is null", dialArgs.intentExtras);
+        assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN));
+        assertEquals(selectedDomain,
+                dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1));
+        assertTrue(dialArgs.isEmergency);
+        assertEquals(eccCategory, dialArgs.eccCategory);
+    }
+
+    @Test
+    public void testDomainSelectionNormalToEmergencyPs() throws Exception {
+        setupForCallTest();
+
+        int preciseDisconnectCause = com.android.internal.telephony.CallFailCause.ERROR_UNSPECIFIED;
+        int disconnectCause = android.telephony.DisconnectCause.ERROR_UNSPECIFIED;
+        int eccCategory = EMERGENCY_SERVICE_CATEGORY_POLICE;
+        int selectedDomain = DOMAIN_PS;
+
+        setupForDialForDomainSelection(mPhone0, selectedDomain, true);
+
+        TestTelephonyConnection c = setupForReDialForDomainSelection(
+                mPhone0, selectedDomain, preciseDisconnectCause, disconnectCause, false);
+        c.setEmergencyServiceCategory(eccCategory);
+        c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED);
+
+        ImsReasonInfo reasonInfo = new ImsReasonInfo(CODE_SIP_ALTERNATE_EMERGENCY_CALL, 0, null);
+        assertTrue(mTestConnectionService.maybeReselectDomain(c,
+                  preciseDisconnectCause, reasonInfo));
+
+        verify(mDomainSelectionResolver)
+                .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
+        verify(mEmergencyStateTracker)
+                .startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+        verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
+
+        ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
+
+        verify(mPhone0).dial(anyString(), argsCaptor.capture(), any());
+        DialArgs dialArgs = argsCaptor.getValue();
+        assertNotNull("DialArgs param is null", dialArgs);
+        assertNotNull("intentExtras is null", dialArgs.intentExtras);
+        assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN));
+        assertEquals(selectedDomain,
+                dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1));
+        assertTrue(dialArgs.isEmergency);
+        assertEquals(eccCategory, dialArgs.eccCategory);
+    }
+
+    private void setupForDialForDomainSelection(Phone mockPhone, int domain, boolean isEmergency) {
+        if (isEmergency) {
+            doReturn(mEmergencyCallDomainSelectionConnection).when(mDomainSelectionResolver)
+                    .getDomainSelectionConnection(any(), anyInt(), eq(true));
+            doReturn(CompletableFuture.completedFuture(domain))
+                    .when(mEmergencyCallDomainSelectionConnection)
+                    .createEmergencyConnection(any(), any());
+            doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(anyString());
+        }
+
+        doReturn(true).when(mDomainSelectionResolver).isDomainSelectionSupported();
+        doReturn(mImsPhone).when(mockPhone).getImsPhone();
+    }
+
+    private TestTelephonyConnection setupForReDialForDomainSelection(
+            Phone mockPhone, int domain, int preciseDisconnectCause,
+            int disconnectCause, boolean fromEmergency) throws Exception {
+        try {
+            if (fromEmergency) {
+                doReturn(CompletableFuture.completedFuture(domain))
+                        .when(mEmergencyCallDomainSelectionConnection)
+                        .reselectDomain(any());
+                replaceInstance(TelephonyConnectionService.class,
+                        "mEmergencyCallDomainSelectionConnection",
+                        mTestConnectionService, mEmergencyCallDomainSelectionConnection);
+                replaceInstance(TelephonyConnectionService.class, "mEmergencyCallId",
+                        mTestConnectionService, TELECOM_CALL_ID1);
+            }
+        } catch (Exception e) {
+            // This shouldn't happen
+            fail();
+        }
+
+        doReturn(true).when(mDomainSelectionResolver).isDomainSelectionSupported();
+
+        TestTelephonyConnection c = new TestTelephonyConnection();
+        c.setTelecomCallId(TELECOM_CALL_ID1);
+        c.setMockPhone(mockPhone);
+        c.setAddress(TEST_ADDRESS, TelecomManager.PRESENTATION_ALLOWED);
+
+        Connection oc = c.getOriginalConnection();
+        doReturn(disconnectCause).when(oc).getDisconnectCause();
+        doReturn(preciseDisconnectCause).when(oc).getPreciseDisconnectCause();
+
+        return c;
+    }
+
     private SimpleTelephonyConnection createTestConnection(PhoneAccountHandle handle,
             int properties, boolean isEmergency) {
         SimpleTelephonyConnection connection = new SimpleTelephonyConnection();
@@ -1760,4 +1854,18 @@
             fail();
         }
     }
+
+    private ConnectionRequest createConnectionRequest(
+            PhoneAccountHandle accountHandle, String address, String callId) {
+        return new ConnectionRequest.Builder()
+                .setAccountHandle(accountHandle)
+                .setAddress(Uri.parse("tel:" + address))
+                .setExtras(new Bundle())
+                .setTelecomCallId(callId)
+                .build();
+    }
+
+    private Executor getExecutor() {
+        return Runnable::run;
+    }
 }
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionTest.java
index c996e5f..3c309ba 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionTest.java
@@ -1,5 +1,7 @@
 package com.android.services.telephony;
 
+import static android.telecom.Connection.STATE_DISCONNECTED;
+
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertNull;
@@ -7,6 +9,9 @@
 import static junit.framework.Assert.fail;
 import static junit.framework.TestCase.assertFalse;
 
+import static org.junit.Assert.assertNotEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
@@ -26,7 +31,6 @@
 import com.android.internal.telephony.d2d.DtmfTransport;
 import com.android.internal.telephony.d2d.RtpTransport;
 import com.android.internal.telephony.imsphone.ImsPhoneConnection;
-import com.android.phone.PhoneGlobals;
 import com.android.phone.R;
 
 import org.junit.Before;
@@ -39,6 +43,8 @@
 public class TelephonyConnectionTest {
     @Mock
     private ImsPhoneConnection mImsPhoneConnection;
+    @Mock
+    private TelephonyConnectionService mTelephonyConnectionService;
 
     @Before
     public void setUp() throws Exception {
@@ -257,4 +263,44 @@
         assertTrue(c.isRttMergeSupported(c.getCarrierConfig()));
     }
 
+    @Test
+    public void testDomainSelectionDisconnected() {
+        TestTelephonyConnection c = new TestTelephonyConnection();
+        c.setOriginalConnection(mImsPhoneConnection);
+        doReturn(Call.State.DISCONNECTED).when(mImsPhoneConnection)
+                .getState();
+        c.setTelephonyConnectionService(mTelephonyConnectionService);
+        c.updateState();
+
+        verify(mTelephonyConnectionService)
+                .maybeReselectDomain(any(), anyInt(), any());
+    }
+
+    @Test
+    public void testDomainSelectionDisconnected_NoRedial() {
+        TestTelephonyConnection c = new TestTelephonyConnection();
+        c.setOriginalConnection(mImsPhoneConnection);
+        doReturn(Call.State.DISCONNECTED).when(mImsPhoneConnection)
+                .getState();
+        c.setTelephonyConnectionService(mTelephonyConnectionService);
+        doReturn(false).when(mTelephonyConnectionService)
+                .maybeReselectDomain(any(), anyInt(), any());
+        c.updateState();
+
+        assertEquals(STATE_DISCONNECTED, c.getState());
+    }
+
+    @Test
+    public void testDomainSelectionDisconnected_Redial() {
+        TestTelephonyConnection c = new TestTelephonyConnection();
+        c.setOriginalConnection(mImsPhoneConnection);
+        doReturn(Call.State.DISCONNECTED).when(mImsPhoneConnection)
+                .getState();
+        c.setTelephonyConnectionService(mTelephonyConnectionService);
+        doReturn(true).when(mTelephonyConnectionService)
+                .maybeReselectDomain(any(), anyInt(), any());
+        c.updateState();
+
+        assertNotEquals(STATE_DISCONNECTED, c.getState());
+    }
 }
diff --git a/tests/src/com/android/services/telephony/domainselection/DomainSelectorBaseTest.java b/tests/src/com/android/services/telephony/domainselection/DomainSelectorBaseTest.java
new file mode 100644
index 0000000..74c3311
--- /dev/null
+++ b/tests/src/com/android/services/telephony/domainselection/DomainSelectorBaseTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony.domainselection;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.telephony.DomainSelectionService.SelectionAttributes;
+import android.telephony.TransportSelectorCallback;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.TestContext;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Unit tests for DomainSelectorBase.
+ */
+@RunWith(AndroidJUnit4.class)
+public class DomainSelectorBaseTest {
+    public class TestDomainSelectorBase extends DomainSelectorBase {
+        public TestDomainSelectorBase(Context context, int slotId, int subId,
+                @NonNull Looper looper, @NonNull ImsStateTracker imsStateTracker,
+                @NonNull DomainSelectorBase.DestroyListener listener, String logTag) {
+            super(context, slotId, subId, looper, imsStateTracker, listener, logTag);
+        }
+
+        @Override
+        public void cancelSelection() {
+            // No operations.
+        }
+
+        @Override
+        public void reselectDomain(@NonNull SelectionAttributes attr) {
+            // No operations.
+        }
+
+        @Override
+        public void finishSelection() {
+            // No operations.
+        }
+
+        @Override
+        public void selectDomain(SelectionAttributes attr, TransportSelectorCallback callback) {
+            // No operations.
+        }
+    }
+
+    private static final String TAG = DomainSelectorBaseTest.class.getSimpleName();
+    private static final int SLOT_0 = 0;
+    private static final int SUB_1 = 1;
+
+    @Mock private DomainSelectorBase.DestroyListener mDomainSelectorDestroyListener;
+    @Mock private ImsStateTracker mImsStateTracker;
+
+    private Context mContext;
+    private Looper mLooper;
+    private TestDomainSelectorBase mDomainSelector;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mContext = new TestContext();
+
+        HandlerThread handlerThread = new HandlerThread(TAG);
+        handlerThread.start();
+        mLooper = handlerThread.getLooper();
+        mDomainSelector = new TestDomainSelectorBase(mContext, SLOT_0, SUB_1, mLooper,
+                mImsStateTracker, mDomainSelectorDestroyListener, TAG);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        if (mDomainSelector != null) {
+            mDomainSelector.destroy();
+            mDomainSelector = null;
+        }
+
+        if (mLooper != null) {
+            mLooper.quit();
+            mLooper = null;
+        }
+
+        mDomainSelectorDestroyListener = null;
+        mImsStateTracker = null;
+        mContext = null;
+    }
+
+    @Test
+    @SmallTest
+    public void testInit() {
+        assertEquals(SLOT_0, mDomainSelector.getSlotId());
+        assertEquals(SUB_1, mDomainSelector.getSubId());
+    }
+
+    @Test
+    @SmallTest
+    public void testDestroy() {
+        mDomainSelector.destroy();
+        verify(mDomainSelectorDestroyListener).onDomainSelectorDestroyed(eq(mDomainSelector));
+        mDomainSelector = null;
+    }
+}
diff --git a/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
new file mode 100644
index 0000000..e1de0ab
--- /dev/null
+++ b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
@@ -0,0 +1,1081 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony.domainselection;
+
+import static android.telephony.AccessNetworkConstants.AccessNetworkType.EUTRAN;
+import static android.telephony.AccessNetworkConstants.AccessNetworkType.GERAN;
+import static android.telephony.AccessNetworkConstants.AccessNetworkType.UNKNOWN;
+import static android.telephony.AccessNetworkConstants.AccessNetworkType.UTRAN;
+import static android.telephony.BarringInfo.BARRING_SERVICE_TYPE_EMERGENCY;
+import static android.telephony.BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_CALL_SETUP_TIMER_ON_CURRENT_NETWORK_SEC_INT;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_CDMA_PREFERRED_NUMBERS_STRING_ARRAY;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_DOMAIN_PREFERENCE_ROAMING_INT_ARRAY;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_LTE_PREFERRED_AFTER_NR_FAILED_BOOL;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_NETWORK_SCAN_TYPE_INT;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_OVER_CS_ROAMING_SUPPORTED_ACCESS_NETWORK_TYPES_INT_ARRAY;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_OVER_CS_SUPPORTED_ACCESS_NETWORK_TYPES_INT_ARRAY;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_OVER_IMS_ROAMING_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_OVER_IMS_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_REQUIRES_IMS_REGISTRATION_BOOL;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_REQUIRES_VOLTE_ENABLED_BOOL;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_SCAN_TIMER_SEC_INT;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_MAXIMUM_NUMBER_OF_EMERGENCY_TRIES_OVER_VOWIFI_INT;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_PREFER_IMS_EMERGENCY_WHEN_VOICE_CALLS_ON_CS_BOOL;
+import static android.telephony.CarrierConfigManager.ImsEmergency.SCAN_TYPE_NO_PREFERENCE;
+import static android.telephony.DomainSelectionService.SELECTOR_TYPE_CALLING;
+import static android.telephony.NetworkRegistrationInfo.DOMAIN_CS;
+import static android.telephony.NetworkRegistrationInfo.DOMAIN_PS;
+import static android.telephony.NetworkRegistrationInfo.REGISTRATION_STATE_HOME;
+import static android.telephony.NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN;
+
+import static com.android.services.telephony.domainselection.EmergencyCallDomainSelector.MSG_NETWORK_SCAN_TIMEOUT;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IPowerManager;
+import android.os.IThermalService;
+import android.os.Looper;
+import android.os.PersistableBundle;
+import android.os.PowerManager;
+import android.telephony.AccessNetworkConstants;
+import android.telephony.BarringInfo;
+import android.telephony.CarrierConfigManager;
+import android.telephony.CellIdentityLte;
+import android.telephony.DomainSelectionService;
+import android.telephony.DomainSelectionService.SelectionAttributes;
+import android.telephony.EmergencyRegResult;
+import android.telephony.NetworkRegistrationInfo;
+import android.telephony.TelephonyManager;
+import android.telephony.TransportSelectorCallback;
+import android.telephony.WwanSelectorCallback;
+import android.telephony.ims.ImsManager;
+import android.telephony.ims.ImsMmTelManager;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.TestableLooper;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.TestContext;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.lang.reflect.Field;
+import java.util.List;
+import java.util.function.Consumer;
+
+/**
+ * Unit tests for EmergencyCallDomainSelector
+ */
+public class EmergencyCallDomainSelectorTest {
+    private static final String TAG = "EmergencyCallDomainSelectorTest";
+
+    private static final int SLOT_0 = 0;
+    private static final int SLOT_0_SUB_ID = 1;
+
+    @Mock private CarrierConfigManager mCarrierConfigManager;
+    @Mock private TelephonyManager mTelephonyManager;
+    @Mock private WwanSelectorCallback mWwanSelectorCallback;
+    @Mock private TransportSelectorCallback mTransportSelectorCallback;
+    @Mock private ImsMmTelManager mMmTelManager;
+    @Mock private ImsStateTracker mImsStateTracker;
+    @Mock private DomainSelectorBase.DestroyListener mDestroyListener;
+
+    private Context mContext;
+
+    private HandlerThread mHandlerThread;
+    private TestableLooper mLooper;
+    private EmergencyCallDomainSelector mDomainSelector;
+    private SelectionAttributes mSelectionAttributes;
+    private @AccessNetworkConstants.RadioAccessNetworkType List<Integer> mAccessNetwork;
+    private PowerManager mPowerManager;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mContext = new TestContext() {
+            @Override
+            public String getSystemServiceName(Class<?> serviceClass) {
+                if (serviceClass == ImsManager.class) {
+                    return Context.TELEPHONY_IMS_SERVICE;
+                } else if (serviceClass == TelephonyManager.class) {
+                    return Context.TELEPHONY_SERVICE;
+                } else if (serviceClass == CarrierConfigManager.class) {
+                    return Context.CARRIER_CONFIG_SERVICE;
+                } else if (serviceClass == PowerManager.class) {
+                    return Context.POWER_SERVICE;
+                }
+                return super.getSystemServiceName(serviceClass);
+            }
+
+            @Override
+            public Object getSystemService(String name) {
+                switch (name) {
+                    case (Context.POWER_SERVICE) : {
+                        return mPowerManager;
+                    }
+                }
+                return super.getSystemService(name);
+            }
+
+            @Override
+            public String getOpPackageName() {
+                return "";
+            }
+        };
+
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+
+        mHandlerThread = new HandlerThread("EmergencyCallDomainSelectorTest");
+        mHandlerThread.start();
+
+        try {
+            mLooper = new TestableLooper(mHandlerThread.getLooper());
+        } catch (Exception e) {
+            logd("Unable to create looper from handler.");
+        }
+
+        mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
+        when(mTelephonyManager.createForSubscriptionId(anyInt()))
+                .thenReturn(mTelephonyManager);
+        when(mTelephonyManager.getNetworkCountryIso()).thenReturn("");
+
+        mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt()))
+            .thenReturn(getDefaultPersistableBundle());
+
+        IPowerManager powerManager = mock(IPowerManager.class);
+        mPowerManager = new PowerManager(mContext, powerManager, mock(IThermalService.class),
+                new Handler(mHandlerThread.getLooper()));
+
+        ImsManager imsManager = mContext.getSystemService(ImsManager.class);
+        when(imsManager.getImsMmTelManager(anyInt())).thenReturn(mMmTelManager);
+        when(mMmTelManager.isAdvancedCallingSettingEnabled()).thenReturn(true);
+
+        when(mTransportSelectorCallback.onWwanSelected()).thenReturn(mWwanSelectorCallback);
+        doAnswer(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                Consumer<WwanSelectorCallback> consumer =
+                        (Consumer<WwanSelectorCallback>) invocation.getArguments()[0];
+                consumer.accept(mWwanSelectorCallback);
+                return null;
+            }
+        }).when(mTransportSelectorCallback).onWwanSelected(any());
+
+        doAnswer(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                mAccessNetwork = (List<Integer>) invocation.getArguments()[0];
+                return null;
+            }
+        }).when(mWwanSelectorCallback).onRequestEmergencyNetworkScan(
+                any(), anyInt(), any(), any());
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        if (mDomainSelector != null) {
+            mDomainSelector.destroy();
+            mDomainSelector = null;
+        }
+
+        if (mLooper != null) {
+            mLooper.destroy();
+            mLooper = null;
+        }
+    }
+
+    @SmallTest
+    @Test
+    public void testInit() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+
+        verify(mWwanSelectorCallback, times(0)).onRequestEmergencyNetworkScan(
+                any(), anyInt(), any(), any());
+        verify(mWwanSelectorCallback, times(0)).onDomainSelected(anyInt());
+    }
+
+    @Test
+    public void testDefaultCombinedImsRegisteredBarredSelectCs() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(true);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
+                true, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsService();
+
+        verifyCsDialed();
+    }
+
+    @Test
+    public void testDefaultCombinedImsRegisteredSelectPs() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
+                true, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsService();
+
+        verifyPsDialed();
+    }
+
+    @Test
+    public void testDefaultCombinedImsNotRegisteredSelectCs() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
+                true, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyCsDialed();
+    }
+
+    @Test
+    public void testDefaultCombinedImsNotRegisteredBarredSelectCs() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(true);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
+                true, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyCsDialed();
+    }
+
+    @Test
+    public void testDefaultCombinedImsRegisteredEmsOffBarredSelectCs() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(true);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
+                true, false, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsService();
+
+        verifyCsDialed();
+    }
+
+    @Test
+    public void testDefaultCombinedImsRegisteredEmsOffSelectCs() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
+                true, false, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsService();
+
+        verifyCsDialed();
+    }
+
+    @Test
+    public void testDefaultCombinedImsNotRegisteredEmsOffSelectCs() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
+                true, false, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyCsDialed();
+    }
+
+    @Test
+    public void testDefaultCombinedImsNotRegisteredEmsOffBarredSelectCs() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(true);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
+                true, false, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyCsDialed();
+    }
+
+    @Test
+    public void testDefaultCombinedImsRegisteredVopsOffBarredSelectCs() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(true);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
+                false, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsService();
+
+        verifyCsDialed();
+    }
+
+    @Test
+    public void testDefaultCombinedImsRegisteredVopsOffSelectCs() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
+                false, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsService();
+
+        verifyCsDialed();
+    }
+
+    @Test
+    public void testDefaultCombinedImsNotRegisteredVopsOffSelectCs() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
+                false, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyCsDialed();
+    }
+
+    @Test
+    public void testDefaultCombinedImsNotRegisteredVopsOffBarredSelectCs() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(true);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
+                false, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyCsDialed();
+    }
+
+    @Test
+    public void testDefaultCombinedImsRegisteredVopsOffEmsOffBarredSelectCs() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(true);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
+                false, false, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsService();
+
+        verifyCsDialed();
+    }
+
+    @Test
+    public void testDefaultCombinedImsRegisteredVopsOffEmsOffSelectCs() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
+                false, false, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsService();
+
+        verifyCsDialed();
+    }
+
+    @Test
+    public void testDefaultCombinedImsNotRegisteredVopsOffEmsOffSelectCs() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
+                false, false, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyCsDialed();
+    }
+
+    @Test
+    public void testDefaultCombinedImsNotRegisteredVopsOffEmsOffBarredSelectCs() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(true);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_CS | NetworkRegistrationInfo.DOMAIN_PS,
+                false, false, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyCsDialed();
+    }
+
+    @Test
+    public void testDefaultCsSelectCs() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(UTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_CS,
+                true, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyCsDialed();
+    }
+
+    @Test
+    public void testDefaultEpsImsRegisteredBarredScanPsPreferred() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(true);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                true, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsService();
+
+        verifyScanPsPreferred();
+    }
+
+    @Test
+    public void testDefaultEpsImsRegisteredSelectPs() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                true, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsService();
+
+        verifyPsDialed();
+    }
+
+    @Test
+    public void testDefaultEpsImsNotRegisteredSelectPs() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                true, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyPsDialed();
+    }
+
+    @Test
+    public void testDefaultEpsImsNotRegisteredBarredSelectScanPsPreferred() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(true);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                true, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyScanPsPreferred();
+    }
+
+    @Test
+    public void testDefaultEpsImsRegisteredEmsOffBarredScanPsPreferred() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(true);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                true, false, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsService();
+
+        verifyScanPsPreferred();
+    }
+
+    @Test
+    public void testDefaultEpsImsRegisteredEmsOffScanPsPreferred() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                true, false, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsService();
+
+        verifyScanPsPreferred();
+    }
+
+    @Test
+    public void testDefaultEpsImsNotRegisteredEmsOffScanPsPreferred() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                true, false, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyScanPsPreferred();
+    }
+
+    @Test
+    public void testDefaultEpsImsNotRegisteredEmsOffBarredScanPsPreferred() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(true);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                true, false, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyScanPsPreferred();
+    }
+
+    @Test
+    public void testDefaultEpsImsRegisteredVopsOffBarredScanPsPreferred() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(true);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                false, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsService();
+
+        verifyScanPsPreferred();
+    }
+
+    @Test
+    public void testDefaultEpsImsRegisteredVopsOffScanPsPreferred() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                false, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsService();
+
+        verifyScanPsPreferred();
+    }
+
+    @Test
+    public void testDefaultEpsImsNotRegisteredVopsOffScanPsPreferred() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                false, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyScanPsPreferred();
+    }
+
+    @Test
+    public void testDefaultEpsImsNotRegisteredVopsOffBarredScanPsPreferred() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(true);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                false, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyScanPsPreferred();
+    }
+
+    @Test
+    public void testDefaultEpsImsRegisteredVopsOffEmsOffBarredScanPsPreferred() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(true);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                false, false, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsService();
+
+        verifyScanPsPreferred();
+    }
+
+    @Test
+    public void testDefaultEpsImsRegisteredVopsOffEmsOffScanPsPreferred() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                false, false, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsService();
+
+        verifyScanPsPreferred();
+    }
+
+    @Test
+    public void testDefaultEpsImsNotRegisteredVopsOffEmsOffScanPsPreferred() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                false, false, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyScanPsPreferred();
+    }
+
+    @Test
+    public void testDefaultEpsNotRegisteredVopsOffEmsOffBarredScanPsPreferred() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(true);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                false, false, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyScanPsPreferred();
+    }
+
+    @Test
+    public void testDefaultOutOfServiceScanPsPreferred() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(
+                UNKNOWN, REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyScanPsPreferred();
+    }
+
+    @Test
+    public void testVoLteOnEpsImsNotRegisteredSelectPs() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        bundle.putBoolean(KEY_EMERGENCY_REQUIRES_VOLTE_ENABLED_BOOL, true);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(bundle);
+
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                true, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        // Requires VoLTE enabled and VoLTE is enabled.
+        verifyPsDialed();
+    }
+
+    @Test
+    public void testVoLteOffEpsImsNotRegisteredSelectCs() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        bundle.putBoolean(KEY_EMERGENCY_REQUIRES_VOLTE_ENABLED_BOOL, true);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(bundle);
+
+        // Disable VoLTE.
+        when(mMmTelManager.isAdvancedCallingSettingEnabled()).thenReturn(false);
+
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                true, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        // Requires VoLTE enabled but VoLTE is'nt enabled.
+        verifyCsDialed();
+    }
+
+    @Test
+    public void testRequiresRegEpsImsNotRegisteredScanCsPreferred() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        bundle.putBoolean(KEY_EMERGENCY_REQUIRES_IMS_REGISTRATION_BOOL, true);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(bundle);
+
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                true, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+
+        verifyScanCsPreferred();
+    }
+
+    @Test
+    public void testDefaultEpsImsRegisteredBarredScanTimeoutWifi() throws Exception {
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(true);
+
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                NetworkRegistrationInfo.DOMAIN_PS,
+                true, true, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsService(true);
+
+        verifyScanPsPreferred();
+
+        assertTrue(mDomainSelector.hasMessages(MSG_NETWORK_SCAN_TIMEOUT));
+
+        mDomainSelector.handleMessage(mDomainSelector.obtainMessage(MSG_NETWORK_SCAN_TIMEOUT));
+
+        verify(mTransportSelectorCallback, times(1)).onWlanSelected();
+    }
+
+    private void createSelector(int subId) throws Exception {
+        mDomainSelector = new EmergencyCallDomainSelector(
+                mContext, SLOT_0, subId, mHandlerThread.getLooper(),
+                mImsStateTracker, mDestroyListener);
+
+        replaceInstance(DomainSelectorBase.class,
+                "mWwanSelectorCallback", mDomainSelector, mWwanSelectorCallback);
+    }
+
+    private void verifyCsDialed() {
+        verify(mWwanSelectorCallback, times(1)).onDomainSelected(eq(DOMAIN_CS));
+    }
+
+    private void verifyPsDialed() {
+        verify(mWwanSelectorCallback, times(1)).onDomainSelected(eq(DOMAIN_PS));
+    }
+
+    private void verifyScanPsPreferred() {
+        verifyScanPreferred(DomainSelectionService.SCAN_TYPE_NO_PREFERENCE, EUTRAN);
+    }
+
+    private void verifyScanCsPreferred() {
+        verifyScanPreferred(DomainSelectionService.SCAN_TYPE_NO_PREFERENCE, UTRAN);
+    }
+
+    private void verifyScanPreferred(int scanType, int expectedPreferredAccessNetwork) {
+        verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
+                any(), eq(scanType), any(), any());
+        assertEquals(expectedPreferredAccessNetwork, (int) mAccessNetwork.get(0));
+    }
+
+    private void unsolBarringInfoChanged(boolean barred) {
+        SparseArray<BarringInfo.BarringServiceInfo> serviceInfos = new SparseArray<>();
+        if (barred) {
+            serviceInfos.put(BARRING_SERVICE_TYPE_EMERGENCY,
+                    new BarringInfo.BarringServiceInfo(BARRING_TYPE_UNCONDITIONAL, false, 0, 0));
+        }
+        mDomainSelector.onBarringInfoUpdated(new BarringInfo(new CellIdentityLte(), serviceInfos));
+    }
+
+    private void bindImsService() {
+        bindImsService(false);
+    }
+
+    private void bindImsService(boolean isWifi) {
+        doReturn(isWifi).when(mImsStateTracker).isImsRegisteredOverWlan();
+        doReturn(true).when(mImsStateTracker).isImsRegistered();
+        mDomainSelector.onImsRegistrationStateChanged();
+        doReturn(true).when(mImsStateTracker).isImsVoiceCapable();
+        mDomainSelector.onImsMmTelCapabilitiesChanged();
+    }
+
+    private void bindImsServiceUnregistered() {
+        doReturn(false).when(mImsStateTracker).isImsRegistered();
+        mDomainSelector.onImsRegistrationStateChanged();
+        doReturn(false).when(mImsStateTracker).isImsVoiceCapable();
+        mDomainSelector.onImsMmTelCapabilitiesChanged();
+    }
+
+    private static EmergencyRegResult getEmergencyRegResult(
+            @AccessNetworkConstants.RadioAccessNetworkType int accessNetwork,
+            @NetworkRegistrationInfo.RegistrationState int regState,
+            @NetworkRegistrationInfo.Domain int domain,
+            boolean isVopsSupported, boolean isEmcBearerSupported, int emc, int emf,
+            @NonNull String mcc, @NonNull String mnc) {
+        return new EmergencyRegResult(accessNetwork, regState,
+                domain, isVopsSupported, isEmcBearerSupported,
+                emc, emf, mcc, mnc, "");
+    }
+
+    private static PersistableBundle getDefaultPersistableBundle() {
+        int[] imsRats = new int[] { EUTRAN };
+        int[] csRats = new int[] { UTRAN, GERAN };
+        int[] imsRoamRats = new int[] { EUTRAN };
+        int[] csRoamRats = new int[] { UTRAN, GERAN };
+        int[] domainPreference = new int[] {
+                CarrierConfigManager.ImsEmergency.DOMAIN_PS_3GPP,
+                CarrierConfigManager.ImsEmergency.DOMAIN_CS,
+                CarrierConfigManager.ImsEmergency.DOMAIN_PS_NON_3GPP
+                };
+        int[] roamDomainPreference = new int[] {
+                CarrierConfigManager.ImsEmergency.DOMAIN_PS_3GPP,
+                CarrierConfigManager.ImsEmergency.DOMAIN_CS,
+                CarrierConfigManager.ImsEmergency.DOMAIN_PS_NON_3GPP
+                };
+        boolean imsWhenVoiceOnCs = false;
+        int maxRetriesOverWiFi = 1;
+        int cellularScanTimerSec = 10;
+        int scanType = SCAN_TYPE_NO_PREFERENCE;
+        boolean requiresImsRegistration = false;
+        boolean requiresVoLteEnabled = false;
+        boolean ltePreferredAfterNrFailed = false;
+        String[] cdmaPreferredNumbers = new String[] {};
+
+        return getPersistableBundle(imsRats, csRats, imsRoamRats, csRoamRats,
+                domainPreference, roamDomainPreference, imsWhenVoiceOnCs, maxRetriesOverWiFi,
+                cellularScanTimerSec, scanType, requiresImsRegistration, requiresVoLteEnabled,
+                ltePreferredAfterNrFailed, cdmaPreferredNumbers);
+    }
+
+    private static PersistableBundle getPersistableBundle(
+            @Nullable int[] imsRats, @Nullable int[] csRats,
+            @Nullable int[] imsRoamRats, @Nullable int[] csRoamRats,
+            @Nullable int[] domainPreference, @Nullable int[] roamDomainPreference,
+            boolean imsWhenVoiceOnCs, int maxRetriesOverWiFi,
+            int cellularScanTimerSec, int scanType, boolean requiresImsRegistration,
+            boolean requiresVoLteEnabled, boolean ltePreferredAfterNrFailed,
+            @Nullable String[] cdmaPreferredNumbers) {
+
+        PersistableBundle bundle  = new PersistableBundle();
+        if (imsRats != null) {
+            bundle.putIntArray(KEY_EMERGENCY_OVER_IMS_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY,
+                    imsRats);
+        }
+        if (imsRoamRats != null) {
+            bundle.putIntArray(
+                    KEY_EMERGENCY_OVER_IMS_ROAMING_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY,
+                    imsRoamRats);
+        }
+        if (csRats != null) {
+            bundle.putIntArray(KEY_EMERGENCY_OVER_CS_SUPPORTED_ACCESS_NETWORK_TYPES_INT_ARRAY,
+                    csRats);
+        }
+        if (csRoamRats != null) {
+            bundle.putIntArray(
+                    KEY_EMERGENCY_OVER_CS_ROAMING_SUPPORTED_ACCESS_NETWORK_TYPES_INT_ARRAY,
+                    csRoamRats);
+        }
+        if (domainPreference != null) {
+            bundle.putIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY, domainPreference);
+        }
+        if (roamDomainPreference != null) {
+            bundle.putIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_ROAMING_INT_ARRAY,
+                    roamDomainPreference);
+        }
+        bundle.putBoolean(KEY_PREFER_IMS_EMERGENCY_WHEN_VOICE_CALLS_ON_CS_BOOL, imsWhenVoiceOnCs);
+        bundle.putInt(KEY_MAXIMUM_NUMBER_OF_EMERGENCY_TRIES_OVER_VOWIFI_INT, maxRetriesOverWiFi);
+        bundle.putInt(KEY_EMERGENCY_SCAN_TIMER_SEC_INT, cellularScanTimerSec);
+        bundle.putInt(KEY_EMERGENCY_NETWORK_SCAN_TYPE_INT, scanType);
+        bundle.putBoolean(KEY_EMERGENCY_REQUIRES_IMS_REGISTRATION_BOOL, requiresImsRegistration);
+        bundle.putBoolean(KEY_EMERGENCY_REQUIRES_VOLTE_ENABLED_BOOL, requiresVoLteEnabled);
+        bundle.putInt(KEY_EMERGENCY_CALL_SETUP_TIMER_ON_CURRENT_NETWORK_SEC_INT, 0);
+        bundle.putBoolean(KEY_EMERGENCY_LTE_PREFERRED_AFTER_NR_FAILED_BOOL,
+                ltePreferredAfterNrFailed);
+        bundle.putStringArray(KEY_EMERGENCY_CDMA_PREFERRED_NUMBERS_STRING_ARRAY,
+                cdmaPreferredNumbers);
+
+        return bundle;
+    }
+
+    public static SelectionAttributes getSelectionAttributes(int slotId, int subId,
+            EmergencyRegResult regResult) {
+        SelectionAttributes.Builder builder =
+                new SelectionAttributes.Builder(slotId, subId, SELECTOR_TYPE_CALLING)
+                .setEmergency(true)
+                .setEmergencyRegResult(regResult);
+        return builder.build();
+    }
+
+    private static void replaceInstance(final Class c,
+            final String instanceName, final Object obj, final Object newValue) throws Exception {
+        Field field = c.getDeclaredField(instanceName);
+        field.setAccessible(true);
+        field.set(obj, newValue);
+    }
+
+    private void processAllMessages() {
+        while (!mLooper.getLooper().getQueue().isIdle()) {
+            mLooper.processAllMessages();
+        }
+    }
+
+    private static void logd(String str) {
+        Log.d(TAG, str);
+    }
+}
diff --git a/tests/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelectorTest.java
new file mode 100644
index 0000000..8b63530
--- /dev/null
+++ b/tests/src/com/android/services/telephony/domainselection/EmergencySmsDomainSelectorTest.java
@@ -0,0 +1,799 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony.domainselection;
+
+import static android.telephony.DomainSelectionService.SELECTOR_TYPE_SMS;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.PersistableBundle;
+import android.telephony.AccessNetworkConstants;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
+import android.telephony.AccessNetworkConstants.RadioAccessNetworkType;
+import android.telephony.BarringInfo;
+import android.telephony.CarrierConfigManager;
+import android.telephony.DataSpecificRegistrationInfo;
+import android.telephony.DomainSelectionService.SelectionAttributes;
+import android.telephony.NetworkRegistrationInfo;
+import android.telephony.ServiceState;
+import android.telephony.TelephonyManager;
+import android.telephony.TransportSelectorCallback;
+import android.telephony.VopsSupportInfo;
+import android.telephony.WwanSelectorCallback;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.TestableLooper;
+import android.util.SparseArray;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.TestContext;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.function.Consumer;
+
+/**
+ * Unit tests for EmergencySmsDomainSelector.
+ */
+@RunWith(AndroidJUnit4.class)
+public class EmergencySmsDomainSelectorTest {
+    private static final int SLOT_0 = 0;
+    private static final int SUB_1 = 1;
+
+    @Mock private ServiceState mServiceState;
+    @Mock private TransportSelectorCallback mTransportSelectorCallback;
+    @Mock private WwanSelectorCallback mWwanSelectorCallback;
+    @Mock private VopsSupportInfo mVopsSupportInfo;
+    @Mock private ImsStateTracker mImsStateTracker;
+    @Mock private DomainSelectorBase.DestroyListener mDomainSelectorDestroyListener;
+
+    private final SelectionAttributes mSelectionAttributes =
+            new SelectionAttributes.Builder(SLOT_0, SUB_1, SELECTOR_TYPE_SMS)
+            .setEmergency(true)
+            .build();
+    private Context mContext;
+    private Looper mLooper;
+    private TestableLooper mTestableLooper;
+    private CarrierConfigManager mCarrierConfigManager;
+    private NetworkRegistrationInfo mNetworkRegistrationInfo;
+    private boolean mCarrierConfigManagerNullTest = false;
+    private BarringInfo mBarringInfo = new BarringInfo();
+    private ImsStateTracker.ImsStateListener mImsStateListener;
+    private ImsStateTracker.BarringInfoListener mBarringInfoListener;
+    private ImsStateTracker.ServiceStateListener mServiceStateListener;
+    private EmergencySmsDomainSelector mDomainSelector;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mContext = new TestContext() {
+            @Override
+            public Object getSystemService(String name) {
+                if (name.equals(Context.CARRIER_CONFIG_SERVICE)) {
+                    if (mCarrierConfigManagerNullTest) {
+                        return null;
+                    }
+                }
+
+                return super.getSystemService(name);
+            }
+        };
+
+        HandlerThread handlerThread = new HandlerThread(
+                EmergencySmsDomainSelectorTest.class.getSimpleName());
+        handlerThread.start();
+        mLooper = handlerThread.getLooper();
+        mTestableLooper = new TestableLooper(mLooper);
+        mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
+
+        mDomainSelector = new EmergencySmsDomainSelector(mContext, SLOT_0, SUB_1,
+                mLooper, mImsStateTracker, mDomainSelectorDestroyListener);
+
+        ArgumentCaptor<ImsStateTracker.ServiceStateListener> serviceStateListenerCaptor =
+                ArgumentCaptor.forClass(ImsStateTracker.ServiceStateListener.class);
+        verify(mImsStateTracker).addServiceStateListener(serviceStateListenerCaptor.capture());
+        mServiceStateListener = serviceStateListenerCaptor.getValue();
+        assertNotNull(mServiceStateListener);
+
+        ArgumentCaptor<ImsStateTracker.BarringInfoListener> barringInfoListenerCaptor =
+                ArgumentCaptor.forClass(ImsStateTracker.BarringInfoListener.class);
+        verify(mImsStateTracker).addBarringInfoListener(barringInfoListenerCaptor.capture());
+        mBarringInfoListener = barringInfoListenerCaptor.getValue();
+        assertNotNull(mBarringInfoListener);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        if (mTestableLooper != null) {
+            mTestableLooper.destroy();
+            mTestableLooper = null;
+        }
+
+        if (mDomainSelector != null) {
+            mDomainSelector.destroy();
+            verify(mImsStateTracker).removeImsStateListener(eq(mDomainSelector));
+            verify(mImsStateTracker).removeBarringInfoListener(eq(mDomainSelector));
+            verify(mImsStateTracker).removeServiceStateListener(eq(mDomainSelector));
+        }
+
+        if (mLooper != null) {
+            mLooper.quit();
+            mLooper = null;
+        }
+
+        mDomainSelector = null;
+        mNetworkRegistrationInfo = null;
+        mVopsSupportInfo = null;
+        mDomainSelectorDestroyListener = null;
+        mWwanSelectorCallback = null;
+        mTransportSelectorCallback = null;
+        mServiceState = null;
+        mCarrierConfigManager = null;
+        mCarrierConfigManagerNullTest = false;
+    }
+
+    @Test
+    @SmallTest
+    public void testFinishSelection() {
+        setUpImsStateTracker(AccessNetworkType.EUTRAN);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        mServiceStateListener.onServiceStateUpdated(mServiceState);
+        mBarringInfoListener.onBarringInfoUpdated(mBarringInfo);
+
+        assertTrue(mDomainSelector.isDomainSelectionRequested());
+        assertTrue(mDomainSelector.isDomainSelectionReady());
+
+        mDomainSelector.finishSelection();
+
+        assertFalse(mDomainSelector.isDomainSelectionReady());
+        assertFalse(mDomainSelector.isDomainSelectionRequested());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsDomainSelectionReady() {
+        setUpImsStateTracker(AccessNetworkType.EUTRAN);
+
+        assertFalse(mDomainSelector.isDomainSelectionReady());
+
+        mServiceStateListener.onServiceStateUpdated(mServiceState);
+        mBarringInfoListener.onBarringInfoUpdated(mBarringInfo);
+
+        assertTrue(mDomainSelector.isDomainSelectionReady());
+        assertFalse(mDomainSelector.isDomainSelectionRequested());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsDomainSelectionReadyAndSelectDomain() {
+        setUpImsStateTracker(AccessNetworkType.EUTRAN);
+        setUpWwanSelectorCallback();
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        mServiceStateListener.onServiceStateUpdated(mServiceState);
+        mBarringInfoListener.onBarringInfoUpdated(mBarringInfo);
+
+        assertTrue(mDomainSelector.isDomainSelectionRequested());
+        assertTrue(mDomainSelector.isDomainSelectionReady());
+
+        processAllMessages();
+
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS));
+        assertFalse(mDomainSelector.isDomainSelectionRequested());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenImsRegistered() {
+        assertFalse(mDomainSelector.isSmsOverImsAvailable());
+
+        setUpImsStateTracker(AccessNetworkType.EUTRAN);
+
+        assertTrue(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenImsRegisteredAndConfigEnabledAndLteAvailable() {
+        setUpImsStateTracker(AccessNetworkType.EUTRAN);
+        setUpCarrierConfig(true);
+        setUpLteInService(false, false, true, false, false);
+
+        assertTrue(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenImsRegisteredAndConfigEnabledAndLteNotAvailable() {
+        setUpImsStateTracker(AccessNetworkType.EUTRAN);
+        setUpCarrierConfig(true);
+        setUpLteInService(false, false, false, false, false);
+
+        assertFalse(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenCarrierConfigManagerIsNull() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        mCarrierConfigManagerNullTest = true;
+
+        assertFalse(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenCarrierConfigIsNull() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(null);
+
+        assertFalse(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenCarrierConfigNotEnabled() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpCarrierConfig(false);
+
+        assertFalse(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenMmTelFeatureUnavailable() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN, false, false);
+        setUpCarrierConfig(true);
+
+        assertFalse(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenServiceStateIsNull() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpCarrierConfig(true);
+
+        assertFalse(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenNoLte() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpCarrierConfig(true);
+        mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
+                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_UMTS)
+                .build();
+        when(mServiceState.getNetworkRegistrationInfo(
+                anyInt(), eq(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)))
+                .thenReturn(mNetworkRegistrationInfo);
+
+        mServiceStateListener.onServiceStateUpdated(mServiceState);
+
+        assertFalse(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenLteNotRegisteredOrEmergencyNotEnabled() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpCarrierConfig(true);
+        mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
+                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
+                .build();
+        when(mServiceState.getNetworkRegistrationInfo(
+                anyInt(), eq(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)))
+                .thenReturn(mNetworkRegistrationInfo);
+
+        mServiceStateListener.onServiceStateUpdated(mServiceState);
+
+        assertFalse(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenLteInServiceAndNoDataSpecificRegistrationInfo() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpCarrierConfig(true);
+        setUpLteInService(true, true, true, true, false);
+
+        assertFalse(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenLteInServiceAndNoVopsSupportInfo() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpCarrierConfig(true);
+        setUpLteInService(false, true, true, true, false);
+
+        assertFalse(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenLteInServiceAndEmcBsNotSupported() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpCarrierConfig(true);
+        setUpLteInService(false, false, false, true, false);
+
+        assertFalse(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenLteInServiceAndEmcBsSupportedAndNoBarringInfo() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpCarrierConfig(true);
+        setUpLteInService(false, false, true, true, false);
+
+        assertTrue(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenLteInServiceAndEmcBsSupportedAndBarred() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpCarrierConfig(true);
+        setUpLteInService(false, false, true, false, true);
+
+        assertFalse(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenLteInServiceAndEmcBsSupportedAndNotBarred() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpCarrierConfig(true);
+        setUpLteInService(false, false, true, false, false);
+
+        assertTrue(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsSmsOverImsAvailableWhenLteInLimitedService() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpCarrierConfig(true);
+        setUpLimitedLteService(false, false, true, false, false);
+
+        assertTrue(mDomainSelector.isSmsOverImsAvailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhilePreviousRequestInProgress() {
+        setUpImsStateTracker(AccessNetworkType.EUTRAN);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpLteInService(false, false, true, false, false);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        mServiceStateListener.onServiceStateUpdated(mServiceState);
+        mBarringInfoListener.onBarringInfoUpdated(mBarringInfo);
+
+        assertTrue(mDomainSelector.isDomainSelectionRequested());
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+
+        processAllMessages();
+
+        // onDomainSelected will be invoked only once
+        // even though the domain selection was requested twice.
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS));
+        assertFalse(mDomainSelector.isDomainSelectionRequested());
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenImsNotRegisteredAndConfigDisabled() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(false);
+        setUpLteInService(false, false, true, false, false);
+        setUpImsStateListener(true, false, false);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // Expected: CS network
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenImsNotRegisteredAndUmtsNetwork() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpNonLteService(TelephonyManager.NETWORK_TYPE_UMTS);
+        setUpImsStateListener(true, false, false);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // Expected: CS network
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenImsNotRegisteredAndUnknownNetwork() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpNonLteService(TelephonyManager.NETWORK_TYPE_UNKNOWN);
+        setUpImsStateListener(true, false, false);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // Expected: CS network
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenImsNotRegisteredAndLteInService() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpLteInService(false, false, true, false, false);
+        setUpImsStateListener(true, false, false);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // Expected: PS network
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS));
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenImsNotRegisteredAndLteEmcBsNotSupported() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpLteInService(false, false, false, false, false);
+        setUpImsStateListener(true, false, false);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // Expected: CS network
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenImsNotRegisteredAndLteEmergencyBarred() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpLteInService(false, false, true, false, true);
+        setUpImsStateListener(true, false, false);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // Expected: CS network
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenImsNotRegisteredAndLimitedLteService() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpLimitedLteService(false, false, true, false, false);
+        setUpImsStateListener(true, false, false);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // Expected: PS network
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS));
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenImsNotRegisteredAndLimitedLteEmcBsNotSupported() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpLimitedLteService(false, false, false, false, false);
+        setUpImsStateListener(true, false, false);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // Expected: CS network
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenImsNotRegisteredAndLimitedLteEmergencyBarred() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpLimitedLteService(false, false, true, false, true);
+        setUpImsStateListener(true, false, false);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // Expected: CS network
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenImsRegisteredOnLte() {
+        setUpImsStateTracker(AccessNetworkType.EUTRAN);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpLteInService(false, false, true, false, false);
+        setUpImsStateListener(true, true, true);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // Expected: PS network
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS));
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenImsRegisteredOnLteAndEmcBsNotSupported() {
+        setUpImsStateTracker(AccessNetworkType.EUTRAN);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpLteInService(false, false, false, false, false);
+        setUpImsStateListener(true, true, true);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // Expected: CS network
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenImsRegisteredOnLteAndEmergencyBarred() {
+        setUpImsStateTracker(AccessNetworkType.EUTRAN);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpLteInService(false, false, true, false, true);
+        setUpImsStateListener(true, true, true);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // Expected: CS network
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenImsRegisteredOnIwlanAndConfigDisabled() {
+        setUpImsStateTracker(AccessNetworkType.IWLAN);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(false);
+        setUpLteInService(false, false, true, false, false);
+        setUpImsStateListener(true, true, true);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // Expected: WLAN
+        verify(mTransportSelectorCallback).onWlanSelected();
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenImsRegisteredOnIwlanAndLteNotAvailable() {
+        setUpImsStateTracker(AccessNetworkType.IWLAN);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpLteInService(false, false, false, false, false);
+        setUpImsStateListener(true, true, true);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // Expected: CS network - even though IMS is successfully registered over Wi-Fi,
+        // if the emergency SMS messages over IMS is enabled in the carrier configuration and
+        // the PS network does not allow the emergency service, this MO SMS should be routed to
+        // CS domain.
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenImsRegisteredOnIwlanAndLteAvailable() {
+        setUpImsStateTracker(AccessNetworkType.IWLAN);
+        setUpWwanSelectorCallback();
+        setUpCarrierConfig(true);
+        setUpLteInService(false, false, true, false, false);
+        setUpImsStateListener(true, true, true);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+        processAllMessages();
+
+        // Expected: PS network
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS));
+    }
+
+    private void setUpCarrierConfig(boolean supported) {
+        PersistableBundle b = new PersistableBundle();
+        b.putBoolean(CarrierConfigManager.KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL, supported);
+        when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(b);
+    }
+
+    private void setUpNonLteService(int networkType) {
+        mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
+                .setAccessNetworkTechnology(networkType)
+                .setRegistrationState(networkType == TelephonyManager.NETWORK_TYPE_UNKNOWN
+                        ? NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN
+                        : NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
+                .build();
+        when(mServiceState.getNetworkRegistrationInfo(
+                anyInt(), eq(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)))
+                .thenReturn(mNetworkRegistrationInfo);
+
+        mServiceStateListener.onServiceStateUpdated(mServiceState);
+        mBarringInfoListener.onBarringInfoUpdated(null);
+    }
+
+    private void setUpLteInService(boolean noDataSpecificRegistrationInfo,
+            boolean noVopsSupportInfo, boolean emcBsSupported,
+            boolean noBarringInfo, boolean barred) {
+        DataSpecificRegistrationInfo dsri = noDataSpecificRegistrationInfo
+                ? null : new DataSpecificRegistrationInfo(
+                        8, false, false, false, noVopsSupportInfo ? null : mVopsSupportInfo);
+
+        mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
+                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
+                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
+                .setDataSpecificInfo(dsri)
+                .build();
+        when(mServiceState.getNetworkRegistrationInfo(
+                anyInt(), eq(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)))
+                .thenReturn(mNetworkRegistrationInfo);
+        when(mVopsSupportInfo.isEmergencyServiceSupported()).thenReturn(emcBsSupported);
+
+        BarringInfo barringInfo = null;
+
+        if (!noBarringInfo) {
+            SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos = new SparseArray<>();
+            barringServiceInfos.put(BarringInfo.BARRING_SERVICE_TYPE_EMERGENCY,
+                    new BarringInfo.BarringServiceInfo(
+                            barred ? BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL :
+                                    BarringInfo.BarringServiceInfo.BARRING_TYPE_NONE, false, 0, 0));
+            barringInfo = new BarringInfo(null, barringServiceInfos);
+        }
+
+        mServiceStateListener.onServiceStateUpdated(mServiceState);
+        mBarringInfoListener.onBarringInfoUpdated(barringInfo);
+    }
+
+    private void setUpLimitedLteService(boolean noDataSpecificRegistrationInfo,
+            boolean noVopsSupportInfo, boolean emcBsSupported,
+            boolean noBarringInfo, boolean barred) {
+        DataSpecificRegistrationInfo dsri = noDataSpecificRegistrationInfo
+                ? null : new DataSpecificRegistrationInfo(
+                        8, false, false, false, noVopsSupportInfo ? null : mVopsSupportInfo);
+
+        mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
+                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
+                .setEmergencyOnly(true)
+                .setDataSpecificInfo(dsri)
+                .build();
+        when(mServiceState.getNetworkRegistrationInfo(
+                anyInt(), eq(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)))
+                .thenReturn(mNetworkRegistrationInfo);
+        when(mVopsSupportInfo.isEmergencyServiceSupported()).thenReturn(emcBsSupported);
+
+        BarringInfo barringInfo = null;
+
+        if (!noBarringInfo) {
+            SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos = new SparseArray<>();
+            barringServiceInfos.put(BarringInfo.BARRING_SERVICE_TYPE_EMERGENCY,
+                    new BarringInfo.BarringServiceInfo(
+                            barred ? BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL :
+                                    BarringInfo.BarringServiceInfo.BARRING_TYPE_NONE, false, 0, 0));
+            barringInfo = new BarringInfo(null, barringServiceInfos);
+        }
+
+        mServiceStateListener.onServiceStateUpdated(mServiceState);
+        mBarringInfoListener.onBarringInfoUpdated(barringInfo);
+    }
+
+    private void setUpImsStateTracker(@RadioAccessNetworkType int accessNetworkType) {
+        setUpImsStateTracker(accessNetworkType, true, true);
+    }
+
+    private void setUpImsStateTracker(@RadioAccessNetworkType int accessNetworkType,
+            boolean mmTelFeatureAvailable, boolean smsCapable) {
+        when(mImsStateTracker.isMmTelFeatureAvailable()).thenReturn(mmTelFeatureAvailable);
+        when(mImsStateTracker.isImsRegistered())
+                .thenReturn(accessNetworkType != AccessNetworkType.UNKNOWN);
+        when(mImsStateTracker.isImsRegisteredOverWlan())
+                .thenReturn(accessNetworkType == AccessNetworkType.IWLAN);
+        when(mImsStateTracker.getImsAccessNetworkType()).thenReturn(accessNetworkType);
+        when(mImsStateTracker.isImsSmsCapable()).thenReturn(smsCapable);
+    }
+
+    private void setUpWwanSelectorCallback() {
+        doAnswer((invocation) -> {
+            Object[] args = invocation.getArguments();
+            final Consumer<WwanSelectorCallback> callback =
+                    (Consumer<WwanSelectorCallback>) args[0];
+            callback.accept(mWwanSelectorCallback);
+            return null;
+        }).when(mTransportSelectorCallback).onWwanSelected(any(Consumer.class));
+    }
+
+    private void setUpImsStateListener(boolean notifyMmTelFeatureAvailable,
+            boolean notifyImsRegState, boolean notifyMmTelCapability) {
+        doAnswer((invocation) -> {
+            Object[] args = invocation.getArguments();
+            final ImsStateTracker.ImsStateListener listener =
+                    (ImsStateTracker.ImsStateListener) args[0];
+            mDomainSelector.post(() -> {
+                if (notifyMmTelFeatureAvailable) {
+                    listener.onImsMmTelFeatureAvailableChanged();
+                }
+                if (notifyImsRegState) {
+                    listener.onImsRegistrationStateChanged();
+                }
+                if (notifyMmTelCapability) {
+                    listener.onImsMmTelCapabilitiesChanged();
+                }
+            });
+            return null;
+        }).when(mImsStateTracker).addImsStateListener(any(ImsStateTracker.ImsStateListener.class));
+    }
+
+    private void processAllMessages() {
+        while (!mTestableLooper.getLooper().getQueue().isIdle()) {
+            mTestableLooper.processAllMessages();
+        }
+    }
+}
diff --git a/tests/src/com/android/services/telephony/domainselection/ImsStateTrackerTest.java b/tests/src/com/android/services/telephony/domainselection/ImsStateTrackerTest.java
new file mode 100644
index 0000000..b00926f
--- /dev/null
+++ b/tests/src/com/android/services/telephony/domainselection/ImsStateTrackerTest.java
@@ -0,0 +1,744 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony.domainselection;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
+import android.telephony.BarringInfo;
+import android.telephony.ServiceState;
+import android.telephony.SubscriptionManager;
+import android.telephony.ims.ImsException;
+import android.telephony.ims.ImsManager;
+import android.telephony.ims.ImsMmTelManager;
+import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.ImsRegistrationAttributes;
+import android.telephony.ims.ImsStateCallback;
+import android.telephony.ims.RegistrationManager;
+import android.telephony.ims.feature.MmTelFeature.MmTelCapabilities;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.TestContext;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Unit tests for ImsStateTracker.
+ */
+@RunWith(AndroidJUnit4.class)
+public class ImsStateTrackerTest {
+    private static final int SLOT_0 = 0;
+    private static final int SUB_1 = 1;
+    private static final int SUB_2 = 2;
+    private static final long TIMEOUT_MS = 100;
+
+    @Mock private ImsMmTelManager mMmTelManager;
+    @Mock private ImsMmTelManager mMmTelManager2;
+    @Mock private ImsStateTracker.BarringInfoListener mBarringInfoListener;
+    @Mock private ImsStateTracker.ServiceStateListener mServiceStateListener;
+    @Mock private ImsStateTracker.ImsStateListener mImsStateListener;
+    @Mock private ServiceState mServiceState;
+
+    private Context mContext;
+    private Looper mLooper;
+    private BarringInfo mBarringInfo = new BarringInfo();
+    private ImsStateTracker mImsStateTracker;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mContext = new TestContext() {
+            @Override
+            public String getSystemServiceName(Class<?> serviceClass) {
+                if (serviceClass == ImsManager.class) {
+                    return Context.TELEPHONY_IMS_SERVICE;
+                }
+                return super.getSystemServiceName(serviceClass);
+            }
+        };
+
+        HandlerThread handlerThread = new HandlerThread(
+                ImsStateTrackerTest.class.getSimpleName());
+        handlerThread.start();
+        mLooper = handlerThread.getLooper();
+        mImsStateTracker = new ImsStateTracker(mContext, SLOT_0, mLooper);
+
+        ImsManager imsManager = mContext.getSystemService(ImsManager.class);
+        when(imsManager.getImsMmTelManager(eq(SUB_1))).thenReturn(mMmTelManager);
+        when(imsManager.getImsMmTelManager(eq(SUB_2))).thenReturn(mMmTelManager2);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mImsStateTracker.destroy();
+        mImsStateTracker = null;
+        mMmTelManager = null;
+
+        if (mLooper != null) {
+            mLooper.quit();
+            mLooper = null;
+        }
+    }
+
+    @Test
+    @SmallTest
+    public void testInit() {
+        assertEquals(SLOT_0, mImsStateTracker.getSlotId());
+        assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID, mImsStateTracker.getSubId());
+    }
+
+    @Test
+    @SmallTest
+    public void testStartWithInvalidSubId() {
+        mImsStateTracker.start(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+
+        assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID, mImsStateTracker.getSubId());
+        assertTrue(isImsStateUnavailable());
+    }
+
+    @Test
+    @SmallTest
+    public void testStart() throws ImsException {
+        mImsStateTracker.start(SUB_1);
+
+        assertEquals(SUB_1, mImsStateTracker.getSubId());
+        assertTrue(isImsStateInit());
+        verify(mMmTelManager).registerImsStateCallback(
+                any(Executor.class), any(ImsStateCallback.class));
+    }
+
+    @Test
+    @SmallTest
+    public void testStartWithDifferentSubId() throws ImsException {
+        mImsStateTracker.start(SUB_1);
+
+        assertEquals(SUB_1, mImsStateTracker.getSubId());
+        assertTrue(isImsStateInit());
+
+        mImsStateTracker.start(SUB_2);
+
+        assertEquals(SUB_2, mImsStateTracker.getSubId());
+        assertTrue(isImsStateInit());
+        verify(mMmTelManager).registerImsStateCallback(
+                any(Executor.class), any(ImsStateCallback.class));
+        verify(mMmTelManager).unregisterImsStateCallback(
+                any(ImsStateCallback.class));
+        verify(mMmTelManager2).registerImsStateCallback(
+                any(Executor.class), any(ImsStateCallback.class));
+    }
+
+    @Test
+    @SmallTest
+    public void testStartWithSameSubId() throws ImsException {
+        mImsStateTracker.start(SUB_1);
+
+        assertEquals(SUB_1, mImsStateTracker.getSubId());
+        assertTrue(isImsStateInit());
+
+        mImsStateTracker.start(SUB_1);
+
+        assertEquals(SUB_1, mImsStateTracker.getSubId());
+        assertTrue(isImsStateInit());
+        verify(mMmTelManager).registerImsStateCallback(
+                any(Executor.class), any(ImsStateCallback.class));
+        verify(mMmTelManager, never()).unregisterImsStateCallback(
+                any(ImsStateCallback.class));
+    }
+
+    @Test
+    @SmallTest
+    public void testStartWhenRegisteringCallbacksThrowException() throws ImsException {
+        doAnswer((invocation) -> {
+            throw new ImsException("Intended exception for ImsStateCallback.");
+        }).when(mMmTelManager).registerImsStateCallback(
+                any(Executor.class), any(ImsStateCallback.class));
+
+        mImsStateTracker.start(SUB_1);
+
+        assertEquals(SUB_1, mImsStateTracker.getSubId());
+
+        mImsStateTracker.start(SUB_2);
+
+        assertEquals(SUB_2, mImsStateTracker.getSubId());
+
+        verify(mMmTelManager, never()).unregisterImsStateCallback(
+                any(ImsStateCallback.class));
+    }
+
+    @Test
+    @SmallTest
+    public void testUpdateServiceStateBeforeAddingListener() {
+        mImsStateTracker.updateServiceState(mServiceState);
+        mImsStateTracker.addServiceStateListener(mServiceStateListener);
+        waitForHandlerAction(mImsStateTracker.getHandler(), TIMEOUT_MS);
+
+        verify(mServiceStateListener).onServiceStateUpdated(eq(mServiceState));
+
+        mImsStateTracker.removeServiceStateListener(mServiceStateListener);
+        ServiceState ss = Mockito.mock(ServiceState.class);
+        mImsStateTracker.updateServiceState(ss);
+        waitForHandlerAction(mImsStateTracker.getHandler(), TIMEOUT_MS);
+
+        verifyNoMoreInteractions(mServiceStateListener);
+    }
+
+    @Test
+    @SmallTest
+    public void testUpdateServiceStateAfterAddingListener() {
+        mImsStateTracker.addServiceStateListener(mServiceStateListener);
+        mImsStateTracker.updateServiceState(mServiceState);
+        waitForHandlerAction(mImsStateTracker.getHandler(), TIMEOUT_MS);
+
+        verify(mServiceStateListener).onServiceStateUpdated(eq(mServiceState));
+
+        mImsStateTracker.removeServiceStateListener(mServiceStateListener);
+        ServiceState ss = Mockito.mock(ServiceState.class);
+        mImsStateTracker.updateServiceState(ss);
+        waitForHandlerAction(mImsStateTracker.getHandler(), TIMEOUT_MS);
+
+        verifyNoMoreInteractions(mServiceStateListener);
+    }
+
+    @Test
+    @SmallTest
+    public void testAddAndRemoveServiceStateListener() {
+        mImsStateTracker.updateServiceState(mServiceState);
+        mImsStateTracker.addServiceStateListener(mServiceStateListener);
+        mImsStateTracker.removeServiceStateListener(mServiceStateListener);
+        waitForHandlerAction(mImsStateTracker.getHandler(), TIMEOUT_MS);
+
+        verify(mServiceStateListener, never()).onServiceStateUpdated(eq(mServiceState));
+    }
+
+    @Test
+    @SmallTest
+    public void testUpdateBarringInfoBeforeAddingListener() {
+        mImsStateTracker.updateBarringInfo(mBarringInfo);
+        mImsStateTracker.addBarringInfoListener(mBarringInfoListener);
+        waitForHandlerAction(mImsStateTracker.getHandler(), TIMEOUT_MS);
+
+        verify(mBarringInfoListener).onBarringInfoUpdated(eq(mBarringInfo));
+
+        mImsStateTracker.removeBarringInfoListener(mBarringInfoListener);
+        BarringInfo bi = new BarringInfo();
+        mImsStateTracker.updateBarringInfo(bi);
+        waitForHandlerAction(mImsStateTracker.getHandler(), TIMEOUT_MS);
+
+        verifyNoMoreInteractions(mBarringInfoListener);
+    }
+
+    @Test
+    @SmallTest
+    public void testUpdateBarringInfoAfterAddingListener() {
+        mImsStateTracker.addBarringInfoListener(mBarringInfoListener);
+        mImsStateTracker.updateBarringInfo(mBarringInfo);
+        waitForHandlerAction(mImsStateTracker.getHandler(), TIMEOUT_MS);
+
+        verify(mBarringInfoListener).onBarringInfoUpdated(eq(mBarringInfo));
+
+        mImsStateTracker.removeBarringInfoListener(mBarringInfoListener);
+        BarringInfo bi = new BarringInfo();
+        mImsStateTracker.updateBarringInfo(bi);
+        waitForHandlerAction(mImsStateTracker.getHandler(), TIMEOUT_MS);
+
+        verifyNoMoreInteractions(mBarringInfoListener);
+    }
+
+    @Test
+    @SmallTest
+    public void testAddAndRemoveBarringInfoListener() {
+        mImsStateTracker.updateBarringInfo(mBarringInfo);
+        mImsStateTracker.addBarringInfoListener(mBarringInfoListener);
+        mImsStateTracker.removeBarringInfoListener(mBarringInfoListener);
+        waitForHandlerAction(mImsStateTracker.getHandler(), TIMEOUT_MS);
+
+        verify(mBarringInfoListener, never()).onBarringInfoUpdated(eq(mBarringInfo));
+    }
+
+    @Test
+    @SmallTest
+    public void testNotifyImsStateCallbackOnAvailable() throws ImsException {
+        ImsStateCallback callback = setUpImsStateCallback();
+        callback.onAvailable();
+
+        assertTrue(mImsStateTracker.isMmTelFeatureAvailable());
+        assertFalse(mImsStateTracker.isImsStateReady());
+        verify(mMmTelManager).registerImsRegistrationCallback(
+                any(Executor.class), any(RegistrationManager.RegistrationCallback.class));
+        verify(mMmTelManager).registerMmTelCapabilityCallback(
+                any(Executor.class), any(ImsMmTelManager.CapabilityCallback.class));
+        verify(mImsStateListener).onImsMmTelFeatureAvailableChanged();
+    }
+
+    @Test
+    @SmallTest
+    public void testNotifyImsStateCallbackOnUnavailableWithReasonUnknownPermanentError()
+            throws ImsException {
+        ImsStateCallback callback = setUpImsStateCallback();
+        callback.onUnavailable(ImsStateCallback.REASON_UNKNOWN_PERMANENT_ERROR);
+
+        assertTrue(isImsStateUnavailable());
+        assertTrue(mImsStateTracker.isImsStateReady());
+        verify(mImsStateListener).onImsMmTelFeatureAvailableChanged();
+    }
+
+    @Test
+    @SmallTest
+    public void testNotifyImsStateCallbackOnUnavailableWithReasonNoImsServiceConfigured()
+            throws ImsException {
+        ImsStateCallback callback = setUpImsStateCallback();
+        callback.onUnavailable(ImsStateCallback.REASON_NO_IMS_SERVICE_CONFIGURED);
+
+        assertTrue(isImsStateUnavailable());
+        assertTrue(mImsStateTracker.isImsStateReady());
+        verify(mImsStateListener).onImsMmTelFeatureAvailableChanged();
+    }
+
+    @Test
+    public void testNotifyImsStateCallbackOnUnavailableWithReasonUnknownTemporaryError()
+            throws ImsException {
+        ImsStateCallback callback = setUpImsStateCallback();
+        callback.onUnavailable(ImsStateCallback.REASON_UNKNOWN_TEMPORARY_ERROR);
+
+        assertFalse(mImsStateTracker.isMmTelFeatureAvailable());
+        assertFalse(isImsStateUnavailable());
+        assertFalse(mImsStateTracker.isImsStateReady());
+
+        waitForHandlerActionDelayed(mImsStateTracker.getHandler(),
+                ImsStateTracker.MMTEL_FEATURE_AVAILABLE_WAIT_TIME_MILLIS,
+                ImsStateTracker.MMTEL_FEATURE_AVAILABLE_WAIT_TIME_MILLIS + TIMEOUT_MS);
+
+        assertFalse(mImsStateTracker.isMmTelFeatureAvailable());
+        assertTrue(isImsStateUnavailable());
+        assertTrue(mImsStateTracker.isImsStateReady());
+        verify(mImsStateListener).onImsMmTelFeatureAvailableChanged();
+    }
+
+    @Test
+    public void testNotifyImsStateCallbackOnUnavailableWithReasonImsServiceNotReady()
+            throws ImsException {
+        ImsStateCallback callback = setUpImsStateCallback();
+        callback.onUnavailable(ImsStateCallback.REASON_IMS_SERVICE_NOT_READY);
+
+        assertFalse(mImsStateTracker.isMmTelFeatureAvailable());
+        assertFalse(isImsStateUnavailable());
+        assertFalse(mImsStateTracker.isImsStateReady());
+
+        waitForHandlerActionDelayed(mImsStateTracker.getHandler(),
+                ImsStateTracker.MMTEL_FEATURE_AVAILABLE_WAIT_TIME_MILLIS,
+                ImsStateTracker.MMTEL_FEATURE_AVAILABLE_WAIT_TIME_MILLIS + TIMEOUT_MS);
+
+        assertFalse(mImsStateTracker.isMmTelFeatureAvailable());
+        assertTrue(isImsStateUnavailable());
+        assertTrue(mImsStateTracker.isImsStateReady());
+        verify(mImsStateListener).onImsMmTelFeatureAvailableChanged();
+    }
+
+    @Test
+    public void testNotifyImsStateCallbackOnUnavailableWithReasonImsServiceDisconnected()
+            throws ImsException {
+        ImsStateCallback callback = setUpImsStateCallback();
+        callback.onUnavailable(ImsStateCallback.REASON_IMS_SERVICE_DISCONNECTED);
+
+        assertFalse(mImsStateTracker.isMmTelFeatureAvailable());
+        assertFalse(isImsStateUnavailable());
+        assertFalse(mImsStateTracker.isImsStateReady());
+
+        waitForHandlerActionDelayed(mImsStateTracker.getHandler(),
+                ImsStateTracker.MMTEL_FEATURE_AVAILABLE_WAIT_TIME_MILLIS,
+                ImsStateTracker.MMTEL_FEATURE_AVAILABLE_WAIT_TIME_MILLIS + TIMEOUT_MS);
+
+        assertFalse(mImsStateTracker.isMmTelFeatureAvailable());
+        assertTrue(isImsStateUnavailable());
+        assertTrue(mImsStateTracker.isImsStateReady());
+        verify(mMmTelManager, never()).unregisterImsRegistrationCallback(
+                any(RegistrationManager.RegistrationCallback.class));
+        verify(mMmTelManager, never()).unregisterMmTelCapabilityCallback(
+                any(ImsMmTelManager.CapabilityCallback.class));
+        verify(mImsStateListener).onImsMmTelFeatureAvailableChanged();
+    }
+
+    @Test
+    @SmallTest
+    public void testNotifyImsStateCallbackOnUnavailableWithReasonSubscriptionInactive()
+            throws ImsException {
+        ImsStateCallback callback = setUpImsStateCallback();
+        callback.onUnavailable(ImsStateCallback.REASON_SUBSCRIPTION_INACTIVE);
+
+        assertFalse(mImsStateTracker.isMmTelFeatureAvailable());
+        assertTrue(isImsStateUnavailable());
+        assertTrue(mImsStateTracker.isImsStateReady());
+        verify(mMmTelManager, never()).unregisterImsRegistrationCallback(
+                any(RegistrationManager.RegistrationCallback.class));
+        verify(mMmTelManager, never()).unregisterMmTelCapabilityCallback(
+                any(ImsMmTelManager.CapabilityCallback.class));
+        verify(mImsStateListener).onImsMmTelFeatureAvailableChanged();
+    }
+
+    @Test
+    public void testNotifyImsStateCallbackOnAvailableUnavailableWithReasonImsServiceDisconnected()
+            throws ImsException {
+        ImsStateCallback callback = setUpImsStateCallback();
+        callback.onAvailable();
+        callback.onUnavailable(ImsStateCallback.REASON_IMS_SERVICE_DISCONNECTED);
+
+        assertFalse(mImsStateTracker.isMmTelFeatureAvailable());
+        assertFalse(isImsStateUnavailable());
+        assertFalse(mImsStateTracker.isImsStateReady());
+
+        waitForHandlerActionDelayed(mImsStateTracker.getHandler(),
+                ImsStateTracker.MMTEL_FEATURE_AVAILABLE_WAIT_TIME_MILLIS,
+                ImsStateTracker.MMTEL_FEATURE_AVAILABLE_WAIT_TIME_MILLIS + TIMEOUT_MS);
+
+        assertFalse(mImsStateTracker.isMmTelFeatureAvailable());
+        assertTrue(isImsStateUnavailable());
+        assertTrue(mImsStateTracker.isImsStateReady());
+        verify(mMmTelManager).registerImsRegistrationCallback(
+                any(Executor.class), any(RegistrationManager.RegistrationCallback.class));
+        verify(mMmTelManager).registerMmTelCapabilityCallback(
+                any(Executor.class), any(ImsMmTelManager.CapabilityCallback.class));
+        verify(mMmTelManager).unregisterImsRegistrationCallback(
+                any(RegistrationManager.RegistrationCallback.class));
+        verify(mMmTelManager).unregisterMmTelCapabilityCallback(
+                any(ImsMmTelManager.CapabilityCallback.class));
+        verify(mImsStateListener, times(2)).onImsMmTelFeatureAvailableChanged();
+    }
+
+    @Test
+    public void testNotifyImsStateCallbackOnUnavailableAvailableWithReasonImsServiceDisconnected()
+            throws ImsException {
+        ImsStateCallback callback = setUpImsStateCallback();
+        callback.onUnavailable(ImsStateCallback.REASON_IMS_SERVICE_DISCONNECTED);
+        callback.onAvailable();
+
+        assertTrue(mImsStateTracker.isMmTelFeatureAvailable());
+        assertFalse(isImsStateUnavailable());
+        assertFalse(mImsStateTracker.isImsStateReady());
+
+        waitForHandlerActionDelayed(mImsStateTracker.getHandler(),
+                ImsStateTracker.MMTEL_FEATURE_AVAILABLE_WAIT_TIME_MILLIS,
+                ImsStateTracker.MMTEL_FEATURE_AVAILABLE_WAIT_TIME_MILLIS + TIMEOUT_MS);
+
+        assertTrue(mImsStateTracker.isMmTelFeatureAvailable());
+        assertFalse(isImsStateUnavailable());
+        assertFalse(mImsStateTracker.isImsStateReady());
+        verify(mMmTelManager).registerImsRegistrationCallback(
+                any(Executor.class), any(RegistrationManager.RegistrationCallback.class));
+        verify(mMmTelManager).registerMmTelCapabilityCallback(
+                any(Executor.class), any(ImsMmTelManager.CapabilityCallback.class));
+        verify(mMmTelManager, never()).unregisterImsRegistrationCallback(
+                any(RegistrationManager.RegistrationCallback.class));
+        verify(mMmTelManager, never()).unregisterMmTelCapabilityCallback(
+                any(ImsMmTelManager.CapabilityCallback.class));
+        verify(mImsStateListener).onImsMmTelFeatureAvailableChanged();
+    }
+
+    @Test
+    @SmallTest
+    public void testNotifyImsStateCallbackOnAvailableUnavailableWithReasonSubscriptionInactive()
+            throws ImsException {
+        ImsStateCallback callback = setUpImsStateCallback();
+        callback.onAvailable();
+        callback.onUnavailable(ImsStateCallback.REASON_SUBSCRIPTION_INACTIVE);
+
+        assertFalse(mImsStateTracker.isMmTelFeatureAvailable());
+        assertTrue(isImsStateUnavailable());
+        assertTrue(mImsStateTracker.isImsStateReady());
+        verify(mMmTelManager).registerImsRegistrationCallback(
+                any(Executor.class), any(RegistrationManager.RegistrationCallback.class));
+        verify(mMmTelManager).registerMmTelCapabilityCallback(
+                any(Executor.class), any(ImsMmTelManager.CapabilityCallback.class));
+        verify(mMmTelManager).unregisterImsRegistrationCallback(
+                any(RegistrationManager.RegistrationCallback.class));
+        verify(mMmTelManager).unregisterMmTelCapabilityCallback(
+                any(ImsMmTelManager.CapabilityCallback.class));
+        verify(mImsStateListener, times(2)).onImsMmTelFeatureAvailableChanged();
+    }
+
+    @Test
+    @SmallTest
+    public void testNotifyImsRegistrationCallbackOnRegistered() throws ImsException {
+        RegistrationManager.RegistrationCallback callback = setUpImsRegistrationCallback();
+        callback.onRegistered(new ImsRegistrationAttributes.Builder(
+                ImsRegistrationImplBase.REGISTRATION_TECH_LTE).build());
+
+        // It's false because the MMTEL capabilities are not updated yet.
+        assertFalse(mImsStateTracker.isImsStateReady());
+        assertTrue(mImsStateTracker.isImsRegistered());
+        assertFalse(mImsStateTracker.isImsRegisteredOverWlan());
+        assertEquals(AccessNetworkType.EUTRAN, mImsStateTracker.getImsAccessNetworkType());
+
+        callback.onRegistered(new ImsRegistrationAttributes.Builder(
+                ImsRegistrationImplBase.REGISTRATION_TECH_NR).build());
+
+        assertFalse(mImsStateTracker.isImsStateReady());
+        assertTrue(mImsStateTracker.isImsRegistered());
+        assertFalse(mImsStateTracker.isImsRegisteredOverWlan());
+        assertEquals(AccessNetworkType.NGRAN, mImsStateTracker.getImsAccessNetworkType());
+
+        callback.onRegistered(new ImsRegistrationAttributes.Builder(
+                ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN).build());
+
+        assertFalse(mImsStateTracker.isImsStateReady());
+        assertTrue(mImsStateTracker.isImsRegistered());
+        assertTrue(mImsStateTracker.isImsRegisteredOverWlan());
+        assertEquals(AccessNetworkType.IWLAN, mImsStateTracker.getImsAccessNetworkType());
+
+        callback.onRegistered(new ImsRegistrationAttributes.Builder(
+                ImsRegistrationImplBase.REGISTRATION_TECH_NONE).build());
+
+        assertFalse(mImsStateTracker.isImsStateReady());
+        assertTrue(mImsStateTracker.isImsRegistered());
+        assertFalse(mImsStateTracker.isImsRegisteredOverWlan());
+        assertEquals(AccessNetworkType.UNKNOWN, mImsStateTracker.getImsAccessNetworkType());
+
+        verify(mImsStateListener, times(4)).onImsRegistrationStateChanged();
+    }
+
+    @Test
+    @SmallTest
+    public void testNotifyImsRegistrationCallbackOnUnregistered() throws ImsException {
+        RegistrationManager.RegistrationCallback callback = setUpImsRegistrationCallback();
+        callback.onRegistered(new ImsRegistrationAttributes.Builder(
+                ImsRegistrationImplBase.REGISTRATION_TECH_LTE).build());
+
+        // It's false because the MMTEL capabilities are not updated yet.
+        assertFalse(mImsStateTracker.isImsStateReady());
+        assertTrue(mImsStateTracker.isImsRegistered());
+        assertFalse(mImsStateTracker.isImsRegisteredOverWlan());
+        assertEquals(AccessNetworkType.EUTRAN, mImsStateTracker.getImsAccessNetworkType());
+
+        callback.onUnregistered(new ImsReasonInfo(ImsReasonInfo.CODE_REGISTRATION_ERROR, 0, null));
+
+        // When IMS is unregistered, the MMTEL capability is also reset.
+        assertTrue(mImsStateTracker.isImsStateReady());
+        assertFalse(mImsStateTracker.isImsRegistered());
+        assertFalse(mImsStateTracker.isImsRegisteredOverWlan());
+        assertEquals(AccessNetworkType.UNKNOWN, mImsStateTracker.getImsAccessNetworkType());
+
+        verify(mImsStateListener, times(2)).onImsRegistrationStateChanged();
+    }
+
+    @Test
+    @SmallTest
+    public void testNotifyMmTelCapabilityCallbackOnCapabilitiesStatusChanged() throws ImsException {
+        ImsMmTelManager.CapabilityCallback callback = setUpMmTelCapabilityCallback();
+
+        assertFalse(mImsStateTracker.isImsVoiceCapable());
+        assertFalse(mImsStateTracker.isImsVideoCapable());
+        assertFalse(mImsStateTracker.isImsSmsCapable());
+        assertFalse(mImsStateTracker.isImsUtCapable());
+
+        MmTelCapabilities capabilities = new MmTelCapabilities(
+                MmTelCapabilities.CAPABILITY_TYPE_VOICE
+                | MmTelCapabilities.CAPABILITY_TYPE_VIDEO
+                | MmTelCapabilities.CAPABILITY_TYPE_SMS
+                | MmTelCapabilities.CAPABILITY_TYPE_UT
+            );
+        callback.onCapabilitiesStatusChanged(capabilities);
+
+        assertTrue(mImsStateTracker.isImsStateReady());
+        assertTrue(mImsStateTracker.isImsVoiceCapable());
+        assertTrue(mImsStateTracker.isImsVideoCapable());
+        assertTrue(mImsStateTracker.isImsSmsCapable());
+        assertTrue(mImsStateTracker.isImsUtCapable());
+
+        capabilities = new MmTelCapabilities();
+        callback.onCapabilitiesStatusChanged(capabilities);
+
+        assertTrue(mImsStateTracker.isImsStateReady());
+        assertFalse(mImsStateTracker.isImsVoiceCapable());
+        assertFalse(mImsStateTracker.isImsVideoCapable());
+        assertFalse(mImsStateTracker.isImsSmsCapable());
+        assertFalse(mImsStateTracker.isImsUtCapable());
+
+        verify(mImsStateListener, times(2)).onImsMmTelCapabilitiesChanged();
+    }
+
+    @Test
+    @SmallTest
+    public void testAddImsStateListenerWhenImsStateReady() throws ImsException {
+        ImsMmTelManager.CapabilityCallback callback = setUpMmTelCapabilityCallback();
+
+        MmTelCapabilities capabilities = new MmTelCapabilities(
+                MmTelCapabilities.CAPABILITY_TYPE_VOICE
+                | MmTelCapabilities.CAPABILITY_TYPE_VIDEO
+                | MmTelCapabilities.CAPABILITY_TYPE_SMS
+                | MmTelCapabilities.CAPABILITY_TYPE_UT
+            );
+        callback.onCapabilitiesStatusChanged(capabilities);
+
+        ImsStateTracker.ImsStateListener listener =
+                Mockito.mock(ImsStateTracker.ImsStateListener.class);
+        mImsStateTracker.addImsStateListener(listener);
+        waitForHandlerAction(mImsStateTracker.getHandler(), TIMEOUT_MS);
+
+        verify(listener).onImsMmTelFeatureAvailableChanged();
+        verify(listener).onImsRegistrationStateChanged();
+        verify(listener).onImsMmTelCapabilitiesChanged();
+    }
+
+    @Test
+    @SmallTest
+    public void testAddAndRemoveImsStateListenerWhenImsStateReady() throws ImsException {
+        ImsMmTelManager.CapabilityCallback callback = setUpMmTelCapabilityCallback();
+
+        MmTelCapabilities capabilities = new MmTelCapabilities(
+                MmTelCapabilities.CAPABILITY_TYPE_VOICE
+                | MmTelCapabilities.CAPABILITY_TYPE_VIDEO
+                | MmTelCapabilities.CAPABILITY_TYPE_SMS
+                | MmTelCapabilities.CAPABILITY_TYPE_UT
+            );
+        callback.onCapabilitiesStatusChanged(capabilities);
+
+        Handler handler = new Handler(mLooper);
+        ImsStateTracker.ImsStateListener listener =
+                Mockito.mock(ImsStateTracker.ImsStateListener.class);
+        handler.post(() -> {
+            mImsStateTracker.addImsStateListener(listener);
+            mImsStateTracker.removeImsStateListener(listener);
+        });
+        waitForHandlerAction(mImsStateTracker.getHandler(), TIMEOUT_MS);
+
+        verify(listener, never()).onImsMmTelFeatureAvailableChanged();
+        verify(listener, never()).onImsRegistrationStateChanged();
+        verify(listener, never()).onImsMmTelCapabilitiesChanged();
+    }
+
+    private ImsStateCallback setUpImsStateCallback() throws ImsException {
+        mImsStateTracker.start(SUB_1);
+        mImsStateTracker.addImsStateListener(mImsStateListener);
+        waitForHandlerAction(mImsStateTracker.getHandler(), TIMEOUT_MS);
+
+        assertEquals(SUB_1, mImsStateTracker.getSubId());
+        assertFalse(mImsStateTracker.isMmTelFeatureAvailable());
+        ArgumentCaptor<ImsStateCallback> callbackCaptor =
+                ArgumentCaptor.forClass(ImsStateCallback.class);
+        verify(mMmTelManager).registerImsStateCallback(
+                any(Executor.class), callbackCaptor.capture());
+
+        ImsStateCallback imsStateCallback = callbackCaptor.getValue();
+        assertNotNull(imsStateCallback);
+        return imsStateCallback;
+    }
+
+    private RegistrationManager.RegistrationCallback setUpImsRegistrationCallback()
+            throws ImsException {
+        ImsStateCallback imsStateCallback = setUpImsStateCallback();
+        imsStateCallback.onAvailable();
+
+        assertTrue(mImsStateTracker.isMmTelFeatureAvailable());
+        ArgumentCaptor<RegistrationManager.RegistrationCallback> callbackCaptor =
+                ArgumentCaptor.forClass(RegistrationManager.RegistrationCallback.class);
+        verify(mMmTelManager).registerImsRegistrationCallback(
+                any(Executor.class), callbackCaptor.capture());
+
+        RegistrationManager.RegistrationCallback registrationCallback = callbackCaptor.getValue();
+        assertNotNull(registrationCallback);
+        return registrationCallback;
+    }
+
+    private ImsMmTelManager.CapabilityCallback setUpMmTelCapabilityCallback()
+            throws ImsException {
+        RegistrationManager.RegistrationCallback registrationCallback =
+                setUpImsRegistrationCallback();
+        registrationCallback.onRegistered(new ImsRegistrationAttributes.Builder(
+                ImsRegistrationImplBase.REGISTRATION_TECH_LTE).build());
+
+        assertTrue(mImsStateTracker.isMmTelFeatureAvailable());
+        // It's false because the MMTEL capabilities are not updated.
+        assertFalse(mImsStateTracker.isImsStateReady());
+        assertTrue(mImsStateTracker.isImsRegistered());
+        assertFalse(mImsStateTracker.isImsRegisteredOverWlan());
+        assertEquals(AccessNetworkType.EUTRAN, mImsStateTracker.getImsAccessNetworkType());
+        ArgumentCaptor<ImsMmTelManager.CapabilityCallback> callbackCaptor =
+                ArgumentCaptor.forClass(ImsMmTelManager.CapabilityCallback.class);
+        verify(mMmTelManager).registerMmTelCapabilityCallback(
+                any(Executor.class), callbackCaptor.capture());
+
+        ImsMmTelManager.CapabilityCallback capabilityCallback = callbackCaptor.getValue();
+        assertNotNull(capabilityCallback);
+        return capabilityCallback;
+    }
+
+    private boolean isImsStateUnavailable() {
+        return mImsStateTracker.isImsStateReady()
+                && !mImsStateTracker.isImsRegistered()
+                && !mImsStateTracker.isMmTelFeatureAvailable()
+                && !mImsStateTracker.isImsVoiceCapable()
+                && !mImsStateTracker.isImsVideoCapable()
+                && !mImsStateTracker.isImsSmsCapable()
+                && !mImsStateTracker.isImsUtCapable()
+                && (AccessNetworkType.UNKNOWN == mImsStateTracker.getImsAccessNetworkType());
+    }
+
+    private boolean isImsStateInit() {
+        return !mImsStateTracker.isImsStateReady()
+                && !mImsStateTracker.isImsRegistered()
+                && !mImsStateTracker.isMmTelFeatureAvailable()
+                && !mImsStateTracker.isImsVoiceCapable()
+                && !mImsStateTracker.isImsVideoCapable()
+                && !mImsStateTracker.isImsSmsCapable()
+                && !mImsStateTracker.isImsUtCapable()
+                && (AccessNetworkType.UNKNOWN == mImsStateTracker.getImsAccessNetworkType());
+    }
+
+    private void waitForHandlerAction(Handler h, long timeoutMillis) {
+        waitForHandlerActionDelayed(h, 0, timeoutMillis);
+    }
+
+    private void waitForHandlerActionDelayed(Handler h, long delayMillis, long timeoutMillis) {
+        final CountDownLatch lock = new CountDownLatch(1);
+        h.postDelayed(lock::countDown, delayMillis);
+        while (lock.getCount() > 0) {
+            try {
+                lock.await(timeoutMillis, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                // do nothing
+            }
+        }
+    }
+}
diff --git a/tests/src/com/android/services/telephony/domainselection/SmsDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/SmsDomainSelectorTest.java
new file mode 100644
index 0000000..412d83d
--- /dev/null
+++ b/tests/src/com/android/services/telephony/domainselection/SmsDomainSelectorTest.java
@@ -0,0 +1,434 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony.domainselection;
+
+import static android.telephony.DomainSelectionService.SELECTOR_TYPE_SMS;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
+import android.telephony.AccessNetworkConstants.RadioAccessNetworkType;
+import android.telephony.DomainSelectionService.SelectionAttributes;
+import android.telephony.NetworkRegistrationInfo;
+import android.telephony.TransportSelectorCallback;
+import android.telephony.WwanSelectorCallback;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.TestableLooper;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.TestContext;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.function.Consumer;
+
+/**
+ * Unit tests for SmsDomainSelector.
+ */
+@RunWith(AndroidJUnit4.class)
+public class SmsDomainSelectorTest {
+    private static final String LOG_TAG = "DomainSelector-SMS";
+    private static final int SLOT_0 = 0;
+    private static final int SUB_1 = 1;
+    private static final int SUB_2 = 2;
+
+    @Mock private TransportSelectorCallback mTransportSelectorCallback;
+    @Mock private WwanSelectorCallback mWwanSelectorCallback;
+    @Mock private ImsStateTracker mImsStateTracker;
+    @Mock private DomainSelectorBase.DestroyListener mDomainSelectorDestroyListener;
+
+    private final SelectionAttributes mSelectionAttributes =
+            new SelectionAttributes.Builder(SLOT_0, SUB_1, SELECTOR_TYPE_SMS).build();
+    private Context mContext;
+    private Looper mLooper;
+    private TestableLooper mTestableLooper;
+    private SmsDomainSelector mDomainSelector;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mContext = new TestContext();
+        HandlerThread handlerThread = new HandlerThread(
+                SmsDomainSelectorTest.class.getSimpleName());
+        handlerThread.start();
+        mLooper = handlerThread.getLooper();
+        mTestableLooper = new TestableLooper(mLooper);
+        mDomainSelector = new SmsDomainSelector(mContext, SLOT_0, SUB_1,
+                mLooper, mImsStateTracker, mDomainSelectorDestroyListener);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        if (mTestableLooper != null) {
+            mTestableLooper.destroy();
+            mTestableLooper = null;
+        }
+
+        if (mDomainSelector != null) {
+            mDomainSelector.destroy();
+            verify(mImsStateTracker).removeImsStateListener(eq(mDomainSelector));
+        }
+
+        if (mLooper != null) {
+            mLooper.quit();
+            mLooper = null;
+        }
+
+        mDomainSelector = null;
+        mWwanSelectorCallback = null;
+        mTransportSelectorCallback = null;
+        mImsStateTracker = null;
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenImsRegisteredOnEutran() {
+        selectDomain(AccessNetworkType.EUTRAN);
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenImsRegisteredOnNgran() {
+        selectDomain(AccessNetworkType.NGRAN);
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenImsRegisteredOnIwlan() {
+        selectDomain(AccessNetworkType.IWLAN);
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenImsNotRegistered() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpImsStateListener(true, false, false);
+        setUpWwanSelectorCallback();
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+
+        assertTrue(mDomainSelector.isDomainSelectionRequested());
+
+        processAllMessages();
+
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+        assertFalse(mDomainSelector.isDomainSelectionRequested());
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhenWwanSelectorCallbackNull() {
+        setUpImsStateTracker(AccessNetworkType.EUTRAN);
+        doAnswer((invocation) -> {
+            Object[] args = invocation.getArguments();
+            final Consumer<WwanSelectorCallback> callback =
+                    (Consumer<WwanSelectorCallback>) args[0];
+            callback.accept(null);
+            return null;
+        }).when(mTransportSelectorCallback).onWwanSelected(any(Consumer.class));
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+
+        assertTrue(mDomainSelector.isDomainSelectionRequested());
+
+        processAllMessages();
+
+        verify(mTransportSelectorCallback).onSelectionTerminated(anyInt());
+        assertFalse(mDomainSelector.isDomainSelectionRequested());
+    }
+
+    @Test
+    @SmallTest
+    public void testSelectDomainWhilePreviousRequestInProgress() {
+        setUpImsStateTracker(AccessNetworkType.EUTRAN);
+        setUpWwanSelectorCallback();
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+
+        assertTrue(mDomainSelector.isDomainSelectionRequested());
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+
+        processAllMessages();
+
+        // onDomainSelected will be invoked only once
+        // even though the domain selection was requested twice.
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS));
+        assertFalse(mDomainSelector.isDomainSelectionRequested());
+    }
+
+    @Test
+    @SmallTest
+    public void testCancelSelection() {
+        setUpImsStateTracker(AccessNetworkType.EUTRAN);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+
+        assertTrue(mDomainSelector.isDomainSelectionRequested());
+
+        mDomainSelector.cancelSelection();
+
+        assertFalse(mDomainSelector.isDomainSelectionRequested());
+        verify(mDomainSelectorDestroyListener).onDomainSelectorDestroyed(eq(mDomainSelector));
+    }
+
+    @Test
+    @SmallTest
+    public void testFinishSelection() {
+        setUpImsStateTracker(AccessNetworkType.EUTRAN);
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+
+        assertTrue(mDomainSelector.isDomainSelectionRequested());
+
+        mDomainSelector.finishSelection();
+
+        assertFalse(mDomainSelector.isDomainSelectionRequested());
+        verify(mDomainSelectorDestroyListener).onDomainSelectorDestroyed(eq(mDomainSelector));
+    }
+
+    @Test
+    @SmallTest
+    public void testReselectDomain() {
+        setUpImsStateTracker(AccessNetworkType.EUTRAN, AccessNetworkType.IWLAN);
+        setUpWwanSelectorCallback();
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+
+        assertTrue(mDomainSelector.isDomainSelectionRequested());
+
+        processAllMessages();
+
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS));
+        assertFalse(mDomainSelector.isDomainSelectionRequested());
+
+        mDomainSelector.reselectDomain(mSelectionAttributes);
+
+        assertTrue(mDomainSelector.isDomainSelectionRequested());
+
+        processAllMessages();
+
+        verify(mTransportSelectorCallback).onWlanSelected();
+        assertFalse(mDomainSelector.isDomainSelectionRequested());
+    }
+
+    @Test
+    @SmallTest
+    public void testReselectDomainWhilePreviousRequestInProgress() {
+        setUpImsStateTracker(AccessNetworkType.EUTRAN, AccessNetworkType.IWLAN);
+        setUpWwanSelectorCallback();
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+
+        assertTrue(mDomainSelector.isDomainSelectionRequested());
+
+        mDomainSelector.reselectDomain(mSelectionAttributes);
+        processAllMessages();
+
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS));
+        assertFalse(mDomainSelector.isDomainSelectionRequested());
+        verify(mTransportSelectorCallback, never()).onWlanSelected();
+        assertFalse(mDomainSelector.isDomainSelectionRequested());
+    }
+
+    @Test
+    @SmallTest
+    public void testOnImsRegistrationStateChangedWhenNotRegistered() {
+        setUpImsStateTracker(AccessNetworkType.UNKNOWN);
+        setUpImsStateListener(false, true, false);
+        setUpWwanSelectorCallback();
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+
+        assertTrue(mDomainSelector.isDomainSelectionRequested());
+
+        processAllMessages();
+
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+        assertFalse(mDomainSelector.isDomainSelectionRequested());
+    }
+
+    @Test
+    @SmallTest
+    public void testOnImsRegistrationStateChangedWhenRegisteredAndSmsCapable() {
+        setUpImsStateTracker(AccessNetworkType.EUTRAN, true);
+        setUpImsStateListener(false, true, false);
+        setUpWwanSelectorCallback();
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+
+        assertTrue(mDomainSelector.isDomainSelectionRequested());
+
+        processAllMessages();
+
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS));
+        assertFalse(mDomainSelector.isDomainSelectionRequested());
+    }
+
+    @Test
+    @SmallTest
+    public void testOnImsRegistrationStateChangedWhenRegisteredAndSmsIncapable() {
+        setUpImsStateTracker(AccessNetworkType.EUTRAN, false);
+        setUpImsStateListener(false, true, false);
+        setUpWwanSelectorCallback();
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+
+        assertTrue(mDomainSelector.isDomainSelectionRequested());
+
+        processAllMessages();
+
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+        assertFalse(mDomainSelector.isDomainSelectionRequested());
+    }
+
+    @Test
+    @SmallTest
+    public void testOnImsMmTelCapabilitiesChangedWhenSmsCapable() {
+        setUpImsStateTracker(AccessNetworkType.EUTRAN, true);
+        setUpImsStateListener(false, false, true);
+        setUpWwanSelectorCallback();
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+
+        assertTrue(mDomainSelector.isDomainSelectionRequested());
+
+        processAllMessages();
+
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS));
+        assertFalse(mDomainSelector.isDomainSelectionRequested());
+    }
+
+    @Test
+    @SmallTest
+    public void testOnImsMmTelCapabilitiesChangedWhenSmsIncapable() {
+        setUpImsStateTracker(AccessNetworkType.EUTRAN, false);
+        setUpImsStateListener(false, false, true);
+        setUpWwanSelectorCallback();
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+
+        assertTrue(mDomainSelector.isDomainSelectionRequested());
+
+        processAllMessages();
+
+        verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_CS));
+        assertFalse(mDomainSelector.isDomainSelectionRequested());
+    }
+
+    private void selectDomain(@RadioAccessNetworkType int accessNetworkType) {
+        setUpImsStateTracker(accessNetworkType);
+        setUpWwanSelectorCallback();
+
+        mDomainSelector.selectDomain(mSelectionAttributes, mTransportSelectorCallback);
+
+        assertTrue(mDomainSelector.isDomainSelectionRequested());
+
+        processAllMessages();
+
+        if (accessNetworkType == AccessNetworkType.IWLAN) {
+            verify(mTransportSelectorCallback).onWlanSelected();
+        } else {
+            verify(mWwanSelectorCallback).onDomainSelected(eq(NetworkRegistrationInfo.DOMAIN_PS));
+        }
+        assertFalse(mDomainSelector.isDomainSelectionRequested());
+    }
+
+    private void setUpImsStateTracker(@RadioAccessNetworkType int accessNetworkType) {
+        setUpImsStateTracker(accessNetworkType, true);
+    }
+
+    private void setUpImsStateTracker(@RadioAccessNetworkType int accessNetworkType,
+            boolean smsCapable) {
+        when(mImsStateTracker.isMmTelFeatureAvailable()).thenReturn(true);
+        when(mImsStateTracker.isImsRegistered())
+                .thenReturn(accessNetworkType != AccessNetworkType.UNKNOWN);
+        when(mImsStateTracker.isImsRegisteredOverWlan())
+                .thenReturn(accessNetworkType == AccessNetworkType.IWLAN);
+        when(mImsStateTracker.getImsAccessNetworkType()).thenReturn(accessNetworkType);
+        when(mImsStateTracker.isImsSmsCapable()).thenReturn(smsCapable);
+    }
+
+    private void setUpImsStateTracker(@RadioAccessNetworkType int firstAccessNetworkType,
+            @RadioAccessNetworkType int secondAccessNetworkType) {
+        when(mImsStateTracker.isMmTelFeatureAvailable()).thenReturn(true);
+        when(mImsStateTracker.isImsRegistered()).thenReturn(
+                firstAccessNetworkType != AccessNetworkType.UNKNOWN,
+                secondAccessNetworkType != AccessNetworkType.UNKNOWN);
+        when(mImsStateTracker.isImsRegisteredOverWlan()).thenReturn(
+                firstAccessNetworkType == AccessNetworkType.IWLAN,
+                secondAccessNetworkType == AccessNetworkType.IWLAN);
+        when(mImsStateTracker.getImsAccessNetworkType()).thenReturn(
+                firstAccessNetworkType,
+                secondAccessNetworkType);
+        when(mImsStateTracker.isImsSmsCapable()).thenReturn(true);
+    }
+
+    private void setUpWwanSelectorCallback() {
+        doAnswer((invocation) -> {
+            Object[] args = invocation.getArguments();
+            final Consumer<WwanSelectorCallback> callback =
+                    (Consumer<WwanSelectorCallback>) args[0];
+            callback.accept(mWwanSelectorCallback);
+            return null;
+        }).when(mTransportSelectorCallback).onWwanSelected(any(Consumer.class));
+    }
+
+    private void setUpImsStateListener(boolean notifyMmTelFeatureAvailable,
+            boolean notifyImsRegState, boolean notifyMmTelCapability) {
+        doAnswer((invocation) -> {
+            Object[] args = invocation.getArguments();
+            final ImsStateTracker.ImsStateListener listener =
+                    (ImsStateTracker.ImsStateListener) args[0];
+            mDomainSelector.post(() -> {
+                if (notifyMmTelFeatureAvailable) {
+                    listener.onImsMmTelFeatureAvailableChanged();
+                }
+                if (notifyImsRegState) {
+                    listener.onImsRegistrationStateChanged();
+                }
+                if (notifyMmTelCapability) {
+                    listener.onImsMmTelCapabilitiesChanged();
+                }
+            });
+            return null;
+        }).when(mImsStateTracker).addImsStateListener(any(ImsStateTracker.ImsStateListener.class));
+    }
+
+    private void processAllMessages() {
+        while (!mTestableLooper.getLooper().getQueue().isIdle()) {
+            mTestableLooper.processAllMessages();
+        }
+    }
+}
diff --git a/tests/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionServiceTest.java b/tests/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionServiceTest.java
new file mode 100644
index 0000000..ace59e3
--- /dev/null
+++ b/tests/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionServiceTest.java
@@ -0,0 +1,365 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony.domainselection;
+
+import static org.junit.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.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
+import android.telephony.BarringInfo;
+import android.telephony.DomainSelectionService;
+import android.telephony.DomainSelectionService.SelectionAttributes;
+import android.telephony.DomainSelectionService.SelectorType;
+import android.telephony.ServiceState;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
+import android.telephony.TransportSelectorCallback;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.TestableLooper;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.TestContext;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+/**
+ * Unit tests for TelephonyDomainSelectionService.
+ */
+@RunWith(AndroidJUnit4.class)
+public class TelephonyDomainSelectionServiceTest {
+    private TelephonyDomainSelectionService.ImsStateTrackerFactory mImsStateTrackerFactory =
+            new TelephonyDomainSelectionService.ImsStateTrackerFactory() {
+                @Override
+                public ImsStateTracker create(Context context, int slotId,
+                        @NonNull Looper looper) {
+                    return mImsStateTracker;
+                }
+            };
+    private TelephonyDomainSelectionService.DomainSelectorFactory mDomainSelectorFactory =
+            new TelephonyDomainSelectionService.DomainSelectorFactory() {
+                @Override
+                public DomainSelectorBase create(Context context, int slotId, int subId,
+                        @SelectorType int selectorType, boolean isEmergency,
+                        @NonNull Looper looper, @NonNull ImsStateTracker imsStateTracker,
+                        @NonNull DomainSelectorBase.DestroyListener listener) {
+                    switch (selectorType) {
+                        case DomainSelectionService.SELECTOR_TYPE_CALLING: // fallthrough
+                        case DomainSelectionService.SELECTOR_TYPE_SMS: // fallthrough
+                        case DomainSelectionService.SELECTOR_TYPE_UT:
+                            mDomainSelectorDestroyListener = listener;
+                            if (subId == SUB_1) {
+                                return mDomainSelectorBase1;
+                            } else {
+                                return mDomainSelectorBase2;
+                            }
+                        default:
+                            return null;
+                    }
+                }
+            };
+    private static final int SLOT_0 = 0;
+    private static final int SUB_1 = 1;
+    private static final int SUB_2 = 2;
+    private static final String CALL_ID = "Call_1";
+    private static final @SelectorType int TEST_SELECTOR_TYPE =
+            DomainSelectionService.SELECTOR_TYPE_CALLING;
+    private static final @SelectorType int INVALID_SELECTOR_TYPE = -1;
+
+    @Mock private DomainSelectorBase mDomainSelectorBase1;
+    @Mock private DomainSelectorBase mDomainSelectorBase2;
+    @Mock private TransportSelectorCallback mSelectorCallback1;
+    @Mock private TransportSelectorCallback mSelectorCallback2;
+    @Mock private ImsStateTracker mImsStateTracker;
+
+    private final ServiceState mServiceState = new ServiceState();
+    private final BarringInfo mBarringInfo = new BarringInfo();
+    private Context mContext;
+    private Handler mServiceHandler;
+    private TestableLooper mTestableLooper;
+    private SubscriptionManager mSubscriptionManager;
+    private OnSubscriptionsChangedListener mOnSubscriptionsChangedListener;
+    private DomainSelectorBase.DestroyListener mDomainSelectorDestroyListener;
+    private TelephonyDomainSelectionService mDomainSelectionService;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+
+        mContext = new TestContext();
+        mDomainSelectionService = new TelephonyDomainSelectionService(mContext,
+                mImsStateTrackerFactory, mDomainSelectorFactory);
+        mServiceHandler = new Handler(mDomainSelectionService.getLooper());
+        mTestableLooper = new TestableLooper(mDomainSelectionService.getLooper());
+
+        mSubscriptionManager = mContext.getSystemService(SubscriptionManager.class);
+        ArgumentCaptor<OnSubscriptionsChangedListener> listenerCaptor =
+                ArgumentCaptor.forClass(OnSubscriptionsChangedListener.class);
+        verify(mSubscriptionManager).addOnSubscriptionsChangedListener(
+                any(Executor.class), listenerCaptor.capture());
+        mOnSubscriptionsChangedListener = listenerCaptor.getValue();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        if (mTestableLooper != null) {
+            mTestableLooper.destroy();
+            mTestableLooper = null;
+        }
+        mServiceHandler = null;
+
+        if (mDomainSelectionService != null) {
+            mDomainSelectionService.onDestroy();
+            mDomainSelectionService = null;
+        }
+
+        mDomainSelectorBase1 = null;
+        mDomainSelectorBase2 = null;
+        mSelectorCallback1 = null;
+        mSelectorCallback2 = null;
+        mImsStateTracker = null;
+        mSubscriptionManager = null;
+        mOnSubscriptionsChangedListener = null;
+        mDomainSelectorDestroyListener = null;
+    }
+
+    @Test
+    @SmallTest
+    public void testGetExecutor() {
+        assertNotNull(mDomainSelectionService.getExecutor());
+    }
+
+    @Test
+    @SmallTest
+    public void testOnDomainSelection() {
+        SelectionAttributes attr1 = new SelectionAttributes.Builder(
+                SLOT_0, SUB_1, TEST_SELECTOR_TYPE)
+                .setCallId(CALL_ID)
+                .setEmergency(true)
+                .build();
+        mServiceHandler.post(() -> {
+            mDomainSelectionService.onDomainSelection(attr1, mSelectorCallback1);
+        });
+        processAllMessages();
+
+        verify(mImsStateTracker).start(eq(SUB_1));
+        verify(mSelectorCallback1).onCreated(eq(mDomainSelectorBase1));
+        verifyNoMoreInteractions(mSelectorCallback1);
+        verify(mDomainSelectorBase1).selectDomain(eq(attr1), eq(mSelectorCallback1));
+    }
+
+    @Test
+    @SmallTest
+    public void testOnDomainSelectionWithInvalidSelectorType() {
+        SelectionAttributes attr1 = new SelectionAttributes.Builder(
+                SLOT_0, SUB_1, INVALID_SELECTOR_TYPE)
+                .setCallId(CALL_ID)
+                .setEmergency(true)
+                .build();
+        mServiceHandler.post(() -> {
+            mDomainSelectionService.onDomainSelection(attr1, mSelectorCallback1);
+        });
+        processAllMessages();
+
+        verify(mImsStateTracker, never()).start(anyInt());
+        verify(mSelectorCallback1).onSelectionTerminated(anyInt());
+        verifyNoMoreInteractions(mSelectorCallback1);
+        verify(mDomainSelectorBase1, never()).selectDomain(eq(attr1), eq(mSelectorCallback1));
+    }
+
+    @Test
+    @SmallTest
+    public void testOnDomainSelectionTwiceWithDestroy() {
+        SelectionAttributes attr1 = new SelectionAttributes.Builder(
+                SLOT_0, SUB_1, TEST_SELECTOR_TYPE)
+                .setCallId(CALL_ID)
+                .setEmergency(true)
+                .build();
+        mServiceHandler.post(() -> {
+            mDomainSelectionService.onDomainSelection(attr1, mSelectorCallback1);
+        });
+        processAllMessages();
+
+        verify(mImsStateTracker).start(eq(SUB_1));
+        verify(mSelectorCallback1).onCreated(eq(mDomainSelectorBase1));
+        verifyNoMoreInteractions(mSelectorCallback1);
+        verify(mDomainSelectorBase1).selectDomain(eq(attr1), eq(mSelectorCallback1));
+
+        // Notify the domain selection service that this domain selector is destroyed.
+        mDomainSelectorDestroyListener.onDomainSelectorDestroyed(mDomainSelectorBase1);
+
+        SelectionAttributes attr2 = new SelectionAttributes.Builder(
+                SLOT_0, SUB_2, TEST_SELECTOR_TYPE)
+                .setCallId(CALL_ID)
+                .setEmergency(true)
+                .build();
+        mServiceHandler.post(() -> {
+            mDomainSelectionService.onDomainSelection(attr2, mSelectorCallback2);
+        });
+        processAllMessages();
+
+        verify(mImsStateTracker).start(eq(SUB_2));
+        verify(mSelectorCallback2).onCreated(eq(mDomainSelectorBase2));
+        verifyNoMoreInteractions(mSelectorCallback2);
+        verify(mDomainSelectorBase2).selectDomain(eq(attr2), eq(mSelectorCallback2));
+    }
+
+    @Test
+    @SmallTest
+    public void testOnDomainSelectionTwiceWithoutDestroy() {
+        SelectionAttributes attr1 = new SelectionAttributes.Builder(
+                SLOT_0, SUB_1, TEST_SELECTOR_TYPE)
+                .setCallId(CALL_ID)
+                .setEmergency(true)
+                .build();
+        mServiceHandler.post(() -> {
+            mDomainSelectionService.onDomainSelection(attr1, mSelectorCallback1);
+        });
+        processAllMessages();
+
+        verify(mImsStateTracker).start(eq(SUB_1));
+        verify(mSelectorCallback1).onCreated(eq(mDomainSelectorBase1));
+        verifyNoMoreInteractions(mSelectorCallback1);
+        verify(mDomainSelectorBase1).selectDomain(eq(attr1), eq(mSelectorCallback1));
+
+        SelectionAttributes attr2 = new SelectionAttributes.Builder(
+                SLOT_0, SUB_2, TEST_SELECTOR_TYPE)
+                .setCallId(CALL_ID)
+                .setEmergency(true)
+                .build();
+        mServiceHandler.post(() -> {
+            mDomainSelectionService.onDomainSelection(attr2, mSelectorCallback2);
+        });
+        processAllMessages();
+
+        verify(mImsStateTracker).start(eq(SUB_2));
+        verify(mSelectorCallback2).onCreated(eq(mDomainSelectorBase2));
+        verifyNoMoreInteractions(mSelectorCallback2);
+        verify(mDomainSelectorBase2).selectDomain(eq(attr2), eq(mSelectorCallback2));
+    }
+
+    @Test
+    @SmallTest
+    public void testOnServiceStateUpdated() {
+        mDomainSelectionService.onServiceStateUpdated(SLOT_0, SUB_1, mServiceState);
+
+        verify(mImsStateTracker).updateServiceState(eq(mServiceState));
+    }
+
+    @Test
+    @SmallTest
+    public void testOnBarringInfoUpdated() {
+        mDomainSelectionService.onBarringInfoUpdated(SLOT_0, SUB_1, mBarringInfo);
+
+        verify(mImsStateTracker).updateBarringInfo(eq(mBarringInfo));
+    }
+
+    @Test
+    @SmallTest
+    public void testOnDestroy() {
+        SelectionAttributes attr1 = new SelectionAttributes.Builder(
+                SLOT_0, SUB_1, TEST_SELECTOR_TYPE)
+                .setCallId(CALL_ID)
+                .setEmergency(true)
+                .build();
+        mServiceHandler.post(() -> {
+            mDomainSelectionService.onDomainSelection(attr1, mSelectorCallback1);
+        });
+        processAllMessages();
+
+        mDomainSelectionService.onDestroy();
+
+        verify(mImsStateTracker).destroy();
+        verify(mDomainSelectorBase1).destroy();
+        verify(mSubscriptionManager).removeOnSubscriptionsChangedListener(any());
+    }
+
+    @Test
+    @SmallTest
+    public void testHandleSubscriptionsChangedWithEmptySubscriptionInfo() {
+        when(mSubscriptionManager.getActiveSubscriptionInfoList())
+                .thenReturn(null, new ArrayList<SubscriptionInfo>());
+
+        mOnSubscriptionsChangedListener.onSubscriptionsChanged();
+        mOnSubscriptionsChangedListener.onSubscriptionsChanged();
+
+        verify(mImsStateTracker, never()).start(anyInt());
+    }
+
+    @Test
+    @SmallTest
+    public void testHandleSubscriptionsChangedWithActiveSubscriptionInfoAndInvalidSlotIndex() {
+        SubscriptionInfo subsInfo = Mockito.mock(SubscriptionInfo.class);
+        List<SubscriptionInfo> subsInfoList = new ArrayList<>();
+        subsInfoList.add(subsInfo);
+        when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(subsInfoList);
+        when(subsInfo.getSimSlotIndex()).thenReturn(SubscriptionManager.INVALID_SIM_SLOT_INDEX);
+
+        mOnSubscriptionsChangedListener.onSubscriptionsChanged();
+
+        verify(mImsStateTracker, never()).start(anyInt());
+    }
+
+    @Test
+    @SmallTest
+    public void testHandleSubscriptionsChangedWithActiveSubscriptionInfo() {
+        SubscriptionInfo subsInfo = Mockito.mock(SubscriptionInfo.class);
+        List<SubscriptionInfo> subsInfoList = new ArrayList<>();
+        subsInfoList.add(subsInfo);
+        when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(subsInfoList);
+        when(subsInfo.getSubscriptionId())
+                .thenReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID, SUB_1);
+        when(subsInfo.getSimSlotIndex()).thenReturn(SLOT_0);
+
+        mOnSubscriptionsChangedListener.onSubscriptionsChanged();
+        mOnSubscriptionsChangedListener.onSubscriptionsChanged();
+
+        verify(mImsStateTracker).start(eq(SubscriptionManager.INVALID_SUBSCRIPTION_ID));
+        verify(mImsStateTracker).start(eq(SUB_1));
+    }
+
+    private void processAllMessages() {
+        while (!mTestableLooper.getLooper().getQueue().isIdle()) {
+            mTestableLooper.processAllMessages();
+        }
+    }
+}
diff --git a/tests/src/com/android/services/telephony/rcs/RcsFeatureControllerTest.java b/tests/src/com/android/services/telephony/rcs/RcsFeatureControllerTest.java
index 2a30e1a..7cf0852 100644
--- a/tests/src/com/android/services/telephony/rcs/RcsFeatureControllerTest.java
+++ b/tests/src/com/android/services/telephony/rcs/RcsFeatureControllerTest.java
@@ -22,6 +22,7 @@
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -171,12 +172,12 @@
         verify(mFeatureManager).registerImsRegistrationCallback(captor.capture());
         assertNotNull(captor.getValue());
 
-        captor.getValue().onDeregistered(REASON_DISCONNECTED);
+        captor.getValue().onDeregistered(REASON_DISCONNECTED, 0);
         controller.getRegistrationState(result -> {
             assertNotNull(result);
             assertEquals(RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED, result.intValue());
         });
-        verify(mRegistrationCallback).handleImsUnregistered(REASON_DISCONNECTED);
+        verify(mRegistrationCallback).handleImsUnregistered(eq(REASON_DISCONNECTED), anyInt());
 
         ImsRegistrationAttributes attr = new ImsRegistrationAttributes.Builder(
                 ImsRegistrationImplBase.REGISTRATION_TECH_LTE).build();
@@ -193,8 +194,7 @@
             assertNotNull(result);
             assertEquals(RegistrationManager.REGISTRATION_STATE_REGISTERED, result.intValue());
         });
-        verify(mRegistrationCallback).handleImsRegistered(
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        verify(mRegistrationCallback).handleImsRegistered(attr);
     }
 
     @Test
