diff --git a/src/com/android/phone/ImsRcsController.java b/src/com/android/phone/ImsRcsController.java
index 461a097..e415122 100644
--- a/src/com/android/phone/ImsRcsController.java
+++ b/src/com/android/phone/ImsRcsController.java
@@ -23,6 +23,7 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyFrameworkInitializer;
 import android.telephony.ims.ImsException;
+import android.telephony.ims.RcsUceAdapter.PublishState;
 import android.telephony.ims.RegistrationManager;
 import android.telephony.ims.aidl.IImsCapabilityCallback;
 import android.telephony.ims.aidl.IImsRcsController;
@@ -44,7 +45,7 @@
 import com.android.services.telephony.rcs.RcsFeatureController;
 import com.android.services.telephony.rcs.SipTransportController;
 import com.android.services.telephony.rcs.TelephonyRcsService;
-import com.android.services.telephony.rcs.UserCapabilityExchangeImpl;
+import com.android.services.telephony.rcs.UceControllerManager;
 
 import java.util.List;
 
@@ -203,40 +204,6 @@
         }
     }
 
-    @Override
-    public void registerUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c) {
-        enforceReadPrivilegedPermission("registerUcePublishStateCallback");
-        final long token = Binder.clearCallingIdentity();
-        try {
-            UserCapabilityExchangeImpl uce = getRcsFeatureController(subId).getFeature(
-                    UserCapabilityExchangeImpl.class);
-            if (uce == null) {
-                throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
-                    "This subscription does not support UCE.");
-            }
-            uce.registerPublishStateCallback(c);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    @Override
-    public void unregisterUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c) {
-        enforceReadPrivilegedPermission("unregisterUcePublishStateCallback");
-        final long token = Binder.clearCallingIdentity();
-        try {
-            UserCapabilityExchangeImpl uce = getRcsFeatureController(subId).getFeature(
-                    UserCapabilityExchangeImpl.class);
-            if (uce == null) {
-                throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
-                    "This subscription does not support UCE.");
-            }
-            uce.unregisterUcePublishStateCallback(c);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
     /**
      * Query for the capability of an IMS RCS service
      *
@@ -296,13 +263,15 @@
         }
         final long token = Binder.clearCallingIdentity();
         try {
-            UserCapabilityExchangeImpl uce = getRcsFeatureController(subId).getFeature(
-                    UserCapabilityExchangeImpl.class);
-            if (uce == null) {
+            UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature(
+                    UceControllerManager.class);
+            if (uceCtrlManager == null) {
                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
                         "This subscription does not support UCE.");
             }
-            uce.requestCapabilities(contactNumbers, c);
+            uceCtrlManager.requestCapabilities(contactNumbers, c);
+        } catch (ImsException e) {
+            throw new ServiceSpecificException(e.getCode(), e.getMessage());
         } finally {
             Binder.restoreCallingIdentity(token);
         }
@@ -316,21 +285,72 @@
             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
                     "The user has not enabled UCE for this subscription.");
         }
-        // TODO: Implement this method
-    }
-
-    @Override
-    public int getUcePublishState(int subId) {
-        enforceReadPrivilegedPermission("getUcePublishState");
         final long token = Binder.clearCallingIdentity();
         try {
-            UserCapabilityExchangeImpl uce = getRcsFeatureController(subId).getFeature(
-                    UserCapabilityExchangeImpl.class);
-            if (uce == null) {
+            UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature(
+                    UceControllerManager.class);
+            if (uceCtrlManager == null) {
                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
                         "This subscription does not support UCE.");
             }
-            return uce.getUcePublishState();
+            uceCtrlManager.requestNetworkAvailability(contactNumber, c);
+        } catch (ImsException e) {
+            throw new ServiceSpecificException(e.getCode(), e.getMessage());
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    @Override
+    public @PublishState int getUcePublishState(int subId) {
+        enforceReadPrivilegedPermission("getUcePublishState");
+        final long token = Binder.clearCallingIdentity();
+        try {
+            UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature(
+                    UceControllerManager.class);
+            if (uceCtrlManager == null) {
+                throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
+                        "This subscription does not support UCE.");
+            }
+            return uceCtrlManager.getUcePublishState();
+        } catch (ImsException e) {
+            throw new ServiceSpecificException(e.getCode(), e.getMessage());
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    @Override
+    public void registerUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c) {
+        enforceReadPrivilegedPermission("registerUcePublishStateCallback");
+        final long token = Binder.clearCallingIdentity();
+        try {
+            UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature(
+                    UceControllerManager.class);
+            if (uceCtrlManager == null) {
+                throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
+                        "This subscription does not support UCE.");
+            }
+            uceCtrlManager.registerPublishStateCallback(c);
+        } catch (ImsException e) {
+            throw new ServiceSpecificException(e.getCode(), e.getMessage());
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    @Override
+    public void unregisterUcePublishStateCallback(int subId, IRcsUcePublishStateCallback c) {
+        enforceReadPrivilegedPermission("unregisterUcePublishStateCallback");
+        final long token = Binder.clearCallingIdentity();
+        try {
+            UceControllerManager uceCtrlManager = getRcsFeatureController(subId).getFeature(
+                    UceControllerManager.class);
+            if (uceCtrlManager == null) {
+                throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
+                        "This subscription does not support UCE.");
+            }
+            uceCtrlManager.unregisterPublishStateCallback(c);
         } finally {
             Binder.restoreCallingIdentity(token);
         }
diff --git a/src/com/android/services/telephony/rcs/TelephonyRcsService.java b/src/com/android/services/telephony/rcs/TelephonyRcsService.java
index 79170af..941a6a8 100644
--- a/src/com/android/services/telephony/rcs/TelephonyRcsService.java
+++ b/src/com/android/services/telephony/rcs/TelephonyRcsService.java
@@ -47,21 +47,19 @@
     private static final String LOG_TAG = "TelephonyRcsService";
 
     /**
-     * Used to inject RcsFeatureController and UserCapabilityExchangeImpl instances for testing.
+     * Used to inject RcsFeatureController and UceController instances for testing.
      */
     @VisibleForTesting
     public interface FeatureFactory {
         /**
-         * @return an {@link RcsFeatureController} assoicated with the slot specified.
+         * @return an {@link RcsFeatureController} associated with the slot specified.
          */
         RcsFeatureController createController(Context context, int slotId);
 
         /**
-         * @return an instance of {@link UserCapabilityExchangeImpl} associated with the slot
-         * specified.
+         * @return an instance of {@link UceControllerManager} associated with the slot specified.
          */
-        UserCapabilityExchangeImpl createUserCapabilityExchange(Context context, int slotId,
-                int subId);
+        UceControllerManager createUceControllerManager(Context context, int slotId, int subId);
 
         /**
          * @return an instance of {@link SipTransportController} for the slot and subscription
@@ -77,9 +75,9 @@
         }
 
         @Override
-        public UserCapabilityExchangeImpl createUserCapabilityExchange(Context context, int slotId,
+        public UceControllerManager createUceControllerManager(Context context, int slotId,
                 int subId) {
-            return new UserCapabilityExchangeImpl(context, slotId, subId);
+            return new UceControllerManager(context, slotId, subId);
         }
 
         @Override
@@ -237,13 +235,13 @@
 
     private void updateSupportedFeatures(RcsFeatureController c, int slotId, int subId) {
         if (doesSubscriptionSupportPresence(subId)) {
-            if (c.getFeature(UserCapabilityExchangeImpl.class) == null) {
-                c.addFeature(mFeatureFactory.createUserCapabilityExchange(mContext, slotId, subId),
-                        UserCapabilityExchangeImpl.class);
+            if (c.getFeature(UceControllerManager.class) == null) {
+                c.addFeature(mFeatureFactory.createUceControllerManager(mContext, slotId, subId),
+                        UceControllerManager.class);
             }
         } else {
-            if (c.getFeature(UserCapabilityExchangeImpl.class) != null) {
-                c.removeFeature(UserCapabilityExchangeImpl.class);
+            if (c.getFeature(UceControllerManager.class) != null) {
+                c.removeFeature(UceControllerManager.class);
             }
         }
 
diff --git a/src/com/android/services/telephony/rcs/UceControllerManager.java b/src/com/android/services/telephony/rcs/UceControllerManager.java
new file mode 100644
index 0000000..db8c933
--- /dev/null
+++ b/src/com/android/services/telephony/rcs/UceControllerManager.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony.rcs;
+
+import android.content.Context;
+import android.net.Uri;
+import android.telephony.ims.ImsException;
+import android.telephony.ims.RcsUceAdapter;
+import android.telephony.ims.RcsUceAdapter.PublishState;
+import android.telephony.ims.aidl.IRcsUceControllerCallback;
+import android.telephony.ims.aidl.IRcsUcePublishStateCallback;
+import android.util.Log;
+
+import com.android.ims.RcsFeatureManager;
+import com.android.ims.rcs.uce.UceController;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+/**
+ * Responsible for managing the creation and destruction of UceController. It also received the
+ * requests from {@link com.android.phone.ImsRcsController} and pass these requests to
+ * {@link UceController}
+ */
+public class UceControllerManager implements RcsFeatureController.Feature {
+
+    private static final String LOG_TAG = "UceControllerManager";
+
+    private final int mSlotId;
+    private final Context mContext;
+    private final ExecutorService mExecutorService;
+
+    private volatile UceController mUceController;
+
+    public UceControllerManager(Context context, int slotId, int subId) {
+        Log.d(LOG_TAG, "create: slotId=" + slotId + ", subId=" + subId);
+
+        mSlotId = slotId;
+        mContext = context;
+        mExecutorService = Executors.newSingleThreadExecutor();
+        mUceController = new UceController(mContext, subId);
+    }
+
+    /**
+     * Constructor to inject dependencies for testing.
+     */
+    @VisibleForTesting
+    public UceControllerManager(Context context, int slotId, int subId, ExecutorService executor) {
+        mSlotId = slotId;
+        mContext = context;
+        mExecutorService = executor;
+        mUceController = new UceController(mContext, subId);
+    }
+
+    @Override
+    public void onRcsConnected(RcsFeatureManager manager) {
+        mExecutorService.submit(() -> mUceController.onRcsConnected(manager));
+    }
+
+    @Override
+    public void onRcsDisconnected() {
+        mExecutorService.submit(() -> mUceController.onRcsDisconnected());
+    }
+
+    @Override
+    public void onDestroy() {
+        Log.d(LOG_TAG, "onDestroy");
+        mExecutorService.submit(() -> mUceController.onDestroy());
+        // When the shutdown is called, it will refuse any new tasks and let existing tasks finish.
+        mExecutorService.shutdown();
+    }
+
+    /**
+     * This method will be called when either the subscription ID associated with the slot has
+     * changed or the carrier configuration associated with the same subId has changed.
+     */
+    @Override
+    public void onAssociatedSubscriptionUpdated(int subId) {
+        mExecutorService.submit(() -> {
+            Log.i(LOG_TAG, "onAssociatedSubscriptionUpdated: slotId=" + mSlotId
+                    + ", subId=" + subId);
+
+            // Destroy existing UceController and create a new one.
+            mUceController.onDestroy();
+            mUceController = new UceController(mContext, subId);
+        });
+    }
+
+    @VisibleForTesting
+    public void setUceController(UceController uceController) {
+        mUceController = uceController;
+    }
+
+    /**
+     * Request the capabilities for contacts.
+     *
+     * @param contactNumbers A list of numbers that the capabilities are being requested for.
+     * @param c A callback for when the request for capabilities completes.
+     * @throws ImsException if the ImsService connected to this controller is currently down.
+     */
+    public void requestCapabilities(List<Uri> contactNumbers, IRcsUceControllerCallback c)
+            throws ImsException {
+        Future future = mExecutorService.submit(() -> {
+            checkUceControllerState();
+            mUceController.requestCapabilities(contactNumbers, c);
+            return true;
+        });
+
+        try {
+            future.get();
+        } catch (ExecutionException | InterruptedException e) {
+            Log.w(LOG_TAG, "requestCapabilities: " + e);
+            Throwable cause = e.getCause();
+            if (cause instanceof ImsException) {
+                throw (ImsException) cause;
+            }
+        }
+    }
+
+    /**
+     * Request the capabilities for the given contact.
+     * @param contactNumber The contact of the capabilities are being requested for.
+     * @param c A callback for when the request for capabilities completes.
+     * @throws ImsException if the ImsService connected to this controller is currently down.
+     */
+    public void requestNetworkAvailability(Uri contactNumber, IRcsUceControllerCallback c)
+            throws ImsException {
+        Future future = mExecutorService.submit(() -> {
+            checkUceControllerState();
+            mUceController.requestAvailability(contactNumber, c);
+            return true;
+        });
+
+        try {
+            future.get();
+        } catch (ExecutionException | InterruptedException e) {
+            Log.w(LOG_TAG, "requestNetworkAvailability exception: " + e);
+            Throwable cause = e.getCause();
+            if (cause instanceof ImsException) {
+                throw (ImsException) cause;
+            }
+        }
+    }
+
+    /**
+     * Get the UCE publish state.
+     *
+     * @throws ImsException if the ImsService connected to this controller is currently down.
+     */
+    public @PublishState int getUcePublishState() throws ImsException {
+        Future future = mExecutorService.submit(() -> {
+            checkUceControllerState();
+            return mUceController.getUcePublishState();
+        });
+
+        try {
+            return (Integer) future.get();
+        } catch (ExecutionException | InterruptedException e) {
+            Log.w(LOG_TAG, "requestNetworkAvailability exception: " + e);
+            Throwable cause = e.getCause();
+            if (cause instanceof ImsException) {
+                throw (ImsException) cause;
+            }
+            return RcsUceAdapter.PUBLISH_STATE_OTHER_ERROR;
+        }
+    }
+
+    /**
+     * Register the Publish state changed callback.
+     *
+     * @throws ImsException if the ImsService connected to this controller is currently down.
+     */
+    public void registerPublishStateCallback(IRcsUcePublishStateCallback c) throws ImsException {
+        Future future = mExecutorService.submit(() -> {
+            checkUceControllerState();
+            mUceController.registerPublishStateCallback(c);
+            return true;
+        });
+
+        try {
+            future.get();
+        } catch (ExecutionException | InterruptedException e) {
+            Log.w(LOG_TAG, "registerPublishStateCallback exception: " + e);
+            Throwable cause = e.getCause();
+            if (cause instanceof ImsException) {
+                throw (ImsException) cause;
+            }
+        }
+    }
+
+    /**
+     * Unregister the existing publish state changed callback.
+     */
+    public void unregisterPublishStateCallback(IRcsUcePublishStateCallback c) {
+        Future future = mExecutorService.submit(() -> {
+            if (checkUceControllerState()) {
+                mUceController.unregisterPublishStateCallback(c);
+            }
+            return true;
+        });
+
+        try {
+            future.get();
+        } catch (ExecutionException | InterruptedException e) {
+            Log.w(LOG_TAG, "unregisterPublishStateCallback exception: " + e);
+        }
+    }
+
+    private boolean checkUceControllerState() throws ImsException {
+        if (mUceController == null || mUceController.isUnavailable()) {
+            throw new ImsException("UCE controller is unavailable",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+        return true;
+    }
+}
diff --git a/src/com/android/services/telephony/rcs/UserCapabilityExchangeImpl.java b/src/com/android/services/telephony/rcs/UserCapabilityExchangeImpl.java
deleted file mode 100644
index 138d2d0..0000000
--- a/src/com/android/services/telephony/rcs/UserCapabilityExchangeImpl.java
+++ /dev/null
@@ -1,1063 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.services.telephony.rcs;
-
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PersistableBundle;
-import android.os.RemoteCallbackList;
-import android.os.RemoteException;
-import android.provider.Settings;
-import android.provider.Telephony;
-import android.telecom.TelecomManager;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.CarrierConfigManager;
-import android.telephony.SubscriptionManager;
-import android.telephony.ims.ImsException;
-import android.telephony.ims.ImsManager;
-import android.telephony.ims.ImsMmTelManager;
-import android.telephony.ims.ImsReasonInfo;
-import android.telephony.ims.ProvisioningManager;
-import android.telephony.ims.RcsContactUceCapability;
-import android.telephony.ims.RcsUceAdapter;
-import android.telephony.ims.RegistrationManager;
-import android.telephony.ims.aidl.IRcsUceControllerCallback;
-import android.telephony.ims.aidl.IRcsUcePublishStateCallback;
-import android.telephony.ims.feature.MmTelFeature;
-import android.telephony.ims.stub.RcsCapabilityExchange;
-import android.telephony.ims.stub.RcsPresenceExchangeImplBase;
-import android.util.Log;
-
-import com.android.ims.RcsFeatureManager;
-import com.android.ims.RcsFeatureManager.RcsFeatureCallbacks;
-import com.android.ims.ResultCode;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.phone.R;
-import com.android.service.ims.presence.ContactCapabilityResponse;
-import com.android.service.ims.presence.PresenceBase;
-import com.android.service.ims.presence.PresencePublication;
-import com.android.service.ims.presence.PresencePublisher;
-import com.android.service.ims.presence.PresenceSubscriber;
-import com.android.service.ims.presence.SubscribePublisher;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.stream.Collectors;
-
-/**
- * Implements User Capability Exchange using Presence.
- */
-public class UserCapabilityExchangeImpl implements RcsFeatureController.Feature, SubscribePublisher,
-        PresencePublisher {
-
-    private static final String LOG_TAG = "RcsUceImpl";
-
-    private final int mSlotId;
-    private volatile int mSubId;
-    private volatile boolean mImsContentChangedCallbackRegistered = false;
-    // The result of requesting publish
-    private volatile int mPublishState = PresenceBase.PUBLISH_STATE_NOT_PUBLISHED;
-    // The network type which IMS registers on
-    private volatile int mNetworkRegistrationType = AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
-    // The MMTel capabilities of this subscription Id
-    private MmTelFeature.MmTelCapabilities mMmTelCapabilities;
-    private final Object mCapabilitiesLock = new Object();
-
-    private final Context mContext;
-    private final UceImplHandler mUceImplHandler;
-    private RcsFeatureManager mRcsFeatureManager;
-    private final PresencePublication mPresencePublication;
-    private final PresenceSubscriber mPresenceSubscriber;
-
-    // The task Ids of updating capabilities
-    private final Set<Integer> mRequestingPublishTaskIds = new HashSet<>();
-
-    // The callbacks to notify publish state changed.
-    private final RemoteCallbackList<IRcsUcePublishStateCallback> mPublishStateCallbacks;
-
-    // The task Ids of pending availability request.
-    private final Set<Integer> mPendingAvailabilityRequests = new HashSet<>();
-
-    private final ConcurrentHashMap<Integer, IRcsUceControllerCallback> mPendingCapabilityRequests =
-            new ConcurrentHashMap<>();
-
-    UserCapabilityExchangeImpl(Context context, int slotId, int subId) {
-        mSlotId = slotId;
-        mSubId = subId;
-        logi("created");
-
-        mContext = context;
-        mPublishStateCallbacks = new RemoteCallbackList<>();
-
-        HandlerThread handlerThread = new HandlerThread("UceImplHandlerThread");
-        handlerThread.start();
-        mUceImplHandler = new UceImplHandler(this, handlerThread.getLooper());
-
-        String[] volteError = context.getResources().getStringArray(
-                R.array.config_volte_provision_error_on_publish_response);
-        String[] rcsError = context.getResources().getStringArray(
-                R.array.config_rcs_provision_error_on_publish_response);
-
-        // Initialize PresencePublication
-        mPresencePublication = new PresencePublication(null /*PresencePublisher*/, context,
-                volteError, rcsError);
-        // Initialize PresenceSubscriber
-        mPresenceSubscriber = new PresenceSubscriber(null /*SubscribePublisher*/, context,
-                volteError, rcsError);
-
-        onAssociatedSubscriptionUpdated(mSubId);
-        registerReceivers();
-    }
-
-    @VisibleForTesting
-    UserCapabilityExchangeImpl(Context context, int slotId, int subId, Looper looper,
-            PresencePublication presencePublication, PresenceSubscriber presenceSubscriber,
-            RemoteCallbackList<IRcsUcePublishStateCallback> publishStateCallbacks) {
-        mSlotId = slotId;
-        mSubId = subId;
-        mContext = context;
-        mPublishStateCallbacks = publishStateCallbacks;
-        mUceImplHandler = new UceImplHandler(this, looper);
-        mPresencePublication = presencePublication;
-        mPresenceSubscriber = presenceSubscriber;
-        onAssociatedSubscriptionUpdated(mSubId);
-        registerReceivers();
-    }
-
-    // Runs on main thread.
-    @Override
-    public void onRcsConnected(RcsFeatureManager rcsFeatureManager) {
-        logi("onRcsConnected");
-        mRcsFeatureManager = rcsFeatureManager;
-        mRcsFeatureManager.addFeatureListenerCallback(mRcsFeatureCallback);
-
-        mPresencePublication.updatePresencePublisher(this);
-        mPresenceSubscriber.updatePresenceSubscriber(this);
-    }
-
-    // Runs on main thread.
-    @Override
-    public void onRcsDisconnected() {
-        logi("onRcsDisconnected");
-        mPresencePublication.removePresencePublisher();
-        mPresenceSubscriber.removePresenceSubscriber();
-
-        if (mRcsFeatureManager != null) {
-            mRcsFeatureManager.releaseConnection();
-            mRcsFeatureManager = null;
-        }
-    }
-
-    // Runs on main thread.
-    @Override
-    public void onAssociatedSubscriptionUpdated(int subId) {
-        logi("onAssociatedSubscriptionUpdated: new subId=" + subId);
-
-        // Listen to the IMS content changed with new subId.
-        mUceImplHandler.registerImsContentChangedReceiver(subId);
-
-        mSubId = subId;
-        mPresencePublication.handleAssociatedSubscriptionChanged(subId);
-        mPresenceSubscriber.handleAssociatedSubscriptionChanged(subId);
-    }
-
-    /**
-     * Should be called before destroying this instance.
-     * This instance is not usable after this method is called.
-     */
-    // Called on main thread.
-    public void onDestroy() {
-        logi("onDestroy");
-        mUceImplHandler.getLooper().quit();
-        unregisterReceivers();
-        unregisterImsProvisionCallback(mSubId);
-        onRcsDisconnected();
-    }
-
-    /**
-     * @return the UCE Publish state.
-     */
-    // May happen on a Binder thread, PresencePublication locks to get result.
-    public int getUcePublishState() {
-        int publishState = mPresencePublication.getPublishState();
-        return toUcePublishState(publishState);
-    }
-
-    @VisibleForTesting
-    public UceImplHandler getHandler() {
-        return mUceImplHandler;
-    }
-
-    /**
-     * Register receiver to receive UCE publish state changed.
-     */
-    public void registerPublishStateCallback(IRcsUcePublishStateCallback c) {
-        synchronized (mPublishStateCallbacks) {
-            mPublishStateCallbacks.register(c);
-        }
-    }
-
-    /**
-     * Unregister UCE publish state callback.
-     */
-    public void unregisterUcePublishStateCallback(IRcsUcePublishStateCallback c) {
-        synchronized (mPublishStateCallbacks) {
-            mPublishStateCallbacks.unregister(c);
-        }
-    }
-
-    private void clearPublishStateCallbacks() {
-        synchronized (mPublishStateCallbacks) {
-            logi("clearPublishStateCallbacks");
-            final int lastIndex = mPublishStateCallbacks.getRegisteredCallbackCount() - 1;
-            for (int index = lastIndex; index >= 0; index--) {
-                IRcsUcePublishStateCallback callback =
-                        mPublishStateCallbacks.getRegisteredCallbackItem(index);
-                mPublishStateCallbacks.unregister(callback);
-            }
-        }
-    }
-
-    private void notifyPublishStateChanged(@PresenceBase.PresencePublishState int state) {
-        int result = toUcePublishState(state);
-        synchronized (mPublishStateCallbacks) {
-            mPublishStateCallbacks.broadcast(c -> {
-                try {
-                    c.onPublishStateChanged(result);
-                } catch (RemoteException e) {
-                    logw("notifyPublishStateChanged error: " + e);
-                }
-            });
-        }
-    }
-
-    /**
-     * Perform a capabilities request and call {@link IRcsUceControllerCallback} with the result.
-     */
-    // May happen on a Binder thread, PresenceSubscriber locks when requesting Capabilities.
-    public void requestCapabilities(List<Uri> contactNumbers, IRcsUceControllerCallback c) {
-        List<String> numbers = contactNumbers.stream()
-                .map(UserCapabilityExchangeImpl::getNumberFromUri).collect(Collectors.toList());
-        int taskId = mPresenceSubscriber.requestCapability(numbers,
-                new ContactCapabilityResponse() {
-                    @Override
-                    public void onSuccess(int reqId) {
-                        logi("onSuccess called for reqId:" + reqId);
-                    }
-
-                    @Override
-                    public void onError(int reqId, int resultCode) {
-                        IRcsUceControllerCallback c = mPendingCapabilityRequests.remove(reqId);
-                        try {
-                            if (c != null) {
-                                c.onError(toUceError(resultCode));
-                            } else {
-                                logw("onError called for unknown reqId:" + reqId);
-                            }
-                        } catch (RemoteException e) {
-                            logi("Calling back to dead service");
-                        }
-                    }
-
-                    @Override
-                    public void onFinish(int reqId) {
-                        logi("onFinish called for reqId:" + reqId);
-                    }
-
-                    @Override
-                    public void onTimeout(int reqId) {
-                        IRcsUceControllerCallback c = mPendingCapabilityRequests.remove(reqId);
-                        try {
-                            if (c != null) {
-                                c.onError(RcsUceAdapter.ERROR_REQUEST_TIMEOUT);
-                            } else {
-                                logw("onTimeout called for unknown reqId:" + reqId);
-                            }
-                        } catch (RemoteException e) {
-                            logi("Calling back to dead service");
-                        }
-                    }
-
-                    @Override
-                    public void onCapabilitiesUpdated(int reqId,
-                            List<RcsContactUceCapability> contactCapabilities,
-                            boolean updateLastTimestamp) {
-                        IRcsUceControllerCallback c = mPendingCapabilityRequests.remove(reqId);
-                        try {
-                            if (c != null) {
-                                c.onCapabilitiesReceived(contactCapabilities);
-                            } else {
-                                logw("onCapabilitiesUpdated, unknown reqId:" + reqId);
-                            }
-                        } catch (RemoteException e) {
-                            logw("onCapabilitiesUpdated on dead service");
-                        }
-                    }
-                });
-        if (taskId < 0) {
-            try {
-                c.onError(toUceError(taskId));
-            } catch (RemoteException e) {
-                logi("Calling back to dead service");
-            }
-            return;
-        }
-        mPendingCapabilityRequests.put(taskId, c);
-    }
-
-    @Override
-    public int requestCapability(String[] formattedContacts, int taskId) {
-        if (formattedContacts == null || formattedContacts.length == 0) {
-            logw("requestCapability error: contacts is null.");
-            return ResultCode.SUBSCRIBE_INVALID_PARAM;
-        }
-        if (mRcsFeatureManager == null) {
-            logw("requestCapability error: RcsFeatureManager is null.");
-            return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-        }
-
-        logi("requestCapability: taskId=" + taskId);
-
-        try {
-            List<Uri> contactList = Arrays.stream(formattedContacts)
-                    .map(Uri::parse).collect(Collectors.toList());
-            mRcsFeatureManager.requestCapabilities(contactList, taskId);
-        } catch (Exception e) {
-            logw("requestCapability error: " + e.getMessage());
-            return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-        }
-        return ResultCode.SUCCESS;
-    }
-
-    @Override
-    public int requestAvailability(String formattedContact, int taskId) {
-        if (formattedContact == null || formattedContact.isEmpty()) {
-            logw("requestAvailability error: contact is null.");
-            return ResultCode.SUBSCRIBE_INVALID_PARAM;
-        }
-        if (mRcsFeatureManager == null) {
-            logw("requestAvailability error: RcsFeatureManager is null.");
-            return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-        }
-
-        logi("requestAvailability: taskId=" + taskId);
-        addRequestingAvailabilityTaskId(taskId);
-
-        try {
-            Uri contactUri = Uri.parse(formattedContact);
-            List<Uri> contactUris = new ArrayList<>(Arrays.asList(contactUri));
-            mRcsFeatureManager.requestCapabilities(contactUris, taskId);
-        } catch (Exception e) {
-            logw("requestAvailability error: " + e.getMessage());
-            removeRequestingAvailabilityTaskId(taskId);
-            return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-        }
-        return ResultCode.SUCCESS;
-    }
-
-    @Override
-    public int getStackStatusForCapabilityRequest() {
-        if (mRcsFeatureManager == null) {
-            logw("Check Stack status: Error! RcsFeatureManager is null.");
-            return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-        }
-
-        if (!isCapabilityDiscoveryEnabled(mSubId)) {
-            logw("Check Stack status: Error! capability discovery not enabled");
-            return ResultCode.ERROR_SERVICE_NOT_ENABLED;
-        }
-
-        if (!isEabProvisioned(mContext, mSubId)) {
-            logw("Check Stack status: Error! EAB provisioning disabled.");
-            return ResultCode.ERROR_SERVICE_NOT_ENABLED;
-        }
-
-        if (getPublisherState() != PresenceBase.PUBLISH_STATE_200_OK) {
-            logw("Check Stack status: Error! publish state " + getPublisherState());
-            return ResultCode.ERROR_SERVICE_NOT_PUBLISHED;
-        }
-        return ResultCode.SUCCESS;
-    }
-
-    /**
-     * The feature callback is to receive the request and update from RcsPresExchangeImplBase
-     */
-    @VisibleForTesting
-    public RcsFeatureCallbacks mRcsFeatureCallback = new RcsFeatureCallbacks() {
-        public void onCommandUpdate(int commandCode, int operationToken) {
-            logi("onCommandUpdate: code=" + commandCode + ", token=" + operationToken);
-            if (isPublishRequestExisted(operationToken)) {
-                onCommandUpdateForPublishRequest(commandCode, operationToken);
-            } else if (isCapabilityRequestExisted(operationToken)) {
-                onCommandUpdateForCapabilityRequest(commandCode, operationToken);
-            } else if (isAvailabilityRequestExisted(operationToken)) {
-                onCommandUpdateForAvailabilityRequest(commandCode, operationToken);
-            } else {
-                logw("onCommandUpdate: invalid token " + operationToken);
-            }
-        }
-
-        /** See {@link RcsPresenceExchangeImplBase#onNetworkResponse(int, String, int)} */
-        public void onNetworkResponse(int responseCode, String reason, int operationToken) {
-            logi("onNetworkResponse: code=" + responseCode + ", reason=" + reason
-                    + ", operationToken=" + operationToken);
-            if (isPublishRequestExisted(operationToken)) {
-                onNetworkResponseForPublishRequest(responseCode, reason, operationToken);
-            } else if (isCapabilityRequestExisted(operationToken)) {
-                onNetworkResponseForCapabilityRequest(responseCode, reason, operationToken);
-            } else if (isAvailabilityRequestExisted(operationToken)) {
-                onNetworkResponseForAvailabilityRequest(responseCode, reason, operationToken);
-            } else {
-                logw("onNetworkResponse: invalid token " + operationToken);
-            }
-        }
-
-        /** See {@link RcsPresenceExchangeImplBase#onCapabilityRequestResponse(List, int)} */
-        public void onCapabilityRequestResponsePresence(List<RcsContactUceCapability> infos,
-                int operationToken) {
-            if (isAvailabilityRequestExisted(operationToken)) {
-                handleAvailabilityReqResponse(infos, operationToken);
-            } else if (isCapabilityRequestExisted(operationToken)) {
-                handleCapabilityReqResponse(infos, operationToken);
-            } else {
-                logw("capability request response: invalid token " + operationToken);
-            }
-        }
-
-        /** See {@link RcsPresenceExchangeImplBase#onNotifyUpdateCapabilites(int)} */
-        public void onNotifyUpdateCapabilities(int publishTriggerType) {
-            logi("onNotifyUpdateCapabilities: type=" + publishTriggerType);
-            mUceImplHandler.notifyUpdateCapabilities(publishTriggerType);
-        }
-
-        /** See {@link RcsPresenceExchangeImplBase#onUnpublish()} */
-        public void onUnpublish() {
-            logi("onUnpublish");
-            mUceImplHandler.unpublish();
-        }
-    };
-
-    private static class UceImplHandler extends Handler {
-        private static final int EVENT_REGISTER_IMS_CHANGED_RECEIVER = 1;
-        private static final int EVENT_NOTIFY_UPDATE_CAPABILITIES = 2;
-        private static final int EVENT_UNPUBLISH = 3;
-
-        private static final int REGISTER_IMS_CHANGED_DELAY = 10000;  //10 seconds
-
-        private final WeakReference<UserCapabilityExchangeImpl> mUceImplRef;
-
-        UceImplHandler(UserCapabilityExchangeImpl uceImpl, Looper looper) {
-            super(looper);
-            mUceImplRef = new WeakReference(uceImpl);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            UserCapabilityExchangeImpl uceImpl = mUceImplRef.get();
-            if (uceImpl == null) {
-                return;
-            }
-            switch (msg.what) {
-                case EVENT_REGISTER_IMS_CHANGED_RECEIVER:
-                    int subId = msg.arg1;
-                    uceImpl.registerImsContentChangedReceiverInternal(subId);
-                    break;
-                case EVENT_NOTIFY_UPDATE_CAPABILITIES:
-                    int publishTriggerType = msg.arg1;
-                    uceImpl.onNotifyUpdateCapabilities(publishTriggerType);
-                    break;
-                case EVENT_UNPUBLISH:
-                    uceImpl.onUnPublish();
-                    break;
-                default:
-                    Log.w(LOG_TAG, "handleMessage: error=" + msg.what);
-                    break;
-            }
-        }
-
-        private void retryRegisteringImsContentChangedReceiver(int subId) {
-            sendRegisteringImsContentChangedMessage(subId, REGISTER_IMS_CHANGED_DELAY);
-        }
-
-        private void registerImsContentChangedReceiver(int subId) {
-            sendRegisteringImsContentChangedMessage(subId, 0);
-        }
-
-        private void sendRegisteringImsContentChangedMessage(int subId, int delay) {
-            if (subId <= SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-                return;
-            }
-            removeRegisteringImsContentChangedReceiver();
-            Message message = obtainMessage(EVENT_REGISTER_IMS_CHANGED_RECEIVER);
-            message.arg1 = subId;
-            sendMessageDelayed(message, delay);
-        }
-
-        private void removeRegisteringImsContentChangedReceiver() {
-            removeMessages(EVENT_REGISTER_IMS_CHANGED_RECEIVER);
-        }
-
-        private void notifyUpdateCapabilities(int publishTriggerType) {
-            Message message = obtainMessage(EVENT_NOTIFY_UPDATE_CAPABILITIES);
-            message.arg1 = publishTriggerType;
-            sendMessage(message);
-        }
-
-        private void unpublish() {
-            sendEmptyMessage(EVENT_UNPUBLISH);
-        }
-    }
-
-    private void onNotifyUpdateCapabilities(int publishTriggerType) {
-        mPresencePublication.onStackPublishRequested(publishTriggerType);
-    }
-
-    private void onUnPublish() {
-        mPresencePublication.setPublishState(PresenceBase.PUBLISH_STATE_NOT_PUBLISHED);
-    }
-
-    @Override
-    public @PresenceBase.PresencePublishState int getPublisherState() {
-        return mPublishState;
-    }
-
-    @Override
-    public int requestPublication(RcsContactUceCapability capabilities, String contactUri,
-            int taskId) {
-        if (mRcsFeatureManager == null) {
-            logw("requestPublication error: RcsFeatureManager is null.");
-            return ResultCode.ERROR_SERVICE_NOT_AVAILABLE;
-        }
-
-        logi("requestPublication: taskId=" + taskId);
-        addPublishRequestTaskId(taskId);
-
-        try {
-            mRcsFeatureManager.requestPublication(capabilities, taskId);
-        } catch (Exception ex) {
-            logw("requestPublication error: " + ex.getMessage());
-            removePublishRequestTaskId(taskId);
-            return ResultCode.PUBLISH_GENERIC_FAILURE;
-        }
-        return ResultCode.SUCCESS;
-    }
-
-    /*
-     * Handle the callback method RcsFeatureCallbacks#onCommandUpdate(int, int)
-     */
-    private void onCommandUpdateForPublishRequest(int commandCode, int operationToken) {
-        if (!isPublishRequestExisted(operationToken)) {
-            return;
-        }
-        int resultCode = ResultCode.SUCCESS;
-        if (commandCode != RcsCapabilityExchange.COMMAND_CODE_SUCCESS) {
-            logw("onCommandUpdateForPublishRequest failed! taskId=" + operationToken
-                    + ", code=" + commandCode);
-            removePublishRequestTaskId(operationToken);
-            resultCode = ResultCode.PUBLISH_GENERIC_FAILURE;
-        }
-        mPresencePublication.onCommandStatusUpdated(operationToken, operationToken, resultCode);
-    }
-
-    private void onCommandUpdateForCapabilityRequest(int commandCode, int operationToken) {
-        if (!isCapabilityRequestExisted(operationToken)) {
-            return;
-        }
-        int resultCode = ResultCode.SUCCESS;
-        if (commandCode != RcsCapabilityExchange.COMMAND_CODE_SUCCESS) {
-            logw("onCommandUpdateForCapabilityRequest failed! taskId=" + operationToken
-                    + ", code=" + commandCode);
-            mPendingCapabilityRequests.remove(operationToken);
-            resultCode = ResultCode.PUBLISH_GENERIC_FAILURE;
-        }
-        mPresenceSubscriber.onCommandStatusUpdated(operationToken, operationToken, resultCode);
-    }
-
-    private void onCommandUpdateForAvailabilityRequest(int commandCode, int operationToken) {
-        if (!isAvailabilityRequestExisted(operationToken)) {
-            return;
-        }
-        int resultCode = ResultCode.SUCCESS;
-        if (commandCode != RcsCapabilityExchange.COMMAND_CODE_SUCCESS) {
-            logw("onCommandUpdateForAvailabilityRequest failed! taskId=" + operationToken
-                    + ", code=" + commandCode);
-            removeRequestingAvailabilityTaskId(operationToken);
-            resultCode = ResultCode.PUBLISH_GENERIC_FAILURE;
-        }
-        mPresenceSubscriber.onCommandStatusUpdated(operationToken, operationToken, resultCode);
-    }
-
-    /*
-     * Handle the callback method RcsFeatureCallbacks#onNetworkResponse(int, String, int)
-     */
-    private void onNetworkResponseForPublishRequest(int responseCode, String reason,
-            int operationToken) {
-        if (!isPublishRequestExisted(operationToken)) {
-            return;
-        }
-        removePublishRequestTaskId(operationToken);
-        mPresencePublication.onSipResponse(operationToken, responseCode, reason);
-    }
-
-    private void onNetworkResponseForCapabilityRequest(int responseCode, String reason,
-            int operationToken) {
-        if (!isCapabilityRequestExisted(operationToken)) {
-            return;
-        }
-        mPresenceSubscriber.onSipResponse(operationToken, responseCode, reason);
-    }
-
-    private void onNetworkResponseForAvailabilityRequest(int responseCode, String reason,
-            int operationToken) {
-        if (!isAvailabilityRequestExisted(operationToken)) {
-            return;
-        }
-        removeRequestingAvailabilityTaskId(operationToken);
-        mPresenceSubscriber.onSipResponse(operationToken, responseCode, reason);
-    }
-
-    private void handleAvailabilityReqResponse(List<RcsContactUceCapability> infos, int token) {
-        try {
-            if (infos == null || infos.isEmpty()) {
-                logw("handle availability request response: infos is null " + token);
-                return;
-            }
-            logi("handleAvailabilityReqResponse: token=" + token);
-            mPresenceSubscriber.updatePresence(infos.get(0));
-        } finally {
-            removeRequestingAvailabilityTaskId(token);
-        }
-    }
-
-    private void handleCapabilityReqResponse(List<RcsContactUceCapability> infos, int token) {
-        if (infos == null) {
-            logw("handleCapabilityReqResponse: infos is null " + token);
-            mPendingCapabilityRequests.remove(token);
-            return;
-        }
-        logi("handleCapabilityReqResponse: token=" + token);
-        mPresenceSubscriber.updatePresences(token, infos, true, null);
-    }
-
-    @Override
-    public void updatePublisherState(@PresenceBase.PresencePublishState int publishState) {
-        logi("updatePublisherState: from " + mPublishState + " to " + publishState);
-        mPublishState = publishState;
-        notifyPublishStateChanged(publishState);
-    }
-
-    private void addPublishRequestTaskId(int taskId) {
-        synchronized (mRequestingPublishTaskIds) {
-            mRequestingPublishTaskIds.add(taskId);
-        }
-    }
-
-    private void removePublishRequestTaskId(int taskId) {
-        synchronized (mRequestingPublishTaskIds) {
-            mRequestingPublishTaskIds.remove(taskId);
-        }
-    }
-
-    private boolean isPublishRequestExisted(Integer taskId) {
-        synchronized (mRequestingPublishTaskIds) {
-            return mRequestingPublishTaskIds.contains(taskId);
-        }
-    }
-
-    private void addRequestingAvailabilityTaskId(int taskId) {
-        synchronized (mPendingAvailabilityRequests) {
-            mPendingAvailabilityRequests.contains(taskId);
-        }
-    }
-
-    private void removeRequestingAvailabilityTaskId(int taskId) {
-        synchronized (mPendingAvailabilityRequests) {
-            mPendingAvailabilityRequests.remove(taskId);
-        }
-    }
-
-    private boolean isAvailabilityRequestExisted(Integer taskId) {
-        synchronized (mPendingAvailabilityRequests) {
-            return mPendingAvailabilityRequests.contains(taskId);
-        }
-    }
-
-    private boolean isCapabilityRequestExisted(Integer taskId) {
-        return mPendingCapabilityRequests.containsKey(taskId);
-    }
-
-    private static String getNumberFromUri(Uri uri) {
-        String number = uri.getSchemeSpecificPart();
-        String[] numberParts = number.split("[@;:]");
-
-        if (numberParts.length == 0) {
-            return null;
-        }
-        return numberParts[0];
-    }
-
-    private static int toUcePublishState(int publishState) {
-        switch (publishState) {
-            case PresenceBase.PUBLISH_STATE_200_OK:
-                return RcsUceAdapter.PUBLISH_STATE_OK;
-            case PresenceBase.PUBLISH_STATE_NOT_PUBLISHED:
-                return RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED;
-            case PresenceBase.PUBLISH_STATE_VOLTE_PROVISION_ERROR:
-                return RcsUceAdapter.PUBLISH_STATE_VOLTE_PROVISION_ERROR;
-            case PresenceBase.PUBLISH_STATE_RCS_PROVISION_ERROR:
-                return RcsUceAdapter.PUBLISH_STATE_RCS_PROVISION_ERROR;
-            case PresenceBase.PUBLISH_STATE_REQUEST_TIMEOUT:
-                return RcsUceAdapter.PUBLISH_STATE_REQUEST_TIMEOUT;
-            case PresenceBase.PUBLISH_STATE_OTHER_ERROR:
-                return RcsUceAdapter.PUBLISH_STATE_OTHER_ERROR;
-            default:
-                return RcsUceAdapter.PUBLISH_STATE_OTHER_ERROR;
-        }
-    }
-
-    private static int toUceError(int resultCode) {
-        switch (resultCode) {
-            case ResultCode.SUBSCRIBE_NOT_REGISTERED:
-                return RcsUceAdapter.ERROR_NOT_REGISTERED;
-            case ResultCode.SUBSCRIBE_REQUEST_TIMEOUT:
-                return RcsUceAdapter.ERROR_REQUEST_TIMEOUT;
-            case ResultCode.SUBSCRIBE_FORBIDDEN:
-                return RcsUceAdapter.ERROR_FORBIDDEN;
-            case ResultCode.SUBSCRIBE_NOT_FOUND:
-                return RcsUceAdapter.ERROR_NOT_FOUND;
-            case ResultCode.SUBSCRIBE_TOO_LARGE:
-                return RcsUceAdapter.ERROR_REQUEST_TOO_LARGE;
-            case ResultCode.SUBSCRIBE_INSUFFICIENT_MEMORY:
-                return RcsUceAdapter.ERROR_INSUFFICIENT_MEMORY;
-            case ResultCode.SUBSCRIBE_LOST_NETWORK:
-                return RcsUceAdapter.ERROR_LOST_NETWORK;
-            default:
-                return RcsUceAdapter.ERROR_GENERIC_FAILURE;
-        }
-    }
-
-    /*
-     * Register receivers for updating capabilities
-     */
-    private void registerReceivers() {
-        IntentFilter filter = new IntentFilter(TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED);
-        filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
-        mContext.registerReceiver(mReceiver, filter);
-
-        ContentResolver resolver = mContext.getContentResolver();
-        if (resolver != null) {
-            // Register mobile data content changed.
-            resolver.registerContentObserver(
-                    Settings.Global.getUriFor(Settings.Global.MOBILE_DATA), false,
-                    mMobileDataObserver);
-
-            // Register SIM info content changed.
-            resolver.registerContentObserver(Telephony.SimInfo.CONTENT_URI, false,
-                    mSimInfoContentObserver);
-        }
-    }
-
-    private void unregisterReceivers() {
-        mContext.unregisterReceiver(mReceiver);
-        ContentResolver resolver = mContext.getContentResolver();
-        if (resolver != null) {
-            resolver.unregisterContentObserver(mMobileDataObserver);
-            resolver.unregisterContentObserver(mSimInfoContentObserver);
-        }
-    }
-
-    /**
-     * Register IMS and provision content changed.
-     *
-     * Call the UceImplHandler#registerImsContentChangedReceiver instead of
-     * calling this method directly.
-     */
-    private void registerImsContentChangedReceiverInternal(int subId) {
-        mUceImplHandler.removeRegisteringImsContentChangedReceiver();
-        try {
-            final int originalSubId = mSubId;
-            if ((originalSubId == subId) && (mImsContentChangedCallbackRegistered)) {
-                logi("registerImsContentChangedReceiverInternal: already registered. skip");
-                return;
-            }
-            // Unregister original IMS and Provision callback
-            unregisterImsProvisionCallback(originalSubId);
-            // Register new IMS and Provision callback
-            registerImsProvisionCallback(subId);
-        } catch (ImsException e) {
-            logw("registerImsContentChangedReceiverInternal error: " + e);
-            mUceImplHandler.retryRegisteringImsContentChangedReceiver(subId);
-        }
-    }
-
-    private void unregisterImsProvisionCallback(int subId) {
-        if (subId <= SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            return;
-        }
-        // Unregister IMS callback
-        ImsMmTelManager imsMmtelManager = getImsMmTelManager(subId);
-        if (imsMmtelManager != null) {
-            try {
-                imsMmtelManager.unregisterImsRegistrationCallback(mImsRegistrationCallback);
-                imsMmtelManager.unregisterMmTelCapabilityCallback(mCapabilityCallback);
-            } catch (RuntimeException e) {
-                logw("unregister IMS callback error: " + e.getMessage());
-            }
-        }
-
-        // Unregister provision changed callback
-        ProvisioningManager provisioningManager =
-                ProvisioningManager.createForSubscriptionId(subId);
-        try {
-            provisioningManager.unregisterProvisioningChangedCallback(mProvisioningChangedCallback);
-        } catch (RuntimeException e) {
-            logw("unregister provisioning callback error: " + e.getMessage());
-        }
-
-        // Remove all publish state callbacks
-        clearPublishStateCallbacks();
-
-        mImsContentChangedCallbackRegistered = false;
-    }
-
-    private void registerImsProvisionCallback(int subId) throws ImsException {
-        if (subId <= SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            return;
-        }
-        // Register IMS callback
-        ImsMmTelManager imsMmtelManager = getImsMmTelManager(subId);
-        if (imsMmtelManager != null) {
-            imsMmtelManager.registerImsRegistrationCallback(mContext.getMainExecutor(),
-                    mImsRegistrationCallback);
-            imsMmtelManager.registerMmTelCapabilityCallback(mContext.getMainExecutor(),
-                    mCapabilityCallback);
-        }
-        // Register provision changed callback
-        ProvisioningManager provisioningManager =
-                ProvisioningManager.createForSubscriptionId(subId);
-        provisioningManager.registerProvisioningChangedCallback(mContext.getMainExecutor(),
-                mProvisioningChangedCallback);
-
-        mImsContentChangedCallbackRegistered = true;
-        logi("registerImsProvisionCallback");
-    }
-
-    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (intent == null) return;
-            switch (intent.getAction()) {
-                case TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED:
-                    int preferredMode = intent.getIntExtra(
-                            TelecomManager.EXTRA_TTY_PREFERRED_MODE, TelecomManager.TTY_MODE_OFF);
-                    logi("TTY preferred mode changed: " + preferredMode);
-                    mPresencePublication.onTtyPreferredModeChanged(preferredMode);
-                    break;
-
-                case Intent.ACTION_AIRPLANE_MODE_CHANGED:
-                    boolean airplaneMode = intent.getBooleanExtra("state", false);
-                    logi("Airplane mode changed: " + airplaneMode);
-                    mPresencePublication.onAirplaneModeChanged(airplaneMode);
-                    break;
-            }
-        }
-    };
-
-    private ContentObserver mMobileDataObserver = new ContentObserver(
-            new Handler(Looper.getMainLooper())) {
-        @Override
-        public void onChange(boolean selfChange) {
-            boolean isEnabled = Settings.Global.getInt(mContext.getContentResolver(),
-                    Settings.Global.MOBILE_DATA, 1) == 1;
-            logi("Mobile data changed: enabled=" + isEnabled);
-            mPresencePublication.onMobileDataChanged(isEnabled);
-        }
-    };
-
-    private ContentObserver mSimInfoContentObserver = new ContentObserver(
-            new Handler(Looper.getMainLooper())) {
-        @Override
-        public void onChange(boolean selfChange) {
-            if (mSubId <= SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-                return;
-            }
-
-            ImsMmTelManager ims = getImsMmTelManager(mSubId);
-            if (ims == null) return;
-
-            try {
-                boolean isEnabled = ims.isVtSettingEnabled();
-                logi("SimInfo changed: VT setting=" + isEnabled);
-                mPresencePublication.onVtEnabled(isEnabled);
-            } catch (RuntimeException e) {
-                logw("SimInfo changed error: " + e);
-            }
-        }
-    };
-
-    private RegistrationManager.RegistrationCallback mImsRegistrationCallback =
-            new RegistrationManager.RegistrationCallback() {
-        @Override
-        public void onRegistered(int imsTransportType) {
-            logi("onRegistered: type=" + imsTransportType);
-            mNetworkRegistrationType = imsTransportType;
-            mPresencePublication.onImsConnected();
-
-            // Also trigger PresencePublication#onFeatureCapabilityChanged method
-            MmTelFeature.MmTelCapabilities capabilities = null;
-            synchronized (mCapabilitiesLock) {
-                capabilities = mMmTelCapabilities;
-            }
-
-            if (capabilities != null) {
-                mPresencePublication.onFeatureCapabilityChanged(mNetworkRegistrationType,
-                        capabilities);
-            }
-        }
-
-        @Override
-        public void onUnregistered(ImsReasonInfo info) {
-            logi("onUnregistered");
-            mNetworkRegistrationType = AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
-
-            // Also trigger PresencePublication#onFeatureCapabilityChanged method
-            MmTelFeature.MmTelCapabilities capabilities = null;
-            synchronized (mCapabilitiesLock) {
-                capabilities = mMmTelCapabilities;
-            }
-
-            if (capabilities != null) {
-                mPresencePublication.onFeatureCapabilityChanged(mNetworkRegistrationType,
-                        capabilities);
-            }
-            mPresencePublication.onImsDisconnected();
-        }
-    };
-
-    private ImsMmTelManager.CapabilityCallback mCapabilityCallback =
-            new ImsMmTelManager.CapabilityCallback() {
-        @Override
-        public void onCapabilitiesStatusChanged(MmTelFeature.MmTelCapabilities capabilities) {
-            if (capabilities == null) {
-                logw("onCapabilitiesStatusChanged: parameter is null");
-                return;
-            }
-            synchronized (mCapabilitiesLock) {
-                mMmTelCapabilities = capabilities;
-            }
-            mPresencePublication.onFeatureCapabilityChanged(mNetworkRegistrationType, capabilities);
-        }
-    };
-
-    private ProvisioningManager.Callback mProvisioningChangedCallback =
-            new ProvisioningManager.Callback() {
-        @Override
-        public void onProvisioningIntChanged(int item, int value) {
-            logi("onProvisioningIntChanged: item=" + item);
-            switch (item) {
-                case ProvisioningManager.KEY_EAB_PROVISIONING_STATUS:
-                case ProvisioningManager.KEY_VOLTE_PROVISIONING_STATUS:
-                case ProvisioningManager.KEY_VT_PROVISIONING_STATUS:
-                    mPresencePublication.handleProvisioningChanged();
-                    break;
-                default:
-                    break;
-            }
-        }
-    };
-
-    private boolean isCapabilityDiscoveryEnabled(int subId) {
-        try {
-            ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
-            int discoveryEnabled = manager.getProvisioningIntValue(
-                    ProvisioningManager.KEY_RCS_CAPABILITY_DISCOVERY_ENABLED);
-            return (discoveryEnabled == ProvisioningManager.PROVISIONING_VALUE_ENABLED);
-        } catch (Exception e) {
-            logw("isCapabilityDiscoveryEnabled error: " + e.getMessage());
-        }
-        return false;
-    }
-
-    private boolean isEabProvisioned(Context context, int subId) {
-        if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            logw("isEabProvisioned error: invalid subscriptionId " + subId);
-            return false;
-        }
-
-        CarrierConfigManager configManager = (CarrierConfigManager)
-                context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        if (configManager != null) {
-            PersistableBundle config = configManager.getConfigForSubId(subId);
-            if (config != null && !config.getBoolean(
-                    CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONED_BOOL)) {
-                return true;
-            }
-        }
-
-        try {
-            ProvisioningManager manager = ProvisioningManager.createForSubscriptionId(subId);
-            int provisioningStatus = manager.getProvisioningIntValue(
-                    ProvisioningManager.KEY_EAB_PROVISIONING_STATUS);
-            return (provisioningStatus == ProvisioningManager.PROVISIONING_VALUE_ENABLED);
-        } catch (Exception e) {
-            logw("isEabProvisioned error: " + e.getMessage());
-        }
-        return false;
-    }
-
-    private ImsMmTelManager getImsMmTelManager(int subId) {
-        try {
-            ImsManager imsManager = (ImsManager) mContext.getSystemService(
-                    Context.TELEPHONY_IMS_SERVICE);
-            return (imsManager == null) ? null : imsManager.getImsMmTelManager(subId);
-        } catch (IllegalArgumentException e) {
-            logw("getImsMmTelManager error: " + e.getMessage());
-            return null;
-        }
-    }
-
-    private void logi(String log) {
-        Log.i(LOG_TAG, getLogPrefix().append(log).toString());
-    }
-
-    private void logw(String log) {
-        Log.w(LOG_TAG, getLogPrefix().append(log).toString());
-    }
-
-    private StringBuilder getLogPrefix() {
-        StringBuilder builder = new StringBuilder("[");
-        builder.append(mSlotId);
-        builder.append("->");
-        builder.append(mSubId);
-        builder.append("] ");
-        return builder;
-    }
-}
diff --git a/tests/src/com/android/services/telephony/rcs/TelephonyRcsServiceTest.java b/tests/src/com/android/services/telephony/rcs/TelephonyRcsServiceTest.java
index ffbb71d..7a9f9e3 100644
--- a/tests/src/com/android/services/telephony/rcs/TelephonyRcsServiceTest.java
+++ b/tests/src/com/android/services/telephony/rcs/TelephonyRcsServiceTest.java
@@ -50,8 +50,8 @@
 
     @Captor ArgumentCaptor<BroadcastReceiver> mReceiverCaptor;
     @Mock TelephonyRcsService.FeatureFactory mFeatureFactory;
-    @Mock UserCapabilityExchangeImpl mMockUceSlot0;
-    @Mock UserCapabilityExchangeImpl mMockUceSlot1;
+    @Mock UceControllerManager mMockUceSlot0;
+    @Mock UceControllerManager mMockUceSlot1;
     @Mock SipTransportController mMockSipTransportSlot0;
     @Mock SipTransportController mMockSipTransportSlot1;
     @Mock RcsFeatureController.RegistrationHelperFactory mRegistrationFactory;
@@ -70,9 +70,9 @@
         mFeatureControllerSlot1 = createFeatureController(1 /*slotId*/);
         doReturn(mFeatureControllerSlot0).when(mFeatureFactory).createController(any(), eq(0));
         doReturn(mFeatureControllerSlot1).when(mFeatureFactory).createController(any(), eq(1));
-        doReturn(mMockUceSlot0).when(mFeatureFactory).createUserCapabilityExchange(any(), eq(0),
+        doReturn(mMockUceSlot0).when(mFeatureFactory).createUceControllerManager(any(), eq(0),
                 anyInt());
-        doReturn(mMockUceSlot1).when(mFeatureFactory).createUserCapabilityExchange(any(), eq(1),
+        doReturn(mMockUceSlot1).when(mFeatureFactory).createUceControllerManager(any(), eq(1),
                 anyInt());
         doReturn(mMockSipTransportSlot0).when(mFeatureFactory).createSipTransportController(any(),
                 eq(0), anyInt());
@@ -89,20 +89,20 @@
     }
 
     @Test
-    public void testUserCapabilityExchangePresenceConnected() {
+    public void testUceControllerPresenceConnected() {
         setCarrierConfig(1 /*subId*/, CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL,
                 true /*isEnabled*/);
         createRcsService(1 /*numSlots*/);
-        verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UserCapabilityExchangeImpl.class);
+        verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UceControllerManager.class);
         verify(mFeatureControllerSlot0).connect();
     }
 
     @Test
-    public void testUserCapabilityExchangeOptionsConnected() {
+    public void testUceControllerOptionsConnected() {
         setCarrierConfig(1 /*subId*/, CarrierConfigManager.KEY_USE_RCS_SIP_OPTIONS_BOOL,
                 true /*isEnabled*/);
         createRcsService(1 /*numSlots*/);
-        verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UserCapabilityExchangeImpl.class);
+        verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UceControllerManager.class);
         verify(mFeatureControllerSlot0).connect();
     }
 
@@ -111,7 +111,7 @@
         createRcsService(1 /*numSlots*/);
         // No carrier config set for UCE.
         verify(mFeatureControllerSlot0, never()).addFeature(mMockUceSlot0,
-                UserCapabilityExchangeImpl.class);
+                UceControllerManager.class);
         verify(mFeatureControllerSlot0, never()).connect();
     }
 
@@ -171,7 +171,7 @@
 
         sendCarrierConfigChanged(0, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
         verify(mFeatureControllerSlot0, never()).addFeature(mMockUceSlot0,
-                UserCapabilityExchangeImpl.class);
+                UceControllerManager.class);
         verify(mFeatureControllerSlot0, never()).connect();
         verify(mFeatureControllerSlot0, never()).updateAssociatedSubscription(anyInt());
     }
@@ -184,25 +184,25 @@
         setCarrierConfig(2 /*subId*/, CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL,
                 true /*isEnabled*/);
         TelephonyRcsService service = createRcsService(1 /*numSlots*/);
-        verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UserCapabilityExchangeImpl.class);
+        verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UceControllerManager.class);
         verify(mFeatureControllerSlot0).connect();
 
         // there should be no changes if the new num slots = old num
         service.updateFeatureControllerSize(1 /*newNumSlots*/);
         verify(mFeatureControllerSlot0, times(1)).addFeature(mMockUceSlot0,
-                UserCapabilityExchangeImpl.class);
+                UceControllerManager.class);
         verify(mFeatureControllerSlot0, times(1)).connect();
 
         // Add a new slot.
         verify(mFeatureControllerSlot1, never()).addFeature(mMockUceSlot1,
-                UserCapabilityExchangeImpl.class);
+                UceControllerManager.class);
         verify(mFeatureControllerSlot1, never()).connect();
         service.updateFeatureControllerSize(2 /*newNumSlots*/);
         // This shouldn't have changed for slot 0.
         verify(mFeatureControllerSlot0, times(1)).addFeature(mMockUceSlot0,
-                UserCapabilityExchangeImpl.class);
+                UceControllerManager.class);
         verify(mFeatureControllerSlot0, times(1)).connect();
-        verify(mFeatureControllerSlot1).addFeature(mMockUceSlot1, UserCapabilityExchangeImpl.class);
+        verify(mFeatureControllerSlot1).addFeature(mMockUceSlot1, UceControllerManager.class);
         verify(mFeatureControllerSlot1, times(1)).connect();
 
         // Remove a slot.
@@ -211,10 +211,10 @@
         service.updateFeatureControllerSize(1 /*newNumSlots*/);
         // addFeature/connect shouldn't have been called again
         verify(mFeatureControllerSlot0, times(1)).addFeature(mMockUceSlot0,
-                UserCapabilityExchangeImpl.class);
+                UceControllerManager.class);
         verify(mFeatureControllerSlot0, times(1)).connect();
         verify(mFeatureControllerSlot1, times(1)).addFeature(mMockUceSlot1,
-                UserCapabilityExchangeImpl.class);
+                UceControllerManager.class);
         verify(mFeatureControllerSlot1, times(1)).connect();
         // Verify destroy is only called for slot 1.
         verify(mFeatureControllerSlot0, never()).destroy();
@@ -228,8 +228,8 @@
         setCarrierConfig(2 /*subId*/, CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL,
                 true /*isEnabled*/);
         createRcsService(2 /*numSlots*/);
-        verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UserCapabilityExchangeImpl.class);
-        verify(mFeatureControllerSlot1).addFeature(mMockUceSlot1, UserCapabilityExchangeImpl.class);
+        verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UceControllerManager.class);
+        verify(mFeatureControllerSlot1).addFeature(mMockUceSlot1, UceControllerManager.class);
         verify(mFeatureControllerSlot0).connect();
         verify(mFeatureControllerSlot1).connect();
 
@@ -248,7 +248,7 @@
         setCarrierConfig(1 /*subId*/, CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL,
                 true /*isEnabled*/);
         createRcsService(1 /*numSlots*/);
-        verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UserCapabilityExchangeImpl.class);
+        verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UceControllerManager.class);
         verify(mFeatureControllerSlot0).connect();
 
 
@@ -256,7 +256,7 @@
         setCarrierConfig(1 /*subId*/, CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL,
                 false /*isEnabled*/);
         sendCarrierConfigChanged(0 /*slotId*/, 1 /*subId*/);
-        verify(mFeatureControllerSlot0).removeFeature(UserCapabilityExchangeImpl.class);
+        verify(mFeatureControllerSlot0).removeFeature(UceControllerManager.class);
         verify(mFeatureControllerSlot0).updateAssociatedSubscription(1);
     }
 
@@ -284,7 +284,7 @@
     public void testCarrierConfigUpdateNoUceToUce() {
         createRcsService(1 /*numSlots*/);
         verify(mFeatureControllerSlot0, never()).addFeature(mMockUceSlot0,
-                UserCapabilityExchangeImpl.class);
+                UceControllerManager.class);
         verify(mFeatureControllerSlot0, never()).connect();
 
 
@@ -292,7 +292,7 @@
         setCarrierConfig(1 /*subId*/, CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL,
                 true /*isEnabled*/);
         sendCarrierConfigChanged(0 /*slotId*/, 1 /*subId*/);
-        verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UserCapabilityExchangeImpl.class);
+        verify(mFeatureControllerSlot0).addFeature(mMockUceSlot0, UceControllerManager.class);
         verify(mFeatureControllerSlot0).connect();
         verify(mFeatureControllerSlot0).updateAssociatedSubscription(1);
     }
diff --git a/tests/src/com/android/services/telephony/rcs/UceControllerManagerTest.java b/tests/src/com/android/services/telephony/rcs/UceControllerManagerTest.java
new file mode 100644
index 0000000..4148d13
--- /dev/null
+++ b/tests/src/com/android/services/telephony/rcs/UceControllerManagerTest.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.services.telephony.rcs;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+
+import android.net.Uri;
+import android.telephony.ims.ImsException;
+import android.telephony.ims.aidl.IRcsUceControllerCallback;
+import android.telephony.ims.aidl.IRcsUcePublishStateCallback;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.TelephonyTestBase;
+import com.android.TestExecutorService;
+import com.android.ims.RcsFeatureManager;
+import com.android.ims.rcs.uce.UceController;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+
+@RunWith(AndroidJUnit4.class)
+public class UceControllerManagerTest extends TelephonyTestBase {
+
+    @Mock private UceController mUceController;
+    @Mock private RcsFeatureManager mRcsFeatureManager;
+
+    private final ExecutorService mExecutorService = new TestExecutorService();
+
+    private int mSlotId = 1;
+    private int mSubId = 1;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        doReturn(mSubId).when(mUceController).getSubId();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void testRcsConnected() throws Exception {
+        UceControllerManager controllerManager = getUceControllerManager();
+
+        controllerManager.onRcsConnected(mRcsFeatureManager);
+
+        verify(mUceController).onRcsConnected(mRcsFeatureManager);
+    }
+
+    @Test
+    public void testRcsDisconnected() throws Exception {
+        UceControllerManager uceCtrlManager = getUceControllerManager();
+
+        uceCtrlManager.onRcsDisconnected();
+
+        verify(mUceController).onRcsDisconnected();
+    }
+
+    @Test
+    public void testDestroy() throws Exception {
+        UceControllerManager uceCtrlManager = getUceControllerManager();
+
+        uceCtrlManager.onDestroy();
+
+        verify(mUceController).onDestroy();
+    }
+
+    @Test
+    public void testSubscriptionUpdated() throws Exception {
+        UceControllerManager uceCtrlManager = getUceControllerManager();
+
+        uceCtrlManager.onAssociatedSubscriptionUpdated(mSubId);
+
+        verify(mUceController).onDestroy();
+    }
+
+    @Test
+    public void testRequestCapabilitiesWithRcsUnavailable() throws Exception {
+        UceControllerManager uceCtrlManager = getUceControllerManager();
+        doReturn(true).when(mUceController).isUnavailable();
+        uceCtrlManager.onRcsDisconnected();
+
+        try {
+            List<Uri> contacts = Arrays.asList(Uri.fromParts("sip", "00000", null));
+            IRcsUceControllerCallback callback = Mockito.mock(IRcsUceControllerCallback.class);
+
+            uceCtrlManager.requestCapabilities(contacts, callback);
+
+            fail();
+        } catch (ImsException e) {
+            assertEquals(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE, e.getCode());
+            return;
+        }
+        fail();
+    }
+
+    @Test
+    public void testRequestCapabilitiesWithRcsConnected() throws Exception {
+        UceControllerManager uceCtrlManager = getUceControllerManager();
+        doReturn(false).when(mUceController).isUnavailable();
+        uceCtrlManager.onRcsConnected(mRcsFeatureManager);
+
+        try {
+            List<Uri> contacts = Arrays.asList(Uri.fromParts("sip", "00000", null));
+            IRcsUceControllerCallback callback = Mockito.mock(IRcsUceControllerCallback.class);
+
+            uceCtrlManager.requestCapabilities(contacts, callback);
+
+            verify(mUceController).requestCapabilities(contacts, callback);
+        } catch (ImsException e) {
+            fail();
+        }
+    }
+
+    @Test
+    public void testRequestNetworkAvailability() throws Exception {
+        UceControllerManager uceCtrlManager = getUceControllerManager();
+        doReturn(false).when(mUceController).isUnavailable();
+        uceCtrlManager.onRcsConnected(mRcsFeatureManager);
+
+        Uri contact = Uri.fromParts("sip", "00000", null);
+        IRcsUceControllerCallback callback = Mockito.mock(IRcsUceControllerCallback.class);
+
+        uceCtrlManager.requestNetworkAvailability(contact, callback);
+
+        verify(mUceController).requestAvailability(contact, callback);
+    }
+
+    @Test
+    public void testRequestNetworkAvailabilityWithRcsUnavailable() throws Exception {
+        UceControllerManager uceCtrlManager = getUceControllerManager();
+        doReturn(true).when(mUceController).isUnavailable();
+        uceCtrlManager.onRcsDisconnected();
+
+        try {
+            Uri contact = Uri.fromParts("sip", "00000", null);
+            IRcsUceControllerCallback callback = Mockito.mock(IRcsUceControllerCallback.class);
+            uceCtrlManager.requestNetworkAvailability(contact, callback);
+            fail();
+        } catch (ImsException e) {
+            assertEquals(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE, e.getCode());
+            return;
+        }
+        fail();
+    }
+
+    @Test
+    public void testGetPublishState() throws Exception {
+        UceControllerManager uceCtrlManager = getUceControllerManager();
+        doReturn(false).when(mUceController).isUnavailable();
+        uceCtrlManager.onRcsConnected(mRcsFeatureManager);
+
+        uceCtrlManager.getUcePublishState();
+
+        verify(mUceController).getUcePublishState();
+    }
+
+    @Test
+    public void testGetPublishStateWithRcsUnavailable() throws Exception {
+        UceControllerManager uceCtrlManager = getUceControllerManager();
+        doReturn(true).when(mUceController).isUnavailable();
+        uceCtrlManager.onRcsDisconnected();
+
+        try {
+            uceCtrlManager.getUcePublishState();
+            fail();
+        } catch (ImsException e) {
+            assertEquals(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE, e.getCode());
+            return;
+        }
+        fail();
+    }
+
+    @Test
+    public void testRegisterPublishStateCallback() throws Exception {
+        UceControllerManager uceCtrlManager = getUceControllerManager();
+        IRcsUcePublishStateCallback callback = Mockito.mock(IRcsUcePublishStateCallback.class);
+
+        uceCtrlManager.registerPublishStateCallback(callback);
+
+        verify(mUceController).registerPublishStateCallback(callback);
+    }
+
+    @Test
+    public void testRegisterPublishStateCallbackWithRcsUnavailable() throws Exception {
+        UceControllerManager uceCtrlManager = getUceControllerManager();
+        doReturn(true).when(mUceController).isUnavailable();
+        uceCtrlManager.onRcsDisconnected();
+
+        try {
+            IRcsUcePublishStateCallback callback = Mockito.mock(IRcsUcePublishStateCallback.class);
+            uceCtrlManager.registerPublishStateCallback(callback);
+            fail();
+        } catch (ImsException e) {
+            assertEquals(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE, e.getCode());
+            return;
+        }
+        fail();
+    }
+
+    @Test
+    public void testUnregisterPublishStateCallback() throws Exception {
+        UceControllerManager uceCtrlManager = getUceControllerManager();
+        IRcsUcePublishStateCallback callback = Mockito.mock(IRcsUcePublishStateCallback.class);
+
+        uceCtrlManager.unregisterPublishStateCallback(callback);
+
+        verify(mUceController).unregisterPublishStateCallback(callback);
+    }
+
+    private UceControllerManager getUceControllerManager() {
+        UceControllerManager manager = new UceControllerManager(mContext, mSlotId, mSubId,
+                mExecutorService);
+        manager.setUceController(mUceController);
+        return manager;
+    }
+}
diff --git a/tests/src/com/android/services/telephony/rcs/UserCapabilityExchangeImplTest.java b/tests/src/com/android/services/telephony/rcs/UserCapabilityExchangeImplTest.java
deleted file mode 100644
index 3cbe8bf..0000000
--- a/tests/src/com/android/services/telephony/rcs/UserCapabilityExchangeImplTest.java
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.services.telephony.rcs;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyList;
-import static org.mockito.Mockito.atLeast;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.net.Uri;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.RemoteCallbackList;
-import android.telephony.ims.ImsManager;
-import android.telephony.ims.ImsMmTelManager;
-import android.telephony.ims.RcsContactPresenceTuple;
-import android.telephony.ims.RcsContactPresenceTuple.ServiceCapabilities;
-import android.telephony.ims.RcsContactUceCapability;
-import android.telephony.ims.RcsContactUceCapability.PresenceBuilder;
-import android.telephony.ims.RegistrationManager;
-import android.telephony.ims.aidl.IRcsUceControllerCallback;
-import android.telephony.ims.aidl.IRcsUcePublishStateCallback;
-import android.telephony.ims.stub.RcsCapabilityExchange;
-import android.telephony.ims.stub.RcsPresenceExchangeImplBase;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.TelephonyTestBase;
-import com.android.ims.RcsFeatureManager;
-import com.android.ims.RcsFeatureManager.RcsFeatureCallbacks;
-import com.android.ims.ResultCode;
-import com.android.service.ims.presence.PresenceBase;
-import com.android.service.ims.presence.PresencePublication;
-import com.android.service.ims.presence.PresencePublisher;
-import com.android.service.ims.presence.PresenceSubscriber;
-import com.android.service.ims.presence.SubscribePublisher;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.Executor;
-
-@RunWith(AndroidJUnit4.class)
-public class UserCapabilityExchangeImplTest extends TelephonyTestBase {
-
-    private int  mSlotId = 0;
-    private int mSubId = 1;
-    private int mUpdatedSubId = 2;
-
-    @Captor ArgumentCaptor<IRcsUcePublishStateCallback> mPublishStateCallbacksCaptor;
-
-    @Mock PresencePublication mPresencePublication;
-    @Mock PresenceSubscriber mPresenceSubscriber;
-    @Mock RcsFeatureManager mRcsFeatureManager;
-    @Mock ImsMmTelManager mImsMmTelManager;
-    @Mock RemoteCallbackList<IRcsUcePublishStateCallback> mPublishStateCallbacks;
-
-    private Looper mLooper;
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-
-        ImsManager imsManager =
-                (ImsManager) mContext.getSystemService(Context.TELEPHONY_IMS_SERVICE);
-        when(imsManager.getImsMmTelManager(mSubId)).thenReturn(mImsMmTelManager);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        super.tearDown();
-
-        if (mLooper != null) {
-            mLooper.quit();
-            mLooper = null;
-        }
-    }
-
-    @Test
-    public void testServiceConnected() throws Exception {
-        UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
-        uceImpl.onRcsConnected(mRcsFeatureManager);
-
-        verify(mRcsFeatureManager).addFeatureListenerCallback(any(RcsFeatureCallbacks.class));
-        verify(mPresencePublication).updatePresencePublisher(any(PresencePublisher.class));
-        verify(mPresenceSubscriber).updatePresenceSubscriber(any(SubscribePublisher.class));
-    }
-
-    @Test
-    public void testServiceDisconnected() throws Exception {
-        UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
-        uceImpl.onRcsDisconnected();
-
-        verify(mPresencePublication).removePresencePublisher();
-        verify(mPresenceSubscriber).removePresenceSubscriber();
-    }
-
-    @Test
-    public void testSubscriptionUpdated() throws Exception {
-        UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
-        uceImpl.onAssociatedSubscriptionUpdated(mUpdatedSubId);
-
-        verify(mImsMmTelManager).registerImsRegistrationCallback(any(Executor.class),
-                any(RegistrationManager.RegistrationCallback.class));
-        verify(mImsMmTelManager).registerMmTelCapabilityCallback(any(Executor.class),
-                any(ImsMmTelManager.CapabilityCallback.class));
-        verify(mPresencePublication).handleAssociatedSubscriptionChanged(mUpdatedSubId);
-        verify(mPresenceSubscriber).handleAssociatedSubscriptionChanged(mUpdatedSubId);
-    }
-
-    @Test
-    public void testUcePublishStateRetrieval() throws Exception {
-        UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
-        uceImpl.getUcePublishState();
-
-        verify(mPresencePublication).getPublishState();
-    }
-
-    @Test
-    public void testRegisterPublishStateCallbacks() throws Exception {
-        UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
-        uceImpl.registerPublishStateCallback(any(IRcsUcePublishStateCallback.class));
-        verify(mPublishStateCallbacks).register(mPublishStateCallbacksCaptor.capture());
-    }
-
-    @Test
-    public void testOnNotifyUpdateCapabilities() throws Exception {
-        UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
-        uceImpl.onRcsConnected(mRcsFeatureManager);
-
-        int triggerType = RcsPresenceExchangeImplBase.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN;
-        uceImpl.mRcsFeatureCallback.onNotifyUpdateCapabilities(triggerType);
-        waitForMs(1000);
-
-        verify(mPresencePublication).onStackPublishRequested(triggerType);
-    }
-
-    @Test
-    public void testRequestPublicationWithSuccessfulResponse() throws Exception {
-        int taskId = 1;
-        int sipResponse = 200;
-        Uri contact = Uri.fromParts("sip", "test", null);
-        RcsContactUceCapability capability = getRcsContactUceCapability(contact);
-
-        UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
-        uceImpl.onRcsConnected(mRcsFeatureManager);
-
-        doAnswer(invocation -> {
-            uceImpl.mRcsFeatureCallback.onCommandUpdate(RcsCapabilityExchange.COMMAND_CODE_SUCCESS,
-                    taskId);
-            uceImpl.mRcsFeatureCallback.onNetworkResponse(sipResponse, null, taskId);
-            return null;
-        }).when(mRcsFeatureManager).requestPublication(capability, taskId);
-
-        // Request publication
-        int result = uceImpl.requestPublication(capability, contact.toString(), taskId);
-
-        assertEquals(ResultCode.SUCCESS, result);
-        verify(mPresencePublication).onCommandStatusUpdated(taskId, taskId, ResultCode.SUCCESS);
-        verify(mPresencePublication).onSipResponse(taskId, sipResponse, null);
-    }
-
-    @Test
-    public void testRequestPublicationWithFailedResponse() throws Exception {
-        int taskId = 1;
-        Uri contact = Uri.fromParts("sip", "test", null);
-        RcsContactUceCapability capability = getRcsContactUceCapability(contact);
-
-        UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
-        uceImpl.onRcsConnected(mRcsFeatureManager);
-
-        doAnswer(invocation -> {
-            uceImpl.mRcsFeatureCallback.onCommandUpdate(
-                    RcsCapabilityExchange.COMMAND_CODE_GENERIC_FAILURE, taskId);
-            return null;
-        }).when(mRcsFeatureManager).requestPublication(capability, taskId);
-
-        // Request publication
-        int result = uceImpl.requestPublication(capability, contact.toString(), taskId);
-
-        assertEquals(ResultCode.SUCCESS, result);
-        verify(mPresencePublication).onCommandStatusUpdated(taskId, taskId,
-                ResultCode.PUBLISH_GENERIC_FAILURE);
-    }
-
-    private RcsContactUceCapability getRcsContactUceCapability(Uri contact) {
-        ServiceCapabilities.Builder servCapsBuilder = new ServiceCapabilities.Builder(true, true);
-        servCapsBuilder.addSupportedDuplexMode(ServiceCapabilities.DUPLEX_MODE_FULL);
-
-        RcsContactPresenceTuple.Builder tupleBuilder = new RcsContactPresenceTuple.Builder(
-                RcsContactPresenceTuple.TUPLE_BASIC_STATUS_OPEN,
-                RcsContactPresenceTuple.SERVICE_ID_MMTEL, "1.0");
-        tupleBuilder.addContactUri(contact).addServiceCapabilities(servCapsBuilder.build());
-
-        PresenceBuilder presenceBuilder = new PresenceBuilder(contact,
-                RcsContactUceCapability.SOURCE_TYPE_CACHED,
-                RcsContactUceCapability.REQUEST_RESULT_FOUND);
-        presenceBuilder.addCapabilityTuple(tupleBuilder.build());
-        return presenceBuilder.build();
-    }
-
-    @Test
-    public void testRequestCapability() throws Exception {
-        int taskId = 1;
-        int sipResponse = 200;
-        List<RcsContactUceCapability> infos = new ArrayList<>();
-        List<Uri> contacts = Arrays.asList(Uri.fromParts("sip", "00000", null));
-        IRcsUceControllerCallback callback = Mockito.mock(IRcsUceControllerCallback.class);
-
-        UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
-        uceImpl.onRcsConnected(mRcsFeatureManager);
-
-        when(mPresenceSubscriber.requestCapability(anyList(), any())).thenReturn(taskId);
-
-        doAnswer(invocation -> {
-            uceImpl.mRcsFeatureCallback.onCommandUpdate(RcsCapabilityExchange.COMMAND_CODE_SUCCESS,
-                    taskId);
-            uceImpl.mRcsFeatureCallback.onNetworkResponse(sipResponse, null, taskId);
-            uceImpl.mRcsFeatureCallback.onCapabilityRequestResponsePresence(infos, taskId);
-            return null;
-        }).when(mRcsFeatureManager).requestCapabilities(anyList(), anyInt());
-
-        uceImpl.requestCapabilities(contacts, callback);
-        uceImpl.requestCapability(new String[] {"00000"}, taskId);
-
-        verify(mPresenceSubscriber).onCommandStatusUpdated(taskId, taskId, ResultCode.SUCCESS);
-        verify(mPresenceSubscriber).onSipResponse(taskId, sipResponse, null);
-        verify(mPresenceSubscriber).updatePresences(taskId, infos, true, null);
-    }
-
-    @Test
-    public void testUpdatePublisherState() throws Exception {
-        IRcsUcePublishStateCallback callback = Mockito.mock(IRcsUcePublishStateCallback.class);
-        doAnswer(invocation -> {
-            callback.onPublishStateChanged(anyInt());
-            return null;
-        }).when(mPublishStateCallbacks).broadcast(any());
-
-        UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
-        uceImpl.onRcsConnected(mRcsFeatureManager);
-        uceImpl.registerPublishStateCallback(callback);
-        uceImpl.updatePublisherState(PresenceBase.PUBLISH_STATE_200_OK);
-
-        assertEquals(PresenceBase.PUBLISH_STATE_200_OK, uceImpl.getPublisherState());
-        verify(callback).onPublishStateChanged(anyInt());
-    }
-
-    @Test
-    public void testUnpublish() throws Exception {
-        IRcsUcePublishStateCallback callback = Mockito.mock(IRcsUcePublishStateCallback.class);
-        doAnswer(invocation -> {
-            callback.onPublishStateChanged(anyInt());
-            return null;
-        }).when(mPublishStateCallbacks).broadcast(any());
-
-        UserCapabilityExchangeImpl uceImpl = createUserCapabilityExchangeImpl();
-        uceImpl.onRcsConnected(mRcsFeatureManager);
-        uceImpl.mRcsFeatureCallback.onUnpublish();
-        waitForMs(1000);
-
-        verify(mPresencePublication).setPublishState(PresenceBase.PUBLISH_STATE_NOT_PUBLISHED);
-    }
-
-    private UserCapabilityExchangeImpl createUserCapabilityExchangeImpl() throws Exception {
-        HandlerThread handlerThread = new HandlerThread("UceImplHandlerThread");
-        handlerThread.start();
-        mLooper = handlerThread.getLooper();
-        UserCapabilityExchangeImpl uceImpl = new UserCapabilityExchangeImpl(mContext, mSlotId,
-                mSubId, mLooper, mPresencePublication, mPresenceSubscriber,
-                mPublishStateCallbacks);
-        verify(mPresencePublication).handleAssociatedSubscriptionChanged(1);
-        verify(mPresenceSubscriber).handleAssociatedSubscriptionChanged(1);
-        waitForHandlerAction(uceImpl.getHandler(), 1000);
-        verify(mImsMmTelManager, atLeast(1)).registerImsRegistrationCallback(
-                any(Executor.class), any(RegistrationManager.RegistrationCallback.class));
-        verify(mContext).registerReceiver(any(), any());
-        return uceImpl;
-    }
-}
