diff --git a/res/values/config.xml b/res/values/config.xml
index f69120f..e6c578a 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -303,4 +303,7 @@
         by millisecond. -1 - no release, 0 - release immediately,
         positive n - release in n milliseconds -->
     <integer name="config_gba_release_time">0</integer>
+
+    <!-- Whether or not to support RCS VoLTE single registration  -->
+    <bool name="config_rcsVolteSingleRegistrationEnabled">true</bool>
 </resources>
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 509aa57..ce8e9b3 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -360,6 +360,7 @@
                         defaultImsRcsPackage, PhoneFactory.getPhones().length,
                         new ImsFeatureBinderRepository());
                 mImsResolver.initialize();
+                RcsProvisioningMonitor.make(this);
             }
 
             // Start TelephonyDebugService After the default phone is created.
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 1fcf3b6..796efd0 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -107,12 +107,14 @@
 import android.telephony.gba.UaSecurityProtocolIdentifier;
 import android.telephony.ims.ImsException;
 import android.telephony.ims.ProvisioningManager;
+import android.telephony.ims.RcsClientConfiguration;
 import android.telephony.ims.RegistrationManager;
 import android.telephony.ims.aidl.IImsCapabilityCallback;
 import android.telephony.ims.aidl.IImsConfig;
 import android.telephony.ims.aidl.IImsConfigCallback;
 import android.telephony.ims.aidl.IImsRegistration;
 import android.telephony.ims.aidl.IImsRegistrationCallback;
+import android.telephony.ims.aidl.IRcsConfigCallback;
 import android.telephony.ims.feature.ImsFeature;
 import android.telephony.ims.feature.MmTelFeature;
 import android.telephony.ims.feature.RcsFeature;
@@ -9063,15 +9065,19 @@
             isCompressed) {
         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
                 mApp, subId, "notifyRcsAutoConfigurationReceived");
+        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
+            throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
+        }
+        if (!isImsAvailableOnDevice()) {
+            throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
+                    "IMS not available on device.");
+        }
+
+        final long identity = Binder.clearCallingIdentity();
         try {
-            IImsConfig configBinder = getImsConfig(getSlotIndex(subId), ImsFeature.FEATURE_RCS);
-            if (configBinder == null) {
-                Rlog.e(LOG_TAG, "null result for getImsConfig");
-            } else {
-                configBinder.notifyRcsAutoConfigurationReceived(config, isCompressed);
-            }
-        } catch (RemoteException e) {
-            Rlog.e(LOG_TAG, "fail to getImsConfig " + e.getMessage());
+            RcsProvisioningMonitor.getInstance().updateConfig(subId, config, isCompressed);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
         }
     }
 
@@ -9497,4 +9503,184 @@
         }
         return instance;
     }
+
+    /**
+     * indicate whether the device and the carrier can support
+     * RCS VoLTE single registration.
+     */
+    @Override
+    public boolean isRcsVolteSingleRegistrationCapable(int subId) {
+        enforceReadPrivilegedPermission("isRcsVolteSingleRegistrationCapable");
+
+        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
+            throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
+        }
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            RcsProvisioningMonitor rpm = RcsProvisioningMonitor.getInstance();
+            if (rpm != null) {
+                return rpm.isRcsVolteSingleRegistrationEnabled(subId);
+            }
+            return false;
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    /**
+     * Register RCS provisioning callback.
+     */
+    @Override
+    public void registerRcsProvisioningChangedCallback(int subId,
+            IRcsConfigCallback callback) {
+        enforceReadPrivilegedPermission("registerRcsProvisioningChangedCallback");
+
+        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
+            throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
+        }
+        if (!isImsAvailableOnDevice()) {
+            throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
+                    "IMS not available on device.");
+        }
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
+                    .addRcsProvisioningCallbackForSubscription(callback, subId);
+        } catch (ImsException e) {
+            throw new ServiceSpecificException(e.getCode());
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    /**
+     * Unregister RCS provisioning callback.
+     */
+    @Override
+    public void unregisterRcsProvisioningChangedCallback(int subId,
+            IRcsConfigCallback callback) {
+        enforceReadPrivilegedPermission("unregisterRcsProvisioningChangedCallback");
+
+        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
+            throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
+        }
+        if (!isImsAvailableOnDevice()) {
+            throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
+                    "IMS not available on device.");
+        }
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
+                    .removeRcsProvisioningCallbackForSubscription(callback, subId);
+        } catch (ImsException e) {
+            Log.i(LOG_TAG, "unregisterRcsProvisioningChangedCallback: " + subId
+                    + "is inactive, ignoring unregister.");
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    /**
+     * trigger RCS reconfiguration.
+     */
+    public void triggerRcsReconfiguration(int subId) {
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "triggerRcsReconfiguration");
+
+        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
+            throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
+        }
+        if (!isImsAvailableOnDevice()) {
+            throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
+                    "IMS not available on device.");
+        }
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            RcsProvisioningMonitor.getInstance().requestReconfig(subId);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    /**
+     * Provide the client configuration parameters of the RCS application.
+     */
+    public void setRcsClientConfiguration(int subId, RcsClientConfiguration rcc) {
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "setRcsClientConfiguration");
+
+        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
+            throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
+        }
+        if (!isImsAvailableOnDevice()) {
+            throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
+                    "IMS not available on device.");
+        }
+
+        final long identity = Binder.clearCallingIdentity();
+
+        try {
+            IImsConfig configBinder = getImsConfig(getSlotIndex(subId), ImsFeature.FEATURE_RCS);
+            if (configBinder == null) {
+                Rlog.e(LOG_TAG, "null result for setRcsClientConfiguration");
+            } else {
+                configBinder.setRcsClientConfiguration(rcc);
+            }
+        } catch (RemoteException e) {
+            Rlog.e(LOG_TAG, "fail to setRcsClientConfiguration " + e.getMessage());
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    /**
+     * Overrides the config of RCS VoLTE single registration enabled for the device.
+     */
+    @Override
+    public void setDeviceSingleRegistrationEnabledOverride(String enabledStr) {
+        TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
+                "setDeviceSingleRegistrationEnabledOverride");
+        enforceModifyPermission();
+
+        Boolean enabled = "NULL".equalsIgnoreCase(enabledStr) ? null
+                : Boolean.parseBoolean(enabledStr);
+        RcsProvisioningMonitor.getInstance().overrideDeviceSingleRegistrationEnabled(enabled);
+    }
+
+    /**
+     * Gets the config of RCS VoLTE single registration enabled for the device.
+     */
+    @Override
+    public boolean getDeviceSingleRegistrationEnabled() {
+        enforceReadPrivilegedPermission("getDeviceSingleRegistrationEnabled");
+        return RcsProvisioningMonitor.getInstance().getDeviceSingleRegistrationEnabled();
+    }
+
+    /**
+     * Overrides the config of RCS VoLTE single registration enabled for the carrier/subscription.
+     */
+    @Override
+    public boolean setCarrierSingleRegistrationEnabledOverride(int subId, String enabledStr) {
+        TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
+                "setCarrierSingleRegistrationEnabledOverride");
+        enforceModifyPermission();
+
+        Boolean enabled = "NULL".equalsIgnoreCase(enabledStr) ? null
+                : Boolean.parseBoolean(enabledStr);
+        return RcsProvisioningMonitor.getInstance().overrideCarrierSingleRegistrationEnabled(
+                subId, enabled);
+    }
+
+    /**
+     * Gets the config of RCS VoLTE single registration enabled for the carrier/subscription.
+     */
+    @Override
+    public boolean getCarrierSingleRegistrationEnabled(int subId) {
+        enforceReadPrivilegedPermission("getCarrierSingleRegistrationEnabled");
+        return RcsProvisioningMonitor.getInstance().getCarrierSingleRegistrationEnabled(subId);
+    }
 }
diff --git a/src/com/android/phone/RcsProvisioningMonitor.java b/src/com/android/phone/RcsProvisioningMonitor.java
new file mode 100644
index 0000000..8e4d35e
--- /dev/null
+++ b/src/com/android/phone/RcsProvisioningMonitor.java
@@ -0,0 +1,514 @@
+/*
+ * Copyright 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.phone;
+
+import android.app.role.OnRoleHoldersChangedListener;
+import android.app.role.RoleManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Build;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.PersistableBundle;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyRegistryManager;
+import android.telephony.ims.ProvisioningManager;
+import android.telephony.ims.RcsConfig;
+import android.telephony.ims.aidl.IImsConfig;
+import android.telephony.ims.feature.ImsFeature;
+import android.text.TextUtils;
+
+import com.android.ims.ImsManager;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.CollectionUtils;
+import com.android.telephony.Rlog;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Class to monitor RCS Provisioning Status
+ */
+public class RcsProvisioningMonitor {
+    private static final String TAG = "RcsProvisioningMonitor";
+    private static final boolean DBG = Build.IS_ENG;
+
+    private static final int EVENT_SUB_CHANGED = 1;
+    private static final int EVENT_DMA_CHANGED = 2;
+    private static final int EVENT_CC_CHANGED  = 3;
+    private static final int EVENT_CONFIG_RECEIVED = 4;
+    private static final int EVENT_RECONFIG_REQUEST = 5;
+    private static final int EVENT_DEVICE_CONFIG_OVERRIDE = 6;
+    private static final int EVENT_CARRIER_CONFIG_OVERRIDE = 7;
+
+    private final PhoneGlobals mPhone;
+    private final Handler mHandler;
+    //cache the rcs config per sub id
+    private final Map<Integer, byte[]> mConfigs = Collections.synchronizedMap(new HashMap<>());
+    //cache the single registration config per sub id
+    private final ConcurrentHashMap<Integer, Integer> mSingleRegistrations =
+            new ConcurrentHashMap<>();
+    private Boolean mDeviceSingleRegistrationEnabledOverride;
+    private final HashMap<Integer, Boolean> mCarrierSingleRegistrationEnabledOverride =
+            new HashMap<>();
+    private String mDmaPackageName;
+
+    private final CarrierConfigManager mCarrierConfigManager;
+    private final DmaChangedListener mDmaChangedListener;
+    private final SubscriptionManager mSubscriptionManager;
+    private final TelephonyRegistryManager mTelephonyRegistryManager;
+
+    private static RcsProvisioningMonitor sInstance;
+
+    private final SubscriptionManager.OnSubscriptionsChangedListener mSubChangedListener =
+            new SubscriptionManager.OnSubscriptionsChangedListener() {
+        @Override
+        public void onSubscriptionsChanged() {
+            if (!mHandler.hasMessages(EVENT_SUB_CHANGED)) {
+                mHandler.sendEmptyMessage(EVENT_SUB_CHANGED);
+            }
+        }
+    };
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(
+                    intent.getAction())) {
+                int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
+                        SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+                logv("Carrier-config changed for sub : " + subId);
+                if (SubscriptionManager.isValidSubscriptionId(subId)
+                        && !mHandler.hasMessages(EVENT_CC_CHANGED)) {
+                    mHandler.sendEmptyMessage(EVENT_CC_CHANGED);
+                }
+            }
+        }
+    };
+
+    private final class DmaChangedListener implements OnRoleHoldersChangedListener {
+        private RoleManager mRoleManager;
+
+        @Override
+        public void onRoleHoldersChanged(String role, UserHandle user) {
+            if (RoleManager.ROLE_SMS.equals(role)) {
+                logv("default messaging application changed.");
+                String packageName = getDmaPackageName();
+                mHandler.sendEmptyMessage(EVENT_DMA_CHANGED);
+            }
+        }
+
+        public void register() {
+            mRoleManager = mPhone.getSystemService(RoleManager.class);
+            if (mRoleManager != null) {
+                try {
+                    mRoleManager.addOnRoleHoldersChangedListenerAsUser(
+                            mPhone.getMainExecutor(), this, UserHandle.SYSTEM);
+                } catch (RuntimeException e) {
+                    loge("Could not register dma change listener due to " + e);
+                }
+            }
+        }
+
+        public void unregister() {
+            if (mRoleManager != null) {
+                try {
+                    mRoleManager.removeOnRoleHoldersChangedListenerAsUser(this, UserHandle.SYSTEM);
+                } catch (RuntimeException e) {
+                    loge("Could not unregister dma change listener due to " + e);
+                }
+            }
+        }
+    }
+
+    private final class MyHandler extends Handler {
+        MyHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case EVENT_SUB_CHANGED:
+                    onSubChanged();
+                    break;
+                case EVENT_DMA_CHANGED:
+                    onDefaultMessagingApplicationChanged();
+                    break;
+                case EVENT_CC_CHANGED:
+                    onCarrierConfigChange();
+                    break;
+                case EVENT_CONFIG_RECEIVED:
+                    onConfigReceived(msg.arg1, (byte[]) msg.obj, msg.arg2 == 1);
+                    break;
+                case EVENT_RECONFIG_REQUEST:
+                    onReconfigRequest(msg.arg1);
+                    break;
+                case EVENT_DEVICE_CONFIG_OVERRIDE:
+                    Boolean deviceEnabled = (Boolean) msg.obj;
+                    if (!booleanEquals(deviceEnabled, mDeviceSingleRegistrationEnabledOverride)) {
+                        mDeviceSingleRegistrationEnabledOverride = deviceEnabled;
+                        onCarrierConfigChange();
+                    }
+                    break;
+                case EVENT_CARRIER_CONFIG_OVERRIDE:
+                    Boolean carrierEnabledOverride = (Boolean) msg.obj;
+                    Boolean carrierEnabled = mCarrierSingleRegistrationEnabledOverride.put(
+                            msg.arg1, carrierEnabledOverride);
+                    if (!booleanEquals(carrierEnabledOverride, carrierEnabled)) {
+                        onCarrierConfigChange();
+                    }
+                    break;
+                default:
+                    loge("Unhandled event " + msg.what);
+            }
+        }
+    }
+
+    @VisibleForTesting
+    public RcsProvisioningMonitor(PhoneGlobals app, Looper looper) {
+        mPhone = app;
+        mHandler = new MyHandler(looper);
+        mCarrierConfigManager = mPhone.getSystemService(CarrierConfigManager.class);
+        mSubscriptionManager = mPhone.getSystemService(SubscriptionManager.class);
+        mTelephonyRegistryManager = mPhone.getSystemService(TelephonyRegistryManager.class);
+        mDmaPackageName = getDmaPackageName();
+        logv("DMA is " + mDmaPackageName);
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+        mPhone.registerReceiver(mReceiver, filter);
+        mTelephonyRegistryManager.addOnSubscriptionsChangedListener(
+                mSubChangedListener, mSubChangedListener.getHandlerExecutor());
+        mDmaChangedListener = new DmaChangedListener();
+        mDmaChangedListener.register();
+        //initialize configs for all active sub
+        onSubChanged();
+    }
+
+    /**
+     * create an instance
+     */
+    public static RcsProvisioningMonitor make(PhoneGlobals app) {
+        if (sInstance == null) {
+            logd("RcsProvisioningMonitor created.");
+            HandlerThread handlerThread = new HandlerThread(TAG);
+            handlerThread.start();
+            sInstance = new RcsProvisioningMonitor(app, handlerThread.getLooper());
+        }
+        return sInstance;
+    }
+
+    /**
+     * get the instance
+     */
+    public static RcsProvisioningMonitor getInstance() {
+        return sInstance;
+    }
+
+    /**
+     * destroy the instance
+     */
+    @VisibleForTesting
+    public void destroy() {
+        logd("destroy it.");
+        mDmaChangedListener.unregister();
+        mTelephonyRegistryManager.removeOnSubscriptionsChangedListener(mSubChangedListener);
+        mPhone.unregisterReceiver(mReceiver);
+        mHandler.getLooper().quit();
+    }
+
+    /**
+     * get the handler
+     */
+    @VisibleForTesting
+    public Handler getHandler() {
+        return mHandler;
+    }
+
+    /**
+     * Gets the config for a subscription
+     */
+    @VisibleForTesting
+    public byte[] getConfig(int subId) {
+        return mConfigs.get(subId);
+    }
+
+    /**
+     * Returns whether Rcs Volte single registration is enabled for the sub.
+     */
+    public boolean isRcsVolteSingleRegistrationEnabled(int subId) {
+        if (mSingleRegistrations.containsKey(subId)) {
+            return mSingleRegistrations.get(subId) == ProvisioningManager.STATUS_CAPABLE;
+        }
+        return false;
+    }
+
+    /**
+     * Called when the new rcs config is received
+     */
+    public void updateConfig(int subId, byte[] config, boolean isCompressed) {
+        mHandler.sendMessage(mHandler.obtainMessage(
+                EVENT_CONFIG_RECEIVED, subId, isCompressed ? 1 : 0, config));
+    }
+
+    /**
+     * Called when the application needs rcs re-config
+     */
+    public void requestReconfig(int subId) {
+        mHandler.sendMessage(mHandler.obtainMessage(EVENT_RECONFIG_REQUEST, subId, 0));
+    }
+
+    /**
+     * override the device config whether single registration is enabled
+     */
+    public void overrideDeviceSingleRegistrationEnabled(Boolean enabled) {
+        mHandler.sendMessage(mHandler.obtainMessage(EVENT_DEVICE_CONFIG_OVERRIDE, enabled));
+    }
+
+    /**
+     * Overrides the carrier config whether single registration is enabled
+     */
+    public boolean overrideCarrierSingleRegistrationEnabled(int subId, Boolean enabled) {
+        if (!mSingleRegistrations.containsKey(subId)) {
+            return false;
+        }
+        mHandler.sendMessage(mHandler.obtainMessage(
+                EVENT_CARRIER_CONFIG_OVERRIDE, subId, 0, enabled));
+        return true;
+    }
+
+    /**
+     * Returns the device config whether single registration is enabled
+     */
+    public boolean getDeviceSingleRegistrationEnabled() {
+        for (int val : mSingleRegistrations.values()) {
+            return (val & ProvisioningManager.STATUS_DEVICE_NOT_CAPABLE) == 0;
+        }
+        return false;
+    }
+
+    /**
+     * Returns the carrier config whether single registration is enabled
+     */
+    public boolean getCarrierSingleRegistrationEnabled(int subId) {
+        if (mSingleRegistrations.containsKey(subId)) {
+            return (mSingleRegistrations.get(subId)
+                    & ProvisioningManager.STATUS_CARRIER_NOT_CAPABLE) == 0;
+        }
+        return false;
+    }
+
+    private void onDefaultMessagingApplicationChanged() {
+        final String packageName = getDmaPackageName();
+        if (!TextUtils.equals(mDmaPackageName, packageName)) {
+            //clear old callbacks
+            ImsManager.getInstance(mPhone, mPhone.getPhone().getPhoneId())
+                    .clearRcsProvisioningCallbacks();
+            mDmaPackageName = packageName;
+            logv("new default messaging application " + mDmaPackageName);
+            mConfigs.forEach((k, v) -> {
+                if (isAcsUsed(k)) {
+                    logv("acs used, trigger to re-configure.");
+                    notifyRcsAutoConfigurationRemoved(k);
+                    triggerRcsReconfiguration(k);
+                } else {
+                    logv("acs not used, notify.");
+                    notifyRcsAutoConfigurationReceived(k, v, false);
+                }
+            });
+        }
+    }
+
+    private void notifyRcsAutoConfigurationReceived(int subId, byte[] config,
+            boolean isCompressed) {
+        IImsConfig imsConfig = getIImsConfig(subId, ImsFeature.FEATURE_RCS);
+        if (imsConfig != null) {
+            try {
+                imsConfig.notifyRcsAutoConfigurationReceived(config, isCompressed);
+            } catch (RemoteException e) {
+                loge("fail to notify rcs configuration received!");
+            }
+        } else {
+            logd("getIImsConfig returns null.");
+        }
+    }
+
+    private void notifyRcsAutoConfigurationRemoved(int subId) {
+        IImsConfig imsConfig = getIImsConfig(subId, ImsFeature.FEATURE_RCS);
+        if (imsConfig != null) {
+            try {
+                imsConfig.notifyRcsAutoConfigurationRemoved();
+            } catch (RemoteException e) {
+                loge("fail to notify rcs configuration removed!");
+            }
+        } else {
+            logd("getIImsConfig returns null.");
+        }
+    }
+
+    private void triggerRcsReconfiguration(int subId) {
+        IImsConfig imsConfig = getIImsConfig(subId, ImsFeature.FEATURE_RCS);
+        if (imsConfig != null) {
+            try {
+                imsConfig.triggerRcsReconfiguration();
+            } catch (RemoteException e) {
+                loge("fail to trigger rcs reconfiguration!");
+            }
+        } else {
+            logd("getIImsConfig returns null.");
+        }
+    }
+
+    private boolean isAcsUsed(int subId) {
+        PersistableBundle b = mCarrierConfigManager.getConfigForSubId(subId);
+        if (b == null) {
+            return false;
+        }
+        return b.getBoolean(CarrierConfigManager.KEY_USE_ACS_FOR_RCS_BOOL);
+    }
+
+    private boolean isSingleRegistrationRequiredByCarrier(int subId) {
+        Boolean enabledByOverride = mCarrierSingleRegistrationEnabledOverride.get(subId);
+        if (enabledByOverride != null) {
+            return enabledByOverride;
+        }
+
+        PersistableBundle b = mCarrierConfigManager.getConfigForSubId(subId);
+        if (b == null) {
+            return false;
+        }
+        return b.getBoolean(CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL);
+    }
+
+    private int getSingleRegistrationCapableValue(int subId) {
+        boolean isSingleRegistrationEnabledOnDevice =
+                mDeviceSingleRegistrationEnabledOverride != null
+                ? mDeviceSingleRegistrationEnabledOverride
+                : mPhone.getResources().getBoolean(R.bool.config_rcsVolteSingleRegistrationEnabled);
+
+        int value = (isSingleRegistrationEnabledOnDevice ? 0
+                : ProvisioningManager.STATUS_DEVICE_NOT_CAPABLE) | (
+                isSingleRegistrationRequiredByCarrier(subId) ? 0
+                : ProvisioningManager.STATUS_CARRIER_NOT_CAPABLE);
+        logv("SingleRegistrationCapableValue : " + value);
+        return value;
+    }
+
+    private void onCarrierConfigChange() {
+        logv("onCarrierConfigChange");
+        mConfigs.forEach((subId, config) -> {
+            int value = getSingleRegistrationCapableValue(subId);
+            if (value != mSingleRegistrations.get(subId)) {
+                mSingleRegistrations.put(subId, value);
+                notifyDmaForSub(subId);
+            }
+        });
+    }
+
+    private void onSubChanged() {
+        final int[] activeSubs = mSubscriptionManager.getActiveSubscriptionIdList();
+        final HashSet<Integer> subsToBeDeactivated = new HashSet<>(mConfigs.keySet());
+
+        for (int i : activeSubs) {
+            subsToBeDeactivated.remove(i);
+            if (!mConfigs.containsKey(i)) {
+                byte[] data = RcsConfig.loadRcsConfigForSub(mPhone, i, false);
+                logv("new config is created for sub : " + i);
+                mConfigs.put(i, data);
+                notifyRcsAutoConfigurationReceived(i, data, false);
+                mSingleRegistrations.put(i, getSingleRegistrationCapableValue(i));
+                notifyDmaForSub(i);
+            }
+        }
+
+        subsToBeDeactivated.forEach(i -> {
+            mConfigs.remove(i);
+            notifyRcsAutoConfigurationRemoved(i);
+        });
+    }
+
+    private void onConfigReceived(int subId, byte[] config, boolean isCompressed) {
+        logv("onConfigReceived, subId:" + subId + ", config:"
+                + config + ", isCompressed:" + isCompressed);
+        mConfigs.put(subId, isCompressed ? RcsConfig.decompressGzip(config) : config);
+        RcsConfig.updateConfigForSub(mPhone, subId, config, isCompressed);
+        notifyRcsAutoConfigurationReceived(subId, config, isCompressed);
+    }
+
+    private void onReconfigRequest(int subId) {
+        logv("onReconfigRequest, subId:" + subId);
+        mConfigs.remove(subId);
+        RcsConfig.updateConfigForSub(mPhone, subId, null, true);
+        notifyRcsAutoConfigurationRemoved(subId);
+        triggerRcsReconfiguration(subId);
+    }
+
+    private void notifyDmaForSub(int subId) {
+        final Intent intent = new Intent(
+                ProvisioningManager.ACTION_RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE);
+        intent.setPackage(mDmaPackageName);
+        intent.putExtra(ProvisioningManager.EXTRA_SUBSCRIPTION_ID, subId);
+        intent.putExtra(ProvisioningManager.EXTRA_STATUS, mSingleRegistrations.get(subId));
+        logv("notify " + intent);
+        mPhone.sendBroadcast(intent);
+    }
+
+    private IImsConfig getIImsConfig(int subId, int feature) {
+        return mPhone.getImsResolver().getImsConfig(
+                SubscriptionManager.getSlotIndex(subId), feature);
+    }
+
+    private String getDmaPackageName() {
+        try {
+            return CollectionUtils.firstOrNull(mPhone.getSystemService(RoleManager.class)
+                    .getRoleHolders(RoleManager.ROLE_SMS));
+        } catch (RuntimeException e) {
+            loge("Could not get dma name due to " + e);
+            return null;
+        }
+    }
+
+    private static boolean booleanEquals(Boolean val1, Boolean val2) {
+        return (val1 == null && val2 == null)
+                || (Boolean.TRUE.equals(val1) && Boolean.TRUE.equals(val2))
+                || (Boolean.FALSE.equals(val1) && Boolean.FALSE.equals(val2));
+    }
+
+    private static void logv(String msg) {
+        if (DBG) {
+            Rlog.d(TAG, msg);
+        }
+    }
+
+    private static void logd(String msg) {
+        Rlog.d(TAG, msg);
+    }
+
+    private static void loge(String msg) {
+        Rlog.e(TAG, msg);
+    }
+}
diff --git a/src/com/android/phone/TelephonyShellCommand.java b/src/com/android/phone/TelephonyShellCommand.java
index 8d67092..ed719b6 100644
--- a/src/com/android/phone/TelephonyShellCommand.java
+++ b/src/com/android/phone/TelephonyShellCommand.java
@@ -87,6 +87,12 @@
     private static final String GBA_SET_RELEASE_TIME = "set-release";
     private static final String GBA_GET_RELEASE_TIME = "get-release";
 
+    private static final String SINGLE_REGISTATION_CONFIG = "src";
+    private static final String SRC_SET_DEVICE_ENABLED = "set-device-enabled";
+    private static final String SRC_GET_DEVICE_ENABLED = "get-device-enabled";
+    private static final String SRC_SET_CARRIER_ENABLED = "set-carrier-enabled";
+    private static final String SRC_GET_CARRIER_ENABLED = "get-carrier-enabled";
+
     // Take advantage of existing methods that already contain permissions checks when possible.
     private final ITelephony mInterface;
 
@@ -169,6 +175,8 @@
                 return handleEndBlockSuppressionCommand();
             case GBA_SUBCOMMAND:
                 return handleGbaCommand();
+            case SINGLE_REGISTATION_CONFIG:
+                return handleSingleRegistrationConfigCommand();
             default: {
                 return handleDefaultCommands(cmd);
             }
@@ -193,12 +201,15 @@
         pw.println("    Carrier Config Commands.");
         pw.println("  gba");
         pw.println("    GBA Commands.");
+        pw.println("  src");
+        pw.println("    RCS VoLTE Single Registration Config Commands.");
         onHelpIms();
         onHelpEmergencyNumber();
         onHelpEndBlockSupperssion();
         onHelpDataTestMode();
         onHelpCc();
         onHelpGba();
+        onHelpSrc();
     }
 
     private void onHelpIms() {
@@ -330,6 +341,27 @@
         pw.println("          is specified, it will choose the default voice SIM slot.");
     }
 
+    private void onHelpSrc() {
+        PrintWriter pw = getOutPrintWriter();
+        pw.println("RCS VoLTE Single Registration Config Commands:");
+        pw.println("  src set-device-enabled true|false|null");
+        pw.println("    Sets the device config for RCS VoLTE single registration to the value.");
+        pw.println("    The value could be true, false, or null(undefined).");
+        pw.println("  src get-device-enabled");
+        pw.println("    Gets the device config for RCS VoLTE single registration.");
+        pw.println("  src set-carrier-enabled [-s SLOT_ID] true|false|null");
+        pw.println("    Sets the carrier config for RCS VoLTE single registration to the value.");
+        pw.println("    The value could be true, false, or null(undefined).");
+        pw.println("    Options are:");
+        pw.println("      -s: The SIM slot ID to set the config value for. If no option");
+        pw.println("          is specified, it will choose the default voice SIM slot.");
+        pw.println("  src get-carrier-enabled [-s SLOT_ID]");
+        pw.println("    Gets the carrier config for RCS VoLTE single registration.");
+        pw.println("    Options are:");
+        pw.println("      -s: The SIM slot ID to read the config value for. If no option");
+        pw.println("          is specified, it will choose the default voice SIM slot.");
+    }
+
     private int handleImsCommand() {
         String arg = getNextArg();
         if (arg == null) {
@@ -1418,4 +1450,112 @@
         getOutPrintWriter().println(result);
         return 0;
     }
+
+    private int handleSingleRegistrationConfigCommand() {
+        String arg = getNextArg();
+        if (arg == null) {
+            onHelpSrc();
+            return 0;
+        }
+
+        switch (arg) {
+            case SRC_SET_DEVICE_ENABLED: {
+                return handleSrcSetDeviceEnabledCommand();
+            }
+            case SRC_GET_DEVICE_ENABLED: {
+                return handleSrcGetDeviceEnabledCommand();
+            }
+            case SRC_SET_CARRIER_ENABLED: {
+                return handleSrcSetCarrierEnabledCommand();
+            }
+            case SRC_GET_CARRIER_ENABLED: {
+                return handleSrcGetCarrierEnabledCommand();
+            }
+        }
+
+        return -1;
+    }
+
+    private int handleSrcSetDeviceEnabledCommand() {
+        String enabledStr = getNextArg();
+        if (enabledStr == null) {
+            return -1;
+        }
+
+        try {
+            mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
+            if (VDBG) {
+                Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
+            }
+            getOutPrintWriter().println("Done");
+        } catch (NumberFormatException | RemoteException e) {
+            Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
+            getErrPrintWriter().println("Exception: " + e.getMessage());
+            return -1;
+        }
+        return 0;
+    }
+
+    private int handleSrcGetDeviceEnabledCommand() {
+        boolean result = false;
+        try {
+            result = mInterface.getDeviceSingleRegistrationEnabled();
+        } catch (RemoteException e) {
+            return -1;
+        }
+        if (VDBG) {
+            Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
+        }
+        getOutPrintWriter().println(result);
+        return 0;
+    }
+
+    private int handleSrcSetCarrierEnabledCommand() {
+        //the release time value could be -1
+        int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
+                : SubscriptionManager.getDefaultSubscriptionId();
+        if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            return -1;
+        }
+
+        String enabledStr = getNextArg();
+        if (enabledStr == null) {
+            return -1;
+        }
+
+        try {
+            boolean result =
+                    mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
+            if (VDBG) {
+                Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
+                        + enabledStr + ", result=" + result);
+            }
+            getOutPrintWriter().println(result);
+        } catch (NumberFormatException | RemoteException e) {
+            Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
+                    + enabledStr + ", error" + e.getMessage());
+            getErrPrintWriter().println("Exception: " + e.getMessage());
+            return -1;
+        }
+        return 0;
+    }
+
+    private int handleSrcGetCarrierEnabledCommand() {
+        int subId = getSubId("src get-carrier-enabled");
+        if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            return -1;
+        }
+
+        boolean result = false;
+        try {
+            result = mInterface.getCarrierSingleRegistrationEnabled(subId);
+        } catch (RemoteException e) {
+            return -1;
+        }
+        if (VDBG) {
+            Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
+        }
+        getOutPrintWriter().println(result);
+        return 0;
+    }
 }
diff --git a/tests/Android.bp b/tests/Android.bp
index 7ed234e..13c0dc8 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -37,6 +37,7 @@
         "mockito-target-minus-junit4",
         "androidx.test.espresso.core",
         "truth-prebuilt",
+	"testables",
     ],
 
     test_suites: [
diff --git a/tests/src/com/android/phone/RcsProvisioningMonitorTest.java b/tests/src/com/android/phone/RcsProvisioningMonitorTest.java
new file mode 100644
index 0000000..7ef9768
--- /dev/null
+++ b/tests/src/com/android/phone/RcsProvisioningMonitorTest.java
@@ -0,0 +1,507 @@
+/*
+ * Copyright 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.phone;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.role.IOnRoleHoldersChangedListener;
+import android.app.role.IRoleManager;
+import android.app.role.RoleManager;
+import android.content.BroadcastReceiver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.os.Looper;
+import android.os.PersistableBundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.provider.Telephony.SimInfo;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyRegistryManager;
+import android.telephony.ims.ProvisioningManager;
+import android.telephony.ims.RcsConfig;
+import android.telephony.ims.aidl.IImsConfig;
+import android.telephony.ims.feature.ImsFeature;
+import android.test.mock.MockContentProvider;
+import android.test.mock.MockContentResolver;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.TestableLooper;
+import android.util.Log;
+
+import com.android.internal.telephony.ITelephony;
+import com.android.internal.telephony.ims.ImsResolver;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.MockitoSession;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executor;
+
+/**
+ * Unit tests for RcsProvisioningMonitor
+ */
+public class RcsProvisioningMonitorTest {
+    private static final String TAG = "RcsProvisioningMonitorTest";
+    private static final String SAMPLE_CONFIG = "<RCSConfig>\n"
+            + "\t<rcsVolteSingleRegistration>1</rcsVolteSingleRegistration>\n"
+            + "\t<SERVICES>\n"
+            + "\t\t<SupportedRCSProfileVersions>UP_2.0</SupportedRCSProfileVersions>\n"
+            + "\t\t<ChatAuth>1</ChatAuth>\n"
+            + "\t\t<GroupChatAuth>1</GroupChatAuth>\n"
+            + "\t\t<ftAuth>1</ftAuth>\n"
+            + "\t\t<standaloneMsgAuth>1</standaloneMsgAuth>\n"
+            + "\t\t<geolocPushAuth>1<geolocPushAuth>\n"
+            + "\t\t<Ext>\n"
+            + "\t\t\t<DataOff>\n"
+            + "\t\t\t\t<rcsMessagingDataOff>1</rcsMessagingDataOff>\n"
+            + "\t\t\t\t<fileTransferDataOff>1</fileTransferDataOff>\n"
+            + "\t\t\t\t<mmsDataOff>1</mmsDataOff>\n"
+            + "\t\t\t\t<syncDataOff>1</syncDataOff>\n"
+            + "\t\t\t</DataOff>\n"
+            + "\t\t</Ext>\n"
+            + "\t</SERVICES>\n"
+            + "</RCSConfig>";
+    private static final int FAKE_SUB_ID_BASE = 0x0FFFFFF0;
+    private static final String DEFAULT_MESSAGING_APP1 = "DMA1";
+    private static final String DEFAULT_MESSAGING_APP2 = "DMA2";
+
+    private MockitoSession mSession;
+    private RcsProvisioningMonitor mRcsProvisioningMonitor;
+    private Handler mHandler;
+    private HandlerThread mHandlerThread;
+    private TestableLooper mLooper;
+    private PersistableBundle mBundle;
+    private MockContentResolver mContentResolver = new MockContentResolver();
+    private SimInfoContentProvider mProvider;
+    private BroadcastReceiver mReceiver;
+    @Mock
+    private Cursor mCursor;
+    @Mock
+    private SubscriptionManager mSubscriptionManager;
+    private SubscriptionManager.OnSubscriptionsChangedListener mSubChangedListener;
+    @Mock
+    private TelephonyRegistryManager mTelephonyRegistryManager;
+    @Mock
+    private CarrierConfigManager mCarrierConfigManager;
+    private IOnRoleHoldersChangedListener.Stub mRoleHolderChangedListener;
+    private RoleManager mRoleManager;
+    @Mock
+    private IRoleManager.Stub mIRoleManager;
+    @Mock
+    private ITelephony.Stub mITelephony;
+    @Mock
+    private ImsResolver mImsResolver;
+    @Mock
+    private IImsConfig.Stub mIImsConfig;
+    @Mock
+    private Resources mResources;
+    @Mock
+    private PhoneGlobals mPhone;
+
+    private Executor mExecutor = new Executor() {
+        @Override
+        public void execute(Runnable r) {
+            r.run();
+        }
+    };
+
+    private class SimInfoContentProvider extends MockContentProvider {
+        private Cursor mCursor;
+
+        SimInfoContentProvider(Context context) {
+            super(context);
+        }
+
+        public void setCursor(Cursor cursor) {
+            mCursor = cursor;
+        }
+
+        @Override
+        public Cursor query(Uri uri, String[] projection, String selection,
+                String[] selectionArgs, String sortOrder) {
+            return mCursor;
+        }
+
+        @Override
+        public int update(Uri uri, ContentValues values,
+                String selection, String[] selectionArgs) {
+            return 1;
+        }
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        replaceService(Context.ROLE_SERVICE, mIRoleManager);
+        mRoleManager = new RoleManager(mPhone);
+        when(mPhone.getResources()).thenReturn(mResources);
+        when(mResources.getBoolean(
+                eq(R.bool.config_rcsVolteSingleRegistrationEnabled))).thenReturn(true);
+        when(mPhone.getMainExecutor()).thenReturn(mExecutor);
+        when(mPhone.getSystemServiceName(eq(CarrierConfigManager.class)))
+                .thenReturn(Context.CARRIER_CONFIG_SERVICE);
+        when(mPhone.getSystemServiceName(eq(SubscriptionManager.class)))
+                .thenReturn(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+        when(mPhone.getSystemServiceName(eq(TelephonyRegistryManager.class)))
+                .thenReturn(Context.TELEPHONY_REGISTRY_SERVICE);
+        when(mPhone.getSystemServiceName(eq(RoleManager.class)))
+                .thenReturn(Context.ROLE_SERVICE);
+        when(mPhone.getSystemService(eq(Context.CARRIER_CONFIG_SERVICE)))
+                .thenReturn(mCarrierConfigManager);
+        when(mPhone.getSystemService(eq(Context.TELEPHONY_SUBSCRIPTION_SERVICE)))
+                .thenReturn(mSubscriptionManager);
+        when(mPhone.getSystemService(eq(Context.TELEPHONY_REGISTRY_SERVICE)))
+                .thenReturn(mTelephonyRegistryManager);
+        when(mPhone.getSystemService(eq(Context.ROLE_SERVICE)))
+                .thenReturn(mRoleManager);
+
+        mBundle = new PersistableBundle();
+        when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mBundle);
+
+        doAnswer(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                mReceiver = (BroadcastReceiver) invocation.getArguments()[0];
+                return null;
+            }
+        }).when(mPhone).registerReceiver(any(BroadcastReceiver.class), any());
+
+        doAnswer(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                mSubChangedListener = (SubscriptionManager.OnSubscriptionsChangedListener)
+                        invocation.getArguments()[0];
+                return null;
+            }
+        }).when(mTelephonyRegistryManager).addOnSubscriptionsChangedListener(
+                any(SubscriptionManager.OnSubscriptionsChangedListener.class),
+                any());
+
+        doAnswer(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                mRoleHolderChangedListener = (IOnRoleHoldersChangedListener.Stub)
+                        invocation.getArguments()[0];
+                return null;
+            }
+        }).when(mIRoleManager).addOnRoleHoldersChangedListenerAsUser(
+                any(IOnRoleHoldersChangedListener.Stub.class), anyInt());
+        List<String> dmas = new ArrayList<>();
+        dmas.add(DEFAULT_MESSAGING_APP1);
+        when(mIRoleManager.getRoleHoldersAsUser(any(), anyInt())).thenReturn(dmas);
+
+        mProvider = new SimInfoContentProvider(mPhone);
+        mProvider.setCursor(mCursor);
+        mContentResolver.addProvider(SimInfo.CONTENT_URI.getAuthority(), mProvider);
+        when(mPhone.getContentResolver()).thenReturn(mContentResolver);
+        when(mCursor.moveToFirst()).thenReturn(true);
+        when(mCursor.getColumnIndexOrThrow(any())).thenReturn(1);
+        when(mCursor.getBlob(anyInt())).thenReturn(
+                RcsConfig.compressGzip(SAMPLE_CONFIG.getBytes()));
+        when(mPhone.getImsResolver()).thenReturn(mImsResolver);
+        when(mImsResolver.getImsConfig(anyInt(), anyInt())).thenReturn(mIImsConfig);
+        mHandlerThread = new HandlerThread("RcsProvisioningMonitorTest");
+        mHandlerThread.start();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        if (mRcsProvisioningMonitor != null) {
+            mRcsProvisioningMonitor.destroy();
+            mRcsProvisioningMonitor = null;
+        }
+
+        if (mSession != null) {
+            mSession.finishMocking();
+        }
+        if (mLooper != null) {
+            mLooper.destroy();
+            mLooper = null;
+        }
+    }
+
+    @Test
+    @SmallTest
+    public void testInit() throws Exception {
+        createMonitor(3);
+        ArgumentCaptor<Intent> captorIntent = ArgumentCaptor.forClass(Intent.class);
+        for (int i = 0; i < 3; i++) {
+            assertTrue(Arrays.equals(SAMPLE_CONFIG.getBytes(),
+                    mRcsProvisioningMonitor.getConfig(FAKE_SUB_ID_BASE + i)));
+        }
+
+        verify(mPhone, times(3)).sendBroadcast(captorIntent.capture());
+        Intent capturedIntent = captorIntent.getAllValues().get(1);
+        assertEquals(ProvisioningManager.ACTION_RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE,
+                capturedIntent.getAction());
+        PhoneGlobals.getInstance().getImsResolver();
+        verify(mPhone, atLeastOnce()).getImsResolver();
+        verify(mIImsConfig, times(3)).notifyRcsAutoConfigurationReceived(any(), anyBoolean());
+    }
+
+    @Test
+    @SmallTest
+    public void testSubInfoChanged() throws Exception {
+        createMonitor(3);
+        ArgumentCaptor<Intent> captorIntent = ArgumentCaptor.forClass(Intent.class);
+        mExecutor.execute(() -> mSubChangedListener.onSubscriptionsChanged());
+        processAllMessages();
+        for (int i = 0; i < 3; i++) {
+            assertTrue(Arrays.equals(SAMPLE_CONFIG.getBytes(),
+                    mRcsProvisioningMonitor.getConfig(FAKE_SUB_ID_BASE + i)));
+        }
+        verify(mPhone, times(3)).sendBroadcast(captorIntent.capture());
+        Intent capturedIntent = captorIntent.getAllValues().get(1);
+        assertEquals(ProvisioningManager.ACTION_RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE,
+                capturedIntent.getAction());
+        verify(mIImsConfig, times(3)).notifyRcsAutoConfigurationReceived(any(), anyBoolean());
+
+        makeFakeActiveSubIds(1);
+        mExecutor.execute(() -> mSubChangedListener.onSubscriptionsChanged());
+        processAllMessages();
+
+        for (int i = 1; i < 3; i++) {
+            assertNull(mRcsProvisioningMonitor.getConfig(FAKE_SUB_ID_BASE + i));
+        }
+        verify(mIImsConfig, times(2)).notifyRcsAutoConfigurationRemoved();
+    }
+
+    @Test
+    @SmallTest
+    public void testDefaultMessagingApplicationChanged() throws Exception {
+        createMonitor(1);
+        updateDefaultMessageApplication(DEFAULT_MESSAGING_APP2);
+        mBundle.putBoolean(CarrierConfigManager.KEY_USE_ACS_FOR_RCS_BOOL, false);
+        processAllMessages();
+        verify(mIImsConfig, atLeastOnce())
+                .notifyRcsAutoConfigurationReceived(any(), anyBoolean());
+        mBundle.putBoolean(CarrierConfigManager.KEY_USE_ACS_FOR_RCS_BOOL, true);
+        updateDefaultMessageApplication(DEFAULT_MESSAGING_APP1);
+        processAllMessages();
+        verify(mIImsConfig, atLeastOnce()).triggerRcsReconfiguration();
+    }
+
+    @Test
+    @SmallTest
+    public void testCarrierConfigChanged() throws Exception {
+        createMonitor(1);
+        when(mResources.getBoolean(
+                eq(R.bool.config_rcsVolteSingleRegistrationEnabled))).thenReturn(true);
+        ArgumentCaptor<Intent> captorIntent = ArgumentCaptor.forClass(Intent.class);
+        mBundle.putBoolean(
+                CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, true);
+        broadcastCarrierConfigChange(FAKE_SUB_ID_BASE);
+        processAllMessages();
+        verify(mPhone, atLeastOnce()).sendBroadcast(captorIntent.capture());
+        Intent capturedIntent = captorIntent.getValue();
+        assertEquals(capturedIntent.getAction(),
+                ProvisioningManager.ACTION_RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE);
+        assertEquals(FAKE_SUB_ID_BASE, capturedIntent.getIntExtra(
+                ProvisioningManager.EXTRA_SUBSCRIPTION_ID, -1));
+        assertEquals(ProvisioningManager.STATUS_CAPABLE,
+                capturedIntent.getIntExtra(ProvisioningManager.EXTRA_STATUS, -1));
+
+        mBundle.putBoolean(
+                CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, false);
+        broadcastCarrierConfigChange(FAKE_SUB_ID_BASE);
+        processAllMessages();
+        verify(mPhone, atLeastOnce()).sendBroadcast(captorIntent.capture());
+        capturedIntent = captorIntent.getValue();
+        assertEquals(capturedIntent.getAction(),
+                ProvisioningManager.ACTION_RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE);
+        assertEquals(FAKE_SUB_ID_BASE, capturedIntent.getIntExtra(
+                ProvisioningManager.EXTRA_SUBSCRIPTION_ID, -1));
+        assertEquals(ProvisioningManager.STATUS_CARRIER_NOT_CAPABLE,
+                capturedIntent.getIntExtra(ProvisioningManager.EXTRA_STATUS, -1));
+
+
+        when(mResources.getBoolean(
+                eq(R.bool.config_rcsVolteSingleRegistrationEnabled))).thenReturn(false);
+        broadcastCarrierConfigChange(FAKE_SUB_ID_BASE);
+        processAllMessages();
+        verify(mPhone, atLeastOnce()).sendBroadcast(captorIntent.capture());
+        capturedIntent = captorIntent.getValue();
+        assertEquals(capturedIntent.getAction(),
+                ProvisioningManager.ACTION_RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE);
+        assertEquals(FAKE_SUB_ID_BASE, capturedIntent.getIntExtra(
+                ProvisioningManager.EXTRA_SUBSCRIPTION_ID, -1));
+        assertEquals(ProvisioningManager.STATUS_CARRIER_NOT_CAPABLE
+                | ProvisioningManager.STATUS_DEVICE_NOT_CAPABLE,
+                capturedIntent.getIntExtra(ProvisioningManager.EXTRA_STATUS, -1));
+    }
+
+    @Test
+    @SmallTest
+    public void testUpdateConfig() throws Exception {
+        createMonitor(1);
+        final ArgumentCaptor<byte[]> argumentBytes = ArgumentCaptor.forClass(byte[].class);
+
+        mRcsProvisioningMonitor.updateConfig(FAKE_SUB_ID_BASE, SAMPLE_CONFIG.getBytes(), false);
+        processAllMessages();
+
+        verify(mImsResolver, atLeastOnce()).getImsConfig(
+                anyInt(), eq(ImsFeature.FEATURE_RCS));
+        verify(mIImsConfig, atLeastOnce()).notifyRcsAutoConfigurationReceived(
+                argumentBytes.capture(), eq(false));
+        assertTrue(Arrays.equals(SAMPLE_CONFIG.getBytes(), argumentBytes.getValue()));
+    }
+
+    @Test
+    @SmallTest
+    public void testRequestReconfig() throws Exception {
+        createMonitor(1);
+
+        mRcsProvisioningMonitor.requestReconfig(FAKE_SUB_ID_BASE);
+        processAllMessages();
+
+        verify(mImsResolver, atLeastOnce()).getImsConfig(
+                anyInt(), eq(ImsFeature.FEATURE_RCS));
+        verify(mIImsConfig, times(1)).notifyRcsAutoConfigurationRemoved();
+        verify(mIImsConfig, times(1)).triggerRcsReconfiguration();
+    }
+
+
+    @Test
+    @SmallTest
+    public void testIsRcsVolteSingleRegistrationEnabled() throws Exception {
+        createMonitor(1);
+
+        when(mResources.getBoolean(
+                eq(R.bool.config_rcsVolteSingleRegistrationEnabled))).thenReturn(true);
+        mBundle.putBoolean(
+                CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, true);
+        broadcastCarrierConfigChange(FAKE_SUB_ID_BASE);
+        processAllMessages();
+        assertTrue(mRcsProvisioningMonitor.isRcsVolteSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
+
+        mBundle.putBoolean(
+                CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, false);
+        broadcastCarrierConfigChange(FAKE_SUB_ID_BASE);
+        processAllMessages();
+        assertFalse(mRcsProvisioningMonitor.isRcsVolteSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
+
+
+        when(mResources.getBoolean(
+                eq(R.bool.config_rcsVolteSingleRegistrationEnabled))).thenReturn(false);
+        mBundle.putBoolean(
+                CarrierConfigManager.Ims.KEY_IMS_SINGLE_REGISTRATION_REQUIRED_BOOL, true);
+        broadcastCarrierConfigChange(FAKE_SUB_ID_BASE);
+        processAllMessages();
+        assertFalse(mRcsProvisioningMonitor.isRcsVolteSingleRegistrationEnabled(FAKE_SUB_ID_BASE));
+    }
+
+    private void createMonitor(int subCount) {
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+        makeFakeActiveSubIds(subCount);
+        mRcsProvisioningMonitor = new RcsProvisioningMonitor(mPhone, mHandlerThread.getLooper());
+        mHandler = mRcsProvisioningMonitor.getHandler();
+        try {
+            mLooper = new TestableLooper(mHandler.getLooper());
+        } catch (Exception e) {
+            logd("Unable to create looper from handler.");
+        }
+        processAllMessages();
+    }
+
+    private void broadcastCarrierConfigChange(int subId) {
+        Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+        intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId);
+        mExecutor.execute(() -> {
+            mReceiver.onReceive(mPhone, intent);
+        });
+    }
+
+    private void makeFakeActiveSubIds(int count) {
+        final int[] subIds = new int[count];
+        for (int i = 0; i < count; i++) {
+            subIds[i] = FAKE_SUB_ID_BASE + i;
+        }
+        when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(subIds);
+    }
+
+    private void updateDefaultMessageApplication(String packageName) throws Exception {
+        List<String> dmas = new ArrayList<>();
+        dmas.add(packageName);
+        when(mIRoleManager.getRoleHoldersAsUser(any(), anyInt())).thenReturn(dmas);
+        mExecutor.execute(() -> {
+            try {
+                mRoleHolderChangedListener.onRoleHoldersChanged(
+                        RoleManager.ROLE_SMS, UserHandle.USER_ALL);
+            } catch (RemoteException e) {
+                logd("exception to call onRoleHoldersChanged " + e);
+            }
+        });
+    }
+
+    private void replaceService(final String serviceName,
+            final IInterface serviceInstance) throws Exception {
+        IBinder binder = mock(IBinder.class);
+        when(binder.queryLocalInterface(anyString())).thenReturn(serviceInstance);
+        Field field = ServiceManager.class.getDeclaredField("sCache");
+        field.setAccessible(true);
+        ((Map<String, IBinder>) field.get(null)).put(serviceName, binder);
+    }
+
+
+    private void processAllMessages() {
+        while (!mLooper.getLooper().getQueue().isIdle()) {
+            mLooper.processAllMessages();
+        }
+    }
+
+    private static void logd(String str) {
+        Log.d(TAG, str);
+    }
+}
