diff --git a/src/com/android/phone/ImsRcsController.java b/src/com/android/phone/ImsRcsController.java
index 58f3646..52069b8 100644
--- a/src/com/android/phone/ImsRcsController.java
+++ b/src/com/android/phone/ImsRcsController.java
@@ -16,10 +16,12 @@
 
 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;
@@ -413,10 +415,22 @@
     }
 
     @Override
-    public void createSipDelegate(int subId, DelegateRequest request,
+    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(
@@ -426,7 +440,8 @@
                     "This subscription does not support the creation of SIP delegates");
         }
         try {
-            transport.createSipDelegate(subId, request, delegateState, delegateMessage);
+            transport.createSipDelegate(subId, request, packageName, delegateState,
+                    delegateMessage);
         } catch (ImsException e) {
             throw new ServiceSpecificException(e.getCode(), e.getMessage());
         } finally {
@@ -440,7 +455,12 @@
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            // Do nothing yet, we do not support this API yet.
+            SipTransportController transport = getRcsFeatureController(subId).getFeature(
+                    SipTransportController.class);
+            if (transport == null) {
+                return;
+            }
+            transport.destroySipDelegate(subId, connection, reason);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
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..e287813
--- /dev/null
+++ b/src/com/android/services/telephony/rcs/DelegateStateTracker.java
@@ -0,0 +1,203 @@
+/*
+ * 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) {
+        mLastRegState = registrationState;
+        if (mRegistrationStateOverride > DelegateRegistrationState.DEREGISTERED_REASON_UNKNOWN) {
+            logi("onRegistrationStateChanged: overriding registered state to "
+                    + mRegistrationStateOverride);
+            registrationState = overrideRegistrationForDelegateChange(mRegistrationStateOverride,
+                    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();
+        // Override REGISTERED only
+        for (String ft : registeredFeatures) {
+            overriddenState.addDeregisteringFeatureTag(ft, registerOverrideReason);
+        }
+        // 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());
+        }
+        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..531ed7d
--- /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, int 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..8ae1936
--- /dev/null
+++ b/src/com/android/services/telephony/rcs/SipDelegateBinderConnection.java
@@ -0,0 +1,214 @@
+/*
+ * 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.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.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.List;
+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 {
+    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);
+        } 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));
+        }
+    }
+
+    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);
+    }
+}
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..ee9d4a7
--- /dev/null
+++ b/src/com/android/services/telephony/rcs/SipDelegateController.java
@@ -0,0 +1,372 @@
+/*
+ * 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.ArraySet;
+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 = new ArraySet<>();
+
+    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.
+        return pendingCreate.thenApplyAsync((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;
+        }, mExecutorService);
+    }
+
+    /**
+     * 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.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 813834a..dd06cc1 100644
--- a/src/com/android/services/telephony/rcs/SipTransportController.java
+++ b/src/com/android/services/telephony/rcs/SipTransportController.java
@@ -16,26 +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
@@ -46,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.
@@ -64,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();
     }
 
@@ -76,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");
     }
@@ -102,8 +294,14 @@
 
     @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);
+        });
     }
 
     /**
@@ -119,12 +317,24 @@
      * @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,
+    public void createSipDelegate(int subId, DelegateRequest request, String packageName,
             ISipDelegateConnectionStateCallback delegateState,
             ISipDelegateMessageCallback delegateMessage) throws ImsException {
-        // TODO implementation.
-        throw new ImsException("createSipDelegate is not supported yet",
-                ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
+        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);
+        }
     }
 
     /**
@@ -134,7 +344,7 @@
      * @param reason The reason for why the {@link SipDelegate} was destroyed.
      */
     public void destroySipDelegate(int subId, ISipDelegate connection, int reason) {
-        // TODO implementation
+        mExecutorService.execute(() -> destroySipDelegateInternal(subId, connection, reason));
     }
 
     /**
@@ -151,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.
@@ -164,6 +472,277 @@
         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() {
+        // Only one app can fulfill the SMS role.
+        String newSmsRolePackageName = mRoleManagerAdapter.getRoleHolders(RoleManager.ROLE_SMS)
+                .stream().findFirst().orElse("");
+
+        if (TextUtils.equals(mCachedSmsRolePackageName, newSmsRolePackageName)) {
+            logi("onRoleHoldersChanged, 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.
@@ -207,7 +786,26 @@
 
     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 {
+            registerListeners();
+            updateRoleCache();
+        }
+    }
+
+    private void registerListeners() {
+        mRoleManagerAdapter.addOnRoleHoldersChangedListenerAsUser(mExecutorService, this,
+                UserHandle.SYSTEM);
+    }
+
+    private void unregisterListeners() {
+        mRoleManagerAdapter.removeOnRoleHoldersChangedListenerAsUser(this, UserHandle.SYSTEM);
+        mCachedSmsRolePackageName = "";
     }
 
     /**
@@ -216,18 +814,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/UceControllerManager.java b/src/com/android/services/telephony/rcs/UceControllerManager.java
index db8c933..d1f91d1 100644
--- a/src/com/android/services/telephony/rcs/UceControllerManager.java
+++ b/src/com/android/services/telephony/rcs/UceControllerManager.java
@@ -28,7 +28,9 @@
 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;
@@ -231,4 +233,15 @@
         }
         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/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/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..7ba4252
--- /dev/null
+++ b/tests/src/com/android/services/telephony/rcs/MessageTransportStateTrackerTest.java
@@ -0,0 +1,242 @@
+/*
+ * 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.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(), anyInt());
+        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..b95ae90
--- /dev/null
+++ b/tests/src/com/android/services/telephony/rcs/SipDelegateBinderConnectionTest.java
@@ -0,0 +1,226 @@
+/*
+ * 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.doThrow;
+import static org.mockito.Mockito.verify;
+
+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 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();
+        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;
     }
 }
