diff --git a/src/com/android/phone/ImsRcsController.java b/src/com/android/phone/ImsRcsController.java
index e09c6af..6b1b5e3 100644
--- a/src/com/android/phone/ImsRcsController.java
+++ b/src/com/android/phone/ImsRcsController.java
@@ -34,11 +34,12 @@
 import android.util.Log;
 
 import com.android.ims.ImsManager;
-import com.android.ims.RcsFeatureManager;
 import com.android.internal.telephony.IIntegerConsumer;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.imsphone.ImsPhone;
+import com.android.services.telephony.rcs.RcsFeatureController;
 import com.android.services.telephony.rcs.TelephonyRcsService;
+import com.android.services.telephony.rcs.UserCapabilityExchangeImpl;
 
 import java.util.List;
 
@@ -77,16 +78,16 @@
     }
 
     /**
-     * Register a IImsRegistrationCallback to receive IMS network registration state.
+     * Register a {@link RegistrationManager.RegistrationCallback} to receive IMS network
+     * registration state.
      */
     @Override
-    public void registerImsRegistrationCallback(int subId, IImsRegistrationCallback callback)
-            throws RemoteException {
+    public void registerImsRegistrationCallback(int subId, IImsRegistrationCallback callback) {
         enforceReadPrivilegedPermission("registerImsRegistrationCallback");
         final long token = Binder.clearCallingIdentity();
         try {
-            getRcsFeatureManager(subId).registerImsRegistrationCallback(callback);
-        } catch (com.android.ims.ImsException e) {
+            getRcsFeatureController(subId).registerImsRegistrationCallback(subId, callback);
+        } catch (ImsException e) {
             Log.e(TAG, "registerImsRegistrationCallback: sudId=" + subId + ", " + e.getMessage());
             throw new ServiceSpecificException(e.getCode());
         } finally {
@@ -95,14 +96,14 @@
     }
 
     /**
-     * Removes an existing {@link RegistrationCallback}.
+     * Removes an existing {@link RegistrationManager.RegistrationCallback}.
      */
     @Override
     public void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback callback) {
         enforceReadPrivilegedPermission("unregisterImsRegistrationCallback");
         final long token = Binder.clearCallingIdentity();
         try {
-            getRcsFeatureManager(subId).unregisterImsRegistrationCallback(callback);
+            getRcsFeatureController(subId).unregisterImsRegistrationCallback(subId, callback);
         } catch (ServiceSpecificException e) {
             Log.e(TAG, "unregisterImsRegistrationCallback: error=" + e.errorCode);
         } finally {
@@ -118,7 +119,7 @@
         enforceReadPrivilegedPermission("getImsRcsRegistrationState");
         final long token = Binder.clearCallingIdentity();
         try {
-            getImsPhone(subId).getImsRcsRegistrationState(regState -> {
+            getRcsFeatureController(subId).getRegistrationState(regState -> {
                 try {
                     consumer.accept((regState == null)
                             ? RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED : regState);
@@ -139,7 +140,7 @@
         enforceReadPrivilegedPermission("getImsRcsRegistrationTransportType");
         final long token = Binder.clearCallingIdentity();
         try {
-            getImsPhone(subId).getImsRcsRegistrationTech(regTech -> {
+            getRcsFeatureController(subId).getRegistrationTech(regTech -> {
                 // Convert registration tech from ImsRegistrationImplBase -> RegistrationManager
                 int regTechConverted = (regTech == null)
                         ? ImsRegistrationImplBase.REGISTRATION_TECH_NONE : regTech;
@@ -164,13 +165,12 @@
      * @param callback The ImsCapabilityCallback to be registered.
      */
     @Override
-    public void registerRcsAvailabilityCallback(int subId, IImsCapabilityCallback callback)
-            throws RemoteException {
+    public void registerRcsAvailabilityCallback(int subId, IImsCapabilityCallback callback) {
         enforceReadPrivilegedPermission("registerRcsAvailabilityCallback");
         final long token = Binder.clearCallingIdentity();
         try {
-            getRcsFeatureManager(subId).registerRcsAvailabilityCallback(callback);
-        } catch (com.android.ims.ImsException e) {
+            getRcsFeatureController(subId).registerRcsAvailabilityCallback(subId, callback);
+        } catch (ImsException e) {
             Log.e(TAG, "registerRcsAvailabilityCallback: sudId=" + subId + ", " + e.getMessage());
             throw new ServiceSpecificException(e.getCode());
         } finally {
@@ -189,9 +189,7 @@
         enforceReadPrivilegedPermission("unregisterRcsAvailabilityCallback");
         final long token = Binder.clearCallingIdentity();
         try {
-            getRcsFeatureManager(subId).unregisterRcsAvailabilityCallback(callback);
-        } catch (com.android.ims.ImsException e) {
-            Log.e(TAG, "unregisterRcsAvailabilityCallback: sudId=" + subId + "," + e.getMessage());
+            getRcsFeatureController(subId).unregisterRcsAvailabilityCallback(subId, callback);
         } finally {
             Binder.restoreCallingIdentity(token);
         }
@@ -212,8 +210,8 @@
         enforceReadPrivilegedPermission("isCapable");
         final long token = Binder.clearCallingIdentity();
         try {
-            return getRcsFeatureManager(subId).isCapable(capability, radioTech);
-        } catch (com.android.ims.ImsException e) {
+            return getRcsFeatureController(subId).isCapable(capability, radioTech);
+        } catch (ImsException e) {
             Log.e(TAG, "isCapable: sudId=" + subId
                     + ", capability=" + capability + ", " + e.getMessage());
             return false;
@@ -236,8 +234,8 @@
         enforceReadPrivilegedPermission("isAvailable");
         final long token = Binder.clearCallingIdentity();
         try {
-            return getRcsFeatureManager(subId).isAvailable(capability);
-        } catch (com.android.ims.ImsException e) {
+            return getRcsFeatureController(subId).isAvailable(capability);
+        } catch (ImsException e) {
             Log.e(TAG, "isAvailable: sudId=" + subId
                     + ", capability=" + capability + ", " + e.getMessage());
             return false;
@@ -250,21 +248,35 @@
     public void requestCapabilities(int subId, List<Uri> contactNumbers,
             IRcsUceControllerCallback c) {
         enforceReadPrivilegedPermission("requestCapabilities");
-        if (mRcsService == null) {
-            throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
-                    "IMS is not available on device.");
+        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.requestCapabilities(contactNumbers, c);
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
-        mRcsService.requestCapabilities(getImsPhone(subId).getPhoneId(), contactNumbers, c);
     }
 
     @Override
     public int getUcePublishState(int subId) {
         enforceReadPrivilegedPermission("getUcePublishState");
-        if (mRcsService == null) {
-            throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
-                    "IMS is not available on device.");
+        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.");
+            }
+            return uce.getUcePublishState();
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
-        return mRcsService.getUcePublishState(getImsPhone(subId).getPhoneId());
     }
 
     @Override
@@ -332,27 +344,27 @@
      * @return The RcsFeatureManager instance
      * @throws ServiceSpecificException if getting RcsFeatureManager instance failed.
      */
-    private RcsFeatureManager getRcsFeatureManager(int subId) {
+    private RcsFeatureController getRcsFeatureController(int subId) {
         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
                     "IMS is not available on device.");
         }
+        if (mRcsService == null) {
+            throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
+                    "IMS is not available on device.");
+        }
         Phone phone = PhoneGlobals.getPhone(subId);
         if (phone == null) {
             throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION,
                     "Invalid subscription Id: " + subId);
         }
-        ImsPhone imsPhone = (ImsPhone) phone.getImsPhone();
-        if (imsPhone == null) {
+        int slotId = phone.getPhoneId();
+        RcsFeatureController c = mRcsService.getFeatureController(slotId);
+        if (c == null) {
             throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE,
-                    "Cannot find ImsPhone instance: " + subId);
+                    "Cannot find RcsFeatureController instance for sub: " + subId);
         }
-        RcsFeatureManager rcsFeatureManager = imsPhone.getRcsManager();
-        if (rcsFeatureManager == null) {
-            throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE,
-                    "Cannot find RcsFeatureManager instance: " + subId);
-        }
-        return rcsFeatureManager;
+        return c;
     }
 
     void setRcsService(TelephonyRcsService rcsService) {
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index b0e0105..d361bb1 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -375,7 +375,9 @@
             imsRcsController = ImsRcsController.init(this);
 
             if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS)) {
-                mTelephonyRcsService = new TelephonyRcsService(this);
+                mTelephonyRcsService = new TelephonyRcsService(this,
+                        PhoneFactory.getPhones().length);
+                mTelephonyRcsService.initialize();
                 imsRcsController.setRcsService(mTelephonyRcsService);
             }
 
@@ -912,6 +914,12 @@
             e.printStackTrace();
         }
         pw.decreaseIndent();
+        pw.println("RcsService:");
+        try {
+            if (mTelephonyRcsService != null) mTelephonyRcsService.dump(fd, pw, args);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
         pw.decreaseIndent();
         pw.println("------- End PhoneGlobals -------");
     }
diff --git a/src/com/android/services/telephony/rcs/PresenceHelper.java b/src/com/android/services/telephony/rcs/PresenceHelper.java
deleted file mode 100644
index 5f7e35f..0000000
--- a/src/com/android/services/telephony/rcs/PresenceHelper.java
+++ /dev/null
@@ -1,166 +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.annotation.Nullable;
-import android.content.Context;
-import android.telephony.SubscriptionManager;
-import android.util.Log;
-import android.util.SparseArray;
-
-import com.android.ims.RcsFeatureConnection;
-import com.android.ims.RcsFeatureManager;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.imsphone.ImsPhone;
-import com.android.internal.telephony.imsphone.ImsRcsStatusListener;
-import com.android.phone.R;
-import com.android.service.ims.presence.PresencePublication;
-import com.android.service.ims.presence.PresenceSubscriber;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Optional;
-
-class PresenceHelper {
-
-    private static final String LOG_TAG = "PresenceHelper";
-
-    private final Context mContext;
-    private final List<Phone> mPhones;
-
-    private final SparseArray<PresencePublication> mPresencePublications = new SparseArray<>();
-    private final SparseArray<PresenceSubscriber> mPresenceSubscribers = new SparseArray<>();
-
-    PresenceHelper(Context context) {
-        mContext = context;
-
-        // Get phones
-        Phone[] phoneAry = PhoneFactory.getPhones();
-        mPhones = (phoneAry != null) ? Arrays.asList(phoneAry) : new ArrayList<>();
-
-        initRcsPresencesInstance();
-        registerRcsConnectionStatus();
-
-        Log.i(LOG_TAG, "initialized: phone size=" + mPhones.size());
-    }
-
-    private void initRcsPresencesInstance() {
-        String[] volteError = mContext.getResources().getStringArray(
-                R.array.config_volte_provision_error_on_publish_response);
-        String[] rcsError = mContext.getResources().getStringArray(
-                R.array.config_rcs_provision_error_on_publish_response);
-
-        mPhones.forEach((phone) -> {
-            RcsFeatureConnection rcsConnection = getRcsFeatureConnection(phone);
-            // Initialize PresencePublication
-            mPresencePublications.put(
-                    phone.getPhoneId(),
-                    new PresencePublication(rcsConnection, mContext, volteError, rcsError));
-            // Initialize PresenceSubscriber
-            mPresenceSubscribers.put(
-                    phone.getPhoneId(),
-                    new PresenceSubscriber(rcsConnection, mContext, volteError, rcsError));
-        });
-    }
-
-    private @Nullable RcsFeatureConnection getRcsFeatureConnection(Phone phone) {
-        ImsPhone imsPhone = (ImsPhone) phone.getImsPhone();
-        if (imsPhone != null) {
-            RcsFeatureManager rcsFeatureManager = imsPhone.getRcsManager();
-            if (rcsFeatureManager != null) {
-                return rcsFeatureManager.getRcsFeatureConnection();
-            }
-        }
-        return null;
-    }
-
-    /*
-     * RcsFeatureManager in ImsPhone is not null only when RCS is connected. Register a callback to
-     * receive the RCS connection status.
-     */
-    private void registerRcsConnectionStatus() {
-        mPhones.forEach((phone) -> {
-            ImsPhone imsPhone = (ImsPhone) phone.getImsPhone();
-            if (imsPhone != null) {
-                imsPhone.setRcsStatusListener(mStatusListener);
-            }
-        });
-    }
-
-    /**
-     * The IMS RCS status listener to listen the status changed
-     */
-    private ImsRcsStatusListener mStatusListener = new ImsRcsStatusListener() {
-        @Override
-        public void onRcsConnected(int phoneId, RcsFeatureManager rcsFeatureManager) {
-            int subId = getSubscriptionId(phoneId);
-            if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-                Log.e(LOG_TAG, "onRcsConnected: invalid subId, phoneId=" + phoneId);
-                return;
-            }
-
-            Log.i(LOG_TAG, "onRcsConnected: phoneId=" + phoneId + ", subId=" + subId);
-            RcsFeatureConnection connection = rcsFeatureManager.getRcsFeatureConnection();
-            PresencePublication presencePublication = getPresencePublication(phoneId);
-            if (presencePublication != null) {
-                Log.i(LOG_TAG, "Update PresencePublisher because RCS is connected");
-                presencePublication.updatePresencePublisher(subId, connection);
-            }
-            PresenceSubscriber presenceSubscriber = getPresenceSubscriber(phoneId);
-            if (presenceSubscriber != null) {
-                Log.i(LOG_TAG, "Update PresenceSubscriber because RCS is connected");
-                presenceSubscriber.updatePresenceSubscriber(subId, connection);
-            }
-        }
-
-        @Override
-        public void onRcsDisconnected(int phoneId) {
-            int subId = getSubscriptionId(phoneId);
-            Log.i(LOG_TAG, "onRcsDisconnected: phoneId=" + phoneId + ", subId=" + subId);
-            PresencePublication publication = getPresencePublication(phoneId);
-            if (publication != null) {
-                Log.i(LOG_TAG, "Remove PresencePublisher because RCS is disconnected");
-                publication.removePresencePublisher(subId);
-            }
-
-            PresenceSubscriber subscriber = getPresenceSubscriber(phoneId);
-            if (subscriber != null) {
-                Log.i(LOG_TAG, "Remove PresencePublisher because RCS is disconnected");
-                subscriber.removePresenceSubscriber(subId);
-            }
-        }
-    };
-
-    private int getSubscriptionId(int phoneId) {
-        Optional<Phone> phone = mPhones.stream()
-                .filter(p -> p.getPhoneId() == phoneId).findFirst();
-        if (phone.isPresent()) {
-            return phone.get().getSubId();
-        }
-        return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-    }
-
-    public @Nullable PresencePublication getPresencePublication(int phoneId) {
-        return mPresencePublications.get(phoneId);
-    }
-
-    public @Nullable PresenceSubscriber getPresenceSubscriber(int phoneId) {
-        return mPresenceSubscribers.get(phoneId);
-    }
-}
diff --git a/src/com/android/services/telephony/rcs/RcsFeatureController.java b/src/com/android/services/telephony/rcs/RcsFeatureController.java
new file mode 100644
index 0000000..f451e9b
--- /dev/null
+++ b/src/com/android/services/telephony/rcs/RcsFeatureController.java
@@ -0,0 +1,409 @@
+/*
+ * 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.annotation.AnyThread;
+import android.content.Context;
+import android.net.Uri;
+import android.telephony.ims.ImsException;
+import android.telephony.ims.ImsRcsManager;
+import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.RegistrationManager;
+import android.telephony.ims.aidl.IImsCapabilityCallback;
+import android.telephony.ims.aidl.IImsRegistrationCallback;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import com.android.ims.FeatureConnector;
+import com.android.ims.IFeatureConnector;
+import com.android.ims.RcsFeatureManager;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.imsphone.ImsRegistrationCallbackHelper;
+import com.android.internal.util.IndentingPrintWriter;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.Map;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+
+/**
+ * Contains the RCS feature implementations that are associated with this slot's RcsFeature.
+ */
+@AnyThread
+public class RcsFeatureController {
+    private static final String LOG_TAG = "RcsFeatureController";
+
+    /**
+     * Interface used by RCS features that need to listen for when the associated service has been
+     * connected.
+     */
+    public interface Feature {
+        /**
+         * The RcsFeature has been connected to the framework and is ready.
+         */
+        void onRcsConnected(RcsFeatureManager manager);
+
+        /**
+         * The framework has lost the binding to the RcsFeature or it is in the process of changing.
+         */
+        void onRcsDisconnected();
+
+        /**
+         * The subscription associated with the slot this controller is bound to has changed or its
+         * carrier configuration has changed.
+         */
+        void onAssociatedSubscriptionUpdated(int subId);
+
+        /**
+         * Called when the feature should be destroyed.
+         */
+        void onDestroy();
+    }
+
+    /**
+     * Used to inject FeatureConnector instances for testing.
+     */
+    @VisibleForTesting
+    public interface FeatureConnectorFactory<T extends IFeatureConnector> {
+        /**
+         * @return a {@link FeatureConnector} associated for the given {@link IFeatureConnector}
+         * and slot id.
+         */
+        FeatureConnector<T> create(Context context, int slotId,
+                FeatureConnector.Listener<T> listener, Executor executor, String tag);
+    }
+
+    /**
+     * Used to inject ImsRegistrationCallbackHelper instances for testing.
+     */
+    @VisibleForTesting
+    public interface RegistrationHelperFactory {
+        /**
+         * @return an {@link ImsRegistrationCallbackHelper}, which helps manage IMS registration
+         * state.
+         */
+        ImsRegistrationCallbackHelper create(
+                ImsRegistrationCallbackHelper.ImsRegistrationUpdate cb, Executor executor);
+    }
+
+    private FeatureConnectorFactory<RcsFeatureManager> mFeatureFactory = FeatureConnector::new;
+    private RegistrationHelperFactory mRegistrationHelperFactory =
+            ImsRegistrationCallbackHelper::new;
+
+    private final Map<Class<?>, Feature> mFeatures = new ArrayMap<>();
+    private final Context mContext;
+    private final ImsRegistrationCallbackHelper mImsRcsRegistrationHelper;
+    private final int mSlotId;
+    private final Object mLock = new Object();
+    private FeatureConnector<RcsFeatureManager> mFeatureConnector;
+    private RcsFeatureManager mFeatureManager;
+
+    private FeatureConnector.Listener<RcsFeatureManager> mFeatureConnectorListener =
+            new FeatureConnector.Listener<RcsFeatureManager>() {
+                @Override
+                public RcsFeatureManager getFeatureManager() {
+                    return new RcsFeatureManager(mContext, mSlotId);
+                }
+
+                @Override
+                public void connectionReady(RcsFeatureManager manager)
+                        throws com.android.ims.ImsException {
+                    if (manager == null) {
+                        Log.w(LOG_TAG, "connectionReady returned null RcsFeatureManager");
+                        return;
+                    }
+                    try {
+                        // May throw ImsException if for some reason the connection to the
+                        // ImsService is gone.
+                        setupConnectionToService(manager);
+                    } catch (ImsException e) {
+                        // Use deprecated Exception for compatibility.
+                        throw new com.android.ims.ImsException(e.getMessage(),
+                                ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
+                    }
+                    updateConnectionStatus(manager);
+                }
+
+                @Override
+                public void connectionUnavailable() {
+                    // Call before disabling connection to manager.
+                    removeConnectionToService();
+                    updateConnectionStatus(null /*manager*/);
+                }
+            };
+
+    private ImsRegistrationCallbackHelper.ImsRegistrationUpdate mRcsRegistrationUpdate = new
+            ImsRegistrationCallbackHelper.ImsRegistrationUpdate() {
+                @Override
+                public void handleImsRegistered(int imsRadioTech) {
+                }
+
+                @Override
+                public void handleImsRegistering(int imsRadioTech) {
+                }
+
+                @Override
+                public void handleImsUnregistered(ImsReasonInfo imsReasonInfo) {
+                }
+
+                @Override
+                public void handleImsSubscriberAssociatedUriChanged(Uri[] uris) {
+                }
+            };
+
+    public RcsFeatureController(Context context, int slotId) {
+        mContext = context;
+        mSlotId = slotId;
+        mImsRcsRegistrationHelper = mRegistrationHelperFactory.create(mRcsRegistrationUpdate,
+                mContext.getMainExecutor());
+    }
+
+    /**
+     * Should only be used to inject registration helpers for testing.
+     */
+    @VisibleForTesting
+    public RcsFeatureController(Context context, int slotId, RegistrationHelperFactory f) {
+        mContext = context;
+        mSlotId = slotId;
+        mRegistrationHelperFactory = f;
+        mImsRcsRegistrationHelper = mRegistrationHelperFactory.create(mRcsRegistrationUpdate,
+                mContext.getMainExecutor());
+    }
+
+    /**
+     * This method should be called after constructing an instance of this class to start the
+     * connection process to the associated RcsFeature.
+     */
+    public void connect() {
+        synchronized (mLock) {
+            mFeatureConnector = mFeatureFactory.create(mContext, mSlotId, mFeatureConnectorListener,
+                    mContext.getMainExecutor(), LOG_TAG);
+            mFeatureConnector.connect();
+        }
+    }
+
+    /**
+     * Adds a {@link Feature} to be tracked by this FeatureController.
+     */
+    public <T extends Feature> void addFeature(T connector, Class<T> clazz) {
+        synchronized (mLock) {
+            mFeatures.put(clazz, connector);
+        }
+        RcsFeatureManager manager = getFeatureManager();
+        if (manager != null) {
+            connector.onRcsConnected(manager);
+        } else {
+            connector.onRcsDisconnected();
+        }
+    }
+
+    /**
+     * @return The RCS feature implementation tracked by this controller.
+     */
+    @SuppressWarnings("unchecked")
+    public <T> T getFeature(Class<T> clazz) {
+        synchronized (mLock) {
+            return (T) mFeatures.get(clazz);
+        }
+    }
+
+    /**
+     * Update the subscription associated with this controller.
+     */
+    public void updateAssociatedSubscription(int newSubId) {
+        RcsFeatureManager manager = getFeatureManager();
+        if (manager != null) {
+            try {
+                manager.updateCapabilities();
+            } catch (ImsException e) {
+                Log.w(LOG_TAG, "associatedSubscriptionChanged failed:" + e);
+            }
+        }
+        synchronized (mLock) {
+            for (Feature c : mFeatures.values()) {
+                c.onAssociatedSubscriptionUpdated(newSubId);
+            }
+        }
+    }
+
+    /**
+     * Call before this controller is destroyed to tear down associated features.
+     */
+    public void destroy() {
+        synchronized (mLock) {
+            mFeatureConnector.disconnect();
+            for (Feature c : mFeatures.values()) {
+                c.onRcsDisconnected();
+                c.onDestroy();
+            }
+            mFeatures.clear();
+        }
+    }
+
+    @VisibleForTesting
+    public void setFeatureConnectorFactory(FeatureConnectorFactory factory) {
+        mFeatureFactory = factory;
+    }
+
+    /**
+     * Add a {@link RegistrationManager.RegistrationCallback} callback that gets called when IMS
+     * registration has changed for a specific subscription.
+     */
+    public void registerImsRegistrationCallback(int subId, IImsRegistrationCallback callback)
+            throws ImsException {
+        RcsFeatureManager manager = getFeatureManager();
+        if (manager == null) {
+            throw new ImsException("Service is not available",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+        manager.registerImsRegistrationCallback(subId, callback);
+    }
+
+    /**
+     * Removes a previously registered {@link RegistrationManager.RegistrationCallback} callback
+     * that is associated with a specific subscription.
+     */
+    public void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback callback) {
+        RcsFeatureManager manager = getFeatureManager();
+        if (manager != null) {
+            manager.unregisterImsRegistrationCallback(subId, callback);
+        }
+    }
+
+    /**
+     * Register an {@link ImsRcsManager.AvailabilityCallback} with the associated RcsFeature,
+     * which will provide availability updates.
+     */
+    public void registerRcsAvailabilityCallback(int subId, IImsCapabilityCallback callback)
+            throws ImsException {
+        RcsFeatureManager manager = getFeatureManager();
+        if (manager == null) {
+            throw new ImsException("Service is not available",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+        manager.registerRcsAvailabilityCallback(subId, callback);
+    }
+
+    /**
+     * Remove a registered {@link ImsRcsManager.AvailabilityCallback} from the RcsFeature.
+     */
+    public void unregisterRcsAvailabilityCallback(int subId, IImsCapabilityCallback callback) {
+        RcsFeatureManager manager = getFeatureManager();
+        if (manager != null) {
+            manager.unregisterRcsAvailabilityCallback(subId, callback);
+        }
+    }
+
+    /**
+     * Query for the specific capability.
+     */
+    public boolean isCapable(int capability, int radioTech)
+            throws android.telephony.ims.ImsException {
+        RcsFeatureManager manager = getFeatureManager();
+        if (manager == null) {
+            throw new ImsException("Service is not available",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+        return manager.isCapable(capability, radioTech);
+    }
+
+    /**
+     * Query the availability of an IMS RCS capability.
+     */
+    public boolean isAvailable(int capability) throws android.telephony.ims.ImsException {
+        RcsFeatureManager manager = getFeatureManager();
+        if (manager == null) {
+            throw new ImsException("Service is not available",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+        return manager.isAvailable(capability);
+    }
+
+    /**
+     * Get the IMS RCS registration technology for this Phone.
+     */
+    public void getRegistrationTech(Consumer<Integer> callback) {
+        RcsFeatureManager manager = getFeatureManager();
+        if (manager != null) {
+            manager.getImsRegistrationTech(callback);
+        }
+        callback.accept(ImsRegistrationImplBase.REGISTRATION_TECH_NONE);
+    }
+
+    /**
+     * Retrieve the current RCS registration state.
+     */
+    public void getRegistrationState(Consumer<Integer> callback) {
+        callback.accept(mImsRcsRegistrationHelper.getImsRegistrationState());
+    }
+
+    private void setupConnectionToService(RcsFeatureManager manager) throws ImsException {
+        // Open persistent listener connection, sends RcsFeature#onFeatureReady.
+        manager.openConnection();
+        manager.updateCapabilities();
+        manager.registerImsRegistrationCallback(mImsRcsRegistrationHelper.getCallbackBinder());
+    }
+
+    private void removeConnectionToService() {
+        RcsFeatureManager manager = getFeatureManager();
+        if (manager != null) {
+            manager.unregisterImsRegistrationCallback(
+                    mImsRcsRegistrationHelper.getCallbackBinder());
+            // Remove persistent listener connection.
+            manager.releaseConnection();
+        }
+        mImsRcsRegistrationHelper.reset();
+    }
+
+    private void updateConnectionStatus(RcsFeatureManager manager) {
+        synchronized (mLock) {
+            mFeatureManager = manager;
+            if (mFeatureManager != null) {
+                for (Feature c : mFeatures.values()) {
+                    c.onRcsConnected(manager);
+                }
+            } else {
+                for (Feature c : mFeatures.values()) {
+                    c.onRcsDisconnected();
+                }
+            }
+        }
+    }
+
+    private RcsFeatureManager getFeatureManager() {
+        synchronized (mLock) {
+            return mFeatureManager;
+        }
+    }
+
+    /**
+     * Dump this controller's instance information for usage in dumpsys.
+     */
+    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
+        pw.print("slotId=");
+        pw.println(mSlotId);
+        pw.print("RegistrationState=");
+        pw.println(mImsRcsRegistrationHelper.getImsRegistrationState());
+        pw.print("connected=");
+        synchronized (mLock) {
+            pw.println(mFeatureManager != null);
+        }
+    }
+}
diff --git a/src/com/android/services/telephony/rcs/TelephonyRcsService.java b/src/com/android/services/telephony/rcs/TelephonyRcsService.java
index 0e8f8de..b4223d3 100644
--- a/src/com/android/services/telephony/rcs/TelephonyRcsService.java
+++ b/src/com/android/services/telephony/rcs/TelephonyRcsService.java
@@ -16,195 +16,225 @@
 
 package com.android.services.telephony.rcs;
 
+import android.annotation.AnyThread;
+import android.content.BroadcastReceiver;
 import android.content.Context;
-import android.net.Uri;
-import android.os.RemoteException;
-import android.os.ServiceSpecificException;
-import android.telephony.ims.ImsException;
-import android.telephony.ims.RcsContactUceCapability;
-import android.telephony.ims.RcsUceAdapter;
-import android.telephony.ims.aidl.IRcsUceControllerCallback;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.AsyncResult;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
 import android.util.Log;
 
-import com.android.ims.ResultCode;
-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.PresenceSubscriber;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.PhoneConfigurationManager;
+import com.android.internal.util.IndentingPrintWriter;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.stream.Collectors;
 
 /**
- * Telephony RCS Service integrates PresencePublication and PresenceSubscriber into the service.
+ * Singleton service setup to manage RCS related services that the platform provides such as User
+ * Capability Exchange.
  */
+@AnyThread
 public class TelephonyRcsService {
 
     private static final String LOG_TAG = "TelephonyRcsService";
 
+    /**
+     * Used to inject RcsFeatureController and UserCapabilityExchangeImpl instances for testing.
+     */
+    @VisibleForTesting
+    public interface FeatureFactory {
+        /**
+         * @return an {@link RcsFeatureController} assoicated with the slot specified.
+         */
+        RcsFeatureController createController(Context context, int slotId);
+
+        /**
+         * @return an instance of {@link UserCapabilityExchangeImpl} associated with the slot
+         * specified.
+         */
+        UserCapabilityExchangeImpl createUserCapabilityExchange(Context context, int slotId,
+                int subId);
+    }
+
+    private FeatureFactory mFeatureFactory = new FeatureFactory() {
+        @Override
+        public RcsFeatureController createController(Context context, int slotId) {
+            return new RcsFeatureController(context, slotId);
+        }
+
+        @Override
+        public UserCapabilityExchangeImpl createUserCapabilityExchange(Context context, int slotId,
+                int subId) {
+            return new UserCapabilityExchangeImpl(context, slotId, subId);
+        }
+    };
+
+    // Notifies this service that there has been a change in available slots.
+    private static final int HANDLER_MSIM_CONFIGURATION_CHANGE = 1;
+
     private final Context mContext;
+    private final Object mLock = new Object();
+    private int mNumSlots;
 
-    // A helper class to manage the RCS Presences instances.
-    private final PresenceHelper mPresenceHelper;
+    // Index corresponds to the slot ID.
+    private List<RcsFeatureController> mFeatureControllers;
 
-    private ConcurrentHashMap<Integer, IRcsUceControllerCallback> mPendingRequests;
+    private BroadcastReceiver mCarrierConfigChangedReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent == null) {
+                return;
+            }
+            if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(intent.getAction())) {
+                Bundle bundle = intent.getExtras();
+                if (bundle == null) {
+                    return;
+                }
+                int slotId = bundle.getInt(CarrierConfigManager.EXTRA_SLOT_INDEX);
+                int subId = bundle.getInt(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX);
+                updateFeatureControllerSubscription(slotId, subId);
+            }
+        }
+    };
 
-    public TelephonyRcsService(Context context) {
+    private Handler mHandler = new Handler(Looper.getMainLooper(), (msg) -> {
+        switch (msg.what) {
+            case HANDLER_MSIM_CONFIGURATION_CHANGE: {
+                AsyncResult result = (AsyncResult) msg.obj;
+                Integer numSlots = (Integer) result.result;
+                if (numSlots == null) {
+                    Log.w(LOG_TAG, "msim config change with null num slots.");
+                    break;
+                }
+                updateFeatureControllerSize(numSlots);
+                break;
+            }
+            default:
+                return false;
+        }
+        return true;
+    });
+
+    public TelephonyRcsService(Context context, int numSlots) {
         Log.i(LOG_TAG, "initialize");
         mContext = context;
-        mPresenceHelper = new PresenceHelper(mContext);
-        mPendingRequests = new ConcurrentHashMap<>();
+        mNumSlots = numSlots;
+        mFeatureControllers = new ArrayList<>(numSlots);
     }
 
     /**
-     * @return the UCE Publish state for the phone ID specified.
+     * @return the {@link RcsFeatureController} associated with the given slot.
      */
-    public int getUcePublishState(int phoneId) {
-        PresencePublication publisher = getPresencePublication(phoneId);
-        if (publisher == null) {
-            throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE,
-                    "UCE service is not currently running.");
+    public RcsFeatureController getFeatureController(int slotId) {
+        synchronized (mLock) {
+            return mFeatureControllers.get(slotId);
         }
-        int publishState = publisher.getPublishState();
-        return toUcePublishState(publishState);
     }
 
     /**
-     * Perform a capabilities request and call {@link IRcsUceControllerCallback} with the result.
+     * Called after instance creation to initialize internal structures as well as register for
+     * system callbacks.
      */
-    public void requestCapabilities(int phoneId, List<Uri> contactNumbers,
-            IRcsUceControllerCallback c) {
-        PresenceSubscriber subscriber = getPresenceSubscriber(phoneId);
-        if (subscriber == null) {
-            throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE,
-                    "UCE service is not currently running.");
+    public void initialize() {
+        synchronized (mLock) {
+            for (int i = 0; i < mNumSlots; i++) {
+                mFeatureControllers.add(constructFeatureController(i));
+            }
         }
-        List<String> numbers = contactNumbers.stream().map(TelephonyRcsService::getNumberFromUri)
-                .collect(Collectors.toList());
-        int taskId = subscriber.requestCapability(numbers, new ContactCapabilityResponse() {
-            @Override
-            public void onSuccess(int reqId) {
-                Log.i(LOG_TAG, "onSuccess called for reqId:" + reqId);
-            }
 
-            @Override
-            public void onError(int reqId, int resultCode) {
-                IRcsUceControllerCallback c = mPendingRequests.remove(reqId);
-                try {
-                    if (c != null) {
-                        c.onError(toUceError(resultCode));
-                    } else {
-                        Log.w(LOG_TAG, "onError called for unknown reqId:" + reqId);
-                    }
-                } catch (RemoteException e) {
-                    Log.i(LOG_TAG, "Calling back to dead service");
-                }
-            }
+        PhoneConfigurationManager.registerForMultiSimConfigChange(mHandler,
+                HANDLER_MSIM_CONFIGURATION_CHANGE, null);
+        mContext.registerReceiver(mCarrierConfigChangedReceiver, new IntentFilter(
+                CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
+    }
 
-            @Override
-            public void onFinish(int reqId) {
-                Log.i(LOG_TAG, "onFinish called for reqId:" + reqId);
-            }
+    @VisibleForTesting
+    public void setFeatureFactory(FeatureFactory f) {
+        mFeatureFactory = f;
+    }
 
-            @Override
-            public void onTimeout(int reqId) {
-                IRcsUceControllerCallback c = mPendingRequests.remove(reqId);
-                try {
-                    if (c != null) {
-                        c.onError(RcsUceAdapter.ERROR_REQUEST_TIMEOUT);
-                    } else {
-                        Log.w(LOG_TAG, "onTimeout called for unknown reqId:" + reqId);
-                    }
-                } catch (RemoteException e) {
-                    Log.i(LOG_TAG, "Calling back to dead service");
-                }
-            }
-
-            @Override
-            public void onCapabilitiesUpdated(int reqId,
-                    List<RcsContactUceCapability> contactCapabilities,
-                    boolean updateLastTimestamp) {
-                IRcsUceControllerCallback c = mPendingRequests.remove(reqId);
-                try {
-                    if (c != null) {
-                        c.onCapabilitiesReceived(contactCapabilities);
-                    } else {
-                        Log.w(LOG_TAG, "onCapabilitiesUpdated, unknown reqId:" + reqId);
-                    }
-                } catch (RemoteException e) {
-                    Log.w(LOG_TAG, "onCapabilitiesUpdated on dead service");
-                }
-            }
-        });
-        if (taskId < 0) {
-            try {
-                c.onError(toUceError(taskId));
+    /**
+     * Update the number of {@link RcsFeatureController}s that are created based on the number of
+     * active slots on the device.
+     */
+    @VisibleForTesting
+    public void updateFeatureControllerSize(int newNumSlots) {
+        synchronized (mLock) {
+            int oldNumSlots = mFeatureControllers.size();
+            if (oldNumSlots == newNumSlots) {
                 return;
-            } catch (RemoteException e) {
-                Log.i(LOG_TAG, "Calling back to dead service");
+            }
+            mNumSlots = newNumSlots;
+            if (oldNumSlots < newNumSlots) {
+                for (int i = oldNumSlots; i < newNumSlots; i++) {
+                    mFeatureControllers.add(constructFeatureController(i));
+                }
+            } else {
+                for (int i = (oldNumSlots - 1); i > (newNumSlots - 1); i--) {
+                    RcsFeatureController controller = mFeatureControllers.remove(i);
+                    controller.destroy();
+                }
             }
         }
-        mPendingRequests.put(taskId, c);
     }
 
-    private PresencePublication getPresencePublication(int phoneId) {
-        return mPresenceHelper.getPresencePublication(phoneId);
-    }
-
-    private PresenceSubscriber getPresenceSubscriber(int phoneId) {
-        return mPresenceHelper.getPresenceSubscriber(phoneId);
-    }
-
-    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_200_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 void updateFeatureControllerSubscription(int slotId, int newSubId) {
+        synchronized (mLock) {
+            RcsFeatureController f = mFeatureControllers.get(slotId);
+            if (f == null) {
+                Log.w(LOG_TAG, "unexpected null FeatureContainer for slot " + slotId);
+                return;
+            }
+            f.updateAssociatedSubscription(newSubId);
         }
     }
 
-    private static int toUceError(int resultCode) {
-        switch(resultCode) {
-            case ResultCode.SUBSCRIBE_NOT_REGISTERED:
-                return RcsUceAdapter.ERROR_NOT_REGISTERED;
-            case ResultCode.SUBSCRIBE_REQUEST_TIMEOUT:
-                return RcsUceAdapter.ERROR_REQUEST_TIMEOUT;
-            case ResultCode.SUBSCRIBE_FORBIDDEN:
-                return RcsUceAdapter.ERROR_FORBIDDEN;
-            case ResultCode.SUBSCRIBE_NOT_FOUND:
-                return RcsUceAdapter.ERROR_NOT_FOUND;
-            case ResultCode.SUBSCRIBE_TOO_LARGE:
-                return RcsUceAdapter.ERROR_REQUEST_TOO_LARGE;
-            case ResultCode.SUBSCRIBE_INSUFFICIENT_MEMORY:
-                return RcsUceAdapter.ERROR_INSUFFICIENT_MEMORY;
-            case ResultCode.SUBSCRIBE_LOST_NETWORK:
-                return RcsUceAdapter.ERROR_LOST_NETWORK;
-            case ResultCode.SUBSCRIBE_ALREADY_IN_QUEUE:
-                return  RcsUceAdapter.ERROR_ALREADY_IN_QUEUE;
-            default:
-                return RcsUceAdapter.ERROR_GENERIC_FAILURE;
+    private RcsFeatureController constructFeatureController(int slotId) {
+        RcsFeatureController c = mFeatureFactory.createController(mContext, slotId);
+        // TODO: integrate user setting into whether or not this feature is added as well as logic
+        // to listen for changes in user setting.
+        c.addFeature(mFeatureFactory.createUserCapabilityExchange(mContext, slotId,
+                getSubscriptionFromSlot(slotId)), UserCapabilityExchangeImpl.class);
+        c.connect();
+        return c;
+    }
+
+    private int getSubscriptionFromSlot(int slotId) {
+        SubscriptionManager manager = mContext.getSystemService(SubscriptionManager.class);
+        if (manager == null) {
+            Log.w(LOG_TAG, "Couldn't find SubscriptionManager for slotId=" + slotId);
+            return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
         }
+        int[] subIds = manager.getSubscriptionIds(slotId);
+        if (subIds != null && subIds.length > 0) {
+            return subIds[0];
+        }
+        return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+    }
+
+    /**
+     * Dump this instance into a readable format for dumpsys usage.
+     */
+    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
+        pw.println("RcsFeatureControllers:");
+        pw.increaseIndent();
+        synchronized (mLock) {
+            for (RcsFeatureController f : mFeatureControllers) {
+                pw.increaseIndent();
+                f.dump(fd, printWriter, args);
+                pw.decreaseIndent();
+            }
+        }
+        pw.decreaseIndent();
     }
 }
diff --git a/src/com/android/services/telephony/rcs/UserCapabilityExchangeImpl.java b/src/com/android/services/telephony/rcs/UserCapabilityExchangeImpl.java
new file mode 100644
index 0000000..7521205
--- /dev/null
+++ b/src/com/android/services/telephony/rcs/UserCapabilityExchangeImpl.java
@@ -0,0 +1,275 @@
+/*
+ * 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.os.RemoteException;
+import android.telephony.ims.RcsContactUceCapability;
+import android.telephony.ims.RcsUceAdapter;
+import android.telephony.ims.aidl.IRcsUceControllerCallback;
+import android.util.Log;
+
+import com.android.ims.RcsFeatureManager;
+import com.android.ims.ResultCode;
+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.util.List;
+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 = "UserCapabilityExchangeImpl";
+
+    private int mSlotId;
+    private int mSubId;
+
+    private final PresencePublication mPresencePublication;
+    private final PresenceSubscriber mPresenceSubscriber;
+
+    private final ConcurrentHashMap<Integer, IRcsUceControllerCallback> mPendingCapabilityRequests =
+            new ConcurrentHashMap<>();
+
+    UserCapabilityExchangeImpl(Context context, int slotId, int subId) {
+        mSlotId = slotId;
+        mSubId = subId;
+
+        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);
+    }
+
+
+    // Runs on main thread.
+    @Override
+    public void onRcsConnected(RcsFeatureManager rcsFeatureManager) {
+        Log.i(LOG_TAG, "onRcsConnected: slotId=" + mSlotId + ", subId=" + mSubId);
+        mPresencePublication.updatePresencePublisher(this);
+        mPresenceSubscriber.updatePresenceSubscriber(this);
+    }
+
+    // Runs on main thread.
+    @Override
+    public void onRcsDisconnected() {
+        Log.i(LOG_TAG, "onRcsDisconnected: phoneId=" + mSlotId + ", subId=" + mSubId);
+        mPresencePublication.removePresencePublisher();
+        mPresenceSubscriber.removePresenceSubscriber();
+    }
+
+    // Runs on main thread.
+    @Override
+    public void onAssociatedSubscriptionUpdated(int 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() {
+        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);
+    }
+
+    /**
+     * 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) {
+                        Log.i(LOG_TAG, "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 {
+                                Log.w(LOG_TAG, "onError called for unknown reqId:" + reqId);
+                            }
+                        } catch (RemoteException e) {
+                            Log.i(LOG_TAG, "Calling back to dead service");
+                        }
+                    }
+
+                    @Override
+                    public void onFinish(int reqId) {
+                        Log.i(LOG_TAG, "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 {
+                                Log.w(LOG_TAG, "onTimeout called for unknown reqId:" + reqId);
+                            }
+                        } catch (RemoteException e) {
+                            Log.i(LOG_TAG, "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 {
+                                Log.w(LOG_TAG, "onCapabilitiesUpdated, unknown reqId:" + reqId);
+                            }
+                        } catch (RemoteException e) {
+                            Log.w(LOG_TAG, "onCapabilitiesUpdated on dead service");
+                        }
+                    }
+                });
+        if (taskId < 0) {
+            try {
+                c.onError(toUceError(taskId));
+                return;
+            } catch (RemoteException e) {
+                Log.i(LOG_TAG, "Calling back to dead service");
+            }
+        }
+        mPendingCapabilityRequests.put(taskId, c);
+    }
+
+    @Override
+    public int getPublisherState() {
+        return 0;
+    }
+
+    @Override
+    public int requestPublication(RcsContactUceCapability capabilities, String contactUri,
+            int taskId) {
+        return 0;
+    }
+
+    @Override
+    public int requestCapability(String[] formatedContacts, int taskId) {
+        return 0;
+    }
+
+    @Override
+    public int requestAvailability(String formattedContact, int taskId) {
+        return 0;
+    }
+
+    @Override
+    public int getStackStatusForCapabilityRequest() {
+        return 0;
+    }
+
+    @Override
+    public void updatePublisherState(int publishState) {
+
+    }
+
+    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_200_OK;
+            case PresenceBase.PUBLISH_STATE_NOT_PUBLISHED:
+                return RcsUceAdapter.PUBLISH_STATE_NOT_PUBLISHED;
+            case PresenceBase.PUBLISH_STATE_VOLTE_PROVISION_ERROR:
+                return RcsUceAdapter.PUBLISH_STATE_VOLTE_PROVISION_ERROR;
+            case PresenceBase.PUBLISH_STATE_RCS_PROVISION_ERROR:
+                return RcsUceAdapter.PUBLISH_STATE_RCS_PROVISION_ERROR;
+            case PresenceBase.PUBLISH_STATE_REQUEST_TIMEOUT:
+                return RcsUceAdapter.PUBLISH_STATE_REQUEST_TIMEOUT;
+            case PresenceBase.PUBLISH_STATE_OTHER_ERROR:
+                return RcsUceAdapter.PUBLISH_STATE_OTHER_ERROR;
+            default:
+                return RcsUceAdapter.PUBLISH_STATE_OTHER_ERROR;
+        }
+    }
+
+    private static int toUceError(int resultCode) {
+        switch (resultCode) {
+            case ResultCode.SUBSCRIBE_NOT_REGISTERED:
+                return RcsUceAdapter.ERROR_NOT_REGISTERED;
+            case ResultCode.SUBSCRIBE_REQUEST_TIMEOUT:
+                return RcsUceAdapter.ERROR_REQUEST_TIMEOUT;
+            case ResultCode.SUBSCRIBE_FORBIDDEN:
+                return RcsUceAdapter.ERROR_FORBIDDEN;
+            case ResultCode.SUBSCRIBE_NOT_FOUND:
+                return RcsUceAdapter.ERROR_NOT_FOUND;
+            case ResultCode.SUBSCRIBE_TOO_LARGE:
+                return RcsUceAdapter.ERROR_REQUEST_TOO_LARGE;
+            case ResultCode.SUBSCRIBE_INSUFFICIENT_MEMORY:
+                return RcsUceAdapter.ERROR_INSUFFICIENT_MEMORY;
+            case ResultCode.SUBSCRIBE_LOST_NETWORK:
+                return RcsUceAdapter.ERROR_LOST_NETWORK;
+            case ResultCode.SUBSCRIBE_ALREADY_IN_QUEUE:
+                return RcsUceAdapter.ERROR_ALREADY_IN_QUEUE;
+            default:
+                return RcsUceAdapter.ERROR_GENERIC_FAILURE;
+        }
+    }
+}
