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/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/TelephonyDomainSelectionService.java b/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionService.java
new file mode 100644
index 0000000..56b9b68
--- /dev/null
+++ b/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionService.java
@@ -0,0 +1,519 @@
+/*
+ * 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) {
+                        // TODO(ag/19990283) uncomment when emergency call domain selector is ready.
+                        /*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:
+                    // TODO(ag/20075167) uncomment when SMS domain selector is ready.
+                    /*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/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/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/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();
+        }
+    }
+}
