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;
-    }
-}
