diff --git a/Android.bp b/Android.bp
index 1887a8a..e7ca068 100644
--- a/Android.bp
+++ b/Android.bp
@@ -35,6 +35,7 @@
         "com.android.phone.common-lib",
         "guava",
         "PlatformProperties",
+        "modules-utils-os",
     ],
 
     srcs: [
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 92b15b0..e38ea00 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -24,7 +24,6 @@
 
     <original-package android:name="com.android.phone" />
 
-    <protected-broadcast android:name="android.telecom.action.TTY_PREFERRED_MODE_CHANGED" />
     <protected-broadcast android:name="android.telecom.action.CURRENT_TTY_MODE_CHANGED" />
     <protected-broadcast android:name="android.intent.action.SERVICE_STATE" />
     <protected-broadcast android:name="android.intent.action.RADIO_TECHNOLOGY" />
@@ -83,6 +82,7 @@
     <protected-broadcast android:name= "com.android.cellbroadcastreceiver.GET_LATEST_CB_AREA_INFO" />
     <protected-broadcast android:name= "com.android.internal.telephony.ACTION_CARRIER_CERTIFICATE_DOWNLOAD" />
     <protected-broadcast android:name= "com.android.internal.telephony.OPEN_DEFAULT_SMS_APP" />
+    <protected-broadcast android:name= "com.android.internal.telephony.ACTION_TEST_OVERRIDE_CARRIER_ID" />
     <protected-broadcast android:name= "android.telephony.action.SIM_CARD_STATE_CHANGED" />
     <protected-broadcast android:name= "android.telephony.action.SIM_APPLICATION_STATE_CHANGED" />
     <protected-broadcast android:name= "android.telephony.action.SIM_SLOT_STATUS_CHANGED" />
@@ -219,6 +219,8 @@
     <uses-permission android:name="android.permission.START_ACTIVITIES_FROM_BACKGROUND" />
     <uses-permission android:name="android.permission.NETWORK_STATS_PROVIDER" />
     <uses-permission android:name="android.permission.HANDLE_CAR_MODE_CHANGES"/>
+    <uses-permission android:name="android.permission.MANAGE_SUBSCRIPTION_PLANS"/>
+    <uses-permission android:name="android.permission.OBSERVE_ROLE_HOLDERS"/>
 
     <application android:name="PhoneApp"
             android:persistent="true"
diff --git a/src/com/android/phone/ImsRcsController.java b/src/com/android/phone/ImsRcsController.java
index fd61936..52069b8 100644
--- a/src/com/android/phone/ImsRcsController.java
+++ b/src/com/android/phone/ImsRcsController.java
@@ -16,19 +16,26 @@
 
 package com.android.phone;
 
+import android.content.pm.PackageManager;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
+import android.os.UserHandle;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyFrameworkInitializer;
+import android.telephony.ims.DelegateRequest;
 import android.telephony.ims.ImsException;
+import android.telephony.ims.RcsUceAdapter.PublishState;
 import android.telephony.ims.RegistrationManager;
 import android.telephony.ims.aidl.IImsCapabilityCallback;
 import android.telephony.ims.aidl.IImsRcsController;
 import android.telephony.ims.aidl.IImsRegistrationCallback;
 import android.telephony.ims.aidl.IRcsUceControllerCallback;
 import android.telephony.ims.aidl.IRcsUcePublishStateCallback;
+import android.telephony.ims.aidl.ISipDelegate;
+import android.telephony.ims.aidl.ISipDelegateConnectionStateCallback;
+import android.telephony.ims.aidl.ISipDelegateMessageCallback;
 import android.telephony.ims.feature.ImsFeature;
 import android.telephony.ims.feature.RcsFeature;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
@@ -44,7 +51,7 @@
 import com.android.services.telephony.rcs.RcsFeatureController;
 import com.android.services.telephony.rcs.SipTransportController;
 import com.android.services.telephony.rcs.TelephonyRcsService;
-import com.android.services.telephony.rcs.UserCapabilityExchangeImpl;
+import com.android.services.telephony.rcs.UceControllerManager;
 
 import java.util.List;
 
@@ -203,40 +210,6 @@
         }
     }
 
-    @Override
-    public void registerUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c) {
-        enforceReadPrivilegedPermission("registerUcePublishStateCallback");
-        final long token = Binder.clearCallingIdentity();
-        try {
-            UserCapabilityExchangeImpl uce = getRcsFeatureController(subId).getFeature(
-                    UserCapabilityExchangeImpl.class);
-            if (uce == null) {
-                throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
-                    "This subscription does not support UCE.");
-            }
-            uce.registerPublishStateCallback(c);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    @Override
-    public void unregisterUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c) {
-        enforceReadPrivilegedPermission("unregisterUcePublishStateCallback");
-        final long token = Binder.clearCallingIdentity();
-        try {
-            UserCapabilityExchangeImpl uce = getRcsFeatureController(subId).getFeature(
-                    UserCapabilityExchangeImpl.class);
-            if (uce == null) {
-                throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
-                    "This subscription does not support UCE.");
-            }
-            uce.unregisterUcePublishStateCallback(c);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
     /**
      * Query for the capability of an IMS RCS service
      *
@@ -296,30 +269,94 @@
         }
         final long token = Binder.clearCallingIdentity();
         try {
-            UserCapabilityExchangeImpl uce = getRcsFeatureController(subId).getFeature(
-                    UserCapabilityExchangeImpl.class);
-            if (uce == null) {
+            UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature(
+                    UceControllerManager.class);
+            if (uceCtrlManager == null) {
                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
                         "This subscription does not support UCE.");
             }
-            uce.requestCapabilities(contactNumbers, c);
+            uceCtrlManager.requestCapabilities(contactNumbers, c);
+        } catch (ImsException e) {
+            throw new ServiceSpecificException(e.getCode(), e.getMessage());
         } finally {
             Binder.restoreCallingIdentity(token);
         }
     }
 
     @Override
-    public int getUcePublishState(int subId) {
-        enforceReadPrivilegedPermission("getUcePublishState");
+    public void requestNetworkAvailability(int subId, String callingPackage,
+            String callingFeatureId, Uri contactNumber, IRcsUceControllerCallback c) {
+        enforceReadPrivilegedPermission("requestNetworkAvailability");
+        if (!isUceSettingEnabled(subId, callingPackage, callingFeatureId)) {
+            throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
+                    "The user has not enabled UCE for this subscription.");
+        }
         final long token = Binder.clearCallingIdentity();
         try {
-            UserCapabilityExchangeImpl uce = getRcsFeatureController(subId).getFeature(
-                    UserCapabilityExchangeImpl.class);
-            if (uce == null) {
+            UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature(
+                    UceControllerManager.class);
+            if (uceCtrlManager == null) {
                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
                         "This subscription does not support UCE.");
             }
-            return uce.getUcePublishState();
+            uceCtrlManager.requestNetworkAvailability(contactNumber, c);
+        } catch (ImsException e) {
+            throw new ServiceSpecificException(e.getCode(), e.getMessage());
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    @Override
+    public @PublishState int getUcePublishState(int subId) {
+        enforceReadPrivilegedPermission("getUcePublishState");
+        final long token = Binder.clearCallingIdentity();
+        try {
+            UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature(
+                    UceControllerManager.class);
+            if (uceCtrlManager == null) {
+                throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
+                        "This subscription does not support UCE.");
+            }
+            return uceCtrlManager.getUcePublishState();
+        } catch (ImsException e) {
+            throw new ServiceSpecificException(e.getCode(), e.getMessage());
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    @Override
+    public void registerUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c) {
+        enforceReadPrivilegedPermission("registerUcePublishStateCallback");
+        final long token = Binder.clearCallingIdentity();
+        try {
+            UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature(
+                    UceControllerManager.class);
+            if (uceCtrlManager == null) {
+                throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
+                        "This subscription does not support UCE.");
+            }
+            uceCtrlManager.registerPublishStateCallback(c);
+        } catch (ImsException e) {
+            throw new ServiceSpecificException(e.getCode(), e.getMessage());
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    @Override
+    public void unregisterUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c) {
+        enforceReadPrivilegedPermission("unregisterUcePublishStateCallback");
+        final long token = Binder.clearCallingIdentity();
+        try {
+            UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature(
+                    UceControllerManager.class);
+            if (uceCtrlManager == null) {
+                throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
+                        "This subscription does not support UCE.");
+            }
+            uceCtrlManager.unregisterPublishStateCallback(c);
         } finally {
             Binder.restoreCallingIdentity(token);
         }
@@ -377,6 +414,58 @@
         }
     }
 
+    @Override
+    public void createSipDelegate(int subId, DelegateRequest request, String packageName,
+            ISipDelegateConnectionStateCallback delegateState,
+            ISipDelegateMessageCallback delegateMessage) {
+        enforceModifyPermission();
+        if (!UserHandle.getUserHandleForUid(Binder.getCallingUid()).isSystem()) {
+            throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
+                    "SipDelegate creation is only available to primary user.");
+        }
+        try {
+            int remoteUid = mApp.getPackageManager().getPackageUid(packageName, 0 /*flags*/);
+            if (Binder.getCallingUid() != remoteUid) {
+                throw new SecurityException("passed in packageName does not match the caller");
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            throw new SecurityException("Passed in PackageName can not be found on device");
+        }
+
+        final long identity = Binder.clearCallingIdentity();
+        SipTransportController transport = getRcsFeatureController(subId).getFeature(
+                SipTransportController.class);
+        if (transport == null) {
+            throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
+                    "This subscription does not support the creation of SIP delegates");
+        }
+        try {
+            transport.createSipDelegate(subId, request, packageName, delegateState,
+                    delegateMessage);
+        } catch (ImsException e) {
+            throw new ServiceSpecificException(e.getCode(), e.getMessage());
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public void destroySipDelegate(int subId, ISipDelegate connection, int reason) {
+        enforceModifyPermission();
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            SipTransportController transport = getRcsFeatureController(subId).getFeature(
+                    SipTransportController.class);
+            if (transport == null) {
+                return;
+            }
+            transport.destroySipDelegate(subId, connection, reason);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
     /**
      * Registers for updates to the RcsFeature connection through the IImsServiceFeatureCallback
      * callback.
diff --git a/src/com/android/phone/ImsUtil.java b/src/com/android/phone/ImsUtil.java
index 38936ec..0825cfb 100644
--- a/src/com/android/phone/ImsUtil.java
+++ b/src/com/android/phone/ImsUtil.java
@@ -25,6 +25,8 @@
 
 import com.android.ims.ImsConfig;
 import com.android.ims.ImsManager;
+import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.imsphone.ImsPhone;
 
 public class ImsUtil {
     private static final String LOG_TAG = ImsUtil.class.getSimpleName();
@@ -128,6 +130,13 @@
             return false;
         }
 
+        // Do not promote WFC if in roaming and WFC roaming not allowed.
+        // WFC roaming setting is not modifiable, so its value is decided by the default value
+        // chosen by the carrier, hence it really means if the carrier supports WFC roaming.
+        if (getLastKnownRoamingState(phoneId) && !imsManager.isWfcRoamingEnabledByUser()) {
+            return false;
+        }
+
         ConnectivityManager cm =
                 (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
         if (cm != null) {
@@ -152,4 +161,13 @@
         }
         return subId;
     }
+
+    private static boolean getLastKnownRoamingState(int phoneId) {
+        try {
+            ImsPhone imsPhone = (ImsPhone) (PhoneFactory.getPhone(phoneId).getImsPhone());
+            return imsPhone.getRoamingState();
+        } catch (NullPointerException | ClassCastException e) {
+            return false;
+        }
+    }
 }
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index c2dece5..fe4a0ba 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -536,7 +536,11 @@
                 int slotId = SubscriptionManager.getSlotIndex(subId);
                 resId = (slotId == 0) ? R.drawable.stat_sys_phone_call_forward_sub1
                         : R.drawable.stat_sys_phone_call_forward_sub2;
-                notificationTitle = subInfo.getDisplayName().toString();
+                if (subInfo.getDisplayName() != null) {
+                    notificationTitle = subInfo.getDisplayName().toString();
+                } else {
+                    notificationTitle = mContext.getString(R.string.labelCF);
+                }
             } else {
                 notificationTitle = mContext.getString(R.string.labelCF);
             }
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index a28130d..36ac63e 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -65,6 +65,7 @@
 import android.telecom.TelecomManager;
 import android.telephony.Annotation.ApnType;
 import android.telephony.CallForwardingInfo;
+import android.telephony.CarrierBandwidth;
 import android.telephony.CarrierConfigManager;
 import android.telephony.CarrierRestrictionRules;
 import android.telephony.CellIdentity;
@@ -130,6 +131,7 @@
 import com.android.internal.telephony.DefaultPhoneNotifier;
 import com.android.internal.telephony.HalVersion;
 import com.android.internal.telephony.IBooleanConsumer;
+import com.android.internal.telephony.ICallForwardingInfoCallback;
 import com.android.internal.telephony.IIntegerConsumer;
 import com.android.internal.telephony.INumberVerificationCallback;
 import com.android.internal.telephony.ITelephony;
@@ -170,6 +172,7 @@
 import com.android.internal.telephony.uicc.UiccSlot;
 import com.android.internal.telephony.util.LocaleUtils;
 import com.android.internal.telephony.util.VoicemailNotificationSettingsUtil;
+import com.android.internal.util.FunctionalUtils;
 import com.android.internal.util.HexDump;
 import com.android.phone.settings.PickSmsSubscriptionActivity;
 import com.android.phone.vvm.PhoneAccountHandleConverter;
@@ -287,6 +290,12 @@
     private static final int EVENT_GET_CALL_WAITING_DONE = 88;
     private static final int CMD_SET_CALL_WAITING = 89;
     private static final int EVENT_SET_CALL_WAITING_DONE = 90;
+    private static final int CMD_ENABLE_NR_DUAL_CONNECTIVITY = 91;
+    private static final int EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE = 92;
+    private static final int CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED = 93;
+    private static final int EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE = 94;
+    private static final int CMD_GET_CDMA_SUBSCRIPTION_MODE = 95;
+    private static final int EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE = 96;
 
     // Parameters of select command.
     private static final int SELECT_COMMAND = 0xA4;
@@ -749,6 +758,90 @@
                     handleNullReturnEvent(msg, "resetModemConfig");
                     break;
 
+                case CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED: {
+                    request = (MainThreadRequest) msg.obj;
+                    onCompleted = obtainMessage(EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE,
+                            request);
+                    Phone phone = getPhoneFromRequest(request);
+                    if (phone != null) {
+                        phone.isNrDualConnectivityEnabled(onCompleted, request.workSource);
+                    } else {
+                        loge("isNRDualConnectivityEnabled: No phone object");
+                        request.result = false;
+                        notifyRequester(request);
+                    }
+                    break;
+                }
+
+                case EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE:
+                    ar = (AsyncResult) msg.obj;
+                    request = (MainThreadRequest) ar.userObj;
+                    if (ar.exception == null && ar.result != null) {
+                        request.result = ar.result;
+                    } else {
+                        // request.result must be set to something non-null
+                        // for the calling thread to unblock
+                        if (request.result != null) {
+                            request.result = ar.result;
+                        } else {
+                            request.result = false;
+                        }
+                        if (ar.result == null) {
+                            loge("isNRDualConnectivityEnabled: Empty response");
+                        } else if (ar.exception instanceof CommandException) {
+                            loge("isNRDualConnectivityEnabled: CommandException: "
+                                    + ar.exception);
+                        } else {
+                            loge("isNRDualConnectivityEnabled: Unknown exception");
+                        }
+                    }
+                    notifyRequester(request);
+                    break;
+
+                case CMD_ENABLE_NR_DUAL_CONNECTIVITY: {
+                    request = (MainThreadRequest) msg.obj;
+                    onCompleted = obtainMessage(EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE, request);
+                    Phone phone = getPhoneFromRequest(request);
+                    if (phone != null) {
+                        phone.setNrDualConnectivityState((int) request.argument, onCompleted,
+                                request.workSource);
+                    } else {
+                        loge("enableNrDualConnectivity: No phone object");
+                        request.result =
+                                TelephonyManager.ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE;
+                        notifyRequester(request);
+                    }
+                    break;
+                }
+
+                case EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE: {
+                    ar = (AsyncResult) msg.obj;
+                    request = (MainThreadRequest) ar.userObj;
+                    if (ar.exception == null) {
+                        request.result =
+                                TelephonyManager.ENABLE_NR_DUAL_CONNECTIVITY_SUCCESS;
+                    } else {
+                        request.result =
+                                TelephonyManager
+                                        .ENABLE_NR_DUAL_CONNECTIVITY_RADIO_ERROR;
+                        if (ar.exception instanceof CommandException) {
+                            CommandException.Error error =
+                                    ((CommandException) (ar.exception)).getCommandError();
+                            if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
+                                request.result =
+                                        TelephonyManager
+                                                .ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE;
+                            }
+                            loge("enableNrDualConnectivity" + ": CommandException: "
+                                    + ar.exception);
+                        } else {
+                            loge("enableNrDualConnectivity" + ": Unknown exception");
+                        }
+                    }
+                    notifyRequester(request);
+                    break;
+                }
+
                 case CMD_GET_PREFERRED_NETWORK_TYPE:
                     request = (MainThreadRequest) msg.obj;
                     onCompleted = obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE_DONE, request);
@@ -829,38 +922,43 @@
                     getPhoneFromRequest(request).getAvailableNetworks(onCompleted);
                     break;
 
-                case CMD_GET_CALL_FORWARDING:
+                case CMD_GET_CALL_FORWARDING: {
                     request = (MainThreadRequest) msg.obj;
                     onCompleted = obtainMessage(EVENT_GET_CALL_FORWARDING_DONE, request);
-                    int callForwardingReason = (Integer) request.argument;
-                    getPhoneFromRequest(request).getCallForwardingOption(
-                            callForwardingReason, onCompleted);
+                    Pair<Integer, TelephonyManager.CallForwardingInfoCallback> args =
+                            (Pair<Integer, TelephonyManager.CallForwardingInfoCallback>)
+                                    request.argument;
+                    int callForwardingReason = args.first;
+                    request.phone.getCallForwardingOption(callForwardingReason, onCompleted);
                     break;
-
-                case EVENT_GET_CALL_FORWARDING_DONE:
+                }
+                case EVENT_GET_CALL_FORWARDING_DONE: {
                     ar = (AsyncResult) msg.obj;
                     request = (MainThreadRequest) ar.userObj;
-                    CallForwardingInfo callForwardingInfo = null;
+                    TelephonyManager.CallForwardingInfoCallback callback =
+                            ((Pair<Integer, TelephonyManager.CallForwardingInfoCallback>)
+                                    request.argument).second;
                     if (ar.exception == null && ar.result != null) {
+                        CallForwardingInfo callForwardingInfo = null;
                         CallForwardInfo[] callForwardInfos = (CallForwardInfo[]) ar.result;
                         for (CallForwardInfo callForwardInfo : callForwardInfos) {
                             // Service Class is a bit mask per 3gpp 27.007. Search for
                             // any service for voice call.
                             if ((callForwardInfo.serviceClass
                                     & CommandsInterface.SERVICE_CLASS_VOICE) > 0) {
-                                callForwardingInfo = new CallForwardingInfo(
-                                        callForwardInfo.serviceClass, callForwardInfo.reason,
-                                                callForwardInfo.number,
-                                                        callForwardInfo.timeSeconds);
+                                callForwardingInfo = new CallForwardingInfo(true,
+                                        callForwardInfo.reason,
+                                        callForwardInfo.number,
+                                        callForwardInfo.timeSeconds);
                                 break;
                             }
                         }
                         // Didn't find a call forward info for voice call.
                         if (callForwardingInfo == null) {
-                            callForwardingInfo = new CallForwardingInfo(
-                                    CallForwardingInfo.STATUS_UNKNOWN_ERROR,
-                                            0 /* reason */, null /* number */, 0 /* timeout */);
+                            callForwardingInfo = new CallForwardingInfo(false /* enabled */,
+                                    0 /* reason */, null /* number */, 0 /* timeout */);
                         }
+                        callback.onCallForwardingInfoAvailable(callForwardingInfo);
                     } else {
                         if (ar.result == null) {
                             loge("EVENT_GET_CALL_FORWARDING_DONE: Empty response");
@@ -868,56 +966,80 @@
                         if (ar.exception != null) {
                             loge("EVENT_GET_CALL_FORWARDING_DONE: Exception: " + ar.exception);
                         }
-                        int errorCode = CallForwardingInfo.STATUS_UNKNOWN_ERROR;
+                        int errorCode = TelephonyManager
+                                .CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN;
                         if (ar.exception instanceof CommandException) {
                             CommandException.Error error =
                                     ((CommandException) (ar.exception)).getCommandError();
                             if (error == CommandException.Error.FDN_CHECK_FAILURE) {
-                                errorCode = CallForwardingInfo.STATUS_FDN_CHECK_FAILURE;
+                                errorCode = TelephonyManager
+                                        .CallForwardingInfoCallback.RESULT_ERROR_FDN_CHECK_FAILURE;
                             } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
-                                errorCode = CallForwardingInfo.STATUS_NOT_SUPPORTED;
+                                errorCode = TelephonyManager
+                                        .CallForwardingInfoCallback.RESULT_ERROR_NOT_SUPPORTED;
                             }
                         }
-                        callForwardingInfo = new CallForwardingInfo(
-                                errorCode, 0 /* reason */, null /* number */, 0 /* timeout */);
+                        callback.onError(errorCode);
                     }
-                    request.result = callForwardingInfo;
-                    notifyRequester(request);
                     break;
+                }
 
-                case CMD_SET_CALL_FORWARDING:
+                case CMD_SET_CALL_FORWARDING: {
                     request = (MainThreadRequest) msg.obj;
                     onCompleted = obtainMessage(EVENT_SET_CALL_FORWARDING_DONE, request);
+                    request = (MainThreadRequest) msg.obj;
                     CallForwardingInfo callForwardingInfoToSet =
-                            (CallForwardingInfo) request.argument;
-                    getPhoneFromRequest(request).setCallForwardingOption(
-                            callForwardingInfoToSet.getStatus(),
+                            ((Pair<CallForwardingInfo, Consumer<Integer>>)
+                                    request.argument).first;
+                    request.phone.setCallForwardingOption(
+                            callForwardingInfoToSet.isEnabled()
+                                    ? CommandsInterface.CF_ACTION_ENABLE
+                                    : CommandsInterface.CF_ACTION_DISABLE,
                             callForwardingInfoToSet.getReason(),
                             callForwardingInfoToSet.getNumber(),
                             callForwardingInfoToSet.getTimeoutSeconds(), onCompleted);
                     break;
+                }
 
-                case EVENT_SET_CALL_FORWARDING_DONE:
+                case EVENT_SET_CALL_FORWARDING_DONE: {
                     ar = (AsyncResult) msg.obj;
                     request = (MainThreadRequest) ar.userObj;
-                    if (ar.exception == null) {
-                        request.result = true;
-                    } else {
-                        request.result = false;
+                    Consumer<Integer> callback =
+                            ((Pair<CallForwardingInfo, Consumer<Integer>>)
+                                    request.argument).second;
+                    if (ar.exception != null) {
                         loge("setCallForwarding exception: " + ar.exception);
+                        int errorCode = TelephonyManager.CallForwardingInfoCallback
+                                .RESULT_ERROR_UNKNOWN;
+                        if (ar.exception instanceof CommandException) {
+                            CommandException.Error error =
+                                    ((CommandException) (ar.exception)).getCommandError();
+                            if (error == CommandException.Error.FDN_CHECK_FAILURE) {
+                                errorCode = TelephonyManager.CallForwardingInfoCallback
+                                        .RESULT_ERROR_FDN_CHECK_FAILURE;
+                            } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
+                                errorCode = TelephonyManager.CallForwardingInfoCallback
+                                        .RESULT_ERROR_NOT_SUPPORTED;
+                            }
+                        }
+                        callback.accept(errorCode);
+                    } else {
+                        callback.accept(TelephonyManager.CallForwardingInfoCallback.RESULT_SUCCESS);
                     }
-                    notifyRequester(request);
                     break;
+                }
 
-                case CMD_GET_CALL_WAITING:
+                case CMD_GET_CALL_WAITING: {
                     request = (MainThreadRequest) msg.obj;
                     onCompleted = obtainMessage(EVENT_GET_CALL_WAITING_DONE, request);
                     getPhoneFromRequest(request).getCallWaiting(onCompleted);
                     break;
+                }
 
-                case EVENT_GET_CALL_WAITING_DONE:
+                case EVENT_GET_CALL_WAITING_DONE: {
                     ar = (AsyncResult) msg.obj;
                     request = (MainThreadRequest) ar.userObj;
+                    Consumer<Integer> callback = (Consumer<Integer>) request.argument;
                     int callForwardingStatus = TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR;
                     if (ar.exception == null && ar.result != null) {
                         int[] callForwardResults = (int[]) ar.result;
@@ -925,12 +1047,12 @@
                         // Search for any service for voice call.
                         if (callForwardResults.length > 1
                                 && ((callForwardResults[1]
-                                        & CommandsInterface.SERVICE_CLASS_VOICE) > 0)) {
+                                & CommandsInterface.SERVICE_CLASS_VOICE) > 0)) {
                             callForwardingStatus = callForwardResults[0] == 0
-                                    ? TelephonyManager.CALL_WAITING_STATUS_INACTIVE
-                                            : TelephonyManager.CALL_WAITING_STATUS_ACTIVE;
+                                    ? TelephonyManager.CALL_WAITING_STATUS_DISABLED
+                                    : TelephonyManager.CALL_WAITING_STATUS_ENABLED;
                         } else {
-                            callForwardingStatus = TelephonyManager.CALL_WAITING_STATUS_INACTIVE;
+                            callForwardingStatus = TelephonyManager.CALL_WAITING_STATUS_DISABLED;
                         }
                     } else {
                         if (ar.result == null) {
@@ -948,28 +1070,43 @@
                             }
                         }
                     }
-                    request.result = callForwardingStatus;
-                    notifyRequester(request);
+                    callback.accept(callForwardingStatus);
                     break;
+                }
 
-                case CMD_SET_CALL_WAITING:
+                case CMD_SET_CALL_WAITING: {
                     request = (MainThreadRequest) msg.obj;
                     onCompleted = obtainMessage(EVENT_SET_CALL_WAITING_DONE, request);
-                    boolean isEnable = (Boolean) request.argument;
-                    getPhoneFromRequest(request).setCallWaiting(isEnable, onCompleted);
+                    boolean enable = ((Pair<Boolean, Consumer<Integer>>) request.argument).first;
+                    getPhoneFromRequest(request).setCallWaiting(enable, onCompleted);
                     break;
+                }
 
-                case EVENT_SET_CALL_WAITING_DONE:
+                case EVENT_SET_CALL_WAITING_DONE: {
                     ar = (AsyncResult) msg.obj;
                     request = (MainThreadRequest) ar.userObj;
-                    if (ar.exception == null) {
-                        request.result = true;
-                    } else {
-                        request.result = false;
+                    boolean enable = ((Pair<Boolean, Consumer<Integer>>) request.argument).first;
+                    Consumer<Integer> callback =
+                            ((Pair<Boolean, Consumer<Integer>>) request.argument).second;
+                    if (ar.exception != null) {
                         loge("setCallWaiting exception: " + ar.exception);
+                        if (ar.exception instanceof CommandException) {
+                            CommandException.Error error =
+                                    ((CommandException) (ar.exception)).getCommandError();
+                            if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
+                                callback.accept(TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED);
+                            } else {
+                                callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
+                            }
+                        } else {
+                            callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
+                        }
+                    } else {
+                        callback.accept(enable ? TelephonyManager.CALL_WAITING_STATUS_ENABLED
+                                : TelephonyManager.CALL_WAITING_STATUS_DISABLED);
                     }
-                    notifyRequester(request);
                     break;
+                }
 
                 case EVENT_PERFORM_NETWORK_SCAN_DONE:
                     ar = (AsyncResult) msg.obj;
@@ -1248,11 +1385,27 @@
                     request.result = ar.exception == null;
                     notifyRequester(request);
                     break;
+                case CMD_GET_CDMA_SUBSCRIPTION_MODE:
+                    request = (MainThreadRequest) msg.obj;
+                    onCompleted = obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE, request);
+                    getPhoneFromRequest(request).queryCdmaSubscriptionMode(onCompleted);
+                    break;
+                case EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE:
+                    ar = (AsyncResult) msg.obj;
+                    request = (MainThreadRequest) ar.userObj;
+                    if (ar.exception != null) {
+                        request.result = TelephonyManager.CDMA_SUBSCRIPTION_RUIM_SIM;
+                    } else {
+                        request.result = ((int[]) ar.result)[0];
+                    }
+                    notifyRequester(request);
+                    break;
                 case CMD_SET_CDMA_SUBSCRIPTION_MODE:
                     request = (MainThreadRequest) msg.obj;
                     onCompleted = obtainMessage(EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE, request);
                     int subscriptionMode = (int) request.argument;
-                    getPhoneFromRequest(request).setCdmaSubscription(subscriptionMode, onCompleted);
+                    getPhoneFromRequest(request).setCdmaSubscriptionMode(
+                            subscriptionMode, onCompleted);
                     break;
                 case EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE:
                     ar = (AsyncResult) msg.obj;
@@ -2174,7 +2327,8 @@
             int subId = mSubscriptionController.getDefaultDataSubId();
             final Phone phone = getPhone(subId);
             if (phone != null) {
-                phone.getDataEnabledSettings().setUserDataEnabled(true);
+                phone.getDataEnabledSettings().setDataEnabled(
+                        TelephonyManager.DATA_ENABLED_REASON_USER, true);
                 return true;
             } else {
                 return false;
@@ -2194,7 +2348,8 @@
             int subId = mSubscriptionController.getDefaultDataSubId();
             final Phone phone = getPhone(subId);
             if (phone != null) {
-                phone.getDataEnabledSettings().setUserDataEnabled(false);
+                phone.getDataEnabledSettings().setDataEnabled(
+                        TelephonyManager.DATA_ENABLED_REASON_USER, false);
                 return true;
             } else {
                 return false;
@@ -5116,6 +5271,36 @@
     }
 
     /**
+     * Clears any carrier ImsService overrides for the slot index specified that were previously
+     * set with {@link #setBoundImsServiceOverride(int, boolean, int[], String)}.
+     *
+     * This should only be used for testing.
+     *
+     * @param slotIndex the slot ID that the ImsService should bind for.
+     * @return true if clearing the carrier ImsService override succeeded or false if it did not.
+     */
+    @Override
+    public boolean clearCarrierImsServiceOverride(int slotIndex) {
+        int[] subIds = SubscriptionManager.getSubId(slotIndex);
+        TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
+                "clearCarrierImsServiceOverride");
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
+                (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
+                "clearCarrierImsServiceOverride");
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            if (mImsResolver == null) {
+                // may happen if the device does not support IMS.
+                return false;
+            }
+            return mImsResolver.clearCarrierImsServiceConfiguration(slotIndex);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    /**
      * Return the package name of the currently bound ImsService.
      *
      * @param slotId The slot that the ImsService is associated with.
@@ -5316,7 +5501,8 @@
      * Get the call forwarding info, given the call forwarding reason.
      */
     @Override
-    public CallForwardingInfo getCallForwarding(int subId, int callForwardingReason) {
+    public void getCallForwarding(int subId, int callForwardingReason,
+            ICallForwardingInfoCallback callback) {
         enforceReadPrivilegedPermission("getCallForwarding");
         long identity = Binder.clearCallingIdentity();
         try {
@@ -5324,8 +5510,39 @@
                 log("getCallForwarding: subId " + subId
                         + " callForwardingReason" + callForwardingReason);
             }
-            return (CallForwardingInfo) sendRequest(
-                    CMD_GET_CALL_FORWARDING, callForwardingReason, subId);
+
+            Phone phone = getPhone(subId);
+            if (phone == null) {
+                try {
+                    callback.onError(
+                            TelephonyManager.CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN);
+                } catch (RemoteException e) {
+                    // ignore
+                }
+                return;
+            }
+
+            Pair<Integer, TelephonyManager.CallForwardingInfoCallback> argument = Pair.create(
+                    callForwardingReason, new TelephonyManager.CallForwardingInfoCallback() {
+                        @Override
+                        public void onCallForwardingInfoAvailable(CallForwardingInfo info) {
+                            try {
+                                callback.onCallForwardingInfoAvailable(info);
+                            } catch (RemoteException e) {
+                                // ignore
+                            }
+                        }
+
+                        @Override
+                        public void onError(int error) {
+                            try {
+                                callback.onError(error);
+                            } catch (RemoteException e) {
+                                // ignore
+                            }
+                        }
+                    });
+            sendRequestAsync(CMD_GET_CALL_FORWARDING, argument, phone, null);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -5336,7 +5553,8 @@
      * reason, the number to forward, and the timeout before the forwarding is attempted.
      */
     @Override
-    public boolean setCallForwarding(int subId, CallForwardingInfo callForwardingInfo) {
+    public void setCallForwarding(int subId, CallForwardingInfo callForwardingInfo,
+            IIntegerConsumer callback) {
         enforceModifyPermission();
         long identity = Binder.clearCallingIdentity();
         try {
@@ -5344,38 +5562,79 @@
                 log("setCallForwarding: subId " + subId
                         + " callForwardingInfo" + callForwardingInfo);
             }
-            return (Boolean) sendRequest(CMD_SET_CALL_FORWARDING, callForwardingInfo, subId);
+
+            Phone phone = getPhone(subId);
+            if (phone == null) {
+                try {
+                    callback.accept(
+                            TelephonyManager.CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN);
+                } catch (RemoteException e) {
+                    // ignore
+                }
+                return;
+            }
+
+            Pair<CallForwardingInfo, Consumer<Integer>> arguments = Pair.create(callForwardingInfo,
+                    FunctionalUtils.ignoreRemoteException(callback::accept));
+
+            sendRequestAsync(CMD_SET_CALL_FORWARDING, arguments, phone, null);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
     }
 
     /**
-     * Get the call forwarding info, given the call forwarding reason.
+     * Get the call waiting status for a subId.
      */
     @Override
-    public int getCallWaitingStatus(int subId) {
+    public void getCallWaitingStatus(int subId, IIntegerConsumer callback) {
         enforceReadPrivilegedPermission("getCallForwarding");
         long identity = Binder.clearCallingIdentity();
         try {
+
+            Phone phone = getPhone(subId);
+            if (phone == null) {
+                try {
+                    callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
+                } catch (RemoteException e) {
+                    // ignore
+                }
+                return;
+            }
+
+            Consumer<Integer> argument = FunctionalUtils.ignoreRemoteException(callback::accept);
+
             if (DBG) log("getCallWaitingStatus: subId " + subId);
-            return (Integer) sendRequest(CMD_GET_CALL_WAITING, null, subId);
+            sendRequestAsync(CMD_GET_CALL_WAITING, argument, phone, null);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
     }
 
     /**
-     * Sets the voice call forwarding info including status (enable/disable), call forwarding
-     * reason, the number to forward, and the timeout before the forwarding is attempted.
+     * Sets whether call waiting is enabled for a given subId.
      */
     @Override
-    public boolean setCallWaitingStatus(int subId, boolean isEnable) {
+    public void setCallWaitingStatus(int subId, boolean enable, IIntegerConsumer callback) {
         enforceModifyPermission();
         long identity = Binder.clearCallingIdentity();
         try {
-            if (DBG) log("setCallWaitingStatus: subId " + subId + " isEnable: " + isEnable);
-            return (Boolean) sendRequest(CMD_SET_CALL_WAITING, isEnable, subId);
+            if (DBG) log("setCallWaitingStatus: subId " + subId + " enable: " + enable);
+
+            Phone phone = getPhone(subId);
+            if (phone == null) {
+                try {
+                    callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
+                } catch (RemoteException e) {
+                    // ignore
+                }
+                return;
+            }
+
+            Pair<Boolean, Consumer<Integer>> arguments = Pair.create(enable,
+                    FunctionalUtils.ignoreRemoteException(callback::accept));
+
+            sendRequestAsync(CMD_SET_CALL_WAITING, arguments, phone, null);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -5406,7 +5665,8 @@
                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
                                 .build());
         if (locationResult != LocationAccessPolicy.LocationPermissionResult.ALLOWED) {
-            SecurityException e = checkNetworkRequestForSanitizedLocationAccess(request, subId);
+            SecurityException e = checkNetworkRequestForSanitizedLocationAccess(
+                    request, subId, callingPackage);
             if (e != null) {
                 if (locationResult == LocationAccessPolicy.LocationPermissionResult.DENIED_HARD) {
                     throw e;
@@ -5429,8 +5689,8 @@
     }
 
     private SecurityException checkNetworkRequestForSanitizedLocationAccess(
-            NetworkScanRequest request, int subId) {
-        boolean hasCarrierPriv = getCarrierPrivilegeStatusForUid(subId, Binder.getCallingUid())
+            NetworkScanRequest request, int subId, String callingPackage) {
+        boolean hasCarrierPriv = checkCarrierPrivilegesForPackage(subId, callingPackage)
                 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
         boolean hasNetworkScanPermission =
                 mApp.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_SCAN)
@@ -5610,6 +5870,80 @@
     }
 
     /**
+     * Enable/Disable E-UTRA-NR Dual Connectivity
+     * @param subId subscription id of the sim card
+     * @param nrDualConnectivityState expected NR dual connectivity state
+     * This can be passed following states
+     * <ol>
+     * <li>Enable NR dual connectivity {@link TelephonyManager#NR_DUAL_CONNECTIVITY_ENABLE}
+     * <li>Disable NR dual connectivity {@link TelephonyManager#NR_DUAL_CONNECTIVITY_DISABLE}
+     * <li>Disable NR dual connectivity and force secondary cell to be released
+     * {@link TelephonyManager#NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE}
+     * </ol>
+     * @return operation result.
+     */
+    @Override
+    public int setNrDualConnectivityState(int subId,
+            @TelephonyManager.NrDualConnectivityState int nrDualConnectivityState) {
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "enableNRDualConnectivity");
+        WorkSource workSource = getWorkSource(Binder.getCallingUid());
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            int result = (int) sendRequest(CMD_ENABLE_NR_DUAL_CONNECTIVITY,
+                    nrDualConnectivityState, subId,
+                    workSource);
+            if (DBG) log("enableNRDualConnectivity result: " + result);
+            return result;
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    /**
+     * Is E-UTRA-NR Dual Connectivity enabled
+     * @return true if dual connectivity is enabled else false
+     */
+    @Override
+    public boolean isNrDualConnectivityEnabled(int subId) {
+        TelephonyPermissions
+                .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
+                        mApp, subId, "isNRDualConnectivityEnabled");
+        WorkSource workSource = getWorkSource(Binder.getCallingUid());
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            boolean isEnabled = (boolean) sendRequest(CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED,
+                    null, subId, workSource);
+            if (DBG) log("isNRDualConnectivityEnabled: " + isEnabled);
+            return isEnabled;
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    /**
+     * get carrier bandwidth per primary and secondary carrier
+     * @param subId subscription id of the sim card
+     * @return CarrierBandwidth with bandwidth of both primary and secondary carrier..
+     */
+    @Override
+    public CarrierBandwidth getCarrierBandwidth(int subId) {
+        TelephonyPermissions
+                .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
+                        mApp, subId, "isNRDualConnectivityEnabled");
+        WorkSource workSource = getWorkSource(Binder.getCallingUid());
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            CarrierBandwidth carrierBandwidth =
+                    getPhoneFromSubId(subId).getCarrierBandwidth();
+            if (DBG) log("getCarrierBandwidth: " + carrierBandwidth);
+            return carrierBandwidth;
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    /**
      * Get the effective allowed network types on the device.
      * This API will return an intersection of allowed network types for all reasons,
      * including the configuration done through setAllowedNetworkTypes
@@ -5680,33 +6014,6 @@
     }
 
     /**
-     * Set mobile data enabled
-     * Used by the user through settings etc to turn on/off mobile data
-     *
-     * @param enable {@code true} turn turn data on, else {@code false}
-     */
-    @Override
-    public void setUserDataEnabled(int subId, boolean enable) {
-        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
-                mApp, subId, "setUserDataEnabled");
-
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            int phoneId = mSubscriptionController.getPhoneId(subId);
-            if (DBG) log("setUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
-            Phone phone = PhoneFactory.getPhone(phoneId);
-            if (phone != null) {
-                if (DBG) log("setUserDataEnabled: subId=" + subId + " enable=" + enable);
-                phone.getDataEnabledSettings().setUserDataEnabled(enable);
-            } else {
-                loge("setUserDataEnabled: no phone found. Invalid subId=" + subId);
-            }
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    /**
      * Enable or disable always reporting signal strength changes from radio.
      *
      * @param isEnable {@code true} for enabling; {@code false} for disabling.
@@ -5796,7 +6103,18 @@
      */
     @Override
     public boolean isDataEnabled(int subId) {
-        enforceReadPrivilegedPermission("isDataEnabled");
+        try {
+            try {
+                mApp.enforceCallingOrSelfPermission(
+                        android.Manifest.permission.ACCESS_NETWORK_STATE,
+                        null);
+            } catch (Exception e) {
+                mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE,
+                        "isDataEnabled");
+            }
+        } catch (Exception e) {
+            enforceReadPrivilegedPermission("isDataEnabled");
+        }
 
         final long identity = Binder.clearCallingIdentity();
         try {
@@ -5816,6 +6134,53 @@
         }
     }
 
+    /**
+     * Check if data is enabled for a specific reason
+     * @param subId Subscription index
+     * @param reason the reason the data enable change is taking place
+     * @return {@code true} if the overall data is enabled; {@code false} if not.
+     */
+    @Override
+    public boolean isDataEnabledForReason(int subId,
+            @TelephonyManager.DataEnabledReason int reason) {
+        try {
+            mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
+                    null);
+        } catch (Exception e) {
+            mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE,
+                    "isDataEnabledForReason");
+        }
+
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            int phoneId = mSubscriptionController.getPhoneId(subId);
+            if (DBG) {
+                log("isDataEnabledForReason: subId=" + subId + " phoneId=" + phoneId
+                        + " reason=" + reason);
+            }
+            Phone phone = PhoneFactory.getPhone(phoneId);
+            if (phone != null) {
+                boolean retVal;
+                if (reason == TelephonyManager.DATA_ENABLED_REASON_USER) {
+                    retVal = phone.isUserDataEnabled();
+                } else {
+                    retVal = phone.getDataEnabledSettings().isDataEnabledForReason(reason);
+                }
+                if (DBG) log("isDataEnabledForReason: retVal=" + retVal);
+                return retVal;
+            } else {
+                if (DBG) {
+                    loge("isDataEnabledForReason: no phone subId="
+                            + subId + " retVal=false");
+                }
+                return false;
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
     private int getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim, int uid,
             Phone phone) {
         if (uid == Process.SYSTEM_UID || uid == Process.PHONE_UID) {
@@ -6020,12 +6385,10 @@
         final Phone phone = getPhone(subId);
         UiccCard card = phone == null ? null : phone.getUiccCard();
         if (card == null) {
-            loge("getIccId: No UICC");
             return null;
         }
         String iccId = card.getIccId();
         if (TextUtils.isEmpty(iccId)) {
-            loge("getIccId: ICC ID is null or empty.");
             return null;
         }
         return iccId;
@@ -6644,7 +7007,8 @@
         try {
             if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction(
                     UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
-                setUserDataEnabled(subId, getDefaultDataEnabled());
+                setDataEnabledForReason(subId, TelephonyManager.DATA_ENABLED_REASON_USER,
+                        getDefaultDataEnabled());
                 setNetworkSelectionModeAutomatic(subId);
                 setPreferredNetworkType(subId, getDefaultNetworkType(subId));
                 setDataRoamingEnabled(subId, getDefaultDataRoamingEnabled(subId));
@@ -7164,31 +7528,6 @@
     }
 
     /**
-     * Action set from carrier signalling broadcast receivers to enable/disable metered apns
-     * @param subId the subscription ID that this action applies to.
-     * @param enabled control enable or disable metered apns.
-     * {@hide}
-     */
-    @Override
-    public void carrierActionSetMeteredApnsEnabled(int subId, boolean enabled) {
-        enforceModifyPermission();
-        final Phone phone = getPhone(subId);
-
-        final long identity = Binder.clearCallingIdentity();
-        if (phone == null) {
-            loge("carrierAction: SetMeteredApnsEnabled fails with invalid subId: " + subId);
-            return;
-        }
-        try {
-            phone.carrierActionSetMeteredApnsEnabled(enabled);
-        } catch (Exception e) {
-            Log.e(LOG_TAG, "carrierAction: SetMeteredApnsEnabled fails. Exception ex=" + e);
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    /**
      * Action set from carrier signalling broadcast receivers to enable/disable radio
      * @param subId the subscription ID that this action applies to.
      * @param enabled control enable or disable radio.
@@ -7289,20 +7628,36 @@
     }
 
     /**
-     * Policy control of data connection. Usually used when data limit is passed.
-     * @param enabled True if enabling the data, otherwise disabling.
+     * Policy control of data connection with reason {@@TelephonyManager.DataEnabledReason}
      * @param subId Subscription index
-     * {@hide}
+     * @param reason the reason the data enable change is taking place
+     * @param enabled True if enabling the data, otherwise disabling.
+     * @hide
      */
     @Override
-    public void setPolicyDataEnabled(boolean enabled, int subId) {
-        enforceModifyPermission();
+    public void setDataEnabledForReason(int subId, @TelephonyManager.DataEnabledReason int reason,
+            boolean enabled) {
+        if (reason == TelephonyManager.DATA_ENABLED_REASON_USER
+                || reason == TelephonyManager.DATA_ENABLED_REASON_CARRIER) {
+            try {
+                TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
+                        mApp, subId, "setDataEnabledForReason");
+            } catch (SecurityException se) {
+                enforceModifyPermission();
+            }
+        } else {
+            enforceModifyPermission();
+        }
 
         final long identity = Binder.clearCallingIdentity();
         try {
             Phone phone = getPhone(subId);
             if (phone != null) {
-                phone.getDataEnabledSettings().setPolicyDataEnabled(enabled);
+                if (reason == TelephonyManager.DATA_ENABLED_REASON_CARRIER) {
+                    phone.carrierActionSetMeteredApnsEnabled(enabled);
+                } else {
+                    phone.getDataEnabledSettings().setDataEnabled(reason, enabled);
+                }
             }
         } finally {
             Binder.restoreCallingIdentity(identity);
@@ -7825,6 +8180,20 @@
     }
 
     @Override
+    public int getCdmaSubscriptionMode(int subId) {
+        TelephonyPermissions
+                .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
+                        mApp, subId, "getCdmaSubscriptionMode");
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            return (int) sendRequest(CMD_GET_CDMA_SUBSCRIPTION_MODE, null /* argument */, subId);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
     public boolean setCdmaSubscriptionMode(int subId, int mode) {
         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
                 mApp, subId, "setCdmaSubscriptionMode");
@@ -8257,7 +8626,7 @@
      *  1) user data is turned on, or
      *  2) APN is un-metered for this subscription, or
      *  3) APN type is whitelisted. E.g. MMS is whitelisted if
-     *  {@link TelephonyManager#setAlwaysAllowMmsData} is turned on.
+     *  {@link TelephonyManager#MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED} is enabled.
      *
      * @return whether data is allowed for a apn type.
      *
@@ -8399,55 +8768,54 @@
     }
 
     @Override
-    public boolean setDataAllowedDuringVoiceCall(int subId, boolean allow) {
-        enforceModifyPermission();
+    public boolean isMobileDataPolicyEnabled(int subscriptionId, int policy) {
+        enforceReadPrivilegedPermission("isMobileDataPolicyEnabled");
 
-        // Now that all security checks passes, perform the operation as ourselves.
         final long identity = Binder.clearCallingIdentity();
         try {
-            Phone phone = getPhone(subId);
+            Phone phone = getPhone(subscriptionId);
             if (phone == null) return false;
 
-            return phone.getDataEnabledSettings().setAllowDataDuringVoiceCall(allow);
+            switch (policy) {
+                case TelephonyManager.MOBILE_DATA_POLICY_DATA_ON_NON_DEFAULT_DURING_VOICE_CALL:
+                    return phone.getDataEnabledSettings().isDataAllowedInVoiceCall();
+                case TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED:
+                    return phone.getDataEnabledSettings().isMmsAlwaysAllowed();
+                default:
+                    throw new IllegalArgumentException(policy + " is not a valid policy");
+            }
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
     }
 
     @Override
-    public boolean isDataAllowedInVoiceCall(int subId) {
-        enforceReadPrivilegedPermission("isDataAllowedInVoiceCall");
-
-        // Now that all security checks passes, perform the operation as ourselves.
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            Phone phone = getPhone(subId);
-            if (phone == null) return false;
-
-            return phone.getDataEnabledSettings().isDataAllowedInVoiceCall();
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    @Override
-    public boolean setAlwaysAllowMmsData(int subId, boolean alwaysAllow) {
+    public void setMobileDataPolicyEnabledStatus(int subscriptionId, int policy,
+            boolean enabled) {
         enforceModifyPermission();
 
-        // Now that all security checks passes, perform the operation as ourselves.
         final long identity = Binder.clearCallingIdentity();
         try {
-            Phone phone = getPhone(subId);
-            if (phone == null) return false;
+            Phone phone = getPhone(subscriptionId);
+            if (phone == null) return;
 
-            return phone.getDataEnabledSettings().setAlwaysAllowMmsData(alwaysAllow);
+            switch (policy) {
+                case TelephonyManager.MOBILE_DATA_POLICY_DATA_ON_NON_DEFAULT_DURING_VOICE_CALL:
+                    phone.getDataEnabledSettings().setAllowDataDuringVoiceCall(enabled);
+                    break;
+                case TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED:
+                    phone.getDataEnabledSettings().setAlwaysAllowMmsData(enabled);
+                    break;
+                default:
+                    throw new IllegalArgumentException(policy + " is not a valid policy");
+            }
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
     }
 
     /**
-     * Updates whether conference event pacakge handling is enabled.
+     * Updates whether conference event package handling is enabled.
      * @param isCepEnabled {@code true} if CEP handling is enabled (default), or {@code false}
      *                                 otherwise.
      */
diff --git a/src/com/android/phone/TelephonyShellCommand.java b/src/com/android/phone/TelephonyShellCommand.java
index c3f2974..33d0721 100644
--- a/src/com/android/phone/TelephonyShellCommand.java
+++ b/src/com/android/phone/TelephonyShellCommand.java
@@ -17,7 +17,6 @@
 package com.android.phone;
 
 import android.content.Context;
-import android.os.BasicShellCommandHandler;
 import android.os.Binder;
 import android.os.PersistableBundle;
 import android.os.Process;
@@ -34,6 +33,7 @@
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
 import com.android.internal.telephony.util.TelephonyUtils;
+import com.android.modules.utils.BasicShellCommandHandler;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -64,8 +64,9 @@
     private static final String DATA_ENABLE = "enable";
     private static final String DATA_DISABLE = "disable";
 
-    private static final String IMS_SET_CARRIER_SERVICE = "set-ims-service";
-    private static final String IMS_GET_CARRIER_SERVICE = "get-ims-service";
+    private static final String IMS_SET_IMS_SERVICE = "set-ims-service";
+    private static final String IMS_GET_IMS_SERVICE = "get-ims-service";
+    private static final String IMS_CLEAR_SERVICE_OVERRIDE = "clear-ims-service-override";
     private static final String IMS_ENABLE = "enable";
     private static final String IMS_DISABLE = "disable";
     // Used to disable or enable processing of conference event package data from the network.
@@ -210,6 +211,11 @@
         pw.println("      -d: The ImsService defined as the device default ImsService.");
         pw.println("      -f: The feature type that the query will be requested for. If none is");
         pw.println("          specified, the returned package name will correspond to MMTEL.");
+        pw.println("  ims clear-ims-service-override [-s SLOT_ID]");
+        pw.println("    Clear all carrier ImsService overrides. This does not work for device ");
+        pw.println("    configuration overrides. Options are:");
+        pw.println("      -s: The SIM slot ID for the registered ImsService. If no option");
+        pw.println("          is specified, it will choose the default voice SIM slot.");
         pw.println("  ims enable [-s SLOT_ID]");
         pw.println("    enables IMS for the SIM slot specified, or for the default voice SIM slot");
         pw.println("    if none is specified.");
@@ -295,12 +301,15 @@
         }
 
         switch (arg) {
-            case IMS_SET_CARRIER_SERVICE: {
+            case IMS_SET_IMS_SERVICE: {
                 return handleImsSetServiceCommand();
             }
-            case IMS_GET_CARRIER_SERVICE: {
+            case IMS_GET_IMS_SERVICE: {
                 return handleImsGetServiceCommand();
             }
+            case IMS_CLEAR_SERVICE_OVERRIDE: {
+                return handleImsClearCarrierServiceCommand();
+            }
             case IMS_ENABLE: {
                 return handleEnableIms();
             }
@@ -547,6 +556,42 @@
         return 0;
     }
 
+    // ims clear-ims-service-override
+    private int handleImsClearCarrierServiceCommand() {
+        PrintWriter errPw = getErrPrintWriter();
+        int slotId = getDefaultSlot();
+
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            switch (opt) {
+                case "-s": {
+                    try {
+                        slotId = Integer.parseInt(getNextArgRequired());
+                    } catch (NumberFormatException e) {
+                        errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
+                        return -1;
+                    }
+                    break;
+                }
+            }
+        }
+
+        try {
+            boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
+            if (VDBG) {
+                Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
+                        + ", result=" + result);
+            }
+            getOutPrintWriter().println(result);
+        } catch (RemoteException e) {
+            Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
+                    + ", error" + e.getMessage());
+            errPw.println("Exception: " + e.getMessage());
+            return -1;
+        }
+        return 0;
+    }
+
     // ims get-ims-service
     private int handleImsGetServiceCommand() {
         PrintWriter errPw = getErrPrintWriter();
diff --git a/src/com/android/services/telephony/ImsConference.java b/src/com/android/services/telephony/ImsConference.java
index 4826ecb..c9f762b 100644
--- a/src/com/android/services/telephony/ImsConference.java
+++ b/src/com/android/services/telephony/ImsConference.java
@@ -16,6 +16,7 @@
 
 package com.android.services.telephony;
 
+import android.annotation.NonNull;
 import android.content.Context;
 import android.graphics.drawable.Icon;
 import android.net.Uri;
@@ -28,6 +29,7 @@
 import android.telecom.TelecomManager;
 import android.telecom.VideoProfile;
 import android.telephony.PhoneNumberUtils;
+import android.text.TextUtils;
 import android.util.Pair;
 
 import com.android.ims.internal.ConferenceParticipant;
@@ -1269,58 +1271,79 @@
     }
 
     /**
+     * Extracts a phone number from a {@link Uri}.
+     * <p>
+     * Phone numbers can be represented either as a TEL URI or a SIP URI.
+     * For conference event packages, RFC3261 specifies how participants can be identified using a
+     * SIP URI.
+     * A valid SIP uri has the format: sip:user:password@host:port;uri-parameters?headers
+     * Per RFC3261, the "user" can be a telephone number.
+     * For example: sip:1650555121;phone-context=blah.com@host.com
+     * In this case, the phone number is in the user field of the URI, and the parameters can be
+     * ignored.
+     *
+     * A SIP URI can also specify a phone number in a format similar to:
+     * sip:+1-212-555-1212@something.com;user=phone
+     * In this case, the phone number is again in user field and the parameters can be ignored.
+     * We can get the user field in these instances by splitting the string on the @, ;, or :
+     * and looking at the first found item.
+     * @param handle The URI containing a SIP or TEL formatted phone number.
+     * @return extracted phone number.
+     */
+    private static @NonNull String extractPhoneNumber(@NonNull Uri handle) {
+        // Number is always in the scheme specific part, regardless of whether this is a TEL or SIP
+        // URI.
+        String number = handle.getSchemeSpecificPart();
+        // Get anything before the @ for the SIP case.
+        String[] numberParts = number.split("[@;:]");
+
+        if (numberParts.length == 0) {
+            Log.v(LOG_TAG, "extractPhoneNumber(N) : no number in handle");
+            return "";
+        }
+        return numberParts[0];
+    }
+
+    /**
      * Determines if the passed in participant handle is the same as the conference host's handle.
      * Starts with a simple equality check.  However, the handles from a conference event package
      * will be a SIP uri, so we need to pull that apart to look for the participant's phone number.
      *
-     * @param hostHandles The handle(s) of the connection hosting the conference.
+     * @param hostHandles The handle(s) of the connection hosting the conference, typically obtained
+     *                    from P-Associated-Uri entries.
      * @param handle The handle of the conference participant.
      * @return {@code true} if the host's handle matches the participant's handle, {@code false}
      *      otherwise.
      */
-    private boolean isParticipantHost(Uri[] hostHandles, Uri handle) {
+    @VisibleForTesting
+    public static boolean isParticipantHost(Uri[] hostHandles, Uri handle) {
         // If there is no host handle or no participant handle, bail early.
         if (hostHandles == null || hostHandles.length == 0 || handle == null) {
-            Log.v(this, "isParticipantHost(N) : host or participant uri null");
+            Log.v(LOG_TAG, "isParticipantHost(N) : host or participant uri null");
             return false;
         }
 
-        // Conference event package participants are identified using SIP URIs (see RFC3261).
-        // A valid SIP uri has the format: sip:user:password@host:port;uri-parameters?headers
-        // Per RFC3261, the "user" can be a telephone number.
-        // For example: sip:1650555121;phone-context=blah.com@host.com
-        // In this case, the phone number is in the user field of the URI, and the parameters can be
-        // ignored.
-        //
-        // A SIP URI can also specify a phone number in a format similar to:
-        // sip:+1-212-555-1212@something.com;user=phone
-        // In this case, the phone number is again in user field and the parameters can be ignored.
-        // We can get the user field in these instances by splitting the string on the @, ;, or :
-        // and looking at the first found item.
-
-        String number = handle.getSchemeSpecificPart();
-        String numberParts[] = number.split("[@;:]");
-
-        if (numberParts.length == 0) {
-            Log.v(this, "isParticipantHost(N) : no number in participant handle");
+        String number = extractPhoneNumber(handle);
+        // If we couldn't extract the participant's number, then we can't determine if it is the
+        // host or not.
+        if (TextUtils.isEmpty(number)) {
             return false;
         }
-        number = numberParts[0];
 
         for (Uri hostHandle : hostHandles) {
             if (hostHandle == null) {
                 continue;
             }
-            // The host number will be a tel: uri.  Per RFC3966, the part after tel: is the phone
-            // number.
-            String hostNumber = hostHandle.getSchemeSpecificPart();
+            // Similar to the CEP participant data, the host identity in the P-Associated-Uri could
+            // be a SIP URI or a TEL URI.
+            String hostNumber = extractPhoneNumber(hostHandle);
 
             // Use a loose comparison of the phone numbers.  This ensures that numbers that differ
             // by special characters are counted as equal.
             // E.g. +16505551212 would be the same as 16505551212
             boolean isHost = PhoneNumberUtils.compare(hostNumber, number);
 
-            Log.v(this, "isParticipantHost(%s) : host: %s, participant %s", (isHost ? "Y" : "N"),
+            Log.v(LOG_TAG, "isParticipantHost(%s) : host: %s, participant %s", (isHost ? "Y" : "N"),
                     Rlog.pii(LOG_TAG, hostNumber), Rlog.pii(LOG_TAG, number));
 
             if (isHost) {
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index 46c245a..0e7c8ed 100644
--- a/src/com/android/services/telephony/TelecomAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecomAccountRegistry.java
@@ -428,8 +428,7 @@
                             .getBoolean(R.bool.config_support_video_calling_fallback));
 
             if (slotId != SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
-                extras.putString(PhoneAccount.EXTRA_SORT_ORDER,
-                    String.valueOf(slotId));
+                extras.putInt(PhoneAccount.EXTRA_SORT_ORDER, slotId);
             }
 
             mIsMergeCallSupported = isCarrierMergeCallSupported();
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 1caa8e7..09c83c0 100755
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -96,6 +96,9 @@
     private static final int MSG_CONFERENCE_MERGE_FAILED = 6;
     private static final int MSG_SUPP_SERVICE_NOTIFY = 7;
 
+    // the threshold used to compare mAudioCodecBitrateKbps and mAudioCodecBandwidth.
+    private static final float THRESHOLD = 0.01f;
+
     /**
      * Mappings from {@link com.android.internal.telephony.Connection} extras keys to their
      * equivalents defined in {@link android.telecom.Connection}.
@@ -1496,7 +1499,8 @@
         }
     }
 
-    private void refreshCodecType() {
+    private void refreshCodec() {
+        boolean changed = false;
         Bundle newExtras = getExtras();
         if (newExtras == null) {
             newExtras = new Bundle();
@@ -1512,6 +1516,31 @@
                 Connection.AUDIO_CODEC_NONE);
         if (newCodecType != oldCodecType) {
             newExtras.putInt(Connection.EXTRA_AUDIO_CODEC, newCodecType);
+            changed = true;
+        }
+        if (isImsConnection()) {
+            float newBitrate = getOriginalConnection().getAudioCodecBitrateKbps();
+            float oldBitrate = newExtras.getFloat(Connection.EXTRA_AUDIO_CODEC_BITRATE_KBPS, 0.0f);
+            if (Math.abs(newBitrate - oldBitrate) > THRESHOLD) {
+                newExtras.putFloat(Connection.EXTRA_AUDIO_CODEC_BITRATE_KBPS, newBitrate);
+                changed = true;
+            }
+
+            float newBandwidth = getOriginalConnection().getAudioCodecBandwidthKhz();
+            float oldBandwidth = newExtras.getFloat(Connection.EXTRA_AUDIO_CODEC_BANDWIDTH_KHZ,
+                    0.0f);
+            if (Math.abs(newBandwidth - oldBandwidth) > THRESHOLD) {
+                newExtras.putFloat(Connection.EXTRA_AUDIO_CODEC_BANDWIDTH_KHZ, newBandwidth);
+                changed = true;
+            }
+        } else {
+            ArrayList<String> toRemove = new ArrayList<>();
+            toRemove.add(Connection.EXTRA_AUDIO_CODEC_BITRATE_KBPS);
+            toRemove.add(Connection.EXTRA_AUDIO_CODEC_BANDWIDTH_KHZ);
+            removeTelephonyExtras(toRemove);
+        }
+
+        if (changed) {
             putTelephonyExtras(newExtras);
         }
     }
@@ -2195,7 +2224,7 @@
         updateAddress();
         updateMultiparty();
         refreshDisableAddCall();
-        refreshCodecType();
+        refreshCodec();
     }
 
     /**
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 953d415..322993a 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -1687,7 +1687,6 @@
                 EmergencyNumber emergencyNumber =
                         phone.getEmergencyNumberTracker().getEmergencyNumber(number);
                 if (emergencyNumber != null) {
-                    phone.notifyOutgoingEmergencyCall(emergencyNumber);
                     if (!getAllConnections().isEmpty()) {
                         if (!shouldHoldForEmergencyCall(phone)) {
                             // If we do not support holding ongoing calls for an outgoing
diff --git a/src/com/android/services/telephony/rcs/DelegateBinderStateManager.java b/src/com/android/services/telephony/rcs/DelegateBinderStateManager.java
new file mode 100644
index 0000000..39e9965
--- /dev/null
+++ b/src/com/android/services/telephony/rcs/DelegateBinderStateManager.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2020 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.rcs;
+
+import android.telephony.ims.DelegateRegistrationState;
+import android.telephony.ims.DelegateRequest;
+import android.telephony.ims.FeatureTagState;
+import android.telephony.ims.SipDelegateImsConfiguration;
+import android.telephony.ims.aidl.ISipDelegate;
+import android.telephony.ims.aidl.ISipDelegateMessageCallback;
+import android.telephony.ims.aidl.ISipTransport;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+
+/**
+ * Defines the interface to be used to manage the state of a SipDelegate on the ImsService side.
+ */
+public interface DelegateBinderStateManager {
+
+    /**
+     * Callback interface that allows listeners to listen to changes in registration or
+     * configuration state.
+     */
+    interface StateCallback {
+        /**
+         * The SipDelegate has notified telephony that the registration state has changed.
+         */
+        void onRegistrationStateChanged(DelegateRegistrationState registrationState);
+
+        /**
+         * The SipDelegate has notified telephony that the IMS configuration has changed.
+         */
+        void onImsConfigurationChanged(SipDelegateImsConfiguration config);
+    }
+
+    /** Allow for mocks to be created for testing. */
+    @VisibleForTesting
+    interface Factory {
+        /**
+         * Create a new instance of this interface, which may change depending on the tags being
+         * denied. See {@link SipDelegateBinderConnectionStub} and
+         * {@link SipDelegateBinderConnection}
+         */
+        DelegateBinderStateManager create(int subId, ISipTransport sipTransport,
+                DelegateRequest requestedConfig, Set<FeatureTagState> transportDeniedTags,
+                Executor executor, List<StateCallback> stateCallbacks);
+    }
+
+    /**
+     * Start the process to create a SipDelegate on the ImsService.
+     * @param cb The Binder interface that the SipDelegate should use to notify new incoming SIP
+     *         messages as well as acknowledge whether or not an outgoing SIP message was
+     *         successfully sent.
+     * @param createdConsumer The consumer that will be notified when the creation process has
+     *         completed. Contains the ISipDelegate interface to communicate with the SipDelegate
+     *         and the feature tags the SipDelegate itself denied.
+     * @return true if the creation process started, false if the remote process died. If false, the
+     * consumers will not be notified.
+     */
+    boolean create(ISipDelegateMessageCallback cb,
+            BiConsumer<ISipDelegate, Set<FeatureTagState>> createdConsumer);
+
+    /**
+     * Destroy the existing SipDelegate managed by this object.
+     * <p>
+     * This instance should be cleaned up after this call.
+     * @param reason The reason for why this delegate is being destroyed.
+     * @param destroyedConsumer The consumer that will be notified when this operation completes.
+     *         Contains the reason the SipDelegate reported it was destroyed.
+     */
+    void destroy(int reason, Consumer<Integer> destroyedConsumer);
+}
diff --git a/src/com/android/services/telephony/rcs/DelegateStateTracker.java b/src/com/android/services/telephony/rcs/DelegateStateTracker.java
new file mode 100644
index 0000000..1d8fa3b
--- /dev/null
+++ b/src/com/android/services/telephony/rcs/DelegateStateTracker.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2020 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.rcs;
+
+import android.os.RemoteException;
+import android.telephony.ims.DelegateRegistrationState;
+import android.telephony.ims.FeatureTagState;
+import android.telephony.ims.SipDelegateImsConfiguration;
+import android.telephony.ims.aidl.ISipDelegate;
+import android.telephony.ims.aidl.ISipDelegateConnectionStateCallback;
+import android.telephony.ims.stub.DelegateConnectionStateCallback;
+import android.util.LocalLog;
+import android.util.Log;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Manages the events sent back to the remote IMS application using the AIDL backing for the
+ * {@link DelegateConnectionStateCallback} interface.
+ */
+public class DelegateStateTracker implements DelegateBinderStateManager.StateCallback {
+    private static final String LOG_TAG = "DelegateST";
+
+    private final int mSubId;
+    private final ISipDelegateConnectionStateCallback mAppStateCallback;
+    private final ISipDelegate mLocalDelegateImpl;
+
+    private final LocalLog mLocalLog = new LocalLog(SipTransportController.LOG_SIZE);
+
+    private List<FeatureTagState> mDelegateDeniedTags;
+    private DelegateRegistrationState mLastRegState;
+    private boolean mCreatedCalled = false;
+    private int mRegistrationStateOverride = -1;
+
+    public DelegateStateTracker(int subId, ISipDelegateConnectionStateCallback appStateCallback,
+            ISipDelegate localDelegateImpl) {
+        mSubId = subId;
+        mAppStateCallback = appStateCallback;
+        mLocalDelegateImpl = localDelegateImpl;
+    }
+
+    /**
+     * Notify this state tracker that a new internal SipDelegate has been connected.
+     *
+     * Registration and state updates will be send via the
+     * {@link SipDelegateBinderConnection.StateCallback} callback implemented by this class as they
+     * arrive.
+     * @param deniedTags The tags denied by the SipTransportController and ImsService creating the
+     *         SipDelegate. These tags will need to be notified back to the IMS application.
+     */
+    public void sipDelegateConnected(Set<FeatureTagState> deniedTags) {
+        logi("SipDelegate connected with denied tags:" + deniedTags);
+        // From the IMS application perspective, we only call onCreated/onDestroyed once and
+        // provide the local implementation of ISipDelegate, which doesn't change, even though
+        // SipDelegates may be changing underneath.
+        if (!mCreatedCalled) {
+            mCreatedCalled = true;
+            notifySipDelegateCreated();
+        }
+        mRegistrationStateOverride = -1;
+        mDelegateDeniedTags = new ArrayList<>(deniedTags);
+    }
+
+    /**
+     * The underlying SipDelegate is changing due to a state change in the SipDelegateController.
+     *
+     * This will trigger an override of the IMS application's registration state. All feature tags
+     * in the REGISTERED state will be overridden to move to the deregistering state specified until
+     * a new SipDelegate was successfully created and {@link #sipDelegateConnected(Set)} was called
+     * or it was destroyed and {@link #sipDelegateDestroyed(int)} was called.
+     * @param deregisteringReason The new deregistering reason that all feature tags in the
+     *         registered state should now report.
+     */
+    public void sipDelegateChanging(int deregisteringReason) {
+        logi("SipDelegate Changing");
+        mRegistrationStateOverride = deregisteringReason;
+        if (mLastRegState == null) {
+            logw("sipDelegateChanging: invalid state, onRegistrationStateChanged never called.");
+            mLastRegState = new DelegateRegistrationState.Builder().build();
+        }
+        onRegistrationStateChanged(mLastRegState);
+    }
+
+    /**
+     * The underlying SipDelegate has been destroyed.
+     *
+     * This should only be called when the entire {@link SipDelegateController} is going down
+     * because the application has requested that the SipDelegate be destroyed.
+     *
+     * This can also be called in error conditions where the IMS application or ImsService has
+     * crashed.
+     * @param reason The reason that will be sent to the IMS application for why the SipDelegate
+     *         is being destroyed.
+     */
+    public void sipDelegateDestroyed(int reason) {
+        logi("SipDelegate destroyed:" + reason);
+        mRegistrationStateOverride = -1;
+        try {
+            mAppStateCallback.onDestroyed(reason);
+        } catch (RemoteException e) {
+            logw("sipDelegateDestroyed: IMS application is dead: " + e);
+        }
+    }
+
+    /**
+     * The underlying SipDelegate has reported that its registration state has changed.
+     * @param registrationState The RegistrationState reported by the SipDelegate to be sent to the
+     *         IMS application.
+     */
+    @Override
+    public void onRegistrationStateChanged(DelegateRegistrationState registrationState) {
+        if (mRegistrationStateOverride > DelegateRegistrationState.DEREGISTERED_REASON_UNKNOWN) {
+            logi("onRegistrationStateChanged: overriding registered state to "
+                    + mRegistrationStateOverride);
+            registrationState = overrideRegistrationForDelegateChange(mRegistrationStateOverride,
+                    registrationState);
+        }
+        if (registrationState.equals(mLastRegState)) {
+            logi("onRegistrationStateChanged: skipping notification, state is the same.");
+            return;
+        }
+        mLastRegState = registrationState;
+        logi("onRegistrationStateChanged: sending reg state " + registrationState);
+        try {
+            mAppStateCallback.onFeatureTagStatusChanged(registrationState, mDelegateDeniedTags);
+        } catch (RemoteException e) {
+            logw("onRegistrationStateChanged: IMS application is dead: " + e);
+        }
+    }
+
+    /**
+     * THe underlying SipDelegate has reported that the IMS configuration has changed.
+     * @param config The config to be sent to the IMS application.
+     */
+    @Override
+    public void onImsConfigurationChanged(SipDelegateImsConfiguration config) {
+        logi("onImsConfigurationChanged: Sending new IMS configuration.");
+        try {
+            mAppStateCallback.onImsConfigurationChanged(config);
+        } catch (RemoteException e) {
+            logw("onImsConfigurationChanged: IMS application is dead: " + e);
+        }
+    }
+
+    /** Write state about this tracker into the PrintWriter to be included in the dumpsys */
+    public void dump(PrintWriter printWriter) {
+        printWriter.println("Last reg state: " + mLastRegState);
+        printWriter.println("Denied tags: " + mDelegateDeniedTags);
+        printWriter.println("Most recent logs: ");
+        printWriter.println();
+        mLocalLog.dump(printWriter);
+    }
+
+    private DelegateRegistrationState overrideRegistrationForDelegateChange(
+            int registerOverrideReason, DelegateRegistrationState state) {
+        Set<String> registeredFeatures = state.getRegisteredFeatureTags();
+        DelegateRegistrationState.Builder overriddenState = new DelegateRegistrationState.Builder();
+        // keep other deregistering/deregistered tags the same.
+        for (FeatureTagState dereging : state.getDeregisteringFeatureTags()) {
+            overriddenState.addDeregisteringFeatureTag(dereging.getFeatureTag(),
+                    dereging.getState());
+        }
+        for (FeatureTagState dereged : state.getDeregisteredFeatureTags()) {
+            overriddenState.addDeregisteredFeatureTag(dereged.getFeatureTag(),
+                    dereged.getState());
+        }
+        // Override REGISTERED only
+        for (String ft : registeredFeatures) {
+            overriddenState.addDeregisteringFeatureTag(ft, registerOverrideReason);
+        }
+        return overriddenState.build();
+    }
+
+    private void notifySipDelegateCreated() {
+        try {
+            mAppStateCallback.onCreated(mLocalDelegateImpl);
+        } catch (RemoteException e) {
+            logw("notifySipDelegateCreated: IMS application is dead: " + e);
+        }
+    }
+
+    private void logi(String log) {
+        Log.i(SipTransportController.LOG_TAG, LOG_TAG + "[" + mSubId + "] " + log);
+        mLocalLog.log("[I] " + log);
+    }
+    private void logw(String log) {
+        Log.w(SipTransportController.LOG_TAG, LOG_TAG + "[" + mSubId + "] " + log);
+        mLocalLog.log("[W] " + log);
+    }
+}
diff --git a/src/com/android/services/telephony/rcs/MessageTransportStateTracker.java b/src/com/android/services/telephony/rcs/MessageTransportStateTracker.java
new file mode 100644
index 0000000..0691ae5
--- /dev/null
+++ b/src/com/android/services/telephony/rcs/MessageTransportStateTracker.java
@@ -0,0 +1,478 @@
+/*
+ * Copyright (C) 2020 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.rcs;
+
+import android.os.Binder;
+import android.os.RemoteException;
+import android.telephony.ims.DelegateMessageCallback;
+import android.telephony.ims.DelegateRegistrationState;
+import android.telephony.ims.FeatureTagState;
+import android.telephony.ims.SipDelegateImsConfiguration;
+import android.telephony.ims.SipDelegateManager;
+import android.telephony.ims.SipMessage;
+import android.telephony.ims.aidl.ISipDelegate;
+import android.telephony.ims.aidl.ISipDelegateMessageCallback;
+import android.telephony.ims.stub.SipDelegate;
+import android.util.LocalLog;
+import android.util.Log;
+
+import java.io.PrintWriter;
+import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+
+/**
+ * Tracks the SIP message path both from the IMS application to the SipDelegate and from the
+ * SipDelegate back to the IMS Application.
+ * <p>
+ * Responsibilities include:
+ * 1) Queue incoming and outgoing SIP messages and deliver to IMS application and SipDelegate in
+ *        order. If there is an error delivering the message, notify the caller.
+ * 2) TODO Perform basic validation of outgoing messages.
+ * 3) TODO Record the status of ongoing SIP Dialogs and trigger the completion of pending
+ *         consumers when they are finished or call closeDialog to clean up the SIP
+ *         dialogs that did not complete within the allotted timeout time.
+ * <p>
+ * Note: This handles incoming binder calls, so all calls from other processes should be handled on
+ * the provided Executor.
+ */
+public class MessageTransportStateTracker implements DelegateBinderStateManager.StateCallback {
+    private static final String TAG = "MessageST";
+
+    /**
+     * Communicates the result of verifying whether a SIP message should be sent based on the
+     * contents of the SIP message as well as if the transport is in an available state for the
+     * intended recipient of the message.
+     */
+    private static class VerificationResult {
+        public static final VerificationResult SUCCESS = new VerificationResult();
+
+        /**
+         * If {@code true}, the requested SIP message has been verified to be sent to the remote. If
+         * {@code false}, the SIP message has failed verification and should not be sent to the
+         * result. The {@link #restrictedReason} field will contain the reason for the verification
+         * failure.
+         */
+        public final boolean isVerified;
+
+        /**
+         * The reason associated with why the SIP message was not verified and generated a
+         * {@code false} result for {@link #isVerified}.
+         */
+        public final int restrictedReason;
+
+        /**
+         * Communicates a verified result of success. Use {@link #SUCCESS} instead.
+         */
+        private VerificationResult() {
+            isVerified = true;
+            restrictedReason = SipDelegateManager.MESSAGE_FAILURE_REASON_UNKNOWN;
+        }
+
+        /**
+         * The result of verifying that the SIP Message should be sent.
+         * @param reason The reason associated with why the SIP message was not verified and
+         *               generated a {@code false} result for {@link #isVerified}.
+         */
+        VerificationResult(@SipDelegateManager.MessageFailureReason int reason) {
+            isVerified = false;
+            restrictedReason = reason;
+        }
+    }
+
+    // SipDelegateConnection(IMS Application) -> SipDelegate(ImsService)
+    private final ISipDelegate.Stub mSipDelegateConnection = new ISipDelegate.Stub() {
+        /**
+         * The IMS application is acknowledging that it has successfully received and processed an
+         * incoming SIP message sent by the SipDelegate in
+         * {@link ISipDelegateMessageCallback#onMessageReceived(SipMessage)}.
+         */
+        @Override
+        public void notifyMessageReceived(String viaTransactionId) {
+            long token = Binder.clearCallingIdentity();
+            try {
+                mExecutor.execute(() -> {
+                    if (mSipDelegate == null) {
+                        logw("notifyMessageReceived called when SipDelegate is not associated for "
+                                + "transaction id: " + viaTransactionId);
+                        return;
+                    }
+                    try {
+                        // TODO track the SIP Dialogs created/destroyed on the associated
+                        // SipDelegate.
+                        mSipDelegate.notifyMessageReceived(viaTransactionId);
+                    } catch (RemoteException e) {
+                        logw("SipDelegate not available when notifyMessageReceived was called "
+                                + "for transaction id: " + viaTransactionId);
+                    }
+                });
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        /**
+         * The IMS application is acknowledging that it received an incoming SIP message sent by the
+         * SipDelegate in {@link ISipDelegateMessageCallback#onMessageReceived(SipMessage)} but it
+         * was unable to process it.
+         */
+        @Override
+        public void notifyMessageReceiveError(String viaTransactionId, int reason) {
+            long token = Binder.clearCallingIdentity();
+            try {
+                mExecutor.execute(() -> {
+                    if (mSipDelegate == null) {
+                        logw("notifyMessageReceiveError called when SipDelegate is not associated "
+                                + "for transaction id: " + viaTransactionId);
+                        return;
+                    }
+                    try {
+                        // TODO track the SIP Dialogs created/destroyed on the associated
+                        // SipDelegate.
+                        mSipDelegate.notifyMessageReceiveError(viaTransactionId, reason);
+                    } catch (RemoteException e) {
+                        logw("SipDelegate not available when notifyMessageReceiveError was called "
+                                + "for transaction id: " + viaTransactionId);
+                    }
+                });
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        /**
+         * The IMS application is sending an outgoing SIP message to the SipDelegate to be processed
+         * and sent over the network.
+         */
+        @Override
+        public void sendMessage(SipMessage sipMessage, long configVersion) {
+            long token = Binder.clearCallingIdentity();
+            try {
+                mExecutor.execute(() -> {
+                    VerificationResult result = verifyOutgoingMessage(sipMessage);
+                    if (!result.isVerified) {
+                        notifyDelegateSendError("Outgoing messages restricted", sipMessage,
+                                result.restrictedReason);
+                        return;
+                    }
+                    try {
+                        // TODO track the SIP Dialogs created/destroyed on the associated
+                        // SipDelegate.
+                        mSipDelegate.sendMessage(sipMessage, configVersion);
+                        logi("sendMessage: message sent - " + sipMessage + ", configVersion: "
+                                + configVersion);
+                    } catch (RemoteException e) {
+                        notifyDelegateSendError("RemoteException: " + e, sipMessage,
+                                SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_DEAD);
+                    }
+                });
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        /**
+         * The SipDelegateConnection is requesting that the resources associated with an ongoing SIP
+         * dialog be released as the SIP dialog is now closed.
+         */
+        @Override
+        public void closeDialog(String callId) {
+            long token = Binder.clearCallingIdentity();
+            try {
+                mExecutor.execute(() -> {
+                    if (mSipDelegate == null) {
+                        logw("closeDialog called when SipDelegate is not associated, callId: "
+                                + callId);
+                        return;
+                    }
+                    try {
+                        // TODO track the SIP Dialogs created/destroyed on the associated
+                        // SipDelegate.
+                        mSipDelegate.closeDialog(callId);
+                    } catch (RemoteException e) {
+                        logw("SipDelegate not available when closeDialog was called "
+                                + "for call id: " + callId);
+                    }
+                });
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+    };
+
+    // SipDelegate(ImsService) -> SipDelegateConnection(IMS Application)
+    private final ISipDelegateMessageCallback.Stub mDelegateConnectionMessageCallback =
+            new ISipDelegateMessageCallback.Stub() {
+        /**
+         * An Incoming SIP Message has been received by the SipDelegate and is being routed
+         * to the IMS application for processing.
+         * <p>
+         * IMS application will call {@link ISipDelegate#notifyMessageReceived(String)} to
+         * acknowledge receipt of this incoming message.
+         */
+        @Override
+        public void onMessageReceived(SipMessage message) {
+            long token = Binder.clearCallingIdentity();
+            try {
+                mExecutor.execute(() -> {
+                    VerificationResult result = verifyIncomingMessage(message);
+                    if (!result.isVerified) {
+                        notifyAppReceiveError("Incoming messages restricted", message,
+                                result.restrictedReason);
+                        return;
+                    }
+                    try {
+                        // TODO track the SIP Dialogs created/destroyed on the associated
+                        //  SipDelegate.
+                        mAppCallback.onMessageReceived(message);
+                        logi("onMessageReceived: received " + message);
+                    } catch (RemoteException e) {
+                        notifyAppReceiveError("RemoteException: " + e, message,
+                                SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_DEAD);
+                    }
+                });
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        /**
+         * An outgoing SIP message sent previously by the SipDelegateConnection to the SipDelegate
+         * using {@link ISipDelegate#sendMessage(SipMessage, int)} as been successfully sent.
+         */
+        @Override
+        public void onMessageSent(String viaTransactionId) {
+            long token = Binder.clearCallingIdentity();
+            try {
+                mExecutor.execute(() -> {
+                    if (mSipDelegate == null) {
+                        logw("Unexpected state, onMessageSent called when SipDelegate is not "
+                                + "associated");
+                    }
+                    try {
+                        mAppCallback.onMessageSent(viaTransactionId);
+                    } catch (RemoteException e) {
+                        logw("Error sending onMessageSent to SipDelegateConnection, remote not"
+                                + "available for transaction ID: " + viaTransactionId);
+                    }
+                });
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        /**
+         * An outgoing SIP message sent previously by the SipDelegateConnection to the SipDelegate
+         * using {@link ISipDelegate#sendMessage(SipMessage, int)} failed to be sent.
+         */
+        @Override
+        public void onMessageSendFailure(String viaTransactionId, int reason) {
+            long token = Binder.clearCallingIdentity();
+            try {
+                mExecutor.execute(() -> {
+                    if (mSipDelegate == null) {
+                        logw("Unexpected state, onMessageSendFailure called when SipDelegate is not"
+                                + "associated");
+                    }
+                    try {
+                        mAppCallback.onMessageSendFailure(viaTransactionId, reason);
+                    } catch (RemoteException e) {
+                        logw("Error sending onMessageSendFailure to SipDelegateConnection, remote"
+                                + " not available for transaction ID: " + viaTransactionId);
+                    }
+                });
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+    };
+
+    private final ISipDelegateMessageCallback mAppCallback;
+    private final Executor mExecutor;
+    private final int mSubId;
+    private final LocalLog mLocalLog = new LocalLog(SipTransportController.LOG_SIZE);
+
+    private ISipDelegate mSipDelegate;
+    private Consumer<Boolean> mPendingClosedConsumer;
+    private int mDelegateClosingReason = -1;
+    private int mDelegateClosedReason = -1;
+
+    public MessageTransportStateTracker(int subId, Executor executor,
+            ISipDelegateMessageCallback appMessageCallback) {
+        mSubId = subId;
+        mAppCallback = appMessageCallback;
+        mExecutor = executor;
+    }
+
+    @Override
+    public void onRegistrationStateChanged(DelegateRegistrationState registrationState) {
+        // TODO: integrate registration changes to SipMessage verification checks.
+    }
+
+    @Override
+    public void onImsConfigurationChanged(SipDelegateImsConfiguration config) {
+        // Not needed for this Tracker
+    }
+
+    /**
+     * Open the transport and allow SIP messages to be sent/received on the delegate specified.
+     * @param delegate The delegate connection to send SIP messages to on the ImsService.
+     * @param deniedFeatureTags Feature tags that have been denied. Outgoing SIP messages relating
+     *         to these tags will be denied.
+     */
+    public void openTransport(ISipDelegate delegate, Set<FeatureTagState> deniedFeatureTags) {
+        mSipDelegate = delegate;
+        mDelegateClosingReason = -1;
+        mDelegateClosedReason = -1;
+        // TODO: integrate denied tags to SipMessage verification checks.
+    }
+
+    /** Dump state about this tracker that should be included in the dumpsys */
+    public void dump(PrintWriter printWriter) {
+        mLocalLog.dump(printWriter);
+    }
+
+    /**
+     * @return SipDelegate implementation to be sent to IMS application.
+     */
+    public ISipDelegate getDelegateConnection() {
+        return mSipDelegateConnection;
+    }
+
+    /**
+     * @return MessageCallback implementation to be sent to the ImsService.
+     */
+    public ISipDelegateMessageCallback getMessageCallback() {
+        return mDelegateConnectionMessageCallback;
+    }
+
+    /**
+     * Gradually close all SIP Dialogs by:
+     * 1) denying all new outgoing SIP Dialog requests with the reason specified and
+     * 2) only allowing existing SIP Dialogs to continue.
+     * <p>
+     * This will allow traffic to continue on existing SIP Dialogs until a BYE is sent and the
+     * SIP Dialogs are closed or a timeout is hit and {@link SipDelegate#closeDialog(String)} is
+     * forcefully called on all open SIP Dialogs.
+     * <p>
+     * Any outgoing out-of-dialog traffic on this transport will be denied with the provided reason.
+     * <p>
+     * Incoming out-of-dialog traffic will continue to be set up until the SipDelegate is fully
+     * closed.
+     * @param delegateClosingReason The reason code to return to
+     * {@link DelegateMessageCallback#onMessageSendFailure(String, int)} if a new out-of-dialog SIP
+     *         message is received while waiting for existing Dialogs.
+     * @param closedReason reason to return to new outgoing SIP messages via
+     *         {@link SipDelegate#notifyMessageReceiveError(String, int)} once the transport
+     *         transitions to the fully closed state.
+     * @param resultConsumer The consumer called when the message transport has been closed. It will
+     *         return {@code true} if the procedure completed successfully or {@link false} if the
+     *         transport needed to be closed forcefully due to the application not responding before
+     *         a timeout occurred.
+     */
+    public void closeGracefully(int delegateClosingReason, int closedReason,
+            Consumer<Boolean> resultConsumer) {
+        mDelegateClosingReason = delegateClosingReason;
+        mPendingClosedConsumer = resultConsumer;
+        mExecutor.execute(() -> {
+            // TODO: Track SIP Dialogs and complete when there are no SIP dialogs open anymore or
+            //  the timeout occurs.
+            mPendingClosedConsumer.accept(true);
+            mPendingClosedConsumer = null;
+            closeTransport(closedReason);
+        });
+    }
+
+    /**
+     * Close all ongoing SIP Dialogs immediately and respond to any incoming/outgoing messages with
+     * the provided reason.
+     * @param closedReason The failure reason to provide to incoming/outgoing SIP messages
+     *         if an attempt is made to send/receive a message after this method is called.
+     */
+    public void close(int closedReason) {
+        closeTransport(closedReason);
+    }
+
+    // Clean up all state related to the existing SipDelegate immediately.
+    private void closeTransport(int closedReason) {
+        // TODO: add logic to forcefully close open SIP dialogs once they are being tracked.
+        mSipDelegate = null;
+        if (mPendingClosedConsumer != null) {
+            mExecutor.execute(() -> {
+                logw("closeTransport: transport close forced with pending consumer.");
+                mPendingClosedConsumer.accept(false /*closedGracefully*/);
+                mPendingClosedConsumer = null;
+            });
+        }
+        mDelegateClosingReason = -1;
+        mDelegateClosedReason = closedReason;
+    }
+
+    private VerificationResult verifyOutgoingMessage(SipMessage message) {
+        if (mDelegateClosingReason > -1) {
+            return new VerificationResult(mDelegateClosingReason);
+        }
+        if (mDelegateClosedReason > -1) {
+            return new VerificationResult(mDelegateClosedReason);
+        }
+        if (mSipDelegate == null) {
+            logw("sendMessage called when SipDelegate is not associated." + message);
+            return new VerificationResult(SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_DEAD);
+        }
+        return VerificationResult.SUCCESS;
+    }
+
+    private VerificationResult verifyIncomingMessage(SipMessage message) {
+        // Do not restrict incoming based on closing reason.
+        if (mDelegateClosedReason > -1) {
+            return new VerificationResult(mDelegateClosedReason);
+        }
+        return VerificationResult.SUCCESS;
+    }
+
+    private void notifyDelegateSendError(String logReason, SipMessage message, int reasonCode) {
+        // TODO parse SipMessage header for viaTransactionId.
+        logw("Error sending SipMessage[id: " + null + ", code: " + reasonCode + "] -> SipDelegate "
+                + "for reason: " + logReason);
+        try {
+            mAppCallback.onMessageSendFailure(null, reasonCode);
+        } catch (RemoteException e) {
+            logw("notifyDelegateSendError, SipDelegate is not available: " + e);
+        }
+    }
+
+    private void notifyAppReceiveError(String logReason, SipMessage message, int reasonCode) {
+        // TODO parse SipMessage header for viaTransactionId.
+        logw("Error sending SipMessage[id: " + null + ", code: " + reasonCode + "] -> "
+                + "SipDelegateConnection for reason: " + logReason);
+        try {
+            mSipDelegate.notifyMessageReceiveError(null, reasonCode);
+        } catch (RemoteException e) {
+            logw("notifyAppReceiveError, SipDelegate is not available: " + e);
+        }
+    }
+
+    private void logi(String log) {
+        Log.w(SipTransportController.LOG_TAG, TAG + "[" + mSubId + "] " + log);
+        mLocalLog.log("[I] " + log);
+    }
+
+    private void logw(String log) {
+        Log.w(SipTransportController.LOG_TAG, TAG + "[" + mSubId + "] " + log);
+        mLocalLog.log("[W] " + log);
+    }
+}
diff --git a/src/com/android/services/telephony/rcs/RcsFeatureController.java b/src/com/android/services/telephony/rcs/RcsFeatureController.java
index 8c6fce0..304a74d 100644
--- a/src/com/android/services/telephony/rcs/RcsFeatureController.java
+++ b/src/com/android/services/telephony/rcs/RcsFeatureController.java
@@ -74,6 +74,12 @@
          * Called when the feature should be destroyed.
          */
         void onDestroy();
+
+        /**
+         * Called when a dumpsys is being generated for this RcsFeatureController for all Features
+         * to report their status.
+         */
+        void dump(PrintWriter pw);
     }
 
     /**
@@ -427,6 +433,14 @@
         pw.print("connected=");
         synchronized (mLock) {
             pw.println(mFeatureManager != null);
+            pw.println();
+            pw.println("RcsFeatureControllers:");
+            pw.increaseIndent();
+            for (Feature f : mFeatures.values()) {
+                f.dump(pw);
+                pw.println();
+            }
+            pw.decreaseIndent();
         }
     }
 
diff --git a/src/com/android/services/telephony/rcs/SipDelegateBinderConnection.java b/src/com/android/services/telephony/rcs/SipDelegateBinderConnection.java
new file mode 100644
index 0000000..1a77f2b
--- /dev/null
+++ b/src/com/android/services/telephony/rcs/SipDelegateBinderConnection.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2020 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.rcs;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.telephony.ims.DelegateRegistrationState;
+import android.telephony.ims.DelegateRequest;
+import android.telephony.ims.FeatureTagState;
+import android.telephony.ims.SipDelegateImsConfiguration;
+import android.telephony.ims.SipDelegateManager;
+import android.telephony.ims.aidl.ISipDelegate;
+import android.telephony.ims.aidl.ISipDelegateMessageCallback;
+import android.telephony.ims.aidl.ISipDelegateStateCallback;
+import android.telephony.ims.aidl.ISipTransport;
+import android.telephony.ims.stub.SipDelegate;
+import android.util.LocalLog;
+import android.util.Log;
+
+import java.io.PrintWriter;
+import java.util.Collections;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+
+/**
+ * Container for the active connection to the {@link SipDelegate} active on the ImsService.
+ * <p>
+ * New instances of this class will be created and destroyed new {@link SipDelegate}s are created
+ * and destroyed by the {@link SipDelegateController}.
+ */
+public class SipDelegateBinderConnection implements DelegateBinderStateManager,
+        IBinder.DeathRecipient {
+    private static final String LOG_TAG = "BinderConn";
+
+    protected final int mSubId;
+    protected final Set<FeatureTagState> mDeniedTags;
+    protected final Executor mExecutor;
+    protected final List<StateCallback> mStateCallbacks;
+
+    private final LocalLog mLocalLog = new LocalLog(SipTransportController.LOG_SIZE);
+
+    // Callback interface from ImsService to this Connection. State Events will be forwarded to IMS
+    // application through DelegateStateTracker.
+    private final ISipDelegateStateCallback mSipDelegateStateCallback =
+            new ISipDelegateStateCallback.Stub() {
+                @Override
+                public void onCreated(ISipDelegate delegate,
+                        List<FeatureTagState> deniedFeatureTags) {
+                    long token = Binder.clearCallingIdentity();
+                    try {
+                        mExecutor.execute(() ->
+                                notifySipDelegateCreated(delegate, deniedFeatureTags));
+                    } finally {
+                        Binder.restoreCallingIdentity(token);
+                    }
+                }
+
+                @Override
+                public void onFeatureTagRegistrationChanged(
+                        DelegateRegistrationState registrationState) {
+                    long token = Binder.clearCallingIdentity();
+                    try {
+                        mExecutor.execute(() -> {
+                            logi("onFeatureTagRegistrationChanged:" + registrationState);
+                            for (StateCallback c : mStateCallbacks) {
+                                c.onRegistrationStateChanged(registrationState);
+                            }
+                        });
+                    } finally {
+                        Binder.restoreCallingIdentity(token);
+                    }
+                }
+
+                @Override
+                public void onImsConfigurationChanged(
+                        SipDelegateImsConfiguration registeredSipConfig) {
+                    long token = Binder.clearCallingIdentity();
+                    try {
+                        mExecutor.execute(() -> {
+                            logi("onImsConfigurationChanged");
+                            for (StateCallback c : mStateCallbacks) {
+                                c.onImsConfigurationChanged(registeredSipConfig);
+                            }
+                        });
+                    } finally {
+                        Binder.restoreCallingIdentity(token);
+                    }
+                }
+
+                @Override
+                public void onDestroyed(int reason) {
+                    long token = Binder.clearCallingIdentity();
+                    try {
+                        mExecutor.execute(() -> notifySipDelegateDestroyed(reason));
+                    } finally {
+                        Binder.restoreCallingIdentity(token);
+                    }
+                }
+            };
+
+    private final ISipTransport mSipTransport;
+    private final DelegateRequest mRequestedConfig;
+
+    private ISipDelegate mDelegateBinder;
+    private BiConsumer<ISipDelegate, Set<FeatureTagState>> mPendingCreatedConsumer;
+    private Consumer<Integer> mPendingDestroyedConsumer;
+
+    /**
+     * Create a new Connection object to manage the creation and destruction of a
+     * {@link SipDelegate}.
+     * @param subId The subid that this SipDelegate is being created for.
+     * @param sipTransport The SipTransport implementation that will be used to manage SipDelegates.
+     * @param requestedConfig The DelegateRequest to be sent to the ImsService.
+     * @param transportDeniedTags The feature tags that have already been denied by the
+     *                            SipTransportController and should not be requested.
+     * @param executor The Executor that all binder calls from the remote process will be executed
+     *                on.
+     * @param stateCallbacks A list of callbacks that will each be called when the state of the
+     *                       SipDelegate changes. This will be called on the supplied executor.
+     */
+    public SipDelegateBinderConnection(int subId, ISipTransport sipTransport,
+            DelegateRequest requestedConfig, Set<FeatureTagState> transportDeniedTags,
+            Executor executor, List<StateCallback> stateCallbacks) {
+        mSubId = subId;
+        mSipTransport = sipTransport;
+        mRequestedConfig = requestedConfig;
+        mDeniedTags = transportDeniedTags;
+        mExecutor = executor;
+        mStateCallbacks = stateCallbacks;
+    }
+
+    @Override
+    public boolean create(ISipDelegateMessageCallback cb,
+            BiConsumer<ISipDelegate, Set<FeatureTagState>> createdConsumer) {
+        try {
+            mSipTransport.createSipDelegate(mSubId, mRequestedConfig, mSipDelegateStateCallback,
+                    cb);
+            mSipTransport.asBinder().linkToDeath(this, 0);
+        } catch (RemoteException e) {
+            logw("create called on unreachable SipTransport:" + e);
+            return false;
+        }
+        mPendingCreatedConsumer = createdConsumer;
+        return true;
+    }
+
+    @Override
+    public void destroy(int reason, Consumer<Integer> destroyedConsumer) {
+        mPendingDestroyedConsumer = destroyedConsumer;
+        try {
+            if (mDelegateBinder != null) {
+                mSipTransport.destroySipDelegate(mDelegateBinder, reason);
+            } else {
+                mExecutor.execute(() -> notifySipDelegateDestroyed(reason));
+            }
+            mStateCallbacks.clear();
+        } catch (RemoteException e) {
+            logw("destroy called on unreachable SipTransport:" + e);
+            mExecutor.execute(() -> notifySipDelegateDestroyed(reason));
+        }
+        try {
+            mSipTransport.asBinder().unlinkToDeath(this, 0);
+        } catch (NoSuchElementException e) {
+            logw("unlinkToDeath called on already unlinked binder" + e);
+        }
+    }
+
+    private void notifySipDelegateCreated(ISipDelegate delegate,
+            List<FeatureTagState> deniedFeatureTags) {
+        logi("Delegate Created: " + delegate + ", deniedTags:" + deniedFeatureTags);
+        if (delegate == null) {
+            logw("Invalid null delegate returned!");
+        }
+        mDelegateBinder = delegate;
+        // Add denied feature tags from SipDelegate to the ones denied by the transport
+        if (deniedFeatureTags != null) {
+            mDeniedTags.addAll(deniedFeatureTags);
+        }
+        if (mPendingCreatedConsumer == null) return;
+        mPendingCreatedConsumer.accept(delegate, mDeniedTags);
+        mPendingCreatedConsumer = null;
+    }
+
+    private void notifySipDelegateDestroyed(int reason) {
+        logi("Delegate Destroyed, reason: " + reason);
+        mDelegateBinder = null;
+        if (mPendingDestroyedConsumer == null) return;
+        mPendingDestroyedConsumer.accept(reason);
+        mPendingDestroyedConsumer = null;
+    }
+
+    /** Dump state about this binder connection that should be included in the dumpsys. */
+    public void dump(PrintWriter printWriter) {
+        mLocalLog.dump(printWriter);
+    }
+
+    protected final void logi(String log) {
+        Log.i(SipTransportController.LOG_TAG, LOG_TAG + "[" + mSubId + "] " + log);
+        mLocalLog.log("[I] " + log);
+    }
+
+    protected final void logw(String log) {
+        Log.w(SipTransportController.LOG_TAG, LOG_TAG + "[" + mSubId + "] " + log);
+        mLocalLog.log("[W] " + log);
+    }
+
+    @Override
+    public void binderDied() {
+        mExecutor.execute(() -> {
+            logw("binderDied!");
+            // Unblock any pending create/destroy operations.
+            // SipTransportController will handle the overall destruction/teardown.
+            notifySipDelegateCreated(null, Collections.emptyList());
+            notifySipDelegateDestroyed(SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD);
+        });
+    }
+}
diff --git a/src/com/android/services/telephony/rcs/SipDelegateBinderConnectionStub.java b/src/com/android/services/telephony/rcs/SipDelegateBinderConnectionStub.java
new file mode 100644
index 0000000..888af94
--- /dev/null
+++ b/src/com/android/services/telephony/rcs/SipDelegateBinderConnectionStub.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2020 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.rcs;
+
+import android.telephony.ims.DelegateRegistrationState;
+import android.telephony.ims.FeatureTagState;
+import android.telephony.ims.aidl.ISipDelegate;
+import android.telephony.ims.aidl.ISipDelegateMessageCallback;
+import android.telephony.ims.stub.SipDelegate;
+
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+
+/**
+ * Stub implementation used when a SipDelegate needs to be set up in specific cases, but there
+ * is no underlying implementation in the ImsService.
+ *
+ * This is used in cases where all of the requested feature tags were denied for various reasons
+ * from the SipTransportController. In this case, we will "connect", send a update to include the
+ * denied feature tags, and then do nothing until this stub is torn down.
+ */
+public class SipDelegateBinderConnectionStub implements DelegateBinderStateManager {
+    protected final Set<FeatureTagState> mDeniedTags;
+    protected final Executor mExecutor;
+    protected final List<StateCallback> mStateCallbacks;
+
+    /**
+     * Create a new Connection object to manage the creation and destruction of a
+     * {@link SipDelegate}.
+     * @param transportDeniedTags The feature tags that have already been denied by the
+     *                            SipTransportController and should not be requested.
+     * @param executor The Executor that all binder calls from the remote process will be executed
+     *                on.
+     * @param stateCallbacks A list of callbacks that will each be called when the state of the
+     *                       SipDelegate changes. This will be called on the supplied executor.
+     */
+    public SipDelegateBinderConnectionStub(Set<FeatureTagState> transportDeniedTags,
+            Executor executor, List<StateCallback> stateCallbacks) {
+        mDeniedTags = transportDeniedTags;
+        mExecutor = executor;
+        mStateCallbacks = stateCallbacks;
+    }
+
+    @Override
+    public boolean create(ISipDelegateMessageCallback cb,
+            BiConsumer<ISipDelegate, Set<FeatureTagState>> createdConsumer) {
+        mExecutor.execute(() -> {
+            createdConsumer.accept(null, (mDeniedTags));
+            for (SipDelegateBinderConnection.StateCallback  c: mStateCallbacks) {
+                c.onRegistrationStateChanged(new DelegateRegistrationState.Builder().build());
+            }
+        });
+        return true;
+    }
+
+    @Override
+    public void destroy(int reason, Consumer<Integer> destroyedConsumer) {
+        mExecutor.execute(() -> {
+            mStateCallbacks.clear();
+            destroyedConsumer.accept(reason);
+        });
+    }
+}
diff --git a/src/com/android/services/telephony/rcs/SipDelegateController.java b/src/com/android/services/telephony/rcs/SipDelegateController.java
new file mode 100644
index 0000000..ed50778
--- /dev/null
+++ b/src/com/android/services/telephony/rcs/SipDelegateController.java
@@ -0,0 +1,375 @@
+/*
+ * Copyright (C) 2020 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.rcs;
+
+import android.telephony.ims.DelegateRegistrationState;
+import android.telephony.ims.DelegateRequest;
+import android.telephony.ims.FeatureTagState;
+import android.telephony.ims.SipDelegateConnection;
+import android.telephony.ims.SipDelegateManager;
+import android.telephony.ims.aidl.ISipDelegate;
+import android.telephony.ims.aidl.ISipDelegateConnectionStateCallback;
+import android.telephony.ims.aidl.ISipDelegateMessageCallback;
+import android.telephony.ims.aidl.ISipTransport;
+import android.telephony.ims.stub.DelegateConnectionStateCallback;
+import android.telephony.ims.stub.SipDelegate;
+import android.util.LocalLog;
+import android.util.Log;
+import android.util.Pair;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IndentingPrintWriter;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ScheduledExecutorService;
+
+/**
+ * Created when an IMS application wishes to open up a {@link SipDelegateConnection} and manages the
+ * resulting {@link SipDelegate} that may be created on the ImsService side.
+ */
+public class SipDelegateController {
+    static final String LOG_TAG = "SipDelegateC";
+
+    private DelegateBinderStateManager.Factory mBinderConnectionFactory =
+            new DelegateBinderStateManager.Factory() {
+        @Override
+        public DelegateBinderStateManager create(int subId, ISipTransport sipTransport,
+                DelegateRequest requestedConfig, Set<FeatureTagState> transportDeniedTags,
+                Executor executor, List<DelegateBinderStateManager.StateCallback> stateCallbacks) {
+            // We should not actually create a SipDelegate in this case.
+            if (requestedConfig.getFeatureTags().isEmpty()) {
+                return new SipDelegateBinderConnectionStub(transportDeniedTags, executor,
+                        stateCallbacks);
+            }
+            return new SipDelegateBinderConnection(mSubId, mSipTransportImpl, requestedConfig,
+                    transportDeniedTags, mExecutorService, stateCallbacks);
+        }
+    };
+
+    private final int mSubId;
+    private final String mPackageName;
+    private final DelegateRequest mInitialRequest;
+    private final ISipTransport mSipTransportImpl;
+    private final ScheduledExecutorService mExecutorService;
+    private final MessageTransportStateTracker mMessageTransportStateTracker;
+    private final DelegateStateTracker mDelegateStateTracker;
+    private final LocalLog mLocalLog = new LocalLog(SipTransportController.LOG_SIZE);
+
+    private DelegateBinderStateManager mBinderConnection;
+    private Set<String> mTrackedFeatureTags;
+
+    public SipDelegateController(int subId, DelegateRequest initialRequest, String packageName,
+            ISipTransport sipTransportImpl, ScheduledExecutorService executorService,
+            ISipDelegateConnectionStateCallback stateCallback,
+            ISipDelegateMessageCallback messageCallback) {
+        mSubId = subId;
+        mPackageName = packageName;
+        mInitialRequest = initialRequest;
+        mSipTransportImpl = sipTransportImpl;
+        mExecutorService = executorService;
+
+        mMessageTransportStateTracker = new MessageTransportStateTracker(mSubId, executorService,
+                messageCallback);
+        mDelegateStateTracker = new DelegateStateTracker(mSubId, stateCallback,
+                mMessageTransportStateTracker.getDelegateConnection());
+    }
+
+    /**
+     * Inject dependencies for testing only.
+     */
+    @VisibleForTesting
+    public SipDelegateController(int subId, DelegateRequest initialRequest, String packageName,
+            ISipTransport sipTransportImpl, ScheduledExecutorService executorService,
+            MessageTransportStateTracker messageTransportStateTracker,
+            DelegateStateTracker delegateStateTracker,
+            DelegateBinderStateManager.Factory connectionFactory) {
+        mSubId = subId;
+        mInitialRequest = initialRequest;
+        mPackageName = packageName;
+        mSipTransportImpl = sipTransportImpl;
+        mExecutorService = executorService;
+        mMessageTransportStateTracker = messageTransportStateTracker;
+        mDelegateStateTracker = delegateStateTracker;
+        mBinderConnectionFactory = connectionFactory;
+    }
+
+    /**
+     * @return The InitialRequest from the IMS application. The feature tags that are actually set
+     * up may differ from this request based on the state of this controller.
+     */
+    public DelegateRequest getInitialRequest() {
+        return mInitialRequest;
+    }
+
+    /**
+     * @return The package name of the IMS application associated with this SipDelegateController.
+     */
+    public String getPackageName() {
+        return mPackageName;
+    }
+
+    public ISipDelegate getSipDelegateInterface() {
+        return mMessageTransportStateTracker.getDelegateConnection();
+    }
+
+    /**
+     * Create the underlying SipDelegate.
+     * <p>
+     * This may not happen instantly, The CompletableFuture returned will not complete until
+     * {@link DelegateConnectionStateCallback#onCreated(SipDelegateConnection)} is called by the
+     * SipDelegate or DelegateStateTracker state is updated in the case that all requested features
+     * were denied.
+     * @return A CompletableFuture that will complete once the SipDelegate has been created. If true
+     * is returned, the SipDelegate has been created successfully. If false, the ImsService is not
+     * reachable and the process should be aborted.
+     */
+    public CompletableFuture<Boolean> create(Set<String> supportedSet,
+            Set<FeatureTagState> deniedSet) {
+        logi("create, supported: " + supportedSet + ", denied: " + deniedSet);
+        mTrackedFeatureTags = supportedSet;
+        DelegateBinderStateManager connection =
+                createBinderConnection(supportedSet, deniedSet);
+        CompletableFuture<Pair<ISipDelegate, Set<FeatureTagState>>> pendingCreate =
+                createSipDelegate(connection);
+        // May need to implement special case handling where SipDelegate denies all in supportedSet,
+        // however that should be a very rare case. For now, if that happens, just keep the
+        // SipDelegate bound.
+        // use thenApply here because we need this to happen on the same thread that it was called
+        // on in order to ensure ordering of onCreated being called, followed by registration
+        // state changed. If not, this is subject to race conditions where registered is queued
+        // before the async processing of this future.
+        return pendingCreate.thenApply((resultPair) -> {
+            if (resultPair == null) {
+                logw("create: resultPair returned null");
+                return false;
+            }
+            mBinderConnection = connection;
+            logi("create: created, delegate denied: " + resultPair.second);
+            mMessageTransportStateTracker.openTransport(resultPair.first, resultPair.second);
+            mDelegateStateTracker.sipDelegateConnected(resultPair.second);
+            return true;
+        });
+    }
+
+    /**
+     * Modify the SipTransport to reflect the new Feature Tag set that the IMS application has
+     * access to.
+     * <p>
+     * This involves the following operations if the new supported tag set does not match the
+     * the existing set:
+     * 1) destroy the existing underlying SipDelegate. If there are SIP Dialogs that are active
+     * on the SipDelegate that is pending to be destroyed, we must move the feature tags into a
+     * deregistering state via
+     * {@link DelegateRegistrationState#DEREGISTERING_REASON_FEATURE_TAGS_CHANGING} to signal to the
+     * IMS application to close all dialogs before the operation can proceed. If any outgoing
+     * out-of-dialog messages are sent at this time, they will also fail with reason
+     * {@link SipDelegateManager#MESSAGE_FAILURE_REASON_INTERNAL_DELEGATE_STATE_TRANSITION}.
+     * 2) create a new underlying SipDelegate and notify trackers, allowing the transport to
+     * re-open.
+     * @param newSupportedSet The new supported set of feature tags that the SipDelegate should
+     *     be opened for.
+     * @param deniedSet The new set of tags that have been denied as well as the reason for the
+     *        denial to be reported back to the IMS Application.
+     * @return A CompletableFuture containing the pending operation that will change the supported
+     * feature tags. Any operations to change the supported feature tags of the associated
+     * SipDelegate after this should not happen until this pending operation completes. Will
+     * complete with {@code true} if the operation was successful or {@code false} if the
+     * IMS service was unreachable.
+     */
+    public CompletableFuture<Boolean> changeSupportedFeatureTags(Set<String> newSupportedSet,
+            Set<FeatureTagState> deniedSet) {
+        logi("Received feature tag set change, old: [" + mTrackedFeatureTags + "], new: "
+                + newSupportedSet + ",denied: [" + deniedSet + "]");
+        if (mTrackedFeatureTags != null && mTrackedFeatureTags.equals(newSupportedSet)) {
+            logi("changeSupportedFeatureTags: no change, returning");
+            return CompletableFuture.completedFuture(true);
+        }
+
+        mTrackedFeatureTags = newSupportedSet;
+        // Next perform the destroy operation.
+        CompletableFuture<Integer> pendingDestroy = destroySipDelegate(false/*force*/,
+                SipDelegateManager.MESSAGE_FAILURE_REASON_INTERNAL_DELEGATE_STATE_TRANSITION,
+                SipDelegateManager.MESSAGE_FAILURE_REASON_INTERNAL_DELEGATE_STATE_TRANSITION,
+                DelegateRegistrationState.DEREGISTERING_REASON_FEATURE_TAGS_CHANGING,
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+
+        // Next perform the create operation with the new set of supported feature tags.
+        return pendingDestroy.thenComposeAsync((reasonFromService) -> {
+            logi("changeSupportedFeatureTags: destroy stage complete, reason reported: "
+                    + reasonFromService);
+            return create(newSupportedSet, deniedSet);
+        }, mExecutorService);
+    }
+
+    /**
+     * Destroy this SipDelegate. This controller should be disposed of after this method is
+     * called.
+     * <p>
+     * This may not happen instantly if there are SIP Dialogs that are active on this SipDelegate.
+     * In this case, the CompletableFuture will not complete until
+     * {@link DelegateConnectionStateCallback#onDestroyed(int)} is called by the SipDelegate.
+     * @param force If set true, we will close the transport immediately and call
+     * {@link SipDelegate#closeDialog(String)} on any open dialogs. If false, we will wait for the
+     *         SIP Dialogs to close or the close timer to timeout before destroying the underlying
+     *         SipDelegate.
+     * @param destroyReason The reason for why this SipDelegate is being destroyed.
+     * @return A CompletableFuture that will complete once the SipDelegate has been destroyed.
+     */
+    public CompletableFuture<Integer> destroy(boolean force, int destroyReason) {
+        logi("destroy, forced " + force + ", destroyReason: " + destroyReason);
+
+        CompletableFuture<Integer> pendingOperationComplete =
+                destroySipDelegate(force, SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED,
+                        getMessageFailReasonFromDestroyReason(destroyReason),
+                        DelegateRegistrationState.DEREGISTERING_REASON_DESTROY_PENDING,
+                        destroyReason);
+        return pendingOperationComplete.thenApplyAsync((reasonFromDelegate) -> {
+            logi("destroy, operation complete, notifying trackers, reason" + reasonFromDelegate);
+            mDelegateStateTracker.sipDelegateDestroyed(reasonFromDelegate);
+            return reasonFromDelegate;
+        }, mExecutorService);
+    };
+
+    private static int getMessageFailReasonFromDestroyReason(int destroyReason) {
+        switch (destroyReason) {
+            case SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD:
+                return SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_DEAD;
+            case SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP:
+            case SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_USER_DISABLED_RCS:
+                return SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED;
+            default:
+                return SipDelegateManager.MESSAGE_FAILURE_REASON_UNKNOWN;
+        }
+    }
+
+    /**
+     * @param force If set true, we will close the transport immediately and call
+     * {@link SipDelegate#closeDialog(String)} on any open dialogs. If false, we will wait for the
+     *         SIP Dialogs to close or the close timer to timeout before destroying the underlying
+     *         SipDelegate.
+     * @param messageDestroyingReason The reason to send back to the IMS application in the case
+     *         that a new outgoing SIP message is sent that is out-of-dialog while the message
+     *         transport is closing.
+     * @param messageDestroyedReason The reason to send back to the IMS application in the case
+     *         that a new outgoing SIP message is sent once the underlying transport is closed.
+     * @param deregisteringReason The deregistering state reported to the IMS application for all
+     *         registered feature tags.
+     * @param delegateDestroyedReason The reason to send to the underlying SipDelegate that is being
+     *         destroyed.
+     * @return A CompletableFuture containing the reason from the SipDelegate for why it was
+     * destroyed.
+     */
+    private CompletableFuture<Integer> destroySipDelegate(boolean force,
+            int messageDestroyingReason, int messageDestroyedReason, int deregisteringReason,
+            int delegateDestroyedReason) {
+        if (mBinderConnection == null) {
+            logi("destroySipDelegate, called when binder connection is already null");
+            return CompletableFuture.completedFuture(delegateDestroyedReason);
+        }
+        // First, bring down the message transport.
+        CompletableFuture<Boolean> pendingTransportClosed = new CompletableFuture<>();
+        if (force) {
+            logi("destroySipDelegate, forced");
+            mMessageTransportStateTracker.close(messageDestroyedReason);
+            pendingTransportClosed.complete(true);
+        } else {
+            mMessageTransportStateTracker.closeGracefully(messageDestroyingReason,
+                    messageDestroyedReason, pendingTransportClosed::complete);
+        }
+
+        // Do not send an intermediate pending state to app if there are no open SIP dialogs to
+        // worry about.
+        if (!pendingTransportClosed.isDone()) {
+            mDelegateStateTracker.sipDelegateChanging(deregisteringReason);
+        } else {
+            logi("destroySipDelegate, skip DEREGISTERING_REASON_DESTROY_PENDING");
+        }
+
+        // Next, destroy the SipDelegate.
+        return pendingTransportClosed.thenComposeAsync((wasGraceful) -> {
+            logi("destroySipDelegate, transport gracefully closed = " + wasGraceful);
+            CompletableFuture<Integer> pendingDestroy = new CompletableFuture<>();
+            mBinderConnection.destroy(delegateDestroyedReason, pendingDestroy::complete);
+            return pendingDestroy;
+        }, mExecutorService);
+    }
+
+    /**
+     * @return a CompletableFuture that returns a Pair containing SipDelegate Binder interface as
+     * well as rejected feature tags or a {@code null} Pair instance if the ImsService is not
+     * available.
+     */
+    private CompletableFuture<Pair<ISipDelegate, Set<FeatureTagState>>> createSipDelegate(
+            DelegateBinderStateManager connection) {
+        CompletableFuture<Pair<ISipDelegate, Set<FeatureTagState>>> createdFuture =
+                new CompletableFuture<>();
+        boolean isStarted = connection.create(mMessageTransportStateTracker.getMessageCallback(),
+                (delegate, delegateDeniedTags) ->
+                        createdFuture.complete(new Pair<>(delegate, delegateDeniedTags)));
+        if (!isStarted) {
+            logw("Couldn't create binder connection, ImsService is not available.");
+            connection.destroy(SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD, null);
+            return CompletableFuture.completedFuture(null);
+        }
+        return createdFuture;
+    }
+
+    private DelegateBinderStateManager createBinderConnection(Set<String> supportedSet,
+            Set<FeatureTagState> deniedSet) {
+
+        List<DelegateBinderStateManager.StateCallback> stateCallbacks = new ArrayList<>(2);
+        stateCallbacks.add(mDelegateStateTracker);
+        stateCallbacks.add(mMessageTransportStateTracker);
+
+        return mBinderConnectionFactory.create(mSubId, mSipTransportImpl,
+                new DelegateRequest(supportedSet), deniedSet, mExecutorService, stateCallbacks);
+    }
+
+    /**
+     * Write the current state of this controller in String format using the PrintWriter provided
+     * for dumpsys.
+     */
+    public void dump(PrintWriter printWriter) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
+        pw.println("SipDelegateController" + "[" + mSubId + "]:");
+        pw.increaseIndent();
+        pw.println("DelegateStateTracker:");
+        pw.increaseIndent();
+        mDelegateStateTracker.dump(printWriter);
+        pw.decreaseIndent();
+        pw.println("MessageStateTracker:");
+        pw.increaseIndent();
+        mMessageTransportStateTracker.dump(printWriter);
+        pw.decreaseIndent();
+        pw.decreaseIndent();
+    }
+
+    private void logi(String log) {
+        Log.w(SipTransportController.LOG_TAG, LOG_TAG + "[" + mSubId + "] " + log);
+        mLocalLog.log("[I] " + log);
+    }
+
+    private void logw(String log) {
+        Log.w(SipTransportController.LOG_TAG, LOG_TAG + "[" + mSubId + "] " + log);
+        mLocalLog.log("[W] " + log);
+    }
+}
diff --git a/src/com/android/services/telephony/rcs/SipTransportController.java b/src/com/android/services/telephony/rcs/SipTransportController.java
index da5374a..5d817ba 100644
--- a/src/com/android/services/telephony/rcs/SipTransportController.java
+++ b/src/com/android/services/telephony/rcs/SipTransportController.java
@@ -16,19 +16,51 @@
 
 package com.android.services.telephony.rcs;
 
+import android.app.role.OnRoleHoldersChangedListener;
+import android.app.role.RoleManager;
 import android.content.Context;
+import android.os.UserHandle;
+import android.telephony.ims.DelegateRequest;
+import android.telephony.ims.FeatureTagState;
 import android.telephony.ims.ImsException;
 import android.telephony.ims.ImsService;
+import android.telephony.ims.SipDelegateManager;
+import android.telephony.ims.aidl.ISipDelegate;
+import android.telephony.ims.aidl.ISipDelegateConnectionStateCallback;
+import android.telephony.ims.aidl.ISipDelegateMessageCallback;
+import android.telephony.ims.aidl.ISipTransport;
+import android.telephony.ims.stub.DelegateConnectionMessageCallback;
+import android.telephony.ims.stub.DelegateConnectionStateCallback;
+import android.telephony.ims.stub.SipDelegate;
+import android.text.TextUtils;
+import android.util.ArraySet;
+import android.util.LocalLog;
 import android.util.Log;
 
+import androidx.annotation.NonNull;
+
 import com.android.ims.RcsFeatureManager;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IndentingPrintWriter;
 
+import com.google.common.base.Objects;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
 import java.util.concurrent.Callable;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
 
 /**
  * Manages the creation and destruction of SipDelegates in response to an IMS application requesting
@@ -39,16 +71,179 @@
  * instead of requiring that the IMS application manage its own IMS registration over-the-top. This
  * is required for some cellular carriers, which mandate that all IMS SIP traffic must be sent
  * through a single IMS registration managed by the system IMS service.
+ *
+ * //TODO: Support other roles besides SMS
+ * //TODO: Bring in carrier provisioning to influence features that can be created.
+ * //TODO: Generate registration change events.
  */
-public class SipTransportController implements RcsFeatureController.Feature {
-    private static final String LOG_TAG = "SipTransportC";
+public class SipTransportController implements RcsFeatureController.Feature,
+        OnRoleHoldersChangedListener {
+    static final int LOG_SIZE = 50;
+    static final String LOG_TAG = "SipTransportC";
 
-    private final Context mContext;
+    /**See {@link TimerAdapter#getReevaluateThrottleTimerMilliseconds()}.*/
+    private static final int REEVALUATE_THROTTLE_DEFAULT_MS = 1000;
+    /**See {@link TimerAdapter#getUpdateRegistrationDelayMilliseconds()}.*/
+    private static final int TRIGGER_UPDATE_REGISTRATION_DELAY_DEFAULT_MS = 1000;
+
+    /**
+     * {@link RoleManager} is final so we have to wrap the implementation for testing.
+     */
+    @VisibleForTesting
+    public interface RoleManagerAdapter {
+        /** See {@link RoleManager#getRoleHolders(String)} */
+        List<String> getRoleHolders(String roleName);
+        /** See {@link RoleManager#addOnRoleHoldersChangedListenerAsUser} */
+        void addOnRoleHoldersChangedListenerAsUser(Executor executor,
+                OnRoleHoldersChangedListener listener, UserHandle user);
+        /** See {@link RoleManager#removeOnRoleHoldersChangedListenerAsUser} */
+        void removeOnRoleHoldersChangedListenerAsUser(OnRoleHoldersChangedListener listener,
+                UserHandle user);
+    }
+
+    /**
+     * Adapter for timers related to this class so they can be modified during testing.
+     */
+    @VisibleForTesting
+    public interface TimerAdapter {
+        /**
+         * Time we will delay after a {@link #createSipDelegate} or {@link #destroySipDelegate}
+         * command to re-evaluate and apply any changes to the list of tracked
+         * SipDelegateControllers.
+         * <p>
+         * Another create/destroy request sent during this time will not postpone re-evaluation
+         * again.
+         */
+        int getReevaluateThrottleTimerMilliseconds();
+
+        /**
+         * Time after re-evaluate we will wait to trigger the update of IMS registration.
+         * <p>
+         * Another re-evaluate while waiting to trigger a registration update will cause this
+         * controller to cancel and reschedule the event again, further delaying the trigger to send
+         * a registration update.
+         */
+        int getUpdateRegistrationDelayMilliseconds();
+    }
+
+    private static class TimerAdapterImpl implements TimerAdapter {
+
+        @Override
+        public int getReevaluateThrottleTimerMilliseconds() {
+            return REEVALUATE_THROTTLE_DEFAULT_MS;
+        }
+
+        @Override
+        public int getUpdateRegistrationDelayMilliseconds() {
+            return TRIGGER_UPDATE_REGISTRATION_DELAY_DEFAULT_MS;
+        }
+    }
+
+    private static class RoleManagerAdapterImpl implements RoleManagerAdapter {
+
+        private final RoleManager mRoleManager;
+
+        private RoleManagerAdapterImpl(Context context) {
+            mRoleManager = context.getSystemService(RoleManager.class);
+        }
+
+        @Override
+        public List<String> getRoleHolders(String roleName) {
+            return mRoleManager.getRoleHolders(roleName);
+        }
+
+        @Override
+        public void addOnRoleHoldersChangedListenerAsUser(Executor executor,
+                OnRoleHoldersChangedListener listener, UserHandle user) {
+            mRoleManager.addOnRoleHoldersChangedListenerAsUser(executor, listener, user);
+        }
+
+        @Override
+        public void removeOnRoleHoldersChangedListenerAsUser(OnRoleHoldersChangedListener listener,
+                UserHandle user) {
+            mRoleManager.removeOnRoleHoldersChangedListenerAsUser(listener, user);
+        }
+    }
+
+    /**
+     * Used in {@link #destroySipDelegate(int, ISipDelegate, int)} to store pending destroy
+     * requests.
+     */
+    private static final class DestroyRequest {
+        public final SipDelegateController controller;
+        public final int reason;
+
+        DestroyRequest(SipDelegateController c, int r) {
+            controller = c;
+            reason = r;
+        }
+
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            DestroyRequest that = (DestroyRequest) o;
+            return reason == that.reason
+                    && controller.equals(that.controller);
+        }
+
+        @Override
+        public int hashCode() {
+            return java.util.Objects.hash(controller, reason);
+        }
+
+        @Override
+        public String toString() {
+            return "DestroyRequest{" + "controller=" + controller + ", reason=" + reason + '}';
+        }
+    }
+
+    /**
+     * Allow the ability for tests to easily mock out the SipDelegateController for testing.
+     */
+    @VisibleForTesting
+    public interface SipDelegateControllerFactory {
+        /** See {@link SipDelegateController} */
+        SipDelegateController create(int subId, DelegateRequest initialRequest, String packageName,
+                ISipTransport sipTransportImpl, ScheduledExecutorService executorService,
+                ISipDelegateConnectionStateCallback stateCallback,
+                ISipDelegateMessageCallback messageCallback);
+    }
+
+    private SipDelegateControllerFactory mDelegateControllerFactory = SipDelegateController::new;
     private final int mSlotId;
     private final ScheduledExecutorService mExecutorService;
+    private final RoleManagerAdapter mRoleManagerAdapter;
+    private final TimerAdapter mTimerAdapter;
+    private final LocalLog mLocalLog = new LocalLog(LOG_SIZE);
 
+    // A priority queue of active SipDelegateControllers, where the oldest SipDelegate gets
+    // access to the feature tag if multiple apps are allowed to request the same feature tag.
+    private final List<SipDelegateController> mDelegatePriorityQueue = new ArrayList<>();
+    // SipDelegateControllers who have been created and are pending to be added to the priority
+    // queue. Will be added into the queue in the same order as they were added here.
+    private final List<SipDelegateController> mDelegatePendingCreate = new ArrayList<>();
+    // SipDelegateControllers that are pending to be destroyed.
+    private final List<DestroyRequest> mDelegatePendingDestroy = new ArrayList<>();
+
+    // Future scheduled for operations that require the list of SipDelegateControllers to
+    // be evaluated. When the timer expires and triggers the reevaluate method, this controller
+    // will iterate through mDelegatePriorityQueue and assign Feature Tags based on role+priority.
+    private ScheduledFuture<?> mScheduledEvaluateFuture;
+    // mPendingEvaluateFTFuture creates this CompletableFuture, exposed in order to stop other
+    // evaluates from occurring while another is waiting for a result on other threads.
+    private CompletableFuture<Void> mEvaluateCompleteFuture;
+    // Future scheduled that will trigger the ImsService to update the IMS registration for the
+    // SipDelegate configuration. Will be scheduled TRIGGER_UPDATE_REGISTRATION_DELAY_MS
+    // milliseconds after a pending evaluate completes.
+    private ScheduledFuture<?> mPendingUpdateRegistrationFuture;
+    // Subscription id will change as new subscriptions are loaded on the slot.
     private int mSubId;
+    // Will go up/down as the ImsService associated with this slotId goes up/down.
     private RcsFeatureManager mRcsManager;
+    // Cached package name of the app that is considered the default SMS app.
+    private String mCachedSmsRolePackageName = "";
 
     /**
      * Create an instance of SipTransportController.
@@ -57,10 +252,11 @@
      * @param subId The subscription ID associated with this controller when it was first created.
      */
     public SipTransportController(Context context, int slotId, int subId) {
-        mContext = context;
         mSlotId = slotId;
         mSubId = subId;
 
+        mRoleManagerAdapter = new RoleManagerAdapterImpl(context);
+        mTimerAdapter = new TimerAdapterImpl();
         mExecutorService = Executors.newSingleThreadScheduledExecutor();
     }
 
@@ -69,11 +265,14 @@
      */
     @VisibleForTesting
     public SipTransportController(Context context, int slotId, int subId,
-            ScheduledExecutorService executor) {
-        mContext = context;
+            SipDelegateControllerFactory delegateFactory, RoleManagerAdapter roleManagerAdapter,
+            TimerAdapter timerAdapter, ScheduledExecutorService executor) {
         mSlotId = slotId;
         mSubId = subId;
 
+        mRoleManagerAdapter = roleManagerAdapter;
+        mTimerAdapter = timerAdapter;
+        mDelegateControllerFactory = delegateFactory;
         mExecutorService = executor;
         logi("created");
     }
@@ -95,8 +294,57 @@
 
     @Override
     public void onDestroy() {
-        // Can be null in testing.
-        mExecutorService.shutdownNow();
+        mExecutorService.submit(()-> {
+            // Ensure new create/destroy requests are denied.
+            mSubId = -1;
+            triggerDeregistrationEvent();
+            scheduleDestroyDelegates(
+                    SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SUBSCRIPTION_TORN_DOWN)
+                    .thenRun(mExecutorService::shutdown);
+        });
+    }
+
+    /**
+     * Optionally create a new {@link SipDelegate} based off of the {@link DelegateRequest} given
+     * based on the state of this controller and associate it with the given callbacks.
+     * <p>
+     * Once the {@link SipDelegate} has been created,
+     * {@link ISipDelegateConnectionStateCallback#onCreated(ISipDelegate)} must be called with
+     * the AIDL instance corresponding to the remote {@link SipDelegate}.
+     * @param subId the subId associated with the request.
+     * @param request The request parameters used to create the {@link SipDelegate}.
+     * @param delegateState The {@link DelegateConnectionStateCallback} Binder connection.
+     * @param delegateMessage The {@link DelegateConnectionMessageCallback} Binder Connection
+     * @throws ImsException if the request to create the {@link SipDelegate} did not complete.
+     */
+    public void createSipDelegate(int subId, DelegateRequest request, String packageName,
+            ISipDelegateConnectionStateCallback delegateState,
+            ISipDelegateMessageCallback delegateMessage) throws ImsException {
+        logi("createSipDelegate: request= " + request + ", packageName= " + packageName);
+        CompletableFuture<ImsException> result = new CompletableFuture<>();
+        mExecutorService.submit(() -> createSipDelegateInternal(subId, request, packageName,
+                delegateState,
+                // Capture any ImsExceptions generated during the process.
+                delegateMessage, result::complete));
+        try {
+            ImsException e = result.get();
+            logi("createSipDelegate: request finished");
+            if (e != null) {
+                throw e;
+            }
+        } catch (InterruptedException | ExecutionException e) {
+            logw("createSipDelegate: exception completing future: " + e);
+        }
+    }
+
+    /**
+     * The remote IMS application has requested the destruction of an existing {@link SipDelegate}.
+     * @param subId The subId associated with the request.
+     * @param connection The internal Binder connection associated with the {@link SipDelegate}.
+     * @param reason The reason for why the {@link SipDelegate} was destroyed.
+     */
+    public void destroySipDelegate(int subId, ISipDelegate connection, int reason) {
+        mExecutorService.execute(() -> destroySipDelegateInternal(subId, connection, reason));
     }
 
     /**
@@ -113,6 +361,104 @@
         return result;
     }
 
+    private void createSipDelegateInternal(int subId, DelegateRequest request, String packageName,
+            ISipDelegateConnectionStateCallback delegateState,
+            ISipDelegateMessageCallback delegateMessage,
+            Consumer<ImsException> startedErrorConsumer) {
+        ISipTransport transport;
+        // Send back any errors via Consumer early in creation process if it is clear that the
+        // SipDelegate will never be created.
+        try {
+            checkStateOfController(subId);
+            transport = mRcsManager.getSipTransport();
+            if (transport == null) {
+                logw("createSipDelegateInternal, transport null during request.");
+                startedErrorConsumer.accept(new ImsException("SipTransport not supported",
+                        ImsException.CODE_ERROR_UNSUPPORTED_OPERATION));
+                return;
+            } else {
+                // Release the binder thread as there were no issues processing the initial request.
+                startedErrorConsumer.accept(null);
+            }
+        } catch (ImsException e) {
+            logw("createSipDelegateInternal, ImsException during create: " + e);
+            startedErrorConsumer.accept(e);
+            return;
+        }
+
+        SipDelegateController c = mDelegateControllerFactory.create(subId, request, packageName,
+                transport, mExecutorService, delegateState, delegateMessage);
+        logi("createSipDelegateInternal: request= " + request + ", packageName= " + packageName
+                + ", controller created: " + c);
+        addPendingCreateAndEvaluate(c);
+    }
+
+    private void destroySipDelegateInternal(int subId, ISipDelegate connection, int reason) {
+        if (subId != mSubId) {
+            logw("destroySipDelegateInternal: ignoring destroy, as this is about to be destroyed "
+                    + "anyway due to subId change, delegate=" + connection);
+            return;
+        }
+        if (connection == null) {
+            logw("destroySipDelegateInternal: ignoring destroy, null connection binder.");
+            return;
+        }
+        SipDelegateController match = null;
+        for (SipDelegateController controller : mDelegatePriorityQueue) {
+            if (Objects.equal(connection.asBinder(),
+                    controller.getSipDelegateInterface().asBinder())) {
+                match = controller;
+                break;
+            }
+        }
+        if (match == null) {
+            logw("destroySipDelegateInternal: could not find matching connection=" + connection);
+            return;
+        }
+
+        logi("destroySipDelegateInternal: destroy queued for connection= " + connection);
+        addPendingDestroyAndEvaluate(match, reason);
+    }
+
+    /**
+     * Cancel pending update IMS registration events if they exist and instead send a deregister
+     * event.
+     */
+    private void triggerDeregistrationEvent() {
+        if (mPendingUpdateRegistrationFuture != null
+                && !mPendingUpdateRegistrationFuture.isDone()) {
+            // Cancel pending update and replace with a call to deregister now.
+            mPendingUpdateRegistrationFuture.cancel(false);
+            logi("triggerDeregistrationEvent: cancelling existing reg update event: "
+                    + mPendingUpdateRegistrationFuture);
+        }
+        logi("triggerDeregistrationEvent: Sending deregister event to ImsService");
+        //TODO hook up registration apis
+    }
+
+    /**
+     * Schedule an update to the IMS registration. If there is an existing update scheduled, cancel
+     * it and reschedule.
+     */
+    private void scheduleUpdateRegistration() {
+        if (mPendingUpdateRegistrationFuture != null
+                && !mPendingUpdateRegistrationFuture.isDone()) {
+            // Cancel the old pending operation and reschedule again.
+            mPendingUpdateRegistrationFuture.cancel(false);
+            logi("scheduleUpdateRegistration: cancelling existing reg update event: "
+                    + mPendingUpdateRegistrationFuture);
+        }
+        ScheduledFuture<?> f = mExecutorService.schedule(this::triggerUpdateRegistrationEvent,
+                mTimerAdapter.getUpdateRegistrationDelayMilliseconds(), TimeUnit.MILLISECONDS);
+        logi("scheduleUpdateRegistration: scheduling new event: " + f);
+        mPendingUpdateRegistrationFuture = f;
+    }
+
+    private void triggerUpdateRegistrationEvent() {
+        logi("triggerUpdateRegistrationEvent: Sending update registration event to ImsService");
+        //TODO hook up registration apis
+    }
+
     /**
      * Returns whether or not the ImsService implementation associated with the supplied subId
      * supports the SipTransport APIs.
@@ -126,6 +472,283 @@
         return (mRcsManager.getSipTransport() != null);
     }
 
+    private boolean addPendingDestroy(SipDelegateController c, int reason) {
+        DestroyRequest request = new DestroyRequest(c, reason);
+        if (!mDelegatePendingDestroy.contains(request)) {
+            return mDelegatePendingDestroy.add(request);
+        }
+        return false;
+    }
+
+    /**
+     * The supplied SipDelegateController has been destroyed and associated feature tags have been
+     * released. Trigger the re-evaluation of the priority queue with the new configuration.
+     */
+    private void addPendingDestroyAndEvaluate(SipDelegateController c, int reason) {
+        if (addPendingDestroy(c, reason)) {
+            scheduleThrottledReevaluate();
+        }
+    }
+
+    /**
+     * A new SipDelegateController has been created, add to the back of the priority queue and
+     * trigger the re-evaluation of the priority queue with the new configuration.
+     */
+    private void addPendingCreateAndEvaluate(SipDelegateController c) {
+        mDelegatePendingCreate.add(c);
+        scheduleThrottledReevaluate();
+    }
+
+    /**
+     * The priority queue has changed, which will cause a re-evaluation of the feature tags granted
+     * to each SipDelegate.
+     * <p>
+     * Note: re-evaluations are throttled to happen at a minimum to occur every
+     * REEVALUATE_THROTTLE_MS seconds. We also do not reevaluate while another reevaluate operation
+     * is in progress, so in this case, defer schedule itself.
+     */
+    private void scheduleThrottledReevaluate() {
+        if (isEvaluatePendingAndNotInProgress()) {
+            logi("scheduleThrottledReevaluate: throttling reevaluate, eval already pending: "
+                    + mScheduledEvaluateFuture);
+        } else {
+            mScheduledEvaluateFuture = mExecutorService.schedule(this::reevaluateDelegates,
+                    mTimerAdapter.getReevaluateThrottleTimerMilliseconds(), TimeUnit.MILLISECONDS);
+            logi("scheduleThrottledReevaluate: new reevaluate scheduled: "
+                    + mScheduledEvaluateFuture);
+        }
+    }
+
+    /**
+     * @return true if there is a evaluate pending, false if there is not. If evaluate has already
+     * begun, but we are waiting for it to complete, this will also return false.
+     */
+    private boolean isEvaluatePendingAndNotInProgress() {
+        boolean isEvalScheduled = mScheduledEvaluateFuture != null
+                && !mScheduledEvaluateFuture.isDone();
+        boolean isEvalInProgress = mEvaluateCompleteFuture != null
+                && !mEvaluateCompleteFuture.isDone();
+        return isEvalScheduled && !isEvalInProgress;
+    }
+
+    /**
+     * Cancel any pending re-evaluates and perform it as soon as possible. This is done in the case
+     * where we need to do something like tear down this controller or change subId.
+     */
+    private void scheduleReevaluateNow(CompletableFuture<Void> onDoneFuture) {
+        if (isEvaluatePendingAndNotInProgress()) {
+            mScheduledEvaluateFuture.cancel(false /*interrupt*/);
+            logi("scheduleReevaluateNow: cancelling pending reevaluate: "
+                    + mScheduledEvaluateFuture);
+        }
+        // we have tasks that depend on this potentially, so once the last reevaluate is done,
+        // schedule a new one right away.
+        if (mEvaluateCompleteFuture != null && !mEvaluateCompleteFuture.isDone()) {
+            mEvaluateCompleteFuture.thenRunAsync(
+                    () -> scheduleReevaluateNow(onDoneFuture), mExecutorService);
+            return;
+        }
+
+        reevaluateDelegates();
+        mEvaluateCompleteFuture.thenAccept(onDoneFuture::complete);
+    }
+
+    /**
+     * Apply all operations that have been pending by collecting pending create/destroy operations
+     * and batch applying them to the mDelegatePriorityQueue.
+     *
+     * First perform the operation of destroying all SipDelegateConnections that have been pending
+     * destroy. Next, add all pending new SipDelegateControllers to the end of
+     * mDelegatePriorityQueue and loop through all in the queue, applying feature tags to the
+     * appropriate SipDelegateController if they pass role checks and have not already been claimed
+     * by another delegate higher in the priority queue.
+     */
+    private void reevaluateDelegates() {
+        if (mEvaluateCompleteFuture != null && !mEvaluateCompleteFuture.isDone()) {
+            logw("reevaluateDelegates: last evaluate not done, deferring new request");
+            // Defer re-evaluate until after the pending re-evaluate is complete.
+            mEvaluateCompleteFuture.thenRunAsync(this::scheduleThrottledReevaluate,
+                    mExecutorService);
+            return;
+        }
+
+        // Destroy all pending destroy delegates first. Order doesn't matter.
+        List<CompletableFuture<Void>> pendingDestroyList = mDelegatePendingDestroy.stream()
+                .map(d -> triggerDestroy(d.controller, d.reason)).collect(
+                Collectors.toList());
+        CompletableFuture<Void> pendingDestroy = CompletableFuture.allOf(
+                pendingDestroyList.toArray(new CompletableFuture[mDelegatePendingDestroy.size()]));
+        mDelegatePriorityQueue.removeAll(mDelegatePendingDestroy.stream().map(d -> d.controller)
+                .collect(Collectors.toList()));
+        mDelegatePendingDestroy.clear();
+
+        // Add newly created SipDelegates to end of queue before evaluating associated features.
+        mDelegatePriorityQueue.addAll(mDelegatePendingCreate);
+        for (SipDelegateController c : mDelegatePendingCreate) {
+            logi("reevaluateDelegates: pending create: " + c);
+        }
+        mDelegatePendingCreate.clear();
+
+        // Wait for destroy stages to complete, then loop from oldest to most recent and associate
+        // feature tags that the app has requested to the SipDelegate.
+        // Each feature tag can only be associated with one SipDelegate, so as feature tags are
+        // taken, do not allow other SipDelegates to be associated with those tags as well. Each
+        // stage of the CompletableFuture chain passes the previously claimed feature tags into the
+        // next stage so that those feature tags can be denied if already claimed.
+        // Executor doesn't matter here, just composing here to transform to the next stage.
+        CompletableFuture<Set<String>> pendingChange = pendingDestroy.thenCompose((ignore) -> {
+            logi("reevaluateDelegates: destroy phase complete");
+            return CompletableFuture.completedFuture(new ArraySet<>());
+        });
+        final String cachedSmsRolePackage = mCachedSmsRolePackageName;
+        for (SipDelegateController c : mDelegatePriorityQueue) {
+            logi("reevaluateDelegates: pending reeval: " + c);
+            pendingChange = pendingChange.thenComposeAsync((takenTags) -> {
+                logi("reevaluateDelegates: last stage completed with result:" + takenTags);
+                if (takenTags == null) {
+                    // return early, the ImsService is no longer available. This will eventually be
+                    // destroyed.
+                    return CompletableFuture.completedFuture(null /*failed*/);
+                }
+                return changeSupportedFeatureTags(c, cachedSmsRolePackage, takenTags);
+            }, mExecutorService);
+        }
+
+        // Executor doesn't matter here, just adding an extra stage to print result.
+        mEvaluateCompleteFuture = pendingChange
+                .thenAccept((associatedFeatures) -> logi("reevaluateDelegates: reevaluate complete,"
+                        + " feature tags associated: " + associatedFeatures));
+        logi("reevaluateDelegates: future created.");
+    }
+
+    private CompletableFuture<Void> triggerDestroy(SipDelegateController c, int reason) {
+        return c.destroy(isForcedFromReason(reason), reason)
+                // Executor doesn't matter here, just for logging.
+                .thenAccept((delegateReason) -> logi("destroy triggered with " + reason
+                        + " and finished with reason= " + delegateReason));
+    }
+
+    private boolean isForcedFromReason(int reason) {
+        switch (reason) {
+            case SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_UNKNOWN:
+                logw("isForcedFromReason, unknown reason");
+                /*intentional fallthrough*/
+            case SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP:
+                /*intentional fallthrough*/
+            case SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_USER_DISABLED_RCS:
+                return false;
+            case SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD:
+                /*intentional fallthrough*/
+            case SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SUBSCRIPTION_TORN_DOWN:
+                return true;
+        }
+        logw("isForcedFromReason, unexpected reason: " + reason);
+        return false;
+    }
+
+    /**
+     * Called by RoleManager when a role has changed so that we can query the new role holder.
+     * @param roleName the name of the role whose holders are changed
+     * @param user the user for this role holder change
+     */
+    // Called on mExecutorThread
+    @Override
+    public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) {
+        logi("onRoleHoldersChanged, roleName= " + roleName + ", user= " + user);
+        // Only monitor changes on the system
+        if (!UserHandle.SYSTEM.equals(user)) {
+            return;
+        }
+
+        if (!RoleManager.ROLE_SMS.equals(roleName)) {
+            logi("onRoleHoldersChanged, ignoring non SMS role change");
+            // TODO: only target default sms app for now and add new roles later using
+            // CarrierConfigManager
+            return;
+        }
+        updateRoleCache();
+        // new denied tags will be picked up when reevaluate completes.
+        scheduleThrottledReevaluate();
+    }
+
+
+    private void updateRoleCache() {
+        String newSmsRolePackageName = "";
+        try {
+            // Only one app can fulfill the SMS role.
+            newSmsRolePackageName = mRoleManagerAdapter.getRoleHolders(RoleManager.ROLE_SMS)
+                    .stream().findFirst().orElse("");
+        } catch (Exception e) {
+            logi("updateRoleCache: exception=" + e);
+        }
+
+        logi("updateRoleCache: new packageName=" + newSmsRolePackageName);
+        if (TextUtils.equals(mCachedSmsRolePackageName, newSmsRolePackageName)) {
+            logi("updateRoleCache, skipping, role did not change");
+            return;
+        }
+        mCachedSmsRolePackageName = newSmsRolePackageName;
+    }
+
+    /**
+     * Check the requested roles for the specified package name and return the tags that were
+     * applied to that SipDelegateController.
+     * @param controller Controller to attribute feature tags to.
+     * @param alreadyRequestedTags The feature tags that were already granted to other SipDelegates.
+     * @return Once complete, contains the set of feature tags that the SipDelegate now has
+     * associated with it along with the feature tags that previous SipDelegates had.
+     *
+     * // TODO: we currently only track SMS role, extend to support other roles as well.
+     */
+    private CompletableFuture<Set<String>> changeSupportedFeatureTags(
+            SipDelegateController controller, String smsRolePackageName,
+            Set<String> alreadyRequestedTags) {
+        Set<String> requestedFeatureTags = controller.getInitialRequest().getFeatureTags();
+        String packageName = controller.getPackageName();
+        if (!smsRolePackageName.equals(packageName)) {
+            // Deny all tags.
+            Set<FeatureTagState> deniedTags = new ArraySet<>();
+            for (String s : requestedFeatureTags) {
+                deniedTags.add(new FeatureTagState(s,
+                        SipDelegateManager.DENIED_REASON_NOT_ALLOWED));
+            }
+            CompletableFuture<Boolean> pendingDeny = controller.changeSupportedFeatureTags(
+                    Collections.emptySet(), deniedTags);
+            logi("changeSupportedFeatureTags pendingDeny=" + pendingDeny);
+            // do not worry about executor used here, this stage used to interpret result + add log.
+            return pendingDeny.thenApply((completedSuccessfully) ->  {
+                logi("changeSupportedFeatureTags: deny completed: " + completedSuccessfully);
+                if (!completedSuccessfully) return null;
+                // Return back the previous list of requested tags, as we did not add any more.
+                return alreadyRequestedTags;
+            });
+        }
+
+        ArraySet<String> previouslyGrantedTags = new ArraySet<>(alreadyRequestedTags);
+        // deny tags already used by other delegates
+        Set<FeatureTagState> deniedTags = new ArraySet<>();
+        for (String s : requestedFeatureTags) {
+            if (previouslyGrantedTags.contains(s)) {
+                deniedTags.add(new FeatureTagState(s,
+                        SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE));
+            }
+        }
+        Set<String> nonDeniedTags = requestedFeatureTags.stream()
+                .filter(r -> !previouslyGrantedTags.contains(r))
+                .collect(Collectors.toSet());
+        // Add newly granted tags to the already requested tags list.
+        previouslyGrantedTags.addAll(nonDeniedTags);
+        CompletableFuture<Boolean> pendingChange = controller.changeSupportedFeatureTags(
+                nonDeniedTags, deniedTags);
+        logi("changeSupportedFeatureTags pendingChange=" + pendingChange);
+        // do not worry about executor used here, this stage used to interpret result + add log.
+        return pendingChange.thenApply((completedSuccessfully) ->  {
+            logi("changeSupportedFeatureTags: change completed: " + completedSuccessfully);
+            if (!completedSuccessfully) return null;
+            return previouslyGrantedTags;
+        });
+    }
+
     /**
      * Run a Callable on the ExecutorService Thread and wait for the result.
      * If an ImsException is thrown, catch it and rethrow it to caller.
@@ -169,7 +792,31 @@
 
     private void onRcsManagerChanged(RcsFeatureManager m) {
         logi("manager changed, " + mRcsManager + "->" + m);
+        if (mRcsManager == m) return;
         mRcsManager = m;
+        if (mRcsManager == null) {
+            logi("onRcsManagerChanged: lost connection to ImsService, tearing down...");
+            unregisterListeners();
+            scheduleDestroyDelegates(SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD);
+        } else {
+            logi("onRcsManagerChanged: registering listeners/updating role cache...");
+            registerListeners();
+            updateRoleCache();
+        }
+    }
+
+    private void registerListeners() {
+        try {
+            mRoleManagerAdapter.addOnRoleHoldersChangedListenerAsUser(mExecutorService, this,
+                    UserHandle.SYSTEM);
+        } catch (Exception e) {
+            logi("registerListeners: exception=" + e);
+        }
+    }
+
+    private void unregisterListeners() {
+        mCachedSmsRolePackageName = "";
+        mRoleManagerAdapter.removeOnRoleHoldersChangedListenerAsUser(this, UserHandle.SYSTEM);
     }
 
     /**
@@ -178,18 +825,65 @@
      */
     private void onSubIdChanged(int newSubId) {
         logi("subId changed, " + mSubId + "->" + newSubId);
-        mSubId = newSubId;
+        if (mSubId != newSubId) {
+            // Swap subId, any pending create/destroy on old subId will be denied.
+            mSubId = newSubId;
+            scheduleDestroyDelegates(
+                    SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SUBSCRIPTION_TORN_DOWN);
+            return;
+        }
+        // TODO: if subId hasn't changed this means that we should load in any new carrier configs
+        // that we care about and apply.
     }
 
-    private void logi(String message) {
-        Log.i(LOG_TAG, getPrefix() + ": " + message);
+    /**
+     * Destroy all tracked SipDelegateConnections due to the subscription being torn down.
+     * @return A CompletableFuture that will complete when all SipDelegates have been torn down.
+     */
+    private CompletableFuture<Void> scheduleDestroyDelegates(int reason) {
+        boolean addedDestroy = false;
+        for (SipDelegateController c : mDelegatePriorityQueue) {
+            logi("scheduleDestroyDelegates: Controller pending destroy: " + c);
+            addedDestroy |= addPendingDestroy(c, reason);
+        }
+        if (addedDestroy) {
+            CompletableFuture<Void> pendingDestroy = new CompletableFuture<>();
+            scheduleReevaluateNow(pendingDestroy);
+            return pendingDestroy;
+        } else {
+            return CompletableFuture.completedFuture(null);
+        }
     }
 
-    private void logw(String message) {
-        Log.w(LOG_TAG, getPrefix() + ": " + message);
+    @Override
+    public void dump(PrintWriter printWriter) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
+        pw.println("SipTransportController" + "[" + mSlotId  + "->" + mSubId + "]:");
+        pw.increaseIndent();
+        pw.println("LocalLog:");
+        pw.increaseIndent();
+        mLocalLog.dump(pw);
+        pw.decreaseIndent();
+        pw.println("SipDelegateControllers (in priority order):");
+        pw.increaseIndent();
+        if (mDelegatePriorityQueue.isEmpty()) {
+            pw.println("[NONE]");
+        } else {
+            for (SipDelegateController c : mDelegatePriorityQueue) {
+                c.dump(pw);
+            }
+        }
+        pw.decreaseIndent();
+        pw.decreaseIndent();
     }
 
-    private String getPrefix() {
-        return "[" + mSlotId + "," + mSubId + "]";
+    private void logi(String log) {
+        Log.w(LOG_TAG, "[" + mSlotId  + "->" + mSubId + "] " + log);
+        mLocalLog.log("[I] " + log);
+    }
+
+    private void logw(String log) {
+        Log.w(LOG_TAG, "[" + mSlotId  + "->" + mSubId + "] " + log);
+        mLocalLog.log("[W] " + log);
     }
 }
diff --git a/src/com/android/services/telephony/rcs/TelephonyRcsService.java b/src/com/android/services/telephony/rcs/TelephonyRcsService.java
index 79170af..941a6a8 100644
--- a/src/com/android/services/telephony/rcs/TelephonyRcsService.java
+++ b/src/com/android/services/telephony/rcs/TelephonyRcsService.java
@@ -47,21 +47,19 @@
     private static final String LOG_TAG = "TelephonyRcsService";
 
     /**
-     * Used to inject RcsFeatureController and UserCapabilityExchangeImpl instances for testing.
+     * Used to inject RcsFeatureController and UceController instances for testing.
      */
     @VisibleForTesting
     public interface FeatureFactory {
         /**
-         * @return an {@link RcsFeatureController} assoicated with the slot specified.
+         * @return an {@link RcsFeatureController} associated with the slot specified.
          */
         RcsFeatureController createController(Context context, int slotId);
 
         /**
-         * @return an instance of {@link UserCapabilityExchangeImpl} associated with the slot
-         * specified.
+         * @return an instance of {@link UceControllerManager} associated with the slot specified.
          */
-        UserCapabilityExchangeImpl createUserCapabilityExchange(Context context, int slotId,
-                int subId);
+        UceControllerManager createUceControllerManager(Context context, int slotId, int subId);
 
         /**
          * @return an instance of {@link SipTransportController} for the slot and subscription
@@ -77,9 +75,9 @@
         }
 
         @Override
-        public UserCapabilityExchangeImpl createUserCapabilityExchange(Context context, int slotId,
+        public UceControllerManager createUceControllerManager(Context context, int slotId,
                 int subId) {
-            return new UserCapabilityExchangeImpl(context, slotId, subId);
+            return new UceControllerManager(context, slotId, subId);
         }
 
         @Override
@@ -237,13 +235,13 @@
 
     private void updateSupportedFeatures(RcsFeatureController c, int slotId, int subId) {
         if (doesSubscriptionSupportPresence(subId)) {
-            if (c.getFeature(UserCapabilityExchangeImpl.class) == null) {
-                c.addFeature(mFeatureFactory.createUserCapabilityExchange(mContext, slotId, subId),
-                        UserCapabilityExchangeImpl.class);
+            if (c.getFeature(UceControllerManager.class) == null) {
+                c.addFeature(mFeatureFactory.createUceControllerManager(mContext, slotId, subId),
+                        UceControllerManager.class);
             }
         } else {
-            if (c.getFeature(UserCapabilityExchangeImpl.class) != null) {
-                c.removeFeature(UserCapabilityExchangeImpl.class);
+            if (c.getFeature(UceControllerManager.class) != null) {
+                c.removeFeature(UceControllerManager.class);
             }
         }
 
diff --git a/src/com/android/services/telephony/rcs/UceControllerManager.java b/src/com/android/services/telephony/rcs/UceControllerManager.java
new file mode 100644
index 0000000..d1f91d1
--- /dev/null
+++ b/src/com/android/services/telephony/rcs/UceControllerManager.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2020 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.rcs;
+
+import android.content.Context;
+import android.net.Uri;
+import android.telephony.ims.ImsException;
+import android.telephony.ims.RcsUceAdapter;
+import android.telephony.ims.RcsUceAdapter.PublishState;
+import android.telephony.ims.aidl.IRcsUceControllerCallback;
+import android.telephony.ims.aidl.IRcsUcePublishStateCallback;
+import android.util.Log;
+
+import com.android.ims.RcsFeatureManager;
+import com.android.ims.rcs.uce.UceController;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IndentingPrintWriter;
+
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+/**
+ * Responsible for managing the creation and destruction of UceController. It also received the
+ * requests from {@link com.android.phone.ImsRcsController} and pass these requests to
+ * {@link UceController}
+ */
+public class UceControllerManager implements RcsFeatureController.Feature {
+
+    private static final String LOG_TAG = "UceControllerManager";
+
+    private final int mSlotId;
+    private final Context mContext;
+    private final ExecutorService mExecutorService;
+
+    private volatile UceController mUceController;
+
+    public UceControllerManager(Context context, int slotId, int subId) {
+        Log.d(LOG_TAG, "create: slotId=" + slotId + ", subId=" + subId);
+
+        mSlotId = slotId;
+        mContext = context;
+        mExecutorService = Executors.newSingleThreadExecutor();
+        mUceController = new UceController(mContext, subId);
+    }
+
+    /**
+     * Constructor to inject dependencies for testing.
+     */
+    @VisibleForTesting
+    public UceControllerManager(Context context, int slotId, int subId, ExecutorService executor) {
+        mSlotId = slotId;
+        mContext = context;
+        mExecutorService = executor;
+        mUceController = new UceController(mContext, subId);
+    }
+
+    @Override
+    public void onRcsConnected(RcsFeatureManager manager) {
+        mExecutorService.submit(() -> mUceController.onRcsConnected(manager));
+    }
+
+    @Override
+    public void onRcsDisconnected() {
+        mExecutorService.submit(() -> mUceController.onRcsDisconnected());
+    }
+
+    @Override
+    public void onDestroy() {
+        Log.d(LOG_TAG, "onDestroy");
+        mExecutorService.submit(() -> mUceController.onDestroy());
+        // When the shutdown is called, it will refuse any new tasks and let existing tasks finish.
+        mExecutorService.shutdown();
+    }
+
+    /**
+     * This method will be called when either the subscription ID associated with the slot has
+     * changed or the carrier configuration associated with the same subId has changed.
+     */
+    @Override
+    public void onAssociatedSubscriptionUpdated(int subId) {
+        mExecutorService.submit(() -> {
+            Log.i(LOG_TAG, "onAssociatedSubscriptionUpdated: slotId=" + mSlotId
+                    + ", subId=" + subId);
+
+            // Destroy existing UceController and create a new one.
+            mUceController.onDestroy();
+            mUceController = new UceController(mContext, subId);
+        });
+    }
+
+    @VisibleForTesting
+    public void setUceController(UceController uceController) {
+        mUceController = uceController;
+    }
+
+    /**
+     * Request the capabilities for contacts.
+     *
+     * @param contactNumbers A list of numbers that the capabilities are being requested for.
+     * @param c A callback for when the request for capabilities completes.
+     * @throws ImsException if the ImsService connected to this controller is currently down.
+     */
+    public void requestCapabilities(List<Uri> contactNumbers, IRcsUceControllerCallback c)
+            throws ImsException {
+        Future future = mExecutorService.submit(() -> {
+            checkUceControllerState();
+            mUceController.requestCapabilities(contactNumbers, c);
+            return true;
+        });
+
+        try {
+            future.get();
+        } catch (ExecutionException | InterruptedException e) {
+            Log.w(LOG_TAG, "requestCapabilities: " + e);
+            Throwable cause = e.getCause();
+            if (cause instanceof ImsException) {
+                throw (ImsException) cause;
+            }
+        }
+    }
+
+    /**
+     * Request the capabilities for the given contact.
+     * @param contactNumber The contact of the capabilities are being requested for.
+     * @param c A callback for when the request for capabilities completes.
+     * @throws ImsException if the ImsService connected to this controller is currently down.
+     */
+    public void requestNetworkAvailability(Uri contactNumber, IRcsUceControllerCallback c)
+            throws ImsException {
+        Future future = mExecutorService.submit(() -> {
+            checkUceControllerState();
+            mUceController.requestAvailability(contactNumber, c);
+            return true;
+        });
+
+        try {
+            future.get();
+        } catch (ExecutionException | InterruptedException e) {
+            Log.w(LOG_TAG, "requestNetworkAvailability exception: " + e);
+            Throwable cause = e.getCause();
+            if (cause instanceof ImsException) {
+                throw (ImsException) cause;
+            }
+        }
+    }
+
+    /**
+     * Get the UCE publish state.
+     *
+     * @throws ImsException if the ImsService connected to this controller is currently down.
+     */
+    public @PublishState int getUcePublishState() throws ImsException {
+        Future future = mExecutorService.submit(() -> {
+            checkUceControllerState();
+            return mUceController.getUcePublishState();
+        });
+
+        try {
+            return (Integer) future.get();
+        } catch (ExecutionException | InterruptedException e) {
+            Log.w(LOG_TAG, "requestNetworkAvailability exception: " + e);
+            Throwable cause = e.getCause();
+            if (cause instanceof ImsException) {
+                throw (ImsException) cause;
+            }
+            return RcsUceAdapter.PUBLISH_STATE_OTHER_ERROR;
+        }
+    }
+
+    /**
+     * Register the Publish state changed callback.
+     *
+     * @throws ImsException if the ImsService connected to this controller is currently down.
+     */
+    public void registerPublishStateCallback(IRcsUcePublishStateCallback c) throws ImsException {
+        Future future = mExecutorService.submit(() -> {
+            checkUceControllerState();
+            mUceController.registerPublishStateCallback(c);
+            return true;
+        });
+
+        try {
+            future.get();
+        } catch (ExecutionException | InterruptedException e) {
+            Log.w(LOG_TAG, "registerPublishStateCallback exception: " + e);
+            Throwable cause = e.getCause();
+            if (cause instanceof ImsException) {
+                throw (ImsException) cause;
+            }
+        }
+    }
+
+    /**
+     * Unregister the existing publish state changed callback.
+     */
+    public void unregisterPublishStateCallback(IRcsUcePublishStateCallback c) {
+        Future future = mExecutorService.submit(() -> {
+            if (checkUceControllerState()) {
+                mUceController.unregisterPublishStateCallback(c);
+            }
+            return true;
+        });
+
+        try {
+            future.get();
+        } catch (ExecutionException | InterruptedException e) {
+            Log.w(LOG_TAG, "unregisterPublishStateCallback exception: " + e);
+        }
+    }
+
+    private boolean checkUceControllerState() throws ImsException {
+        if (mUceController == null || mUceController.isUnavailable()) {
+            throw new ImsException("UCE controller is unavailable",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+        return true;
+    }
+
+
+    @Override
+    public void dump(PrintWriter printWriter) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
+        pw.println("UceControllerManager" + "[" + mSlotId + "]:");
+        pw.increaseIndent();
+        pw.println("UceController available = " + mUceController != null);
+        //TODO: Add dump for UceController
+        pw.decreaseIndent();
+    }
+}
diff --git a/src/com/android/services/telephony/rcs/UserCapabilityExchangeImpl.java b/src/com/android/services/telephony/rcs/UserCapabilityExchangeImpl.java
deleted file mode 100644
index ee0c5be..0000000
--- a/src/com/android/services/telephony/rcs/UserCapabilityExchangeImpl.java
+++ /dev/null
@@ -1,1065 +0,0 @@
-/*
- * Copyright (C) 2020 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.rcs;
-
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PersistableBundle;
-import android.os.RemoteCallbackList;
-import android.os.RemoteException;
-import android.provider.Settings;
-import android.provider.Telephony;
-import android.telecom.TelecomManager;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.CarrierConfigManager;
-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.ProvisioningManager;
-import android.telephony.ims.RcsContactUceCapability;
-import android.telephony.ims.RcsUceAdapter;
-import android.telephony.ims.RegistrationManager;
-import android.telephony.ims.aidl.IRcsUceControllerCallback;
-import android.telephony.ims.aidl.IRcsUcePublishStateCallback;
-import android.telephony.ims.feature.MmTelFeature;
-import android.telephony.ims.stub.RcsCapabilityExchange;
-import android.telephony.ims.stub.RcsPresenceExchangeImplBase;
-import android.util.Log;
-
-import com.android.ims.RcsFeatureManager;
-import com.android.ims.RcsFeatureManager.RcsFeatureCallbacks;
-import com.android.ims.ResultCode;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.phone.R;
-import com.android.service.ims.presence.ContactCapabilityResponse;
-import com.android.service.ims.presence.PresenceBase;
-import com.android.service.ims.presence.PresencePublication;
-import com.android.service.ims.presence.PresencePublisher;
-import com.android.service.ims.presence.PresenceSubscriber;
-import com.android.service.ims.presence.SubscribePublisher;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.stream.Collectors;
-
-/**
- * Implements User Capability Exchange using Presence.
- */
-public class UserCapabilityExchangeImpl implements RcsFeatureController.Feature, SubscribePublisher,
-        PresencePublisher {
-
-    private static final String LOG_TAG = "RcsUceImpl";
-
-    private final int mSlotId;
-    private volatile int mSubId;
-    private volatile boolean mImsContentChangedCallbackRegistered = false;
-    // The result of requesting publish
-    private volatile int mPublishState = PresenceBase.PUBLISH_STATE_NOT_PUBLISHED;
-    // The network type which IMS registers on
-    private volatile int mNetworkRegistrationType = AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
-    // The MMTel capabilities of this subscription Id
-    private MmTelFeature.MmTelCapabilities mMmTelCapabilities;
-    private final Object mCapabilitiesLock = new Object();
-
-    private final Context mContext;
-    private final UceImplHandler mUceImplHandler;
-    private RcsFeatureManager mRcsFeatureManager;
-    private final PresencePublication mPresencePublication;
-    private final PresenceSubscriber mPresenceSubscriber;
-
-    // The task Ids of updating capabilities
-    private final Set<Integer> mRequestingPublishTaskIds = new HashSet<>();
-
-    // The callbacks to notify publish state changed.
-    private final RemoteCallbackList<IRcsUcePublishStateCallback> mPublishStateCallbacks;
-
-    // The task Ids of pending availability request.
-    private final Set<Integer> mPendingAvailabilityRequests = new HashSet<>();
-
-    private final ConcurrentHashMap<Integer, IRcsUceControllerCallback> mPendingCapabilityRequests =
-            new ConcurrentHashMap<>();
-
-    UserCapabilityExchangeImpl(Context context, int slotId, int subId) {
-        mSlotId = slotId;
-        mSubId = subId;
-        logi("created");
-
-        mContext = context;
-        mPublishStateCallbacks = new RemoteCallbackList<>();
-
-        HandlerThread handlerThread = new HandlerThread("UceImplHandlerThread");
-        handlerThread.start();
-        mUceImplHandler = new UceImplHandler(this, handlerThread.getLooper());
-
-        String[] volteError = context.getResources().getStringArray(
-                R.array.config_volte_provision_error_on_publish_response);
-        String[] rcsError = context.getResources().getStringArray(
-                R.array.config_rcs_provision_error_on_publish_response);
-
-        // Initialize PresencePublication
-        mPresencePublication = new PresencePublication(null /*PresencePublisher*/, context,
-                volteError, rcsError);
-        // Initialize PresenceSubscriber
-        mPresenceSubscriber = new PresenceSubscriber(null /*SubscribePublisher*/, context,
-                volteError, rcsError);
-
-        onAssociatedSubscriptionUpdated(mSubId);
-        registerReceivers();
-    }
-
-    @VisibleForTesting
-    UserCapabilityExchangeImpl(Context context, int slotId, int subId, Looper looper,
-            PresencePublication presencePublication, PresenceSubscriber presenceSubscriber,
-            RemoteCallbackList<IRcsUcePublishStateCallback> publishStateCallbacks) {
-        mSlotId = slotId;
-        mSubId = subId;
-        mContext = context;
-        mPublishStateCallbacks = publishStateCallbacks;
-        mUceImplHandler = new UceImplHandler(this, looper);
-        mPresencePublication = presencePublication;
-        mPresenceSubscriber = presenceSubscriber;
-        onAssociatedSubscriptionUpdated(mSubId);
-        registerReceivers();
-    }
-
-    // Runs on main thread.
-    @Override
-    public void onRcsConnected(RcsFeatureManager rcsFeatureManager) {
-        logi("onRcsConnected");
-        mRcsFeatureManager = rcsFeatureManager;
-        mRcsFeatureManager.addFeatureListenerCallback(mRcsFeatureCallback);
-
-        mPresencePublication.updatePresencePublisher(this);
-        mPresenceSubscriber.updatePresenceSubscriber(this);
-    }
-
-    // Runs on main thread.
-    @Override
-    public void onRcsDisconnected() {
-        logi("onRcsDisconnected");
-        mPresencePublication.removePresencePublisher();
-        mPresenceSubscriber.removePresenceSubscriber();
-
-        if (mRcsFeatureManager != null) {
-            mRcsFeatureManager.releaseConnection();
-            mRcsFeatureManager = null;
-        }
-    }
-
-    // Runs on main thread.
-    @Override
-    public void onAssociatedSubscriptionUpdated(int subId) {
-        logi("onAssociatedSubscriptionUpdated: new subId=" + subId);
-
-        // Listen to the IMS content changed with new subId.
-        mUceImplHandler.registerImsContentChangedReceiver(subId);
-
-        mSubId = subId;
-        mPresencePublication.handleAssociatedSubscriptionChanged(subId);
-        mPresenceSubscriber.handleAssociatedSubscriptionChanged(subId);
-    }
-
-    /**
-     * Should be called before destroying this instance.
-     * This instance is not usable after this method is called.
-     */
-    // Called on main thread.
-    public void onDestroy() {
-        logi("onDestroy");
-        mUceImplHandler.getLooper().quit();
-        unregisterReceivers();
-        unregisterImsProvisionCallback(mSubId);
-        onRcsDisconnected();
-    }
-
-    /**
-     * @return the UCE Publish state.
-     */
-    // May happen on a Binder thread, PresencePublication locks to get result.
-    public int getUcePublishState() {
-        int publishState = mPresencePublication.getPublishState();
-        return toUcePublishState(publishState);
-    }
-
-    @VisibleForTesting
-    public UceImplHandler getHandler() {
-        return mUceImplHandler;
-    }
-
-    /**
-     * Register receiver to receive UCE publish state changed.
-     */
-    public void registerPublishStateCallback(IRcsUcePublishStateCallback c) {
-        synchronized (mPublishStateCallbacks) {
-            mPublishStateCallbacks.register(c);
-        }
-    }
-
-    /**
-     * Unregister UCE publish state callback.
-     */
-    public void unregisterUcePublishStateCallback(IRcsUcePublishStateCallback c) {
-        synchronized (mPublishStateCallbacks) {
-            mPublishStateCallbacks.unregister(c);
-        }
-    }
-
-    private void clearPublishStateCallbacks() {
-        synchronized (mPublishStateCallbacks) {
-            logi("clearPublishStateCallbacks");
-            final int lastIndex = mPublishStateCallbacks.getRegisteredCallbackCount() - 1;
-            for (int index = lastIndex; index >= 0; index--) {
-                IRcsUcePublishStateCallback callback =
-                        mPublishStateCallbacks.getRegisteredCallbackItem(index);
-                mPublishStateCallbacks.unregister(callback);
-            }
-        }
-    }
-
-    private void notifyPublishStateChanged(@PresenceBase.PresencePublishState int state) {
-        int result = toUcePublishState(state);
-        synchronized (mPublishStateCallbacks) {
-            mPublishStateCallbacks.broadcast(c -> {
-                try {
-                    c.onPublishStateChanged(result);
-                } catch (RemoteException e) {
-                    logw("notifyPublishStateChanged error: " + e);
-                }
-            });
-        }
-    }
-
-    /**
-     * Perform a capabilities request and call {@link IRcsUceControllerCallback} with the result.
-     */
-    // May happen on a Binder thread, PresenceSubscriber locks when requesting Capabilities.
-    public void requestCapabilities(List<Uri> contactNumbers, IRcsUceControllerCallback c) {
-        List<String> numbers = contactNumbers.stream()
-                .map(UserCapabilityExchangeImpl::getNumberFromUri).collect(Collectors.toList());
-        int taskId = mPresenceSubscriber.requestCapability(numbers,
-                new ContactCapabilityResponse() {
-                    @Override
-                    public void onSuccess(int reqId) {
-                        logi("onSuccess called for reqId:" + reqId);
-                    }
-
-                    @Override
-                    public void onError(int reqId, int resultCode) {
-                        IRcsUceControllerCallback c = mPendingCapabilityRequests.remove(reqId);
-                        try {
-                            if (c != null) {
-                                c.onError(toUceError(resultCode));
-                            } else {
-                                logw("onError called for unknown reqId:" + reqId);
-                            }
-                        } catch (RemoteException e) {
-                            logi("Calling back to dead service");
-                        }
-                    }
-
-                    @Override
-                    public void onFinish(int reqId) {
-                        logi("onFinish called for reqId:" + reqId);
-                    }
-
-                    @Override
-                    public void onTimeout(int reqId) {
-                        IRcsUceControllerCallback c = mPendingCapabilityRequests.remove(reqId);
-                        try {
-                            if (c != null) {
-                                c.onError(RcsUceAdapter.ERROR_REQUEST_TIMEOUT);
-                            } else {
-                                logw("onTimeout called for unknown reqId:" + reqId);
-                            }
-                        } catch (RemoteException e) {
-                            logi("Calling back to dead service");
-                        }
-                    }
-
-                    @Override
-                    public void onCapabilitiesUpdated(int reqId,
-                            List<RcsContactUceCapability> contactCapabilities,
-                            boolean updateLastTimestamp) {
-                        IRcsUceControllerCallback c = mPendingCapabilityRequests.remove(reqId);
-                        try {
-                            if (c != null) {
-                                c.onCapabilitiesReceived(contactCapabilities);
-                            } else {
-                                logw("onCapabilitiesUpdated, unknown reqId:" + reqId);
-                            }
-                        } catch (RemoteException e) {
-                            logw("onCapabilitiesUpdated on dead service");
-                        }
-                    }
-                });
-        if (taskId < 0) {
-            try {
-                c.onError(toUceError(taskId));
-            } catch (RemoteException e) {
-                logi("Calling back to dead service");
-            }
-            return;
-        }
-        mPendingCapabilityRequests.put(taskId, c);
-    }
-
-    @Override
-    public int requestCapability(String[] formattedContacts, int taskId) {
-        if (formattedContacts == null || formattedContacts.length == 0) {
-            logw("requestCapability error: contacts is null.");
-            return ResultCode.SUBSCRIBE_INVALID_PARAM;
-        }
-        if (mRcsFeatureManager == null) {
-            logw("requestCapability error: RcsFeatureManager is null.");
-            return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-        }
-
-        logi("requestCapability: taskId=" + taskId);
-
-        try {
-            List<Uri> contactList = Arrays.stream(formattedContacts)
-                    .map(Uri::parse).collect(Collectors.toList());
-            mRcsFeatureManager.requestCapabilities(contactList, taskId);
-        } catch (Exception e) {
-            logw("requestCapability error: " + e.getMessage());
-            return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-        }
-        return ResultCode.SUCCESS;
-    }
-
-    @Override
-    public int requestAvailability(String formattedContact, int taskId) {
-        if (formattedContact == null || formattedContact.isEmpty()) {
-            logw("requestAvailability error: contact is null.");
-            return ResultCode.SUBSCRIBE_INVALID_PARAM;
-        }
-        if (mRcsFeatureManager == null) {
-            logw("requestAvailability error: RcsFeatureManager is null.");
-            return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-        }
-
-        logi("requestAvailability: taskId=" + taskId);
-        addRequestingAvailabilityTaskId(taskId);
-
-        try {
-            Uri contactUri = Uri.parse(formattedContact);
-            List<Uri> contactUris = new ArrayList<>(Arrays.asList(contactUri));
-            mRcsFeatureManager.requestCapabilities(contactUris, taskId);
-        } catch (Exception e) {
-            logw("requestAvailability error: " + e.getMessage());
-            removeRequestingAvailabilityTaskId(taskId);
-            return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-        }
-        return ResultCode.SUCCESS;
-    }
-
-    @Override
-    public int getStackStatusForCapabilityRequest() {
-        if (mRcsFeatureManager == null) {
-            logw("Check Stack status: Error! RcsFeatureManager is null.");
-            return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-        }
-
-        if (!isCapabilityDiscoveryEnabled(mSubId)) {
-            logw("Check Stack status: Error! capability discovery not enabled");
-            return ResultCode.ERROR_SERVICE_NOT_ENABLED;
-        }
-
-        if (!isEabProvisioned(mContext, mSubId)) {
-            logw("Check Stack status: Error! EAB provisioning disabled.");
-            return ResultCode.ERROR_SERVICE_NOT_ENABLED;
-        }
-
-        if (getPublisherState() != PresenceBase.PUBLISH_STATE_200_OK) {
-            logw("Check Stack status: Error! publish state " + getPublisherState());
-            return ResultCode.ERROR_SERVICE_NOT_PUBLISHED;
-        }
-        return ResultCode.SUCCESS;
-    }
-
-    /**
-     * The feature callback is to receive the request and update from RcsPresExchangeImplBase
-     */
-    @VisibleForTesting
-    public RcsFeatureCallbacks mRcsFeatureCallback = new RcsFeatureCallbacks() {
-        public void onCommandUpdate(int commandCode, int operationToken) {
-            logi("onCommandUpdate: code=" + commandCode + ", token=" + operationToken);
-            if (isPublishRequestExisted(operationToken)) {
-                onCommandUpdateForPublishRequest(commandCode, operationToken);
-            } else if (isCapabilityRequestExisted(operationToken)) {
-                onCommandUpdateForCapabilityRequest(commandCode, operationToken);
-            } else if (isAvailabilityRequestExisted(operationToken)) {
-                onCommandUpdateForAvailabilityRequest(commandCode, operationToken);
-            } else {
-                logw("onCommandUpdate: invalid token " + operationToken);
-            }
-        }
-
-        /** See {@link RcsPresenceExchangeImplBase#onNetworkResponse(int, String, int)} */
-        public void onNetworkResponse(int responseCode, String reason, int operationToken) {
-            logi("onNetworkResponse: code=" + responseCode + ", reason=" + reason
-                    + ", operationToken=" + operationToken);
-            if (isPublishRequestExisted(operationToken)) {
-                onNetworkResponseForPublishRequest(responseCode, reason, operationToken);
-            } else if (isCapabilityRequestExisted(operationToken)) {
-                onNetworkResponseForCapabilityRequest(responseCode, reason, operationToken);
-            } else if (isAvailabilityRequestExisted(operationToken)) {
-                onNetworkResponseForAvailabilityRequest(responseCode, reason, operationToken);
-            } else {
-                logw("onNetworkResponse: invalid token " + operationToken);
-            }
-        }
-
-        /** See {@link RcsPresenceExchangeImplBase#onCapabilityRequestResponse(List, int)} */
-        public void onCapabilityRequestResponsePresence(List<RcsContactUceCapability> infos,
-                int operationToken) {
-            if (isAvailabilityRequestExisted(operationToken)) {
-                handleAvailabilityReqResponse(infos, operationToken);
-            } else if (isCapabilityRequestExisted(operationToken)) {
-                handleCapabilityReqResponse(infos, operationToken);
-            } else {
-                logw("capability request response: invalid token " + operationToken);
-            }
-        }
-
-        /** See {@link RcsPresenceExchangeImplBase#onNotifyUpdateCapabilites(int)} */
-        public void onNotifyUpdateCapabilities(int publishTriggerType) {
-            logi("onNotifyUpdateCapabilities: type=" + publishTriggerType);
-            mUceImplHandler.notifyUpdateCapabilities(publishTriggerType);
-        }
-
-        /** See {@link RcsPresenceExchangeImplBase#onUnpublish()} */
-        public void onUnpublish() {
-            logi("onUnpublish");
-            mUceImplHandler.unpublish();
-        }
-    };
-
-    private static class UceImplHandler extends Handler {
-        private static final int EVENT_REGISTER_IMS_CHANGED_RECEIVER = 1;
-        private static final int EVENT_NOTIFY_UPDATE_CAPABILITIES = 2;
-        private static final int EVENT_UNPUBLISH = 3;
-
-        private static final int REGISTER_IMS_CHANGED_DELAY = 10000;  //10 seconds
-
-        private final WeakReference<UserCapabilityExchangeImpl> mUceImplRef;
-
-        UceImplHandler(UserCapabilityExchangeImpl uceImpl, Looper looper) {
-            super(looper);
-            mUceImplRef = new WeakReference(uceImpl);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            UserCapabilityExchangeImpl uceImpl = mUceImplRef.get();
-            if (uceImpl == null) {
-                return;
-            }
-            switch (msg.what) {
-                case EVENT_REGISTER_IMS_CHANGED_RECEIVER:
-                    int subId = msg.arg1;
-                    uceImpl.registerImsContentChangedReceiverInternal(subId);
-                    break;
-                case EVENT_NOTIFY_UPDATE_CAPABILITIES:
-                    int publishTriggerType = msg.arg1;
-                    uceImpl.onNotifyUpdateCapabilities(publishTriggerType);
-                    break;
-                case EVENT_UNPUBLISH:
-                    uceImpl.onUnPublish();
-                    break;
-                default:
-                    Log.w(LOG_TAG, "handleMessage: error=" + msg.what);
-                    break;
-            }
-        }
-
-        private void retryRegisteringImsContentChangedReceiver(int subId) {
-            sendRegisteringImsContentChangedMessage(subId, REGISTER_IMS_CHANGED_DELAY);
-        }
-
-        private void registerImsContentChangedReceiver(int subId) {
-            sendRegisteringImsContentChangedMessage(subId, 0);
-        }
-
-        private void sendRegisteringImsContentChangedMessage(int subId, int delay) {
-            if (subId <= SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-                return;
-            }
-            removeRegisteringImsContentChangedReceiver();
-            Message message = obtainMessage(EVENT_REGISTER_IMS_CHANGED_RECEIVER);
-            message.arg1 = subId;
-            sendMessageDelayed(message, delay);
-        }
-
-        private void removeRegisteringImsContentChangedReceiver() {
-            removeMessages(EVENT_REGISTER_IMS_CHANGED_RECEIVER);
-        }
-
-        private void notifyUpdateCapabilities(int publishTriggerType) {
-            Message message = obtainMessage(EVENT_NOTIFY_UPDATE_CAPABILITIES);
-            message.arg1 = publishTriggerType;
-            sendMessage(message);
-        }
-
-        private void unpublish() {
-            sendEmptyMessage(EVENT_UNPUBLISH);
-        }
-    }
-
-    private void onNotifyUpdateCapabilities(int publishTriggerType) {
-        mPresencePublication.onStackPublishRequested(publishTriggerType);
-    }
-
-    private void onUnPublish() {
-        mPresencePublication.setPublishState(PresenceBase.PUBLISH_STATE_NOT_PUBLISHED);
-    }
-
-    @Override
-    public @PresenceBase.PresencePublishState int getPublisherState() {
-        return mPublishState;
-    }
-
-    @Override
-    public int requestPublication(RcsContactUceCapability capabilities, String contactUri,
-            int taskId) {
-        if (mRcsFeatureManager == null) {
-            logw("requestPublication error: RcsFeatureManager is null.");
-            return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-        }
-
-        logi("requestPublication: taskId=" + taskId);
-        addPublishRequestTaskId(taskId);
-
-        try {
-            mRcsFeatureManager.requestPublication(capabilities, taskId);
-        } catch (Exception ex) {
-            logw("requestPublication error: " + ex.getMessage());
-            removePublishRequestTaskId(taskId);
-            return ResultCode.PUBLISH_GENERIC_FAILURE;
-        }
-        return ResultCode.SUCCESS;
-    }
-
-    /*
-     * Handle the callback method RcsFeatureCallbacks#onCommandUpdate(int, int)
-     */
-    private void onCommandUpdateForPublishRequest(int commandCode, int operationToken) {
-        if (!isPublishRequestExisted(operationToken)) {
-            return;
-        }
-        int resultCode = ResultCode.SUCCESS;
-        if (commandCode != RcsCapabilityExchange.COMMAND_CODE_SUCCESS) {
-            logw("onCommandUpdateForPublishRequest failed! taskId=" + operationToken
-                    + ", code=" + commandCode);
-            removePublishRequestTaskId(operationToken);
-            resultCode = ResultCode.PUBLISH_GENERIC_FAILURE;
-        }
-        mPresencePublication.onCommandStatusUpdated(operationToken, operationToken, resultCode);
-    }
-
-    private void onCommandUpdateForCapabilityRequest(int commandCode, int operationToken) {
-        if (!isCapabilityRequestExisted(operationToken)) {
-            return;
-        }
-        int resultCode = ResultCode.SUCCESS;
-        if (commandCode != RcsCapabilityExchange.COMMAND_CODE_SUCCESS) {
-            logw("onCommandUpdateForCapabilityRequest failed! taskId=" + operationToken
-                    + ", code=" + commandCode);
-            mPendingCapabilityRequests.remove(operationToken);
-            resultCode = ResultCode.PUBLISH_GENERIC_FAILURE;
-        }
-        mPresenceSubscriber.onCommandStatusUpdated(operationToken, operationToken, resultCode);
-    }
-
-    private void onCommandUpdateForAvailabilityRequest(int commandCode, int operationToken) {
-        if (!isAvailabilityRequestExisted(operationToken)) {
-            return;
-        }
-        int resultCode = ResultCode.SUCCESS;
-        if (commandCode != RcsCapabilityExchange.COMMAND_CODE_SUCCESS) {
-            logw("onCommandUpdateForAvailabilityRequest failed! taskId=" + operationToken
-                    + ", code=" + commandCode);
-            removeRequestingAvailabilityTaskId(operationToken);
-            resultCode = ResultCode.PUBLISH_GENERIC_FAILURE;
-        }
-        mPresenceSubscriber.onCommandStatusUpdated(operationToken, operationToken, resultCode);
-    }
-
-    /*
-     * Handle the callback method RcsFeatureCallbacks#onNetworkResponse(int, String, int)
-     */
-    private void onNetworkResponseForPublishRequest(int responseCode, String reason,
-            int operationToken) {
-        if (!isPublishRequestExisted(operationToken)) {
-            return;
-        }
-        removePublishRequestTaskId(operationToken);
-        mPresencePublication.onSipResponse(operationToken, responseCode, reason);
-    }
-
-    private void onNetworkResponseForCapabilityRequest(int responseCode, String reason,
-            int operationToken) {
-        if (!isCapabilityRequestExisted(operationToken)) {
-            return;
-        }
-        mPresenceSubscriber.onSipResponse(operationToken, responseCode, reason);
-    }
-
-    private void onNetworkResponseForAvailabilityRequest(int responseCode, String reason,
-            int operationToken) {
-        if (!isAvailabilityRequestExisted(operationToken)) {
-            return;
-        }
-        removeRequestingAvailabilityTaskId(operationToken);
-        mPresenceSubscriber.onSipResponse(operationToken, responseCode, reason);
-    }
-
-    private void handleAvailabilityReqResponse(List<RcsContactUceCapability> infos, int token) {
-        try {
-            if (infos == null || infos.isEmpty()) {
-                logw("handle availability request response: infos is null " + token);
-                return;
-            }
-            logi("handleAvailabilityReqResponse: token=" + token);
-            mPresenceSubscriber.updatePresence(infos.get(0));
-        } finally {
-            removeRequestingAvailabilityTaskId(token);
-        }
-    }
-
-    private void handleCapabilityReqResponse(List<RcsContactUceCapability> infos, int token) {
-        if (infos == null) {
-            logw("handleCapabilityReqResponse: infos is null " + token);
-            mPendingCapabilityRequests.remove(token);
-            return;
-        }
-        logi("handleCapabilityReqResponse: token=" + token);
-        mPresenceSubscriber.updatePresences(token, infos, true, null);
-    }
-
-    @Override
-    public void updatePublisherState(@PresenceBase.PresencePublishState int publishState) {
-        logi("updatePublisherState: from " + mPublishState + " to " + publishState);
-        mPublishState = publishState;
-        notifyPublishStateChanged(publishState);
-    }
-
-    private void addPublishRequestTaskId(int taskId) {
-        synchronized (mRequestingPublishTaskIds) {
-            mRequestingPublishTaskIds.add(taskId);
-        }
-    }
-
-    private void removePublishRequestTaskId(int taskId) {
-        synchronized (mRequestingPublishTaskIds) {
-            mRequestingPublishTaskIds.remove(taskId);
-        }
-    }
-
-    private boolean isPublishRequestExisted(Integer taskId) {
-        synchronized (mRequestingPublishTaskIds) {
-            return mRequestingPublishTaskIds.contains(taskId);
-        }
-    }
-
-    private void addRequestingAvailabilityTaskId(int taskId) {
-        synchronized (mPendingAvailabilityRequests) {
-            mPendingAvailabilityRequests.contains(taskId);
-        }
-    }
-
-    private void removeRequestingAvailabilityTaskId(int taskId) {
-        synchronized (mPendingAvailabilityRequests) {
-            mPendingAvailabilityRequests.remove(taskId);
-        }
-    }
-
-    private boolean isAvailabilityRequestExisted(Integer taskId) {
-        synchronized (mPendingAvailabilityRequests) {
-            return mPendingAvailabilityRequests.contains(taskId);
-        }
-    }
-
-    private boolean isCapabilityRequestExisted(Integer taskId) {
-        return mPendingCapabilityRequests.containsKey(taskId);
-    }
-
-    private static String getNumberFromUri(Uri uri) {
-        String number = uri.getSchemeSpecificPart();
-        String[] numberParts = number.split("[@;:]");
-
-        if (numberParts.length == 0) {
-            return null;
-        }
-        return numberParts[0];
-    }
-
-    private static int toUcePublishState(int publishState) {
-        switch (publishState) {
-            case PresenceBase.PUBLISH_STATE_200_OK:
-                return RcsUceAdapter.PUBLISH_STATE_OK;
-            case PresenceBase.PUBLISH_STATE_NOT_PUBLISHED:
-                return RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED;
-            case PresenceBase.PUBLISH_STATE_VOLTE_PROVISION_ERROR:
-                return RcsUceAdapter.PUBLISH_STATE_VOLTE_PROVISION_ERROR;
-            case PresenceBase.PUBLISH_STATE_RCS_PROVISION_ERROR:
-                return RcsUceAdapter.PUBLISH_STATE_RCS_PROVISION_ERROR;
-            case PresenceBase.PUBLISH_STATE_REQUEST_TIMEOUT:
-                return RcsUceAdapter.PUBLISH_STATE_REQUEST_TIMEOUT;
-            case PresenceBase.PUBLISH_STATE_OTHER_ERROR:
-                return RcsUceAdapter.PUBLISH_STATE_OTHER_ERROR;
-            default:
-                return RcsUceAdapter.PUBLISH_STATE_OTHER_ERROR;
-        }
-    }
-
-    private static int toUceError(int resultCode) {
-        switch (resultCode) {
-            case ResultCode.SUBSCRIBE_NOT_REGISTERED:
-                return RcsUceAdapter.ERROR_NOT_REGISTERED;
-            case ResultCode.SUBSCRIBE_REQUEST_TIMEOUT:
-                return RcsUceAdapter.ERROR_REQUEST_TIMEOUT;
-            case ResultCode.SUBSCRIBE_FORBIDDEN:
-                return RcsUceAdapter.ERROR_FORBIDDEN;
-            case ResultCode.SUBSCRIBE_NOT_FOUND:
-                return RcsUceAdapter.ERROR_NOT_FOUND;
-            case ResultCode.SUBSCRIBE_TOO_LARGE:
-                return RcsUceAdapter.ERROR_REQUEST_TOO_LARGE;
-            case ResultCode.SUBSCRIBE_INSUFFICIENT_MEMORY:
-                return RcsUceAdapter.ERROR_INSUFFICIENT_MEMORY;
-            case ResultCode.SUBSCRIBE_LOST_NETWORK:
-                return RcsUceAdapter.ERROR_LOST_NETWORK;
-            case ResultCode.SUBSCRIBE_ALREADY_IN_QUEUE:
-                return RcsUceAdapter.ERROR_ALREADY_IN_QUEUE;
-            default:
-                return RcsUceAdapter.ERROR_GENERIC_FAILURE;
-        }
-    }
-
-    /*
-     * Register receivers for updating capabilities
-     */
-    private void registerReceivers() {
-        IntentFilter filter = new IntentFilter(TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED);
-        filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
-        mContext.registerReceiver(mReceiver, filter);
-
-        ContentResolver resolver = mContext.getContentResolver();
-        if (resolver != null) {
-            // Register mobile data content changed.
-            resolver.registerContentObserver(
-                    Settings.Global.getUriFor(Settings.Global.MOBILE_DATA), false,
-                    mMobileDataObserver);
-
-            // Register SIM info content changed.
-            resolver.registerContentObserver(Telephony.SimInfo.CONTENT_URI, false,
-                    mSimInfoContentObserver);
-        }
-    }
-
-    private void unregisterReceivers() {
-        mContext.unregisterReceiver(mReceiver);
-        ContentResolver resolver = mContext.getContentResolver();
-        if (resolver != null) {
-            resolver.unregisterContentObserver(mMobileDataObserver);
-            resolver.unregisterContentObserver(mSimInfoContentObserver);
-        }
-    }
-
-    /**
-     * Register IMS and provision content changed.
-     *
-     * Call the UceImplHandler#registerImsContentChangedReceiver instead of
-     * calling this method directly.
-     */
-    private void registerImsContentChangedReceiverInternal(int subId) {
-        mUceImplHandler.removeRegisteringImsContentChangedReceiver();
-        try {
-            final int originalSubId = mSubId;
-            if ((originalSubId == subId) && (mImsContentChangedCallbackRegistered)) {
-                logi("registerImsContentChangedReceiverInternal: already registered. skip");
-                return;
-            }
-            // Unregister original IMS and Provision callback
-            unregisterImsProvisionCallback(originalSubId);
-            // Register new IMS and Provision callback
-            registerImsProvisionCallback(subId);
-        } catch (ImsException e) {
-            logw("registerImsContentChangedReceiverInternal error: " + e);
-            mUceImplHandler.retryRegisteringImsContentChangedReceiver(subId);
-        }
-    }
-
-    private void unregisterImsProvisionCallback(int subId) {
-        if (subId <= SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            return;
-        }
-        // Unregister IMS callback
-        ImsMmTelManager imsMmtelManager = getImsMmTelManager(subId);
-        if (imsMmtelManager != null) {
-            try {
-                imsMmtelManager.unregisterImsRegistrationCallback(mImsRegistrationCallback);
-                imsMmtelManager.unregisterMmTelCapabilityCallback(mCapabilityCallback);
-            } catch (RuntimeException e) {
-                logw("unregister IMS callback error: " + e.getMessage());
-            }
-        }
-
-        // Unregister provision changed callback
-        ProvisioningManager provisioningManager =
-                ProvisioningManager.createForSubscriptionId(subId);
-        try {
-            provisioningManager.unregisterProvisioningChangedCallback(mProvisioningChangedCallback);
-        } catch (RuntimeException e) {
-            logw("unregister provisioning callback error: " + e.getMessage());
-        }
-
-        // Remove all publish state callbacks
-        clearPublishStateCallbacks();
-
-        mImsContentChangedCallbackRegistered = false;
-    }
-
-    private void registerImsProvisionCallback(int subId) throws ImsException {
-        if (subId <= SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            return;
-        }
-        // Register IMS callback
-        ImsMmTelManager imsMmtelManager = getImsMmTelManager(subId);
-        if (imsMmtelManager != null) {
-            imsMmtelManager.registerImsRegistrationCallback(mContext.getMainExecutor(),
-                    mImsRegistrationCallback);
-            imsMmtelManager.registerMmTelCapabilityCallback(mContext.getMainExecutor(),
-                    mCapabilityCallback);
-        }
-        // Register provision changed callback
-        ProvisioningManager provisioningManager =
-                ProvisioningManager.createForSubscriptionId(subId);
-        provisioningManager.registerProvisioningChangedCallback(mContext.getMainExecutor(),
-                mProvisioningChangedCallback);
-
-        mImsContentChangedCallbackRegistered = true;
-        logi("registerImsProvisionCallback");
-    }
-
-    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (intent == null) return;
-            switch (intent.getAction()) {
-                case TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED:
-                    int preferredMode = intent.getIntExtra(
-                            TelecomManager.EXTRA_TTY_PREFERRED_MODE, TelecomManager.TTY_MODE_OFF);
-                    logi("TTY preferred mode changed: " + preferredMode);
-                    mPresencePublication.onTtyPreferredModeChanged(preferredMode);
-                    break;
-
-                case Intent.ACTION_AIRPLANE_MODE_CHANGED:
-                    boolean airplaneMode = intent.getBooleanExtra("state", false);
-                    logi("Airplane mode changed: " + airplaneMode);
-                    mPresencePublication.onAirplaneModeChanged(airplaneMode);
-                    break;
-            }
-        }
-    };
-
-    private ContentObserver mMobileDataObserver = new ContentObserver(
-            new Handler(Looper.getMainLooper())) {
-        @Override
-        public void onChange(boolean selfChange) {
-            boolean isEnabled = Settings.Global.getInt(mContext.getContentResolver(),
-                    Settings.Global.MOBILE_DATA, 1) == 1;
-            logi("Mobile data changed: enabled=" + isEnabled);
-            mPresencePublication.onMobileDataChanged(isEnabled);
-        }
-    };
-
-    private ContentObserver mSimInfoContentObserver = new ContentObserver(
-            new Handler(Looper.getMainLooper())) {
-        @Override
-        public void onChange(boolean selfChange) {
-            if (mSubId <= SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-                return;
-            }
-
-            ImsMmTelManager ims = getImsMmTelManager(mSubId);
-            if (ims == null) return;
-
-            try {
-                boolean isEnabled = ims.isVtSettingEnabled();
-                logi("SimInfo changed: VT setting=" + isEnabled);
-                mPresencePublication.onVtEnabled(isEnabled);
-            } catch (RuntimeException e) {
-                logw("SimInfo changed error: " + e);
-            }
-        }
-    };
-
-    private RegistrationManager.RegistrationCallback mImsRegistrationCallback =
-            new RegistrationManager.RegistrationCallback() {
-        @Override
-        public void onRegistered(int imsTransportType) {
-            logi("onRegistered: type=" + imsTransportType);
-            mNetworkRegistrationType = imsTransportType;
-            mPresencePublication.onImsConnected();
-
-            // Also trigger PresencePublication#onFeatureCapabilityChanged method
-            MmTelFeature.MmTelCapabilities capabilities = null;
-            synchronized (mCapabilitiesLock) {
-                capabilities = mMmTelCapabilities;
-            }
-
-            if (capabilities != null) {
-                mPresencePublication.onFeatureCapabilityChanged(mNetworkRegistrationType,
-                        capabilities);
-            }
-        }
-
-        @Override
-        public void onUnregistered(ImsReasonInfo info) {
-            logi("onUnregistered");
-            mNetworkRegistrationType = AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
-
-            // Also trigger PresencePublication#onFeatureCapabilityChanged method
-            MmTelFeature.MmTelCapabilities capabilities = null;
-            synchronized (mCapabilitiesLock) {
-                capabilities = mMmTelCapabilities;
-            }
-
-            if (capabilities != null) {
-                mPresencePublication.onFeatureCapabilityChanged(mNetworkRegistrationType,
-                        capabilities);
-            }
-            mPresencePublication.onImsDisconnected();
-        }
-    };
-
-    private ImsMmTelManager.CapabilityCallback mCapabilityCallback =
-            new ImsMmTelManager.CapabilityCallback() {
-        @Override
-        public void onCapabilitiesStatusChanged(MmTelFeature.MmTelCapabilities capabilities) {
-            if (capabilities == null) {
-                logw("onCapabilitiesStatusChanged: parameter is null");
-                return;
-            }
-            synchronized (mCapabilitiesLock) {
-                mMmTelCapabilities = capabilities;
-            }
-            mPresencePublication.onFeatureCapabilityChanged(mNetworkRegistrationType, capabilities);
-        }
-    };
-
-    private ProvisioningManager.Callback mProvisioningChangedCallback =
-            new ProvisioningManager.Callback() {
-        @Override
-        public void onProvisioningIntChanged(int item, int value) {
-            logi("onProvisioningIntChanged: item=" + item);
-            switch (item) {
-                case ProvisioningManager.KEY_EAB_PROVISIONING_STATUS:
-                case ProvisioningManager.KEY_VOLTE_PROVISIONING_STATUS:
-                case ProvisioningManager.KEY_VT_PROVISIONING_STATUS:
-                    mPresencePublication.handleProvisioningChanged();
-                    break;
-                default:
-                    break;
-            }
-        }
-    };
-
-    private boolean isCapabilityDiscoveryEnabled(int subId) {
-        try {
-            ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
-            int discoveryEnabled = manager.getProvisioningIntValue(
-                    ProvisioningManager.KEY_RCS_CAPABILITY_DISCOVERY_ENABLED);
-            return (discoveryEnabled == ProvisioningManager.PROVISIONING_VALUE_ENABLED);
-        } catch (Exception e) {
-            logw("isCapabilityDiscoveryEnabled error: " + e.getMessage());
-        }
-        return false;
-    }
-
-    private boolean isEabProvisioned(Context context, int subId) {
-        if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            logw("isEabProvisioned error: invalid subscriptionId " + subId);
-            return false;
-        }
-
-        CarrierConfigManager configManager = (CarrierConfigManager)
-                context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        if (configManager != null) {
-            PersistableBundle config = configManager.getConfigForSubId(subId);
-            if (config != null && !config.getBoolean(
-                    CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL)) {
-                return true;
-            }
-        }
-
-        try {
-            ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
-            int provisioningStatus = manager.getProvisioningIntValue(
-                    ProvisioningManager.KEY_EAB_PROVISIONING_STATUS);
-            return (provisioningStatus == ProvisioningManager.PROVISIONING_VALUE_ENABLED);
-        } catch (Exception e) {
-            logw("isEabProvisioned error: " + e.getMessage());
-        }
-        return false;
-    }
-
-    private ImsMmTelManager getImsMmTelManager(int subId) {
-        try {
-            ImsManager imsManager = (ImsManager) mContext.getSystemService(
-                    Context.TELEPHONY_IMS_SERVICE);
-            return (imsManager == null) ? null : imsManager.getImsMmTelManager(subId);
-        } catch (IllegalArgumentException e) {
-            logw("getImsMmTelManager error: " + e.getMessage());
-            return null;
-        }
-    }
-
-    private void logi(String log) {
-        Log.i(LOG_TAG, getLogPrefix().append(log).toString());
-    }
-
-    private void logw(String log) {
-        Log.w(LOG_TAG, getLogPrefix().append(log).toString());
-    }
-
-    private StringBuilder getLogPrefix() {
-        StringBuilder builder = new StringBuilder("[");
-        builder.append(mSlotId);
-        builder.append("->");
-        builder.append(mSubId);
-        builder.append("] ");
-        return builder;
-    }
-}
diff --git a/tests/src/com/android/TelephonyTestBase.java b/tests/src/com/android/TelephonyTestBase.java
index 132d893..502740d 100644
--- a/tests/src/com/android/TelephonyTestBase.java
+++ b/tests/src/com/android/TelephonyTestBase.java
@@ -27,6 +27,7 @@
 import org.mockito.MockitoAnnotations;
 
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -58,6 +59,23 @@
         PhoneConfigurationManager.unregisterAllMultiSimConfigChangeRegistrants();
     }
 
+    protected final boolean waitForExecutorAction(Executor executor, long timeoutMillis) {
+        final CountDownLatch lock = new CountDownLatch(1);
+        Log.i("BRAD", "waitForExecutorAction");
+        executor.execute(() -> {
+            Log.i("BRAD", "countdown");
+            lock.countDown();
+        });
+        while (lock.getCount() > 0) {
+            try {
+                return lock.await(timeoutMillis, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                // do nothing
+            }
+        }
+        return true;
+    }
+
     protected final void waitForHandlerAction(Handler h, long timeoutMillis) {
         final CountDownLatch lock = new CountDownLatch(1);
         h.post(lock::countDown);
diff --git a/tests/src/com/android/services/telephony/ImsConferenceTest.java b/tests/src/com/android/services/telephony/ImsConferenceTest.java
index f13d709..7e6488d 100644
--- a/tests/src/com/android/services/telephony/ImsConferenceTest.java
+++ b/tests/src/com/android/services/telephony/ImsConferenceTest.java
@@ -16,6 +16,8 @@
 
 package com.android.services.telephony;
 
+import static junit.framework.Assert.assertTrue;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -573,4 +575,40 @@
         assertEquals(0, imsConference.getNumberOfParticipants());
         verify(mConferenceHost.mMockCall).hangup();
     }
+
+    /**
+     * Verifies that an ImsConference can handle SIP and TEL URIs for both the P-Associated-Uri and
+     * conference event package identities.
+     */
+    @Test
+    public void testIsParticipantHost() {
+        // Simplest case, assume P-Associated-Uri is a tel URI and that the CEP participant is also
+        // a tel URI.
+        assertTrue(ImsConference.isParticipantHost(new Uri[] {
+                        Uri.parse("tel:+8616505551234")},
+                Uri.parse("tel:+8616505551234")));
+
+        // Assume P-Associated-Uri is a tel URI and the CEP participant is a sip URI.
+        assertTrue(ImsConference.isParticipantHost(new Uri[] {
+                        Uri.parse("tel:+8616505551234")},
+                Uri.parse("sip:+8616505551234@bj.ims.mnc011.mcc460.3gppnetwork.org")));
+
+        // Assume P-Associated-Uri is a sip URI and the CEP participant is a tel URI.
+        assertTrue(ImsConference.isParticipantHost(new Uri[] {
+                        Uri.parse("sip:+8616505551234@bj.ims.mnc011.mcc460.3gppnetwork.org")},
+                Uri.parse("tel:+8616505551234")));
+
+        // Assume both P-Associated-Uri and the CEP participant are SIP URIs.
+        assertTrue(ImsConference.isParticipantHost(new Uri[] {
+                        Uri.parse("sip:+8616505551234@bj.ims.mnc011.mcc460.3gppnetwork.org")},
+                Uri.parse("sip:+8616505551234@bj.ims.mnc011.mcc460.3gppnetwork.org")));
+
+        // Corner cases
+        assertFalse(ImsConference.isParticipantHost(new Uri[] {
+                        Uri.parse("tel:+8616505551234")}, Uri.fromParts("", "", "")));
+        assertFalse(ImsConference.isParticipantHost(new Uri[] {
+                        Uri.parse("tel:+8616505551234")}, null));
+        assertFalse(ImsConference.isParticipantHost(null, null));
+        assertFalse(ImsConference.isParticipantHost(new Uri[0], null));
+    }
 }
diff --git a/tests/src/com/android/services/telephony/TelephonyManagerTest.java b/tests/src/com/android/services/telephony/TelephonyManagerTest.java
new file mode 100644
index 0000000..e9cdc98
--- /dev/null
+++ b/tests/src/com/android/services/telephony/TelephonyManagerTest.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2020 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;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.telephony.emergency.EmergencyNumber;
+import android.test.mock.MockContext;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.telephony.ITelephony;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/** Unit tests for {@link TelephonyManager}. */
+@RunWith(AndroidJUnit4.class)
+public class TelephonyManagerTest {
+    private static final String PKG_NAME = "Unittest.TelephonyManagerTest";
+    private static final String TAG = "TelephonyManagerTest";
+
+    private ITelephony mMockITelephony;
+    private SubscriptionManager mMockSubscriptionManager;
+    private Context mMockContext;
+
+    private TelephonyManager mTelephonyManager;
+
+    private final MockContext mContext =
+            new MockContext() {
+                @Override
+                public String getOpPackageName() {
+                    return PKG_NAME;
+                }
+                @Override
+                public String getAttributionTag() {
+                    return TAG;
+                }
+                @Override
+                public Context getApplicationContext() {
+                    return null;
+                }
+                @Override
+                public Object getSystemService(String name) {
+                    switch (name) {
+                        case (Context.TELEPHONY_SUBSCRIPTION_SERVICE) : {
+                            return mMockSubscriptionManager;
+                        }
+                    }
+                    return null;
+                }
+            };
+
+    @Before
+    public void setUp() throws Exception {
+        mMockITelephony = mock(ITelephony.class);
+        mMockSubscriptionManager = mock(SubscriptionManager.class);
+        mMockContext = mock(Context.class);
+        when(mMockContext.getSystemService(eq(Context.TELEPHONY_SUBSCRIPTION_SERVICE)))
+                .thenReturn(mMockSubscriptionManager);
+
+        mTelephonyManager = new TelephonyManager(mContext);
+        TelephonyManager.setupITelephonyForTest(mMockITelephony);
+        TelephonyManager.enableServiceHandleCaching();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        TelephonyManager.setupITelephonyForTest(null);
+        TelephonyManager.disableServiceHandleCaching();
+    }
+
+    @Test
+    public void testGetEmergencyNumberListForCategories() throws Exception {
+        Map<Integer, List<EmergencyNumber>> emergencyNumberLists = new HashMap<>();
+        List<EmergencyNumber> emergencyNumberList = new ArrayList<>();
+        EmergencyNumber number_police = new EmergencyNumber(
+                "911",
+                "us",
+                "30",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE,
+                new ArrayList<String>(),
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
+        EmergencyNumber number_fire = new EmergencyNumber(
+                "912",
+                "us",
+                "30",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE,
+                new ArrayList<String>(),
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL);
+        emergencyNumberList.add(number_police);
+        emergencyNumberList.add(number_fire);
+        final int test_sub_id = 1;
+        emergencyNumberLists.put(test_sub_id, emergencyNumberList);
+        when(mMockITelephony.getEmergencyNumberList(eq(PKG_NAME), eq(TAG))).thenReturn(
+                emergencyNumberLists);
+
+        // Call TelephonyManager.getEmergencyNumberList(Category)
+        Map<Integer, List<EmergencyNumber>> returnedEmergencyNumberLists =
+                mTelephonyManager.getEmergencyNumberList(
+                        EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE);
+
+        // Verify the ITelephony service is called
+        verify(mMockITelephony, times(1)).getEmergencyNumberList(eq(PKG_NAME), eq(TAG));
+
+        // Verify the returned number list contains only the police number(s)
+        List<EmergencyNumber> returnedEmergencyNumberList = returnedEmergencyNumberLists.get(
+                test_sub_id);
+        for (EmergencyNumber num : returnedEmergencyNumberList) {
+            assertTrue(num.isInEmergencyServiceCategories(
+                    EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE));
+        }
+    }
+}
diff --git a/tests/src/com/android/services/telephony/rcs/DelegateStateTrackerTest.java b/tests/src/com/android/services/telephony/rcs/DelegateStateTrackerTest.java
new file mode 100644
index 0000000..4d40702
--- /dev/null
+++ b/tests/src/com/android/services/telephony/rcs/DelegateStateTrackerTest.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2020 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.rcs;
+
+import static org.junit.Assert.assertEquals;
+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.times;
+import static org.mockito.Mockito.verify;
+
+import android.telephony.ims.DelegateRegistrationState;
+import android.telephony.ims.FeatureTagState;
+import android.telephony.ims.SipDelegateImsConfiguration;
+import android.telephony.ims.SipDelegateManager;
+import android.telephony.ims.aidl.ISipDelegate;
+import android.telephony.ims.aidl.ISipDelegateConnectionStateCallback;
+import android.util.ArraySet;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.TelephonyTestBase;
+
+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 java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+@RunWith(AndroidJUnit4.class)
+public class DelegateStateTrackerTest extends TelephonyTestBase {
+    private static final int TEST_SUB_ID = 1;
+
+    @Mock private ISipDelegate mSipDelegate;
+    @Mock private ISipDelegateConnectionStateCallback mAppCallback;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /**
+     * When an underlying SipDelegate is created, the app should only receive one onCreated callback
+     * independent of how many times sipDelegateConnected is called. Once created, registration
+     * and IMS configuration events should propagate up to the app as well.
+     */
+    @SmallTest
+    @Test
+    public void testDelegateCreated() throws Exception {
+        DelegateStateTracker stateTracker = new DelegateStateTracker(TEST_SUB_ID, mAppCallback,
+                mSipDelegate);
+        Set<FeatureTagState> deniedTags = getMmTelDeniedTag();
+        stateTracker.sipDelegateConnected(deniedTags);
+        // Calling connected multiple times should not generate multiple onCreated events.
+        stateTracker.sipDelegateConnected(deniedTags);
+        verify(mAppCallback).onCreated(mSipDelegate);
+
+        // Ensure status updates are sent to app as expected.
+        DelegateRegistrationState regState = new DelegateRegistrationState.Builder()
+                .addRegisteredFeatureTag(ImsSignallingUtils.ONE_TO_ONE_CHAT_TAG)
+                .build();
+        SipDelegateImsConfiguration config = new SipDelegateImsConfiguration.Builder(1/*version*/)
+                .build();
+        stateTracker.onRegistrationStateChanged(regState);
+        stateTracker.onImsConfigurationChanged(config);
+        verify(mAppCallback).onFeatureTagStatusChanged(eq(regState),
+                eq(new ArrayList<>(deniedTags)));
+        verify(mAppCallback).onImsConfigurationChanged(config);
+
+        verify(mAppCallback, never()).onDestroyed(anyInt());
+    }
+
+    /**
+     * onDestroyed should be called when sipDelegateDestroyed is called.
+     */
+    @SmallTest
+    @Test
+    public void testDelegateDestroyed() throws Exception {
+        DelegateStateTracker stateTracker = new DelegateStateTracker(TEST_SUB_ID, mAppCallback,
+                mSipDelegate);
+        Set<FeatureTagState> deniedTags = getMmTelDeniedTag();
+        stateTracker.sipDelegateConnected(deniedTags);
+
+        stateTracker.sipDelegateDestroyed(
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+        verify(mAppCallback).onDestroyed(
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+    }
+
+    /**
+     * When a SipDelegate is created and then an event occurs that will destroy->create a new
+     * SipDelegate underneath, we need to move the state of the features that are reporting
+     * registered to DEREGISTERING_REASON_FEATURE_TAGS_CHANGING so that the app can close dialogs on
+     * it. Once the new underlying SipDelegate is created, we must verify that the new registration
+     * is propagated up without any overrides.
+     */
+    @SmallTest
+    @Test
+    public void testDelegateChangingRegisteredTagsOverride() throws Exception {
+        DelegateStateTracker stateTracker = new DelegateStateTracker(TEST_SUB_ID, mAppCallback,
+                mSipDelegate);
+        Set<FeatureTagState> deniedTags = getMmTelDeniedTag();
+        stateTracker.sipDelegateConnected(deniedTags);
+        // SipDelegate created
+        verify(mAppCallback).onCreated(mSipDelegate);
+        DelegateRegistrationState regState = new DelegateRegistrationState.Builder()
+                .addRegisteredFeatureTag(ImsSignallingUtils.ONE_TO_ONE_CHAT_TAG)
+                .addDeregisteringFeatureTag(ImsSignallingUtils.FILE_TRANSFER_HTTP_TAG,
+                        DelegateRegistrationState.DEREGISTERING_REASON_PROVISIONING_CHANGE)
+                .addDeregisteredFeatureTag(ImsSignallingUtils.GROUP_CHAT_TAG,
+                        DelegateRegistrationState.DEREGISTERED_REASON_NOT_PROVISIONED)
+                .build();
+        stateTracker.onRegistrationStateChanged(regState);
+        // Simulate underlying SipDelegate switch
+        stateTracker.sipDelegateChanging(
+                DelegateRegistrationState.DEREGISTERING_REASON_FEATURE_TAGS_CHANGING);
+        // onFeatureTagStatusChanged should now be called with registered features overridden with
+        // DEREGISTERING_REASON_FEATURE_TAGS_CHANGING
+        DelegateRegistrationState overrideRegState = new DelegateRegistrationState.Builder()
+                .addDeregisteringFeatureTag(ImsSignallingUtils.ONE_TO_ONE_CHAT_TAG,
+                        DelegateRegistrationState.DEREGISTERING_REASON_FEATURE_TAGS_CHANGING)
+                // Already Deregistering/Deregistered tags should not be overridden.
+                .addDeregisteringFeatureTag(ImsSignallingUtils.FILE_TRANSFER_HTTP_TAG,
+                        DelegateRegistrationState.DEREGISTERING_REASON_PROVISIONING_CHANGE)
+                .addDeregisteredFeatureTag(ImsSignallingUtils.GROUP_CHAT_TAG,
+                        DelegateRegistrationState.DEREGISTERED_REASON_NOT_PROVISIONED)
+                .build();
+        // new underlying SipDelegate created
+        stateTracker.sipDelegateConnected(deniedTags);
+        stateTracker.onRegistrationStateChanged(regState);
+
+        // Verify registration state through the process:
+        ArgumentCaptor<DelegateRegistrationState> regCaptor =
+                ArgumentCaptor.forClass(DelegateRegistrationState.class);
+        verify(mAppCallback, times(3)).onFeatureTagStatusChanged(
+                regCaptor.capture(), eq(new ArrayList<>(deniedTags)));
+        List<DelegateRegistrationState> testStates = regCaptor.getAllValues();
+        // feature tags should first be registered
+        assertEquals(regState, testStates.get(0));
+        // registered feature tags should have moved to deregistering
+        assertEquals(overrideRegState, testStates.get(1));
+        // and then moved back to registered after underlying FT change done.
+        assertEquals(regState, testStates.get(2));
+
+        //onCreate should only have been called once and onDestroy should have never been called.
+        verify(mAppCallback).onCreated(mSipDelegate);
+        verify(mAppCallback, never()).onDestroyed(anyInt());
+    }
+
+    /**
+     * Test the case that when the underlying Denied tags change in the SipDelegate, the change is
+     * properly shown in the registration update event.
+     */
+    @SmallTest
+    @Test
+    public void testDelegateChangingDeniedTagsChanged() throws Exception {
+        DelegateStateTracker stateTracker = new DelegateStateTracker(TEST_SUB_ID, mAppCallback,
+                mSipDelegate);
+        Set<FeatureTagState> deniedTags = getMmTelDeniedTag();
+        stateTracker.sipDelegateConnected(deniedTags);
+        // SipDelegate created
+        verify(mAppCallback).onCreated(mSipDelegate);
+        DelegateRegistrationState regState = new DelegateRegistrationState.Builder()
+                .addRegisteredFeatureTag(ImsSignallingUtils.ONE_TO_ONE_CHAT_TAG)
+                .build();
+        stateTracker.onRegistrationStateChanged(regState);
+        // Simulate underlying SipDelegate switch
+        stateTracker.sipDelegateChanging(
+                DelegateRegistrationState.DEREGISTERING_REASON_FEATURE_TAGS_CHANGING);
+        // onFeatureTagStatusChanged should now be called with registered features overridden with
+        // DEREGISTERING_REASON_FEATURE_TAGS_CHANGING
+        DelegateRegistrationState overrideRegState = new DelegateRegistrationState.Builder()
+                .addDeregisteringFeatureTag(ImsSignallingUtils.ONE_TO_ONE_CHAT_TAG,
+                        DelegateRegistrationState.DEREGISTERING_REASON_FEATURE_TAGS_CHANGING)
+                .build();
+        // Verify registration state so far.
+        ArgumentCaptor<DelegateRegistrationState> regCaptor =
+                ArgumentCaptor.forClass(DelegateRegistrationState.class);
+        verify(mAppCallback, times(2)).onFeatureTagStatusChanged(
+                regCaptor.capture(), eq(new ArrayList<>(deniedTags)));
+        List<DelegateRegistrationState> testStates = regCaptor.getAllValues();
+        assertEquals(2, testStates.size());
+        // feature tags should first be registered
+        assertEquals(regState, testStates.get(0));
+        // registered feature tags should have moved to deregistering
+        assertEquals(overrideRegState, testStates.get(1));
+
+        // new underlying SipDelegate created, but SipDelegate denied one to one chat
+        deniedTags.add(new FeatureTagState(ImsSignallingUtils.ONE_TO_ONE_CHAT_TAG,
+                SipDelegateManager.DENIED_REASON_NOT_ALLOWED));
+        stateTracker.sipDelegateConnected(deniedTags);
+        DelegateRegistrationState fullyDeniedRegState = new DelegateRegistrationState.Builder()
+                .build();
+        // In this special case, it will be the SipDelegateConnectionBase that will trigger
+        // reg state change.
+        stateTracker.onRegistrationStateChanged(fullyDeniedRegState);
+        verify(mAppCallback).onFeatureTagStatusChanged(regCaptor.capture(),
+                eq(new ArrayList<>(deniedTags)));
+        // now all feature tags denied, so we should see only denied tags.
+        assertEquals(fullyDeniedRegState, regCaptor.getValue());
+
+        //onCreate should only have been called once and onDestroy should have never been called.
+        verify(mAppCallback).onCreated(mSipDelegate);
+        verify(mAppCallback, never()).onDestroyed(anyInt());
+    }
+
+    /**
+     * Test that when we move from changing tags state to the delegate being destroyed, we get the
+     * correct onDestroy event sent to the app.
+     */
+    @SmallTest
+    @Test
+    public void testDelegateChangingDeniedTagsChangingToDestroy() throws Exception {
+        DelegateStateTracker stateTracker = new DelegateStateTracker(TEST_SUB_ID, mAppCallback,
+                mSipDelegate);
+        Set<FeatureTagState> deniedTags = getMmTelDeniedTag();
+        stateTracker.sipDelegateConnected(deniedTags);
+        // SipDelegate created
+        verify(mAppCallback).onCreated(mSipDelegate);
+        DelegateRegistrationState regState = new DelegateRegistrationState.Builder()
+                .addRegisteredFeatureTag(ImsSignallingUtils.ONE_TO_ONE_CHAT_TAG)
+                .addDeregisteredFeatureTag(ImsSignallingUtils.GROUP_CHAT_TAG,
+                        DelegateRegistrationState.DEREGISTERED_REASON_NOT_PROVISIONED)
+                .build();
+        stateTracker.onRegistrationStateChanged(regState);
+        verify(mAppCallback).onFeatureTagStatusChanged(any(),
+                eq(new ArrayList<>(deniedTags)));
+        // Simulate underlying SipDelegate switch
+        stateTracker.sipDelegateChanging(
+                DelegateRegistrationState.DEREGISTERING_REASON_DESTROY_PENDING);
+        // Destroy
+        stateTracker.sipDelegateDestroyed(
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+
+        // onFeatureTagStatusChanged should now be called with registered features overridden with
+        // DEREGISTERING_REASON_DESTROY_PENDING
+        DelegateRegistrationState overrideRegState = new DelegateRegistrationState.Builder()
+                .addDeregisteringFeatureTag(ImsSignallingUtils.ONE_TO_ONE_CHAT_TAG,
+                        DelegateRegistrationState.DEREGISTERING_REASON_DESTROY_PENDING)
+                // Deregistered should stay the same.
+                .addDeregisteredFeatureTag(ImsSignallingUtils.GROUP_CHAT_TAG,
+                        DelegateRegistrationState.DEREGISTERED_REASON_NOT_PROVISIONED)
+                .build();
+        // Verify registration state through process:
+        ArgumentCaptor<DelegateRegistrationState> regCaptor =
+                ArgumentCaptor.forClass(DelegateRegistrationState.class);
+        verify(mAppCallback, times(2)).onFeatureTagStatusChanged(regCaptor.capture(),
+                eq(new ArrayList<>(deniedTags)));
+        List<DelegateRegistrationState> testStates = regCaptor.getAllValues();
+        assertEquals(2, testStates.size());
+        // feature tags should first be registered
+        assertEquals(regState, testStates.get(0));
+        // registered feature tags should have moved to deregistering
+        assertEquals(overrideRegState, testStates.get(1));
+        //onCreate/onDestroy should only be called once.
+        verify(mAppCallback).onCreated(mSipDelegate);
+        verify(mAppCallback).onDestroyed(
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+    }
+
+    private Set<FeatureTagState> getMmTelDeniedTag() {
+        Set<FeatureTagState> deniedTags = new ArraySet<>();
+        deniedTags.add(new FeatureTagState(ImsSignallingUtils.MMTEL_TAG,
+                SipDelegateManager.DENIED_REASON_NOT_ALLOWED));
+        return deniedTags;
+    }
+}
diff --git a/tests/src/com/android/services/telephony/rcs/ImsSignallingUtils.java b/tests/src/com/android/services/telephony/rcs/ImsSignallingUtils.java
new file mode 100644
index 0000000..d607f6d
--- /dev/null
+++ b/tests/src/com/android/services/telephony/rcs/ImsSignallingUtils.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2020 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.rcs;
+
+/**
+ * Various definitions and utilities related to IMS Signalling.
+ */
+public class ImsSignallingUtils {
+    public static final String MMTEL_TAG =
+            "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel\"";
+    public static final String ONE_TO_ONE_CHAT_TAG =
+            "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gppservice.ims.icsi.oma.cpm.msg\"";
+    public static final String GROUP_CHAT_TAG =
+            "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gppservice.ims.icsi.oma.cpm.session\"";
+    public static final String FILE_TRANSFER_HTTP_TAG =
+            "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gppapplication.ims.iari.rcs.fthttp\"";
+}
diff --git a/tests/src/com/android/services/telephony/rcs/MessageTransportStateTrackerTest.java b/tests/src/com/android/services/telephony/rcs/MessageTransportStateTrackerTest.java
new file mode 100644
index 0000000..5e05085
--- /dev/null
+++ b/tests/src/com/android/services/telephony/rcs/MessageTransportStateTrackerTest.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2020 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.rcs;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.os.RemoteException;
+import android.telephony.ims.SipDelegateManager;
+import android.telephony.ims.SipMessage;
+import android.telephony.ims.aidl.ISipDelegate;
+import android.telephony.ims.aidl.ISipDelegateMessageCallback;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.TelephonyTestBase;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+
+@RunWith(AndroidJUnit4.class)
+public class MessageTransportStateTrackerTest extends TelephonyTestBase {
+    private static final int TEST_SUB_ID = 1;
+
+    private static final SipMessage TEST_MESSAGE = new SipMessage(
+            "INVITE sip:callee@ex.domain.com SIP/2.0",
+            "Via: SIP/2.0/UDP ex.place.com;branch=z9hG4bK776asdhds",
+            new byte[0]);
+
+    // Use for finer-grained control of when the Executor executes.
+    private static class PendingExecutor implements Executor {
+        private final ArrayList<Runnable> mPendingRunnables = new ArrayList<>();
+
+        @Override
+        public void execute(Runnable command) {
+            mPendingRunnables.add(command);
+        }
+
+        public void executePending() {
+            for (Runnable r : mPendingRunnables) {
+                r.run();
+            }
+            mPendingRunnables.clear();
+        }
+    }
+
+    @Mock private ISipDelegateMessageCallback mDelegateMessageCallback;
+    @Mock private ISipDelegate mISipDelegate;
+    @Mock private Consumer<Boolean> mMockCloseConsumer;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @SmallTest
+    @Test
+    public void testDelegateConnectionSendOutgoingMessage() throws Exception {
+        MessageTransportStateTracker tracker = new MessageTransportStateTracker(TEST_SUB_ID,
+                Runnable::run, mDelegateMessageCallback);
+
+        tracker.openTransport(mISipDelegate, Collections.emptySet());
+        tracker.getDelegateConnection().sendMessage(TEST_MESSAGE, 1 /*version*/);
+        verify(mISipDelegate).sendMessage(TEST_MESSAGE, 1 /*version*/);
+
+        doThrow(new RemoteException()).when(mISipDelegate).sendMessage(any(), anyLong());
+        tracker.getDelegateConnection().sendMessage(TEST_MESSAGE, 1 /*version*/);
+        verify(mDelegateMessageCallback).onMessageSendFailure(any(),
+                eq(SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_DEAD));
+
+        tracker.close(SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED);
+        tracker.getDelegateConnection().sendMessage(TEST_MESSAGE, 1 /*version*/);
+        verify(mDelegateMessageCallback).onMessageSendFailure(any(),
+                eq(SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED));
+    }
+
+    @SmallTest
+    @Test
+    public void testDelegateConnectionCloseGracefully() throws Exception {
+        PendingExecutor executor = new PendingExecutor();
+        MessageTransportStateTracker tracker = new MessageTransportStateTracker(TEST_SUB_ID,
+                executor, mDelegateMessageCallback);
+
+        tracker.openTransport(mISipDelegate, Collections.emptySet());
+        tracker.getDelegateConnection().sendMessage(TEST_MESSAGE, 1 /*version*/);
+        executor.executePending();
+        verify(mISipDelegate).sendMessage(TEST_MESSAGE, 1 /*version*/);
+        verify(mDelegateMessageCallback, never()).onMessageSendFailure(any(), anyInt());
+
+        // Use PendingExecutor a little weird here, we need to queue sendMessage first, even though
+        // closeGracefully will complete partly synchronously to test that the pending message will
+        // return MESSAGE_FAILURE_REASON_INTERNAL_DELEGATE_STATE_TRANSITION before the scheduled
+        // graceful close operation completes.
+        tracker.getDelegateConnection().sendMessage(TEST_MESSAGE, 1 /*version*/);
+        tracker.closeGracefully(
+                SipDelegateManager.MESSAGE_FAILURE_REASON_INTERNAL_DELEGATE_STATE_TRANSITION,
+                SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED,
+                mMockCloseConsumer);
+        verify(mMockCloseConsumer, never()).accept(any());
+        // resolve pending close operation
+        executor.executePending();
+        verify(mDelegateMessageCallback).onMessageSendFailure(any(),
+                eq(SipDelegateManager.MESSAGE_FAILURE_REASON_INTERNAL_DELEGATE_STATE_TRANSITION));
+        // Still should only report one call of sendMessage from before
+        verify(mISipDelegate).sendMessage(TEST_MESSAGE, 1 /*version*/);
+        verify(mMockCloseConsumer).accept(true);
+
+        // ensure that after close operation completes, we get the correct
+        // MESSAGE_FAILURE_REASON_DELEGATE_CLOSED message.
+        tracker.getDelegateConnection().sendMessage(TEST_MESSAGE, 1 /*version*/);
+        executor.executePending();
+        verify(mDelegateMessageCallback).onMessageSendFailure(any(),
+                eq(SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED));
+        // Still should only report one call of sendMessage from before
+        verify(mISipDelegate).sendMessage(TEST_MESSAGE, 1 /*version*/);
+    }
+
+    @SmallTest
+    @Test
+    public void testDelegateConnectionNotifyMessageReceived() throws Exception {
+        MessageTransportStateTracker tracker = new MessageTransportStateTracker(TEST_SUB_ID,
+                Runnable::run, mDelegateMessageCallback);
+        tracker.openTransport(mISipDelegate, Collections.emptySet());
+        tracker.getDelegateConnection().notifyMessageReceived("z9hG4bK776asdhds");
+        verify(mISipDelegate).notifyMessageReceived("z9hG4bK776asdhds");
+    }
+
+    @SmallTest
+    @Test
+    public void testDelegateConnectionNotifyMessageReceiveError() throws Exception {
+        MessageTransportStateTracker tracker = new MessageTransportStateTracker(TEST_SUB_ID,
+                Runnable::run, mDelegateMessageCallback);
+        tracker.openTransport(mISipDelegate, Collections.emptySet());
+        tracker.getDelegateConnection().notifyMessageReceiveError("z9hG4bK776asdhds",
+                SipDelegateManager.MESSAGE_FAILURE_REASON_NETWORK_NOT_AVAILABLE);
+        verify(mISipDelegate).notifyMessageReceiveError("z9hG4bK776asdhds",
+                SipDelegateManager.MESSAGE_FAILURE_REASON_NETWORK_NOT_AVAILABLE);
+    }
+
+    @SmallTest
+    @Test
+    public void testDelegateConnectionCloseDialog() throws Exception {
+        MessageTransportStateTracker tracker = new MessageTransportStateTracker(TEST_SUB_ID,
+                Runnable::run, mDelegateMessageCallback);
+        tracker.openTransport(mISipDelegate, Collections.emptySet());
+        tracker.getDelegateConnection().closeDialog("testCallId");
+        verify(mISipDelegate).closeDialog("testCallId");
+    }
+
+    @SmallTest
+    @Test
+    public void testDelegateOnMessageReceived() throws Exception {
+        MessageTransportStateTracker tracker = new MessageTransportStateTracker(TEST_SUB_ID,
+                Runnable::run, mDelegateMessageCallback);
+        tracker.openTransport(mISipDelegate, Collections.emptySet());
+
+        tracker.getMessageCallback().onMessageReceived(TEST_MESSAGE);
+        verify(mDelegateMessageCallback).onMessageReceived(TEST_MESSAGE);
+
+        doThrow(new RemoteException()).when(mDelegateMessageCallback).onMessageReceived(any());
+        tracker.getMessageCallback().onMessageReceived(TEST_MESSAGE);
+        verify(mISipDelegate).notifyMessageReceiveError(any(),
+                eq(SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_DEAD));
+    }
+
+    @SmallTest
+    @Test
+    public void testDelegateOnMessageReceivedClosedGracefully() throws Exception {
+        PendingExecutor executor = new PendingExecutor();
+        MessageTransportStateTracker tracker = new MessageTransportStateTracker(TEST_SUB_ID,
+                executor, mDelegateMessageCallback);
+        tracker.openTransport(mISipDelegate, Collections.emptySet());
+
+        tracker.getMessageCallback().onMessageReceived(TEST_MESSAGE);
+        executor.executePending();
+        verify(mDelegateMessageCallback).onMessageReceived(TEST_MESSAGE);
+
+        tracker.getMessageCallback().onMessageReceived(TEST_MESSAGE);
+        tracker.closeGracefully(
+                SipDelegateManager.MESSAGE_FAILURE_REASON_INTERNAL_DELEGATE_STATE_TRANSITION,
+                SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED,
+                mMockCloseConsumer);
+        executor.executePending();
+        // Incoming SIP message should not be blocked by closeGracefully
+        verify(mDelegateMessageCallback, times(2)).onMessageReceived(TEST_MESSAGE);
+    }
+
+    @SmallTest
+    @Test
+    public void testDelegateOnMessageSent() throws Exception {
+        MessageTransportStateTracker tracker = new MessageTransportStateTracker(TEST_SUB_ID,
+                Runnable::run, mDelegateMessageCallback);
+        tracker.openTransport(mISipDelegate, Collections.emptySet());
+        tracker.getMessageCallback().onMessageSent("z9hG4bK776asdhds");
+        verify(mDelegateMessageCallback).onMessageSent("z9hG4bK776asdhds");
+    }
+
+    @SmallTest
+    @Test
+    public void testDelegateonMessageSendFailure() throws Exception {
+        MessageTransportStateTracker tracker = new MessageTransportStateTracker(TEST_SUB_ID,
+                Runnable::run, mDelegateMessageCallback);
+        tracker.openTransport(mISipDelegate, Collections.emptySet());
+        tracker.getMessageCallback().onMessageSendFailure("z9hG4bK776asdhds",
+                SipDelegateManager.MESSAGE_FAILURE_REASON_NETWORK_NOT_AVAILABLE);
+        verify(mDelegateMessageCallback).onMessageSendFailure("z9hG4bK776asdhds",
+                SipDelegateManager.MESSAGE_FAILURE_REASON_NETWORK_NOT_AVAILABLE);
+    }
+}
diff --git a/tests/src/com/android/services/telephony/rcs/SipDelegateBinderConnectionTest.java b/tests/src/com/android/services/telephony/rcs/SipDelegateBinderConnectionTest.java
new file mode 100644
index 0000000..fa439dc
--- /dev/null
+++ b/tests/src/com/android/services/telephony/rcs/SipDelegateBinderConnectionTest.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2020 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.rcs;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.verify;
+
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.telephony.ims.DelegateRegistrationState;
+import android.telephony.ims.DelegateRequest;
+import android.telephony.ims.FeatureTagState;
+import android.telephony.ims.SipDelegateImsConfiguration;
+import android.telephony.ims.SipDelegateManager;
+import android.telephony.ims.aidl.ISipDelegate;
+import android.telephony.ims.aidl.ISipDelegateMessageCallback;
+import android.telephony.ims.aidl.ISipDelegateStateCallback;
+import android.telephony.ims.aidl.ISipTransport;
+import android.util.ArraySet;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.TelephonyTestBase;
+
+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 java.util.ArrayList;
+import java.util.Set;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+
+@RunWith(AndroidJUnit4.class)
+public class SipDelegateBinderConnectionTest extends TelephonyTestBase {
+    private static final int TEST_SUB_ID = 1;
+
+    @Mock private ISipDelegate mMockDelegate;
+    @Mock private ISipTransport mMockTransport;
+    @Mock private IBinder mTransportBinder;
+    @Mock private ISipDelegateMessageCallback mMessageCallback;
+    @Mock private DelegateBinderStateManager.StateCallback mMockStateCallback;
+    @Mock private BiConsumer<ISipDelegate, Set<FeatureTagState>> mMockCreatedCallback;
+    @Mock private Consumer<Integer> mMockDestroyedCallback;
+
+    private ArrayList<SipDelegateBinderConnection.StateCallback> mStateCallbackList;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        doReturn(mTransportBinder).when(mMockTransport).asBinder();
+        mStateCallbackList = new ArrayList<>(1);
+        mStateCallbackList.add(mMockStateCallback);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @SmallTest
+    @Test
+    public void testBaseImpl() throws Exception {
+        DelegateBinderStateManager baseConnection = new SipDelegateBinderConnectionStub(
+                getMmTelDeniedTag(), Runnable::run, mStateCallbackList);
+
+        baseConnection.create(null /*message cb*/, mMockCreatedCallback);
+        // Verify the stub simulates onCreated + on registration state callback.
+        verify(mMockCreatedCallback).accept(any(), eq(getMmTelDeniedTag()));
+        verify(mMockStateCallback).onRegistrationStateChanged(
+                new DelegateRegistrationState.Builder().build());
+
+        // Verify onDestroyed is called correctly.
+        baseConnection.destroy(SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP,
+                mMockDestroyedCallback);
+        verify(mMockDestroyedCallback).accept(
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+    }
+
+    @SmallTest
+    @Test
+    public void testCreateConnection() throws Exception {
+        DelegateRequest request = getDelegateRequest();
+        ArraySet<FeatureTagState> deniedTags = getMmTelDeniedTag();
+        SipDelegateBinderConnection connection = new SipDelegateBinderConnection(TEST_SUB_ID,
+                mMockTransport, request, deniedTags, Runnable::run, mStateCallbackList);
+        ISipDelegateStateCallback cb = createDelegateCaptureStateCallback(request, connection);
+
+        // Send onCreated callback from SipDelegate
+        ArrayList<FeatureTagState> delegateDeniedTags = new ArrayList<>(1);
+        delegateDeniedTags.add(new FeatureTagState(ImsSignallingUtils.GROUP_CHAT_TAG,
+                SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE));
+        assertNotNull(cb);
+        cb.onCreated(mMockDelegate, delegateDeniedTags);
+
+        ArraySet<FeatureTagState> totalDeniedTags = new ArraySet<>(deniedTags);
+        // Add the tags denied by the controller as well.
+        totalDeniedTags.addAll(delegateDeniedTags);
+        // The callback should contain the controller and delegate denied tags in the callback.
+        verify(mMockCreatedCallback).accept(mMockDelegate, totalDeniedTags);
+    }
+
+    @SmallTest
+    @Test
+    public void testCreateConnectionServiceDead() throws Exception {
+        DelegateRequest request = getDelegateRequest();
+        ArraySet<FeatureTagState> deniedTags = getMmTelDeniedTag();
+        SipDelegateBinderConnection connection = new SipDelegateBinderConnection(TEST_SUB_ID,
+                mMockTransport, request, deniedTags, Runnable::run, mStateCallbackList);
+        doThrow(new RemoteException()).when(mMockTransport).createSipDelegate(eq(TEST_SUB_ID),
+                any(), any(), any());
+        ISipDelegateStateCallback cb = createDelegateCaptureStateCallback(request, connection);
+        assertNull(cb);
+    }
+
+    @SmallTest
+    @Test
+    public void testDestroyConnection() throws Exception {
+        DelegateRequest request = getDelegateRequest();
+        ArraySet<FeatureTagState> deniedTags = getMmTelDeniedTag();
+        SipDelegateBinderConnection connection = new SipDelegateBinderConnection(TEST_SUB_ID,
+                mMockTransport, request, deniedTags, Runnable::run, mStateCallbackList);
+        ISipDelegateStateCallback cb = createDelegateCaptureStateCallback(request, connection);
+        assertNotNull(cb);
+        cb.onCreated(mMockDelegate, null /*denied*/);
+        verify(mMockCreatedCallback).accept(mMockDelegate, deniedTags);
+
+        // call Destroy on the SipDelegate
+        destroy(connection, SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+        cb.onDestroyed(SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+        verify(mMockDestroyedCallback).accept(
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+    }
+
+    @SmallTest
+    @Test
+    public void testDestroyConnectionDead() throws Exception {
+        DelegateRequest request = getDelegateRequest();
+        ArraySet<FeatureTagState> deniedTags = getMmTelDeniedTag();
+        SipDelegateBinderConnection connection = new SipDelegateBinderConnection(TEST_SUB_ID,
+                mMockTransport, request, deniedTags, Runnable::run, mStateCallbackList);
+        ISipDelegateStateCallback cb = createDelegateCaptureStateCallback(request, connection);
+        assertNotNull(cb);
+        cb.onCreated(mMockDelegate, null /*denied*/);
+        verify(mMockCreatedCallback).accept(mMockDelegate, deniedTags);
+
+        // try to destroy when dead and ensure callback is still called.
+        doThrow(new RemoteException()).when(mMockTransport).destroySipDelegate(any(), anyInt());
+        destroy(connection, SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+        verify(mMockDestroyedCallback).accept(
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+    }
+
+    @SmallTest
+    @Test
+    public void testStateCallback() throws Exception {
+        DelegateRequest request = getDelegateRequest();
+        ArraySet<FeatureTagState> deniedTags = getMmTelDeniedTag();
+        SipDelegateBinderConnection connection = new SipDelegateBinderConnection(TEST_SUB_ID,
+                mMockTransport, request, deniedTags, Runnable::run, mStateCallbackList);
+        ISipDelegateStateCallback cb = createDelegateCaptureStateCallback(request, connection);
+        assertNotNull(cb);
+        cb.onCreated(mMockDelegate, new ArrayList<>(deniedTags));
+        verify(mMockCreatedCallback).accept(mMockDelegate, deniedTags);
+
+        SipDelegateImsConfiguration config = new SipDelegateImsConfiguration.Builder(1).build();
+        cb.onImsConfigurationChanged(config);
+        verify(mMockStateCallback).onImsConfigurationChanged(config);
+
+        DelegateRegistrationState regState = new DelegateRegistrationState.Builder()
+                .addRegisteredFeatureTags(request.getFeatureTags()).build();
+        cb.onFeatureTagRegistrationChanged(regState);
+        verify(mMockStateCallback).onRegistrationStateChanged(regState);
+    }
+
+    private ISipDelegateStateCallback createDelegateCaptureStateCallback(
+            DelegateRequest r, SipDelegateBinderConnection c) throws Exception {
+        boolean isCreating = c.create(mMessageCallback, mMockCreatedCallback);
+        if (!isCreating) return null;
+        ArgumentCaptor<ISipDelegateStateCallback> stateCaptor =
+                ArgumentCaptor.forClass(ISipDelegateStateCallback.class);
+        verify(mMockTransport).createSipDelegate(eq(TEST_SUB_ID), eq(r), stateCaptor.capture(),
+                eq(mMessageCallback));
+        assertNotNull(stateCaptor.getValue());
+        return stateCaptor.getValue();
+    }
+
+    private void destroy(SipDelegateBinderConnection c, int reason) throws Exception {
+        c.destroy(reason, mMockDestroyedCallback);
+        verify(mMockTransport).destroySipDelegate(mMockDelegate, reason);
+    }
+
+    private DelegateRequest getDelegateRequest() {
+        ArraySet<String> featureTags = new ArraySet<>(2);
+        featureTags.add(ImsSignallingUtils.ONE_TO_ONE_CHAT_TAG);
+        featureTags.add(ImsSignallingUtils.GROUP_CHAT_TAG);
+        return new DelegateRequest(featureTags);
+    }
+
+    private ArraySet<FeatureTagState> getMmTelDeniedTag() {
+        ArraySet<FeatureTagState> deniedTags = new ArraySet<>();
+        deniedTags.add(new FeatureTagState(ImsSignallingUtils.MMTEL_TAG,
+                SipDelegateManager.DENIED_REASON_NOT_ALLOWED));
+        return deniedTags;
+    }
+}
diff --git a/tests/src/com/android/services/telephony/rcs/SipDelegateControllerTest.java b/tests/src/com/android/services/telephony/rcs/SipDelegateControllerTest.java
new file mode 100644
index 0000000..47b4808
--- /dev/null
+++ b/tests/src/com/android/services/telephony/rcs/SipDelegateControllerTest.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2020 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.rcs;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.telephony.ims.DelegateRegistrationState;
+import android.telephony.ims.DelegateRequest;
+import android.telephony.ims.FeatureTagState;
+import android.telephony.ims.SipDelegateManager;
+import android.telephony.ims.aidl.ISipDelegate;
+import android.telephony.ims.aidl.ISipDelegateMessageCallback;
+import android.telephony.ims.aidl.ISipTransport;
+import android.util.ArraySet;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.TelephonyTestBase;
+import com.android.TestExecutorService;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+
+@RunWith(AndroidJUnit4.class)
+public class SipDelegateControllerTest extends TelephonyTestBase {
+    private static final int TEST_SUB_ID = 1;
+
+    @Mock private ISipDelegate mMockSipDelegate;
+    @Mock private ISipTransport mMockSipTransport;
+    @Mock private MessageTransportStateTracker mMockMessageTracker;
+    @Mock private ISipDelegateMessageCallback mMockMessageCallback;
+    @Mock private DelegateStateTracker mMockDelegateStateTracker;
+    @Mock private DelegateBinderStateManager mMockBinderConnection;
+    @Captor private ArgumentCaptor<BiConsumer<ISipDelegate, Set<FeatureTagState>>> mCreatedCaptor;
+    @Captor private ArgumentCaptor<Consumer<Boolean>> mBooleanConsumerCaptor;
+    @Captor private ArgumentCaptor<Consumer<Integer>> mIntegerConsumerCaptor;
+
+    private ScheduledExecutorService mExecutorService;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        when(mMockMessageTracker.getMessageCallback()).thenReturn(mMockMessageCallback);
+        mExecutorService = new TestExecutorService();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mExecutorService.shutdownNow();
+        super.tearDown();
+    }
+
+    @SmallTest
+    @Test
+    public void testCreateDelegate() throws Exception {
+        DelegateRequest request = getBaseDelegateRequest();
+        SipDelegateController controller = getTestDelegateController(request,
+                Collections.emptySet());
+
+        doReturn(true).when(mMockBinderConnection).create(eq(mMockMessageCallback), any());
+        CompletableFuture<Boolean> future = controller.create(request.getFeatureTags(),
+                Collections.emptySet() /*denied tags*/);
+        BiConsumer<ISipDelegate, Set<FeatureTagState>> consumer =
+                verifyConnectionCreated(1);
+        assertNotNull(consumer);
+
+        assertFalse(future.isDone());
+        consumer.accept(mMockSipDelegate, Collections.emptySet());
+        assertTrue(future.get());
+        verify(mMockMessageTracker).openTransport(mMockSipDelegate, Collections.emptySet());
+        verify(mMockDelegateStateTracker).sipDelegateConnected(Collections.emptySet());
+    }
+
+    @SmallTest
+    @Test
+    public void testCreateDelegateTransportDied() throws Exception {
+        DelegateRequest request = getBaseDelegateRequest();
+        SipDelegateController controller = getTestDelegateController(request,
+                Collections.emptySet());
+
+        //Create operation fails
+        doReturn(false).when(mMockBinderConnection).create(eq(mMockMessageCallback), any());
+        CompletableFuture<Boolean> future = controller.create(request.getFeatureTags(),
+                Collections.emptySet() /*denied tags*/);
+
+        assertFalse(future.get());
+    }
+
+    @SmallTest
+    @Test
+    public void testDestroyDelegate() throws Exception {
+        DelegateRequest request = getBaseDelegateRequest();
+        SipDelegateController controller = getTestDelegateController(request,
+                Collections.emptySet());
+        createSipDelegate(request, controller);
+
+        CompletableFuture<Integer> pendingDestroy = controller.destroy(false /*force*/,
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+        assertFalse(pendingDestroy.isDone());
+        Consumer<Boolean> pendingClosedConsumer = verifyMessageTrackerCloseGracefully();
+        verify(mMockDelegateStateTracker).sipDelegateChanging(
+                DelegateRegistrationState.DEREGISTERING_REASON_DESTROY_PENDING);
+
+        // verify we do not call destroy on the delegate until the message tracker releases the
+        // transport.
+        verify(mMockBinderConnection, never()).destroy(anyInt(), any());
+        pendingClosedConsumer.accept(true);
+        Consumer<Integer> pendingDestroyedConsumer = verifyBinderConnectionDestroy();
+        pendingDestroyedConsumer.accept(
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+        verify(mMockDelegateStateTracker).sipDelegateDestroyed(
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+        assertTrue(pendingDestroy.isDone());
+        assertEquals(SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP,
+                pendingDestroy.get().intValue());
+    }
+
+    @SmallTest
+    @Test
+    public void testDestroyDelegateForce() throws Exception {
+        DelegateRequest request = getBaseDelegateRequest();
+        SipDelegateController controller = getTestDelegateController(request,
+                Collections.emptySet());
+        createSipDelegate(request, controller);
+
+        CompletableFuture<Integer> pendingDestroy = controller.destroy(true /*force*/,
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+        assertFalse(pendingDestroy.isDone());
+        // Do not wait for message transport close in this case.
+        verify(mMockMessageTracker).close(
+                SipDelegateManager.MESSAGE_FAILURE_REASON_DELEGATE_CLOSED);
+        verify(mMockDelegateStateTracker, never()).sipDelegateChanging(
+                DelegateRegistrationState.DEREGISTERING_REASON_DESTROY_PENDING);
+
+        //verify destroy is called
+        Consumer<Integer> pendingDestroyedConsumer = verifyBinderConnectionDestroy();
+        pendingDestroyedConsumer.accept(
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+        verify(mMockDelegateStateTracker).sipDelegateDestroyed(
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+        assertTrue(pendingDestroy.isDone());
+        assertEquals(SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP,
+                pendingDestroy.get().intValue());
+    }
+
+    @SmallTest
+    @Test
+    public void testChangeSupportedFeatures() throws Exception {
+        DelegateRequest request = getBaseDelegateRequest();
+        SipDelegateController controller = getTestDelegateController(request,
+                Collections.emptySet());
+        createSipDelegate(request, controller);
+
+        Set<String> newFts = getBaseFTSet();
+        newFts.add(ImsSignallingUtils.GROUP_CHAT_TAG);
+        CompletableFuture<Boolean> pendingChange = controller.changeSupportedFeatureTags(
+                newFts, Collections.emptySet());
+        assertFalse(pendingChange.isDone());
+        // message tracker should close gracefully.
+        Consumer<Boolean> pendingClosedConsumer = verifyMessageTrackerCloseGracefully();
+        verify(mMockDelegateStateTracker).sipDelegateChanging(
+                DelegateRegistrationState.DEREGISTERING_REASON_FEATURE_TAGS_CHANGING);
+        verify(mMockBinderConnection, never()).destroy(anyInt(), any());
+        pendingClosedConsumer.accept(true);
+        Consumer<Integer> pendingDestroyedConsumer = verifyBinderConnectionDestroy();
+        pendingDestroyedConsumer.accept(
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+        verify(mMockDelegateStateTracker, never()).sipDelegateDestroyed(anyInt());
+
+        // This will cause any exceptions to be printed if something completed exceptionally.
+        assertNull(pendingChange.getNow(null));
+        BiConsumer<ISipDelegate, Set<FeatureTagState>> consumer =
+                verifyConnectionCreated(2);
+        assertNotNull(consumer);
+        consumer.accept(mMockSipDelegate, Collections.emptySet());
+        assertTrue(pendingChange.get());
+
+        verify(mMockMessageTracker, times(2)).openTransport(mMockSipDelegate,
+                Collections.emptySet());
+        verify(mMockDelegateStateTracker, times(2)).sipDelegateConnected(Collections.emptySet());
+    }
+
+    private void createSipDelegate(DelegateRequest request, SipDelegateController controller)
+            throws Exception {
+        doReturn(true).when(mMockBinderConnection).create(eq(mMockMessageCallback), any());
+        CompletableFuture<Boolean> future = controller.create(request.getFeatureTags(),
+                Collections.emptySet() /*denied tags*/);
+        BiConsumer<ISipDelegate, Set<FeatureTagState>> consumer =
+                verifyConnectionCreated(1);
+        assertNotNull(consumer);
+        consumer.accept(mMockSipDelegate, Collections.emptySet());
+        assertTrue(future.get());
+    }
+
+    private ArraySet<String> getBaseFTSet() {
+        ArraySet<String> request = new ArraySet<>();
+        request.add(ImsSignallingUtils.ONE_TO_ONE_CHAT_TAG);
+        return request;
+    }
+
+    private DelegateRequest getBaseDelegateRequest() {
+        return new DelegateRequest(getBaseFTSet());
+    }
+
+    private SipDelegateController getTestDelegateController(DelegateRequest request,
+            Set<FeatureTagState> deniedSet) {
+        return new SipDelegateController(TEST_SUB_ID, request, "", mMockSipTransport,
+                mExecutorService, mMockMessageTracker, mMockDelegateStateTracker,
+                (a, b, c, deniedFeatureSet, e, f) ->  {
+                    assertEquals(deniedSet, deniedFeatureSet);
+                    return mMockBinderConnection;
+                });
+    }
+
+    private BiConsumer<ISipDelegate, Set<FeatureTagState>> verifyConnectionCreated(int numTimes) {
+        verify(mMockBinderConnection, times(numTimes)).create(eq(mMockMessageCallback),
+                mCreatedCaptor.capture());
+        return mCreatedCaptor.getValue();
+    }
+
+    private Consumer<Boolean> verifyMessageTrackerCloseGracefully() {
+        verify(mMockMessageTracker).closeGracefully(anyInt(), anyInt(),
+                mBooleanConsumerCaptor.capture());
+        return mBooleanConsumerCaptor.getValue();
+    }
+    private Consumer<Integer> verifyBinderConnectionDestroy() {
+        verify(mMockBinderConnection).destroy(anyInt(), mIntegerConsumerCaptor.capture());
+        return mIntegerConsumerCaptor.getValue();
+    }
+
+}
diff --git a/tests/src/com/android/services/telephony/rcs/SipTransportControllerTest.java b/tests/src/com/android/services/telephony/rcs/SipTransportControllerTest.java
index 65a95cd..8e10757 100644
--- a/tests/src/com/android/services/telephony/rcs/SipTransportControllerTest.java
+++ b/tests/src/com/android/services/telephony/rcs/SipTransportControllerTest.java
@@ -18,13 +18,34 @@
 
 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.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
 
+import android.app.role.RoleManager;
+import android.os.IBinder;
+import android.os.UserHandle;
+import android.telephony.ims.DelegateRequest;
+import android.telephony.ims.FeatureTagState;
 import android.telephony.ims.ImsException;
+import android.telephony.ims.SipDelegateManager;
+import android.telephony.ims.aidl.ISipDelegate;
+import android.telephony.ims.aidl.ISipDelegateConnectionStateCallback;
+import android.telephony.ims.aidl.ISipDelegateMessageCallback;
 import android.telephony.ims.aidl.ISipTransport;
+import android.util.ArraySet;
+import android.util.Pair;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -39,30 +60,89 @@
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
 @RunWith(AndroidJUnit4.class)
 public class SipTransportControllerTest extends TelephonyTestBase {
+    private static final int TEST_SUB_ID = 1;
+    private static final String TEST_PACKAGE_NAME = "com.test_pkg";
+    private static final String TEST_PACKAGE_NAME_2 = "com.test_pkg2";
+    private static final int TIMEOUT_MS = 200;
+    private static final int THROTTLE_MS = 50;
+
+    private class SipDelegateControllerContainer {
+        public final int subId;
+        public final String packageName;
+        public final DelegateRequest delegateRequest;
+        public final SipDelegateController delegateController;
+        public final ISipDelegate mMockDelegate;
+        public final IBinder mMockDelegateBinder;
+
+        SipDelegateControllerContainer(int id, String name, DelegateRequest request) {
+            delegateController = mock(SipDelegateController.class);
+            mMockDelegate = mock(ISipDelegate.class);
+            mMockDelegateBinder = mock(IBinder.class);
+            doReturn(mMockDelegateBinder).when(mMockDelegate).asBinder();
+            doReturn(name).when(delegateController).getPackageName();
+            doReturn(request).when(delegateController).getInitialRequest();
+            doReturn(mMockDelegate).when(delegateController).getSipDelegateInterface();
+            subId = id;
+            packageName = name;
+            delegateRequest = request;
+        }
+    }
 
     @Mock private RcsFeatureManager mRcsManager;
     @Mock private ISipTransport mSipTransport;
+    @Mock private ISipDelegateConnectionStateCallback mMockStateCallback;
+    @Mock private ISipDelegateMessageCallback mMockMessageCallback;
+    @Mock private SipTransportController.SipDelegateControllerFactory
+            mMockDelegateControllerFactory;
+    @Mock private SipTransportController.RoleManagerAdapter mMockRoleManager;
 
-    private final TestExecutorService mExecutorService = new TestExecutorService();
+    private ScheduledExecutorService mExecutorService = null;
+    private final ArrayList<SipDelegateControllerContainer> mMockControllers = new ArrayList<>();
+    private final ArrayList<String> mSmsPackageName = new ArrayList<>(1);
 
     @Before
     public void setUp() throws Exception {
         super.setUp();
+        doReturn(mSmsPackageName).when(mMockRoleManager).getRoleHolders(RoleManager.ROLE_SMS);
+        mSmsPackageName.add(TEST_PACKAGE_NAME);
+        doAnswer(invocation -> {
+            Integer subId = invocation.getArgument(0);
+            String packageName = invocation.getArgument(2);
+            DelegateRequest request = invocation.getArgument(1);
+            SipDelegateController c = getMockDelegateController(subId, packageName, request);
+            assertNotNull("create called with no corresponding controller set up", c);
+            return c;
+        }).when(mMockDelegateControllerFactory).create(anyInt(), any(), anyString(), any(),
+                any(), any(), any());
     }
 
     @After
     public void tearDown() throws Exception {
         super.tearDown();
+        boolean isShutdown = mExecutorService == null || mExecutorService.isShutdown();
+        if (!isShutdown) {
+            mExecutorService.shutdownNow();
+        }
     }
 
     @SmallTest
     @Test
     public void isSupportedRcsNotConnected() {
-        SipTransportController controller = createController(0 /*slotId*/, 0 /*subId*/);
+        SipTransportController controller = createController(new TestExecutorService());
         try {
-            controller.isSupported(0 /*subId*/);
+            controller.isSupported(TEST_SUB_ID);
             fail();
         } catch (ImsException e) {
             assertEquals(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE, e.getCode());
@@ -72,9 +152,9 @@
     @SmallTest
     @Test
     public void isSupportedInvalidSubId() {
-        SipTransportController controller = createController(0 /*slotId*/, 0 /*subId*/);
+        SipTransportController controller = createController(new TestExecutorService());
         try {
-            controller.isSupported(1 /*subId*/);
+            controller.isSupported(TEST_SUB_ID + 1);
             fail();
         } catch (ImsException e) {
             assertEquals(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION, e.getCode());
@@ -84,10 +164,10 @@
     @SmallTest
     @Test
     public void isSupportedSubIdChanged() {
-        SipTransportController controller = createController(0 /*slotId*/, 0 /*subId*/);
-        controller.onAssociatedSubscriptionUpdated(1 /*subId*/);
+        SipTransportController controller = createController(new TestExecutorService());
+        controller.onAssociatedSubscriptionUpdated(TEST_SUB_ID + 1);
         try {
-            controller.isSupported(0 /*subId*/);
+            controller.isSupported(TEST_SUB_ID);
             fail();
         } catch (ImsException e) {
             assertEquals(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION, e.getCode());
@@ -97,11 +177,11 @@
     @SmallTest
     @Test
     public void isSupportedSipTransportAvailableRcsConnected() throws Exception {
-        SipTransportController controller = createController(0 /*slotId*/, 0 /*subId*/);
+        SipTransportController controller = createController(new TestExecutorService());
         doReturn(mSipTransport).when(mRcsManager).getSipTransport();
         controller.onRcsConnected(mRcsManager);
         try {
-            assertTrue(controller.isSupported(0 /*subId*/));
+            assertTrue(controller.isSupported(TEST_SUB_ID));
         } catch (ImsException e) {
             fail();
         }
@@ -110,12 +190,12 @@
     @SmallTest
     @Test
     public void isSupportedSipTransportNotAvailableRcsDisconnected() throws Exception {
-        SipTransportController controller = createController(0 /*slotId*/, 0 /*subId*/);
+        SipTransportController controller = createController(new TestExecutorService());
         doReturn(mSipTransport).when(mRcsManager).getSipTransport();
         controller.onRcsConnected(mRcsManager);
         controller.onRcsDisconnected();
         try {
-            controller.isSupported(0 /*subId*/);
+            controller.isSupported(TEST_SUB_ID);
             fail();
         } catch (ImsException e) {
             assertEquals(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE, e.getCode());
@@ -125,11 +205,11 @@
     @SmallTest
     @Test
     public void isSupportedSipTransportNotAvailableRcsConnected() throws Exception {
-        SipTransportController controller = createController(0 /*slotId*/, 0 /*subId*/);
+        SipTransportController controller = createController(new TestExecutorService());
         doReturn(null).when(mRcsManager).getSipTransport();
         controller.onRcsConnected(mRcsManager);
         try {
-            assertFalse(controller.isSupported(0 /*subId*/));
+            assertFalse(controller.isSupported(TEST_SUB_ID));
         } catch (ImsException e) {
             fail();
         }
@@ -138,19 +218,627 @@
     @SmallTest
     @Test
     public void isSupportedImsServiceNotAvailableRcsConnected() throws Exception {
-        SipTransportController controller = createController(0 /*slotId*/, 0 /*subId*/);
+        SipTransportController controller = createController(new TestExecutorService());
         doThrow(new ImsException("", ImsException.CODE_ERROR_SERVICE_UNAVAILABLE))
                 .when(mRcsManager).getSipTransport();
         controller.onRcsConnected(mRcsManager);
         try {
-            controller.isSupported(0 /*subId*/);
+            controller.isSupported(TEST_SUB_ID);
             fail();
         } catch (ImsException e) {
             assertEquals(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE, e.getCode());
         }
     }
 
-    private SipTransportController createController(int slotId, int subId) {
-        return new SipTransportController(mContext, slotId, subId, mExecutorService);
+    @SmallTest
+    @Test
+    public void createImsServiceAvailableSubIdIncorrect() throws Exception {
+        SipTransportController controller = createController(new TestExecutorService());
+        doReturn(mSipTransport).when(mRcsManager).getSipTransport();
+        controller.onRcsConnected(mRcsManager);
+        try {
+            controller.createSipDelegate(TEST_SUB_ID + 1,
+                    new DelegateRequest(Collections.emptySet()), TEST_PACKAGE_NAME,
+                    mMockStateCallback, mMockMessageCallback);
+            fail();
+        } catch (ImsException e) {
+            assertEquals(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION, e.getCode());
+        }
+    }
+
+    @SmallTest
+    @Test
+    public void createImsServiceDoesntSupportTransport() throws Exception {
+        SipTransportController controller = createController(new TestExecutorService());
+        doReturn(null).when(mRcsManager).getSipTransport();
+        controller.onRcsConnected(mRcsManager);
+        try {
+            controller.createSipDelegate(TEST_SUB_ID,
+                    new DelegateRequest(Collections.emptySet()), TEST_PACKAGE_NAME,
+                    mMockStateCallback, mMockMessageCallback);
+            fail();
+        } catch (ImsException e) {
+            assertEquals(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION, e.getCode());
+        }
+    }
+
+    @SmallTest
+    @Test
+    public void createImsServiceNotAvailable() throws Exception {
+        SipTransportController controller = createController(new TestExecutorService());
+        doThrow(new ImsException("", ImsException.CODE_ERROR_SERVICE_UNAVAILABLE))
+                .when(mRcsManager).getSipTransport();
+        // No RCS connected message
+        try {
+            controller.createSipDelegate(TEST_SUB_ID,
+                    new DelegateRequest(Collections.emptySet()), TEST_PACKAGE_NAME,
+                    mMockStateCallback, mMockMessageCallback);
+            fail();
+        } catch (ImsException e) {
+            assertEquals(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE, e.getCode());
+        }
+    }
+
+    @SmallTest
+    @Test
+    public void basicCreate() throws Exception {
+        SipTransportController controller = setupLiveTransportController();
+
+        DelegateRequest r = getBaseDelegateRequest();
+
+        SipDelegateController c = injectMockDelegateController(TEST_PACKAGE_NAME, r);
+        createDelegateAndVerify(controller, c, r, r.getFeatureTags(), Collections.emptySet(),
+                TEST_PACKAGE_NAME);
+    }
+
+    @SmallTest
+    @Test
+    public void basicCreateDestroy() throws Exception {
+        SipTransportController controller = setupLiveTransportController();
+
+        DelegateRequest r = getBaseDelegateRequest();
+        SipDelegateController c = injectMockDelegateController(TEST_PACKAGE_NAME, r);
+        createDelegateAndVerify(controller, c, r, r.getFeatureTags(), Collections.emptySet(),
+                TEST_PACKAGE_NAME);
+
+        destroyDelegateAndVerify(controller, c, false,
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+    }
+
+    @SmallTest
+    @Test
+    public void testCreateButNotInRole() throws Exception {
+        SipTransportController controller = setupLiveTransportController();
+
+        DelegateRequest r = getBaseDelegateRequest();
+        Set<FeatureTagState> getDeniedTags = getDeniedTagsForReason(r.getFeatureTags(),
+                SipDelegateManager.DENIED_REASON_NOT_ALLOWED);
+
+        // Try to create a SipDelegate for a package that is not the default sms role.
+        SipDelegateController c = injectMockDelegateController(TEST_PACKAGE_NAME_2, r);
+        createDelegateAndVerify(controller, c, r, Collections.emptySet(), getDeniedTags,
+                TEST_PACKAGE_NAME_2);
+    }
+
+    @SmallTest
+    @Test
+    public void createTwoAndDenyOverlappingTags() throws Exception {
+        SipTransportController controller = setupLiveTransportController();
+
+        // First delegate requests RCS message + File transfer
+        ArraySet<String> firstDelegate = new ArraySet<>(getBaseDelegateRequest().getFeatureTags());
+        firstDelegate.remove(ImsSignallingUtils.GROUP_CHAT_TAG);
+        DelegateRequest firstDelegateRequest = new DelegateRequest(firstDelegate);
+        SipDelegateController c1 = injectMockDelegateController(TEST_PACKAGE_NAME,
+                firstDelegateRequest);
+        createDelegateAndVerify(controller, c1, firstDelegateRequest, firstDelegate,
+                Collections.emptySet(), TEST_PACKAGE_NAME);
+
+        // First delegate requests RCS message + Group RCS message. For this delegate, single RCS
+        // message should be denied.
+        ArraySet<String> secondDelegate = new ArraySet<>(getBaseDelegateRequest().getFeatureTags());
+        secondDelegate.remove(ImsSignallingUtils.FILE_TRANSFER_HTTP_TAG);
+        DelegateRequest secondDelegateRequest = new DelegateRequest(secondDelegate);
+        Pair<Set<String>, Set<FeatureTagState>> grantedAndDenied = getAllowedAndDeniedTagsForConfig(
+                secondDelegateRequest, SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE,
+                firstDelegate);
+        SipDelegateController c2 = injectMockDelegateController(TEST_PACKAGE_NAME,
+                secondDelegateRequest);
+        createDelegateAndVerify(controller, c2, secondDelegateRequest, grantedAndDenied.first,
+                grantedAndDenied.second, TEST_PACKAGE_NAME, 1);
+    }
+
+    @SmallTest
+    @Test
+    public void createTwoAndTriggerRoleChange() throws Exception {
+        SipTransportController controller = setupLiveTransportController();
+
+        DelegateRequest firstDelegateRequest = getBaseDelegateRequest();
+        Set<FeatureTagState> firstDeniedTags = getDeniedTagsForReason(
+                firstDelegateRequest.getFeatureTags(),
+                SipDelegateManager.DENIED_REASON_NOT_ALLOWED);
+        SipDelegateController c1 = injectMockDelegateController(TEST_PACKAGE_NAME,
+                firstDelegateRequest);
+        createDelegateAndVerify(controller, c1, firstDelegateRequest,
+                firstDelegateRequest.getFeatureTags(), Collections.emptySet(), TEST_PACKAGE_NAME);
+
+        DelegateRequest secondDelegateRequest = getBaseDelegateRequest();
+        Set<FeatureTagState> secondDeniedTags = getDeniedTagsForReason(
+                secondDelegateRequest.getFeatureTags(),
+                SipDelegateManager.DENIED_REASON_NOT_ALLOWED);
+        // Try to create a SipDelegate for a package that is not the default sms role.
+        SipDelegateController c2 = injectMockDelegateController(TEST_PACKAGE_NAME_2,
+                secondDelegateRequest);
+        createDelegateAndVerify(controller, c2, secondDelegateRequest, Collections.emptySet(),
+                secondDeniedTags, TEST_PACKAGE_NAME_2, 1);
+
+        // now swap the SMS role.
+        CompletableFuture<Boolean> pendingC1Change = setChangeSupportedFeatureTagsFuture(c1,
+                Collections.emptySet(), firstDeniedTags);
+        CompletableFuture<Boolean> pendingC2Change = setChangeSupportedFeatureTagsFuture(c2,
+                secondDelegateRequest.getFeatureTags(), Collections.emptySet());
+        setSmsRoleAndEvaluate(controller, TEST_PACKAGE_NAME_2);
+        // trigger completion stage to run
+        waitForExecutorAction(mExecutorService, TIMEOUT_MS);
+        verify(c1).changeSupportedFeatureTags(Collections.emptySet(), firstDeniedTags);
+        // we should not get a change for c2 until pendingC1Change completes.
+        verify(c2, never()).changeSupportedFeatureTags(secondDelegateRequest.getFeatureTags(),
+                Collections.emptySet());
+        // ensure we are not blocking executor here
+        waitForExecutorAction(mExecutorService, TIMEOUT_MS);
+        completePendingChange(pendingC1Change, true);
+        // trigger completion stage to run
+        waitForExecutorAction(mExecutorService, TIMEOUT_MS);
+        verify(c2).changeSupportedFeatureTags(secondDelegateRequest.getFeatureTags(),
+                Collections.emptySet());
+        // ensure we are not blocking executor here
+        waitForExecutorAction(mExecutorService, TIMEOUT_MS);
+        completePendingChange(pendingC2Change, true);
+    }
+
+    @SmallTest
+    @Test
+    public void createTwoAndDestroyOlder() throws Exception {
+        SipTransportController controller = setupLiveTransportController();
+
+        // First delegate requests RCS message + File transfer
+        ArraySet<String> firstDelegate = new ArraySet<>(getBaseDelegateRequest().getFeatureTags());
+        firstDelegate.remove(ImsSignallingUtils.GROUP_CHAT_TAG);
+        DelegateRequest firstDelegateRequest = new DelegateRequest(firstDelegate);
+        SipDelegateController c1 = injectMockDelegateController(TEST_PACKAGE_NAME,
+                firstDelegateRequest);
+        createDelegateAndVerify(controller, c1, firstDelegateRequest, firstDelegate,
+                Collections.emptySet(), TEST_PACKAGE_NAME);
+
+        // First delegate requests RCS message + Group RCS message. For this delegate, single RCS
+        // message should be denied.
+        ArraySet<String> secondDelegate = new ArraySet<>(getBaseDelegateRequest().getFeatureTags());
+        secondDelegate.remove(ImsSignallingUtils.FILE_TRANSFER_HTTP_TAG);
+        DelegateRequest secondDelegateRequest = new DelegateRequest(secondDelegate);
+        Pair<Set<String>, Set<FeatureTagState>> grantedAndDenied = getAllowedAndDeniedTagsForConfig(
+                secondDelegateRequest, SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE,
+                firstDelegate);
+        SipDelegateController c2 = injectMockDelegateController(TEST_PACKAGE_NAME,
+                secondDelegateRequest);
+        createDelegateAndVerify(controller, c2, secondDelegateRequest, grantedAndDenied.first,
+                grantedAndDenied.second, TEST_PACKAGE_NAME, 1);
+
+        // Destroy the firstDelegate, which should now cause all previously denied tags to be
+        // granted to the new delegate.
+        CompletableFuture<Boolean> pendingC2Change = setChangeSupportedFeatureTagsFuture(c2,
+                secondDelegate, Collections.emptySet());
+        destroyDelegateAndVerify(controller, c1, false /*force*/,
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+        // wait for create to be processed.
+        assertTrue(waitForExecutorAction(mExecutorService, TIMEOUT_MS));
+        verify(c2).changeSupportedFeatureTags(secondDelegate, Collections.emptySet());
+        completePendingChange(pendingC2Change, true);
+    }
+
+    @SmallTest
+    @Test
+    public void testThrottling() throws Exception {
+        SipTransportController controller = setupLiveTransportController(THROTTLE_MS);
+
+        // First delegate requests RCS message + File transfer
+        ArraySet<String> firstDelegate = new ArraySet<>(getBaseDelegateRequest().getFeatureTags());
+        firstDelegate.remove(ImsSignallingUtils.GROUP_CHAT_TAG);
+        DelegateRequest firstDelegateRequest = new DelegateRequest(firstDelegate);
+        SipDelegateController c1 = injectMockDelegateController(TEST_PACKAGE_NAME,
+                firstDelegateRequest);
+        CompletableFuture<Boolean> pendingC1Change = createDelegate(controller, c1,
+                firstDelegateRequest, firstDelegate, Collections.emptySet(), TEST_PACKAGE_NAME);
+
+        // Request RCS message + group RCS Message. For this delegate, single RCS message should be
+        // denied.
+        ArraySet<String> secondDelegate = new ArraySet<>(getBaseDelegateRequest().getFeatureTags());
+        secondDelegate.remove(ImsSignallingUtils.FILE_TRANSFER_HTTP_TAG);
+        DelegateRequest secondDelegateRequest = new DelegateRequest(secondDelegate);
+        Pair<Set<String>, Set<FeatureTagState>> grantedAndDeniedC2 =
+                getAllowedAndDeniedTagsForConfig(secondDelegateRequest,
+                        SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE, firstDelegate);
+        SipDelegateController c2 = injectMockDelegateController(TEST_PACKAGE_NAME,
+                secondDelegateRequest);
+        CompletableFuture<Boolean> pendingC2Change = createDelegate(controller, c2,
+                secondDelegateRequest, grantedAndDeniedC2.first, grantedAndDeniedC2.second,
+                TEST_PACKAGE_NAME);
+
+        // Request group RCS message + file transfer. All should be denied at first
+        ArraySet<String> thirdDelegate = new ArraySet<>(getBaseDelegateRequest().getFeatureTags());
+        thirdDelegate.remove(ImsSignallingUtils.ONE_TO_ONE_CHAT_TAG);
+        DelegateRequest thirdDelegateRequest = new DelegateRequest(thirdDelegate);
+        Pair<Set<String>, Set<FeatureTagState>> grantedAndDeniedC3 =
+                getAllowedAndDeniedTagsForConfig(thirdDelegateRequest,
+                        SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE, firstDelegate,
+                        grantedAndDeniedC2.first);
+        SipDelegateController c3 = injectMockDelegateController(TEST_PACKAGE_NAME,
+                thirdDelegateRequest);
+        CompletableFuture<Boolean> pendingC3Change = createDelegate(controller, c3,
+                thirdDelegateRequest, grantedAndDeniedC3.first, grantedAndDeniedC3.second,
+                TEST_PACKAGE_NAME);
+
+        assertTrue(scheduleDelayedWait(2 * THROTTLE_MS));
+        verifyDelegateChanged(c1, pendingC1Change, firstDelegate, Collections.emptySet(), 0);
+        verifyDelegateChanged(c2, pendingC2Change, grantedAndDeniedC2.first,
+                grantedAndDeniedC2.second, 0);
+        verifyDelegateChanged(c3, pendingC3Change, grantedAndDeniedC3.first,
+                grantedAndDeniedC3.second, 0);
+
+        // Destroy the first and second controller in quick succession, this should only generate
+        // one reevaluate for the third controller.
+        CompletableFuture<Boolean> pendingChangeC3 = setChangeSupportedFeatureTagsFuture(
+                c3, thirdDelegate, Collections.emptySet());
+        CompletableFuture<Integer> pendingDestroyC1 = destroyDelegate(controller, c1,
+                false /*force*/,
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+        CompletableFuture<Integer> pendingDestroyC2 = destroyDelegate(controller, c2,
+                false /*force*/,
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+        assertTrue(scheduleDelayedWait(2 * THROTTLE_MS));
+        verifyDestroyDelegate(controller, c1, pendingDestroyC1, false /*force*/,
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+        verifyDestroyDelegate(controller, c2, pendingDestroyC2, false /*force*/,
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
+
+        // All requested features should now be granted
+        completePendingChange(pendingChangeC3, true);
+        verify(c3).changeSupportedFeatureTags(thirdDelegate, Collections.emptySet());
+        // In total reeval should have only been called twice.
+        verify(c3, times(2)).changeSupportedFeatureTags(any(), any());
+    }
+
+    @SmallTest
+    @Test
+    public void testSubIdChangeDestroyTriggered() throws Exception {
+        SipTransportController controller = setupLiveTransportController();
+
+        ArraySet<String> firstDelegate = new ArraySet<>(getBaseDelegateRequest().getFeatureTags());
+        DelegateRequest firstDelegateRequest = new DelegateRequest(firstDelegate);
+        SipDelegateController c1 = injectMockDelegateController(TEST_PACKAGE_NAME,
+                firstDelegateRequest);
+        createDelegateAndVerify(controller, c1, firstDelegateRequest, firstDelegate,
+                Collections.emptySet(), TEST_PACKAGE_NAME);
+
+        CompletableFuture<Integer> pendingDestroy =  setDestroyFuture(c1, true,
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SUBSCRIPTION_TORN_DOWN);
+        controller.onAssociatedSubscriptionUpdated(TEST_SUB_ID + 1);
+        waitForExecutorAction(mExecutorService, TIMEOUT_MS);
+        verifyDestroyDelegate(controller, c1, pendingDestroy, true /*force*/,
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SUBSCRIPTION_TORN_DOWN);
+    }
+
+    @SmallTest
+    @Test
+    public void testRcsManagerGoneDestroyTriggered() throws Exception {
+        SipTransportController controller = setupLiveTransportController();
+
+        ArraySet<String> firstDelegate = new ArraySet<>(getBaseDelegateRequest().getFeatureTags());
+        DelegateRequest firstDelegateRequest = new DelegateRequest(firstDelegate);
+        SipDelegateController c1 = injectMockDelegateController(TEST_PACKAGE_NAME,
+                firstDelegateRequest);
+        createDelegateAndVerify(controller, c1, firstDelegateRequest, firstDelegate,
+                Collections.emptySet(), TEST_PACKAGE_NAME);
+
+        CompletableFuture<Integer> pendingDestroy =  setDestroyFuture(c1, true,
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD);
+        controller.onRcsDisconnected();
+        waitForExecutorAction(mExecutorService, TIMEOUT_MS);
+        verifyDestroyDelegate(controller, c1, pendingDestroy, true /*force*/,
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD);
+    }
+
+    @SmallTest
+    @Test
+    public void testDestroyTriggered() throws Exception {
+        SipTransportController controller = setupLiveTransportController();
+
+        ArraySet<String> firstDelegate = new ArraySet<>(getBaseDelegateRequest().getFeatureTags());
+        DelegateRequest firstDelegateRequest = new DelegateRequest(firstDelegate);
+        SipDelegateController c1 = injectMockDelegateController(TEST_PACKAGE_NAME,
+                firstDelegateRequest);
+        createDelegateAndVerify(controller, c1, firstDelegateRequest, firstDelegate,
+                Collections.emptySet(), TEST_PACKAGE_NAME);
+
+        CompletableFuture<Integer> pendingDestroy =  setDestroyFuture(c1, true,
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SUBSCRIPTION_TORN_DOWN);
+        controller.onDestroy();
+        waitForExecutorAction(mExecutorService, TIMEOUT_MS);
+        // verify change was called.
+        verify(c1).destroy(true /*force*/,
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SUBSCRIPTION_TORN_DOWN);
+        // ensure thread is not blocked while waiting for pending complete.
+        waitForExecutorAction(mExecutorService, TIMEOUT_MS);
+        completePendingDestroy(pendingDestroy,
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SUBSCRIPTION_TORN_DOWN);
+    }
+
+    @SmallTest
+    @Test
+    public void testTimingSubIdChangedAndCreateNewSubId() throws Exception {
+        SipTransportController controller = setupLiveTransportController(THROTTLE_MS);
+
+        ArraySet<String> firstDelegate = new ArraySet<>(getBaseDelegateRequest().getFeatureTags());
+        DelegateRequest firstDelegateRequest = new DelegateRequest(firstDelegate);
+        SipDelegateController c1 = injectMockDelegateController(TEST_PACKAGE_NAME,
+                firstDelegateRequest);
+        CompletableFuture<Boolean> pendingC1Change = createDelegate(controller, c1,
+                firstDelegateRequest, firstDelegate, Collections.emptySet(), TEST_PACKAGE_NAME);
+        assertTrue(scheduleDelayedWait(2 * THROTTLE_MS));
+        verifyDelegateChanged(c1, pendingC1Change, firstDelegate, Collections.emptySet(), 0);
+
+
+        CompletableFuture<Integer> pendingDestroy =  setDestroyFuture(c1, true,
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SUBSCRIPTION_TORN_DOWN);
+        // triggers reeval now.
+        controller.onAssociatedSubscriptionUpdated(TEST_SUB_ID + 1);
+        waitForExecutorAction(mExecutorService, TIMEOUT_MS);
+
+        // mock a second delegate with the new subId associated with the slot.
+        ArraySet<String> secondDelegate = new ArraySet<>();
+        secondDelegate.add(ImsSignallingUtils.ONE_TO_ONE_CHAT_TAG);
+        secondDelegate.add(ImsSignallingUtils.FILE_TRANSFER_HTTP_TAG);
+        DelegateRequest secondDelegateRequest = new DelegateRequest(secondDelegate);
+        SipDelegateController c2 = injectMockDelegateController(TEST_SUB_ID + 1,
+                TEST_PACKAGE_NAME, secondDelegateRequest);
+        CompletableFuture<Boolean> pendingC2Change = createDelegate(controller, c2,
+                TEST_SUB_ID + 1, secondDelegateRequest, secondDelegate,
+                Collections.emptySet(), TEST_PACKAGE_NAME);
+        assertTrue(scheduleDelayedWait(THROTTLE_MS));
+
+        //trigger destroyed event
+        verifyDestroyDelegate(controller, c1, pendingDestroy, true /*force*/,
+                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SUBSCRIPTION_TORN_DOWN);
+        assertTrue(scheduleDelayedWait(2 * THROTTLE_MS));
+        verifyDelegateChanged(c2, pendingC2Change, secondDelegate, Collections.emptySet(), 0);
+    }
+
+    @SafeVarargs
+    private final Pair<Set<String>, Set<FeatureTagState>> getAllowedAndDeniedTagsForConfig(
+            DelegateRequest r, int denyReason, Set<String>... previousRequestedTagSets) {
+        ArraySet<String> rejectedTags = new ArraySet<>(r.getFeatureTags());
+        ArraySet<String> grantedTags = new ArraySet<>(r.getFeatureTags());
+        Set<String> previousRequestedTags = new ArraySet<>();
+        for (Set<String> s : previousRequestedTagSets) {
+            previousRequestedTags.addAll(s);
+        }
+        rejectedTags.retainAll(previousRequestedTags);
+        grantedTags.removeAll(previousRequestedTags);
+        Set<FeatureTagState> deniedTags = getDeniedTagsForReason(rejectedTags, denyReason);
+        return new Pair<>(grantedTags, deniedTags);
+    }
+
+    private void completePendingChange(CompletableFuture<Boolean> change, boolean result) {
+        mExecutorService.execute(() -> change.complete(result));
+        waitForExecutorAction(mExecutorService, TIMEOUT_MS);
+    }
+
+    private void completePendingDestroy(CompletableFuture<Integer> destroy, int result) {
+        mExecutorService.execute(() -> destroy.complete(result));
+        waitForExecutorAction(mExecutorService, TIMEOUT_MS);
+    }
+
+    private SipTransportController setupLiveTransportController() throws Exception {
+        return setupLiveTransportController(0 /*throttleMs*/);
+    }
+
+    private SipTransportController setupLiveTransportController(int throttleMs) throws Exception {
+        mExecutorService = Executors.newSingleThreadScheduledExecutor();
+        SipTransportController controller = createControllerAndThrottle(mExecutorService,
+                throttleMs);
+        doReturn(mSipTransport).when(mRcsManager).getSipTransport();
+        controller.onAssociatedSubscriptionUpdated(TEST_SUB_ID);
+        controller.onRcsConnected(mRcsManager);
+        waitForExecutorAction(mExecutorService, TIMEOUT_MS);
+        return controller;
+    }
+
+    private void createDelegateAndVerify(SipTransportController controller,
+            SipDelegateController delegateController, DelegateRequest r, Set<String> allowedTags,
+            Set<FeatureTagState> deniedTags, String packageName,
+            int numPreviousChanges) throws ImsException {
+
+        CompletableFuture<Boolean> pendingChange = createDelegate(controller, delegateController, r,
+                allowedTags, deniedTags, packageName);
+        verifyDelegateChanged(delegateController, pendingChange, allowedTags, deniedTags,
+                numPreviousChanges);
+    }
+
+    private void createDelegateAndVerify(SipTransportController controller,
+            SipDelegateController delegateController, DelegateRequest r, Set<String> allowedTags,
+            Set<FeatureTagState> deniedTags, String packageName) throws ImsException {
+        createDelegateAndVerify(controller, delegateController, r, allowedTags, deniedTags,
+                packageName, 0);
+    }
+
+    private CompletableFuture<Boolean> createDelegate(SipTransportController controller,
+            SipDelegateController delegateController, int subId, DelegateRequest r,
+            Set<String> allowedTags, Set<FeatureTagState> deniedTags, String packageName) {
+        CompletableFuture<Boolean> pendingChange = setChangeSupportedFeatureTagsFuture(
+                delegateController, allowedTags, deniedTags);
+        try {
+            controller.createSipDelegate(subId, r, packageName, mMockStateCallback,
+                    mMockMessageCallback);
+        } catch (ImsException e) {
+            fail("ImsException thrown:" + e);
+        }
+        // move to internal & schedule eval
+        waitForExecutorAction(mExecutorService, TIMEOUT_MS);
+        // reeval
+        waitForExecutorAction(mExecutorService, TIMEOUT_MS);
+        return pendingChange;
+    }
+
+    private CompletableFuture<Boolean> createDelegate(SipTransportController controller,
+            SipDelegateController delegateController, DelegateRequest r, Set<String> allowedTags,
+            Set<FeatureTagState> deniedTags, String packageName) throws ImsException {
+        return createDelegate(controller, delegateController, TEST_SUB_ID, r, allowedTags,
+                deniedTags, packageName);
+    }
+
+    private void verifyDelegateChanged(SipDelegateController delegateController,
+            CompletableFuture<Boolean> pendingChange, Set<String> allowedTags,
+            Set<FeatureTagState> deniedTags, int numPreviousChangeStages) {
+        // empty the queue of pending changeSupportedFeatureTags before running the one we are
+        // interested in, since the reevaluate waits for one stage to complete before moving to the
+        // next.
+        for (int i = 0; i < numPreviousChangeStages + 1; i++) {
+            assertTrue(waitForExecutorAction(mExecutorService, TIMEOUT_MS));
+        }
+        // verify change was called.
+        verify(delegateController).changeSupportedFeatureTags(allowedTags, deniedTags);
+        // ensure thread is not blocked while waiting for pending complete.
+        assertTrue(waitForExecutorAction(mExecutorService, TIMEOUT_MS));
+        completePendingChange(pendingChange, true);
+        // process pending change.
+        assertTrue(waitForExecutorAction(mExecutorService, TIMEOUT_MS));
+    }
+
+    private void destroyDelegateAndVerify(SipTransportController controller,
+            SipDelegateController delegateController, boolean force, int reason) {
+        CompletableFuture<Integer> pendingDestroy =  destroyDelegate(controller, delegateController,
+                force, reason);
+        verifyDestroyDelegate(controller, delegateController, pendingDestroy, force, reason);
+    }
+
+    private CompletableFuture<Integer> destroyDelegate(SipTransportController controller,
+            SipDelegateController delegateController, boolean force, int reason) {
+        CompletableFuture<Integer> pendingDestroy =  setDestroyFuture(delegateController, force,
+                reason);
+        controller.destroySipDelegate(TEST_SUB_ID, delegateController.getSipDelegateInterface(),
+                reason);
+        // move to internal & schedule eval
+        waitForExecutorAction(mExecutorService, TIMEOUT_MS);
+        // reeval
+        waitForExecutorAction(mExecutorService, TIMEOUT_MS);
+        return pendingDestroy;
+    }
+
+    private void verifyDestroyDelegate(SipTransportController controller,
+            SipDelegateController delegateController, CompletableFuture<Integer> pendingDestroy,
+            boolean force, int reason) {
+        // verify destroy was called.
+        verify(delegateController).destroy(force, reason);
+        // ensure thread is not blocked while waiting for pending complete.
+        waitForExecutorAction(mExecutorService, TIMEOUT_MS);
+        completePendingDestroy(pendingDestroy, reason);
+    }
+
+    private DelegateRequest getBaseDelegateRequest() {
+        Set<String> featureTags = new ArraySet<>();
+        featureTags.add(ImsSignallingUtils.ONE_TO_ONE_CHAT_TAG);
+        featureTags.add(ImsSignallingUtils.GROUP_CHAT_TAG);
+        featureTags.add(ImsSignallingUtils.FILE_TRANSFER_HTTP_TAG);
+        return new DelegateRequest(featureTags);
+    }
+
+    private Set<FeatureTagState> getBaseDeniedSet() {
+        Set<FeatureTagState> deniedTags = new ArraySet<>();
+        deniedTags.add(new FeatureTagState(ImsSignallingUtils.MMTEL_TAG,
+                SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE));
+        return deniedTags;
+    }
+
+    private Set<FeatureTagState> getDeniedTagsForReason(Set<String> deniedTags, int reason) {
+        return deniedTags.stream().map(t -> new FeatureTagState(t, reason))
+                .collect(Collectors.toSet());
+    }
+
+    private SipDelegateController injectMockDelegateController(String packageName,
+            DelegateRequest r) {
+        return injectMockDelegateController(TEST_SUB_ID, packageName, r);
+    }
+
+    private SipDelegateController injectMockDelegateController(int subId, String packageName,
+            DelegateRequest r) {
+        SipDelegateControllerContainer c = new SipDelegateControllerContainer(subId,
+                packageName, r);
+        mMockControllers.add(c);
+        return c.delegateController;
+    }
+
+    private SipDelegateController getMockDelegateController(int subId, String packageName,
+            DelegateRequest r) {
+        return mMockControllers.stream()
+                .filter(c -> c.subId == subId && c.packageName.equals(packageName)
+                        && c.delegateRequest.equals(r))
+                .map(c -> c.delegateController).findFirst().orElse(null);
+    }
+
+    private CompletableFuture<Boolean> setChangeSupportedFeatureTagsFuture(SipDelegateController c,
+            Set<String> supportedSet, Set<FeatureTagState> deniedSet) {
+        CompletableFuture<Boolean> result = new CompletableFuture<>();
+        doReturn(result).when(c).changeSupportedFeatureTags(eq(supportedSet), eq(deniedSet));
+        return result;
+    }
+
+    private CompletableFuture<Integer> setDestroyFuture(SipDelegateController c, boolean force,
+            int destroyReason) {
+        CompletableFuture<Integer> result = new CompletableFuture<>();
+        doReturn(result).when(c).destroy(force, destroyReason);
+        return result;
+    }
+
+    private void setSmsRoleAndEvaluate(SipTransportController c, String packageName) {
+        verify(mMockRoleManager).addOnRoleHoldersChangedListenerAsUser(any(), any(), any());
+        mSmsPackageName.clear();
+        mSmsPackageName.add(packageName);
+        c.onRoleHoldersChanged(RoleManager.ROLE_SMS, UserHandle.SYSTEM);
+        // finish internal throttled re-evaluate
+        waitForExecutorAction(mExecutorService, TIMEOUT_MS);
+    }
+
+    private SipTransportController createController(ScheduledExecutorService e) {
+        return createControllerAndThrottle(e, 0 /*throttleMs*/);
+    }
+
+    private SipTransportController createControllerAndThrottle(ScheduledExecutorService e,
+            int throttleMs) {
+        return new SipTransportController(mContext, 0 /*slotId*/, TEST_SUB_ID,
+                mMockDelegateControllerFactory, mMockRoleManager,
+                // Remove delays for testing.
+                new SipTransportController.TimerAdapter() {
+                    @Override
+                    public int getReevaluateThrottleTimerMilliseconds() {
+                        return throttleMs;
+                    }
+
+                    @Override
+                    public int getUpdateRegistrationDelayMilliseconds() {
+                        return 0;
+                    }
+                }, e);
+    }
+
+    private boolean scheduleDelayedWait(long timeMs) {
+        CountDownLatch l = new CountDownLatch(1);
+        mExecutorService.schedule(l::countDown, timeMs, TimeUnit.MILLISECONDS);
+        while (l.getCount() > 0) {
+            try {
+                return l.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                // try again
+            }
+        }
+        return true;
     }
 }
diff --git a/tests/src/com/android/services/telephony/rcs/TelephonyRcsServiceTest.java b/tests/src/com/android/services/telephony/rcs/TelephonyRcsServiceTest.java
index ffbb71d..7a9f9e3 100644
--- a/tests/src/com/android/services/telephony/rcs/TelephonyRcsServiceTest.java
+++ b/tests/src/com/android/services/telephony/rcs/TelephonyRcsServiceTest.java
@@ -50,8 +50,8 @@
 
     @Captor ArgumentCaptor<BroadcastReceiver> mReceiverCaptor;
     @Mock TelephonyRcsService.FeatureFactory mFeatureFactory;
-    @Mock UserCapabilityExchangeImpl mMockUceSlot0;
-    @Mock UserCapabilityExchangeImpl mMockUceSlot1;
+    @Mock UceControllerManager mMockUceSlot0;
+    @Mock UceControllerManager mMockUceSlot1;
     @Mock SipTransportController mMockSipTransportSlot0;
     @Mock SipTransportController mMockSipTransportSlot1;
     @Mock RcsFeatureController.RegistrationHelperFactory mRegistrationFactory;
@@ -70,9 +70,9 @@
         mFeatureControllerSlot1 = createFeatureController(1 /*slotId*/);
         doReturn(mFeatureControllerSlot0).when(mFeatureFactory).createController(any(), eq(0));
         doReturn(mFeatureControllerSlot1).when(mFeatureFactory).createController(any(), eq(1));
-        doReturn(mMockUceSlot0).when(mFeatureFactory).createUserCapabilityExchange(any(), eq(0),
+        doReturn(mMockUceSlot0).when(mFeatureFactory).createUceControllerManager(any(), eq(0),
                 anyInt());
-        doReturn(mMockUceSlot1).when(mFeatureFactory).createUserCapabilityExchange(any(), eq(1),
+        doReturn(mMockUceSlot1).when(mFeatureFactory).createUceControllerManager(any(), eq(1),
                 anyInt());
         doReturn(mMockSipTransportSlot0).when(mFeatureFactory).createSipTransportController(any(),
                 eq(0), anyInt());
@@ -89,20 +89,20 @@
     }
 
     @Test
-    public void testUserCapabilityExchangePresenceConnected() {
+    public void testUceControllerPresenceConnected() {
         setCarrierConfig(1 /*subId*/, CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL,
                 true /*isEnabled*/);
         createRcsService(1 /*numSlots*/);
-        verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UserCapabilityExchangeImpl.class);
+        verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UceControllerManager.class);
         verify(mFeatureControllerSlot0).connect();
     }
 
     @Test
-    public void testUserCapabilityExchangeOptionsConnected() {
+    public void testUceControllerOptionsConnected() {
         setCarrierConfig(1 /*subId*/, CarrierConfigManager.KEY_USE_RCS_SIP_OPTIONS_BOOL,
                 true /*isEnabled*/);
         createRcsService(1 /*numSlots*/);
-        verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UserCapabilityExchangeImpl.class);
+        verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UceControllerManager.class);
         verify(mFeatureControllerSlot0).connect();
     }
 
@@ -111,7 +111,7 @@
         createRcsService(1 /*numSlots*/);
         // No carrier config set for UCE.
         verify(mFeatureControllerSlot0, never()).addFeature(mMockUceSlot0,
-                UserCapabilityExchangeImpl.class);
+                UceControllerManager.class);
         verify(mFeatureControllerSlot0, never()).connect();
     }
 
@@ -171,7 +171,7 @@
 
         sendCarrierConfigChanged(0, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
         verify(mFeatureControllerSlot0, never()).addFeature(mMockUceSlot0,
-                UserCapabilityExchangeImpl.class);
+                UceControllerManager.class);
         verify(mFeatureControllerSlot0, never()).connect();
         verify(mFeatureControllerSlot0, never()).updateAssociatedSubscription(anyInt());
     }
@@ -184,25 +184,25 @@
         setCarrierConfig(2 /*subId*/, CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL,
                 true /*isEnabled*/);
         TelephonyRcsService service = createRcsService(1 /*numSlots*/);
-        verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UserCapabilityExchangeImpl.class);
+        verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UceControllerManager.class);
         verify(mFeatureControllerSlot0).connect();
 
         // there should be no changes if the new num slots = old num
         service.updateFeatureControllerSize(1 /*newNumSlots*/);
         verify(mFeatureControllerSlot0, times(1)).addFeature(mMockUceSlot0,
-                UserCapabilityExchangeImpl.class);
+                UceControllerManager.class);
         verify(mFeatureControllerSlot0, times(1)).connect();
 
         // Add a new slot.
         verify(mFeatureControllerSlot1, never()).addFeature(mMockUceSlot1,
-                UserCapabilityExchangeImpl.class);
+                UceControllerManager.class);
         verify(mFeatureControllerSlot1, never()).connect();
         service.updateFeatureControllerSize(2 /*newNumSlots*/);
         // This shouldn't have changed for slot 0.
         verify(mFeatureControllerSlot0, times(1)).addFeature(mMockUceSlot0,
-                UserCapabilityExchangeImpl.class);
+                UceControllerManager.class);
         verify(mFeatureControllerSlot0, times(1)).connect();
-        verify(mFeatureControllerSlot1).addFeature(mMockUceSlot1, UserCapabilityExchangeImpl.class);
+        verify(mFeatureControllerSlot1).addFeature(mMockUceSlot1, UceControllerManager.class);
         verify(mFeatureControllerSlot1, times(1)).connect();
 
         // Remove a slot.
@@ -211,10 +211,10 @@
         service.updateFeatureControllerSize(1 /*newNumSlots*/);
         // addFeature/connect shouldn't have been called again
         verify(mFeatureControllerSlot0, times(1)).addFeature(mMockUceSlot0,
-                UserCapabilityExchangeImpl.class);
+                UceControllerManager.class);
         verify(mFeatureControllerSlot0, times(1)).connect();
         verify(mFeatureControllerSlot1, times(1)).addFeature(mMockUceSlot1,
-                UserCapabilityExchangeImpl.class);
+                UceControllerManager.class);
         verify(mFeatureControllerSlot1, times(1)).connect();
         // Verify destroy is only called for slot 1.
         verify(mFeatureControllerSlot0, never()).destroy();
@@ -228,8 +228,8 @@
         setCarrierConfig(2 /*subId*/, CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL,
                 true /*isEnabled*/);
         createRcsService(2 /*numSlots*/);
-        verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UserCapabilityExchangeImpl.class);
-        verify(mFeatureControllerSlot1).addFeature(mMockUceSlot1, UserCapabilityExchangeImpl.class);
+        verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UceControllerManager.class);
+        verify(mFeatureControllerSlot1).addFeature(mMockUceSlot1, UceControllerManager.class);
         verify(mFeatureControllerSlot0).connect();
         verify(mFeatureControllerSlot1).connect();
 
@@ -248,7 +248,7 @@
         setCarrierConfig(1 /*subId*/, CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL,
                 true /*isEnabled*/);
         createRcsService(1 /*numSlots*/);
-        verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UserCapabilityExchangeImpl.class);
+        verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UceControllerManager.class);
         verify(mFeatureControllerSlot0).connect();
 
 
@@ -256,7 +256,7 @@
         setCarrierConfig(1 /*subId*/, CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL,
                 false /*isEnabled*/);
         sendCarrierConfigChanged(0 /*slotId*/, 1 /*subId*/);
-        verify(mFeatureControllerSlot0).removeFeature(UserCapabilityExchangeImpl.class);
+        verify(mFeatureControllerSlot0).removeFeature(UceControllerManager.class);
         verify(mFeatureControllerSlot0).updateAssociatedSubscription(1);
     }
 
@@ -284,7 +284,7 @@
     public void testCarrierConfigUpdateNoUceToUce() {
         createRcsService(1 /*numSlots*/);
         verify(mFeatureControllerSlot0, never()).addFeature(mMockUceSlot0,
-                UserCapabilityExchangeImpl.class);
+                UceControllerManager.class);
         verify(mFeatureControllerSlot0, never()).connect();
 
 
@@ -292,7 +292,7 @@
         setCarrierConfig(1 /*subId*/, CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL,
                 true /*isEnabled*/);
         sendCarrierConfigChanged(0 /*slotId*/, 1 /*subId*/);
-        verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UserCapabilityExchangeImpl.class);
+        verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UceControllerManager.class);
         verify(mFeatureControllerSlot0).connect();
         verify(mFeatureControllerSlot0).updateAssociatedSubscription(1);
     }
diff --git a/tests/src/com/android/services/telephony/rcs/UceControllerManagerTest.java b/tests/src/com/android/services/telephony/rcs/UceControllerManagerTest.java
new file mode 100644
index 0000000..4148d13
--- /dev/null
+++ b/tests/src/com/android/services/telephony/rcs/UceControllerManagerTest.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2020 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.rcs;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+
+import android.net.Uri;
+import android.telephony.ims.ImsException;
+import android.telephony.ims.aidl.IRcsUceControllerCallback;
+import android.telephony.ims.aidl.IRcsUcePublishStateCallback;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.TelephonyTestBase;
+import com.android.TestExecutorService;
+import com.android.ims.RcsFeatureManager;
+import com.android.ims.rcs.uce.UceController;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+
+@RunWith(AndroidJUnit4.class)
+public class UceControllerManagerTest extends TelephonyTestBase {
+
+    @Mock private UceController mUceController;
+    @Mock private RcsFeatureManager mRcsFeatureManager;
+
+    private final ExecutorService mExecutorService = new TestExecutorService();
+
+    private int mSlotId = 1;
+    private int mSubId = 1;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        doReturn(mSubId).when(mUceController).getSubId();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void testRcsConnected() throws Exception {
+        UceControllerManager controllerManager = getUceControllerManager();
+
+        controllerManager.onRcsConnected(mRcsFeatureManager);
+
+        verify(mUceController).onRcsConnected(mRcsFeatureManager);
+    }
+
+    @Test
+    public void testRcsDisconnected() throws Exception {
+        UceControllerManager uceCtrlManager = getUceControllerManager();
+
+        uceCtrlManager.onRcsDisconnected();
+
+        verify(mUceController).onRcsDisconnected();
+    }
+
+    @Test
+    public void testDestroy() throws Exception {
+        UceControllerManager uceCtrlManager = getUceControllerManager();
+
+        uceCtrlManager.onDestroy();
+
+        verify(mUceController).onDestroy();
+    }
+
+    @Test
+    public void testSubscriptionUpdated() throws Exception {
+        UceControllerManager uceCtrlManager = getUceControllerManager();
+
+        uceCtrlManager.onAssociatedSubscriptionUpdated(mSubId);
+
+        verify(mUceController).onDestroy();
+    }
+
+    @Test
+    public void testRequestCapabilitiesWithRcsUnavailable() throws Exception {
+        UceControllerManager uceCtrlManager = getUceControllerManager();
+        doReturn(true).when(mUceController).isUnavailable();
+        uceCtrlManager.onRcsDisconnected();
+
+        try {
+            List<Uri> contacts = Arrays.asList(Uri.fromParts("sip", "00000", null));
+            IRcsUceControllerCallback callback = Mockito.mock(IRcsUceControllerCallback.class);
+
+            uceCtrlManager.requestCapabilities(contacts, callback);
+
+            fail();
+        } catch (ImsException e) {
+            assertEquals(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE, e.getCode());
+            return;
+        }
+        fail();
+    }
+
+    @Test
+    public void testRequestCapabilitiesWithRcsConnected() throws Exception {
+        UceControllerManager uceCtrlManager = getUceControllerManager();
+        doReturn(false).when(mUceController).isUnavailable();
+        uceCtrlManager.onRcsConnected(mRcsFeatureManager);
+
+        try {
+            List<Uri> contacts = Arrays.asList(Uri.fromParts("sip", "00000", null));
+            IRcsUceControllerCallback callback = Mockito.mock(IRcsUceControllerCallback.class);
+
+            uceCtrlManager.requestCapabilities(contacts, callback);
+
+            verify(mUceController).requestCapabilities(contacts, callback);
+        } catch (ImsException e) {
+            fail();
+        }
+    }
+
+    @Test
+    public void testRequestNetworkAvailability() throws Exception {
+        UceControllerManager uceCtrlManager = getUceControllerManager();
+        doReturn(false).when(mUceController).isUnavailable();
+        uceCtrlManager.onRcsConnected(mRcsFeatureManager);
+
+        Uri contact = Uri.fromParts("sip", "00000", null);
+        IRcsUceControllerCallback callback = Mockito.mock(IRcsUceControllerCallback.class);
+
+        uceCtrlManager.requestNetworkAvailability(contact, callback);
+
+        verify(mUceController).requestAvailability(contact, callback);
+    }
+
+    @Test
+    public void testRequestNetworkAvailabilityWithRcsUnavailable() throws Exception {
+        UceControllerManager uceCtrlManager = getUceControllerManager();
+        doReturn(true).when(mUceController).isUnavailable();
+        uceCtrlManager.onRcsDisconnected();
+
+        try {
+            Uri contact = Uri.fromParts("sip", "00000", null);
+            IRcsUceControllerCallback callback = Mockito.mock(IRcsUceControllerCallback.class);
+            uceCtrlManager.requestNetworkAvailability(contact, callback);
+            fail();
+        } catch (ImsException e) {
+            assertEquals(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE, e.getCode());
+            return;
+        }
+        fail();
+    }
+
+    @Test
+    public void testGetPublishState() throws Exception {
+        UceControllerManager uceCtrlManager = getUceControllerManager();
+        doReturn(false).when(mUceController).isUnavailable();
+        uceCtrlManager.onRcsConnected(mRcsFeatureManager);
+
+        uceCtrlManager.getUcePublishState();
+
+        verify(mUceController).getUcePublishState();
+    }
+
+    @Test
+    public void testGetPublishStateWithRcsUnavailable() throws Exception {
+        UceControllerManager uceCtrlManager = getUceControllerManager();
+        doReturn(true).when(mUceController).isUnavailable();
+        uceCtrlManager.onRcsDisconnected();
+
+        try {
+            uceCtrlManager.getUcePublishState();
+            fail();
+        } catch (ImsException e) {
+            assertEquals(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE, e.getCode());
+            return;
+        }
+        fail();
+    }
+
+    @Test
+    public void testRegisterPublishStateCallback() throws Exception {
+        UceControllerManager uceCtrlManager = getUceControllerManager();
+        IRcsUcePublishStateCallback callback = Mockito.mock(IRcsUcePublishStateCallback.class);
+
+        uceCtrlManager.registerPublishStateCallback(callback);
+
+        verify(mUceController).registerPublishStateCallback(callback);
+    }
+
+    @Test
+    public void testRegisterPublishStateCallbackWithRcsUnavailable() throws Exception {
+        UceControllerManager uceCtrlManager = getUceControllerManager();
+        doReturn(true).when(mUceController).isUnavailable();
+        uceCtrlManager.onRcsDisconnected();
+
+        try {
+            IRcsUcePublishStateCallback callback = Mockito.mock(IRcsUcePublishStateCallback.class);
+            uceCtrlManager.registerPublishStateCallback(callback);
+            fail();
+        } catch (ImsException e) {
+            assertEquals(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE, e.getCode());
+            return;
+        }
+        fail();
+    }
+
+    @Test
+    public void testUnregisterPublishStateCallback() throws Exception {
+        UceControllerManager uceCtrlManager = getUceControllerManager();
+        IRcsUcePublishStateCallback callback = Mockito.mock(IRcsUcePublishStateCallback.class);
+
+        uceCtrlManager.unregisterPublishStateCallback(callback);
+
+        verify(mUceController).unregisterPublishStateCallback(callback);
+    }
+
+    private UceControllerManager getUceControllerManager() {
+        UceControllerManager manager = new UceControllerManager(mContext, mSlotId, mSubId,
+                mExecutorService);
+        manager.setUceController(mUceController);
+        return manager;
+    }
+}
diff --git a/tests/src/com/android/services/telephony/rcs/UserCapabilityExchangeImplTest.java b/tests/src/com/android/services/telephony/rcs/UserCapabilityExchangeImplTest.java
deleted file mode 100644
index 3cbe8bf..0000000
--- a/tests/src/com/android/services/telephony/rcs/UserCapabilityExchangeImplTest.java
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright (C) 2020 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.rcs;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyList;
-import static org.mockito.Mockito.atLeast;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.net.Uri;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.RemoteCallbackList;
-import android.telephony.ims.ImsManager;
-import android.telephony.ims.ImsMmTelManager;
-import android.telephony.ims.RcsContactPresenceTuple;
-import android.telephony.ims.RcsContactPresenceTuple.ServiceCapabilities;
-import android.telephony.ims.RcsContactUceCapability;
-import android.telephony.ims.RcsContactUceCapability.PresenceBuilder;
-import android.telephony.ims.RegistrationManager;
-import android.telephony.ims.aidl.IRcsUceControllerCallback;
-import android.telephony.ims.aidl.IRcsUcePublishStateCallback;
-import android.telephony.ims.stub.RcsCapabilityExchange;
-import android.telephony.ims.stub.RcsPresenceExchangeImplBase;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.TelephonyTestBase;
-import com.android.ims.RcsFeatureManager;
-import com.android.ims.RcsFeatureManager.RcsFeatureCallbacks;
-import com.android.ims.ResultCode;
-import com.android.service.ims.presence.PresenceBase;
-import com.android.service.ims.presence.PresencePublication;
-import com.android.service.ims.presence.PresencePublisher;
-import com.android.service.ims.presence.PresenceSubscriber;
-import com.android.service.ims.presence.SubscribePublisher;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.Executor;
-
-@RunWith(AndroidJUnit4.class)
-public class UserCapabilityExchangeImplTest extends TelephonyTestBase {
-
-    private int  mSlotId = 0;
-    private int mSubId = 1;
-    private int mUpdatedSubId = 2;
-
-    @Captor ArgumentCaptor<IRcsUcePublishStateCallback> mPublishStateCallbacksCaptor;
-
-    @Mock PresencePublication mPresencePublication;
-    @Mock PresenceSubscriber mPresenceSubscriber;
-    @Mock RcsFeatureManager mRcsFeatureManager;
-    @Mock ImsMmTelManager mImsMmTelManager;
-    @Mock RemoteCallbackList<IRcsUcePublishStateCallback> mPublishStateCallbacks;
-
-    private Looper mLooper;
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-
-        ImsManager imsManager =
-                (ImsManager) mContext.getSystemService(Context.TELEPHONY_IMS_SERVICE);
-        when(imsManager.getImsMmTelManager(mSubId)).thenReturn(mImsMmTelManager);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        super.tearDown();
-
-        if (mLooper != null) {
-            mLooper.quit();
-            mLooper = null;
-        }
-    }
-
-    @Test
-    public void testServiceConnected() throws Exception {
-        UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
-        uceImpl.onRcsConnected(mRcsFeatureManager);
-
-        verify(mRcsFeatureManager).addFeatureListenerCallback(any(RcsFeatureCallbacks.class));
-        verify(mPresencePublication).updatePresencePublisher(any(PresencePublisher.class));
-        verify(mPresenceSubscriber).updatePresenceSubscriber(any(SubscribePublisher.class));
-    }
-
-    @Test
-    public void testServiceDisconnected() throws Exception {
-        UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
-        uceImpl.onRcsDisconnected();
-
-        verify(mPresencePublication).removePresencePublisher();
-        verify(mPresenceSubscriber).removePresenceSubscriber();
-    }
-
-    @Test
-    public void testSubscriptionUpdated() throws Exception {
-        UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
-        uceImpl.onAssociatedSubscriptionUpdated(mUpdatedSubId);
-
-        verify(mImsMmTelManager).registerImsRegistrationCallback(any(Executor.class),
-                any(RegistrationManager.RegistrationCallback.class));
-        verify(mImsMmTelManager).registerMmTelCapabilityCallback(any(Executor.class),
-                any(ImsMmTelManager.CapabilityCallback.class));
-        verify(mPresencePublication).handleAssociatedSubscriptionChanged(mUpdatedSubId);
-        verify(mPresenceSubscriber).handleAssociatedSubscriptionChanged(mUpdatedSubId);
-    }
-
-    @Test
-    public void testUcePublishStateRetrieval() throws Exception {
-        UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
-        uceImpl.getUcePublishState();
-
-        verify(mPresencePublication).getPublishState();
-    }
-
-    @Test
-    public void testRegisterPublishStateCallbacks() throws Exception {
-        UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
-        uceImpl.registerPublishStateCallback(any(IRcsUcePublishStateCallback.class));
-        verify(mPublishStateCallbacks).register(mPublishStateCallbacksCaptor.capture());
-    }
-
-    @Test
-    public void testOnNotifyUpdateCapabilities() throws Exception {
-        UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
-        uceImpl.onRcsConnected(mRcsFeatureManager);
-
-        int triggerType = RcsPresenceExchangeImplBase.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN;
-        uceImpl.mRcsFeatureCallback.onNotifyUpdateCapabilities(triggerType);
-        waitForMs(1000);
-
-        verify(mPresencePublication).onStackPublishRequested(triggerType);
-    }
-
-    @Test
-    public void testRequestPublicationWithSuccessfulResponse() throws Exception {
-        int taskId = 1;
-        int sipResponse = 200;
-        Uri contact = Uri.fromParts("sip", "test", null);
-        RcsContactUceCapability capability = getRcsContactUceCapability(contact);
-
-        UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
-        uceImpl.onRcsConnected(mRcsFeatureManager);
-
-        doAnswer(invocation -> {
-            uceImpl.mRcsFeatureCallback.onCommandUpdate(RcsCapabilityExchange.COMMAND_CODE_SUCCESS,
-                    taskId);
-            uceImpl.mRcsFeatureCallback.onNetworkResponse(sipResponse, null, taskId);
-            return null;
-        }).when(mRcsFeatureManager).requestPublication(capability, taskId);
-
-        // Request publication
-        int result = uceImpl.requestPublication(capability, contact.toString(), taskId);
-
-        assertEquals(ResultCode.SUCCESS, result);
-        verify(mPresencePublication).onCommandStatusUpdated(taskId, taskId, ResultCode.SUCCESS);
-        verify(mPresencePublication).onSipResponse(taskId, sipResponse, null);
-    }
-
-    @Test
-    public void testRequestPublicationWithFailedResponse() throws Exception {
-        int taskId = 1;
-        Uri contact = Uri.fromParts("sip", "test", null);
-        RcsContactUceCapability capability = getRcsContactUceCapability(contact);
-
-        UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
-        uceImpl.onRcsConnected(mRcsFeatureManager);
-
-        doAnswer(invocation -> {
-            uceImpl.mRcsFeatureCallback.onCommandUpdate(
-                    RcsCapabilityExchange.COMMAND_CODE_GENERIC_FAILURE, taskId);
-            return null;
-        }).when(mRcsFeatureManager).requestPublication(capability, taskId);
-
-        // Request publication
-        int result = uceImpl.requestPublication(capability, contact.toString(), taskId);
-
-        assertEquals(ResultCode.SUCCESS, result);
-        verify(mPresencePublication).onCommandStatusUpdated(taskId, taskId,
-                ResultCode.PUBLISH_GENERIC_FAILURE);
-    }
-
-    private RcsContactUceCapability getRcsContactUceCapability(Uri contact) {
-        ServiceCapabilities.Builder servCapsBuilder = new ServiceCapabilities.Builder(true, true);
-        servCapsBuilder.addSupportedDuplexMode(ServiceCapabilities.DUPLEX_MODE_FULL);
-
-        RcsContactPresenceTuple.Builder tupleBuilder = new RcsContactPresenceTuple.Builder(
-                RcsContactPresenceTuple.TUPLE_BASIC_STATUS_OPEN,
-                RcsContactPresenceTuple.SERVICE_ID_MMTEL, "1.0");
-        tupleBuilder.addContactUri(contact).addServiceCapabilities(servCapsBuilder.build());
-
-        PresenceBuilder presenceBuilder = new PresenceBuilder(contact,
-                RcsContactUceCapability.SOURCE_TYPE_CACHED,
-                RcsContactUceCapability.REQUEST_RESULT_FOUND);
-        presenceBuilder.addCapabilityTuple(tupleBuilder.build());
-        return presenceBuilder.build();
-    }
-
-    @Test
-    public void testRequestCapability() throws Exception {
-        int taskId = 1;
-        int sipResponse = 200;
-        List<RcsContactUceCapability> infos = new ArrayList<>();
-        List<Uri> contacts = Arrays.asList(Uri.fromParts("sip", "00000", null));
-        IRcsUceControllerCallback callback = Mockito.mock(IRcsUceControllerCallback.class);
-
-        UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
-        uceImpl.onRcsConnected(mRcsFeatureManager);
-
-        when(mPresenceSubscriber.requestCapability(anyList(), any())).thenReturn(taskId);
-
-        doAnswer(invocation -> {
-            uceImpl.mRcsFeatureCallback.onCommandUpdate(RcsCapabilityExchange.COMMAND_CODE_SUCCESS,
-                    taskId);
-            uceImpl.mRcsFeatureCallback.onNetworkResponse(sipResponse, null, taskId);
-            uceImpl.mRcsFeatureCallback.onCapabilityRequestResponsePresence(infos, taskId);
-            return null;
-        }).when(mRcsFeatureManager).requestCapabilities(anyList(), anyInt());
-
-        uceImpl.requestCapabilities(contacts, callback);
-        uceImpl.requestCapability(new String[] {"00000"}, taskId);
-
-        verify(mPresenceSubscriber).onCommandStatusUpdated(taskId, taskId, ResultCode.SUCCESS);
-        verify(mPresenceSubscriber).onSipResponse(taskId, sipResponse, null);
-        verify(mPresenceSubscriber).updatePresences(taskId, infos, true, null);
-    }
-
-    @Test
-    public void testUpdatePublisherState() throws Exception {
-        IRcsUcePublishStateCallback callback = Mockito.mock(IRcsUcePublishStateCallback.class);
-        doAnswer(invocation -> {
-            callback.onPublishStateChanged(anyInt());
-            return null;
-        }).when(mPublishStateCallbacks).broadcast(any());
-
-        UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
-        uceImpl.onRcsConnected(mRcsFeatureManager);
-        uceImpl.registerPublishStateCallback(callback);
-        uceImpl.updatePublisherState(PresenceBase.PUBLISH_STATE_200_OK);
-
-        assertEquals(PresenceBase.PUBLISH_STATE_200_OK, uceImpl.getPublisherState());
-        verify(callback).onPublishStateChanged(anyInt());
-    }
-
-    @Test
-    public void testUnpublish() throws Exception {
-        IRcsUcePublishStateCallback callback = Mockito.mock(IRcsUcePublishStateCallback.class);
-        doAnswer(invocation -> {
-            callback.onPublishStateChanged(anyInt());
-            return null;
-        }).when(mPublishStateCallbacks).broadcast(any());
-
-        UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
-        uceImpl.onRcsConnected(mRcsFeatureManager);
-        uceImpl.mRcsFeatureCallback.onUnpublish();
-        waitForMs(1000);
-
-        verify(mPresencePublication).setPublishState(PresenceBase.PUBLISH_STATE_NOT_PUBLISHED);
-    }
-
-    private UserCapabilityExchangeImpl createUserCapabilityExchangeImpl() throws Exception {
-        HandlerThread handlerThread = new HandlerThread("UceImplHandlerThread");
-        handlerThread.start();
-        mLooper = handlerThread.getLooper();
-        UserCapabilityExchangeImpl uceImpl = new UserCapabilityExchangeImpl(mContext, mSlotId,
-                mSubId, mLooper, mPresencePublication, mPresenceSubscriber,
-                mPublishStateCallbacks);
-        verify(mPresencePublication).handleAssociatedSubscriptionChanged(1);
-        verify(mPresenceSubscriber).handleAssociatedSubscriptionChanged(1);
-        waitForHandlerAction(uceImpl.getHandler(), 1000);
-        verify(mImsMmTelManager, atLeast(1)).registerImsRegistrationCallback(
-                any(Executor.class), any(RegistrationManager.RegistrationCallback.class));
-        verify(mContext).registerReceiver(any(), any());
-        return uceImpl;
-    }
-}
