diff --git a/Android.bp b/Android.bp
index 0649958..742de0a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -12,26 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // See: http://go/android-license-faq
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 // Build the Phone app which includes the emergency dialer. See Contacts
 // for the 'other' dialer.
-
-package {
-    default_applicable_licenses: ["packages_services_Telephony_license"],
-}
-
-// Added automatically by a large-scale-change
-// See: http://go/android-license-faq
-license {
-    name: "packages_services_Telephony_license",
-    visibility: [":__subpackages__"],
-    license_kinds: [
-        "SPDX-license-identifier-Apache-2.0",
-    ],
-    license_text: [
-        "NOTICE",
-    ],
-}
-
 android_app {
     name: "TeleService",
 
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 5050ea3..a4fa767 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -709,7 +709,7 @@
                 <action android:name="android.telephony.NetworkService" />
             </intent-filter>
         </service>
-        <service android:name="com.android.internal.telephony.dataconnection.CellularDataService"
+        <service android:name="com.android.internal.telephony.data.CellularDataService"
             android:exported="true"
             android:permission="android.permission.BIND_TELEPHONY_DATA_SERVICE" >
             <intent-filter>
diff --git a/NOTICE b/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
-   Copyright (c) 2005-2008, 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.
-
-   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.
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
diff --git a/OWNERS b/OWNERS
index c394f15..b4ef543 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,3 +1,4 @@
+amitmahajan@google.com
 breadley@google.com
 fionaxu@google.com
 jackyu@google.com
diff --git a/apex/Android.bp b/apex/Android.bp
index a0e5713..fbb70db 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -1,10 +1,6 @@
 package {
     // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "packages_services_Telephony_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["packages_services_Telephony_license"],
+    default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
 apex_defaults {
diff --git a/apex/testing/Android.bp b/apex/testing/Android.bp
index 1138b5e..1c6f4a3 100644
--- a/apex/testing/Android.bp
+++ b/apex/testing/Android.bp
@@ -14,11 +14,7 @@
 
 package {
     // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "packages_services_Telephony_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["packages_services_Telephony_license"],
+    default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
 apex {
diff --git a/ecc/conversion_toolset_v1/proto/Android.bp b/ecc/conversion_toolset_v1/proto/Android.bp
index 632ab40..cefd789 100644
--- a/ecc/conversion_toolset_v1/proto/Android.bp
+++ b/ecc/conversion_toolset_v1/proto/Android.bp
@@ -14,11 +14,7 @@
 
 package {
     // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "packages_services_Telephony_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["packages_services_Telephony_license"],
+    default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
 java_library_static {
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 6fda189..1684e89 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1446,19 +1446,19 @@
     <!-- ECM: Displays the time when ECM will end, Example: "No Data Connection until 10:45 AM" -->
     <string name="phone_in_ecm_notification_complete_time">No data connection until <xliff:g id="completeTime">%s</xliff:g></string>
     <!-- ECM: Dialog box message for exiting from the notifications screen -->
-    <plurals name="alert_dialog_exit_ecm">
+    <string name="alert_dialog_exit_ecm"> {count, plural,
         <!-- number of minutes is one -->
-        <item quantity="one">The phone will be in Emergency Callback mode for <xliff:g id="count">%s</xliff:g> minute. While in this mode no apps using a data connection can be used. Do you want to exit now?</item>
+        =1    {The phone will be in Emergency Callback mode for one minute. While in this mode no apps using a data connection can be used. Do you want to exit now?}
         <!-- number of minutes is not equal to one -->
-        <item quantity="other">The phone will be in Emergency Callback mode for <xliff:g id="count">%s</xliff:g> minutes. While in this mode no applications using a data connection can be used. Do you want to exit now?</item>
-    </plurals>
+        other {The phone will be in Emergency Callback mode for %s minutes. While in this mode no applications using a data connection can be used. Do you want to exit now?}
+    }</string>
     <!-- ECM: Dialog box message for exiting from any other app -->
-    <plurals name="alert_dialog_not_avaialble_in_ecm">
+    <string name="alert_dialog_not_avaialble_in_ecm"> {count, plural,
         <!-- number of minutes is one -->
-        <item quantity="one">The selected action isn\'t available while in the Emergency Callback mode. The phone will be in this mode for <xliff:g id="count">%s</xliff:g> minute. Do you want to exit now?</item>
+        =1    {The selected action isn\'t available while in the Emergency Callback mode. The phone will be in this mode for one minute. Do you want to exit now?}
         <!-- number of minutes is not equal to one -->
-        <item quantity="other">The selected action isn\'t available while in the Emergency Callback mode. The phone will be in this mode for <xliff:g id="count">%s</xliff:g> minutes. Do you want to exit now?</item>
-    </plurals>
+        other {The selected action isn\'t available while in the Emergency Callback mode. The phone will be in this mode for %s minutes. Do you want to exit now?}
+    }</string>
     <!-- ECM: Dialog box message while in emergency call -->
     <string name="alert_dialog_in_ecm_call">The selected action isn\'t available while in an emergency call.</string>
     <!-- ECM: Progress text -->
@@ -1474,12 +1474,12 @@
     <!-- ECM: Displays the time when ECM will end without data restriction hint, Example: "Until 10:45 AM" -->
     <string name="phone_in_ecm_notification_complete_time_without_data_restriction_hint">Until <xliff:g id="completeTime">%s</xliff:g></string>
     <!-- ECM: Dialog box message without data restriction hint for exiting from the notifications screen -->
-    <plurals name="alert_dialog_exit_ecm_without_data_restriction_hint">
+    <string name="alert_dialog_exit_ecm_without_data_restriction_hint"> {count, plural,
         <!-- number of minutes is one -->
-        <item quantity="one">The phone will be in emergency callback mode for <xliff:g id="count">%s</xliff:g> minute.\nDo you want to exit now?</item>
+        =1    {The phone will be in emergency callback mode for one minute.\nDo you want to exit now?}
         <!-- number of minutes is not equal to one -->
-        <item quantity="other">The phone will be in emergency callback mode for <xliff:g id="count">%s</xliff:g> minutes.\nDo you want to exit now?</item>
-    </plurals>
+        other {The phone will be in emergency callback mode for %s minutes.\nDo you want to exit now?}
+    }</string>
 
     <!-- For incoming calls, this is a string we can get from a CDMA network instead of
          the actual phone number, to indicate there's no number present.  DO NOT TRANSLATE. -->
diff --git a/sip/src/com/android/services/telephony/sip/SipAccountRegistry.java b/sip/src/com/android/services/telephony/sip/SipAccountRegistry.java
index 2845dac..6b34f00 100644
--- a/sip/src/com/android/services/telephony/sip/SipAccountRegistry.java
+++ b/sip/src/com/android/services/telephony/sip/SipAccountRegistry.java
@@ -236,7 +236,8 @@
 
         Intent intent = new Intent(TelecomManager.ACTION_CHANGE_PHONE_ACCOUNTS);
         intent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
-        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
+        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent,
+                PendingIntent.FLAG_IMMUTABLE);
 
         Notification.Action action = new Notification.Action.Builder(R.drawable.ic_sim_card,
                 context.getString(R.string.sip_accounts_removed_notification_action),
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index d249fae..e64c81c 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -455,10 +455,16 @@
         boolean useWfcHomeModeForRoaming = carrierConfig.getBoolean(
                     CarrierConfigManager.KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL,
                     false);
+        boolean isDataEnabled;
+        if (mPhone.isUsingNewDataStack()) {
+            isDataEnabled = mPhone.getDataSettingsManager().isDataEnabled();
+        } else {
+            isDataEnabled = mPhone.getDataEnabledSettings().isDataEnabled();
+        }
         if (mImsMgr.isVtEnabledByPlatform() && mImsMgr.isVtProvisionedOnDevice()
                 && (carrierConfig.getBoolean(
                         CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS)
-                || mPhone.getDataEnabledSettings().isDataEnabled())) {
+                || isDataEnabled)) {
             boolean currentValue =
                     mImsMgr.isEnhanced4gLteModeSettingEnabledByUser()
                     ? mImsMgr.isVtEnabledByUser() : false;
diff --git a/src/com/android/phone/CallForwardEditPreference.java b/src/com/android/phone/CallForwardEditPreference.java
index db1c5b4..2cbb7c5 100644
--- a/src/com/android/phone/CallForwardEditPreference.java
+++ b/src/com/android/phone/CallForwardEditPreference.java
@@ -58,6 +58,7 @@
             CarrierXmlParser.SsEntry.SSAction.UNKNOWN;
     private int mAction;
     private HashMap<String, String> mCfInfo;
+    private long mDelayMillisAfterUssdSet = 1000;
 
     public CallForwardEditPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -490,8 +491,9 @@
                 mPhone.getCallForwardingOption(reason, mServiceClass,
                         obtainMessage(MESSAGE_GET_CF, msg.arg1, MESSAGE_SET_CF, ar.exception));
             } else {
-                mHandler.sendMessage(mHandler.obtainMessage(mHandler.MESSAGE_GET_CF_USSD,
-                        msg.arg1, MyHandler.MESSAGE_SET_CF, ar.exception));
+                mHandler.sendMessageDelayed(mHandler.obtainMessage(mHandler.MESSAGE_GET_CF_USSD,
+                        msg.arg1, MyHandler.MESSAGE_SET_CF, ar.exception),
+                        mDelayMillisAfterUssdSet);
             }
         }
 
diff --git a/src/com/android/phone/CallWaitingSwitchPreference.java b/src/com/android/phone/CallWaitingSwitchPreference.java
index 01dd3b2..609488c 100644
--- a/src/com/android/phone/CallWaitingSwitchPreference.java
+++ b/src/com/android/phone/CallWaitingSwitchPreference.java
@@ -6,28 +6,34 @@
 import android.content.Context;
 import android.os.Handler;
 import android.os.Message;
+import android.os.PersistableBundle;
 import android.preference.SwitchPreference;
+import android.telephony.CarrierConfigManager;
 import android.telephony.TelephonyManager;
 import android.util.AttributeSet;
 import android.util.Log;
 
 import com.android.internal.telephony.Phone;
 
-import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
 
 public class CallWaitingSwitchPreference extends SwitchPreference {
     private static final String LOG_TAG = "CallWaitingSwitchPreference";
+    private static final int DELAY_MILLIS_FOR_USSD = 1000;
     private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
 
     private final MyHandler mHandler = new MyHandler();
     private Phone mPhone;
     private TimeConsumingPreferenceListener mTcpListener;
-    private Executor mExecutor;
+    private ScheduledExecutorService mExecutor;
     private TelephonyManager mTelephonyManager;
     private boolean mIsDuringUpdateProcess = false;
     private int mUpdateStatus = TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR;
     private int mQueryStatus = TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR;
+    private boolean mUssdMode = false;
 
     public CallWaitingSwitchPreference(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
@@ -45,9 +51,14 @@
             TimeConsumingPreferenceListener listener, boolean skipReading, Phone phone) {
         mPhone = phone;
         mTcpListener = listener;
-        mExecutor = Executors.newSingleThreadExecutor();
+        mExecutor = Executors.newSingleThreadScheduledExecutor();
         mTelephonyManager = getContext().getSystemService(
                 TelephonyManager.class).createForSubscriptionId(phone.getSubId());
+        CarrierConfigManager configManager = getContext().getSystemService(
+                CarrierConfigManager.class);
+        PersistableBundle bundle = configManager.getConfigForSubId(phone.getSubId());
+        mUssdMode = (bundle != null) ? bundle.getBoolean(
+                CarrierConfigManager.KEY_USE_CALL_WAITING_USSD_BOOL, false) : false;
 
         if (!skipReading) {
             Log.d(LOG_TAG, "init getCallWaitingStatus");
@@ -67,7 +78,23 @@
     private void updateStatusCallBack(int result) {
         Log.d(LOG_TAG, "updateStatusCallBack: CW state " + result + ", and re get");
         mUpdateStatus = result;
-        mTelephonyManager.getCallWaitingStatus(mExecutor, this::queryStatusCallBack);
+        if (mUssdMode) {
+            Log.d(LOG_TAG, "updateStatusCallBack: USSD mode needs to wait 1s since Framework"
+                    + " has the limitation");
+            Consumer<Integer> resultListener = this::queryStatusCallBack;
+            try {
+                mExecutor.schedule(new Runnable() {
+                    @Override
+                    public void run() {
+                        mTelephonyManager.getCallWaitingStatus(mExecutor, resultListener);
+                    }
+                }, DELAY_MILLIS_FOR_USSD, TimeUnit.MILLISECONDS);
+            } catch (Exception e) {
+                Log.d(LOG_TAG, "Exception while waiting: " + e);
+            }
+        } else {
+            mTelephonyManager.getCallWaitingStatus(mExecutor, this::queryStatusCallBack);
+        }
     }
 
     @Override
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index e276082..8a007b6 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -65,6 +65,7 @@
 import com.android.internal.telephony.TelephonyPermissions;
 import com.android.internal.telephony.util.ArrayUtils;
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.telephony.Rlog;
 
 import java.io.File;
 import java.io.FileDescriptor;
@@ -1064,6 +1065,7 @@
         }
 
         String fileName;
+        String iccid = null;
         if (isNoSimConfig) {
             fileName = getFilenameForNoSimConfig(packageName);
         } else {
@@ -1073,7 +1075,7 @@
                 return null;
             }
 
-            final String iccid = getIccIdForPhoneId(phoneId);
+            iccid = getIccIdForPhoneId(phoneId);
             final int cid = getSpecificCarrierIdForPhoneId(phoneId);
             if (iccid == null) {
                 loge("Cannot restore config with null iccid.");
@@ -1102,7 +1104,15 @@
         } catch (FileNotFoundException e) {
             // Missing file is normal occurrence that might occur with a new sim or when restoring
             // an override file during boot and should not be treated as an error.
-            if (file != null) logd("File not found: " + file.getPath());
+            if (file != null) {
+                if (isNoSimConfig) {
+                    logd("File not found: " + file.getPath());
+                } else {
+                    String filePath = file.getPath();
+                    filePath = getFilePathForLogging(filePath, iccid);
+                    logd("File not found : " + filePath);
+                }
+            }
         } catch (IOException e) {
             loge(e.toString());
         }
@@ -1110,6 +1120,22 @@
         return restoredBundle;
     }
 
+    /**
+     * This method will mask most part of iccid in the filepath for logging on userbuild
+     */
+    private String getFilePathForLogging(String filePath, String iccid) {
+        // If loggable then return with actual file path
+        if (Rlog.isLoggable(LOG_TAG, Log.VERBOSE)) {
+            return filePath;
+        }
+        String path = filePath;
+        int length = (iccid != null) ? iccid.length() : 0;
+        if (length > 5 && filePath != null) {
+            path = filePath.replace(iccid.substring(5), "***************");
+        }
+        return path;
+    }
+
     private PersistableBundle restoreConfigFromXml(String packageName, @NonNull String extraString,
             int phoneId) {
         return restoreConfigFromXml(packageName, extraString, phoneId, false);
diff --git a/src/com/android/phone/EmergencyCallbackModeExitDialog.java b/src/com/android/phone/EmergencyCallbackModeExitDialog.java
index adba850..fc0e513 100644
--- a/src/com/android/phone/EmergencyCallbackModeExitDialog.java
+++ b/src/com/android/phone/EmergencyCallbackModeExitDialog.java
@@ -30,6 +30,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
+import android.icu.text.MessageFormat;
 import android.os.AsyncResult;
 import android.os.Bundle;
 import android.os.CountDownTimer;
@@ -43,6 +44,9 @@
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.TelephonyIntents;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * Displays dialog that enables users to exit Emergency Callback Mode
  *
@@ -297,20 +301,22 @@
         int minutes = (int)(millisUntilFinished / 60000);
         String time = String.format("%d:%02d", minutes,
                 (millisUntilFinished % 60000) / 1000);
+        Map<String, Object> msgArgs = new HashMap<>();
+        msgArgs.put("count", minutes);
 
         switch (mDialogType) {
         case EXIT_ECM_BLOCK_OTHERS:
-            return String.format(getResources().getQuantityText(
-                    R.plurals.alert_dialog_not_avaialble_in_ecm, minutes).toString(), time);
+            return MessageFormat.format(getResources().getString(
+                    R.string.alert_dialog_not_avaialble_in_ecm, time), msgArgs);
         case EXIT_ECM_DIALOG:
                 boolean shouldRestrictData = mPhone.getImsPhone() != null
                         && mPhone.getImsPhone().isInImsEcm();
-                return String.format(getResources().getQuantityText(
+                return MessageFormat.format(getResources().getString(
                         // During IMS ECM, data restriction hint should be removed.
                         shouldRestrictData
-                        ? R.plurals.alert_dialog_exit_ecm_without_data_restriction_hint
-                        : R.plurals.alert_dialog_exit_ecm,
-                        minutes).toString(), time);
+                        ? R.string.alert_dialog_exit_ecm_without_data_restriction_hint
+                        : R.string.alert_dialog_exit_ecm,
+                        time), msgArgs);
         }
         return null;
     }
diff --git a/src/com/android/phone/ImsProvisioningController.java b/src/com/android/phone/ImsProvisioningController.java
new file mode 100644
index 0000000..d78e565
--- /dev/null
+++ b/src/com/android/phone/ImsProvisioningController.java
@@ -0,0 +1,1489 @@
+/*
+ * Copyright (C) 2021 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 android.telephony.ims.ProvisioningManager.KEY_EAB_PROVISIONING_STATUS;
+import static android.telephony.ims.ProvisioningManager.KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE;
+import static android.telephony.ims.ProvisioningManager.KEY_VOLTE_PROVISIONING_STATUS;
+import static android.telephony.ims.ProvisioningManager.KEY_VT_PROVISIONING_STATUS;
+import static android.telephony.ims.ProvisioningManager.PROVISIONING_VALUE_DISABLED;
+import static android.telephony.ims.ProvisioningManager.PROVISIONING_VALUE_ENABLED;
+import static android.telephony.ims.feature.ImsFeature.FEATURE_MMTEL;
+import static android.telephony.ims.feature.ImsFeature.FEATURE_RCS;
+import static android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER;
+import static android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_SMS;
+import static android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT;
+import static android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO;
+import static android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE;
+import static android.telephony.ims.feature.RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE;
+import static android.telephony.ims.feature.RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE;
+import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM;
+import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN;
+import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_LTE;
+import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_MAX;
+import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
+import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_NR;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.os.AsyncResult;
+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.telephony.CarrierConfigManager;
+import android.telephony.CarrierConfigManager.Ims;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyRegistryManager;
+import android.telephony.ims.ProvisioningManager;
+import android.telephony.ims.aidl.IFeatureProvisioningCallback;
+import android.telephony.ims.aidl.IImsConfig;
+import android.telephony.ims.feature.MmTelFeature.MmTelCapabilities;
+import android.telephony.ims.feature.RcsFeature.RcsImsCapabilities;
+import android.telephony.ims.stub.ImsConfigImplBase;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
+import android.util.SparseArray;
+
+import com.android.ims.FeatureConnector;
+import com.android.ims.ImsConfig;
+import com.android.ims.ImsException;
+import com.android.ims.ImsManager;
+import com.android.ims.RcsFeatureManager;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.PhoneConfigurationManager;
+import com.android.internal.telephony.util.HandlerExecutor;
+import com.android.telephony.Rlog;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.concurrent.Executor;
+
+/**
+ * Provides APIs for MMTEL and RCS provisioning status. This class handles provisioning status and
+ * notifies the status changing for each capability
+ * {{@link MmTelCapabilities.MmTelCapability} for MMTel services}
+ * {{@link RcsImsCapabilities.RcsImsCapabilityFlag} for RCS services}
+ */
+public class ImsProvisioningController {
+    private static final String TAG = "ImsProvisioningController";
+    private static final int INVALID_VALUE = -1;
+
+    private static final int EVENT_SUB_CHANGED = 1;
+    private static final int EVENT_PROVISIONING_CAPABILITY_CHANGED = 2;
+    @VisibleForTesting
+    protected static final int EVENT_MULTI_SIM_CONFIGURATION_CHANGE = 3;
+
+    // Provisioning Keys that are handled via AOSP cache and not sent to the ImsService
+    private static final int[] LOCAL_IMS_CONFIG_KEYS = {
+            KEY_VOLTE_PROVISIONING_STATUS,
+            KEY_VT_PROVISIONING_STATUS,
+            KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE,
+            KEY_EAB_PROVISIONING_STATUS
+    };
+    private static final int[] LOCAL_RADIO_TECHS = {
+            REGISTRATION_TECH_LTE,
+            REGISTRATION_TECH_IWLAN,
+            REGISTRATION_TECH_CROSS_SIM,
+            REGISTRATION_TECH_NR
+    };
+
+    private static final int MMTEL_CAPABILITY_MIN = MmTelCapabilities.CAPABILITY_TYPE_NONE;
+    private static final int MMTEL_CAPABILITY_MAX = MmTelCapabilities.CAPABILITY_TYPE_MAX;
+
+    private static final int RCS_CAPABILITY_MIN = RcsImsCapabilities.CAPABILITY_TYPE_NONE;
+    private static final int RCS_CAPABILITY_MAX = RcsImsCapabilities.CAPABILITY_TYPE_MAX;
+
+    private static final int[] LOCAL_MMTEL_CAPABILITY = {
+            CAPABILITY_TYPE_VOICE,
+            CAPABILITY_TYPE_VIDEO,
+            CAPABILITY_TYPE_UT,
+            CAPABILITY_TYPE_SMS,
+            CAPABILITY_TYPE_CALL_COMPOSER
+    };
+
+    /**
+     * map the MmTelCapabilities.MmTelCapability and
+     * CarrierConfigManager.Ims.KEY_CAPABILITY_TYPE_VOICE_INT
+     * CarrierConfigManager.Ims.KEY_CAPABILITY_TYPE_VIDEO_INT
+     * CarrierConfigManager.Ims.KEY_CAPABILITY_TYPE_UT_INT
+     * CarrierConfigManager.Ims.KEY_CAPABILITY_TYPE_SMS_INT
+     * CarrierConfigManager.Ims.KEY_CAPABILITY_TYPE_CALL_COMPOSER_INT
+     */
+    private static final Map<Integer, String> KEYS_MMTEL_CAPABILITY = Map.of(
+            CAPABILITY_TYPE_VOICE, Ims.KEY_CAPABILITY_TYPE_VOICE_INT_ARRAY,
+            CAPABILITY_TYPE_VIDEO, Ims.KEY_CAPABILITY_TYPE_VIDEO_INT_ARRAY,
+            CAPABILITY_TYPE_UT, Ims.KEY_CAPABILITY_TYPE_UT_INT_ARRAY,
+            CAPABILITY_TYPE_SMS, Ims.KEY_CAPABILITY_TYPE_SMS_INT_ARRAY,
+            CAPABILITY_TYPE_CALL_COMPOSER, Ims.KEY_CAPABILITY_TYPE_CALL_COMPOSER_INT_ARRAY
+    );
+
+    /**
+     * map the RcsImsCapabilities.RcsImsCapabilityFlag and
+     * CarrierConfigManager.Ims.KEY_CAPABILITY_TYPE_OPTIONS_UCE
+     * CarrierConfigManager.Ims.KEY_CAPABILITY_TYPE_PRESENCE_UCE
+     */
+    private static final Map<Integer, String> KEYS_RCS_CAPABILITY = Map.of(
+            CAPABILITY_TYPE_OPTIONS_UCE, Ims.KEY_CAPABILITY_TYPE_OPTIONS_UCE_INT_ARRAY,
+            CAPABILITY_TYPE_PRESENCE_UCE, Ims.KEY_CAPABILITY_TYPE_PRESENCE_UCE_INT_ARRAY
+    );
+
+    /**
+     * Create a FeatureConnector for this class to use to connect to an ImsManager.
+     */
+    @VisibleForTesting
+    public interface MmTelFeatureConnector {
+        /**
+         * Create a FeatureConnector for this class to use to connect to an ImsManager.
+         * @param listener will receive ImsManager instance.
+         * @param executor that the Listener callbacks will be called on.
+         * @return A FeatureConnector
+         */
+        FeatureConnector<ImsManager> create(Context context, int slotId,
+                String logPrefix, FeatureConnector.Listener<ImsManager> listener,
+                Executor executor);
+    }
+
+    /**
+     * Create a FeatureConnector for this class to use to connect to an RcsFeatureManager.
+     */
+    @VisibleForTesting
+    public interface RcsFeatureConnector {
+        /**
+         * Create a FeatureConnector for this class to use to connect to an RcsFeatureManager.
+         * @param listener will receive RcsFeatureManager instance.
+         * @param executor that the Listener callbacks will be called on.
+         * @return A FeatureConnector
+         */
+        FeatureConnector<RcsFeatureManager> create(Context context, int slotId,
+                FeatureConnector.Listener<RcsFeatureManager> listener,
+                Executor executor, String logPrefix);
+    }
+
+    private static ImsProvisioningController sInstance;
+
+    private final PhoneGlobals mApp;
+    private final Handler mHandler;
+    private final CarrierConfigManager mCarrierConfigManager;
+    private final SubscriptionManager mSubscriptionManager;
+    private final TelephonyRegistryManager mTelephonyRegistryManager;
+    private final MmTelFeatureConnector mMmTelFeatureConnector;
+    private final RcsFeatureConnector mRcsFeatureConnector;
+
+    // maps a slotId to a list of MmTelFeatureListeners
+    private final SparseArray<MmTelFeatureListener> mMmTelFeatureListenersSlotMap =
+            new SparseArray<>();
+    // maps a slotId to a list of RcsFeatureListeners
+    private final SparseArray<RcsFeatureListener> mRcsFeatureListenersSlotMap =
+            new SparseArray<>();
+    // map a slotId to a list of ProvisioningCallbackManager
+    private final SparseArray<ProvisioningCallbackManager> mProvisioningCallbackManagersSlotMap =
+            new SparseArray<>();
+    private final ImsProvisioningLoader mImsProvisioningLoader;
+
+    private int mNumSlot;
+
+    /**
+     * This class contains the provisioning status to notify changes.
+     * {{@link MmTelCapabilities.MmTelCapability} for MMTel services}
+     * {{@link RcsImsCapabilities.RcsImsCapabilityFlag} for RCS services}
+     * {{@link ImsRegistrationImplBase.ImsRegistrationTech} for Registration tech}
+     */
+    private static final class FeatureProvisioningData {
+        public final int mCapability;
+        public final int mTech;
+        public final boolean mProvisioned;
+        public final boolean mIsMmTel;
+
+        FeatureProvisioningData(int capability, int tech, boolean provisioned, boolean isMmTel) {
+            mCapability = capability;
+            mTech = tech;
+            mProvisioned = provisioned;
+            mIsMmTel = isMmTel;
+        }
+    }
+
+    private final class MessageHandler extends Handler {
+        private static final String LOG_PREFIX = "Handler";
+        MessageHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case EVENT_SUB_CHANGED:
+                    onSubscriptionsChanged();
+                    break;
+                case EVENT_PROVISIONING_CAPABILITY_CHANGED:
+                    try {
+                        mProvisioningCallbackManagersSlotMap.get(msg.arg1)
+                                .notifyProvisioningCapabilityChanged(
+                                        (FeatureProvisioningData) msg.obj);
+                    } catch (NullPointerException e) {
+                        logw(LOG_PREFIX, msg.arg1,
+                                "can not find callback manager message" + msg.what);
+                    }
+                    break;
+                case EVENT_MULTI_SIM_CONFIGURATION_CHANGE:
+                    int activeModemCount = (int) ((AsyncResult) msg.obj).result;
+                    onMultiSimConfigChanged(activeModemCount);
+                    break;
+                default:
+                    log("unknown message " + msg);
+                    break;
+            }
+        }
+    }
+
+    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 class ProvisioningCallbackManager {
+        private static final String LOG_PREFIX = "ProvisioningCallbackManager";
+        private RemoteCallbackList<IFeatureProvisioningCallback> mIFeatureProvisioningCallbackList;
+        private int mSubId;
+        private int mSlotId;
+
+        ProvisioningCallbackManager(int slotId) {
+            mIFeatureProvisioningCallbackList =
+                    new RemoteCallbackList<IFeatureProvisioningCallback>();
+            mSlotId = slotId;
+            mSubId = getSubId(slotId);
+            log(LOG_PREFIX, mSlotId, "ProvisioningCallbackManager create");
+        }
+
+        public void clear() {
+            log(LOG_PREFIX, mSlotId, "ProvisioningCallbackManager clear ");
+
+            mIFeatureProvisioningCallbackList.kill();
+
+            // All registered callbacks are unregistered, and the list is disabled
+            // need to create again
+            mIFeatureProvisioningCallbackList =
+                    new RemoteCallbackList<IFeatureProvisioningCallback>();
+        }
+
+        public void registerCallback(IFeatureProvisioningCallback localCallback) {
+            if (!mIFeatureProvisioningCallbackList.register(localCallback, (Object) mSubId)) {
+                log(LOG_PREFIX, mSlotId, "registration callback fail");
+            }
+        }
+
+        public void unregisterCallback(IFeatureProvisioningCallback localCallback) {
+            mIFeatureProvisioningCallbackList.unregister(localCallback);
+        }
+
+        public void setSubId(int subId) {
+            if (mSubId == subId) {
+                log(LOG_PREFIX, mSlotId, "subId is not changed ");
+                return;
+            }
+
+            mSubId = subId;
+            mSlotId = getSlotId(subId);
+
+            // subId changed means the registered callbacks are not available.
+            clear();
+        }
+
+        public boolean hasCallblacks() {
+            int size = mIFeatureProvisioningCallbackList.beginBroadcast();
+            mIFeatureProvisioningCallbackList.finishBroadcast();
+
+            return (size > 0);
+        }
+
+        public void notifyProvisioningCapabilityChanged(FeatureProvisioningData data) {
+            int size = mIFeatureProvisioningCallbackList.beginBroadcast();
+            for (int index = 0; index < size; index++) {
+                try {
+                    IFeatureProvisioningCallback imsFeatureProvisioningCallback =
+                            mIFeatureProvisioningCallbackList.getBroadcastItem(index);
+
+                    // MMTEL
+                    if (data.mIsMmTel
+                            && Arrays.stream(LOCAL_MMTEL_CAPABILITY)
+                            .anyMatch(value -> value == data.mCapability)) {
+                        imsFeatureProvisioningCallback.onFeatureProvisioningChanged(
+                                data.mCapability, data.mTech, data.mProvisioned);
+                        logi(LOG_PREFIX, mSlotId, "notifyProvisioningCapabilityChanged : "
+                                + "onFeatureProvisioningChanged"
+                                + " capability " + data.mCapability
+                                + " tech "  + data.mTech
+                                + " isProvisioned " + data.mProvisioned);
+                    } else if (data.mCapability == CAPABILITY_TYPE_PRESENCE_UCE) {
+                        imsFeatureProvisioningCallback.onRcsFeatureProvisioningChanged(
+                                data.mCapability, data.mTech, data.mProvisioned);
+                        logi(LOG_PREFIX, mSlotId, "notifyProvisioningCapabilityChanged : "
+                                + "onRcsFeatureProvisioningChanged"
+                                + " capability " + data.mCapability
+                                + " tech "  + data.mTech
+                                + " isProvisioned " + data.mProvisioned);
+                    } else {
+                        loge(LOG_PREFIX, mSlotId, "notifyProvisioningCapabilityChanged : "
+                                + "unknown capability "
+                                + data.mCapability);
+                    }
+                } catch (RemoteException e) {
+                    loge(LOG_PREFIX, mSlotId,
+                            "notifyProvisioningChanged: callback #" + index + " failed");
+                }
+            }
+            mIFeatureProvisioningCallbackList.finishBroadcast();
+        }
+    }
+
+    private final class MmTelFeatureListener implements FeatureConnector.Listener<ImsManager> {
+        private static final String LOG_PREFIX = "MmTelFeatureListener";
+        private FeatureConnector<ImsManager> mConnector;
+        private ImsManager mImsManager;
+        private boolean mReady = false;
+        // stores whether the initial provisioning key value should be notified to ImsService
+        private boolean mRequiredNotify = false;
+        private int mSubId;
+        private int mSlotId;
+
+        MmTelFeatureListener(int slotId) {
+            log(LOG_PREFIX, slotId, "created");
+
+            mSlotId = slotId;
+            mSubId = getSubId(slotId);
+            mConnector = mMmTelFeatureConnector.create(
+                    mApp, slotId, TAG, this, new HandlerExecutor(mHandler));
+            mConnector.connect();
+        }
+
+        public void setSubId(int subId) {
+            if (mRequiredNotify && mReady) {
+                mRequiredNotify = false;
+                setInitialProvisioningKeys(subId);
+            }
+            if (mSubId == subId) {
+                log(LOG_PREFIX, mSlotId, "subId is not changed");
+                return;
+            }
+
+            mSubId = subId;
+            mSlotId = getSlotId(subId);
+        }
+
+        public void destroy() {
+            log("destroy");
+            mConnector.disconnect();
+            mConnector = null;
+            mReady = false;
+            mImsManager = null;
+        }
+
+        public @Nullable ImsManager getImsManager() {
+            return mImsManager;
+        }
+
+        @Override
+        public void connectionReady(ImsManager manager, int subId) {
+            log(LOG_PREFIX, mSlotId, "connection ready");
+            mReady = true;
+            mImsManager = manager;
+
+            onMmTelAvailable();
+        }
+
+        @Override
+        public void connectionUnavailable(int reason) {
+            log(LOG_PREFIX, mSlotId, "connection unavailable " + reason);
+
+            mReady = false;
+            mImsManager = null;
+
+            // keep the callback for other reason
+            if (reason == FeatureConnector.UNAVAILABLE_REASON_IMS_UNSUPPORTED) {
+                onMmTelUnavailable();
+            }
+        }
+
+        public int setProvisioningValue(int key, int value) {
+            int retVal = ImsConfigImplBase.CONFIG_RESULT_FAILED;
+
+            if (!mReady) {
+                loge(LOG_PREFIX, mSlotId, "service is Unavailable");
+                return retVal;
+            }
+            try {
+                // getConfigInterface() will return not null or throw the ImsException
+                // need not null checking
+                ImsConfig imsConfig = getImsConfig(mImsManager);
+                retVal = imsConfig.setConfig(key, value);
+                log(LOG_PREFIX, mSlotId, "setConfig called with key " + key + " value " + value);
+            } catch (ImsException e) {
+                logw(LOG_PREFIX, mSlotId,
+                        "setConfig operation failed for key =" + key
+                        + ", value =" + value + ". Exception:" + e.getMessage());
+            }
+            return retVal;
+        }
+
+        public int getProvisioningValue(int key) {
+            if (!mReady) {
+                loge(LOG_PREFIX, mSlotId, "service is Unavailable");
+                return INVALID_VALUE;
+            }
+
+            int retValue = INVALID_VALUE;
+            try {
+                // getConfigInterface() will return not null or throw the ImsException
+                // need not null checking
+                ImsConfig imsConfig = getImsConfig(mImsManager);
+                retValue = imsConfig.getConfigInt(key);
+            } catch (ImsException e) {
+                logw(LOG_PREFIX, mSlotId,
+                        "getConfig operation failed for key =" + key
+                        + ", value =" + retValue + ". Exception:" + e.getMessage());
+            }
+            return retValue;
+        }
+
+        public void onMmTelAvailable() {
+            log(LOG_PREFIX, mSlotId, "onMmTelAvailable");
+
+            if (isValidSubId(mSubId)) {
+                mRequiredNotify = false;
+
+                // notify provisioning key value to ImsService
+                setInitialProvisioningKeys(mSubId);
+            } else {
+                // wait until subId is valid
+                mRequiredNotify = true;
+            }
+        }
+
+        public void onMmTelUnavailable() {
+            log(LOG_PREFIX, mSlotId, "onMmTelUnavailable");
+
+            try {
+                // delete all callbacks reference from ProvisioningManager
+                mProvisioningCallbackManagersSlotMap.get(getSlotId(mSubId)).clear();
+            } catch (NullPointerException e) {
+                logw(LOG_PREFIX, getSlotId(mSubId), "can not find callback manager to clear");
+            }
+        }
+
+        private void setInitialProvisioningKeys(int subId) {
+            boolean required;
+            int value = ImsProvisioningLoader.STATUS_NOT_SET;
+
+            // updating KEY_VOLTE_PROVISIONING_STATUS
+            required = isProvisioningRequired(subId, CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_LTE,
+                    /*isMmTel*/true);
+            log(LOG_PREFIX, mSlotId,
+                    "setInitialProvisioningKeys provisioning required(voice, lte) " + required);
+            if (required) {
+                value = mImsProvisioningLoader.getProvisioningStatus(subId, FEATURE_MMTEL,
+                        CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_LTE);
+                if (value != ImsProvisioningLoader.STATUS_NOT_SET) {
+                    value = (value == ImsProvisioningLoader.STATUS_PROVISIONED)
+                            ? PROVISIONING_VALUE_ENABLED : PROVISIONING_VALUE_DISABLED;
+                    setProvisioningValue(KEY_VOLTE_PROVISIONING_STATUS, value);
+                }
+            }
+
+            // updating KEY_VT_PROVISIONING_STATUS
+            required = isProvisioningRequired(subId, CAPABILITY_TYPE_VIDEO, REGISTRATION_TECH_LTE,
+                    /*isMmTel*/true);
+            log(LOG_PREFIX, mSlotId,
+                    "setInitialProvisioningKeys provisioning required(video, lte) " + required);
+            if (required) {
+                value = mImsProvisioningLoader.getProvisioningStatus(subId, FEATURE_MMTEL,
+                        CAPABILITY_TYPE_VIDEO, REGISTRATION_TECH_LTE);
+                if (value != ImsProvisioningLoader.STATUS_NOT_SET) {
+                    value = (value == ImsProvisioningLoader.STATUS_PROVISIONED)
+                            ? PROVISIONING_VALUE_ENABLED : PROVISIONING_VALUE_DISABLED;
+                    setProvisioningValue(KEY_VT_PROVISIONING_STATUS, value);
+                }
+            }
+
+            // updating KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE
+            required = isProvisioningRequired(subId, CAPABILITY_TYPE_VOICE,
+                    REGISTRATION_TECH_IWLAN, /*isMmTel*/true);
+            log(LOG_PREFIX, mSlotId,
+                    "setInitialProvisioningKeys provisioning required(voice, iwlan) " + required);
+            if (required) {
+                value = mImsProvisioningLoader.getProvisioningStatus(subId, FEATURE_MMTEL,
+                        CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_IWLAN);
+                if (value != ImsProvisioningLoader.STATUS_NOT_SET) {
+                    value = (value == ImsProvisioningLoader.STATUS_PROVISIONED)
+                            ? PROVISIONING_VALUE_ENABLED : PROVISIONING_VALUE_DISABLED;
+                    setProvisioningValue(KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE, value);
+                }
+            }
+        }
+    }
+
+    private final class RcsFeatureListener implements FeatureConnector.Listener<RcsFeatureManager> {
+        private static final String LOG_PREFIX = "RcsFeatureListener";
+        private FeatureConnector<RcsFeatureManager> mConnector;
+        private RcsFeatureManager mRcsFeatureManager;
+        private boolean mReady = false;
+        // stores whether the initial provisioning key value should be notified to ImsService
+        private boolean mRequiredNotify = false;
+        private int mSubId;
+        private int mSlotId;
+
+        RcsFeatureListener(int slotId) {
+            log(LOG_PREFIX, slotId, "created");
+
+            mSlotId = slotId;
+            mSubId = getSubId(slotId);
+            mConnector = mRcsFeatureConnector.create(
+                    mApp, slotId, this, new HandlerExecutor(mHandler), TAG);
+            mConnector.connect();
+        }
+
+        public void setSubId(int subId) {
+            if (mRequiredNotify && mReady) {
+                mRequiredNotify = false;
+                setInitialProvisioningKeys(subId);
+            }
+            if (mSubId == subId) {
+                log(LOG_PREFIX, mSlotId, "subId is not changed");
+                return;
+            }
+
+            mSubId = subId;
+            mSlotId = getSlotId(subId);
+        }
+
+        public void destroy() {
+            log(LOG_PREFIX, mSlotId, "destroy");
+            mConnector.disconnect();
+            mConnector = null;
+            mReady = false;
+            mRcsFeatureManager = null;
+        }
+
+        @Override
+        public void connectionReady(RcsFeatureManager manager, int subId) {
+            log(LOG_PREFIX, mSlotId, "connection ready");
+            mReady = true;
+            mRcsFeatureManager = manager;
+
+            onRcsAvailable();
+        }
+
+        @Override
+        public void connectionUnavailable(int reason) {
+            log(LOG_PREFIX, mSlotId, "connection unavailable");
+            mReady = false;
+            mRcsFeatureManager = null;
+
+            // keep the callback for other reason
+            if (reason == FeatureConnector.UNAVAILABLE_REASON_IMS_UNSUPPORTED) {
+                onRcsUnavailable();
+            }
+        }
+
+        public int setProvisioningValue(int key, int value) {
+            int retVal = ImsConfigImplBase.CONFIG_RESULT_FAILED;
+
+            if (!mReady) {
+                loge(LOG_PREFIX, mSlotId, "service is Unavailable");
+                return retVal;
+            }
+
+            try {
+                // getConfigInterface() will return not null or throw the ImsException
+                // need not null checking
+                ImsConfig imsConfig = getImsConfig(mRcsFeatureManager.getConfig());
+                retVal = imsConfig.setConfig(key, value);
+                log(LOG_PREFIX, mSlotId, "setConfig called with key " + key + " value " + value);
+            } catch (ImsException e) {
+                logw(LOG_PREFIX, mSlotId,
+                        "setConfig operation failed for key =" + key
+                        + ", value =" + value + ". Exception:" + e.getMessage());
+            }
+            return retVal;
+        }
+
+        public int getProvisioningValue(int key) {
+            if (!mReady) {
+                loge(LOG_PREFIX, mSlotId, "service is Unavailable");
+                return INVALID_VALUE;
+            }
+
+            int retValue = INVALID_VALUE;
+            try {
+                // getConfigInterface() will return not null or throw the ImsException
+                // need not null checking
+                ImsConfig imsConfig = getImsConfig(mRcsFeatureManager.getConfig());
+                retValue = imsConfig.getConfigInt(key);
+            } catch (ImsException e) {
+                logw(LOG_PREFIX, mSlotId,
+                        "getConfig operation failed for key =" + key
+                        + ", value =" + retValue + ". Exception:" + e.getMessage());
+            }
+            return retValue;
+        }
+
+        public void onRcsAvailable() {
+            log(LOG_PREFIX, mSlotId, "onRcsAvailable");
+
+            if (isValidSubId(mSubId)) {
+                mRequiredNotify = false;
+
+                // notify provisioning key value to ImsService
+                setInitialProvisioningKeys(mSubId);
+            } else {
+                // wait until subId is valid
+                mRequiredNotify = true;
+            }
+        }
+
+        public void onRcsUnavailable() {
+            log(LOG_PREFIX, mSlotId, "onRcsUnavailable");
+
+            try {
+                // delete all callbacks reference from ProvisioningManager
+                mProvisioningCallbackManagersSlotMap.get(getSlotId(mSubId)).clear();
+            } catch (NullPointerException e) {
+                logw(LOG_PREFIX, getSlotId(mSubId), "can not find callback manager to clear");
+            }
+        }
+
+        private void setInitialProvisioningKeys(int subId) {
+            boolean required;
+            int value = ImsProvisioningLoader.STATUS_NOT_SET;
+
+            // KEY_EAB_PROVISIONING_STATUS
+            int capability = CAPABILITY_TYPE_PRESENCE_UCE;
+            // Assume that all radio techs have the same provisioning value
+            int tech = REGISTRATION_TECH_LTE;
+
+            required = isProvisioningRequired(subId, capability, tech, /*isMmTel*/false);
+            if (required) {
+                value = mImsProvisioningLoader.getProvisioningStatus(subId, FEATURE_RCS,
+                        capability, tech);
+                if (value != ImsProvisioningLoader.STATUS_NOT_SET) {
+                    value = (value == ImsProvisioningLoader.STATUS_PROVISIONED)
+                            ? PROVISIONING_VALUE_ENABLED : PROVISIONING_VALUE_DISABLED;
+                    setProvisioningValue(KEY_EAB_PROVISIONING_STATUS, value);
+                }
+            }
+        }
+    }
+
+    /**
+     * Do NOT use this directly, instead use {@link #getInstance()}.
+     */
+    @VisibleForTesting
+    public ImsProvisioningController(PhoneGlobals app, int numSlot, Looper looper,
+            MmTelFeatureConnector mmTelFeatureConnector, RcsFeatureConnector rcsFeatureConnector,
+            ImsProvisioningLoader imsProvisioningLoader) {
+        log("ImsProvisioningController");
+        mApp = app;
+        mNumSlot = numSlot;
+        mHandler = new MessageHandler(looper);
+        mMmTelFeatureConnector = mmTelFeatureConnector;
+        mRcsFeatureConnector = rcsFeatureConnector;
+        mCarrierConfigManager = mApp.getSystemService(CarrierConfigManager.class);
+        mSubscriptionManager = mApp.getSystemService(SubscriptionManager.class);
+        mTelephonyRegistryManager = mApp.getSystemService(TelephonyRegistryManager.class);
+        mTelephonyRegistryManager.addOnSubscriptionsChangedListener(
+                mSubChangedListener, mSubChangedListener.getHandlerExecutor());
+        mImsProvisioningLoader = imsProvisioningLoader;
+
+        PhoneConfigurationManager.registerForMultiSimConfigChange(mHandler,
+                EVENT_MULTI_SIM_CONFIGURATION_CHANGE, null);
+
+        initialize(numSlot);
+    }
+
+    private void initialize(int numSlot) {
+        for (int i = 0; i < numSlot; i++) {
+            MmTelFeatureListener m = new MmTelFeatureListener(i);
+            mMmTelFeatureListenersSlotMap.put(i, m);
+
+            RcsFeatureListener r = new RcsFeatureListener(i);
+            mRcsFeatureListenersSlotMap.put(i, r);
+
+            ProvisioningCallbackManager p = new ProvisioningCallbackManager(i);
+            mProvisioningCallbackManagersSlotMap.put(i, p);
+        }
+    }
+
+    private void onMultiSimConfigChanged(int newNumSlot) {
+        log("onMultiSimConfigChanged: NumSlot " + mNumSlot + " newNumSlot " + newNumSlot);
+
+        if (mNumSlot < newNumSlot) {
+            for (int i = mNumSlot; i < newNumSlot; i++) {
+                MmTelFeatureListener m = new MmTelFeatureListener(i);
+                mMmTelFeatureListenersSlotMap.put(i, m);
+
+                RcsFeatureListener r = new RcsFeatureListener(i);
+                mRcsFeatureListenersSlotMap.put(i, r);
+
+                ProvisioningCallbackManager p = new ProvisioningCallbackManager(i);
+                mProvisioningCallbackManagersSlotMap.put(i, p);
+            }
+        } else if (mNumSlot > newNumSlot) {
+            for (int i = (mNumSlot - 1); i > (newNumSlot - 1); i--) {
+                MmTelFeatureListener m = mMmTelFeatureListenersSlotMap.get(i);
+                mMmTelFeatureListenersSlotMap.remove(i);
+                m.destroy();
+
+                RcsFeatureListener r = mRcsFeatureListenersSlotMap.get(i);
+                mRcsFeatureListenersSlotMap.remove(i);
+                r.destroy();
+
+                ProvisioningCallbackManager p = mProvisioningCallbackManagersSlotMap.get(i);
+                mProvisioningCallbackManagersSlotMap.remove(i);
+                p.clear();
+            }
+        }
+
+        mNumSlot = newNumSlot;
+    }
+
+    /**
+     * destroy the instance
+     */
+    @VisibleForTesting
+    public void destroy() {
+        log("destroy");
+
+        mHandler.getLooper().quit();
+
+        mTelephonyRegistryManager.removeOnSubscriptionsChangedListener(mSubChangedListener);
+
+        for (int i = 0; i < mMmTelFeatureListenersSlotMap.size(); i++) {
+            mMmTelFeatureListenersSlotMap.get(i).destroy();
+        }
+        mMmTelFeatureListenersSlotMap.clear();
+
+        for (int i = 0; i < mRcsFeatureListenersSlotMap.size(); i++) {
+            mRcsFeatureListenersSlotMap.get(i).destroy();
+        }
+        mRcsFeatureListenersSlotMap.clear();
+
+        for (int i = 0; i < mProvisioningCallbackManagersSlotMap.size(); i++) {
+            mProvisioningCallbackManagersSlotMap.get(i).clear();
+        }
+    }
+
+    /**
+     * create an instance
+     */
+    @VisibleForTesting
+    public static ImsProvisioningController make(PhoneGlobals app, int numSlot) {
+        synchronized (ImsProvisioningController.class) {
+            if (sInstance == null) {
+                Rlog.i(TAG, "ImsProvisioningController created");
+                HandlerThread handlerThread = new HandlerThread(TAG);
+                handlerThread.start();
+                sInstance = new ImsProvisioningController(app, numSlot, handlerThread.getLooper(),
+                        ImsManager::getConnector, RcsFeatureManager::getConnector,
+                        new ImsProvisioningLoader(app));
+            }
+        }
+        return sInstance;
+    }
+
+    /**
+     * Gets a ImsProvisioningController instance
+     */
+    @VisibleForTesting
+    public static ImsProvisioningController getInstance() {
+        synchronized (ImsProvisioningController.class) {
+            return sInstance;
+        }
+    }
+
+    /**
+     * Register IFeatureProvisioningCallback from ProvisioningManager
+     */
+
+    @VisibleForTesting
+    public void addFeatureProvisioningChangedCallback(int subId,
+            IFeatureProvisioningCallback callback) {
+        if (callback == null) {
+            throw new IllegalArgumentException("provisioning callback can't be null");
+        }
+        int slotId = getSlotId(subId);
+        if (slotId < 0 || slotId >= mNumSlot) {
+            throw new IllegalArgumentException("subscription id is not available");
+        }
+
+        try {
+            mProvisioningCallbackManagersSlotMap.get(slotId).registerCallback(callback);
+            log("Feature Provisioning Callback registered.");
+        } catch (NullPointerException e) {
+            logw("can not access callback manager to add callback");
+        }
+    }
+
+    /**
+     * Remove IFeatureProvisioningCallback
+     */
+    @VisibleForTesting
+    public void removeFeatureProvisioningChangedCallback(int subId,
+            IFeatureProvisioningCallback callback) {
+        if (callback == null) {
+            throw new IllegalArgumentException("provisioning callback can't be null");
+        }
+
+        int slotId = getSlotId(subId);
+        if (slotId < 0 || slotId >= mNumSlot) {
+            throw new IllegalArgumentException("subscription id is not available");
+        }
+
+        try {
+            mProvisioningCallbackManagersSlotMap.get(slotId).unregisterCallback(callback);
+            log("Feature Provisioning Callback removed.");
+        } catch (NullPointerException e) {
+            logw("can not access callback manager to remove callback");
+        }
+    }
+
+    /**
+     * return the boolean whether MmTel capability is required provisioning or not
+     */
+    @VisibleForTesting
+    public boolean isImsProvisioningRequiredForCapability(int subId, int capability, int tech) {
+        // check subId
+        int slotId = getSlotId(subId);
+        if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX || slotId >= mNumSlot) {
+            loge("Fail to retrieve slotId from subId");
+            throw new IllegalArgumentException("subscribe id is invalid");
+        }
+
+        // check valid capability
+        if (!(MMTEL_CAPABILITY_MIN < capability && capability < MMTEL_CAPABILITY_MAX)) {
+            throw new IllegalArgumentException("MmTel capability '" + capability + "' is invalid");
+        }
+
+        // check valid radio tech
+        if (!(REGISTRATION_TECH_NONE < tech && tech < REGISTRATION_TECH_MAX)) {
+            log("Ims not matched radio tech " + tech);
+            throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
+        }
+
+        boolean retVal = isProvisioningRequired(subId, capability, tech, /*isMmTel*/true);
+
+        log("isImsProvisioningRequiredForCapability capability " + capability
+                + " tech " + tech + " return value " + retVal);
+
+        return retVal;
+    }
+
+    /**
+     * return the boolean whether RCS capability is required provisioning or not
+     */
+    @VisibleForTesting
+    public boolean isRcsProvisioningRequiredForCapability(int subId, int capability, int tech) {
+        // check slotId and Phone object
+        int slotId = getSlotId(subId);
+        if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX || slotId >= mNumSlot) {
+            loge("Fail to retrieve slotId from subId");
+            throw new IllegalArgumentException("subscribe id is invalid");
+        }
+
+        // check valid capability
+        if (!(RCS_CAPABILITY_MIN < capability && capability < RCS_CAPABILITY_MAX)) {
+            throw new IllegalArgumentException("Rcs capability '" + capability + "' is invalid");
+        }
+
+        // check valid radio tech
+        if (!(REGISTRATION_TECH_NONE < tech && tech < REGISTRATION_TECH_MAX)) {
+            log("Rcs not matched radio tech " + tech);
+            throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
+        }
+
+        boolean retVal = isProvisioningRequired(subId, capability, tech, /*isMmTel*/false);
+
+        log("isRcsProvisioningRequiredForCapability capability " + capability
+                + " tech " + tech + " return value " + retVal);
+
+        return retVal;
+    }
+
+    /**
+     * return the provisioning status for MmTel capability in specific radio tech
+     */
+    @VisibleForTesting
+    public boolean getImsProvisioningStatusForCapability(int subId, int capability, int tech) {
+        boolean mmTelProvisioned = isImsProvisioningRequiredForCapability(subId, capability, tech);
+        if (!mmTelProvisioned) { // provisioning not required
+            log("getImsProvisioningStatusForCapability : not required "
+                    + " capability " + capability + " tech " + tech);
+            return true;
+        }
+
+        // read value from ImsProvisioningLoader
+        int result = mImsProvisioningLoader.getProvisioningStatus(subId, FEATURE_MMTEL,
+                capability, tech);
+        if (result == ImsProvisioningLoader.STATUS_NOT_SET) {
+            // not set means initial value
+            // read data from vendor ImsService and store that in ImsProvisioningLoader
+            result = getValueFromImsService(subId, capability, tech);
+            mmTelProvisioned = getBoolValue(result);
+            if (result != ProvisioningManager.PROVISIONING_RESULT_UNKNOWN) {
+                setAndNotifyMmTelProvisioningValue(subId, capability, tech, mmTelProvisioned);
+            }
+        } else {
+            mmTelProvisioned = getBoolValue(result);
+        }
+
+        log("getImsProvisioningStatusForCapability : "
+                + " capability " + capability
+                + " tech " + tech
+                + " result " + mmTelProvisioned);
+        return mmTelProvisioned;
+    }
+
+    /**
+     * set MmTel provisioning status in specific tech
+     */
+    @VisibleForTesting
+    public void setImsProvisioningStatusForCapability(int subId, int capability, int tech,
+            boolean isProvisioned) {
+        boolean mmTelProvisioned = isImsProvisioningRequiredForCapability(subId, capability, tech);
+        if (!mmTelProvisioned) { // provisioning not required
+            log("setImsProvisioningStatusForCapability : not required "
+                    + " capability " + capability + " tech " + tech);
+            return;
+        }
+
+        // write value to ImsProvisioningLoader
+        boolean isChanged = setAndNotifyMmTelProvisioningValue(subId, capability, tech,
+                isProvisioned);
+        if (!isChanged) {
+            log("status not changed mmtel capability " + capability + " tech " + tech);
+            return;
+        }
+
+        int slotId = getSlotId(subId);
+        // find matched key from capability and tech
+        int value = getIntValue(isProvisioned);
+        int key = getKeyFromCapability(capability, tech);
+        if (key != INVALID_VALUE) {
+            log("setImsProvisioningStatusForCapability : matched key " + key);
+            try {
+                // set key and value to vendor ImsService for MmTel
+                mMmTelFeatureListenersSlotMap.get(slotId).setProvisioningValue(key, value);
+            } catch (NullPointerException e) {
+                loge("can not access MmTelFeatureListener with capability " + capability);
+            }
+        }
+    }
+
+    /**
+     * return the provisioning status for RCS capability in specific radio tech
+     */
+    @VisibleForTesting
+    public boolean getRcsProvisioningStatusForCapability(int subId, int capability, int tech) {
+        boolean rcsProvisioned = isRcsProvisioningRequiredForCapability(subId, capability, tech);
+        if (!rcsProvisioned) { // provisioning not required
+            log("getRcsProvisioningStatusForCapability : not required"
+                    + " capability " + capability + " tech " + tech);
+            return true;
+        }
+
+        // read data from ImsProvisioningLoader
+        int result = mImsProvisioningLoader.getProvisioningStatus(subId, FEATURE_RCS,
+                capability, tech);
+        if (result == ImsProvisioningLoader.STATUS_NOT_SET) {
+            // not set means initial value
+            // read data from vendor ImsService and store that in ImsProvisioningLoader
+            result = getRcsValueFromImsService(subId, capability);
+            rcsProvisioned = getBoolValue(result);
+            if (result != ProvisioningManager.PROVISIONING_RESULT_UNKNOWN) {
+                setAndNotifyRcsProvisioningValueForAllTech(subId, capability, rcsProvisioned);
+            }
+        } else {
+            rcsProvisioned = getBoolValue(result);
+        }
+
+        log("getRcsProvisioningStatusForCapability : "
+                + " capability " + capability
+                + " tech " + tech
+                + " result " + rcsProvisioned);
+        return rcsProvisioned;
+    }
+
+    /**
+     * set RCS provisioning status in specific tech
+     */
+    @VisibleForTesting
+    public void setRcsProvisioningStatusForCapability(int subId, int capability, int tech,
+            boolean isProvisioned) {
+        boolean rcsProvisioned = isRcsProvisioningRequiredForCapability(subId, capability, tech);
+        if (!rcsProvisioned) { // provisioning not required
+            log("set rcs provisioning status but not required");
+            return;
+        }
+
+        // write status using ImsProvisioningLoader
+        boolean isChanged = setAndNotifyRcsProvisioningValue(subId, capability, tech,
+                isProvisioned);
+        if (!isChanged) {
+            log("status not changed rcs capability " + capability + " tech " + tech);
+            return;
+        }
+
+        int slotId = getSlotId(subId);
+        int key =  ProvisioningManager.KEY_EAB_PROVISIONING_STATUS;
+        int value = getIntValue(isProvisioned);
+        try {
+            // set key and value to vendor ImsService for Rcs
+            mRcsFeatureListenersSlotMap.get(slotId).setProvisioningValue(key, value);
+        } catch (NullPointerException e) {
+            loge("can not access RcsFeatureListener with capability " + capability);
+        }
+    }
+
+    /**
+     * set RCS provisioning status in specific key and value
+     * @param key integer key, defined as one of
+     * {@link ProvisioningManager#KEY_VOLTE_PROVISIONING_STATUS}
+     * {@link ProvisioningManager#KEY_VT_PROVISIONING_STATUS}
+     * {@link ProvisioningManager#KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE}
+     * {@link ProvisioningManager#KEY_EAB_PROVISIONING_STATUS}
+     * @param value in Integer format.
+     * @return the result of setting the configuration value, defined as one of
+     * {@link ImsConfigImplBase#CONFIG_RESULT_FAILED} or
+     * {@link ImsConfigImplBase#CONFIG_RESULT_SUCCESS} or
+     */
+    @VisibleForTesting
+    public int setProvisioningValue(int subId, int key, int value) {
+        log("setProvisioningValue");
+
+        int retVal = ImsConfigImplBase.CONFIG_RESULT_FAILED;
+        // check key value
+        if (!Arrays.stream(LOCAL_IMS_CONFIG_KEYS).anyMatch(keyValue -> keyValue == key)) {
+            log("not matched key " + key);
+            return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
+        }
+
+        // check subId
+        int slotId = getSlotId(subId);
+        if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX || slotId >= mNumSlot) {
+            loge("Fail to retrieve slotId from subId");
+            return ImsConfigImplBase.CONFIG_RESULT_FAILED;
+        }
+
+        try {
+            if (key == KEY_EAB_PROVISIONING_STATUS) {
+                // set key and value to vendor ImsService for Rcs
+                retVal = mRcsFeatureListenersSlotMap.get(slotId)
+                        .setProvisioningValue(key, value);
+            } else {
+                // set key and value to vendor ImsService for MmTel
+                retVal = mMmTelFeatureListenersSlotMap.get(slotId)
+                        .setProvisioningValue(key, value);
+            }
+        } catch (NullPointerException e) {
+            loge("can not access FeatureListener to set provisioning value");
+            return ImsConfigImplBase.CONFIG_RESULT_FAILED;
+        }
+
+        // update and notify provisioning status changed capability and tech from key
+        updateCapabilityTechFromKey(subId, key, value);
+
+        return retVal;
+    }
+
+    /**
+     * get RCS provisioning status in specific key and value
+     * @param key integer key, defined as one of
+     * {@link ProvisioningManager#KEY_VOLTE_PROVISIONING_STATUS}
+     * {@link ProvisioningManager#KEY_VT_PROVISIONING_STATUS}
+     * {@link ProvisioningManager#KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE}
+     * {@link ProvisioningManager#KEY_EAB_PROVISIONING_STATUS}
+     * @return the result of setting the configuration value, defined as one of
+     * {@link ImsConfigImplBase#CONFIG_RESULT_FAILED} or
+     * {@link ImsConfigImplBase#CONFIG_RESULT_SUCCESS} or
+     * {@link ImsConfigImplBase#CONFIG_RESULT_UNKNOWN}
+     */
+    @VisibleForTesting
+    public int getProvisioningValue(int subId, int key) {
+        // check key value
+        if (!Arrays.stream(LOCAL_IMS_CONFIG_KEYS).anyMatch(keyValue -> keyValue == key)) {
+            log("not matched key " + key);
+            return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
+        }
+
+        // check subId
+        int slotId = getSlotId(subId);
+        if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX || slotId >= mNumSlot) {
+            loge("Fail to retrieve slotId from subId");
+            return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
+        }
+
+        // check data from ImsProvisioningLoader
+        int capability = getCapabilityFromKey(key);
+        int tech = getTechFromKey(key);
+        int result;
+        if (capability != INVALID_VALUE && tech != INVALID_VALUE) {
+            if (key == KEY_EAB_PROVISIONING_STATUS) {
+                result = mImsProvisioningLoader.getProvisioningStatus(subId, FEATURE_RCS,
+                        capability, tech);
+            } else {
+                result = mImsProvisioningLoader.getProvisioningStatus(subId, FEATURE_MMTEL,
+                        capability, tech);
+            }
+            if (result != ImsProvisioningLoader.STATUS_NOT_SET) {
+                log("getProvisioningValue from loader : key " + key + " result " + result);
+                return result;
+            }
+        }
+
+        // get data from ImsService, update it in ImsProvisioningLoader
+        if (key == KEY_EAB_PROVISIONING_STATUS) {
+            result = getRcsValueFromImsService(subId, capability);
+            if (result == ImsConfigImplBase.CONFIG_RESULT_UNKNOWN) {
+                logw("getProvisioningValue : fail to get data from ImsService capability"
+                        + capability);
+                return result;
+            }
+            log("getProvisioningValue from vendor : key " + key + " result " + result);
+
+            setAndNotifyRcsProvisioningValueForAllTech(subId, capability, getBoolValue(result));
+            return result;
+        } else {
+            result = getValueFromImsService(subId, capability, tech);
+            if (result == ImsConfigImplBase.CONFIG_RESULT_UNKNOWN) {
+                logw("getProvisioningValue : fail to get data from ImsService capability"
+                        + capability);
+                return result;
+            }
+            log("getProvisioningValue from vendor : key " + key + " result " + result);
+
+            setAndNotifyMmTelProvisioningValue(subId, capability, tech, getBoolValue(result));
+            return result;
+        }
+    }
+
+    /**
+     * get the handler
+     */
+    @VisibleForTesting
+    public Handler getHandler() {
+        return mHandler;
+    }
+
+    private boolean isProvisioningRequired(int subId, int capability, int tech, boolean isMmTel) {
+        int[] techArray;
+        techArray = getTechsFromCarrierConfig(subId, capability, isMmTel);
+        if (techArray == null) {
+            logw("isProvisioningRequired : getTechsFromCarrierConfig failed");
+            // not exist in CarrierConfig that means provisioning is not required
+            return false;
+        }
+
+        // compare with carrier config
+        if (Arrays.stream(techArray).anyMatch(keyValue -> keyValue == tech)) {
+            // existing same tech means provisioning required
+            return true;
+        }
+
+        log("isProvisioningRequired : not matched capability " + capability + " tech " + tech);
+        return false;
+    }
+
+    @VisibleForTesting
+    protected int[] getTechsFromCarrierConfig(int subId, int capability, boolean isMmTel) {
+        String featureKey;
+        String capabilityKey;
+        if (isMmTel) {
+            featureKey = CarrierConfigManager.Ims.KEY_MMTEL_REQUIRES_PROVISIONING_BUNDLE;
+            capabilityKey = KEYS_MMTEL_CAPABILITY.get(capability);
+        } else {
+            featureKey = CarrierConfigManager.Ims.KEY_RCS_REQUIRES_PROVISIONING_BUNDLE;
+            capabilityKey = KEYS_RCS_CAPABILITY.get(capability);
+        }
+
+        if (capabilityKey != null) {
+            PersistableBundle imsCarrierConfigs = mCarrierConfigManager.getConfigForSubId(subId);
+            if (imsCarrierConfigs == null) {
+                log("getTechsFromCarrierConfig : imsCarrierConfigs null");
+                return null;
+            }
+
+            PersistableBundle provisioningBundle =
+                    imsCarrierConfigs.getPersistableBundle(featureKey);
+            if (provisioningBundle == null) {
+                log("getTechsFromCarrierConfig : provisioningBundle null");
+                return null;
+            }
+
+            return provisioningBundle.getIntArray(capabilityKey);
+        }
+
+        return null;
+    }
+
+    private int getValueFromImsService(int subId, int capability, int tech) {
+        int config = ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
+
+        // operation is based on capability
+        switch (capability) {
+            case CAPABILITY_TYPE_VOICE:
+                int item = (tech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN)
+                        ? ProvisioningManager.KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE
+                        : ProvisioningManager.KEY_VOLTE_PROVISIONING_STATUS;
+                // read data from vendor ImsService
+                config = mMmTelFeatureListenersSlotMap.get(getSlotId(subId))
+                        .getProvisioningValue(item);
+                break;
+            case CAPABILITY_TYPE_VIDEO:
+                // read data from vendor ImsService
+                config = mMmTelFeatureListenersSlotMap.get(getSlotId(subId))
+                        .getProvisioningValue(ProvisioningManager.KEY_VT_PROVISIONING_STATUS);
+                break;
+            default:
+                log("Capability " + capability + " has been provisioning");
+                break;
+        }
+
+        return config;
+    }
+
+    private int getRcsValueFromImsService(int subId, int capability) {
+        int config = ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
+
+        if (capability == CAPABILITY_TYPE_PRESENCE_UCE) {
+            try {
+                config = mRcsFeatureListenersSlotMap.get(getSlotId(subId))
+                        .getProvisioningValue(ProvisioningManager.KEY_EAB_PROVISIONING_STATUS);
+            } catch (NullPointerException e) {
+                logw("can not access RcsFeatureListener");
+            }
+        } else {
+            log("Capability " + capability + " has been provisioning");
+        }
+
+        return config;
+    }
+
+    private void onSubscriptionsChanged() {
+        for (int index = 0; index < mMmTelFeatureListenersSlotMap.size(); index++) {
+            MmTelFeatureListener m = mMmTelFeatureListenersSlotMap.get(index);
+            m.setSubId(getSubId(index));
+        }
+        for (int index = 0; index < mRcsFeatureListenersSlotMap.size(); index++) {
+            RcsFeatureListener r = mRcsFeatureListenersSlotMap.get(index);
+            r.setSubId(getSubId(index));
+        }
+        for (int index = 0; index < mProvisioningCallbackManagersSlotMap.size(); index++) {
+            ProvisioningCallbackManager m = mProvisioningCallbackManagersSlotMap.get(index);
+            m.setSubId(getSubId(index));
+        }
+    }
+
+    private void  updateCapabilityTechFromKey(int subId, int key, int value) {
+        boolean isProvisioned = getBoolValue(value);
+        int capability = getCapabilityFromKey(key);
+        int tech = getTechFromKey(key);
+
+        if (capability == INVALID_VALUE || tech == INVALID_VALUE) {
+            logw("updateCapabilityTechFromKey : unknown key " + key);
+            return;
+        }
+
+        if (key == KEY_VOLTE_PROVISIONING_STATUS
+                || key == KEY_VT_PROVISIONING_STATUS
+                || key == KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE) {
+            setAndNotifyMmTelProvisioningValue(subId, capability, tech, isProvisioned);
+        }
+        if (key == KEY_EAB_PROVISIONING_STATUS) {
+            setAndNotifyRcsProvisioningValueForAllTech(subId, capability, isProvisioned);
+        }
+    }
+
+    private int getCapabilityFromKey(int key) {
+        int capability;
+        switch (key) {
+            case ProvisioningManager.KEY_VOLTE_PROVISIONING_STATUS:
+                // intentional fallthrough
+            case ProvisioningManager.KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE:
+                capability = CAPABILITY_TYPE_VOICE;
+                break;
+            case ProvisioningManager.KEY_VT_PROVISIONING_STATUS:
+                capability = CAPABILITY_TYPE_VIDEO;
+                break;
+            case ProvisioningManager.KEY_EAB_PROVISIONING_STATUS:
+                // default CAPABILITY_TYPE_PRESENCE_UCE used for KEY_EAB_PROVISIONING_STATUS
+                capability = CAPABILITY_TYPE_PRESENCE_UCE;
+                break;
+            default:
+                capability = INVALID_VALUE;
+                break;
+        }
+        return capability;
+    }
+
+    private int getTechFromKey(int key) {
+        int tech;
+        switch (key) {
+            case ProvisioningManager.KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE:
+                tech = ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN;
+                break;
+            case ProvisioningManager.KEY_VOLTE_PROVISIONING_STATUS:
+                // intentional fallthrough
+            case ProvisioningManager.KEY_VT_PROVISIONING_STATUS:
+                // intentional fallthrough
+            case ProvisioningManager.KEY_EAB_PROVISIONING_STATUS:
+                tech = ImsRegistrationImplBase.REGISTRATION_TECH_LTE;
+                break;
+            default:
+                tech = INVALID_VALUE;
+                break;
+        }
+        return tech;
+    }
+
+    private int getKeyFromCapability(int capability, int tech) {
+        int key = INVALID_VALUE;
+        if (capability == CAPABILITY_TYPE_VOICE && tech == REGISTRATION_TECH_IWLAN) {
+            key = ProvisioningManager.KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE;
+        } else if (capability == CAPABILITY_TYPE_VOICE && tech == REGISTRATION_TECH_LTE) {
+            key = ProvisioningManager.KEY_VOLTE_PROVISIONING_STATUS;
+        } else if (capability == CAPABILITY_TYPE_VIDEO && tech == REGISTRATION_TECH_LTE) {
+            key = ProvisioningManager.KEY_VT_PROVISIONING_STATUS;
+        }
+
+        return key;
+    }
+
+    protected int getSubId(int slotId) {
+        final int[] subIds = mSubscriptionManager.getSubscriptionIds(slotId);
+        int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+        if (subIds != null && subIds.length >= 1) {
+            subId = subIds[0];
+        }
+
+        return subId;
+    }
+
+    protected int getSlotId(int subId) {
+        return mSubscriptionManager.getPhoneId(subId);
+    }
+
+    protected ImsConfig getImsConfig(ImsManager imsManager) throws ImsException {
+        return imsManager.getConfigInterface();
+    }
+
+    protected ImsConfig getImsConfig(IImsConfig iImsConfig) {
+        return new ImsConfig(iImsConfig);
+    }
+
+    private int getIntValue(boolean isProvisioned) {
+        return isProvisioned ? ProvisioningManager.PROVISIONING_VALUE_ENABLED
+                : ProvisioningManager.PROVISIONING_VALUE_DISABLED;
+    }
+
+    private boolean getBoolValue(int value) {
+        return value == ProvisioningManager.PROVISIONING_VALUE_ENABLED ? true : false;
+    }
+
+    private boolean setAndNotifyMmTelProvisioningValue(int subId, int capability, int tech,
+            boolean isProvisioned) {
+        boolean changed = mImsProvisioningLoader.setProvisioningStatus(subId, FEATURE_MMTEL,
+                capability, tech, isProvisioned);
+        // notify MmTel capability changed
+        if (changed) {
+            mHandler.sendMessage(mHandler.obtainMessage(EVENT_PROVISIONING_CAPABILITY_CHANGED,
+                    getSlotId(subId), 0, (Object) new FeatureProvisioningData(
+                            capability, tech, isProvisioned, /*isMmTel*/true)));
+        }
+
+        return changed;
+    }
+
+    private boolean setAndNotifyRcsProvisioningValue(int subId, int capability, int tech,
+            boolean isProvisioned) {
+        boolean isChanged = mImsProvisioningLoader.setProvisioningStatus(subId, FEATURE_RCS,
+                capability, tech, isProvisioned);
+
+        if (isChanged) {
+            int slotId = getSlotId(subId);
+
+            // notify RCS capability changed
+            mHandler.sendMessage(mHandler.obtainMessage(EVENT_PROVISIONING_CAPABILITY_CHANGED,
+                    slotId, 0, (Object) new FeatureProvisioningData(
+                            capability, tech, isProvisioned, /*isMmtel*/false)));
+        }
+
+        return isChanged;
+    }
+
+    private boolean setAndNotifyRcsProvisioningValueForAllTech(int subId, int capability,
+            boolean isProvisioned) {
+        boolean isChanged = false;
+
+        for (int tech : LOCAL_RADIO_TECHS) {
+            isChanged |= setAndNotifyRcsProvisioningValue(subId, capability, tech, isProvisioned);
+        }
+
+        return isChanged;
+    }
+
+    protected boolean isValidSubId(int subId) {
+        int slotId = getSlotId(subId);
+        if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX || slotId >= mNumSlot) {
+            return false;
+        }
+
+        return true;
+    }
+
+    private void log(String s) {
+        Rlog.d(TAG, s);
+    }
+
+    private void log(String prefix, int slotId, String s) {
+        Rlog.d(TAG, prefix + "[" + slotId + "] " + s);
+    }
+
+    private void logi(String prefix, int slotId, String s) {
+        Rlog.i(TAG, prefix + "[" + slotId + "] " + s);
+    }
+
+    private void logw(String s) {
+        Rlog.w(TAG, s);
+    }
+
+    private void logw(String prefix, int slotId, String s) {
+        Rlog.w(TAG, prefix + "[" + slotId + "] " + s);
+    }
+
+    private void loge(String s) {
+        Rlog.e(TAG, s);
+    }
+
+    private void loge(String prefix, int slotId, String s) {
+        Rlog.e(TAG, prefix + "[" + slotId + "] " + s);
+    }
+}
diff --git a/src/com/android/phone/ImsProvisioningLoader.java b/src/com/android/phone/ImsProvisioningLoader.java
new file mode 100644
index 0000000..1238b9a
--- /dev/null
+++ b/src/com/android/phone/ImsProvisioningLoader.java
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2021 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.content.Context;
+import android.content.SharedPreferences;
+import android.os.PersistableBundle;
+import android.preference.PreferenceManager;
+import android.telephony.ims.ProvisioningManager;
+import android.telephony.ims.feature.ImsFeature;
+import android.telephony.ims.feature.MmTelFeature;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * Provides a function to set/get Ims feature provisioning status in storage.
+ */
+public class ImsProvisioningLoader {
+    private static final String LOG_TAG = ImsProvisioningLoader.class.getSimpleName();
+
+    public static final int STATUS_NOT_SET = -1;
+    public static final int STATUS_NOT_PROVISIONED =
+            ProvisioningManager.PROVISIONING_VALUE_DISABLED;
+    public static final int STATUS_PROVISIONED =
+            ProvisioningManager.PROVISIONING_VALUE_ENABLED;
+
+    public static final int IMS_FEATURE_MMTEL = ImsFeature.FEATURE_MMTEL;
+    public static final int IMS_FEATURE_RCS = ImsFeature.FEATURE_RCS;
+
+    private static final String PROVISIONING_FILE_NAME_PREF = "imsprovisioningstatus_";
+    private static final String PREF_PROVISION_IMS_MMTEL_PREFIX = "provision_ims_mmtel_";
+
+    private Context mContext;
+    private SharedPreferences mTelephonySharedPreferences;
+    // key : sub Id, value : read from sub Id's xml and it's in-memory cache
+    private SparseArray<PersistableBundle> mSubIdBundleArray = new SparseArray<>();
+    private final Object mLock = new Object();
+
+    public ImsProvisioningLoader(Context context) {
+        mContext = context;
+        mTelephonySharedPreferences =
+                PreferenceManager.getDefaultSharedPreferences(context);
+    }
+
+    /**
+     * Get Ims feature provisioned status in storage
+     */
+    public int getProvisioningStatus(int subId, @ImsFeature.FeatureType int imsFeature,
+            int capability, @ImsRegistrationImplBase.ImsRegistrationTech int tech) {
+        initCache(subId);
+        return getImsProvisioningStatus(subId, imsFeature, tech,
+                capability);
+    }
+
+    /**
+     * Set Ims feature provisioned status in storage
+     */
+    public boolean setProvisioningStatus(int subId, @ImsFeature.FeatureType int imsFeature,
+            int capability, @ImsRegistrationImplBase.ImsRegistrationTech int tech,
+            boolean isProvisioned) {
+        initCache(subId);
+        return setImsFeatureProvisioning(subId, imsFeature, tech, capability,
+                isProvisioned);
+    }
+
+    private boolean isFileExist(int subId) {
+        File file = new File(mContext.getFilesDir(), getFileName(subId));
+        return file.exists();
+    }
+
+    private void initCache(int subId) {
+        synchronized (mLock) {
+            PersistableBundle subIdBundle = mSubIdBundleArray.get(subId, null);
+            if (subIdBundle != null) {
+                // initCache() has already been called for the subId
+                return;
+            }
+            if (isFileExist(subId)) {
+                subIdBundle = readSubIdBundleFromXml(subId);
+            } else {
+                // It should read the MMTEL capability cache as part of shared prefs and migrate
+                // over any configs for UT.
+                final int[] regTech = {ImsRegistrationImplBase.REGISTRATION_TECH_LTE,
+                        ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN,
+                        ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM,
+                        ImsRegistrationImplBase.REGISTRATION_TECH_NR};
+                subIdBundle = new PersistableBundle();
+                for (int tech : regTech) {
+                    int UtProvisioningStatus = getUTProvisioningStatus(subId, tech);
+                    logd("check UT provisioning status " + UtProvisioningStatus);
+
+                    if (STATUS_PROVISIONED == UtProvisioningStatus) {
+                        setProvisioningStatusToSubIdBundle(ImsFeature.FEATURE_MMTEL, tech,
+                                MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT, subIdBundle,
+                                UtProvisioningStatus);
+                    }
+                }
+                saveSubIdBundleToXml(subId, subIdBundle);
+            }
+            mSubIdBundleArray.put(subId, subIdBundle);
+        }
+    }
+
+    private int getImsProvisioningStatus(int subId, int imsFeature, int tech, int capability) {
+        PersistableBundle subIdBundle = null;
+        synchronized (mLock) {
+            subIdBundle = mSubIdBundleArray.get(subId, null);
+        }
+
+        return getProvisioningStatusFromSubIdBundle(imsFeature, tech,
+                capability, subIdBundle);
+    }
+
+    private boolean setImsFeatureProvisioning(int subId, int imsFeature, int tech, int capability,
+            boolean isProvisioned) {
+        synchronized (mLock) {
+            int preValue = getImsProvisioningStatus(subId, imsFeature, tech, capability);
+            int newValue = isProvisioned ? STATUS_PROVISIONED : STATUS_NOT_PROVISIONED;
+            if (preValue == newValue) {
+                logd("already stored provisioning status " + isProvisioned + " ImsFeature "
+                        + imsFeature + " tech " + tech + " capa " + capability);
+                return false;
+            }
+
+            PersistableBundle subIdBundle = mSubIdBundleArray.get(subId, null);
+            setProvisioningStatusToSubIdBundle(imsFeature, tech, capability, subIdBundle,
+                    newValue);
+            saveSubIdBundleToXml(subId, subIdBundle);
+        }
+        return true;
+    }
+
+    private int getProvisioningStatusFromSubIdBundle(int imsFeature, int tech,
+            int capability, PersistableBundle subIdBundle) {
+        // If it doesn't exist in xml, return STATUS_NOT_SET
+        if (subIdBundle == null || subIdBundle.isEmpty()) {
+            logd("xml is empty");
+            return STATUS_NOT_SET;
+        }
+
+        PersistableBundle regTechBundle = subIdBundle.getPersistableBundle(
+                String.valueOf(imsFeature));
+        if (regTechBundle == null) {
+            logd("ImsFeature " + imsFeature + " is not exist in xml");
+            return STATUS_NOT_SET;
+        }
+
+        PersistableBundle capabilityBundle = regTechBundle.getPersistableBundle(
+                String.valueOf(tech));
+        if (capabilityBundle == null) {
+            logd("RegistrationTech " + tech + " is not exist in xml");
+            return STATUS_NOT_SET;
+        }
+
+        return getIntValueFromBundle(String.valueOf(capability), capabilityBundle);
+    }
+
+    private void setProvisioningStatusToSubIdBundle(int imsFeature, int tech,
+            int capability, PersistableBundle subIdBundle, int newStatus) {
+        logd("set provisioning status " + newStatus + " ImsFeature "
+                + imsFeature + " tech " + tech + " capa " + capability);
+
+        PersistableBundle regTechBundle = subIdBundle.getPersistableBundle(
+                String.valueOf(imsFeature));
+        if (regTechBundle == null) {
+            regTechBundle = new PersistableBundle();
+            subIdBundle.putPersistableBundle(String.valueOf(imsFeature), regTechBundle);
+        }
+
+        PersistableBundle capabilityBundle = regTechBundle.getPersistableBundle(
+                String.valueOf(tech));
+        if (capabilityBundle == null) {
+            capabilityBundle = new PersistableBundle();
+            regTechBundle.putPersistableBundle(String.valueOf(tech), capabilityBundle);
+        }
+
+        capabilityBundle.putInt(String.valueOf(capability), newStatus);
+    }
+
+    // Default value is STATUS_NOT_SET
+    private int getIntValueFromBundle(String key, PersistableBundle bundle) {
+        int value = bundle.getInt(key, STATUS_NOT_SET);
+        logd("get value " + value);
+        return value;
+    }
+
+    // Return subIdBundle from imsprovisioningstatus_{subId}.xml
+    private PersistableBundle readSubIdBundleFromXml(int subId) {
+        String fileName = getFileName(subId);
+
+        PersistableBundle subIdBundles = new PersistableBundle();
+        File file = null;
+        FileInputStream inFile = null;
+        synchronized (mLock) {
+            try {
+                file = new File(mContext.getFilesDir(), fileName);
+                inFile = new FileInputStream(file);
+                subIdBundles = PersistableBundle.readFromStream(inFile);
+                inFile.close();
+            } catch (FileNotFoundException e) {
+                logd(e.toString());
+            } catch (IOException e) {
+                loge(e.toString());
+            } catch (RuntimeException e) {
+                loge(e.toString());
+            }
+        }
+
+        return subIdBundles;
+    }
+
+    private void saveSubIdBundleToXml(int subId, PersistableBundle subIdBundle) {
+        String fileName = getFileName(subId);
+
+        if (subIdBundle == null || subIdBundle.isEmpty()) {
+            logd("subIdBundle is empty");
+            return;
+        }
+
+        FileOutputStream outFile = null;
+        synchronized (mLock) {
+            try {
+                outFile = new FileOutputStream(new File(mContext.getFilesDir(), fileName));
+                subIdBundle.writeToStream(outFile);
+                outFile.flush();
+                outFile.close();
+            } catch (IOException e) {
+                loge(e.toString());
+            } catch (RuntimeException e) {
+                loge(e.toString());
+            }
+        }
+    }
+
+    private int getUTProvisioningStatus(int subId, int tech) {
+        return getMmTelCapabilityProvisioningBitfield(subId, tech) > 0 ? STATUS_PROVISIONED
+                : STATUS_NOT_SET;
+    }
+
+    /**
+     * @return the bitfield containing the MmTel provisioning for the provided subscription and
+     * technology. The bitfield should mirror the bitfield defined by
+     * {@link MmTelFeature.MmTelCapabilities.MmTelCapability}.
+     */
+    private int getMmTelCapabilityProvisioningBitfield(int subId, int tech) {
+        String key = getMmTelProvisioningKey(subId, tech);
+        // Default is no capabilities are provisioned.
+        return mTelephonySharedPreferences.getInt(key, 0 /*default*/);
+    }
+
+    private String getMmTelProvisioningKey(int subId, int tech) {
+        // Resulting key is provision_ims_mmtel_{subId}_{tech}
+        return PREF_PROVISION_IMS_MMTEL_PREFIX + subId + "_" + tech;
+    }
+
+    private String getFileName(int subId) {
+        // Resulting name is imsprovisioningstatus_{subId}.xml
+        return PROVISIONING_FILE_NAME_PREF + subId + ".xml";
+    }
+
+    @VisibleForTesting
+    void clear() {
+        synchronized (mLock) {
+            mSubIdBundleArray.clear();
+        }
+    }
+
+    @VisibleForTesting
+    void setProvisioningToXml(int subId, PersistableBundle subIdBundle,
+            String[] infoArray) {
+        for (String info : infoArray) {
+            String[] paramArray = info.split(",");
+            setProvisioningStatusToSubIdBundle(Integer.valueOf(paramArray[0]),
+                    Integer.valueOf(paramArray[1]), Integer.valueOf(paramArray[2]),
+                    subIdBundle, Integer.valueOf(paramArray[3]));
+        }
+        saveSubIdBundleToXml(subId, subIdBundle);
+    }
+
+    private void loge(String contents) {
+        Log.e(LOG_TAG, contents);
+    }
+
+    private void logd(String contents) {
+        Log.d(LOG_TAG, contents);
+    }
+
+}
diff --git a/src/com/android/phone/ImsStateCallbackController.java b/src/com/android/phone/ImsStateCallbackController.java
index 28fca59..4e2407c 100644
--- a/src/com/android/phone/ImsStateCallbackController.java
+++ b/src/com/android/phone/ImsStateCallbackController.java
@@ -292,7 +292,7 @@
         }
 
         @Override
-        public void connectionReady(ImsManager manager) {
+        public void connectionReady(ImsManager manager, int subId) {
             logd(mLogPrefix + "connectionReady");
 
             mState = STATE_READY;
@@ -434,7 +434,7 @@
         }
 
         @Override
-        public void connectionReady(RcsFeatureManager manager) {
+        public void connectionReady(RcsFeatureManager manager, int subId) {
             logd(mLogPrefix + "connectionReady");
 
             mState = STATE_READY;
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index e7cb28c..a4f405b 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -73,7 +73,6 @@
 import com.android.internal.telephony.ims.ImsResolver;
 import com.android.internal.telephony.imsphone.ImsPhone;
 import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
-import com.android.internal.telephony.uicc.UiccCard;
 import com.android.internal.telephony.uicc.UiccPort;
 import com.android.internal.telephony.uicc.UiccProfile;
 import com.android.internal.util.IndentingPrintWriter;
@@ -161,6 +160,7 @@
     public PhoneInterfaceManager phoneMgr;
     public ImsRcsController imsRcsController;
     public ImsStateCallbackController mImsStateCallbackController;
+    public ImsProvisioningController mImsProvisioningController;
     CarrierConfigLoader configLoader;
 
     private Phone phoneInEcm;
@@ -470,6 +470,8 @@
                         PhoneFactory.getPhones().length);
                 mTelephonyRcsService.initialize();
                 imsRcsController.setRcsService(mTelephonyRcsService);
+                mImsProvisioningController =
+                        ImsProvisioningController.make(this, PhoneFactory.getPhones().length);
             }
 
             configLoader = CarrierConfigLoader.init(this);
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index a807b11..402e7f8 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -22,6 +22,7 @@
 import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_GSM;
 import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_IMS;
 import static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY;
+import static com.android.internal.telephony.TelephonyStatsLog.RCS_CLIENT_PROVISIONING_STATS__EVENT__CLIENT_PARAMS_SENT;
 
 import android.Manifest;
 import android.Manifest.permission;
@@ -122,6 +123,7 @@
 import android.telephony.ims.RcsClientConfiguration;
 import android.telephony.ims.RcsContactUceCapability;
 import android.telephony.ims.RegistrationManager;
+import android.telephony.ims.aidl.IFeatureProvisioningCallback;
 import android.telephony.ims.aidl.IImsCapabilityCallback;
 import android.telephony.ims.aidl.IImsConfig;
 import android.telephony.ims.aidl.IImsConfigCallback;
@@ -186,6 +188,7 @@
 import com.android.internal.telephony.ims.ImsResolver;
 import com.android.internal.telephony.imsphone.ImsPhone;
 import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
+import com.android.internal.telephony.metrics.RcsStats;
 import com.android.internal.telephony.metrics.TelephonyMetrics;
 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
 import com.android.internal.telephony.uicc.IccIoResult;
@@ -2799,8 +2802,13 @@
             int subId = mSubscriptionController.getDefaultDataSubId();
             final Phone phone = getPhone(subId);
             if (phone != null) {
-                phone.getDataEnabledSettings().setDataEnabled(
-                        TelephonyManager.DATA_ENABLED_REASON_USER, true);
+                if (phone.isUsingNewDataStack()) {
+                    phone.getDataSettingsManager().setDataEnabled(
+                            TelephonyManager.DATA_ENABLED_REASON_USER, true);
+                } else {
+                    phone.getDataEnabledSettings().setDataEnabled(
+                            TelephonyManager.DATA_ENABLED_REASON_USER, true);
+                }
                 return true;
             } else {
                 return false;
@@ -2820,8 +2828,13 @@
             int subId = mSubscriptionController.getDefaultDataSubId();
             final Phone phone = getPhone(subId);
             if (phone != null) {
-                phone.getDataEnabledSettings().setDataEnabled(
-                        TelephonyManager.DATA_ENABLED_REASON_USER, false);
+                if (phone.isUsingNewDataStack()) {
+                    phone.getDataSettingsManager().setDataEnabled(
+                            TelephonyManager.DATA_ENABLED_REASON_USER, false);
+                } else {
+                    phone.getDataEnabledSettings().setDataEnabled(
+                            TelephonyManager.DATA_ENABLED_REASON_USER, false);
+                }
                 return true;
             } else {
                 return false;
@@ -2937,6 +2950,9 @@
         try {
             final Phone phone = getPhone(subId);
             if (phone != null) {
+                if (phone.isUsingNewDataStack()) {
+                    return phone.getDataNetworkController().getInternetDataNetworkState();
+                }
                 return PhoneConstantConversions.convertDataState(phone.getDataConnectionState());
             } else {
                 return PhoneConstantConversions.convertDataState(
@@ -4523,6 +4539,7 @@
     @Override
     public void registerImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
         enforceReadPrivilegedPermission("registerImsProvisioningChangedCallback");
+
         final long identity = Binder.clearCallingIdentity();
         try {
             if (!isImsAvailableOnDevice()) {
@@ -4543,6 +4560,7 @@
     @Override
     public void unregisterImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
         enforceReadPrivilegedPermission("unregisterImsProvisioningChangedCallback");
+
         final long identity = Binder.clearCallingIdentity();
         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
@@ -4560,6 +4578,39 @@
         }
     }
 
+    @Override
+    public void registerFeatureProvisioningChangedCallback(int subId,
+            IFeatureProvisioningCallback callback) {
+        TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
+                mApp, subId, "registerFeatureProvisioningChangedCallback");
+
+        final long identity = Binder.clearCallingIdentity();
+        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
+            throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
+        }
+
+        ImsProvisioningController.getInstance()
+                .addFeatureProvisioningChangedCallback(subId, callback);
+
+        Binder.restoreCallingIdentity(identity);
+    }
+
+    @Override
+    public void unregisterFeatureProvisioningChangedCallback(int subId,
+            IFeatureProvisioningCallback callback) {
+        TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
+                mApp, subId, "unregisterFeatureProvisioningChangedCallback");
+
+        final long identity = Binder.clearCallingIdentity();
+        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
+            throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
+        }
+
+        ImsProvisioningController.getInstance()
+                .removeFeatureProvisioningChangedCallback(subId, callback);
+
+        Binder.restoreCallingIdentity(identity);
+    }
 
     private void checkModifyPhoneStatePermission(int subId, String message) {
         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
@@ -4586,60 +4637,30 @@
     }
 
     @Override
-    public void setRcsProvisioningStatusForCapability(int subId, int capability,
+    public void setRcsProvisioningStatusForCapability(int subId, int capability, int tech,
             boolean isProvisioned) {
         checkModifyPhoneStatePermission(subId, "setRcsProvisioningStatusForCapability");
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
-            if (!isImsProvisioningRequired(subId, capability, false)) {
-                return;
-            }
-
-            // this capability requires provisioning, route to the correct API.
-            ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
-            switch (capability) {
-                case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE:
-                case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
-                    ims.setEabProvisioned(isProvisioned);
-                    break;
-                default: {
-                    throw new IllegalArgumentException("Tried to set provisioning for "
-                            + "rcs capability '" + capability + "', which does not require "
-                            + "provisioning.");
-                }
-            }
+            ImsProvisioningController.getInstance()
+                    .setRcsProvisioningStatusForCapability(subId, capability, tech, isProvisioned);
+            return;
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
-
     }
 
 
     @Override
-    public boolean getRcsProvisioningStatusForCapability(int subId, int capability) {
-        enforceReadPrivilegedPermission("getRcsProvisioningStatusForCapability");
+    public boolean getRcsProvisioningStatusForCapability(int subId, int capability, int tech) {
+        TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
+                mApp, subId, "getRcsProvisioningStatusForCapability");
+
         final long identity = Binder.clearCallingIdentity();
         try {
-            // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
-            if (!isImsProvisioningRequired(subId, capability, false)) {
-                return true;
-            }
-
-            ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
-            switch (capability) {
-                case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE:
-                case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
-                    return ims.isEabProvisionedOnDevice();
-
-                default: {
-                    throw new IllegalArgumentException("Tried to get rcs provisioning for "
-                            + "capability '" + capability + "', which does not require "
-                            + "provisioning.");
-                }
-            }
-
+            return ImsProvisioningController.getInstance()
+                    .getRcsProvisioningStatusForCapability(subId, capability, tech);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -4648,66 +4669,12 @@
     @Override
     public void setImsProvisioningStatusForCapability(int subId, int capability, int tech,
             boolean isProvisioned) {
-        if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
-                && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE
-                && tech != ImsRegistrationImplBase.REGISTRATION_TECH_NR
-                && tech != ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM) {
-            throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
-        }
         checkModifyPhoneStatePermission(subId, "setImsProvisioningStatusForCapability");
+
         final long identity = Binder.clearCallingIdentity();
         try {
-            // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
-            if (!isImsProvisioningRequired(subId, capability, true)) {
-                return;
-            }
-            if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_NR
-                    || tech == ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM) {
-                loge("setImsProvisioningStatusForCapability: called for technology that does "
-                        + "not support provisioning - " + tech);
-                return;
-            }
-
-            // this capability requires provisioning, route to the correct API.
-            ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
-            switch (capability) {
-                case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE: {
-                    if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
-                        ims.setVolteProvisioned(isProvisioned);
-                    } else if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
-                        ims.setWfcProvisioned(isProvisioned);
-                    }
-                    break;
-                }
-                case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
-                    // There is currently no difference in VT provisioning type.
-                    ims.setVtProvisioned(isProvisioned);
-                    break;
-                }
-                case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
-                    // There is no "deprecated" UT provisioning mechanism through ImsConfig, so
-                    // change the capability of the feature instead if needed.
-                    if (isMmTelCapabilityProvisionedInCache(subId, capability, tech)
-                            == isProvisioned) {
-                        // No change in provisioning.
-                        return;
-                    }
-                    cacheMmTelCapabilityProvisioning(subId, capability, tech, isProvisioned);
-                    try {
-                        ims.changeMmTelCapability(isProvisioned, capability, tech);
-                    } catch (com.android.ims.ImsException e) {
-                        loge("setImsProvisioningStatusForCapability: couldn't change UT capability"
-                                + ", Exception" + e.getMessage());
-                    }
-                    break;
-                }
-                default: {
-                    throw new IllegalArgumentException("Tried to set provisioning for "
-                            + "MmTel capability '" + capability + "', which does not require "
-                            + "provisioning. ");
-                }
-            }
-
+            ImsProvisioningController.getInstance()
+                    .setImsProvisioningStatusForCapability(subId, capability, tech, isProvisioned);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -4715,54 +4682,13 @@
 
     @Override
     public boolean getImsProvisioningStatusForCapability(int subId, int capability, int tech) {
-        if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
-                && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE
-                && tech != ImsRegistrationImplBase.REGISTRATION_TECH_NR
-                && tech != ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM) {
-            throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
-        }
-        enforceReadPrivilegedPermission("getProvisioningStatusForCapability");
+        TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
+                mApp, subId, "getProvisioningStatusForCapability");
+
         final long identity = Binder.clearCallingIdentity();
         try {
-            // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
-            if (!isImsProvisioningRequired(subId, capability, true)) {
-                return true;
-            }
-
-            if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_NR
-                    || tech == ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM) {
-                loge("getImsProvisioningStatusForCapability: called for technology that does "
-                        + "not support provisioning - " + tech);
-                return true;
-            }
-
-            ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
-            switch (capability) {
-                case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE: {
-                    if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
-                        return ims.isVolteProvisionedOnDevice();
-                    } else if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
-                        return ims.isWfcProvisionedOnDevice();
-                    }
-                    // This should never happen, since we are checking tech above to make sure it
-                    // is either LTE or IWLAN.
-                    throw new IllegalArgumentException("Invalid radio technology for voice "
-                            + "capability.");
-                }
-                case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
-                    // There is currently no difference in VT provisioning type.
-                    return ims.isVtProvisionedOnDevice();
-                }
-                case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
-                    // There is no "deprecated" UT provisioning mechanism, so get from shared prefs.
-                    return isMmTelCapabilityProvisionedInCache(subId, capability, tech);
-                }
-                default: {
-                    throw new IllegalArgumentException(
-                            "Tried to get provisioning for MmTel capability '" + capability
-                                    + "', which does not require provisioning.");
-                }
-            }
+            return ImsProvisioningController.getInstance()
+                    .getImsProvisioningStatusForCapability(subId, capability, tech);
 
         } finally {
             Binder.restoreCallingIdentity(identity);
@@ -4770,61 +4696,31 @@
     }
 
     @Override
-    public boolean isMmTelCapabilityProvisionedInCache(int subId, int capability, int tech) {
-        if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
-                && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
-            throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
+    public boolean isProvisioningRequiredForCapability(int subId, int capability, int tech) {
+        TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
+                mApp, subId, "isProvisioningRequiredForCapability");
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            return ImsProvisioningController.getInstance()
+                    .isImsProvisioningRequiredForCapability(subId, capability, tech);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
         }
-        enforceReadPrivilegedPermission("isMmTelCapabilityProvisionedInCache");
-        int provisionedBits = getMmTelCapabilityProvisioningBitfield(subId, tech);
-        return (provisionedBits & capability) > 0;
     }
 
     @Override
-    public void cacheMmTelCapabilityProvisioning(int subId, int capability, int tech,
-            boolean isProvisioned) {
-        if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
-                && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
-            throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
-        }
-        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
-                "setProvisioningStatusForCapability");
-        int provisionedBits = getMmTelCapabilityProvisioningBitfield(subId, tech);
-        // If the current provisioning status for capability already matches isProvisioned,
-        // do nothing.
-        if (((provisionedBits & capability) > 0) == isProvisioned) {
-            return;
-        }
-        if (isProvisioned) {
-            setMmTelCapabilityProvisioningBitfield(subId, tech, (provisionedBits | capability));
-        } else {
-            setMmTelCapabilityProvisioningBitfield(subId, tech, (provisionedBits & ~capability));
-        }
-    }
+    public boolean isRcsProvisioningRequiredForCapability(int subId, int capability, int tech) {
+        TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
+                mApp, subId, "isProvisioningRequiredForCapability");
 
-    /**
-     * @return the bitfield containing the MmTel provisioning for the provided subscription and
-     * technology. The bitfield should mirror the bitfield defined by
-     * {@link MmTelFeature.MmTelCapabilities.MmTelCapability}.
-     */
-    private int getMmTelCapabilityProvisioningBitfield(int subId, int tech) {
-        String key = getMmTelProvisioningKey(subId, tech);
-        // Default is no capabilities are provisioned.
-        return mTelephonySharedPreferences.getInt(key, 0 /*default*/);
-    }
-
-    /**
-     * Sets the MmTel capability provisioning bitfield (defined by
-     *     {@link MmTelFeature.MmTelCapabilities.MmTelCapability}) for the subscription and
-     *     technology specified.
-     *
-     * Note: This is a synchronous command and should not be called on UI thread.
-     */
-    private void setMmTelCapabilityProvisioningBitfield(int subId, int tech, int newField) {
-        final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
-        String key = getMmTelProvisioningKey(subId, tech);
-        editor.putInt(key, newField);
-        editor.commit();
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            return ImsProvisioningController.getInstance()
+                    .isRcsProvisioningRequiredForCapability(subId, capability, tech);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
     }
 
     private static String getMmTelProvisioningKey(int subId, int tech) {
@@ -4897,7 +4793,9 @@
         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
             throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
         }
-        enforceReadPrivilegedPermission("getImsProvisioningInt");
+        TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
+                mApp, subId, "getImsProvisioningInt");
+
         final long identity = Binder.clearCallingIdentity();
         try {
             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
@@ -4907,6 +4805,12 @@
                         + subId + "' for key:" + key);
                 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
             }
+
+            int retVal = ImsProvisioningController.getInstance().getProvisioningValue(subId, key);
+            if (retVal != ImsConfigImplBase.CONFIG_RESULT_UNKNOWN) {
+                return retVal;
+            }
+
             return ImsManager.getInstance(mApp, slotId).getConfigInt(key);
         } catch (com.android.ims.ImsException e) {
             Log.w(LOG_TAG, "getImsProvisioningInt: ImsService is not available for subscription '"
@@ -4922,7 +4826,9 @@
         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
             throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
         }
-        enforceReadPrivilegedPermission("getImsProvisioningString");
+        TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
+                mApp, subId, "getImsProvisioningString");
+
         final long identity = Binder.clearCallingIdentity();
         try {
             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
@@ -4949,6 +4855,7 @@
         }
         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
                 "setImsProvisioningInt");
+
         final long identity = Binder.clearCallingIdentity();
         try {
             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
@@ -4958,6 +4865,13 @@
                         + subId + "' for key:" + key);
                 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
             }
+
+            int retVal = ImsProvisioningController.getInstance()
+                    .setProvisioningValue(subId, key, value);
+            if (retVal != ImsConfigImplBase.CONFIG_RESULT_UNKNOWN) {
+                return retVal;
+            }
+
             return ImsManager.getInstance(mApp, slotId).setConfig(key, value);
         } catch (com.android.ims.ImsException | RemoteException e) {
             Log.w(LOG_TAG, "setImsProvisioningInt: ImsService unavailable for sub '" + subId
@@ -5538,11 +5452,9 @@
      */
     public int setForbiddenPlmns(int subId, int appType, List<String> fplmns, String callingPackage,
             String callingFeatureId) {
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
-                callingFeatureId, "setForbiddenPlmns")) {
-            if (DBG) logv("no permissions for setForbiddenplmns");
-            throw new IllegalStateException("No Permissions for setForbiddenPlmns");
-        }
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "setForbiddenPlmns");
+
         if (appType != TelephonyManager.APPTYPE_USIM && appType != TelephonyManager.APPTYPE_SIM) {
             loge("setForbiddenPlmnList(): App Type must be USIM or SIM");
             throw new IllegalArgumentException("Invalid appType: App Type must be USIM or SIM");
@@ -6701,11 +6613,15 @@
         final long identity = Binder.clearCallingIdentity();
         try {
             int phoneId = mSubscriptionController.getPhoneId(subId);
-            if (DBG) log("isDataEnabled: subId=" + subId + " phoneId=" + phoneId);
             Phone phone = PhoneFactory.getPhone(phoneId);
             if (phone != null) {
-                boolean retVal = phone.getDataEnabledSettings().isDataEnabled();
-                if (DBG) log("isDataEnabled: subId=" + subId + " retVal=" + retVal);
+                boolean retVal;
+                if (phone.isUsingNewDataStack()) {
+                    retVal = phone.getDataSettingsManager().isDataEnabled();
+                } else {
+                    retVal = phone.getDataEnabledSettings().isDataEnabled();
+                }
+                if (DBG) log("isDataEnabled: " + retVal + ", subId=" + subId);
                 return retVal;
             } else {
                 if (DBG) loge("isDataEnabled: no phone subId=" + subId + " retVal=false");
@@ -6756,10 +6672,14 @@
             Phone phone = PhoneFactory.getPhone(phoneId);
             if (phone != null) {
                 boolean retVal;
-                if (reason == TelephonyManager.DATA_ENABLED_REASON_USER) {
-                    retVal = phone.isUserDataEnabled();
+                if (phone.isUsingNewDataStack()) {
+                    retVal = phone.getDataSettingsManager().isDataEnabledForReason(reason);
                 } else {
-                    retVal = phone.getDataEnabledSettings().isDataEnabledForReason(reason);
+                    if (reason == TelephonyManager.DATA_ENABLED_REASON_USER) {
+                        retVal = phone.isUserDataEnabled();
+                    } else {
+                        retVal = phone.getDataEnabledSettings().isDataEnabledForReason(reason);
+                    }
                 }
                 if (DBG) log("isDataEnabledForReason: retVal=" + retVal);
                 return retVal;
@@ -8360,6 +8280,16 @@
             int result = (int) sendRequest(CMD_ENABLE_VONR, enabled, subId,
                     workSource);
             if (DBG) log("setVoNrEnabled result: " + result);
+
+            if (result == TelephonyManager.ENABLE_VONR_SUCCESS) {
+                if (DBG) {
+                    log("Set VoNR settings in siminfo db; subId=" + subId + ", value:" + enabled);
+                }
+                SubscriptionManager.setSubscriptionProperty(
+                        subId, SubscriptionManager.NR_ADVANCED_CALLING_ENABLED,
+                        (enabled ? "1" : "0"));
+            }
+
             return result;
         } finally {
             Binder.restoreCallingIdentity(identity);
@@ -8489,7 +8419,11 @@
                 if (reason == TelephonyManager.DATA_ENABLED_REASON_CARRIER) {
                     phone.carrierActionSetMeteredApnsEnabled(enabled);
                 } else {
-                    phone.getDataEnabledSettings().setDataEnabled(reason, enabled);
+                    if (phone.isUsingNewDataStack()) {
+                        phone.getDataSettingsManager().setDataEnabled(reason, enabled);
+                    } else {
+                        phone.getDataEnabledSettings().setDataEnabled(reason, enabled);
+                    }
                 }
             }
         } finally {
@@ -9696,7 +9630,13 @@
             if (phone == null) return false;
 
             boolean isMetered = ApnSettingUtils.isMeteredApnType(apnType, phone);
-            return !isMetered || phone.getDataEnabledSettings().isDataEnabled(apnType);
+            boolean isDataEnabled;
+            if (phone.isUsingNewDataStack()) {
+                isDataEnabled = phone.getDataSettingsManager().isDataEnabled(apnType);
+            } else {
+                isDataEnabled = phone.getDataEnabledSettings().isDataEnabled(apnType);
+            }
+            return !isMetered || isDataEnabled;
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -9850,9 +9790,17 @@
 
             switch (policy) {
                 case TelephonyManager.MOBILE_DATA_POLICY_DATA_ON_NON_DEFAULT_DURING_VOICE_CALL:
-                    return phone.getDataEnabledSettings().isDataAllowedInVoiceCall();
+                    if (phone.isUsingNewDataStack()) {
+                        return phone.getDataSettingsManager().isDataAllowedInVoiceCall();
+                    } else {
+                        return phone.getDataEnabledSettings().isDataAllowedInVoiceCall();
+                    }
                 case TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED:
-                    return phone.getDataEnabledSettings().isMmsAlwaysAllowed();
+                    if (phone.isUsingNewDataStack()) {
+                        return phone.getDataSettingsManager().isMmsAlwaysAllowed();
+                    } else {
+                        return phone.getDataEnabledSettings().isMmsAlwaysAllowed();
+                    }
                 default:
                     throw new IllegalArgumentException(policy + " is not a valid policy");
             }
@@ -9873,10 +9821,18 @@
 
             switch (policy) {
                 case TelephonyManager.MOBILE_DATA_POLICY_DATA_ON_NON_DEFAULT_DURING_VOICE_CALL:
-                    phone.getDataEnabledSettings().setAllowDataDuringVoiceCall(enabled);
+                    if (phone.isUsingNewDataStack()) {
+                        phone.getDataSettingsManager().setAllowDataDuringVoiceCall(enabled);
+                    } else {
+                        phone.getDataEnabledSettings().setAllowDataDuringVoiceCall(enabled);
+                    }
                     break;
                 case TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED:
-                    phone.getDataEnabledSettings().setAlwaysAllowMmsData(enabled);
+                    if (phone.isUsingNewDataStack()) {
+                        phone.getDataSettingsManager().setAlwaysAllowMmsData(enabled);
+                    } else {
+                        phone.getDataEnabledSettings().setAlwaysAllowMmsData(enabled);
+                    }
                     break;
                 default:
                     throw new IllegalArgumentException(policy + " is not a valid policy");
@@ -10592,6 +10548,9 @@
             } else {
                 configBinder.setRcsClientConfiguration(rcc);
             }
+
+            RcsStats.getInstance().onRcsClientProvisioningStats(subId,
+                    RCS_CLIENT_PROVISIONING_STATS__EVENT__CLIENT_PARAMS_SENT);
         } catch (RemoteException e) {
             Rlog.e(LOG_TAG, "fail to setRcsClientConfiguration " + e.getMessage());
             throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE,
@@ -11115,7 +11074,9 @@
      */
     @Override
     public void getSlicingConfig(ResultReceiver callback) {
-        enforceReadPrivilegedPermission("getSlicingConfig");
+        TelephonyPermissions
+                .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
+                        mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, "getSlicingConfig");
 
         final long identity = Binder.clearCallingIdentity();
         try {
diff --git a/src/com/android/phone/RcsProvisioningMonitor.java b/src/com/android/phone/RcsProvisioningMonitor.java
index 6d2bd6f..1ed0d72 100644
--- a/src/com/android/phone/RcsProvisioningMonitor.java
+++ b/src/com/android/phone/RcsProvisioningMonitor.java
@@ -16,6 +16,10 @@
 
 package com.android.phone;
 
+import static com.android.internal.telephony.TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML;
+import static com.android.internal.telephony.TelephonyStatsLog.RCS_CLIENT_PROVISIONING_STATS__EVENT__DMA_CHANGED;
+import static com.android.internal.telephony.TelephonyStatsLog.RCS_CLIENT_PROVISIONING_STATS__EVENT__TRIGGER_RCS_RECONFIGURATION;
+
 import android.Manifest;
 import android.app.role.OnRoleHoldersChangedListener;
 import android.app.role.RoleManager;
@@ -47,6 +51,8 @@
 import com.android.ims.FeatureUpdates;
 import com.android.ims.RcsFeatureManager;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.metrics.RcsStats;
+import com.android.internal.telephony.metrics.RcsStats.RcsProvisioningCallback;
 import com.android.internal.telephony.util.HandlerExecutor;
 import com.android.internal.util.CollectionUtils;
 import com.android.telephony.Rlog;
@@ -100,6 +106,8 @@
     private final RoleManagerAdapter mRoleManager;
     private FeatureConnectorFactory<RcsFeatureManager> mFeatureFactory;
 
+    private RcsStats mRcsStats;
+
     private static RcsProvisioningMonitor sInstance;
 
     private final SubscriptionManager.OnSubscriptionsChangedListener mSubChangedListener =
@@ -227,6 +235,10 @@
             if (mSingleRegistrationCapability != singleRegistrationCapability) {
                 mSingleRegistrationCapability = singleRegistrationCapability;
                 notifyDma();
+
+                // update whether single registration supported.
+                mRcsStats.setEnableSingleRegistration(mSubId,
+                        mSingleRegistrationCapability == ProvisioningManager.STATUS_CAPABLE);
             }
         }
 
@@ -338,6 +350,9 @@
                     } else {
                         notifyRcsAutoConfigurationReceived();
                     }
+
+                    // check callback for metrics if not registered, register callback
+                    registerMetricsCallback();
                 } else {
                     // clear callbacks if rcs disconnected
                     clearCallbacks();
@@ -397,6 +412,18 @@
                 }
             }
         }
+
+        private void registerMetricsCallback() {
+            RcsProvisioningCallback rcsProvisioningCallback = mRcsStats.getRcsProvisioningCallback(
+                    mSubId, mSingleRegistrationCapability == ProvisioningManager.STATUS_CAPABLE);
+
+            // if not yet registered, register callback and set registered value
+            if (rcsProvisioningCallback != null && !rcsProvisioningCallback.getRegistered()) {
+                if (addRcsConfigCallback(rcsProvisioningCallback)) {
+                    rcsProvisioningCallback.setRegistered(true);
+                }
+            }
+        }
     }
 
     @VisibleForTesting
@@ -440,7 +467,7 @@
         }
 
         @Override
-        public void connectionReady(RcsFeatureManager manager) {
+        public void connectionReady(RcsFeatureManager manager, int subId) {
             mRcsFeatureManager = manager;
             mRcsProvisioningInfos.forEach(v -> v.onRcsStatusChanged(manager.getConfig()));
         }
@@ -454,7 +481,7 @@
 
     @VisibleForTesting
     public RcsProvisioningMonitor(PhoneGlobals app, Looper looper, RoleManagerAdapter roleManager,
-            FeatureConnectorFactory<RcsFeatureManager> factory) {
+            FeatureConnectorFactory<RcsFeatureManager> factory, RcsStats rcsStats) {
         mPhone = app;
         mHandler = new MyHandler(looper);
         mCarrierConfigManager = mPhone.getSystemService(CarrierConfigManager.class);
@@ -465,6 +492,7 @@
         logv("DMA is " + mDmaPackageName);
         mDmaChangedListener = new DmaChangedListener();
         mFeatureFactory = factory;
+        mRcsStats = rcsStats;
         init();
     }
 
@@ -477,7 +505,8 @@
             HandlerThread handlerThread = new HandlerThread(TAG);
             handlerThread.start();
             sInstance = new RcsProvisioningMonitor(app, handlerThread.getLooper(),
-                    new RoleManagerAdapterImpl(app), RcsFeatureManager::getConnector);
+                    new RoleManagerAdapterImpl(app), RcsFeatureManager::getConnector,
+                    RcsStats.getInstance());
         }
         return sInstance;
     }
@@ -704,6 +733,10 @@
                     logv("acs not used, set cached config and notify.");
                     v.setConfig(cachedConfig);
                 }
+
+                // store RCS metrics - DMA changed event
+                mRcsStats.onRcsClientProvisioningStats(k,
+                        RCS_CLIENT_PROVISIONING_STATS__EVENT__DMA_CHANGED);
             });
         }
     }
@@ -803,6 +836,14 @@
         }
         info.setConfig(isCompressed ? RcsConfig.decompressGzip(config) : config);
         updateConfigForSub(subId, config, isCompressed);
+
+        // Supporting ACS means config data comes from ACS
+        // store RCS metrics - received provisioning event
+        if (isAcsUsed(subId)) {
+            mRcsStats.onRcsAcsProvisioningStats(subId, 200,
+                    RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML,
+                    isRcsVolteSingleRegistrationEnabled(subId));
+        }
     }
 
     private void onReconfigRequest(int subId) {
@@ -814,6 +855,10 @@
             updateConfigForSub(subId, null, true);
             info.triggerRcsReconfiguration();
         }
+
+        // store RCS metrics - reconfig event
+        mRcsStats.onRcsClientProvisioningStats(subId,
+                RCS_CLIENT_PROVISIONING_STATS__EVENT__TRIGGER_RCS_RECONFIGURATION);
     }
 
     private void notifyDmaForSub(int subId, int capability) {
diff --git a/src/com/android/phone/ServiceStateProvider.java b/src/com/android/phone/ServiceStateProvider.java
index 6f5fcf5..3fa1e58 100644
--- a/src/com/android/phone/ServiceStateProvider.java
+++ b/src/com/android/phone/ServiceStateProvider.java
@@ -426,30 +426,44 @@
                 ss = unredactedServiceState;
             } else {
                 availableColumns = ALL_COLUMNS;
-
-                final boolean hasLocationPermission = hasLocationPermission();
-                if (!enforceLocationPermission || hasLocationPermission) {
-                    // No matter the targetSdkVersion, return unredacted ServiceState if caller does
-                    // have location permission or location permission enforcement is not introduced
+                if (!enforceLocationPermission) {
+                    // No matter the targetSdkVersion, return unredacted ServiceState if location
+                    // permission enforcement is not introduced
                     ss = unredactedServiceState;
                 } else {
-                    // The caller has targetSdkVersion S+ but no location permission. It explicitly
-                    // requires location protected columns. Throw SecurityException to fail loudly.
-                    if (targetingAtLeastS && projection != null) {
+                    boolean implicitlyQueryLocation = projection == null;
+                    boolean explicitlyQueryLocation = false;
+                    if (projection != null) {
                         for (String requiredColumn : projection) {
                             if (LOCATION_PROTECTED_COLUMNS_SET.contains(requiredColumn)) {
-                                throw new SecurityException("Column " + requiredColumn
-                                        + "requires location permissions to access.");
+                                explicitlyQueryLocation = true;
+                                break;
                             }
                         }
                     }
 
-                    // In all other cases, return the redacted ServiceState.
-                    // The caller has no location permission but only requires columns without
-                    // location sensitive info or "all" columns, return result that scrub out all
-                    // sensitive info. In later case, we will not know which columns will be fetched
-                    // from the returned cursor until the result has been returned.
-                    ss = getLocationRedactedServiceState(unredactedServiceState);
+                    // Check location permission only when location sensitive info are queried
+                    // (either explicitly or implicitly) to avoid caller get blamed with location
+                    // permission when query non sensitive info.
+                    if (implicitlyQueryLocation || explicitlyQueryLocation) {
+                        if (hasLocationPermission()) {
+                            ss = unredactedServiceState;
+                        } else {
+                            if (targetingAtLeastS) {
+                                // Throw SecurityException to fail loudly if caller is targetSDK S+
+                                throw new SecurityException(
+                                        "Querying location sensitive info requires location "
+                                                + "permissions");
+                            } else {
+                                // For backward compatibility, return redacted value for old SDK
+                                ss = getLocationRedactedServiceState(unredactedServiceState);
+                            }
+                        }
+                    } else {
+                        // The caller is not interested in location sensitive info, return result
+                        // that scrub out all sensitive info. And no permission check is needed.
+                        ss = getLocationRedactedServiceState(unredactedServiceState);
+                    }
                 }
             }
 
@@ -700,8 +714,6 @@
     /* package */ static ServiceState getLocationRedactedServiceState(ServiceState serviceState) {
         ServiceState ss =
                 serviceState.createLocationInfoSanitizedCopy(true /*removeCoarseLocation*/);
-        // TODO(b/188061647): remove the additional redaction once it is fixed in SS
-        ss.setCdmaSystemAndNetworkId(ServiceState.UNKNOWN_ID, ServiceState.UNKNOWN_ID);
         return ss;
     }
 }
diff --git a/src/com/android/phone/TelephonyShellCommand.java b/src/com/android/phone/TelephonyShellCommand.java
index c6ee74e..eaf4371 100644
--- a/src/com/android/phone/TelephonyShellCommand.java
+++ b/src/com/android/phone/TelephonyShellCommand.java
@@ -250,13 +250,13 @@
                 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
         map.put("chatbot_v2", new ArraySet<>(Arrays.asList(
                 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
-                FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
+                FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
         map.put("chatbot_sa", new ArraySet<>(Arrays.asList(
                 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
                 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
         map.put("chatbot_sa_v2", new ArraySet<>(Arrays.asList(
                 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
-                FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
+                FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
         map.put("chatbot_role", Collections.singleton(FeatureTags.FEATURE_TAG_CHATBOT_ROLE));
         TEST_FEATURE_TAG_MAP = Collections.unmodifiableMap(map);
     }
@@ -323,8 +323,6 @@
             case GET_ALLOWED_NETWORK_TYPES_FOR_USER:
             case SET_ALLOWED_NETWORK_TYPES_FOR_USER:
                 return handleAllowedNetworkTypesCommand(cmd);
-            case RADIO_SUBCOMMAND:
-                return handleRadioCommand();
             default: {
                 return handleDefaultCommands(cmd);
             }
diff --git a/src/com/android/phone/settings/RadioInfo.java b/src/com/android/phone/settings/RadioInfo.java
index 7bf4697..f2a3ff7 100644
--- a/src/com/android/phone/settings/RadioInfo.java
+++ b/src/com/android/phone/settings/RadioInfo.java
@@ -1049,6 +1049,8 @@
                 display = r.getString(R.string.radioInfo_service_in);
                 break;
             case ServiceState.STATE_OUT_OF_SERVICE:
+                display = r.getString(R.string.radioInfo_service_out);
+                break;
             case ServiceState.STATE_EMERGENCY_ONLY:
                 display = r.getString(R.string.radioInfo_service_emergency);
                 break;
@@ -1175,9 +1177,16 @@
         if (s == null) s = r.getString(R.string.radioInfo_unknown);
         mSubscriberId.setText(s);
 
-        //FIXME: Replace with a TelephonyManager call
-        s = mPhone.getLine1Number();
-        if (s == null) s = r.getString(R.string.radioInfo_unknown);
+        SubscriptionManager subMgr = getSystemService(SubscriptionManager.class);
+        int subId = mPhone.getSubId();
+        s = subMgr.getPhoneNumber(subId)
+                + " { CARRIER:"
+                + subMgr.getPhoneNumber(subId, SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER)
+                + ", UICC:"
+                + subMgr.getPhoneNumber(subId, SubscriptionManager.PHONE_NUMBER_SOURCE_UICC)
+                + ", IMS:"
+                + subMgr.getPhoneNumber(subId, SubscriptionManager.PHONE_NUMBER_SOURCE_IMS)
+                + " }";
         mLine1Number.setText(s);
     }
 
diff --git a/src/com/android/services/telephony/ImsConference.java b/src/com/android/services/telephony/ImsConference.java
index 0be927a..c62b4fa 100644
--- a/src/com/android/services/telephony/ImsConference.java
+++ b/src/com/android/services/telephony/ImsConference.java
@@ -257,7 +257,7 @@
 
                 @Override
                 public void onConnectionPropertiesChanged(Connection c, int connectionProperties) {
-                    Log.d(this, "onConnectionPropertiesChanged: Connection: %s,"
+                    Log.i(ImsConference.this, "onConnectionPropertiesChanged: Connection: %s,"
                             + " connectionProperties: %s", c, connectionProperties);
                     updateConnectionProperties(connectionProperties);
                 }
@@ -383,6 +383,11 @@
     private boolean mIsUsingSimCallManager = false;
 
     /**
+     * See {@link #isRemotelyHosted()} for details.
+     */
+    private boolean mWasRemotelyHosted = false;
+
+    /**
      * Where {@link #isMultiparty()} is {@code false}, contains the
      * {@link ConferenceParticipantConnection#getUserEntity()} and
      * {@link ConferenceParticipantConnection#getEndpoint()} of the single participant which this
@@ -522,11 +527,16 @@
                 (properties & Connection.PROPERTY_IS_EXTERNAL_CALL) != 0);
 
         conferenceProperties = changeBitmask(conferenceProperties,
-                Connection.PROPERTY_REMOTELY_HOSTED, !isConferenceHost());
+                Connection.PROPERTY_REMOTELY_HOSTED, isRemotelyHosted());
 
         conferenceProperties = changeBitmask(conferenceProperties,
                 Connection.PROPERTY_IS_ADHOC_CONFERENCE,
                 (properties & Connection.PROPERTY_IS_ADHOC_CONFERENCE) != 0);
+        Log.i(this, "applyHostProperties: confProp=%s", conferenceProperties);
+
+        conferenceProperties = changeBitmask(conferenceProperties,
+                Connection.PROPERTY_CROSS_SIM,
+                (properties & Connection.PROPERTY_CROSS_SIM) != 0);
 
         return conferenceProperties;
     }
@@ -774,6 +784,26 @@
     }
 
     /**
+     * Returns whether the conference is remotely hosted or not.
+     * This method will cache the current remotely hosted state when the conference host or
+     * original connection becomes null.  This is important for scenarios where the conference host
+     * or original connection changes midway through a conference such as in an SRVCC scenario.
+     * @return {@code true} if the conference was remotely hosted based on the conference host and
+     * its original connection, or based on the last known remotely hosted state.  {@code false}
+     * otherwise.
+     */
+    public boolean isRemotelyHosted() {
+        if (mConferenceHost == null || mConferenceHost.getOriginalConnection() == null) {
+            return mWasRemotelyHosted;
+        }
+        com.android.internal.telephony.Connection originalConnection =
+                mConferenceHost.getOriginalConnection();
+        mWasRemotelyHosted = originalConnection.isMultiparty()
+                && !originalConnection.isConferenceHost();
+        return mWasRemotelyHosted;
+    }
+
+    /**
      * Determines if this conference is hosted on the current device or the peer device.
      *
      * @return {@code true} if this conference is hosted on the current device, {@code false} if it
@@ -1209,6 +1239,7 @@
         ConferenceParticipantConnection connection = new ConferenceParticipantConnection(
                 parent.getOriginalConnection(), participant,
                 !isConferenceHost() /* isRemotelyHosted */);
+
         if (participant.getConnectTime() == 0) {
             connection.setConnectTimeMillis(parent.getConnectTimeMillis());
             connection.setConnectionStartElapsedRealtimeMillis(
diff --git a/src/com/android/services/telephony/TelephonyConferenceController.java b/src/com/android/services/telephony/TelephonyConferenceController.java
index 228541a..9aa3dbe 100644
--- a/src/com/android/services/telephony/TelephonyConferenceController.java
+++ b/src/com/android/services/telephony/TelephonyConferenceController.java
@@ -40,6 +40,7 @@
  */
 final class TelephonyConferenceController {
     private static final int TELEPHONY_CONFERENCE_MAX_SIZE = 5;
+    private static final String RIL_REPORTED_CONFERENCE_CALL_STRING = "Conference Call";
 
     private final TelephonyConnection.TelephonyConnectionListener mTelephonyConnectionListener =
             new TelephonyConnection.TelephonyConnectionListener() {
@@ -179,7 +180,6 @@
     private void recalculateConference() {
         Set<TelephonyConnection> conferencedConnections = new HashSet<>();
         int numGsmConnections = 0;
-
         for (TelephonyConnection connection : mTelephonyConnections) {
             com.android.internal.telephony.Connection radioConnection =
                 connection.getOriginalConnection();
@@ -271,11 +271,19 @@
                             // Remove all instances of PROPERTY_IS_DOWNGRADED_CONFERENCE. This
                             // property should only be set on the parent call (i.e. the newly
                             // created TelephonyConference.
-                            Log.d(this, "Removing PROPERTY_IS_DOWNGRADED_CONFERENCE from connection"
-                                    + " %s", connection);
-                            int newProperties = connection.getConnectionProperties()
-                                    & ~Connection.PROPERTY_IS_DOWNGRADED_CONFERENCE;
-                            connection.setTelephonyConnectionProperties(newProperties);
+                            // This doesn't apply to a connection whose address is "Conference
+                            // Call", which may be updated by some modem to create a connection
+                            // to represent a merged conference connection in SRVCC.
+                            if (connection.getAddress() == null
+                                    || !connection.getAddress().getSchemeSpecificPart()
+                                            .equalsIgnoreCase(
+                                                    RIL_REPORTED_CONFERENCE_CALL_STRING)) {
+                                Log.d(this, "Removing PROPERTY_IS_DOWNGRADED_CONFERENCE"
+                                        + " from connection %s", connection);
+                                int newProperties = connection.getConnectionProperties()
+                                        & ~Connection.PROPERTY_IS_DOWNGRADED_CONFERENCE;
+                                connection.setTelephonyConnectionProperties(newProperties);
+                            }
                             isDowngradedConference = true;
                         }
                         mTelephonyConference.addTelephonyConnection(connection);
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 18a40cf..ed07726 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -3814,4 +3814,13 @@
             mCommunicator.sendMessages(set);
         }
     }
+
+    /**
+     * Returns the current telephony connection listeners for test purposes.
+     * @return list of telephony connection listeners.
+     */
+    @VisibleForTesting
+    public List<TelephonyConnectionListener> getTelephonyConnectionListeners() {
+        return new ArrayList<>(mTelephonyListeners);
+    }
 }
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index e637791..b6f785c 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -58,10 +58,10 @@
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.PhoneSwitcher;
 import com.android.internal.telephony.RIL;
 import com.android.internal.telephony.SubscriptionController;
 import com.android.internal.telephony.d2d.Communicator;
+import com.android.internal.telephony.data.PhoneSwitcher;
 import com.android.internal.telephony.imsphone.ImsExternalCallTracker;
 import com.android.internal.telephony.imsphone.ImsPhone;
 import com.android.internal.telephony.imsphone.ImsPhoneConnection;
@@ -499,7 +499,8 @@
 
         IntentFilter intentFilter = new IntentFilter(
                 TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED);
-        registerReceiver(mTtyBroadcastReceiver, intentFilter);
+        registerReceiver(mTtyBroadcastReceiver, intentFilter,
+                android.Manifest.permission.MODIFY_PHONE_STATE, null);
     }
 
     @Override
@@ -2085,8 +2086,7 @@
             if (phone.getEmergencyNumberTracker() != null) {
                 if (phone.getEmergencyNumberTracker().isEmergencyNumber(
                         emergencyNumberAddress, true)) {
-                    if (phone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_4)
-                            || isAvailableForEmergencyCalls(phone)) {
+                    if (isAvailableForEmergencyCalls(phone)) {
                         // a)
                         if (phone.getPhoneId() == defaultVoicePhoneId) {
                             Log.i(this, "getPhoneForEmergencyCall, Phone Id that supports"
@@ -2209,12 +2209,6 @@
                 // Only sort if there are enough elements to do so.
                 if (phoneSlotStatus.size() > 1) {
                     Collections.sort(phoneSlotStatus, (o1, o2) -> {
-                        if (!o1.hasDialedEmergencyNumber && o2.hasDialedEmergencyNumber) {
-                            return -1;
-                        }
-                        if (o1.hasDialedEmergencyNumber && !o2.hasDialedEmergencyNumber) {
-                            return 1;
-                        }
                         // Sort by non-absent SIM.
                         if (o1.simState == TelephonyManager.SIM_STATE_ABSENT
                                 && o2.simState != TelephonyManager.SIM_STATE_ABSENT) {
@@ -2233,6 +2227,13 @@
                         if (o2.isLocked && !o1.isLocked) {
                             return 1;
                         }
+                        // Prefer slots where the number is considered emergency.
+                        if (!o1.hasDialedEmergencyNumber && o2.hasDialedEmergencyNumber) {
+                            return -1;
+                        }
+                        if (o1.hasDialedEmergencyNumber && !o2.hasDialedEmergencyNumber) {
+                            return 1;
+                        }
                         // sort by number of RadioAccessFamily Capabilities.
                         int compare = RadioAccessFamily.compare(o1.capabilities, o2.capabilities);
                         if (compare == 0) {
diff --git a/src/com/android/services/telephony/rcs/RcsFeatureController.java b/src/com/android/services/telephony/rcs/RcsFeatureController.java
index cc1a2cc..0e1cb4b 100644
--- a/src/com/android/services/telephony/rcs/RcsFeatureController.java
+++ b/src/com/android/services/telephony/rcs/RcsFeatureController.java
@@ -128,7 +128,7 @@
     private FeatureConnector.Listener<RcsFeatureManager> mFeatureConnectorListener =
             new FeatureConnector.Listener<RcsFeatureManager>() {
                 @Override
-                public void connectionReady(RcsFeatureManager manager)
+                public void connectionReady(RcsFeatureManager manager, int subId)
                         throws com.android.ims.ImsException {
                     if (manager == null) {
                         logw("connectionReady returned null RcsFeatureManager");
diff --git a/src/com/android/services/telephony/rcs/TelephonyRcsService.java b/src/com/android/services/telephony/rcs/TelephonyRcsService.java
index e72b0ab..dfcea74 100644
--- a/src/com/android/services/telephony/rcs/TelephonyRcsService.java
+++ b/src/com/android/services/telephony/rcs/TelephonyRcsService.java
@@ -32,6 +32,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.PhoneConfigurationManager;
+import com.android.internal.telephony.metrics.RcsStats;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.phone.ImsStateCallbackController;
 import com.android.phone.R;
@@ -164,6 +165,7 @@
         mFeatureControllers = new SparseArray<>(numSlots);
         mSlotToAssociatedSubIds = new SparseArray<>(numSlots);
         mRcsUceEnabled = sResourceProxy.getDeviceUceEnabled(mContext);
+        RcsStats.getInstance().registerUceCallback();
     }
 
     @VisibleForTesting
@@ -174,6 +176,7 @@
         mSlotToAssociatedSubIds = new SparseArray<>(numSlots);
         sResourceProxy = resourceProxy;
         mRcsUceEnabled = sResourceProxy.getDeviceUceEnabled(mContext);
+        RcsStats.getInstance().registerUceCallback();
     }
 
     /**
diff --git a/testapps/EmbmsServiceTestApp/Android.bp b/testapps/EmbmsServiceTestApp/Android.bp
index 584e5bd..236ba43 100644
--- a/testapps/EmbmsServiceTestApp/Android.bp
+++ b/testapps/EmbmsServiceTestApp/Android.bp
@@ -1,13 +1,9 @@
-// Build the Sample Embms Services
 package {
     // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "packages_services_Telephony_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["packages_services_Telephony_license"],
+    default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
+// Build the Sample Embms Services
 android_app {
     name: "EmbmsTestService",
     srcs: ["src/**/*.java"],
diff --git a/testapps/EmbmsTestDownloadApp/Android.bp b/testapps/EmbmsTestDownloadApp/Android.bp
index c1b9425..7a70221 100644
--- a/testapps/EmbmsTestDownloadApp/Android.bp
+++ b/testapps/EmbmsTestDownloadApp/Android.bp
@@ -1,10 +1,6 @@
 package {
     // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "packages_services_Telephony_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["packages_services_Telephony_license"],
+    default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
 src_dirs = ["src"]
diff --git a/testapps/EmbmsTestStreamingApp/Android.bp b/testapps/EmbmsTestStreamingApp/Android.bp
index 9f082ee..d2b8d46 100644
--- a/testapps/EmbmsTestStreamingApp/Android.bp
+++ b/testapps/EmbmsTestStreamingApp/Android.bp
@@ -1,10 +1,6 @@
 package {
     // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "packages_services_Telephony_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["packages_services_Telephony_license"],
+    default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
 android_test {
diff --git a/testapps/GbaTestApp/Android.bp b/testapps/GbaTestApp/Android.bp
index b3c45dd..76e02a0 100644
--- a/testapps/GbaTestApp/Android.bp
+++ b/testapps/GbaTestApp/Android.bp
@@ -14,11 +14,7 @@
 
 package {
     // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "packages_services_Telephony_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["packages_services_Telephony_license"],
+    default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
 android_test {
diff --git a/testapps/ImsTestService/Android.bp b/testapps/ImsTestService/Android.bp
index 7073749..a0bebce 100644
--- a/testapps/ImsTestService/Android.bp
+++ b/testapps/ImsTestService/Android.bp
@@ -1,10 +1,6 @@
 package {
     // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "packages_services_Telephony_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["packages_services_Telephony_license"],
+    default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
 android_app {
diff --git a/testapps/SmsManagerTestApp/Android.bp b/testapps/SmsManagerTestApp/Android.bp
index 4d4afcb..52fea61 100644
--- a/testapps/SmsManagerTestApp/Android.bp
+++ b/testapps/SmsManagerTestApp/Android.bp
@@ -1,10 +1,6 @@
 package {
     // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "packages_services_Telephony_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["packages_services_Telephony_license"],
+    default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
 android_app {
diff --git a/testapps/TelephonyManagerTestApp/Android.bp b/testapps/TelephonyManagerTestApp/Android.bp
index e95d62f..0ff917e 100644
--- a/testapps/TelephonyManagerTestApp/Android.bp
+++ b/testapps/TelephonyManagerTestApp/Android.bp
@@ -1,10 +1,6 @@
 package {
     // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "packages_services_Telephony_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["packages_services_Telephony_license"],
+    default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
 android_test {
diff --git a/testapps/TelephonyRegistryTestApp/Android.bp b/testapps/TelephonyRegistryTestApp/Android.bp
index 2439461..991e85c 100644
--- a/testapps/TelephonyRegistryTestApp/Android.bp
+++ b/testapps/TelephonyRegistryTestApp/Android.bp
@@ -1,10 +1,6 @@
 package {
     // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "packages_services_Telephony_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["packages_services_Telephony_license"],
+    default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
 android_test {
diff --git a/testapps/TestRcsApp/TestApp/Android.bp b/testapps/TestRcsApp/TestApp/Android.bp
index cda7d17..40254af 100644
--- a/testapps/TestRcsApp/TestApp/Android.bp
+++ b/testapps/TestRcsApp/TestApp/Android.bp
@@ -1,10 +1,6 @@
 package {
     // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "packages_services_Telephony_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["packages_services_Telephony_license"],
+    default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
 android_app {
diff --git a/testapps/TestRcsApp/aosp_test_rcsclient/Android.bp b/testapps/TestRcsApp/aosp_test_rcsclient/Android.bp
index 215c692..34b0a12 100644
--- a/testapps/TestRcsApp/aosp_test_rcsclient/Android.bp
+++ b/testapps/TestRcsApp/aosp_test_rcsclient/Android.bp
@@ -1,22 +1,6 @@
-
-
 package {
-    default_applicable_licenses: [
-        "packages_services_Telephony_testapps_TestRcsApp_aosp_test_rcsclient_license",
-    ],
-}
-
-// Added automatically by a large-scale-change
-// See: http://go/android-license-faq
-license {
-    name: "packages_services_Telephony_testapps_TestRcsApp_aosp_test_rcsclient_license",
-    visibility: [":__subpackages__"],
-    license_kinds: [
-        "SPDX-license-identifier-Apache-2.0",
-    ],
-    license_text: [
-        "LICENSE",
-    ],
+    // See: http://go/android-license-faq
+    default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
 android_library {
diff --git a/testapps/TestRcsApp/aosp_test_rcsclient/LICENSE b/testapps/TestRcsApp/aosp_test_rcsclient/LICENSE
deleted file mode 100644
index b9b9d2a..0000000
--- a/testapps/TestRcsApp/aosp_test_rcsclient/LICENSE
+++ /dev/null
@@ -1,176 +0,0 @@
-Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
\ No newline at end of file
diff --git a/tests/Android.bp b/tests/Android.bp
index 083d64d..08cac05 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -16,11 +16,7 @@
 
 package {
     // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "packages_services_Telephony_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["packages_services_Telephony_license"],
+    default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
 android_test {
diff --git a/tests/src/com/android/phone/ImsProvisioningControllerTest.java b/tests/src/com/android/phone/ImsProvisioningControllerTest.java
new file mode 100644
index 0000000..c26b6a0
--- /dev/null
+++ b/tests/src/com/android/phone/ImsProvisioningControllerTest.java
@@ -0,0 +1,1767 @@
+/*
+ * Copyright 2021 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 android.telephony.ims.ProvisioningManager.KEY_EAB_PROVISIONING_STATUS;
+import static android.telephony.ims.ProvisioningManager.KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE;
+import static android.telephony.ims.ProvisioningManager.KEY_VOLTE_PROVISIONING_STATUS;
+import static android.telephony.ims.ProvisioningManager.KEY_VT_PROVISIONING_STATUS;
+import static android.telephony.ims.ProvisioningManager.PROVISIONING_VALUE_ENABLED;
+import static android.telephony.ims.feature.ImsFeature.FEATURE_MMTEL;
+import static android.telephony.ims.feature.ImsFeature.FEATURE_RCS;
+import static android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_CALL_COMPOSER;
+import static android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_SMS;
+import static android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT;
+import static android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO;
+import static android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE;
+import static android.telephony.ims.feature.RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE;
+import static android.telephony.ims.feature.RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE;
+import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM;
+import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN;
+import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_LTE;
+import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_NR;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyRegistryManager;
+import android.telephony.ims.ProvisioningManager;
+import android.telephony.ims.aidl.IFeatureProvisioningCallback;
+import android.telephony.ims.aidl.IImsConfig;
+import android.telephony.ims.feature.MmTelFeature.MmTelCapabilities;
+import android.telephony.ims.feature.RcsFeature.RcsImsCapabilities;
+import android.telephony.ims.stub.ImsConfigImplBase;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.TestableLooper;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.ims.FeatureConnector;
+import com.android.ims.ImsConfig;
+import com.android.ims.ImsManager;
+import com.android.ims.RcsFeatureManager;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+/**
+ * Unit tests for ImsProvisioningContorller
+ */
+public class ImsProvisioningControllerTest {
+    private static final String TAG = "ImsProvisioningControllerTest";
+    private static final int[] MMTEL_CAPAS = new int[]{
+            CAPABILITY_TYPE_VOICE,
+            CAPABILITY_TYPE_VIDEO,
+            CAPABILITY_TYPE_UT,
+            CAPABILITY_TYPE_SMS,
+            CAPABILITY_TYPE_CALL_COMPOSER
+    };
+    private static final int MMTEL_CAPA_INVALID = 0;
+
+    private static final int RCS_CAPA_INVALID = RcsImsCapabilities.CAPABILITY_TYPE_NONE;
+
+    private static final int[] RADIO_TECHS = new int[]{
+            REGISTRATION_TECH_LTE,
+            REGISTRATION_TECH_IWLAN,
+            REGISTRATION_TECH_CROSS_SIM,
+            REGISTRATION_TECH_NR
+    };
+    private static final int RADIO_TECH_INVALID = ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
+
+    @Mock
+    Context mContext;
+
+    @Mock
+    PhoneGlobals mPhone;
+    @Mock
+    CarrierConfigManager mCarrierConfigManager;
+    private PersistableBundle mPersistableBundle0;
+    private PersistableBundle mPersistableBundle1;
+    @Mock
+    SubscriptionManager mSubscriptionManager;
+    @Mock
+    TelephonyRegistryManager mTelephonyRegistryManager;
+    @Mock
+    ImsProvisioningLoader mImsProvisioningLoader;
+
+    @Mock
+    ImsManager mImsManager;
+    @Mock
+    ImsConfig mImsConfig;
+    @Mock
+    ImsProvisioningController.MmTelFeatureConnector mMmTelFeatureConnector;
+    @Mock
+    FeatureConnector<ImsManager> mMmTelFeatureConnector0;
+    @Mock
+    FeatureConnector<ImsManager> mMmTelFeatureConnector1;
+    @Captor
+    ArgumentCaptor<FeatureConnector.Listener<ImsManager>> mMmTelConnectorListener0;
+    @Captor
+    ArgumentCaptor<FeatureConnector.Listener<ImsManager>> mMmTelConnectorListener1;
+
+    @Mock
+    RcsFeatureManager mRcsFeatureManager;
+    @Mock
+    ImsProvisioningController.RcsFeatureConnector mRcsFeatureConnector;
+    @Mock
+    FeatureConnector<RcsFeatureManager> mRcsFeatureConnector0;
+    @Mock
+    FeatureConnector<RcsFeatureManager> mRcsFeatureConnector1;
+    @Captor
+    ArgumentCaptor<FeatureConnector.Listener<RcsFeatureManager>> mRcsConnectorListener0;
+    @Captor
+    ArgumentCaptor<FeatureConnector.Listener<RcsFeatureManager>> mRcsConnectorListener1;
+
+    @Mock
+    IFeatureProvisioningCallback mIFeatureProvisioningCallback0;
+    @Mock
+    IFeatureProvisioningCallback mIFeatureProvisioningCallback1;
+
+    @Mock
+    IBinder mIbinder0;
+    @Mock
+    IBinder mIbinder1;
+
+    private SubscriptionManager.OnSubscriptionsChangedListener mSubChangedListener;
+
+    private Handler mHandler;
+    private HandlerThread mHandlerThread;
+    private TestableLooper mLooper;
+
+    TestImsProvisioningController mTestImsProvisioningController;
+
+    int mPhoneId0 = 0;
+    int mPhoneId1 = 1;
+    int mSubId0 = 1234;
+    int mSubId1 = 5678;
+
+    SparseArray<int[]> mMmTelTechMap = new SparseArray<>();
+    SparseArray<int[]> mRcsTechMap = new SparseArray<>();
+
+    int[][] mMmTelProvisioningStorage;
+    int[][] mRcsProvisioningStorage;
+    int[][] mImsConfigStorage;
+
+    private class TestImsProvisioningController extends ImsProvisioningController {
+        boolean mIsValidSubId = true;
+
+        TestImsProvisioningController() {
+            super(mPhone, 2, mHandlerThread.getLooper(),
+                    mMmTelFeatureConnector, mRcsFeatureConnector,
+                    mImsProvisioningLoader);
+        }
+
+        protected int getSubId(int slotId) {
+            return (slotId == mPhoneId0) ? mSubId0 : mSubId1;
+        }
+
+        protected int getSlotId(int subId) {
+            return (subId == mSubId0) ? mPhoneId0 : mPhoneId1;
+        }
+
+        protected ImsConfig getImsConfig(ImsManager imsManager) {
+            return mImsConfig;
+        }
+
+        protected ImsConfig getImsConfig(IImsConfig iImsConfig) {
+            return mImsConfig;
+        }
+
+        protected int[] getTechsFromCarrierConfig(int subId, int capability, boolean isMmtel) {
+            if (isMmtel) {
+                return mMmTelTechMap.get(capability);
+            } else {
+                return mRcsTechMap.get(capability);
+            }
+        }
+
+        protected boolean isValidSubId(int subId) {
+            return mIsValidSubId;
+        }
+
+        public void setValidSubId(boolean valid) {
+            mIsValidSubId = valid;
+        }
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        logd("setUp");
+        MockitoAnnotations.initMocks(this);
+
+        when(mPhone.getSystemServiceName(eq(CarrierConfigManager.class)))
+                .thenReturn(Context.CARRIER_CONFIG_SERVICE);
+        when(mPhone.getSystemService(eq(Context.CARRIER_CONFIG_SERVICE)))
+                .thenReturn(mCarrierConfigManager);
+
+        mPersistableBundle0 = new PersistableBundle();
+        mPersistableBundle1 = new PersistableBundle();
+
+        when(mCarrierConfigManager.getConfigForSubId(eq(mSubId0)))
+                .thenReturn(mPersistableBundle0);
+        when(mCarrierConfigManager.getConfigForSubId(eq(mSubId1)))
+                .thenReturn(mPersistableBundle1);
+
+        when(mPhone.getSystemServiceName(eq(SubscriptionManager.class)))
+                .thenReturn(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+        when(mPhone.getSystemService(eq(Context.TELEPHONY_SUBSCRIPTION_SERVICE)))
+                .thenReturn(mSubscriptionManager);
+
+
+        when(mPhone.getSystemServiceName(eq(TelephonyRegistryManager.class)))
+                .thenReturn(Context.TELEPHONY_REGISTRY_SERVICE);
+        when(mPhone.getSystemService(eq(Context.TELEPHONY_REGISTRY_SERVICE)))
+                .thenReturn(mTelephonyRegistryManager);
+        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());
+
+        mHandlerThread = new HandlerThread("ImsStateCallbackControllerTest");
+        mHandlerThread.start();
+
+        initializeDefaultData();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        logd("tearDown");
+        if (mTestImsProvisioningController != null) {
+            mTestImsProvisioningController.destroy();
+            mTestImsProvisioningController = null;
+        }
+
+        if (mLooper != null) {
+            mLooper.destroy();
+            mLooper = null;
+        }
+    }
+
+    @Test
+    @SmallTest
+    public void addFeatureProvisioningChangedCallback_withCallback() throws Exception {
+        createImsProvisioningController();
+
+        // add callback with valid obj
+        try {
+            mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                    mSubId0, mIFeatureProvisioningCallback0);
+        } catch (Exception e) {
+            throw new AssertionError("not expected exception", e);
+        }
+        // add callback with invalid obj
+        try {
+            mTestImsProvisioningController.addFeatureProvisioningChangedCallback(mSubId0, null);
+        } catch (IllegalArgumentException e) {
+            // expected result
+        } catch (Exception e) {
+            throw new AssertionError("not expected exception", e);
+        }
+        // remove callback with valid obj
+        try {
+            mTestImsProvisioningController.removeFeatureProvisioningChangedCallback(
+                    mSubId0, mIFeatureProvisioningCallback0);
+        } catch (Exception e) {
+            throw new AssertionError("not expected exception", e);
+        }
+        // remove callback with invalid obj
+        try {
+            mTestImsProvisioningController.removeFeatureProvisioningChangedCallback(mSubId0, null);
+        } catch (IllegalArgumentException e) {
+            // expected result
+        } catch (Exception e) {
+            throw new AssertionError("not expected exception", e);
+        }
+    }
+
+    @Test
+    @SmallTest
+    public void connectionReady_MmTelFeatureListener() throws Exception {
+        createImsProvisioningController();
+
+        try {
+            mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                    mSubId0, mIFeatureProvisioningCallback0);
+            mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                    mSubId1, mIFeatureProvisioningCallback1);
+        } catch (Exception e) {
+            throw new AssertionError("not expected exception", e);
+        }
+        clearInvocations(mIFeatureProvisioningCallback0);
+        clearInvocations(mIFeatureProvisioningCallback1);
+
+        // change subId to be invalid
+        mTestImsProvisioningController.setValidSubId(false);
+
+        mMmTelConnectorListener0.getValue().connectionReady(mImsManager, mSubId0);
+
+        // setConfig not called, wait until subId is valid
+        verify(mImsConfig, times(0)).setConfig(anyInt(), anyInt());
+
+        // change subId
+        mSubChangedListener.onSubscriptionsChanged();
+        processAllMessages();
+
+        int[] keys = {
+                ProvisioningManager.KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE,
+                ProvisioningManager.KEY_VOLTE_PROVISIONING_STATUS,
+                ProvisioningManager.KEY_VT_PROVISIONING_STATUS};
+
+        // verify # of read data times from storage : # of MmTel storage length
+        verify(mImsProvisioningLoader, atLeast(keys.length))
+                .getProvisioningStatus(eq(mSubId0), eq(FEATURE_MMTEL), anyInt(), anyInt());
+
+        for (int index = 0; index < keys.length; index++) {
+            // verify function call vendor interface
+            verify(mImsConfig, times(1)).setConfig(eq(keys[index]), anyInt());
+        }
+
+        // verify other interactions
+        verifyNoMoreInteractions(mIFeatureProvisioningCallback0);
+        verifyNoMoreInteractions(mIFeatureProvisioningCallback1);
+        verifyNoMoreInteractions(mImsConfig);
+    }
+
+    @Test
+    @SmallTest
+    public void connectionReady_RcsFeatureListener() throws Exception {
+        createImsProvisioningController();
+
+        try {
+            mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                    mSubId0, mIFeatureProvisioningCallback0);
+            mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                    mSubId1, mIFeatureProvisioningCallback1);
+        } catch (Exception e) {
+            throw new AssertionError("not expected exception", e);
+        }
+        clearInvocations(mIFeatureProvisioningCallback0);
+        clearInvocations(mIFeatureProvisioningCallback1);
+
+        mRcsConnectorListener0.getValue().connectionReady(mRcsFeatureManager, mSubId0);
+        processAllMessages();
+
+        // verify # of read data times from storage : # of Rcs storage length
+        verify(mImsProvisioningLoader, times(1))
+                .getProvisioningStatus(eq(mSubId0), eq(FEATURE_RCS), anyInt(), anyInt());
+
+        int key = ProvisioningManager.KEY_EAB_PROVISIONING_STATUS;
+        // verify function call vendor interface
+        verify(mImsConfig, times(1)).setConfig(eq(key), anyInt());
+
+        // verify other interactions
+        verifyNoMoreInteractions(mIFeatureProvisioningCallback0);
+        verifyNoMoreInteractions(mIFeatureProvisioningCallback1);
+        verifyNoMoreInteractions(mImsConfig);
+    }
+
+    @Test
+    @SmallTest
+    public void isImsProvisioningRequiredForCapability_withInvalidCapabilityTech()
+            throws Exception {
+        createImsProvisioningController();
+
+        // invalid Capa. and valid Radio tech - IllegalArgumentException OK
+        try {
+            mTestImsProvisioningController.isImsProvisioningRequiredForCapability(
+                    mSubId0, MMTEL_CAPA_INVALID, RADIO_TECHS[0]);
+        } catch (IllegalArgumentException e) {
+            // expected result
+        } catch (Exception e) {
+            throw new AssertionError("not expected exception", e);
+        }
+
+        // valid Capa. and invalid Radio tech - IllegalArumentException OK
+        try {
+            mTestImsProvisioningController.isImsProvisioningRequiredForCapability(
+                    mSubId0, MMTEL_CAPAS[0], RADIO_TECH_INVALID);
+        } catch (IllegalArgumentException e) {
+            // expected result
+        } catch (Exception e) {
+            throw new AssertionError("not expected exception", e);
+        }
+    }
+
+    @Test
+    @SmallTest
+    public void isImsProvisioningRequiredForCapability_withValidCapabilityTech() throws Exception {
+        createImsProvisioningController();
+
+        // provisioning required capability
+        // voice, all tech
+        // video, all tech
+        // UT, all tech
+        mMmTelTechMap.clear();
+        mMmTelTechMap.put(CAPABILITY_TYPE_VOICE,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN,
+                        REGISTRATION_TECH_CROSS_SIM, REGISTRATION_TECH_NR});
+        mMmTelTechMap.put(CAPABILITY_TYPE_VIDEO,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN,
+                        REGISTRATION_TECH_CROSS_SIM, REGISTRATION_TECH_NR});
+        mMmTelTechMap.put(CAPABILITY_TYPE_UT,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN,
+                        REGISTRATION_TECH_CROSS_SIM, REGISTRATION_TECH_NR});
+
+        boolean[][] expectedRequired = new boolean[][] {
+                {true, true, true, true},
+                {true, true, true, true},
+                {true, true, true, true},
+                {false, false, false, false},
+                {false, false, false, false}
+        };
+
+        boolean isRequired;
+        for (int i = 0; i < MMTEL_CAPAS.length; i++) {
+            for (int j = 0; j < RADIO_TECHS.length; j++) {
+                isRequired = mTestImsProvisioningController
+                .isImsProvisioningRequiredForCapability(
+                        mSubId0, MMTEL_CAPAS[i], RADIO_TECHS[j]);
+                assertEquals(expectedRequired[i][j], isRequired);
+            }
+        }
+    }
+
+    @Test
+    @SmallTest
+    public void isRcsProvisioningRequiredForCapability_withInvalidCapabilityTech()
+            throws Exception {
+        createImsProvisioningController();
+
+        // invalid Capa. and valid Radio tech - IllegalArgumentException OK
+        try {
+            mTestImsProvisioningController.isRcsProvisioningRequiredForCapability(
+                    mSubId0, RCS_CAPA_INVALID, RADIO_TECHS[0]);
+        } catch (IllegalArgumentException e) {
+            // expected result
+        } catch (Exception e) {
+            throw new AssertionError("not expected exception", e);
+        }
+
+        // valid Capa. and invalid Radio tech - IllegalArumentException OK
+        try {
+            mTestImsProvisioningController.isRcsProvisioningRequiredForCapability(
+                    mSubId0, CAPABILITY_TYPE_PRESENCE_UCE, RADIO_TECH_INVALID);
+        } catch (IllegalArgumentException e) {
+            // expected result
+        } catch (Exception e) {
+            throw new AssertionError("not expected exception", e);
+        }
+    }
+
+    @Test
+    @SmallTest
+    public void isRcsProvisioningRequiredForCapability_withValidCapabilityTech() throws Exception {
+        createImsProvisioningController();
+
+        // provisioning required capability : PRESENCE, tech : all
+        mRcsTechMap.clear();
+        mRcsTechMap.put(CAPABILITY_TYPE_PRESENCE_UCE,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN,
+                        REGISTRATION_TECH_CROSS_SIM, REGISTRATION_TECH_NR});
+
+        boolean[] expectedRequired = new boolean[] {true, true, true, true};
+
+        boolean isRequired;
+        for (int i = 0; i < RADIO_TECHS.length; i++) {
+            isRequired = mTestImsProvisioningController
+            .isRcsProvisioningRequiredForCapability(
+                    mSubId0, CAPABILITY_TYPE_PRESENCE_UCE, RADIO_TECHS[i]);
+            assertEquals(expectedRequired[i], isRequired);
+        }
+    }
+
+    @Test
+    @SmallTest
+    public void getImsProvisioningRequiredForCapability_withVoiceVideoUt() throws Exception {
+        createImsProvisioningController();
+
+        // provisioning required capability
+        // voice, all tech
+        // video, all tech
+        // UT, all tech
+        mMmTelTechMap.clear();
+        mMmTelTechMap.put(CAPABILITY_TYPE_VOICE,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN,
+                        REGISTRATION_TECH_CROSS_SIM, REGISTRATION_TECH_NR});
+        mMmTelTechMap.put(CAPABILITY_TYPE_VIDEO,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN,
+                        REGISTRATION_TECH_CROSS_SIM, REGISTRATION_TECH_NR});
+        mMmTelTechMap.put(CAPABILITY_TYPE_UT,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN,
+                        REGISTRATION_TECH_CROSS_SIM, REGISTRATION_TECH_NR});
+
+        // provisioning Status
+        mMmTelProvisioningStorage = new int[][] {
+                {CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_LTE, 0},
+                {CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_IWLAN, 1},
+                {CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_CROSS_SIM, 1},
+                {CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_NR, 1},
+                {CAPABILITY_TYPE_VIDEO, REGISTRATION_TECH_LTE, 0},
+                {CAPABILITY_TYPE_VIDEO, REGISTRATION_TECH_IWLAN, 0},
+                {CAPABILITY_TYPE_VIDEO, REGISTRATION_TECH_CROSS_SIM, 1},
+                {CAPABILITY_TYPE_VIDEO, REGISTRATION_TECH_NR, 1},
+                {CAPABILITY_TYPE_UT, REGISTRATION_TECH_LTE, 0},
+                {CAPABILITY_TYPE_UT, REGISTRATION_TECH_IWLAN, 0},
+                {CAPABILITY_TYPE_UT, REGISTRATION_TECH_CROSS_SIM, 0},
+                {CAPABILITY_TYPE_UT, REGISTRATION_TECH_NR, 0},
+        };
+
+        boolean[] expectedVoiceProvisioningStatus = new boolean[] {false, true, true, true};
+        boolean[] expectedVideoProvisioningStatus = new boolean[] {false, false, true, true};
+        boolean[] expectedUtProvisioningStatus = new boolean[] {false, false, false, false};
+
+        boolean provisioned = false;
+        int capability = CAPABILITY_TYPE_VOICE;
+        for (int i = 0; i < RADIO_TECHS.length; i++) {
+            // get provisioning status
+            provisioned = mTestImsProvisioningController
+                    .getImsProvisioningStatusForCapability(mSubId0, capability, RADIO_TECHS[i]);
+
+            // verify return value
+            assertEquals(expectedVoiceProvisioningStatus[i], provisioned);
+
+            // verify weather ImsProvisioningLoader is called or not
+            verify(mImsProvisioningLoader, times(1))
+                    .getProvisioningStatus(eq(mSubId0), eq(FEATURE_MMTEL), eq(capability),
+                            eq(RADIO_TECHS[i]));
+        }
+
+        capability = CAPABILITY_TYPE_VIDEO;
+        for (int i = 0; i < RADIO_TECHS.length; i++) {
+            // get provisioning status
+            provisioned = mTestImsProvisioningController
+                    .getImsProvisioningStatusForCapability(mSubId0, capability, RADIO_TECHS[i]);
+
+            // verify return value
+            assertEquals(expectedVideoProvisioningStatus[i], provisioned);
+
+            // verify weather ImsProvisioningLoader is called or not
+            verify(mImsProvisioningLoader, times(1))
+                    .getProvisioningStatus(eq(mSubId0), eq(FEATURE_MMTEL), eq(capability),
+                            eq(RADIO_TECHS[i]));
+        }
+
+        capability = CAPABILITY_TYPE_UT;
+        for (int i = 0; i < RADIO_TECHS.length; i++) {
+            // get provisioning status
+            provisioned = mTestImsProvisioningController
+                    .getImsProvisioningStatusForCapability(mSubId0, capability, RADIO_TECHS[i]);
+
+            // verify return value
+            assertEquals(expectedUtProvisioningStatus[i], provisioned);
+
+            // verify weather ImsProvisioningLoader is called or not
+            verify(mImsProvisioningLoader, times(1))
+                    .getProvisioningStatus(eq(mSubId0), eq(FEATURE_MMTEL), eq(capability),
+                            eq(RADIO_TECHS[i]));
+        }
+
+        verifyNoMoreInteractions(mImsProvisioningLoader);
+    }
+
+    @Test
+    @SmallTest
+    public void getImsProvisioningRequiredForCapability_withNotSet() throws Exception {
+        createImsProvisioningController();
+
+        mMmTelConnectorListener0.getValue().connectionReady(mImsManager, mSubId0);
+        processAllMessages();
+
+        clearInvocations(mImsConfig);
+        clearInvocations(mImsProvisioningLoader);
+
+        // provisioning required capability
+        // voice, LTE, IWLAN
+        // video, LTE
+        mMmTelTechMap.clear();
+        mMmTelTechMap.put(CAPABILITY_TYPE_VOICE,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN});
+        mMmTelTechMap.put(CAPABILITY_TYPE_VIDEO,
+                new int[] {REGISTRATION_TECH_LTE});
+
+        // provisioning StatusP, all of provisioning status is not provisioned
+        mMmTelProvisioningStorage = new int[][]{
+                {CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_LTE, -1},
+                {CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_IWLAN, -1},
+                {CAPABILITY_TYPE_VIDEO, REGISTRATION_TECH_LTE, -1}
+        };
+        // provisioning status in vendor ImsService
+        mImsConfigStorage = new int[][] {
+                {KEY_VOLTE_PROVISIONING_STATUS, 1},
+                {KEY_VT_PROVISIONING_STATUS, 0},
+                {KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE, 1},
+        };
+
+        boolean provisioned;
+
+        // for KEY_VOLTE_PROVISIONING_STATUS
+        int capability = CAPABILITY_TYPE_VOICE;
+        int tech = REGISTRATION_TECH_LTE;
+        provisioned = mTestImsProvisioningController
+                .getImsProvisioningStatusForCapability(mSubId0, capability, tech);
+
+        // verify return value default false - not provisioned
+        assertEquals(true, provisioned);
+
+        verify(mImsProvisioningLoader, times(1))
+                .getProvisioningStatus(eq(mSubId0), eq(FEATURE_MMTEL), eq(capability), eq(tech));
+
+        // verify weather ImsProvisioningLoader is called or not
+        verify(mImsConfig, times(1)).getConfigInt(eq(KEY_VOLTE_PROVISIONING_STATUS));
+
+        // verify weather ImsProvisioningLoader is called or not
+        verify(mImsProvisioningLoader, times(1))
+                .setProvisioningStatus(eq(mSubId0), eq(FEATURE_MMTEL), eq(capability), eq(tech),
+                        eq(provisioned));
+
+        clearInvocations(mImsConfig);
+        clearInvocations(mImsProvisioningLoader);
+
+        // for KEY_VT_PROVISIONING_STATUS
+        capability = CAPABILITY_TYPE_VIDEO;
+        tech = REGISTRATION_TECH_LTE;
+        provisioned = mTestImsProvisioningController
+                .getImsProvisioningStatusForCapability(mSubId0, capability, tech);
+
+        // verify return value default false - not provisioned
+        assertEquals(false, provisioned);
+
+        verify(mImsProvisioningLoader, times(1))
+                .getProvisioningStatus(eq(mSubId0), eq(FEATURE_MMTEL), eq(capability), eq(tech));
+
+        // verify weather ImsProvisioningLoader is called or not
+        verify(mImsConfig, times(1)).getConfigInt(eq(KEY_VT_PROVISIONING_STATUS));
+
+        // verify weather ImsProvisioningLoader is called or not
+        verify(mImsProvisioningLoader, times(1))
+                .setProvisioningStatus(eq(mSubId0), eq(FEATURE_MMTEL), eq(capability), eq(tech),
+                        eq(provisioned));
+
+        verifyNoMoreInteractions(mImsConfig);
+        verifyNoMoreInteractions(mImsProvisioningLoader);
+    }
+
+    @Test
+    @SmallTest
+    public void getRcsProvisioningRequiredForCapability_withPresence() throws Exception {
+        createImsProvisioningController();
+
+        // provisioning required capability
+        // PRESENCE, all tech
+        mRcsTechMap.clear();
+        mRcsTechMap.put(CAPABILITY_TYPE_PRESENCE_UCE,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN,
+                        REGISTRATION_TECH_CROSS_SIM, REGISTRATION_TECH_NR});
+
+        // provisioning Status
+        mRcsProvisioningStorage = new int[][] {
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_LTE, 1},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_IWLAN, 1},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_CROSS_SIM, 1},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_NR, 1}
+        };
+
+        boolean[] expectedPresenceProvisioningStatus = new boolean[] {true, true, true, true};
+
+        boolean provisioned = false;
+        int capability = CAPABILITY_TYPE_PRESENCE_UCE;
+        for (int i = 0; i < RADIO_TECHS.length; i++) {
+            // get provisioning status
+            provisioned = mTestImsProvisioningController
+                    .getRcsProvisioningStatusForCapability(mSubId0, capability, RADIO_TECHS[i]);
+
+            // verify return value
+            assertEquals(expectedPresenceProvisioningStatus[i], provisioned);
+
+            // verify weather ImsProvisioningLoader is called or not
+            verify(mImsProvisioningLoader, times(1)).getProvisioningStatus(
+                    eq(mSubId0), eq(FEATURE_RCS), eq(capability), eq(RADIO_TECHS[i]));
+        }
+
+        verifyNoMoreInteractions(mImsProvisioningLoader);
+    }
+
+    @Test
+    @SmallTest
+    public void getRcsProvisioningRequiredForCapability_withNotSet() throws Exception {
+        createImsProvisioningController();
+
+        mRcsConnectorListener0.getValue().connectionReady(mRcsFeatureManager, mSubId0);
+        processAllMessages();
+
+        clearInvocations(mImsConfig);
+        clearInvocations(mImsProvisioningLoader);
+
+        // provisioning required capability
+        // PRESENCE, LTE, IWLAN
+        mRcsTechMap.clear();
+        mRcsTechMap.put(CAPABILITY_TYPE_PRESENCE_UCE,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN});
+
+        // provisioning Status, all of provisioning status is not provisioned
+        mRcsProvisioningStorage = new int[][]{
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_LTE, -1},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_IWLAN, -1},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_CROSS_SIM, -1},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_NR, -1}
+        };
+        // provisioning status in vendor ImsService
+        mImsConfigStorage = new int[][] {
+                {KEY_EAB_PROVISIONING_STATUS, 1}
+        };
+
+        boolean provisioned;
+
+        // for KEY_EAB_PROVISIONING_STATUS
+        int capability = CAPABILITY_TYPE_PRESENCE_UCE;
+        int tech = REGISTRATION_TECH_LTE;
+        provisioned = mTestImsProvisioningController
+                .getRcsProvisioningStatusForCapability(mSubId0, capability, tech);
+
+        // verify return value default false - not provisioned
+        assertEquals(true, provisioned);
+
+        verify(mImsProvisioningLoader, times(1)).getProvisioningStatus(
+                eq(mSubId0), eq(FEATURE_RCS), eq(capability), eq(tech));
+
+        // verify weather ImsProvisioningLoader is called or not
+        verify(mImsConfig, times(1)).getConfigInt(eq(KEY_EAB_PROVISIONING_STATUS));
+
+        // verify weather ImsProvisioningLoader is called or not
+        verify(mImsProvisioningLoader, times(RADIO_TECHS.length)).setProvisioningStatus(
+                eq(mSubId0), eq(FEATURE_RCS), eq(capability), anyInt(), eq(provisioned));
+
+        verifyNoMoreInteractions(mImsConfig);
+        verifyNoMoreInteractions(mImsProvisioningLoader);
+    }
+
+    @Test
+    @SmallTest
+    public void setImsProvisioningRequiredForCapability_withVoice() throws Exception {
+        createImsProvisioningController();
+
+        mMmTelConnectorListener0.getValue().connectionReady(mImsManager, mSubId0);
+        processAllMessages();
+
+        // register callbacks
+        mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                mSubId0, mIFeatureProvisioningCallback0);
+        mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                mSubId1, mIFeatureProvisioningCallback1);
+
+        clearInvocations(mIFeatureProvisioningCallback0);
+        clearInvocations(mIFeatureProvisioningCallback1);
+        clearInvocations(mImsConfig);
+        clearInvocations(mImsProvisioningLoader);
+
+        // provisioning required capability
+        // voice, all tech
+        mMmTelTechMap.clear();
+        mMmTelTechMap.put(CAPABILITY_TYPE_VOICE,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN,
+                        REGISTRATION_TECH_CROSS_SIM, REGISTRATION_TECH_NR});
+
+        // provisioning Status, all of provisioning status is not provisioned
+        mMmTelProvisioningStorage = new int[][] {
+                {CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_LTE, 0},
+                {CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_IWLAN, 0},
+                {CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_CROSS_SIM, 0},
+                {CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_NR, 0}
+        };
+
+        boolean provisionedFirst = false;
+        boolean provisionedSecond = false;
+        int capability = CAPABILITY_TYPE_VOICE;
+        for (int i = 0; i < RADIO_TECHS.length; i++) {
+            // get provisioning status
+            provisionedFirst = mTestImsProvisioningController
+                    .getImsProvisioningStatusForCapability(mSubId0, capability, RADIO_TECHS[i]);
+
+            // verify return value default false - not provisioned
+            assertEquals(false, provisionedFirst);
+
+            mTestImsProvisioningController.setImsProvisioningStatusForCapability(
+                    mSubId0, capability, RADIO_TECHS[i], !provisionedFirst);
+            processAllMessages();
+
+            provisionedSecond = mTestImsProvisioningController
+                    .getImsProvisioningStatusForCapability(mSubId0, capability, RADIO_TECHS[i]);
+
+            // verify return value default false - provisioned
+            assertEquals(!provisionedFirst, provisionedSecond);
+
+            // verify weather ImsProvisioningLoader is called or not
+            verify(mImsProvisioningLoader, times(2))
+                    .getProvisioningStatus(eq(mSubId0), eq(FEATURE_MMTEL), eq(capability),
+                            eq(RADIO_TECHS[i]));
+            verify(mImsProvisioningLoader, times(1))
+                    .setProvisioningStatus(eq(mSubId0), eq(FEATURE_MMTEL), eq(capability),
+                            eq(RADIO_TECHS[i]), eq(provisionedSecond));
+
+            // verify weather Callback is called or not
+            verify(mIFeatureProvisioningCallback0, times(1))
+                    .onFeatureProvisioningChanged(eq(capability), eq(RADIO_TECHS[i]),
+                            eq(provisionedSecond));
+        }
+
+        // verify weather ImsConfig is called or not
+        verify(mImsConfig, times(1)).setConfig(
+                eq(KEY_VOLTE_PROVISIONING_STATUS), eq(PROVISIONING_VALUE_ENABLED));
+        verify(mImsConfig, times(1)).setConfig(
+                eq(KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE), eq(PROVISIONING_VALUE_ENABLED));
+
+        verifyNoMoreInteractions(mIFeatureProvisioningCallback0);
+        verifyNoMoreInteractions(mIFeatureProvisioningCallback1);
+        verifyNoMoreInteractions(mImsConfig);
+        verifyNoMoreInteractions(mImsProvisioningLoader);
+    }
+
+    @Test
+    @SmallTest
+    public void setImsProvisioningRequiredForCapability_withVideo() throws Exception {
+        createImsProvisioningController();
+
+        mMmTelConnectorListener0.getValue().connectionReady(mImsManager, mSubId0);
+        processAllMessages();
+
+        // register callbacks
+        mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                mSubId0, mIFeatureProvisioningCallback0);
+        mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                mSubId1, mIFeatureProvisioningCallback1);
+
+        clearInvocations(mIFeatureProvisioningCallback0);
+        clearInvocations(mIFeatureProvisioningCallback1);
+        clearInvocations(mImsConfig);
+        clearInvocations(mImsProvisioningLoader);
+
+        // provisioning required capability
+        // video, all tech
+        mMmTelTechMap.clear();
+        mMmTelTechMap.put(CAPABILITY_TYPE_VIDEO,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN,
+                        REGISTRATION_TECH_CROSS_SIM, REGISTRATION_TECH_NR});
+
+        // provisioning Status, all of provisioning status is not provisioned
+        mMmTelProvisioningStorage = new int[][] {
+                {CAPABILITY_TYPE_VIDEO, REGISTRATION_TECH_LTE, 0},
+                {CAPABILITY_TYPE_VIDEO, REGISTRATION_TECH_IWLAN, 0},
+                {CAPABILITY_TYPE_VIDEO, REGISTRATION_TECH_CROSS_SIM, 0},
+                {CAPABILITY_TYPE_VIDEO, REGISTRATION_TECH_NR, 0}
+        };
+
+        boolean provisionedFirst = false;
+        boolean provisionedSecond = false;
+        int capability = CAPABILITY_TYPE_VIDEO;
+        for (int i = 0; i < RADIO_TECHS.length; i++) {
+            // get provisioning status
+            provisionedFirst = mTestImsProvisioningController
+                    .getImsProvisioningStatusForCapability(mSubId0, capability, RADIO_TECHS[i]);
+
+            // verify return value default false - not provisioned
+            assertEquals(false, provisionedFirst);
+
+            mTestImsProvisioningController.setImsProvisioningStatusForCapability(
+                    mSubId0, capability, RADIO_TECHS[i], !provisionedFirst);
+            processAllMessages();
+
+            provisionedSecond = mTestImsProvisioningController
+                    .getImsProvisioningStatusForCapability(mSubId0, capability, RADIO_TECHS[i]);
+
+            // verify return value default false - provisioned
+            assertEquals(!provisionedFirst, provisionedSecond);
+
+            // verify weather ImsProvisioningLoader is called or not
+            verify(mImsProvisioningLoader, times(2))
+                    .getProvisioningStatus(eq(mSubId0), eq(FEATURE_MMTEL), eq(capability),
+                            eq(RADIO_TECHS[i]));
+            verify(mImsProvisioningLoader, times(1))
+                    .setProvisioningStatus(eq(mSubId0), eq(FEATURE_MMTEL), eq(capability),
+                            eq(RADIO_TECHS[i]), eq(provisionedSecond));
+
+            // verify weather Callback is called or not
+            verify(mIFeatureProvisioningCallback0, times(1))
+                    .onFeatureProvisioningChanged(eq(capability), eq(RADIO_TECHS[i]),
+                            eq(provisionedSecond));
+        }
+
+        // verify weather ImsConfig is called or not
+        verify(mImsConfig, times(1)).setConfig(
+                eq(KEY_VT_PROVISIONING_STATUS), eq(PROVISIONING_VALUE_ENABLED));
+
+        verifyNoMoreInteractions(mIFeatureProvisioningCallback0);
+        verifyNoMoreInteractions(mIFeatureProvisioningCallback1);
+        verifyNoMoreInteractions(mImsConfig);
+        verifyNoMoreInteractions(mImsProvisioningLoader);
+    }
+
+    @Test
+    @SmallTest
+    public void setRcsProvisioningRequiredForCapability_withPresence() throws Exception {
+        createImsProvisioningController();
+
+        mRcsConnectorListener0.getValue().connectionReady(mRcsFeatureManager, mSubId0);
+        processAllMessages();
+
+        // register callbacks
+        mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                mSubId0, mIFeatureProvisioningCallback0);
+        mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                mSubId1, mIFeatureProvisioningCallback1);
+
+        clearInvocations(mIFeatureProvisioningCallback0);
+        clearInvocations(mIFeatureProvisioningCallback1);
+        clearInvocations(mImsConfig);
+        clearInvocations(mImsProvisioningLoader);
+
+        // provisioning required capability
+        // PRESENCE, all tech
+        mRcsTechMap.clear();
+        mRcsTechMap.put(CAPABILITY_TYPE_PRESENCE_UCE,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN,
+                        REGISTRATION_TECH_CROSS_SIM, REGISTRATION_TECH_NR});
+
+        // provisioning Status, all of provisioning status is not provisioned
+        mRcsProvisioningStorage = new int[][] {
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_LTE, 0},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_IWLAN, 0},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_CROSS_SIM, 0},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_NR, 0}
+        };
+
+        boolean provisionedFirst;
+        boolean provisionedSecond;
+        int capability = CAPABILITY_TYPE_PRESENCE_UCE;
+
+        // get provisioning status
+        provisionedFirst = mTestImsProvisioningController
+                .getRcsProvisioningStatusForCapability(mSubId0, capability, REGISTRATION_TECH_LTE);
+
+        // verify return value default false - not provisioned
+        assertEquals(false, provisionedFirst);
+
+        mTestImsProvisioningController.setRcsProvisioningStatusForCapability(
+                mSubId0, capability, REGISTRATION_TECH_LTE, !provisionedFirst);
+        processAllMessages();
+
+        provisionedSecond = mTestImsProvisioningController
+                .getRcsProvisioningStatusForCapability(mSubId0, capability, REGISTRATION_TECH_LTE);
+
+        // verify return value default false - provisioned
+        assertEquals(!provisionedFirst, provisionedSecond);
+
+        // verify weather ImsProvisioningLoader is called or not
+        verify(mImsProvisioningLoader, times(2)).getProvisioningStatus(
+                eq(mSubId0), eq(FEATURE_RCS), eq(capability), eq(REGISTRATION_TECH_LTE));
+        // verify setProvisioningStatus is called RADIO_TECHS.length times for all tech or not
+        verify(mImsProvisioningLoader, times(1)).setProvisioningStatus(
+                eq(mSubId0), eq(FEATURE_RCS), eq(capability), anyInt(), eq(provisionedSecond));
+
+        // verify weather Callback is called RADIO_TECHS.length times for all tech or not
+        verify(mIFeatureProvisioningCallback0, times(1))
+                .onRcsFeatureProvisioningChanged(eq(capability), eq(REGISTRATION_TECH_LTE),
+                        eq(provisionedSecond));
+
+        // verify weather ImsConfig is called or not
+        verify(mImsConfig, times(1)).setConfig(
+                eq(KEY_EAB_PROVISIONING_STATUS), eq(PROVISIONING_VALUE_ENABLED));
+
+        // verify reset
+        clearInvocations(mImsProvisioningLoader);
+
+        // only CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_LTE - provisioned
+        boolean[] expected = {true, false, false, false};
+        for (int i = 0; i < RADIO_TECHS.length; i++) {
+            provisionedSecond = mTestImsProvisioningController
+                    .getRcsProvisioningStatusForCapability(mSubId0, capability, RADIO_TECHS[i]);
+
+            // verify return value
+            assertEquals(expected[i], provisionedSecond);
+
+            // verify weather ImsProvisioningLoader is called or not
+            verify(mImsProvisioningLoader, times(1)).getProvisioningStatus(
+                    eq(mSubId0), eq(FEATURE_RCS), eq(capability), eq(RADIO_TECHS[i]));
+        }
+
+        verifyNoMoreInteractions(mIFeatureProvisioningCallback0);
+        verifyNoMoreInteractions(mIFeatureProvisioningCallback1);
+        verifyNoMoreInteractions(mImsConfig);
+        verifyNoMoreInteractions(mImsProvisioningLoader);
+    }
+
+    @Test
+    @SmallTest
+    public void setProvisioningValue_withMmTelKey() throws Exception {
+        createImsProvisioningController();
+
+        mMmTelConnectorListener0.getValue().connectionReady(mImsManager, mSubId0);
+        processAllMessages();
+
+        // add callback with valid obj
+        mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                mSubId0, mIFeatureProvisioningCallback0);
+        mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                mSubId1, mIFeatureProvisioningCallback1);
+
+        clearInvocations(mIFeatureProvisioningCallback0);
+        clearInvocations(mIFeatureProvisioningCallback1);
+        clearInvocations(mImsConfig);
+        clearInvocations(mImsProvisioningLoader);
+
+        // provisioning required capability
+        // voice, all tech
+        // video, all tech
+        mMmTelTechMap.clear();
+        mMmTelTechMap.put(CAPABILITY_TYPE_VOICE,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN,
+                        REGISTRATION_TECH_CROSS_SIM, REGISTRATION_TECH_NR});
+        mMmTelTechMap.put(CAPABILITY_TYPE_VIDEO,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN,
+                        REGISTRATION_TECH_CROSS_SIM, REGISTRATION_TECH_NR});
+
+        // provisioning Status, all of provisioning status is not set
+        mMmTelProvisioningStorage = new int[][] {
+                {CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_LTE, -1},
+                {CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_IWLAN, -1},
+                {CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_CROSS_SIM, -1},
+                {CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_NR, -1},
+                {CAPABILITY_TYPE_VIDEO, REGISTRATION_TECH_LTE, -1},
+                {CAPABILITY_TYPE_VIDEO, REGISTRATION_TECH_IWLAN, -1},
+                {CAPABILITY_TYPE_VIDEO, REGISTRATION_TECH_CROSS_SIM, -1},
+                {CAPABILITY_TYPE_VIDEO, REGISTRATION_TECH_NR, -1}
+        };
+
+        // MmTel valid
+        int[] keys = {
+                ProvisioningManager.KEY_VOLTE_PROVISIONING_STATUS,
+                ProvisioningManager.KEY_VT_PROVISIONING_STATUS,
+                ProvisioningManager.KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE
+        };
+        int[] capas = {
+                MmTelCapabilities.CAPABILITY_TYPE_VOICE,
+                MmTelCapabilities.CAPABILITY_TYPE_VIDEO,
+                MmTelCapabilities.CAPABILITY_TYPE_VOICE
+        };
+        int[] techs = {
+                ImsRegistrationImplBase.REGISTRATION_TECH_LTE,
+                ImsRegistrationImplBase.REGISTRATION_TECH_LTE,
+                ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
+        };
+
+        int result;
+        for (int i = 0; i < keys.length; i++) {
+            clearInvocations(mIFeatureProvisioningCallback0);
+            result = mTestImsProvisioningController.setProvisioningValue(
+                    mSubId0, keys[i], PROVISIONING_VALUE_ENABLED);
+            processAllMessages();
+
+            // check return value
+            assertEquals(ImsConfig.OperationStatusConstants.SUCCESS, result);
+
+            // check weather to save
+            verify(mImsProvisioningLoader, times(1)).setProvisioningStatus(
+                    eq(mSubId0), eq(FEATURE_MMTEL), eq(capas[i]), eq(techs[i]), eq(true));
+
+            verify(mIFeatureProvisioningCallback0, times(1))
+                    .onFeatureProvisioningChanged(eq(capas[i]), eq(techs[i]), eq(true));
+
+            verify(mImsConfig, times(1)).setConfig(eq(keys[i]), eq(PROVISIONING_VALUE_ENABLED));
+        }
+
+        verifyNoMoreInteractions(mIFeatureProvisioningCallback0);
+        verifyNoMoreInteractions(mIFeatureProvisioningCallback1);
+        verifyNoMoreInteractions(mImsConfig);
+        verifyNoMoreInteractions(mImsProvisioningLoader);
+    }
+
+    @Test
+    @SmallTest
+    public void setProvisioningValue_withRcsKey() throws Exception {
+        createImsProvisioningController();
+
+        mRcsConnectorListener0.getValue().connectionReady(mRcsFeatureManager, mSubId0);
+        processAllMessages();
+
+        // add callback with valid obj
+        mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                mSubId0, mIFeatureProvisioningCallback0);
+        mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                mSubId1, mIFeatureProvisioningCallback1);
+
+        clearInvocations(mIFeatureProvisioningCallback0);
+        clearInvocations(mIFeatureProvisioningCallback1);
+        clearInvocations(mImsConfig);
+        clearInvocations(mImsProvisioningLoader);
+
+        // provisioning required capability
+        // presence, all tech
+        mRcsTechMap.clear();
+        mRcsTechMap.put(CAPABILITY_TYPE_PRESENCE_UCE,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN,
+                        REGISTRATION_TECH_CROSS_SIM, REGISTRATION_TECH_NR});
+
+        // provisioning Status, all of provisioning status is not set
+        mRcsProvisioningStorage = new int[][]{
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_LTE, -1},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_IWLAN, -1},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_CROSS_SIM, -1},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_NR, -1}
+        };
+
+        int key = KEY_EAB_PROVISIONING_STATUS;
+        int capa = CAPABILITY_TYPE_PRESENCE_UCE;
+
+        int result = mTestImsProvisioningController.setProvisioningValue(
+                    mSubId0, key, PROVISIONING_VALUE_ENABLED);
+        processAllMessages();
+
+        // check return value
+        assertEquals(ImsConfig.OperationStatusConstants.SUCCESS, result);
+
+        // check weather to save, for all techs 4 times
+        verify(mImsProvisioningLoader, times(RADIO_TECHS.length)).setProvisioningStatus(
+                eq(mSubId0), eq(FEATURE_RCS), eq(capa), anyInt(), eq(true));
+
+        verify(mIFeatureProvisioningCallback0, times(RADIO_TECHS.length))
+                .onRcsFeatureProvisioningChanged(eq(capa), anyInt(), eq(true));
+
+        verify(mImsConfig, times(1)).setConfig(eq(key), eq(PROVISIONING_VALUE_ENABLED));
+
+        verifyNoMoreInteractions(mIFeatureProvisioningCallback0);
+        verifyNoMoreInteractions(mIFeatureProvisioningCallback1);
+        verifyNoMoreInteractions(mImsConfig);
+        verifyNoMoreInteractions(mImsProvisioningLoader);
+    }
+
+    @Test
+    @SmallTest
+    public void setProvisioningValue_withInvalidKey() throws Exception {
+        createImsProvisioningController();
+
+        mMmTelConnectorListener0.getValue().connectionReady(mImsManager, mSubId0);
+        mRcsConnectorListener0.getValue().connectionReady(mRcsFeatureManager, mSubId0);
+        processAllMessages();
+
+        // add callback with valid obj
+        mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                mSubId0, mIFeatureProvisioningCallback0);
+        mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                mSubId1, mIFeatureProvisioningCallback1);
+
+        clearInvocations(mIFeatureProvisioningCallback0);
+        clearInvocations(mIFeatureProvisioningCallback1);
+        clearInvocations(mImsConfig);
+        clearInvocations(mImsProvisioningLoader);
+
+        // invalid key
+        int[] keys = {
+                ProvisioningManager.KEY_SIP_SESSION_TIMER_SEC,
+                ProvisioningManager.KEY_MINIMUM_SIP_SESSION_EXPIRATION_TIMER_SEC,
+                ProvisioningManager.KEY_TF_TIMER_VALUE_MS
+        };
+        for (int key : keys) {
+            int result = mTestImsProvisioningController.setProvisioningValue(
+                    mSubId0, key, PROVISIONING_VALUE_ENABLED);
+            processAllMessages();
+
+            // check return value
+            assertEquals(ImsConfigImplBase.CONFIG_RESULT_UNKNOWN, result);
+        }
+
+        verifyNoMoreInteractions(mIFeatureProvisioningCallback0);
+        verifyNoMoreInteractions(mIFeatureProvisioningCallback1);
+        verifyNoMoreInteractions(mImsConfig);
+        verifyNoMoreInteractions(mImsProvisioningLoader);
+    }
+
+    @Test
+    @SmallTest
+    public void getProvisioningValue_withValidKey() throws Exception {
+        createImsProvisioningController();
+
+        mMmTelConnectorListener0.getValue().connectionReady(mImsManager, mSubId0);
+        mRcsConnectorListener0.getValue().connectionReady(mRcsFeatureManager, mSubId0);
+        processAllMessages();
+
+        // add callback with valid obj
+        mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                mSubId0, mIFeatureProvisioningCallback0);
+        mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                mSubId1, mIFeatureProvisioningCallback1);
+
+        clearInvocations(mIFeatureProvisioningCallback0);
+        clearInvocations(mIFeatureProvisioningCallback1);
+        clearInvocations(mImsConfig);
+        clearInvocations(mImsProvisioningLoader);
+
+        // provisioning required capability
+        // voice, LTE, IWLAN
+        // video, LTE
+        mMmTelTechMap.clear();
+        mMmTelTechMap.put(CAPABILITY_TYPE_VOICE,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN});
+        mMmTelTechMap.put(CAPABILITY_TYPE_VIDEO,
+                new int[] {REGISTRATION_TECH_LTE});
+
+        // provisioning Status, all of provisioning status is not set
+        mMmTelProvisioningStorage = new int[][] {
+                {CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_LTE, 1},
+                {CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_IWLAN, 1},
+                {CAPABILITY_TYPE_VIDEO, REGISTRATION_TECH_LTE, 1}
+        };
+
+        // provisioning required capability
+        // presence, all tech
+        mRcsTechMap.clear();
+        mRcsTechMap.put(CAPABILITY_TYPE_PRESENCE_UCE,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN,
+                        REGISTRATION_TECH_CROSS_SIM, REGISTRATION_TECH_NR});
+
+        // provisioning Status, all of provisioning status is not set
+        mRcsProvisioningStorage = new int[][]{
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_LTE, 1},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_IWLAN, 1},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_CROSS_SIM, 1},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_NR, 1}
+        };
+
+        // MmTel keys
+        int[] keys = {
+                KEY_VOLTE_PROVISIONING_STATUS,
+                KEY_VT_PROVISIONING_STATUS,
+                KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE,
+        };
+        int[] capas = {
+                CAPABILITY_TYPE_VOICE,
+                CAPABILITY_TYPE_VIDEO,
+                CAPABILITY_TYPE_VOICE
+        };
+        int[] techs = {
+                REGISTRATION_TECH_LTE,
+                REGISTRATION_TECH_LTE,
+                REGISTRATION_TECH_IWLAN
+        };
+        for (int i = 0; i < keys.length; i++) {
+            int result = mTestImsProvisioningController.getProvisioningValue(mSubId0, keys[i]);
+            processAllMessages();
+
+            // check return value
+            assertEquals(PROVISIONING_VALUE_ENABLED, result);
+
+            // verify weather ImsProvisioningLoader is called or not
+            verify(mImsProvisioningLoader, times(1)).getProvisioningStatus(eq(mSubId0),
+                    eq(FEATURE_MMTEL), eq(capas[i]), eq(techs[i]));
+        }
+        clearInvocations(mImsProvisioningLoader);
+
+        // Rcs keys
+        int key = KEY_EAB_PROVISIONING_STATUS;
+        int capa = CAPABILITY_TYPE_PRESENCE_UCE;
+
+        int result = mTestImsProvisioningController.getProvisioningValue(mSubId0, key);
+        processAllMessages();
+
+        // check return value
+        assertEquals(PROVISIONING_VALUE_ENABLED, result);
+
+        // verify weather ImsProvisioningLoader is called or not
+        verify(mImsProvisioningLoader, times(1)).getProvisioningStatus(
+                eq(mSubId0), eq(FEATURE_RCS), eq(capa), anyInt());
+
+        verifyNoMoreInteractions(mIFeatureProvisioningCallback0);
+        verifyNoMoreInteractions(mIFeatureProvisioningCallback1);
+        verifyNoMoreInteractions(mImsConfig);
+        verifyNoMoreInteractions(mImsProvisioningLoader);
+    }
+
+    @Test
+    @SmallTest
+    public void getProvisioningValue_withNotSet() throws Exception {
+        createImsProvisioningController();
+
+        mMmTelConnectorListener0.getValue().connectionReady(mImsManager, mSubId0);
+        mRcsConnectorListener0.getValue().connectionReady(mRcsFeatureManager, mSubId0);
+        processAllMessages();
+
+        // add callback with valid obj
+        mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                mSubId0, mIFeatureProvisioningCallback0);
+        mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                mSubId1, mIFeatureProvisioningCallback1);
+
+        clearInvocations(mIFeatureProvisioningCallback0);
+        clearInvocations(mIFeatureProvisioningCallback1);
+        clearInvocations(mImsConfig);
+        clearInvocations(mImsProvisioningLoader);
+
+        // provisioning required capability
+        // voice, LTE, IWLAN
+        // video, LTE
+        mMmTelTechMap.clear();
+        mMmTelTechMap.put(CAPABILITY_TYPE_VOICE,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN});
+        mMmTelTechMap.put(CAPABILITY_TYPE_VIDEO,
+                new int[] {REGISTRATION_TECH_LTE});
+
+        // provisioning Status, all of provisioning status is not set
+        mMmTelProvisioningStorage = new int[][] {
+                {CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_LTE, -1},
+                {CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_IWLAN, -1},
+                {CAPABILITY_TYPE_VIDEO, REGISTRATION_TECH_LTE, -1}
+        };
+
+        // provisioning required capability
+        // presence, all tech
+        mRcsTechMap.clear();
+        mRcsTechMap.put(CAPABILITY_TYPE_PRESENCE_UCE,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN,
+                        REGISTRATION_TECH_CROSS_SIM, REGISTRATION_TECH_NR});
+
+        // provisioning Status, all of provisioning status is not set
+        mRcsProvisioningStorage = new int[][]{
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_LTE, -1},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_IWLAN, -1},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_CROSS_SIM, -1},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_NR, -1}
+        };
+        // provisioning status in ImsService
+        mImsConfigStorage = new int[][] {
+                {KEY_VOLTE_PROVISIONING_STATUS, 1},
+                {KEY_VT_PROVISIONING_STATUS, 1},
+                {KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE, 1},
+                {KEY_EAB_PROVISIONING_STATUS, 1}
+        };
+
+        // MmTel keys
+        int[] keys = {
+                KEY_VOLTE_PROVISIONING_STATUS,
+                KEY_VT_PROVISIONING_STATUS,
+                KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE,
+        };
+        int[] capas = {
+                CAPABILITY_TYPE_VOICE,
+                CAPABILITY_TYPE_VIDEO,
+                CAPABILITY_TYPE_VOICE
+        };
+        int[] techs = {
+                REGISTRATION_TECH_LTE,
+                REGISTRATION_TECH_LTE,
+                REGISTRATION_TECH_IWLAN
+        };
+        for (int i = 0; i < keys.length; i++) {
+            int result = mTestImsProvisioningController.getProvisioningValue(mSubId0, keys[i]);
+            processAllMessages();
+
+            // check return value
+            assertEquals(PROVISIONING_VALUE_ENABLED, result);
+
+            // verify weather ImsProvisioningLoader is called or not
+            verify(mImsProvisioningLoader, times(1)).getProvisioningStatus(eq(mSubId0),
+                    eq(FEATURE_MMTEL), eq(capas[i]), eq(techs[i]));
+
+            // verify weather ImsConfig is called or not
+            verify(mImsConfig, times(1)).getConfigInt(eq(keys[i]));
+
+            // verify weather ImsProvisioningLoader is called or not
+            verify(mImsProvisioningLoader, times(1)).setProvisioningStatus(eq(mSubId0),
+                    eq(FEATURE_MMTEL), eq(capas[i]), eq(techs[i]), eq(true));
+
+            // verify weather callback is called or not
+            verify(mIFeatureProvisioningCallback0, times(1)).onFeatureProvisioningChanged(
+                    eq(capas[i]), eq(techs[i]), eq(true));
+        }
+        clearInvocations(mImsConfig);
+        clearInvocations(mImsProvisioningLoader);
+
+        // Rcs keys
+        int key = KEY_EAB_PROVISIONING_STATUS;
+        int capa = CAPABILITY_TYPE_PRESENCE_UCE;
+
+        int result = mTestImsProvisioningController.getProvisioningValue(mSubId0, key);
+        processAllMessages();
+
+        // check return value
+        assertEquals(PROVISIONING_VALUE_ENABLED, result);
+
+        // verify weather ImsProvisioningLoader is called or not
+        verify(mImsProvisioningLoader, times(1)).getProvisioningStatus(
+                eq(mSubId0), eq(FEATURE_RCS), eq(capa), anyInt());
+
+        // verify weather ImsConfig is called or not
+        verify(mImsConfig, times(1)).getConfigInt(eq(key));
+
+        // verify weather ImsProvisioningLoader is called or not
+        verify(mImsProvisioningLoader, times(RADIO_TECHS.length)).setProvisioningStatus(
+                eq(mSubId0), eq(FEATURE_RCS), eq(capa), anyInt(), eq(true));
+
+        // verify weather callback is called or not
+        verify(mIFeatureProvisioningCallback0, times(RADIO_TECHS.length))
+                .onRcsFeatureProvisioningChanged(eq(capa), anyInt(), eq(true));
+
+        verifyNoMoreInteractions(mIFeatureProvisioningCallback0);
+        verifyNoMoreInteractions(mIFeatureProvisioningCallback1);
+        verifyNoMoreInteractions(mImsConfig);
+        verifyNoMoreInteractions(mImsProvisioningLoader);
+    }
+
+    @Test
+    @SmallTest
+    public void onMultiSimConfigChanged() throws Exception {
+        createImsProvisioningController();
+
+        // change number of slot 2 -> 1
+        mHandler.sendMessage(mHandler.obtainMessage(
+                mTestImsProvisioningController.EVENT_MULTI_SIM_CONFIGURATION_CHANGE,
+                0, 0, (Object) new AsyncResult(null, 1, null)));
+        processAllMessages();
+
+        // add callback with mSubId0, mPhoneId0 : Ok.
+        try {
+            mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                    mSubId0, mIFeatureProvisioningCallback0);
+        } catch (Exception e) {
+            throw new AssertionError("not expected exception", e);
+        }
+
+        // add callbacks with new mSubId1, mPhoneId1 : IllegalArgumentException.
+        try {
+            mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                    mSubId1, mIFeatureProvisioningCallback1);
+        } catch (IllegalArgumentException e) {
+            // expected result
+        } catch (Exception e) {
+            throw new AssertionError("not expected exception", e);
+        }
+        // check isImsProvisioningRequiredForCapability with mSubId1 : IllegalArgumentException
+        try {
+            mTestImsProvisioningController.isImsProvisioningRequiredForCapability(
+                    mSubId1, CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_LTE);
+        } catch (IllegalArgumentException e) {
+            // expected result
+        } catch (Exception e) {
+            throw new AssertionError("not expected exception", e);
+        }
+        clearInvocations(mIFeatureProvisioningCallback0);
+        clearInvocations(mIFeatureProvisioningCallback1);
+
+        // change number of slot 1 -> 2
+        mHandler.sendMessage(mHandler.obtainMessage(
+                mTestImsProvisioningController.EVENT_MULTI_SIM_CONFIGURATION_CHANGE,
+                0, 0, (Object) new AsyncResult(null, 2, null)));
+        processAllMessages();
+
+        // add callback with mSubId0, mPhoneId0 : Ok.
+        try {
+            mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                    mSubId0, mIFeatureProvisioningCallback0);
+        } catch (Exception e) {
+            throw new AssertionError("not expected exception", e);
+        }
+
+        // add callbacks with new mSubId1, mPhoneId1 : Ok.
+        try {
+            mTestImsProvisioningController.addFeatureProvisioningChangedCallback(
+                    mSubId1, mIFeatureProvisioningCallback1);
+        } catch (Exception e) {
+            throw new AssertionError("not expected exception", e);
+        }
+        clearInvocations(mIFeatureProvisioningCallback0);
+        clearInvocations(mIFeatureProvisioningCallback1);
+
+        // check get,setImsProvisioningRequiredForCapability with mSubId1, mPhoneId1 : Ok
+        int capability = CAPABILITY_TYPE_VOICE;
+        int tech = REGISTRATION_TECH_LTE;
+        boolean provisioned;
+        provisioned = mTestImsProvisioningController.getImsProvisioningStatusForCapability(
+                mSubId1, capability, tech);
+        mTestImsProvisioningController.setImsProvisioningStatusForCapability(mSubId1,
+                capability, tech, !provisioned);
+        processAllMessages();
+
+        // verify weather Callback is called or not
+        verify(mIFeatureProvisioningCallback1, times(1))
+                .onFeatureProvisioningChanged(eq(capability), eq(tech), eq(!provisioned));
+
+        clearInvocations(mIFeatureProvisioningCallback0);
+        clearInvocations(mIFeatureProvisioningCallback1);
+        clearInvocations(mImsConfig);
+    }
+
+    private void createImsProvisioningController() throws Exception {
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+
+        when(mMmTelFeatureConnector
+                .create(any(), eq(0), any(), mMmTelConnectorListener0.capture(), any()))
+                .thenReturn(mMmTelFeatureConnector0);
+        when(mMmTelFeatureConnector
+                .create(any(), eq(1), any(), mMmTelConnectorListener1.capture(), any()))
+                .thenReturn(mMmTelFeatureConnector1);
+
+        when(mRcsFeatureConnector
+                .create(any(), eq(0), mRcsConnectorListener0.capture(), any(), any()))
+                .thenReturn(mRcsFeatureConnector0);
+        when(mRcsFeatureConnector
+                .create(any(), eq(1), mRcsConnectorListener1.capture(), any(), any()))
+                .thenReturn(mRcsFeatureConnector1);
+
+        when(mImsConfig.getConfigInt(anyInt()))
+                .thenAnswer(invocation -> {
+                    int i = (Integer) (invocation.getArguments()[0]);
+                    return getImsConfigValue(i);
+                });
+        when(mImsConfig.setConfig(anyInt(), anyInt()))
+                .thenAnswer(invocation -> {
+                    int i = (Integer) (invocation.getArguments()[0]);
+                    int j = (Integer) (invocation.getArguments()[1]);
+                    return setImsConfigValue(i, j);
+                });
+
+        when(mImsProvisioningLoader.getProvisioningStatus(anyInt(), eq(FEATURE_MMTEL), anyInt(),
+                anyInt()))
+                .thenAnswer(invocation -> {
+                    int i = (Integer) (invocation.getArguments()[2]);
+                    int j = (Integer) (invocation.getArguments()[3]);
+                    return getProvisionedValue(i, j);
+                });
+        when(mImsProvisioningLoader.getProvisioningStatus(anyInt(), eq(FEATURE_RCS), anyInt(),
+                anyInt()))
+                .thenAnswer(invocation -> {
+                    int i = (Integer) (invocation.getArguments()[2]);
+                    int j = (Integer) (invocation.getArguments()[3]);
+                    return getRcsProvisionedValue(i, j);
+                });
+        when(mImsProvisioningLoader
+                .setProvisioningStatus(anyInt(), eq(FEATURE_MMTEL), anyInt(), anyInt(),
+                        anyBoolean()))
+                .thenAnswer(invocation -> {
+                    int i = (Integer) (invocation.getArguments()[2]);
+                    int j = (Integer) (invocation.getArguments()[3]);
+                    int k = (Boolean) (invocation.getArguments()[4]) ? 1 : 0;
+                    return setProvisionedValue(i, j, k);
+                });
+        when(mImsProvisioningLoader
+                .setProvisioningStatus(anyInt(), eq(FEATURE_RCS), anyInt(), anyInt(),
+                        anyBoolean()))
+                .thenAnswer(invocation -> {
+                    int i = (Integer) (invocation.getArguments()[2]);
+                    int j = (Integer) (invocation.getArguments()[3]);
+                    int k = (Boolean) (invocation.getArguments()[4]) ? 1 : 0;
+                    return setRcsProvisionedValue(i, j, k);
+                });
+
+        when(mIFeatureProvisioningCallback0.asBinder()).thenReturn(mIbinder0);
+        when(mIFeatureProvisioningCallback1.asBinder()).thenReturn(mIbinder1);
+
+        doNothing().when(mIFeatureProvisioningCallback0)
+                .onFeatureProvisioningChanged(anyInt(), anyInt(), anyBoolean());
+        doNothing().when(mIFeatureProvisioningCallback0)
+                .onRcsFeatureProvisioningChanged(anyInt(), anyInt(), anyBoolean());
+        doNothing().when(mIFeatureProvisioningCallback1)
+                .onFeatureProvisioningChanged(anyInt(), anyInt(), anyBoolean());
+        doNothing().when(mIFeatureProvisioningCallback1)
+                .onRcsFeatureProvisioningChanged(anyInt(), anyInt(), anyBoolean());
+
+        mTestImsProvisioningController = new TestImsProvisioningController();
+
+        mHandler = mTestImsProvisioningController.getHandler();
+        try {
+            mLooper = new TestableLooper(mHandler.getLooper());
+        } catch (Exception e) {
+            logd("create looper from handler failed");
+        }
+
+        verify(mRcsFeatureConnector0, atLeastOnce()).connect();
+        verify(mMmTelFeatureConnector0, atLeastOnce()).connect();
+
+        verify(mRcsFeatureConnector1, atLeastOnce()).connect();
+        verify(mMmTelFeatureConnector1, atLeastOnce()).connect();
+    }
+
+    private void initializeDefaultData() throws Exception {
+        mMmTelTechMap.clear();
+        mMmTelTechMap.put(CAPABILITY_TYPE_VOICE,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN,
+                        REGISTRATION_TECH_CROSS_SIM, REGISTRATION_TECH_NR});
+        mMmTelTechMap.put(CAPABILITY_TYPE_VIDEO,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN,
+                        REGISTRATION_TECH_CROSS_SIM, REGISTRATION_TECH_NR});
+        mMmTelTechMap.put(CAPABILITY_TYPE_UT,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN,
+                        REGISTRATION_TECH_CROSS_SIM, REGISTRATION_TECH_NR});
+        mMmTelTechMap.put(CAPABILITY_TYPE_SMS,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN,
+                        REGISTRATION_TECH_CROSS_SIM, REGISTRATION_TECH_NR});
+        mMmTelTechMap.put(CAPABILITY_TYPE_CALL_COMPOSER,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN,
+                        REGISTRATION_TECH_CROSS_SIM, REGISTRATION_TECH_NR});
+        mMmTelProvisioningStorage = new int[][]{
+                {CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_LTE, 1},
+                {CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_IWLAN, 1},
+                {CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_CROSS_SIM, 1},
+                {CAPABILITY_TYPE_VOICE, REGISTRATION_TECH_NR, 1},
+                {CAPABILITY_TYPE_VIDEO, REGISTRATION_TECH_LTE, 1},
+                {CAPABILITY_TYPE_VIDEO, REGISTRATION_TECH_IWLAN, 1},
+                {CAPABILITY_TYPE_VIDEO, REGISTRATION_TECH_CROSS_SIM, 1},
+                {CAPABILITY_TYPE_VIDEO, REGISTRATION_TECH_NR, 1},
+                {CAPABILITY_TYPE_UT, REGISTRATION_TECH_LTE, 1},
+                {CAPABILITY_TYPE_UT, REGISTRATION_TECH_IWLAN, 1},
+                {CAPABILITY_TYPE_UT, REGISTRATION_TECH_CROSS_SIM, 1},
+                {CAPABILITY_TYPE_UT, REGISTRATION_TECH_NR, 1},
+                {CAPABILITY_TYPE_SMS, REGISTRATION_TECH_LTE, 1},
+                {CAPABILITY_TYPE_SMS, REGISTRATION_TECH_IWLAN, 1},
+                {CAPABILITY_TYPE_SMS, REGISTRATION_TECH_CROSS_SIM, 1},
+                {CAPABILITY_TYPE_SMS, REGISTRATION_TECH_NR, 1},
+                {CAPABILITY_TYPE_CALL_COMPOSER, REGISTRATION_TECH_LTE, 1},
+                {CAPABILITY_TYPE_CALL_COMPOSER, REGISTRATION_TECH_IWLAN, 1},
+                {CAPABILITY_TYPE_CALL_COMPOSER, REGISTRATION_TECH_CROSS_SIM, 1},
+                {CAPABILITY_TYPE_CALL_COMPOSER, REGISTRATION_TECH_NR, 1}
+        };
+
+        mRcsTechMap.clear();
+        mRcsTechMap.put(CAPABILITY_TYPE_OPTIONS_UCE,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN,
+                        REGISTRATION_TECH_CROSS_SIM, REGISTRATION_TECH_NR});
+        mRcsTechMap.put(CAPABILITY_TYPE_PRESENCE_UCE,
+                new int[] {REGISTRATION_TECH_LTE, REGISTRATION_TECH_IWLAN,
+                        REGISTRATION_TECH_CROSS_SIM, REGISTRATION_TECH_NR});
+        mRcsProvisioningStorage = new int[][]{
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_LTE, 1},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_IWLAN, 1},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_CROSS_SIM, 1},
+                {CAPABILITY_TYPE_PRESENCE_UCE, REGISTRATION_TECH_NR, 1}
+        };
+
+        mImsConfigStorage = new int[][] {
+                {KEY_VOLTE_PROVISIONING_STATUS, 1},
+                {KEY_VT_PROVISIONING_STATUS, 1},
+                {KEY_VOICE_OVER_WIFI_ENABLED_OVERRIDE, 1},
+                {KEY_EAB_PROVISIONING_STATUS, 1}
+        };
+    }
+
+    private int getProvisionedValue(int i, int j) {
+        for (int[] data : mMmTelProvisioningStorage) {
+            if (data[0] == i && data[1] == j) {
+                return data[2];
+            }
+        }
+        return 0;
+    }
+
+    private int getRcsProvisionedValue(int i, int j) {
+        for (int[] data : mRcsProvisioningStorage) {
+            if (data[0] == i && data[1] == j) {
+                return data[2];
+            }
+        }
+        return 0;
+    }
+
+    private boolean setProvisionedValue(int i, int j, int k) {
+        boolean retVal = false;
+        for (int[] data : mMmTelProvisioningStorage) {
+            if (data[0] == i && data[1] == j) {
+                if (data[2] != k) {
+                    data[2] = k;
+                    return true;
+                }
+                return false;
+            }
+        }
+        return retVal;
+    }
+
+    private boolean setRcsProvisionedValue(int i, int j, int k) {
+        boolean retVal = false;
+        for (int[] data : mRcsProvisioningStorage) {
+            if (data[0] == i && data[1] == j) {
+                if (data[2] != k) {
+                    data[2] = k;
+                    return true;
+                }
+                return false;
+            }
+        }
+        return retVal;
+    }
+
+    private int getImsConfigValue(int i) {
+        for (int[] data : mImsConfigStorage) {
+            if (data[0] == i) {
+                return data[1];
+            }
+        }
+        return -1;
+    }
+
+    private int setImsConfigValue(int i, int j) {
+        for (int[] data : mImsConfigStorage) {
+            if (data[0] == i) {
+                data[1] = j;
+                return ImsConfig.OperationStatusConstants.SUCCESS;
+            }
+        }
+        return ImsConfig.OperationStatusConstants.SUCCESS;
+    }
+
+    private void processAllMessages() {
+        while (!mLooper.getLooper().getQueue().isIdle()) {
+            mLooper.processAllMessages();
+        }
+    }
+
+    private static void logd(String str) {
+        Log.d(TAG, str);
+    }
+}
diff --git a/tests/src/com/android/phone/ImsProvisioningLoaderTest.java b/tests/src/com/android/phone/ImsProvisioningLoaderTest.java
new file mode 100644
index 0000000..61cab1d
--- /dev/null
+++ b/tests/src/com/android/phone/ImsProvisioningLoaderTest.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2021 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 org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.PersistableBundle;
+import android.telephony.ims.feature.MmTelFeature;
+import android.telephony.ims.feature.RcsFeature;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Log;
+
+import androidx.test.InstrumentationRegistry;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+/**
+ * Unit Test for ImsProvisioningLoader.
+ */
+public class ImsProvisioningLoaderTest {
+    private static final String LOG_TAG = ImsProvisioningLoaderTest.class.getSimpleName();
+
+    private static final int IMS_FEATURE_MMTEL = ImsProvisioningLoader.IMS_FEATURE_MMTEL;
+    private static final int IMS_FEATURE_RCS = ImsProvisioningLoader.IMS_FEATURE_RCS;
+
+    private static final int TECH_LTE = ImsRegistrationImplBase.REGISTRATION_TECH_LTE;
+    private static final int TECH_IWLAN = ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN;
+    private static final int TECH_NEW = Integer.MAX_VALUE;
+
+    private static final int CAPA_VOICE = MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE;
+    private static final int CAPA_VIDEO = MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO;
+    private static final int CAPA_UT = MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT;
+    private static final int CAPA_PRESENCE =
+            RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE;
+    private static final int CAPA_NEW = Integer.MAX_VALUE;
+
+    private static final int STATUS_NOT_PROVISIONED = ImsProvisioningLoader.STATUS_NOT_PROVISIONED;
+    private static final int STATUS_PROVISIONED = ImsProvisioningLoader.STATUS_PROVISIONED;
+
+    private static final int SUB_ID_1 = 111111;
+    private static final int SUB_ID_2 = 222222;
+
+    @Mock
+    Context mContext;
+    @Mock
+    SharedPreferences mSharedPreferences;
+    private ImsProvisioningLoader mImsProvisioningLoader;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        doReturn(mSharedPreferences).when(mContext).getSharedPreferences(anyString(), anyInt());
+        doReturn(InstrumentationRegistry.getTargetContext().getFilesDir()).when(
+                mContext).getFilesDir();
+
+        mImsProvisioningLoader = new ImsProvisioningLoader(mContext);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        if (mImsProvisioningLoader != null) {
+            mImsProvisioningLoader.clear();
+        }
+        deleteXml(SUB_ID_1, mContext);
+        deleteXml(SUB_ID_2, mContext);
+    }
+
+    @Test
+    @SmallTest
+    public void testSetProvisioningStatus_ExistFeature() {
+        // Set MMTEL IWLAN VOICE to STATUS_PROVISIONED
+        String[] info =
+                new String[]{IMS_FEATURE_MMTEL + "," + TECH_IWLAN + "," + CAPA_VOICE + "," + getInt(
+                        true)};
+        mImsProvisioningLoader.setProvisioningToXml(SUB_ID_1, new PersistableBundle(), info);
+
+        int curValue = mImsProvisioningLoader.getProvisioningStatus(SUB_ID_1, IMS_FEATURE_MMTEL,
+                CAPA_VOICE, TECH_IWLAN);
+        assertEquals(getXmlContents(SUB_ID_1), getInt(true), curValue);
+
+        // Change MMTEL IWLAN VOICE provisioning status
+        boolean saveResult = mImsProvisioningLoader.setProvisioningStatus(SUB_ID_1,
+                IMS_FEATURE_MMTEL, CAPA_VOICE, TECH_IWLAN, false);
+        curValue = mImsProvisioningLoader.getProvisioningStatus(SUB_ID_1,
+                IMS_FEATURE_MMTEL, CAPA_VOICE, TECH_IWLAN);
+        assertEquals(getXmlContents(SUB_ID_1), true, saveResult);
+        assertEquals(getXmlContents(SUB_ID_1), getInt(false), curValue);
+
+        // If set to the same provisioning status,  don't save it.
+        saveResult = mImsProvisioningLoader.setProvisioningStatus(SUB_ID_1,
+                IMS_FEATURE_MMTEL, CAPA_VOICE, TECH_IWLAN, false);
+        curValue = mImsProvisioningLoader.getProvisioningStatus(SUB_ID_1,
+                IMS_FEATURE_MMTEL, CAPA_VOICE, TECH_IWLAN);
+        assertEquals(getXmlContents(SUB_ID_1), false, saveResult);
+        assertEquals(getXmlContents(SUB_ID_1), getInt(false), curValue);
+    }
+
+    @Test
+    @SmallTest
+    public void testSetProvisioningStatus_NewFeature() {
+        // Set new capability
+        // Return true as a result to setProvisioningStatus()
+        boolean saveResult = mImsProvisioningLoader.setProvisioningStatus(SUB_ID_1,
+                IMS_FEATURE_MMTEL, CAPA_NEW, TECH_LTE, true);
+        int curValue = mImsProvisioningLoader.getProvisioningStatus(SUB_ID_1,
+                IMS_FEATURE_MMTEL, CAPA_NEW, TECH_LTE);
+        assertEquals(getXmlContents(SUB_ID_1), true, saveResult);
+        assertEquals(getXmlContents(SUB_ID_1), getInt(true), curValue);
+
+        // Set new tech
+        saveResult = mImsProvisioningLoader.setProvisioningStatus(SUB_ID_1,
+                IMS_FEATURE_MMTEL, CAPA_VOICE, TECH_NEW, false);
+        curValue = mImsProvisioningLoader.getProvisioningStatus(SUB_ID_1,
+                IMS_FEATURE_MMTEL, CAPA_VOICE, TECH_NEW);
+        assertEquals(getXmlContents(SUB_ID_1), true, saveResult);
+        assertEquals(getXmlContents(SUB_ID_1), getInt(false), curValue);
+    }
+
+    @Test
+    @SmallTest
+    public void testSetProvisioningStatus_DifferentSim() {
+        // Check whether the provisioning status does not change even if SIM is changed
+        // Sub id 2, set provisioning status
+        boolean prevValue = getBooleanFromProvisioningStatus(SUB_ID_2,
+                IMS_FEATURE_RCS, CAPA_PRESENCE, TECH_IWLAN);
+        boolean saveResult = mImsProvisioningLoader.setProvisioningStatus(
+                SUB_ID_2, IMS_FEATURE_RCS, CAPA_PRESENCE, TECH_IWLAN, !prevValue);
+        int curValue = mImsProvisioningLoader.getProvisioningStatus(SUB_ID_2,
+                IMS_FEATURE_RCS, CAPA_PRESENCE, TECH_IWLAN);
+        assertEquals(getXmlContents(SUB_ID_2), true, saveResult);
+        assertEquals(getXmlContents(SUB_ID_2), getInt(!prevValue), curValue);
+
+        // Sub id 1, set other provisioned status
+        mImsProvisioningLoader.setProvisioningStatus(
+                SUB_ID_1, IMS_FEATURE_RCS, CAPA_PRESENCE, TECH_IWLAN, prevValue);
+
+        // Sub id 2, check the previous provisioning status isn't changed
+        curValue = mImsProvisioningLoader.getProvisioningStatus(SUB_ID_2,
+                IMS_FEATURE_RCS, CAPA_PRESENCE, TECH_IWLAN);
+        assertEquals(getXmlContents(SUB_ID_2), getInt(!prevValue), curValue);
+    }
+
+    @Test
+    @SmallTest
+    public void testGetProvisioningStatus_UtProvisioningStatusIsExistInPref() {
+        // Ut provisioning status exists in preference
+        doReturn(1).when(mSharedPreferences).getInt(anyString(), anyInt());
+        int curValue = mImsProvisioningLoader.getProvisioningStatus(SUB_ID_1,
+                IMS_FEATURE_MMTEL, CAPA_UT, TECH_LTE);
+        assertEquals(getXmlContents(SUB_ID_1), getInt(true), curValue);
+    }
+
+    @Test
+    @SmallTest
+    public void testGetProvisioningStatus_ExistXml() {
+        // Set MMTEL LTE VOICE to STATUS_PROVISIONED, MMTEL LTE VIDEO to STATUS_NOT_PROVISIONED
+        String[] info =
+                new String[]{IMS_FEATURE_MMTEL + "," + TECH_LTE + "," + CAPA_VOICE + "," + getInt(
+                        true),
+                        IMS_FEATURE_MMTEL + "," + TECH_LTE + "," + CAPA_VIDEO + "," + getInt(
+                                false)};
+        mImsProvisioningLoader.setProvisioningToXml(SUB_ID_1, new PersistableBundle(), info);
+
+        int curValue = mImsProvisioningLoader.getProvisioningStatus(SUB_ID_1,
+                IMS_FEATURE_MMTEL, CAPA_VOICE, TECH_LTE);
+        assertEquals(getXmlContents(SUB_ID_1), getInt(true), curValue);
+
+        curValue = mImsProvisioningLoader.getProvisioningStatus(SUB_ID_1,
+                IMS_FEATURE_MMTEL, CAPA_VIDEO, TECH_LTE);
+        assertEquals(getXmlContents(SUB_ID_1), getInt(false), curValue);
+    }
+
+    private boolean getBooleanFromProvisioningStatus(int subId, int imsFeature, int capa,
+            int tech) {
+        // Return provisioning status to bool
+        return mImsProvisioningLoader.getProvisioningStatus(
+                subId, imsFeature, capa, tech) == STATUS_PROVISIONED ? true
+                : false;
+    }
+
+    private int getInt(boolean isProvisioned) {
+        return isProvisioned ? STATUS_PROVISIONED : STATUS_NOT_PROVISIONED;
+    }
+
+    private void deleteXml(int subId, Context context) {
+        String fileName = getFileName(subId);
+        File file = null;
+        try {
+            file = new File(context.getFilesDir(), fileName);
+        } catch (Exception e) {
+            logd(e.toString());
+        }
+        file.delete();
+    }
+
+    private String getXmlContents(int subId) {
+        String fileName = getFileName(subId);
+
+        File file = null;
+        FileInputStream inFile = null;
+        StringBuilder readString = new StringBuilder();
+        readString.append("file name " + fileName + "\n");
+        byte[] buffer = new byte[1024];
+        int n = 0;
+        try {
+            file = new File(mContext.getFilesDir(), fileName);
+            inFile = new FileInputStream(file);
+            while ((n = inFile.read(buffer)) != -1) {
+                readString.append(new String(buffer, 0, n));
+            }
+            inFile.close();
+        } catch (FileNotFoundException e) {
+            logd(e.toString());
+
+        } catch (IOException e) {
+            logd(e.toString());
+        }
+        return readString.toString();
+    }
+
+    private String getFileName(int subId) {
+        // Resulting name is imsprovisioningstatus_{subId}.xml
+        return "imsprovisioningstatus_" + subId + ".xml";
+    }
+
+    private static void logd(String contents) {
+        Log.d(LOG_TAG, contents);
+    }
+
+}
diff --git a/tests/src/com/android/phone/ImsStateCallbackControllerTest.java b/tests/src/com/android/phone/ImsStateCallbackControllerTest.java
index c493f6b..e4cdc6e 100644
--- a/tests/src/com/android/phone/ImsStateCallbackControllerTest.java
+++ b/tests/src/com/android/phone/ImsStateCallbackControllerTest.java
@@ -243,7 +243,7 @@
         verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_DISCONNECTED);
         verify(mCallback0, times(0)).onAvailable();
 
-        mMmTelConnectorListenerSlot0.getValue().connectionReady(null);
+        mMmTelConnectorListenerSlot0.getValue().connectionReady(null, SLOT_0_SUB_ID);
         processAllMessages();
         verify(mCallback0, atLeastOnce()).onAvailable();
 
@@ -344,7 +344,7 @@
         processAllMessages();
         verify(mCallback0, times(1)).onUnavailable(REASON_IMS_SERVICE_NOT_READY);
 
-        mRcsConnectorListenerSlot0.getValue().connectionReady(null);
+        mRcsConnectorListenerSlot0.getValue().connectionReady(null, SLOT_0_SUB_ID);
         processAllMessages();
         verify(mCallback0, times(0)).onAvailable();
 
@@ -368,7 +368,7 @@
         processAllMessages();
         verify(mCallback0, times(1)).onAvailable();
 
-        mRcsConnectorListenerSlot0.getValue().connectionReady(null);
+        mRcsConnectorListenerSlot0.getValue().connectionReady(null, SLOT_0_SUB_ID);
         processAllMessages();
         verify(mCallback0, times(2)).onAvailable();
 
@@ -398,7 +398,7 @@
         processAllMessages();
         verify(mCallback0, times(0)).onUnavailable(REASON_IMS_SERVICE_NOT_READY);
 
-        mRcsConnectorListenerSlot0.getValue().connectionReady(null);
+        mRcsConnectorListenerSlot0.getValue().connectionReady(null, SLOT_0_SUB_ID);
         processAllMessages();
         verify(mCallback0, times(0)).onAvailable();
 
@@ -693,7 +693,7 @@
         verify(mCallback3, times(2)).onUnavailable(anyInt());
 
         // connectionReady
-        mMmTelConnectorListenerSlot0.getValue().connectionReady(null);
+        mMmTelConnectorListenerSlot0.getValue().connectionReady(null, SLOT_0_SUB_ID);
         processAllMessages();
         verify(mCallback0, times(1)).onAvailable();
         verify(mCallback1, times(0)).onAvailable();
@@ -704,7 +704,7 @@
         verify(mCallback2, times(2)).onUnavailable(anyInt());
         verify(mCallback3, times(2)).onUnavailable(anyInt());
 
-        mRcsConnectorListenerSlot0.getValue().connectionReady(null);
+        mRcsConnectorListenerSlot0.getValue().connectionReady(null, SLOT_0_SUB_ID);
         processAllMessages();
         verify(mCallback0, times(1)).onAvailable();
         verify(mCallback1, times(0)).onAvailable();
@@ -726,7 +726,7 @@
         verify(mCallback2, times(2)).onUnavailable(anyInt());
         verify(mCallback3, times(2)).onUnavailable(anyInt());
 
-        mMmTelConnectorListenerSlot1.getValue().connectionReady(null);
+        mMmTelConnectorListenerSlot1.getValue().connectionReady(null, SLOT_0_SUB_ID);
         processAllMessages();
         verify(mCallback0, times(1)).onAvailable();
         verify(mCallback1, times(1)).onAvailable();
@@ -737,7 +737,7 @@
         verify(mCallback2, times(2)).onUnavailable(anyInt());
         verify(mCallback3, times(2)).onUnavailable(anyInt());
 
-        mRcsConnectorListenerSlot1.getValue().connectionReady(null);
+        mRcsConnectorListenerSlot1.getValue().connectionReady(null, SLOT_0_SUB_ID);
         processAllMessages();
         verify(mCallback0, times(1)).onAvailable();
         verify(mCallback1, times(1)).onAvailable();
diff --git a/tests/src/com/android/phone/RcsProvisioningMonitorTest.java b/tests/src/com/android/phone/RcsProvisioningMonitorTest.java
index 8e5e073..57f9f6b 100644
--- a/tests/src/com/android/phone/RcsProvisioningMonitorTest.java
+++ b/tests/src/com/android/phone/RcsProvisioningMonitorTest.java
@@ -16,6 +16,10 @@
 
 package com.android.phone;
 
+import static com.android.internal.telephony.TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML;
+import static com.android.internal.telephony.TelephonyStatsLog.RCS_CLIENT_PROVISIONING_STATS__EVENT__DMA_CHANGED;
+import static com.android.internal.telephony.TelephonyStatsLog.RCS_CLIENT_PROVISIONING_STATS__EVENT__TRIGGER_RCS_RECONFIGURATION;
+
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertNull;
@@ -64,6 +68,7 @@
 import com.android.ims.FeatureConnector;
 import com.android.ims.RcsFeatureManager;
 import com.android.internal.telephony.ITelephony;
+import com.android.internal.telephony.metrics.RcsStats;
 
 import org.junit.After;
 import org.junit.Before;
@@ -147,6 +152,7 @@
     private MockContentResolver mContentResolver = new MockContentResolver();
     private SimInfoContentProvider mProvider;
     private BroadcastReceiver mReceiver;
+    private static final int TEST_SUB_ID = 1;
     @Mock
     private Cursor mCursor;
     @Mock
@@ -179,6 +185,10 @@
     private IRcsConfigCallback mCallback;
     @Mock
     private PackageManager mPackageManager;
+    @Mock
+    private RcsStats mRcsStats;
+    @Mock
+    private RcsStats.RcsProvisioningCallback mRcsProvisioningCallback;
 
     private Executor mExecutor = new Executor() {
         @Override
@@ -768,6 +778,66 @@
         assertNull(mRcsProvisioningMonitor.getImsFeatureValidationOverride(FAKE_SUB_ID_BASE));
     }
 
+    @Test
+    @SmallTest
+    public void testMetricsAcsNotUsed() throws Exception {
+        createMonitor(1);
+
+        // Not used ACS
+        mBundle.putBoolean(CarrierConfigManager.KEY_USE_ACS_FOR_RCS_BOOL, false);
+        broadcastCarrierConfigChange(FAKE_SUB_ID_BASE);
+        processAllMessages();
+        mRcsProvisioningMonitor.updateConfig(FAKE_SUB_ID_BASE, CONFIG_DEFAULT.getBytes(), false);
+        processAllMessages();
+        verify(mRcsStats, never()).onRcsAcsProvisioningStats(anyInt(), anyInt(),
+                anyInt(), anyBoolean());
+    }
+
+    @Test
+    @SmallTest
+    public void testMetricsAcsUsed() throws Exception {
+        when(mRcsStats.getRcsProvisioningCallback(anyInt(), anyBoolean()))
+                .thenReturn(mRcsProvisioningCallback);
+        createMonitor(1);
+
+        verify(mIImsConfig, times(1))
+                .notifyRcsAutoConfigurationReceived(any(), anyBoolean());
+        // verify RcsStats.getRcsProvisioningCallback() is called
+        verify(mRcsStats, times(1)).getRcsProvisioningCallback(
+                eq(FAKE_SUB_ID_BASE), anyBoolean());
+        // verify registered callback obj which comes from RcsStats.getRcsProvisioningCallback()
+        verify(mIImsConfig, times(1))
+                .addRcsConfigCallback(eq(mRcsProvisioningCallback));
+
+        // Config data received and ACS used
+        int errorCode = 200;
+        mBundle.putBoolean(CarrierConfigManager.KEY_USE_ACS_FOR_RCS_BOOL, true);
+        broadcastCarrierConfigChange(FAKE_SUB_ID_BASE);
+        processAllMessages();
+        mRcsProvisioningMonitor.updateConfig(FAKE_SUB_ID_BASE, CONFIG_DEFAULT.getBytes(), false);
+        processAllMessages();
+        verify(mRcsStats, times(1)).onRcsAcsProvisioningStats(eq(FAKE_SUB_ID_BASE), eq(errorCode),
+                eq(RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML), anyBoolean());
+    }
+
+    @Test
+    @SmallTest
+    public void testMetricsClientProvisioningStats() throws Exception {
+        createMonitor(1);
+
+        // reconfig trigger
+        mRcsProvisioningMonitor.requestReconfig(FAKE_SUB_ID_BASE);
+        processAllMessages();
+        verify(mRcsStats, times(1)).onRcsClientProvisioningStats(eq(FAKE_SUB_ID_BASE),
+                eq(RCS_CLIENT_PROVISIONING_STATS__EVENT__TRIGGER_RCS_RECONFIGURATION));
+
+        // DMA changed
+        updateDefaultMessageApplication(DEFAULT_MESSAGING_APP2);
+        processAllMessages();
+        verify(mRcsStats, times(1)).onRcsClientProvisioningStats(eq(FAKE_SUB_ID_BASE),
+                eq(RCS_CLIENT_PROVISIONING_STATS__EVENT__DMA_CHANGED));
+    }
+
     private void createMonitor(int subCount) throws Exception {
         if (Looper.myLooper() == null) {
             Looper.prepare();
@@ -777,14 +847,14 @@
                 .thenReturn(mFeatureConnector);
         when(mFeatureManager.getConfig()).thenReturn(mIImsConfig);
         mRcsProvisioningMonitor = new RcsProvisioningMonitor(mPhone, mHandlerThread.getLooper(),
-                mRoleManager, mFeatureFactory);
+                mRoleManager, mFeatureFactory, mRcsStats);
         mHandler = mRcsProvisioningMonitor.getHandler();
         try {
             mLooper = new TestableLooper(mHandler.getLooper());
         } catch (Exception e) {
             logd("Unable to create looper from handler.");
         }
-        mConnectorListener.getValue().connectionReady(mFeatureManager);
+        mConnectorListener.getValue().connectionReady(mFeatureManager, TEST_SUB_ID);
 
         verify(mFeatureConnector, atLeastOnce()).connect();
     }
diff --git a/tests/src/com/android/phone/ServiceStateProviderTest.java b/tests/src/com/android/phone/ServiceStateProviderTest.java
index 532b1c0..4bbde79 100644
--- a/tests/src/com/android/phone/ServiceStateProviderTest.java
+++ b/tests/src/com/android/phone/ServiceStateProviderTest.java
@@ -28,6 +28,7 @@
 import static android.telephony.NetworkRegistrationInfo.REGISTRATION_STATE_HOME;
 
 import static com.android.phone.ServiceStateProvider.ENFORCE_LOCATION_PERMISSION_CHECK;
+import static com.android.phone.ServiceStateProvider.NETWORK_ID;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -40,6 +41,8 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.Manifest;
@@ -332,11 +335,8 @@
         setCanReadPrivilegedPhoneState(true);
         setLocationPermissions(false);
 
-        // NETWORK_ID is a location-sensitive column
-        String[] projection = new String[]{"network_id"};
-
         assertThrows(SecurityException.class,
-                () -> verifyServiceStateWithLocationColumns(mTestServiceState, projection));
+                () -> verifyServiceStateWithLocationColumns(mTestServiceState));
     }
 
     /**
@@ -345,7 +345,7 @@
      */
     @Test
     @CoreCompatChangeRule.EnableCompatChanges({ENFORCE_LOCATION_PERMISSION_CHECK})
-    public void query_allColumn_enforceLoationEnabled_targetR_withLocation_getUnredacted() {
+    public void query_allColumn_enforceLocationEnabled_targetR_withLocation_getUnredacted() {
         setTargetSdkVersion(Build.VERSION_CODES.R);
         setLocationPermissions(true);
 
@@ -402,9 +402,24 @@
                 mTestServiceState, true /*hasPermission*/);
     }
 
-    private void verifyServiceStateWithLocationColumns(ServiceState ss, String[] projection) {
-        try (Cursor cursor = mContentResolver.query(ServiceStateTable.CONTENT_URI, projection, null,
-                null)) {
+    /**
+     * Verify that when caller with targetSDK S+ has location permission and try to query
+     * location non-sensitive info, it should not get blamed.
+     */
+    @Test
+    @CoreCompatChangeRule.EnableCompatChanges({ENFORCE_LOCATION_PERMISSION_CHECK})
+    public void testQuery_noLocationBlamed_whenQueryNonLocationInfo_withPermission() {
+        setTargetSdkVersion(Build.VERSION_CODES.S);
+        setLocationPermissions(true);
+
+        verifyServiceStateWithPublicColumns(mTestServiceState, null /*projection*/);
+        verify(mAppOpsManager, never()).noteOpNoThrow(any(), anyInt(), any(), any(), any());
+    }
+
+    private void verifyServiceStateWithLocationColumns(ServiceState ss) {
+        // NETWORK_ID is a location-sensitive column
+        try (Cursor cursor = mContentResolver.query(ServiceStateTable.CONTENT_URI,
+                new String[]{NETWORK_ID}, null, null)) {
             assertNotNull(cursor);
         }
     }
diff --git a/tests/src/com/android/services/telephony/ImsConferenceTest.java b/tests/src/com/android/services/telephony/ImsConferenceTest.java
index 3bc5ee8..9d2f5ac 100644
--- a/tests/src/com/android/services/telephony/ImsConferenceTest.java
+++ b/tests/src/com/android/services/telephony/ImsConferenceTest.java
@@ -622,6 +622,46 @@
     }
 
     /**
+     * Tests a scenario where a handover connection arrives via
+     * {@link TelephonyConnection#onOriginalConnectionRedialed(
+     * com.android.internal.telephony.Connection)}.  During this process, the conference properties
+     * get updated.  Since the original connection is null at this point, we need to verify that
+     * the remotely hosted property is retained from before the original connection was nulled.
+     */
+    @Test
+    public void testIsConferenceRemotelyHostedCachingOnSRVCC() {
+        mConferenceHost.setIsImsConnection(true);
+        when(mConferenceHost.getMockImsPhoneConnection().isMultiparty()).thenReturn(true);
+        when(mConferenceHost.getMockImsPhoneConnection().isConferenceHost()).thenReturn(true);
+
+        // Start out with a valid conference host.
+        ImsConference imsConference = new ImsConference(mMockTelecomAccountRegistry,
+                mMockTelephonyConnectionServiceProxy, mConferenceHost,
+                null /* phoneAccountHandle */, () -> false /* featureFlagProxy */,
+                new ImsConference.CarrierConfiguration.Builder().build());
+
+        // By default it is not remotely hosted.
+        assertFalse(imsConference.isRemotelyHosted());
+        assertEquals(0,
+                imsConference.getConnectionProperties() & Connection.PROPERTY_REMOTELY_HOSTED);
+
+        // Simulate a change to the original connection due to srvcc
+        com.android.internal.telephony.Connection previousOriginalConnection =
+                mConferenceHost.getMockImsPhoneConnection();
+        mConferenceHost.setMockImsPhoneConnection(null);
+
+        // Trigger the property update which takes place when the original connection changes.
+        mConferenceHost.getTelephonyConnectionListeners().forEach(
+                l -> l.onConnectionPropertiesChanged(mConferenceHost,
+                        mConferenceHost.getConnectionProperties()));
+
+        // Should still NOT be remotely hosted based on cached value.
+        assertFalse(imsConference.isRemotelyHosted());
+        assertEquals(0,
+                imsConference.getConnectionProperties() & Connection.PROPERTY_REMOTELY_HOSTED);
+    }
+
+    /**
      * Verifies that an ImsConference can handle SIP and TEL URIs for both the P-Associated-Uri and
      * conference event package identities.
      */
diff --git a/tests/src/com/android/services/telephony/TelephonyConferenceControllerTest.java b/tests/src/com/android/services/telephony/TelephonyConferenceControllerTest.java
index cfdc2fd..b7fe988 100644
--- a/tests/src/com/android/services/telephony/TelephonyConferenceControllerTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConferenceControllerTest.java
@@ -23,9 +23,11 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.net.Uri;
 import android.os.Looper;
 import android.telecom.Conference;
 import android.telecom.Connection;
+import android.telecom.PhoneAccount;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import org.junit.Before;
@@ -35,7 +37,9 @@
 import org.mockito.MockitoAnnotations;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.List;
 
 /**
  * Tests the functionality in TelephonyConferenceController.java
@@ -111,6 +115,46 @@
     }
 
     /**
+     * Verify the connection with "Conference Call" with PROPERTY_IS_DOWNGRADED_CONFERENCE
+     * during SRVCC
+     */
+    @Test
+    @SmallTest
+    public void testSrvccConferenceConnection() {
+        when(mTestTelephonyConnectionA.mMockRadioConnection.getCall()
+                .isMultiparty()).thenReturn(true);
+        when(mTestTelephonyConnectionB.mMockRadioConnection.getCall()
+                .isMultiparty()).thenReturn(true);
+
+        List<Connection> listConnections = Arrays.asList(
+                mTestTelephonyConnectionA, mTestTelephonyConnectionB);
+        when(mMockTelephonyConnectionServiceProxy.getAllConnections()).thenReturn(listConnections);
+
+        mTestTelephonyConnectionA.setAddress(
+                Uri.fromParts(PhoneAccount.SCHEME_TEL, "Conference Call", null), 0);
+        mTestTelephonyConnectionA.setTelephonyConnectionProperties(
+                Connection.PROPERTY_IS_DOWNGRADED_CONFERENCE);
+        mTestTelephonyConnectionB.setAddress(
+                Uri.fromParts(PhoneAccount.SCHEME_TEL, "5551213", null), 0);
+        mTestTelephonyConnectionB.setTelephonyConnectionProperties(
+                Connection.PROPERTY_IS_DOWNGRADED_CONFERENCE);
+
+        // add telephony connection B
+        mControllerTest.add(mTestTelephonyConnectionB);
+
+        // add telephony connection A
+        mControllerTest.add(mTestTelephonyConnectionA);
+
+        // verify the connection with "Conference Call" has PROPERTY_IS_DOWNGRADED_CONFERENCE
+        assertTrue((mTestTelephonyConnectionA.getConnectionProperties()
+                & Connection.PROPERTY_IS_DOWNGRADED_CONFERENCE) != 0);
+
+        // verify the connection with "5551213" hasn't PROPERTY_IS_DOWNGRADED_CONFERENCE
+        assertFalse((mTestTelephonyConnectionB.getConnectionProperties()
+                & Connection.PROPERTY_IS_DOWNGRADED_CONFERENCE) != 0);
+    }
+
+    /**
      * Behavior: add telephony connection B and A to conference controller,
      *           set status for connections and merged calls, remove one call
      * Assumption: after performing the behaviours, the status of Connection A is STATE_ACTIVE;
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
index 4ce94ca..efa906e 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
@@ -61,8 +61,8 @@
 import com.android.internal.telephony.CallStateException;
 import com.android.internal.telephony.Connection;
 import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneSwitcher;
 import com.android.internal.telephony.ServiceStateTracker;
+import com.android.internal.telephony.data.PhoneSwitcher;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
 import com.android.internal.telephony.gsm.SuppServiceNotification;
 
diff --git a/tests/src/com/android/services/telephony/TestTelephonyConnection.java b/tests/src/com/android/services/telephony/TestTelephonyConnection.java
index 817e9a7..e149d3b 100644
--- a/tests/src/com/android/services/telephony/TestTelephonyConnection.java
+++ b/tests/src/com/android/services/telephony/TestTelephonyConnection.java
@@ -305,4 +305,12 @@
     public PersistableBundle getCarrierConfigBundle() {
         return mCarrierConfig;
     }
+
+    public ImsPhoneConnection getMockImsPhoneConnection() {
+        return mImsPhoneConnection;
+    }
+
+    public void setMockImsPhoneConnection(ImsPhoneConnection connection) {
+        mImsPhoneConnection = connection;
+    }
 }
diff --git a/tests/src/com/android/services/telephony/rcs/RcsFeatureControllerTest.java b/tests/src/com/android/services/telephony/rcs/RcsFeatureControllerTest.java
index da614fc..2a30e1a 100644
--- a/tests/src/com/android/services/telephony/rcs/RcsFeatureControllerTest.java
+++ b/tests/src/com/android/services/telephony/rcs/RcsFeatureControllerTest.java
@@ -96,7 +96,7 @@
         controller.addFeature(mMockFeature, RcsFeatureController.Feature.class);
         verify(mMockFeature).onRcsDisconnected();
         // Connect the RcsFeatureManager
-        mConnectorListener.getValue().connectionReady(mFeatureManager);
+        mConnectorListener.getValue().connectionReady(mFeatureManager, TEST_SUB_ID);
 
         verify(mFeatureManager).updateCapabilities(TEST_SUB_ID);
         verify(mFeatureManager).registerImsRegistrationCallback(any());
@@ -114,7 +114,7 @@
     public void testFeatureManagerConnectedAddRemoveFeature() throws Exception {
         RcsFeatureController controller = createFeatureController();
         // Connect the RcsFeatureManager
-        mConnectorListener.getValue().connectionReady(mFeatureManager);
+        mConnectorListener.getValue().connectionReady(mFeatureManager, TEST_SUB_ID);
         controller.addFeature(mMockFeature, RcsFeatureController.Feature.class);
 
         verify(mMockFeature).onRcsConnected(mFeatureManager);
@@ -131,7 +131,7 @@
         IImsRegistrationCallback regCb = mock(IImsRegistrationCallback.class);
         IImsCapabilityCallback capCb = mock(IImsCapabilityCallback.class);
         // Connect the RcsFeatureManager
-        mConnectorListener.getValue().connectionReady(mFeatureManager);
+        mConnectorListener.getValue().connectionReady(mFeatureManager, TEST_SUB_ID);
 
         try {
             controller.registerImsRegistrationCallback(TEST_SUB_ID, regCb);
@@ -165,7 +165,7 @@
     public void testFeatureManagerConnectedHelper() throws Exception {
         RcsFeatureController controller = createFeatureController();
         // Connect the RcsFeatureManager
-        mConnectorListener.getValue().connectionReady(mFeatureManager);
+        mConnectorListener.getValue().connectionReady(mFeatureManager, TEST_SUB_ID);
         ArgumentCaptor<IImsRegistrationCallback> captor =
                 ArgumentCaptor.forClass(IImsRegistrationCallback.class);
         verify(mFeatureManager).registerImsRegistrationCallback(captor.capture());
@@ -257,7 +257,7 @@
     public void testCarrierConfigChanged() throws Exception {
         RcsFeatureController controller = createFeatureController();
         // Connect the RcsFeatureManager
-        mConnectorListener.getValue().connectionReady(mFeatureManager);
+        mConnectorListener.getValue().connectionReady(mFeatureManager, TEST_SUB_ID);
         verify(mFeatureManager).updateCapabilities(TEST_SUB_ID);
         controller.addFeature(mMockFeature, RcsFeatureController.Feature.class);
 
@@ -272,7 +272,7 @@
     public void testChangeSubId() throws Exception {
         RcsFeatureController controller = createFeatureController();
         // Connect the RcsFeatureManager
-        mConnectorListener.getValue().connectionReady(mFeatureManager);
+        mConnectorListener.getValue().connectionReady(mFeatureManager, TEST_SUB_ID);
         verify(mFeatureManager).updateCapabilities(TEST_SUB_ID);
         controller.addFeature(mMockFeature, RcsFeatureController.Feature.class);
 
@@ -286,7 +286,7 @@
     public void testDestroy() throws Exception {
         RcsFeatureController controller = createFeatureController();
         // Connect the RcsFeatureManager
-        mConnectorListener.getValue().connectionReady(mFeatureManager);
+        mConnectorListener.getValue().connectionReady(mFeatureManager, TEST_SUB_ID);
         controller.addFeature(mMockFeature, RcsFeatureController.Feature.class);
         controller.destroy();
 
