Merge "Disconnect ongoing conference call for emergency"
diff --git a/Android.bp b/Android.bp
index 76e910f..a06d5ef 100644
--- a/Android.bp
+++ b/Android.bp
@@ -22,7 +22,6 @@
         "telephony-common",
         "voip-common",
         "ims-common",
-        "org.apache.http.legacy",
         "libprotobuf-java-lite",
         "unsupportedappusage",
     ],
@@ -32,10 +31,10 @@
         "androidx.preference_preference",
         "androidx.recyclerview_recyclerview",
         "androidx.legacy_legacy-preference-v14",
-        "guava",
-        "volley",
         "android-support-annotations",
         "com.android.phone.common-lib",
+        "guava",
+        "PlatformProperties",
     ],
 
     srcs: [
@@ -79,4 +78,4 @@
     proto: {
         type: "lite",
     },
-}
\ No newline at end of file
+}
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 1d32288..3f24251 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -32,10 +32,8 @@
     <protected-broadcast android:name="android.intent.action.EMERGENCY_CALL_STATE_CHANGED" />
     <protected-broadcast android:name="android.intent.action.SIG_STR" />
     <protected-broadcast android:name="android.intent.action.ANY_DATA_STATE" />
-    <protected-broadcast android:name="android.intent.action.DATA_CONNECTION_FAILED" />
     <protected-broadcast android:name="android.intent.action.DATA_STALL_DETECTED" />
     <protected-broadcast android:name="android.intent.action.SIM_STATE_CHANGED" />
-    <protected-broadcast android:name="android.intent.action.NETWORK_SET_TIME" />
     <protected-broadcast android:name="com.android.internal.intent.action.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS" />
     <protected-broadcast android:name="android.intent.action.ACTION_MDN_STATE_CHANGED" />
     <protected-broadcast android:name="android.provider.Telephony.SPN_STRINGS_UPDATED" />
@@ -130,8 +128,8 @@
     <uses-permission android:name="android.permission.WRITE_SMS" />
     <uses-permission android:name="android.permission.SEND_SMS" />
     <uses-permission android:name="android.permission.SEND_RESPOND_VIA_MESSAGE" />
-    <uses-permission android:name="android.permission.SET_TIME" />
     <uses-permission android:name="android.permission.SET_TIME_ZONE" />
+    <uses-permission android:name="android.permission.SUGGEST_PHONE_TIME_AND_ZONE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
     <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
@@ -243,6 +241,15 @@
                 <category android:name="android.intent.category.DEFAULT" />
                 <data android:scheme="tel" />
             </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.DIAL_EMERGENCY" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.DIAL_EMERGENCY" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:scheme="tel" />
+            </intent-filter>
         </activity>
 
         <activity android:name="ADNList" />
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 22845e0..3aa8121 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -50,3 +50,6 @@
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/com.android.services.telephony.common_intermediates)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/telephony-common.jar)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/ims-common.jar)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/apex/com.android.telephony/javalib/telephony-common.jar)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/apex/com.android.telephony/javalib/ims-common.jar)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/apex/com.android.telephony.apex)
\ No newline at end of file
diff --git a/OWNERS b/OWNERS
index 5be6fe5..849347f 100644
--- a/OWNERS
+++ b/OWNERS
@@ -11,4 +11,5 @@
 shuoq@google.com
 paulye@google.com
 nazaninb@google.com
-sarahchin@google.com
\ No newline at end of file
+sarahchin@google.com
+dbright@google.com
diff --git a/apex/Android.bp b/apex/Android.bp
index f9e4b67..16bcb72 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -4,7 +4,7 @@
     // optional. if unspecified, a default one is auto-generated
     androidManifest: "AndroidManifest.xml",
 
-    java_libs: ["telephony-common", "ims-common"],
+    //java_libs: ["telephony-common", "ims-common", "voip-common"],
     //apps: ["TeleService", "StkLib", "ONSLib"],
 
     key: "com.android.telephony.key",
@@ -30,4 +30,4 @@
     // This will use com.android.telephony.x509.pem (the cert) and
     // com.android.telephony.pk8 (the private key)
     certificate: "com.android.telephony",
-}
+}
\ No newline at end of file
diff --git a/res/drawable/preference_background.xml b/res/drawable/preference_background.xml
index 19ca432..1ec90fb 100644
--- a/res/drawable/preference_background.xml
+++ b/res/drawable/preference_background.xml
@@ -21,7 +21,7 @@
         android:insetBottom="0dip">
 
     <shape android:shape="rectangle">
-        <solid android:color="@*android:color/background_material_light" />
+        <solid android:color="@color/background_material_light" />
     </shape>
 
 </inset>
diff --git a/res/drawable/progress_indeterminate_horizontal_material_trimmed.xml b/res/drawable/progress_indeterminate_horizontal_material_trimmed.xml
deleted file mode 100644
index 905dc55..0000000
--- a/res/drawable/progress_indeterminate_horizontal_material_trimmed.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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.
--->
-
-<!-- Variant of progress_indeterminate_horizontal_material in frameworks/base/core/res, which
-     draws the whole height of the progress bar instead having blank space above and below the
-     bar. -->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/vector_drawable_progress_indeterminate_horizontal_trimmed" >
-    <target
-        android:name="rect2_grp"
-        android:animation="@*android:anim/progress_indeterminate_horizontal_rect2" />
-    <target
-        android:name="rect1_grp"
-        android:animation="@*android:anim/progress_indeterminate_horizontal_rect1" />
-</animated-vector>
\ No newline at end of file
diff --git a/res/layout/choose_network_progress_header.xml b/res/layout/choose_network_progress_header.xml
deleted file mode 100644
index 671c297..0000000
--- a/res/layout/choose_network_progress_header.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2018 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.
--->
-
-<FrameLayout
-    android:layout_width="match_parent"
-    android:layout_height="3dp"
-    xmlns:android="http://schemas.android.com/apk/res/android">
-    <View
-        android:id="@+id/progress_bar_background"
-        style="@style/TrimmedHorizontalProgressBar"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:background="?android:attr/colorSecondary" />
-    <ProgressBar
-        android:id="@+id/progress_bar_animation"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        style="@style/TrimmedHorizontalProgressBar"
-        android:indeterminate="true" />
-</FrameLayout>
\ No newline at end of file
diff --git a/res/layout/pref_dialog_editpin.xml b/res/layout/pref_dialog_editpin.xml
deleted file mode 100644
index 94cdadf..0000000
--- a/res/layout/pref_dialog_editpin.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 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.
-     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.
--->
-
-<!-- Layout used as the dialog's content View for EditTextPreference. -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@*android:id/edittext_container"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:orientation="vertical"
-    android:padding="?android:attr/dialogPreferredPadding">
-
-    <TextView android:id="@android:id/message"
-        style="?android:attr/textAppearanceSmall"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:textColor="?android:attr/textColorSecondary" />
-
-</LinearLayout>
diff --git a/res/values-night/styles.xml b/res/values-night/styles.xml
index fa5c8a1..f7d831b 100644
--- a/res/values-night/styles.xml
+++ b/res/values-night/styles.xml
@@ -27,31 +27,31 @@
         <item name="android:dialogTheme">@style/DialerAlertDialogTheme</item>
     </style>
 
-    <style name="EmergencyInfoNameTextAppearance">
-        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+    <style name="EmergencyInfoNameTextAppearance"
+           parent="@android:style/TextAppearance.Material.Subhead">
         <item name="android:textColor">@android:color/white</item>
         <item name="android:textSize">@dimen/emergency_info_name_text_size</item>
     </style>
 
-    <style name="EmergencyInfoHintTextAppearance">
-        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+    <style name="EmergencyInfoHintTextAppearance"
+           parent="@android:style/TextAppearance.Material.Subhead">
         <item name="android:textColor">@color/white_70_percent</item>
         <item name="android:textSize">@dimen/emergency_info_hint_text_size</item>
     </style>
 
-    <style name="EmergencyInfoTapHintTextAppearance">
-        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+    <style name="EmergencyInfoTapHintTextAppearance"
+           parent="@android:style/TextAppearance.Material.Subhead">
         <item name="android:textColor">@android:color/white</item>
         <item name="android:textSize">@dimen/emergency_info_tap_hint_text_size</item>
     </style>
 
-    <style name="ShortcutViewHintTextAppearance">
-        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+    <style name="ShortcutViewHintTextAppearance"
+           parent="@android:style/TextAppearance.Material.Subhead">
         <item name="android:textColor">@android:color/white</item>
     </style>
 
-    <style name="PhoneNumberTextAppearance">
-        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+    <style name="PhoneNumberTextAppearance"
+           parent="@android:style/TextAppearance.Material.Subhead">
         <item name="android:textColor">@android:color/white</item>
         <item name="android:textSize">@dimen/emergency_shortcut_number_text_size</item>
     </style>
@@ -62,8 +62,8 @@
         <item name="android:textSize">@dimen/emergency_shortcut_type_text_size</item>
     </style>
 
-    <style name="PhoneNumberTapHintAppearance">
-        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+    <style name="PhoneNumberTapHintAppearance"
+           parent="@android:style/TextAppearance.Material.Subhead">
         <item name="android:textColor">@android:color/white</item>
         <item name="android:textSize">@dimen/emergency_shortcut_tap_hint_text_size</item>
     </style>
diff --git a/res/values/config.xml b/res/values/config.xml
index 8bc1919..8c36b1a 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -235,6 +235,12 @@
     <!-- Flag indicating whether the device supports RTT (real-time text) -->
     <bool name="config_support_rtt">false</bool>
 
+    <!-- String indicating the package name of the device ImsService implementation for MMTEL. -->
+    <string name="config_ims_mmtel_package"></string>
+
+    <!-- String indicating the package name of the device ImsService implementation for RCS. -->
+    <string name="config_ims_rcs_package"></string>
+
     <!-- The package name for the platform number verification supplier app. -->
     <string name="platform_number_verification_package" translatable="false"></string>
 
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b97ef10..6ac95c3 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -438,6 +438,17 @@
         <item>LTE/TDSCDMA/GSM/WCDMA</item>
         <item>TDSCDMA/CDMA/EVDO/GSM/WCDMA </item>
         <item>LTE/TDSCDMA/CDMA/EVDO/GSM/WCDMA</item>
+        <item>NR only</item>
+        <item>NR/LTE</item>
+        <item>NR/LTE/CDMA/EvDo</item>
+        <item>NR/LTE/GSM/WCDMA</item>
+        <item>NR/LTE/CDMA/EvDo/GSM/WCDMA</item>
+        <item>NR/LTE/WCDMA</item>
+        <item>NR/LTE/TDSCDMA</item>
+        <item>NR/LTE/TDSCDMA/GSM</item>
+        <item>NR/LTE/TDSCDMA/WCDMA</item>
+        <item>NR/LTE/TDSCDMA/GSM/WCDMA</item>
+        <item>NR/LTE/TDSCDMA/CDMA/EvDo/GSM/WCDMA</item>
     </string-array>
     <!-- The preferred network modes RIL constants, in order of the modes above,
          e.g. the choice "GSM/WCDMA preferred" has the corresponding value "0" -->
@@ -465,6 +476,17 @@
         <item>"20"</item>
         <item>"21"</item>
         <item>"22"</item>
+        <item>"23"</item>
+        <item>"24"</item>
+        <item>"25"</item>
+        <item>"26"</item>
+        <item>"27"</item>
+        <item>"28"</item>
+        <item>"29"</item>
+        <item>"30"</item>
+        <item>"31"</item>
+        <item>"32"</item>
+        <item>"33"</item>
     </string-array>
 
     <!-- The following strings are summaries for preferred network modes in Mobile network settings,
@@ -493,6 +515,8 @@
     <string name="preferred_network_mode_lte_gsm_wcdma_summary">Preferred network mode: GSM/WCDMA/LTE</string>
     <!-- CDMA+LTE/EVDO -->
     <string name="preferred_network_mode_lte_cdma_evdo_summary">Preferred network mode: CDMA+LTE/EVDO</string>
+    <!-- LTE/CDMA/EvDo/GSM/WCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_lte_cdma_evdo_gsm_wcdma_summary">Preferred network mode: LTE/CDMA/EvDo/GSM/WCDMA</string>
     <!-- Global -->
     <string name="preferred_network_mode_global_summary">Preferred network mode: Global</string>
     <!-- LTE / WCDMA -->
@@ -521,6 +545,28 @@
     <string name="preferred_network_mode_tdscdma_cdma_evdo_gsm_wcdma_summary">Preferred network mode: TDSCDMA/CDMA/EvDo/GSM/WCDMA</string>
     <!-- LTE/TDSCDMA/CDMA/EvDo/GSM/WCDMA -->
     <string name="preferred_network_mode_lte_tdscdma_cdma_evdo_gsm_wcdma_summary">Preferred network mode: LTE/TDSCDMA/CDMA/EvDo/GSM/WCDMA</string>
+    <!-- NR only [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_nr_only_summary">Preferred network mode: NR only</string>
+    <!-- NR / LTE [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_nr_lte_summary">Preferred network mode: NR / LTE</string>
+    <!-- NR/LTE/CDMA/EvDo [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_nr_lte_cdma_evdo_summary">Preferred network mode: NR/LTE/CDMA/EvDo</string>
+    <!-- NR/LTE/GSM/WCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_nr_lte_gsm_wcdma_summary">Preferred network mode: NR/LTE/GSM/WCDMA</string>
+    <!-- NR/LTE/TDSCDMA/CDMA/EvDo/GSM/WCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_nr_lte_cdma_evdo_gsm_wcdma_summary">Preferred network mode: NR/LTE/CDMA/EvDo/GSM/WCDMA</string>
+    <!-- NR/LTE/WCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_nr_lte_wcdma_summary">Preferred network mode: NR/LTE/WCDMA</string>
+    <!-- NR/LTE/TDSCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_nr_lte_tdscdma_summary">Preferred network mode: NR/LTE/TDSCDMA</string>
+    <!-- NR/LTE/TDSCDMA/GSM [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_nr_lte_tdscdma_gsm_summary">Preferred network mode: NR/LTE/TDSCDMA/GSM</string>
+    <!-- NR/LTE/TDSCDMA/WCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_nr_lte_tdscdma_wcdma_summary">Preferred network mode: NR/LTE/TDSCDMA/WCDMA</string>
+    <!-- NR/LTE/TDSCDMA/GSM/WCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_nr_lte_tdscdma_gsm_wcdma_summary">Preferred network mode: NR/LTE/TDSCDMA/GSM/WCDMA</string>
+    <!-- NR/LTE/TDSCDMA/CDMA/EvDo/GSM/WCDMA [CHAR LIMIT=NONE] -->
+    <string name="preferred_network_mode_nr_lte_tdscdma_cdma_evdo_gsm_wcdma_summary">Preferred network mode: NR/LTE/TDSCDMA/CDMA/EvDo/GSM/WCDMA</string>
 
     <!-- Mobile network settings screen, name for call settings category -->
     <string name="call_category">Calling</string>
@@ -757,6 +803,10 @@
     <string name="multi_category_enable">Multi-category enabled</string>
     <string name="multi_category_disable">Multi-category disabled</string>
 
+    <string name="network_recommended">\u0020(recommended)</string>
+    <string name="network_5G" translatable="false">5G</string>
+    <string name="network_lte_pure" translatable="false">LTE</string>
+    <string name="network_4G_pure" translatable="false">4G</string>
     <string name="network_lte">LTE (recommended)</string>
     <string name="network_4G">4G (recommended)</string>
     <string name="network_3G" translatable="false">3G</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index e95142b..d131bd8 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -211,12 +211,6 @@
         <item name="android:textColor">?android:attr/textColorPrimaryInverseDisableOnly</item>
     </style>
 
-    <style name="TrimmedHorizontalProgressBar" parent="android:Widget.Material.ProgressBar.Horizontal">
-        <item name="android:indeterminateDrawable">@drawable/progress_indeterminate_horizontal_material_trimmed</item>
-        <item name="android:minHeight">3dip</item>
-        <item name="android:maxHeight">3dip</item>
-    </style>
-
     <style name="Empty" parent="@android:style/Theme.Material.Light">
         <item name="android:forceDarkAllowed">true</item>
         <item name="android:windowIsTranslucent">true</item>
@@ -227,33 +221,6 @@
         <item name="android:backgroundDimEnabled">true</item>
     </style>
 
-    <style name="InCallAnimationStyle" parent="@*android:style/Animation.Holo.Activity">
-        <!-- Suppress task-to-task animation happening during the transition from
-             OutgoingCallBroadcaster (and SipOptionHandler) to InCallScreen.
-             The transition unexpectedly happens during the transition (inside the phone task),
-             because InCallScreen is using android:launchMode="singleInstance".
-
-             - taskOpenEnterAnimation/taskOpenExitAnimation is used for the first time
-               InCallScreen instance is created.
-
-             - taskToFrontEnterAnimation/taskToFrontExitAnimation is used when InCallScreen
-               is already available.
-               (Note that InCallScreen won't be destroyed once it is created)
-
-             TODO: try removing the flag instead -->
-        <item name="*android:taskOpenEnterAnimation">@*android:anim/activity_open_enter</item>
-        <item name="*android:taskOpenExitAnimation">@*android:anim/activity_open_exit</item>
-        <item name="*android:taskToFrontEnterAnimation">@*android:anim/activity_open_enter</item>
-        <item name="*android:taskToFrontExitAnimation">@*android:anim/activity_open_exit</item>
-    </style>
-
-    <style name="OutgoingAnimationStyle" parent="@*android:style/Animation.Holo.Activity">
-        <!-- Suppress task-to-task transition animation happening from
-             DialtactsActivity to OutgoingCallBroadcaster. -->
-        <item name="*android:taskOpenEnterAnimation">@*android:anim/activity_open_enter</item>
-        <item name="*android:taskOpenExitAnimation">@*android:anim/activity_open_exit</item>
-    </style>
-
     <!-- Style for the call settings action bar.  Should be kept in sync with Dialer. -->
     <style name="DialtactsActionBarStyle" parent="@style/TelephonyActionBarStyle">
         <!-- Shift the title text to the right -->
@@ -284,7 +251,7 @@
         <item name="android:src">@drawable/overflow_menu</item>
     </style>
 
-    <style name="EmergencyDialerTheme" parent="@*android:style/Theme.DeviceDefault.Settings.Dark.NoActionBar">
+    <style name="EmergencyDialerTheme" parent="@android:style/Theme.Material.NoActionBar">
         <item name="android:forceDarkAllowed">true</item>
         <item name="android:colorPrimaryDark">?android:attr/colorPrimary</item>
         <item name="android:colorBackgroundCacheHint">@null</item>
@@ -318,13 +285,6 @@
         <item name="android:actionOverflowButtonStyle">@style/DialtactsActionBarOverflow</item>
     </style>
 
-    <style name="OutgoingCallBroadcasterTheme" parent="@android:style/Theme.Holo.NoActionBar">
-        <item name="android:forceDarkAllowed">true</item>
-        <item name="android:windowBackground">@android:color/black</item>
-
-        <item name="*android:windowAnimationStyle">@style/OutgoingAnimationStyle</item>
-    </style>
-
     <style name="DialtactsDigitsTextAppearance">
         <item name="android:maxLines">1</item>
         <item name="android:textSize">@dimen/dialpad_digits_text_size</item>
@@ -343,48 +303,47 @@
         <item name="android:backgroundDimEnabled">false</item>
     </style>
 
-    <style name="CallSettingsWithoutDividerTheme" parent="SettingsLight">
-        <item name="android:forceDarkAllowed">true</item>
+    <style name="CallSettingsWithoutDividerTheme" parent="DialerSettingsLight">
         <item name="android:listDivider">@null</item>
     </style>
 
-    <style name="EmergencyInfoNameTextAppearance">
-        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
-        <item name="android:textColor">@*android:color/primary_text_default_material_dark</item>
+    <style name="EmergencyInfoNameTextAppearance"
+           parent="@android:style/TextAppearance.Material.Subhead">
+        <item name="android:textColor">@color/primary_text_default_material_dark</item>
         <item name="android:textSize">@dimen/emergency_info_name_text_size</item>
     </style>
 
-    <style name="EmergencyInfoHintTextAppearance">
-        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
-        <item name="android:textColor">@*android:color/secondary_text_default_material_dark</item>
+    <style name="EmergencyInfoHintTextAppearance"
+           parent="@android:style/TextAppearance.Material.Subhead">
+        <item name="android:textColor">@color/secondary_text_default_material_dark</item>
         <item name="android:textSize">@dimen/emergency_info_hint_text_size</item>
     </style>
 
-    <style name="EmergencyInfoTapHintTextAppearance">
-        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+    <style name="EmergencyInfoTapHintTextAppearance"
+           parent="@android:style/TextAppearance.Material.Subhead">
         <item name="android:textColor">@android:color/white</item>
         <item name="android:textSize">@dimen/emergency_info_tap_hint_text_size</item>
     </style>
 
-    <style name="ShortcutViewHintTextAppearance">
-        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
-        <item name="android:textColor">@*android:color/secondary_text_default_material_dark</item>
+    <style name="ShortcutViewHintTextAppearance"
+           parent="@android:style/TextAppearance.Material.Subhead">
+        <item name="android:textColor">@color/secondary_text_default_material_dark</item>
     </style>
 
-    <style name="PhoneNumberTextAppearance">
-        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
-        <item name="android:textColor">@*android:color/primary_text_default_material_light</item>
+    <style name="PhoneNumberTextAppearance"
+           parent="@android:style/TextAppearance.Material.Subhead">
+        <item name="android:textColor">@color/primary_text_default_material_light</item>
         <item name="android:textSize">@dimen/emergency_shortcut_number_text_size</item>
     </style>
 
     <style name="PhoneNumberTypeAppearance">
         <item name="android:fontFamily">roboto</item>
-        <item name="android:textColor">@*android:color/secondary_text_default_material_light</item>
+        <item name="android:textColor">@color/secondary_text_default_material_light</item>
         <item name="android:textSize">@dimen/emergency_shortcut_type_text_size</item>
     </style>
 
-    <style name="PhoneNumberTapHintAppearance">
-        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+    <style name="PhoneNumberTapHintAppearance"
+           parent="@android:style/TextAppearance.Material.Subhead">
         <item name="android:textColor">@android:color/white</item>
         <item name="android:textSize">@dimen/emergency_shortcut_tap_hint_text_size</item>
     </style>
diff --git a/res/values/styles_preference.xml b/res/values/styles_preference.xml
index fef4f72..eace2e7 100644
--- a/res/values/styles_preference.xml
+++ b/res/values/styles_preference.xml
@@ -19,22 +19,22 @@
 <!-- Things unrelated to preference framework UI customization should go to other styles files -->
 <resources>
     <!-- Preferences -->
-    <style name="SettingsPreference" parent="@*android:style/Preference.DeviceDefault">
+    <style name="SettingsPreference" parent="@style/Preference.Material">
         <item name="android:singleLineTitle">false</item>
         <item name="android:iconSpaceReserved">true</item>
     </style>
 
-    <style name="SettingsSwitchPreference" parent="@*android:style/Preference.DeviceDefault.SwitchPreference">
+    <style name="SettingsSwitchPreference" parent="@style/Preference.SwitchPreference.Material">
         <item name="android:iconSpaceReserved">true</item>
         <item name="android:singleLineTitle">false</item>
     </style>
 
-    <style name="SettingsDialogPreference" parent="@*android:style/Preference.DeviceDefault.DialogPreference">
+    <style name="SettingsDialogPreference" parent="@style/Preference.DialogPreference.Material">
         <item name="android:singleLineTitle">false</item>
         <item name="android:iconSpaceReserved">true</item>
     </style>
 
-    <style name="SettingsPreferenceScreen" parent="@*android:style/Preference.DeviceDefault.PreferenceScreen">
+    <style name="SettingsPreferenceScreen" parent="@style/Preference.PreferenceScreen.Material">
         <item name="android:singleLineTitle">false</item>
         <item name="android:iconSpaceReserved">true</item>
     </style>
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index dab04f0..0af1b23 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -558,7 +558,8 @@
 
     public void updatePhoneStateListeners(boolean isRefresh, int updateType, int subIdToUpdate) {
         List<SubscriptionInfo> subInfos = SubscriptionController.getInstance()
-                .getActiveSubscriptionInfoList(mApplication.getOpPackageName());
+                .getActiveSubscriptionInfoList(mApplication.getOpPackageName(),
+                        null);
 
         // Sort sub id list based on slot id, so that CFI/MWI notifications will be updated for
         // slot 0 first then slot 1. This is needed to ensure that when CFI or MWI is enabled for
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index d451ccf..3812b2f 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -57,13 +57,8 @@
 import com.android.internal.telephony.SubscriptionInfoUpdater;
 import com.android.internal.telephony.TelephonyPermissions;
 import com.android.internal.telephony.util.ArrayUtils;
-import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.IndentingPrintWriter;
 
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlPullParserFactory;
-
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
@@ -80,7 +75,6 @@
 /**
  * CarrierConfigLoader binds to privileged carrier apps to fetch carrier config overlays.
  */
-
 public class CarrierConfigLoader extends ICarrierConfigLoader.Stub {
     private static final String LOG_TAG = "CarrierConfigLoader";
 
@@ -149,10 +143,8 @@
 
     private static final int BIND_TIMEOUT_MILLIS = 30000;
 
-    // Tags used for saving and restoring XML documents.
-    private static final String TAG_DOCUMENT = "carrier_config";
-    private static final String TAG_VERSION = "package_version";
-    private static final String TAG_BUNDLE = "bundle_data";
+    // Keys used for saving and restoring config bundle from file.
+    private static final String KEY_VERSION = "__carrier_config_package_version__";
 
     private static final String OVERRIDE_PACKAGE_ADDITION = "-override";
 
@@ -793,27 +785,14 @@
             outFile = new FileOutputStream(
                     new File(mContext.getFilesDir(),
                             getFilenameForConfig(packageName, extraString, iccid, cid)));
-            FastXmlSerializer out = new FastXmlSerializer();
-            out.setOutput(outFile, "utf-8");
-            out.startDocument("utf-8", true);
-            out.startTag(null, TAG_DOCUMENT);
-            out.startTag(null, TAG_VERSION);
-            out.text(version);
-            out.endTag(null, TAG_VERSION);
-            out.startTag(null, TAG_BUNDLE);
-            config.saveToXml(out);
-            out.endTag(null, TAG_BUNDLE);
-            out.endTag(null, TAG_DOCUMENT);
-            out.endDocument();
-            out.flush();
+            config.putString(KEY_VERSION, version);
+            config.writeToStream(outFile);
+            outFile.flush();
             outFile.close();
         }
         catch (IOException e) {
             loge(e.toString());
         }
-        catch (XmlPullParserException e) {
-            loge(e.toString());
-        }
     }
 
     /**
@@ -858,24 +837,16 @@
             file = new File(mContext.getFilesDir(),
                     getFilenameForConfig(packageName, extraString, iccid, cid));
             inFile = new FileInputStream(file);
-            XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
-            parser.setInput(inFile, "utf-8");
 
-            int event;
-            while (((event = parser.next()) != XmlPullParser.END_DOCUMENT)) {
+            restoredBundle = PersistableBundle.readFromStream(inFile);
+            String savedVersion = restoredBundle.getString(KEY_VERSION);
+            restoredBundle.remove(KEY_VERSION);
 
-                if (event == XmlPullParser.START_TAG && TAG_VERSION.equals(parser.getName())) {
-                    String savedVersion = parser.nextText();
-                    if (!version.equals(savedVersion)) {
-                        loge("Saved version mismatch: " + version + " vs " + savedVersion);
-                        break;
-                    }
-                }
-
-                if (event == XmlPullParser.START_TAG && TAG_BUNDLE.equals(parser.getName())) {
-                    restoredBundle = PersistableBundle.restoreFromXml(parser);
-                }
+            if (!version.equals(savedVersion)) {
+                loge("Saved version mismatch: " + version + " vs " + savedVersion);
+                restoredBundle = null;
             }
+
             inFile.close();
         }
         catch (FileNotFoundException e) {
@@ -883,9 +854,6 @@
             // an override file during boot and should not be treated as an error.
             if (file != null) log("File not found: " + file.getPath());
         }
-        catch (XmlPullParserException e) {
-            loge(e.toString());
-        }
         catch (IOException e) {
             loge(e.toString());
         }
@@ -967,8 +935,14 @@
 
     @Override
     public @NonNull PersistableBundle getConfigForSubId(int subId, String callingPackage) {
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mContext, subId, callingPackage, "getCarrierConfig")) {
+        return getConfigForSubIdWithFeature(subId, callingPackage, null);
+    }
+
+    @Override
+    public @NonNull PersistableBundle getConfigForSubIdWithFeature(int subId, String callingPackage,
+            String callingFeatureId) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, subId, callingPackage,
+                callingFeatureId, "getCarrierConfig")) {
             return new PersistableBundle();
         }
 
@@ -1080,6 +1054,7 @@
             case IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR:
             case IccCardConstants.INTENT_VALUE_ICC_CARD_RESTRICTED:
             case IccCardConstants.INTENT_VALUE_ICC_UNKNOWN:
+            case IccCardConstants.INTENT_VALUE_ICC_NOT_READY:
                 mHandler.sendMessage(mHandler.obtainMessage(EVENT_CLEAR_CONFIG, phoneId, -1));
                 break;
             case IccCardConstants.INTENT_VALUE_ICC_LOADED:
@@ -1091,6 +1066,9 @@
 
     @Override
     public String getDefaultCarrierServicePackageName() {
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+                "getDefaultCarrierServicePackageName");
         return mPlatformCarrierConfigPackage;
     }
 
diff --git a/src/com/android/phone/EmergencyCallbackModeService.java b/src/com/android/phone/EmergencyCallbackModeService.java
index a07f7aa..41d83c4 100644
--- a/src/com/android/phone/EmergencyCallbackModeService.java
+++ b/src/com/android/phone/EmergencyCallbackModeService.java
@@ -30,13 +30,12 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
-import android.os.SystemProperties;
+import android.sysprop.TelephonyProperties;
 import android.util.Log;
 
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.telephony.TelephonyProperties;
 import com.android.internal.telephony.util.NotificationChannelController;
 
 import java.text.SimpleDateFormat;
@@ -50,7 +49,7 @@
 public class EmergencyCallbackModeService extends Service {
 
     // Default Emergency Callback Mode timeout value
-    private static final int DEFAULT_ECM_EXIT_TIMER_VALUE = 300000;
+    private static final long DEFAULT_ECM_EXIT_TIMER_VALUE = 300000L;
     private static final String LOG_TAG = "EmergencyCallbackModeService";
 
     private NotificationManager mNotificationManager = null;
@@ -139,8 +138,7 @@
      */
     private void startTimerNotification() {
         // Get Emergency Callback Mode timeout value
-        long ecmTimeout = SystemProperties.getLong(
-                    TelephonyProperties.PROPERTY_ECM_EXIT_TIMER, DEFAULT_ECM_EXIT_TIMER_VALUE);
+        long ecmTimeout = TelephonyProperties.ecm_exit_timer().orElse(DEFAULT_ECM_EXIT_TIMER_VALUE);
 
         // Show the notification
         showNotification(ecmTimeout);
diff --git a/src/com/android/phone/EmergencyDialer.java b/src/com/android/phone/EmergencyDialer.java
index 7531aca..119c71b 100644
--- a/src/com/android/phone/EmergencyDialer.java
+++ b/src/com/android/phone/EmergencyDialer.java
@@ -45,7 +45,7 @@
 import android.telecom.TelecomManager;
 import android.telephony.CarrierConfigManager;
 import android.telephony.PhoneNumberUtils;
-import android.telephony.Rlog;
+import com.android.telephony.Rlog;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
diff --git a/src/com/android/phone/IccPanel.java b/src/com/android/phone/IccPanel.java
index be182233..73dd8bc 100644
--- a/src/com/android/phone/IccPanel.java
+++ b/src/com/android/phone/IccPanel.java
@@ -74,13 +74,13 @@
     @Override
     protected void onStart() {
         super.onStart();
-        mStatusBarManager.disable(StatusBarManager.DISABLE_EXPAND);
+        mStatusBarManager.setDisabledForSimNetworkLock(true);
     }
 
     @Override
     public void onStop() {
         super.onStop();
-        mStatusBarManager.disable(StatusBarManager.DISABLE_NONE);
+        mStatusBarManager.setDisabledForSimNetworkLock(false);
     }
 
     public boolean onKeyDown(int keyCode, KeyEvent event) {
diff --git a/src/com/android/phone/ImsRcsController.java b/src/com/android/phone/ImsRcsController.java
index 06d2367..1a28afd 100644
--- a/src/com/android/phone/ImsRcsController.java
+++ b/src/com/android/phone/ImsRcsController.java
@@ -23,14 +23,18 @@
 import android.os.ServiceManager;
 import android.os.ServiceSpecificException;
 import android.telephony.ims.ImsException;
+import android.telephony.ims.RegistrationManager;
 import android.telephony.ims.aidl.IImsCapabilityCallback;
 import android.telephony.ims.aidl.IImsRcsController;
+import android.telephony.ims.aidl.IImsRegistrationCallback;
 import android.telephony.ims.aidl.IRcsUceControllerCallback;
 import android.telephony.ims.feature.RcsFeature;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
 import android.util.Log;
 
+import com.android.ims.ImsManager;
 import com.android.ims.RcsFeatureManager;
+import com.android.internal.telephony.IIntegerConsumer;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.imsphone.ImsPhone;
 
@@ -70,6 +74,86 @@
     }
 
     /**
+     * Register a IImsRegistrationCallback to receive IMS network registration state.
+     */
+    @Override
+    public void registerImsRegistrationCallback(int subId, IImsRegistrationCallback callback)
+            throws RemoteException {
+        enforceReadPrivilegedPermission("registerImsRegistrationCallback");
+        final long token = Binder.clearCallingIdentity();
+        try {
+            getRcsFeatureManager(subId).registerImsRegistrationCallback(callback);
+        } catch (com.android.ims.ImsException e) {
+            Log.e(TAG, "registerImsRegistrationCallback: sudId=" + subId + ", " + e.getMessage());
+            throw new ServiceSpecificException(e.getCode());
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    /**
+     * Removes an existing {@link RegistrationCallback}.
+     */
+    @Override
+    public void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback callback) {
+        enforceReadPrivilegedPermission("unregisterImsRegistrationCallback");
+        final long token = Binder.clearCallingIdentity();
+        try {
+            getRcsFeatureManager(subId).unregisterImsRegistrationCallback(callback);
+        } catch (ServiceSpecificException e) {
+            Log.e(TAG, "unregisterImsRegistrationCallback: error=" + e.errorCode);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    /**
+     * Get the IMS service registration state for the RcsFeature associated with this sub id.
+     */
+    @Override
+    public void getImsRcsRegistrationState(int subId, IIntegerConsumer consumer) {
+        enforceReadPrivilegedPermission("getImsRcsRegistrationState");
+        final long token = Binder.clearCallingIdentity();
+        try {
+            getImsPhone(subId).getImsRcsRegistrationState(regState -> {
+                try {
+                    consumer.accept((regState == null)
+                            ? RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED : regState);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "getImsRcsRegistrationState: callback is not available.");
+                }
+            });
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    /**
+     * Gets the Transport Type associated with the current IMS RCS registration.
+     */
+    @Override
+    public void getImsRcsRegistrationTransportType(int subId, IIntegerConsumer consumer) {
+        enforceReadPrivilegedPermission("getImsRcsRegistrationTransportType");
+        final long token = Binder.clearCallingIdentity();
+        try {
+            getImsPhone(subId).getImsRcsRegistrationTech(regTech -> {
+                // Convert registration tech from ImsRegistrationImplBase -> RegistrationManager
+                int regTechConverted = (regTech == null)
+                        ? ImsRegistrationImplBase.REGISTRATION_TECH_NONE : regTech;
+                regTechConverted = RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.get(
+                        regTechConverted);
+                try {
+                    consumer.accept(regTechConverted);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "getImsRcsRegistrationTransportType: callback is not available.");
+                }
+            });
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    /**
      * Register a capability callback which will provide RCS availability updates for the
      * subscription specified.
      *
@@ -202,13 +286,17 @@
     }
 
     /**
-     * Retrieve RcsFeatureManager instance.
+     * Retrieve ImsPhone instance.
      *
      * @param subId the subscription ID
-     * @return The RcsFeatureManager instance
-     * @throws SecurityException if getting Phone or RcsFeatureManager instance failed.
+     * @return The ImsPhone instance
+     * @throws ServiceSpecificException if getting ImsPhone instance failed.
      */
-    private RcsFeatureManager getRcsFeatureManager(int subId) {
+    private ImsPhone getImsPhone(int subId) {
+        if (!ImsManager.isImsSupportedOnDevice(mApp)) {
+            throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
+                    "IMS is not available on device.");
+        }
         Phone phone = PhoneGlobals.getPhone(subId);
         if (phone == null) {
             throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION,
@@ -216,7 +304,32 @@
         }
         ImsPhone imsPhone = (ImsPhone) phone.getImsPhone();
         if (imsPhone == null) {
+            throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE,
+                    "Cannot find ImsPhone instance: " + subId);
+        }
+        return imsPhone;
+    }
+
+    /**
+     * Retrieve RcsFeatureManager instance.
+     *
+     * @param subId the subscription ID
+     * @return The RcsFeatureManager instance
+     * @throws ServiceSpecificException if getting RcsFeatureManager instance failed.
+     */
+    private RcsFeatureManager getRcsFeatureManager(int subId) {
+        if (!ImsManager.isImsSupportedOnDevice(mApp)) {
             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
+                    "IMS is not available on device.");
+        }
+        Phone phone = PhoneGlobals.getPhone(subId);
+        if (phone == null) {
+            throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION,
+                    "Invalid subscription Id: " + subId);
+        }
+        ImsPhone imsPhone = (ImsPhone) phone.getImsPhone();
+        if (imsPhone == null) {
+            throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE,
                     "Cannot find ImsPhone instance: " + subId);
         }
         RcsFeatureManager rcsFeatureManager = imsPhone.getRcsManager();
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 5d4d9b3..9ecb2c5 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -26,6 +26,7 @@
 import android.content.ContextWrapper;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageManager;
 import android.content.res.XmlResourceParser;
 import android.media.AudioManager;
 import android.net.ConnectivityManager;
@@ -66,6 +67,7 @@
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.dataconnection.DataConnectionReasons;
 import com.android.internal.telephony.dataconnection.DataConnectionReasons.DataDisallowedReasonType;
+import com.android.internal.telephony.ims.ImsResolver;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.phone.settings.SettingsConstants;
 import com.android.phone.vvm.CarrierVvmPackageInstalledReceiver;
@@ -146,6 +148,7 @@
     CallNotifier notifier;
     CallerInfoCache callerInfoCache;
     NotificationMgr notificationMgr;
+    ImsResolver mImsResolver;
     public PhoneInterfaceManager phoneMgr;
     public ImsRcsController imsRcsController;
     CarrierConfigLoader configLoader;
@@ -317,6 +320,19 @@
             // Initialize the telephony framework
             PhoneFactory.makeDefaultPhones(this);
 
+            // Only bring up ImsResolver if the device supports having an IMS stack.
+            if (getPackageManager().hasSystemFeature(
+                    PackageManager.FEATURE_TELEPHONY_IMS)) {
+                // Get the package name of the default IMS implementation.
+                String defaultImsMmtelPackage = getResources().getString(
+                        R.string.config_ims_mmtel_package);
+                String defaultImsRcsPackage = getResources().getString(
+                        R.string.config_ims_rcs_package);
+                mImsResolver = new ImsResolver(this, defaultImsMmtelPackage,
+                        defaultImsRcsPackage, PhoneFactory.getPhones().length);
+                mImsResolver.initialize();
+            }
+
             // Start TelephonyDebugService After the default phone is created.
             Intent intent = new Intent(this, TelephonyDebugService.class);
             startService(intent);
@@ -438,6 +454,10 @@
         return PhoneFactory.getPhone(SubscriptionManager.getPhoneId(subId));
     }
 
+    public ImsResolver getImsResolver() {
+        return mImsResolver;
+    }
+
     /* package */ CallManager getCallManager() {
         return mCM;
     }
@@ -447,7 +467,7 @@
     }
 
     public PersistableBundle getCarrierConfigForSubId(int subId) {
-        return configLoader.getConfigForSubId(subId, getOpPackageName());
+        return configLoader.getConfigForSubIdWithFeature(subId, getOpPackageName(), null);
     }
 
     private void registerSettingsObserver() {
@@ -877,6 +897,14 @@
         pw.increaseIndent();
         mDataRoamingNotifLog.dump(fd, pw, args);
         pw.decreaseIndent();
+        pw.println("ImsResolver:");
+        pw.increaseIndent();
+        try {
+            if (mImsResolver != null) mImsResolver.dump(fd, pw, args);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        pw.decreaseIndent();
         pw.decreaseIndent();
         pw.println("------- End PhoneGlobals -------");
     }
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 296525d..8ceb75e 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.SUBSCRIPTION_KEY;
 
 import android.Manifest.permission;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.AppOpsManager;
 import android.app.PendingIntent;
@@ -52,7 +53,6 @@
 import android.os.ServiceManager;
 import android.os.ServiceSpecificException;
 import android.os.ShellCallback;
-import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.WorkSource;
@@ -60,6 +60,7 @@
 import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.provider.Telephony;
+import android.sysprop.TelephonyProperties;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
@@ -67,10 +68,11 @@
 import android.telephony.CarrierConfigManager;
 import android.telephony.CarrierRestrictionRules;
 import android.telephony.CellIdentity;
+import android.telephony.CellIdentityCdma;
+import android.telephony.CellIdentityGsm;
 import android.telephony.CellInfo;
 import android.telephony.CellInfoGsm;
 import android.telephony.CellInfoWcdma;
-import android.telephony.CellLocation;
 import android.telephony.ClientRequestStats;
 import android.telephony.ICellInfoCallback;
 import android.telephony.IccOpenLogicalChannelResponse;
@@ -82,7 +84,7 @@
 import android.telephony.PhoneNumberRange;
 import android.telephony.RadioAccessFamily;
 import android.telephony.RadioAccessSpecifier;
-import android.telephony.Rlog;
+import com.android.telephony.Rlog;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.SubscriptionInfo;
@@ -94,10 +96,8 @@
 import android.telephony.UiccSlotInfo;
 import android.telephony.UssdResponse;
 import android.telephony.VisualVoicemailSmsFilterSettings;
-import android.telephony.cdma.CdmaCellLocation;
 import android.telephony.data.ApnSetting;
 import android.telephony.emergency.EmergencyNumber;
-import android.telephony.gsm.GsmCellLocation;
 import android.telephony.ims.ImsException;
 import android.telephony.ims.ProvisioningManager;
 import android.telephony.ims.RegistrationManager;
@@ -110,6 +110,7 @@
 import android.telephony.ims.aidl.IImsRegistrationCallback;
 import android.telephony.ims.feature.ImsFeature;
 import android.telephony.ims.feature.MmTelFeature;
+import android.telephony.ims.feature.RcsFeature;
 import android.telephony.ims.stub.ImsConfigImplBase;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
 import android.text.TextUtils;
@@ -133,7 +134,6 @@
 import com.android.internal.telephony.ITelephony;
 import com.android.internal.telephony.IccCard;
 import com.android.internal.telephony.LocaleTracker;
-import com.android.internal.telephony.MccTable;
 import com.android.internal.telephony.NetworkScanRequestTracker;
 import com.android.internal.telephony.OperatorInfo;
 import com.android.internal.telephony.Phone;
@@ -158,6 +158,7 @@
 import com.android.internal.telephony.metrics.TelephonyMetrics;
 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
 import com.android.internal.telephony.uicc.IccIoResult;
+import com.android.internal.telephony.uicc.IccRecords;
 import com.android.internal.telephony.uicc.IccUtils;
 import com.android.internal.telephony.uicc.SIMRecords;
 import com.android.internal.telephony.uicc.UiccCard;
@@ -165,6 +166,7 @@
 import com.android.internal.telephony.uicc.UiccController;
 import com.android.internal.telephony.uicc.UiccProfile;
 import com.android.internal.telephony.uicc.UiccSlot;
+import com.android.internal.telephony.util.LocaleUtils;
 import com.android.internal.telephony.util.VoicemailNotificationSettingsUtil;
 import com.android.internal.util.HexDump;
 import com.android.phone.settings.PickSmsSubscriptionActivity;
@@ -272,15 +274,12 @@
     private static final int SELECT_P2 = 0;
     private static final int SELECT_P3 = 0x10;
 
-    private static final String DEFAULT_NETWORK_MODE_PROPERTY_NAME = "ro.telephony.default_network";
-    private static final String DEFAULT_DATA_ROAMING_PROPERTY_NAME = "ro.com.android.dataroaming";
-    private static final String DEFAULT_MOBILE_DATA_PROPERTY_NAME = "ro.com.android.mobiledata";
-
     /** The singleton instance. */
     private static PhoneInterfaceManager sInstance;
 
     private PhoneGlobals mApp;
     private CallManager mCM;
+    private ImsResolver mImsResolver;
     private UserManager mUserManager;
     private AppOpsManager mAppOps;
     private MainThreadHandler mMainThreadHandler;
@@ -881,7 +880,7 @@
                     }
                     // Result cannot be null. Return ModemActivityInfo with all fields set to 0.
                     if (request.result == null) {
-                        request.result = new ModemActivityInfo(0, 0, 0, null, 0, 0);
+                        request.result = new ModemActivityInfo(0, 0, 0, null, 0);
                     }
                     notifyRequester(request);
                     break;
@@ -1105,7 +1104,7 @@
                     request = (MainThreadRequest) msg.obj;
                     WorkSource ws = (WorkSource) request.argument;
                     Phone phone = getPhoneFromRequest(request);
-                    phone.getCellLocation(ws, obtainMessage(EVENT_GET_CELL_LOCATION_DONE, request));
+                    phone.getCellIdentity(ws, obtainMessage(EVENT_GET_CELL_LOCATION_DONE, request));
                     break;
                 case EVENT_GET_CELL_LOCATION_DONE:
                     ar = (AsyncResult) msg.obj;
@@ -1115,7 +1114,7 @@
                     } else {
                         phone = getPhoneFromRequest(request);
                         request.result = (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
-                                ? new CdmaCellLocation() : new GsmCellLocation();
+                                ? new CellIdentityCdma() : new CellIdentityGsm();
                     }
 
                     synchronized (request) {
@@ -1393,6 +1392,7 @@
     private PhoneInterfaceManager(PhoneGlobals app) {
         mApp = app;
         mCM = PhoneGlobals.getInstance().mCM;
+        mImsResolver = PhoneGlobals.getInstance().getImsResolver();
         mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
         mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
         mMainThreadHandler = new MainThreadHandler();
@@ -1530,29 +1530,16 @@
         }
     }
 
-    public boolean supplyPin(String pin) {
-        return supplyPinForSubscriber(getDefaultSubscription(), pin);
-    }
-
     public boolean supplyPinForSubscriber(int subId, String pin) {
         int [] resultArray = supplyPinReportResultForSubscriber(subId, pin);
         return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
     }
 
-    public boolean supplyPuk(String puk, String pin) {
-        return supplyPukForSubscriber(getDefaultSubscription(), puk, pin);
-    }
-
     public boolean supplyPukForSubscriber(int subId, String puk, String pin) {
         int [] resultArray = supplyPukReportResultForSubscriber(subId, puk, pin);
         return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
     }
 
-    /** {@hide} */
-    public int[] supplyPinReportResult(String pin) {
-        return supplyPinReportResultForSubscriber(getDefaultSubscription(), pin);
-    }
-
     public int[] supplyPinReportResultForSubscriber(int subId, String pin) {
         enforceModifyPermission();
 
@@ -1566,11 +1553,6 @@
         }
     }
 
-    /** {@hide} */
-    public int[] supplyPukReportResult(String puk, String pin) {
-        return supplyPukReportResultForSubscriber(getDefaultSubscription(), puk, pin);
-    }
-
     public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) {
         enforceModifyPermission();
 
@@ -1703,15 +1685,29 @@
         }
     }
 
+    @Deprecated
     @Override
     public boolean isRadioOn(String callingPackage) {
-        return isRadioOnForSubscriber(getDefaultSubscription(), callingPackage);
+        return isRadioOnWithFeature(callingPackage, null);
     }
 
     @Override
+    public boolean isRadioOnWithFeature(String callingPackage, String callingFeatureId) {
+        return isRadioOnForSubscriberWithFeature(getDefaultSubscription(), callingPackage,
+                callingFeatureId);
+    }
+
+    @Deprecated
+    @Override
     public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
+        return isRadioOnForSubscriberWithFeature(subId, callingPackage, null);
+    }
+
+    @Override
+    public boolean isRadioOnForSubscriberWithFeature(int subId, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "isRadioOnForSubscriber")) {
+                mApp, subId, callingPackage, callingFeatureId, "isRadioOnForSubscriber")) {
             return false;
         }
 
@@ -1998,7 +1994,7 @@
     }
 
     @Override
-    public Bundle getCellLocation(String callingPackage) {
+    public CellIdentity getCellLocation(String callingPackage, String callingFeatureId) {
         mApp.getSystemService(AppOpsManager.class)
                 .checkPackage(Binder.getCallingUid(), callingPackage);
 
@@ -2006,6 +2002,7 @@
                 LocationAccessPolicy.checkLocationPermission(mApp,
                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
                                 .setCallingPackage(callingPackage)
+                                .setCallingFeatureId(callingFeatureId)
                                 .setCallingPid(Binder.getCallingPid())
                                 .setCallingUid(Binder.getCallingUid())
                                 .setMethod("getCellLocation")
@@ -2015,29 +2012,28 @@
             case DENIED_HARD:
                 throw new SecurityException("Not allowed to access cell location");
             case DENIED_SOFT:
-                return new Bundle();
+                return (getDefaultPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
+                        ? new CellIdentityCdma() : new CellIdentityGsm();
         }
 
         WorkSource workSource = getWorkSource(Binder.getCallingUid());
         final long identity = Binder.clearCallingIdentity();
         try {
             if (DBG_LOC) log("getCellLocation: is active user");
-            Bundle data = new Bundle();
             int subId = mSubscriptionController.getDefaultDataSubId();
-            CellLocation cl = (CellLocation) sendRequest(CMD_GET_CELL_LOCATION, workSource, subId);
-            cl.fillInNotifierBundle(data);
-            return data;
+            return (CellIdentity) sendRequest(CMD_GET_CELL_LOCATION, workSource, subId);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
     }
 
     @Override
-    public String getNetworkCountryIsoForPhone(int phoneId, String callingPackage) {
+    public String getNetworkCountryIsoForPhone(int phoneId, String callingPackage,
+            String callingFeatureId) {
         if (!TextUtils.isEmpty(callingPackage)) {
             final int subId = mSubscriptionController.getSubIdUsingPhoneId(phoneId);
-            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                    mApp, subId, callingPackage, "getNetworkCountryIsoForPhone")) {
+            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
+                    callingFeatureId, "getNetworkCountryIsoForPhone")) {
                 return "";
             }
         }
@@ -2054,7 +2050,8 @@
             // Todo: fix this when we can get the actual cellular network info when the device
             // is on IWLAN.
             if (TelephonyManager.NETWORK_TYPE_IWLAN
-                    == getVoiceNetworkTypeForSubscriber(subId, mApp.getPackageName())) {
+                    == getVoiceNetworkTypeForSubscriber(subId, mApp.getPackageName(),
+                    null)) {
                 return "";
             }
             Phone phone = PhoneFactory.getPhone(phoneId);
@@ -2141,7 +2138,8 @@
 
     @Override
     @SuppressWarnings("unchecked")
-    public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage) {
+    public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage,
+            String callingFeatureId) {
         final int targetSdk = getTargetSdk(callingPackage);
         if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
             throw new SecurityException(
@@ -2155,7 +2153,7 @@
 
         if (DBG_LOC) log("getNeighboringCellInfo: is active user");
 
-        List<CellInfo> info = getAllCellInfo(callingPackage);
+        List<CellInfo> info = getAllCellInfo(callingPackage, callingFeatureId);
         if (info == null) return null;
 
         List<NeighboringCellInfo> neighbors = new ArrayList<NeighboringCellInfo>();
@@ -2179,7 +2177,7 @@
     }
 
     @Override
-    public List<CellInfo> getAllCellInfo(String callingPackage) {
+    public List<CellInfo> getAllCellInfo(String callingPackage, String callingFeatureId) {
         mApp.getSystemService(AppOpsManager.class)
                 .checkPackage(Binder.getCallingUid(), callingPackage);
 
@@ -2187,6 +2185,7 @@
                 LocationAccessPolicy.checkLocationPermission(mApp,
                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
                                 .setCallingPackage(callingPackage)
+                                .setCallingFeatureId(callingFeatureId)
                                 .setCallingPid(Binder.getCallingPid())
                                 .setCallingUid(Binder.getCallingUid())
                                 .setMethod("getAllCellInfo")
@@ -2222,20 +2221,21 @@
     }
 
     @Override
-    public void requestCellInfoUpdate(int subId, ICellInfoCallback cb, String callingPackage) {
-        requestCellInfoUpdateInternal(
-                subId, cb, callingPackage, getWorkSource(Binder.getCallingUid()));
+    public void requestCellInfoUpdate(int subId, ICellInfoCallback cb, String callingPackage,
+            String callingFeatureId) {
+        requestCellInfoUpdateInternal(subId, cb, callingPackage, callingFeatureId,
+                getWorkSource(Binder.getCallingUid()));
     }
 
     @Override
-    public void requestCellInfoUpdateWithWorkSource(
-            int subId, ICellInfoCallback cb, String callingPackage, WorkSource workSource) {
+    public void requestCellInfoUpdateWithWorkSource(int subId, ICellInfoCallback cb,
+            String callingPackage, String callingFeatureId, WorkSource workSource) {
         enforceModifyPermission();
-        requestCellInfoUpdateInternal(subId, cb, callingPackage, workSource);
+        requestCellInfoUpdateInternal(subId, cb, callingPackage, callingFeatureId, workSource);
     }
 
-    private void requestCellInfoUpdateInternal(
-            int subId, ICellInfoCallback cb, String callingPackage, WorkSource workSource) {
+    private void requestCellInfoUpdateInternal(int subId, ICellInfoCallback cb,
+            String callingPackage, String callingFeatureId, WorkSource workSource) {
         mApp.getSystemService(AppOpsManager.class)
                 .checkPackage(Binder.getCallingUid(), callingPackage);
 
@@ -2243,6 +2243,7 @@
                 LocationAccessPolicy.checkLocationPermission(mApp,
                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
                                 .setCallingPackage(callingPackage)
+                                .setCallingFeatureId(callingFeatureId)
                                 .setCallingPid(Binder.getCallingPid())
                                 .setCallingUid(Binder.getCallingUid())
                                 .setMethod("requestCellInfoUpdate")
@@ -2281,14 +2282,14 @@
     }
 
     @Override
-    public String getImeiForSlot(int slotIndex, String callingPackage) {
+    public String getImeiForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
         Phone phone = PhoneFactory.getPhone(slotIndex);
         if (phone == null) {
             return null;
         }
         int subId = phone.getSubId();
         if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
-                callingPackage, "getImeiForSlot")) {
+                callingPackage, callingFeatureId, "getImeiForSlot")) {
             return null;
         }
 
@@ -2312,7 +2313,7 @@
     }
 
     @Override
-    public String getMeidForSlot(int slotIndex, String callingPackage) {
+    public String getMeidForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
         Phone phone = PhoneFactory.getPhone(slotIndex);
         if (phone == null) {
             return null;
@@ -2320,7 +2321,7 @@
 
         int subId = phone.getSubId();
         if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
-                callingPackage, "getMeidForSlot")) {
+                callingPackage, callingFeatureId, "getMeidForSlot")) {
             return null;
         }
 
@@ -2344,14 +2345,16 @@
     }
 
     @Override
-    public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage) {
+    public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage,
+            String callingFeatureId) {
         Phone phone = PhoneFactory.getPhone(slotIndex);
         if (phone == null) {
             return null;
         }
         int subId = phone.getSubId();
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getDeviceSoftwareVersionForSlot")) {
+                mApp, subId, callingPackage, callingFeatureId,
+                "getDeviceSoftwareVersionForSlot")) {
             return null;
         }
 
@@ -2500,14 +2503,17 @@
      * Returns the CDMA ERI icon index to display
      */
     @Override
-    public int getCdmaEriIconIndex(String callingPackage) {
-        return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage);
+    public int getCdmaEriIconIndex(String callingPackage, String callingFeatureId) {
+        return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage,
+                callingFeatureId);
     }
 
     @Override
-    public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage) {
+    public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getCdmaEriIconIndexForSubscriber")) {
+                mApp, subId, callingPackage, callingFeatureId,
+                "getCdmaEriIconIndexForSubscriber")) {
             return -1;
         }
 
@@ -2530,14 +2536,17 @@
      * 1 - FLASHING
      */
     @Override
-    public int getCdmaEriIconMode(String callingPackage) {
-        return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage);
+    public int getCdmaEriIconMode(String callingPackage, String callingFeatureId) {
+        return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage,
+                callingFeatureId);
     }
 
     @Override
-    public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage) {
+    public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getCdmaEriIconModeForSubscriber")) {
+                mApp, subId, callingPackage, callingFeatureId,
+                "getCdmaEriIconModeForSubscriber")) {
             return -1;
         }
 
@@ -2558,14 +2567,17 @@
      * Returns the CDMA ERI text,
      */
     @Override
-    public String getCdmaEriText(String callingPackage) {
-        return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage);
+    public String getCdmaEriText(String callingPackage, String callingFeatureId) {
+        return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage,
+                callingFeatureId);
     }
 
     @Override
-    public String getCdmaEriTextForSubscriber(int subId, String callingPackage) {
+    public String getCdmaEriTextForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getCdmaEriIconTextForSubscriber")) {
+                mApp, subId, callingPackage, callingFeatureId,
+                "getCdmaEriIconTextForSubscriber")) {
             return null;
         }
 
@@ -2700,10 +2712,12 @@
     }
 
     @Override
-    public String getVisualVoicemailPackageName(String callingPackage, int subId) {
+    public String getVisualVoicemailPackageName(String callingPackage, String callingFeatureId,
+            int subId) {
         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getVisualVoicemailPackageName")) {
+                mApp, subId, callingPackage, callingFeatureId,
+                "getVisualVoicemailPackageName")) {
             return null;
         }
 
@@ -2866,9 +2880,11 @@
      * Returns the unread count of voicemails for a subId
      */
     @Override
-    public int getVoiceMessageCountForSubscriber(int subId, String callingPackage) {
+    public int getVoiceMessageCountForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getVoiceMessageCountForSubscriber")) {
+                mApp, subId, callingPackage, callingFeatureId,
+                "getVoiceMessageCountForSubscriber")) {
             return 0;
         }
         final long identity = Binder.clearCallingIdentity();
@@ -3434,6 +3450,91 @@
         }
     }
 
+
+    private void checkModifyPhoneStatePermission(int subId, String message) {
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
+                message);
+    }
+
+    private boolean isImsProvisioningRequired(int subId, int capability,
+            boolean isMmtelCapability) {
+        Phone phone = getPhone(subId);
+        if (phone == null) {
+            loge("phone instance null for subid " + subId);
+            return false;
+        }
+        if (isMmtelCapability) {
+            if (!doesImsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
+                return false;
+            }
+        } else {
+            if (!doesRcsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public void setRcsProvisioningStatusForCapability(int subId, int capability,
+            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.");
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+
+    }
+
+
+    @Override
+    public boolean getRcsProvisioningStatusForCapability(int subId, int capability) {
+        enforceReadPrivilegedPermission("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.");
+                }
+            }
+
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
     @Override
     public void setImsProvisioningStatusForCapability(int subId, int capability, int tech,
             boolean isProvisioned) {
@@ -3441,18 +3542,11 @@
                 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
             throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
         }
-        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
-                "setProvisioningStatusForCapability");
+        checkModifyPhoneStatePermission(subId, "setImsProvisioningStatusForCapability");
         final long identity = Binder.clearCallingIdentity();
         try {
             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
-            Phone phone = getPhone(subId);
-            if (phone == null) {
-                loge("setImsProvisioningStatusForCapability: phone instance null for subid "
-                        + subId);
-                return;
-            }
-            if (!doesImsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
+            if (!isImsProvisioningRequired(subId, capability, true)) {
                 return;
             }
 
@@ -3490,8 +3584,9 @@
                     break;
                 }
                 default: {
-                    throw new IllegalArgumentException("Tried to set provisioning for capability '"
-                            + capability + "', which does not require provisioning.");
+                    throw new IllegalArgumentException("Tried to set provisioning for "
+                            + "MmTel capability '" + capability + "', which does not require "
+                            + "provisioning. ");
                 }
             }
 
@@ -3510,16 +3605,7 @@
         final long identity = Binder.clearCallingIdentity();
         try {
             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
-            Phone phone = getPhone(subId);
-            if (phone == null) {
-                loge("getImsProvisioningStatusForCapability: phone instance null for subid "
-                        + subId);
-                // We will fail with "true" as the provisioning status because this is the default
-                // if we do not require provisioning.
-                return true;
-            }
-
-            if (!doesImsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
+            if (!isImsProvisioningRequired(subId, capability, true)) {
                 return true;
             }
 
@@ -3545,8 +3631,9 @@
                     return isMmTelCapabilityProvisionedInCache(subId, capability, tech);
                 }
                 default: {
-                    throw new IllegalArgumentException("Tried to get provisioning for capability '"
-                            + capability + "', which does not require provisioning.");
+                    throw new IllegalArgumentException(
+                            "Tried to get provisioning for MmTel capability '" + capability
+                                    + "', which does not require provisioning.");
                 }
             }
 
@@ -3655,6 +3742,29 @@
         return false;
     }
 
+    private boolean doesRcsCapabilityRequireProvisioning(Context context, int subId,
+            int capability) {
+        CarrierConfigManager configManager = new CarrierConfigManager(context);
+        PersistableBundle c = configManager.getConfigForSubId(subId);
+
+        boolean requireRcsProvisioning = c.getBoolean(
+                CarrierConfigManager.KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL, false);
+
+        // First check to make sure that the capability requires provisioning.
+        switch (capability) {
+            case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
+                // intentional fallthrough
+            case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE: {
+                if (requireRcsProvisioning) {
+                    // OPTION or PRESENCE requires provisioning
+                    return true;
+                }
+                break;
+            }
+        }
+        return false;
+    }
+
     @Override
     public int getImsProvisioningInt(int subId, int key) {
         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
@@ -3778,13 +3888,15 @@
      * Returns the data network type for a subId; does not throw SecurityException.
      */
     @Override
-    public int getNetworkTypeForSubscriber(int subId, String callingPackage) {
+    public int getNetworkTypeForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
         final int targetSdk = getTargetSdk(callingPackage);
         if (targetSdk > android.os.Build.VERSION_CODES.Q) {
-            return getDataNetworkTypeForSubscriber(subId, callingPackage);
+            return getDataNetworkTypeForSubscriber(subId, callingPackage, callingFeatureId);
         } else if (targetSdk == android.os.Build.VERSION_CODES.Q
                 && !TelephonyPermissions.checkCallingOrSelfReadPhoneStateNoThrow(
-                        mApp, subId, callingPackage, "getNetworkTypeForSubscriber")) {
+                        mApp, subId, callingPackage, callingFeatureId,
+                "getNetworkTypeForSubscriber")) {
             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
         }
 
@@ -3805,17 +3917,20 @@
      * Returns the data network type
      */
     @Override
-    public int getDataNetworkType(String callingPackage) {
-        return getDataNetworkTypeForSubscriber(getDefaultSubscription(), callingPackage);
+    public int getDataNetworkType(String callingPackage, String callingFeatureId) {
+        return getDataNetworkTypeForSubscriber(getDefaultSubscription(), callingPackage,
+                callingFeatureId);
     }
 
     /**
      * Returns the data network type for a subId
      */
     @Override
-    public int getDataNetworkTypeForSubscriber(int subId, String callingPackage) {
+    public int getDataNetworkTypeForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
+                mApp, subId, callingPackage, callingFeatureId,
+                "getDataNetworkTypeForSubscriber")) {
             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
         }
 
@@ -3836,9 +3951,11 @@
      * Returns the Voice network type for a subId
      */
     @Override
-    public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage) {
+    public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
+                mApp, subId, callingPackage, callingFeatureId,
+                "getDataNetworkTypeForSubscriber")) {
             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
         }
 
@@ -3892,14 +4009,17 @@
      * or {@link Phone#LTE_ON_CDMA_TRUE}
      */
     @Override
-    public int getLteOnCdmaMode(String callingPackage) {
-        return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage);
+    public int getLteOnCdmaMode(String callingPackage, String callingFeatureId) {
+        return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage,
+                callingFeatureId);
     }
 
     @Override
-    public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage) {
+    public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getLteOnCdmaModeForSubscriber")) {
+                mApp, subId, callingPackage, callingFeatureId,
+                "getLteOnCdmaModeForSubscriber")) {
             return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
         }
 
@@ -4223,9 +4343,10 @@
      * Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM)
      * on a particular subscription
      */
-    public String[] getForbiddenPlmns(int subId, int appType, String callingPackage) {
+    public String[] getForbiddenPlmns(int subId, int appType, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getForbiddenPlmns")) {
+                mApp, subId, callingPackage, callingFeatureId, "getForbiddenPlmns")) {
             return null;
         }
 
@@ -4257,12 +4378,13 @@
      * @param appType the uicc app type, must be USIM or SIM.
      * @param fplmns the Forbiden plmns list that needed to be written to the SIM.
      * @param callingPackage the op Package name.
+     * @param callingFeatureId the feature in the package.
      * @return number of fplmns that is successfully written to the SIM.
      */
-    public int setForbiddenPlmns(
-            int subId, int appType, List<String> fplmns, String callingPackage) {
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "setForbiddenPlmns")) {
+    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");
         }
@@ -4438,10 +4560,11 @@
         return false;
     }
 
-    public String[] getPcscfAddress(String apnType, String callingPackage) {
+    public String[] getPcscfAddress(String apnType, String callingPackage,
+            String callingFeatureId) {
         final Phone defaultPhone = getDefaultPhone();
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, defaultPhone.getSubId(), callingPackage, "getPcscfAddress")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
+                callingPackage, callingFeatureId, "getPcscfAddress")) {
             return new String[0];
         }
 
@@ -4462,12 +4585,11 @@
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            ImsResolver resolver = PhoneFactory.getImsResolver();
-            if (resolver == null) {
+            if (mImsResolver == null) {
                 // may happen if the device does not support IMS.
                 return;
             }
-            resolver.enableIms(slotId);
+            mImsResolver.enableIms(slotId);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -4482,12 +4604,11 @@
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            ImsResolver resolver = PhoneFactory.getImsResolver();
-            if (resolver == null) {
+            if (mImsResolver == null) {
                 // may happen if the device does not support IMS.
                 return;
             }
-            resolver.disableIms(slotId);
+            mImsResolver.disableIms(slotId);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -4504,12 +4625,11 @@
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            ImsResolver resolver = PhoneFactory.getImsResolver();
-            if (resolver == null) {
+            if (mImsResolver == null) {
                 // may happen if the device does not support IMS.
                 return null;
             }
-            return resolver.getMmTelFeatureAndListen(slotId, callback);
+            return mImsResolver.getMmTelFeatureAndListen(slotId, callback);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -4526,12 +4646,11 @@
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            ImsResolver resolver = PhoneFactory.getImsResolver();
-            if (resolver == null) {
+            if (mImsResolver == null) {
                 // may happen if the device does not support IMS.
                 return null;
             }
-            return resolver.getRcsFeatureAndListen(slotId, callback);
+            return mImsResolver.getRcsFeatureAndListen(slotId, callback);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -4546,12 +4665,11 @@
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            ImsResolver resolver = PhoneFactory.getImsResolver();
-            if (resolver == null) {
+            if (mImsResolver == null) {
                 // may happen if the device does not support IMS.
                 return null;
             }
-            return resolver.getImsRegistration(slotId, feature);
+            return mImsResolver.getImsRegistration(slotId, feature);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -4566,12 +4684,11 @@
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            ImsResolver resolver = PhoneFactory.getImsResolver();
-            if (resolver == null) {
+            if (mImsResolver == null) {
                 // may happen if the device does not support IMS.
                 return null;
             }
-            return resolver.getImsConfig(slotId, feature);
+            return mImsResolver.getImsConfig(slotId, feature);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -4580,58 +4697,65 @@
     /**
      * Sets the ImsService Package Name that Telephony will bind to.
      *
-     * @param slotId the slot ID that the ImsService should bind for.
-     * @param isCarrierImsService true if the ImsService is the carrier override, false if the
+     * @param slotIndex the slot ID that the ImsService should bind for.
+     * @param isCarrierService true if the ImsService is the carrier override, false if the
      *         ImsService is the device default ImsService.
-     * @param packageName The package name of the application that contains the ImsService to bind
-     *         to.
+     * @param featureTypes An integer array of feature types associated with a packageName.
+     * @param packageName The name of the package that the current configuration will be replaced
+     *                    with.
      * @return true if setting the ImsService to bind to succeeded, false if it did not.
-     * @hide
      */
-    public boolean setImsService(int slotId, boolean isCarrierImsService, String packageName) {
-        int[] subIds = SubscriptionManager.getSubId(slotId);
+    public boolean setBoundImsServiceOverride(int slotIndex, boolean isCarrierService,
+            int[] featureTypes, String packageName) {
+        int[] subIds = SubscriptionManager.getSubId(slotIndex);
+        TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setBoundImsServiceOverride");
         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
                 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
-                "setImsService");
+                "setBoundImsServiceOverride");
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            ImsResolver resolver = PhoneFactory.getImsResolver();
-            if (resolver == null) {
+            if (mImsResolver == null) {
                 // may happen if the device does not support IMS.
                 return false;
             }
-            return resolver.overrideImsServiceConfiguration(slotId, isCarrierImsService,
-                    packageName);
+            Map<Integer, String> featureConfig = new HashMap<>();
+            for (int featureType : featureTypes) {
+                featureConfig.put(featureType, packageName);
+            }
+            return mImsResolver.overrideImsServiceConfiguration(slotIndex, isCarrierService,
+                    featureConfig);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
     }
 
     /**
-     * Return the ImsService configuration.
+     * Return the package name of the currently bound ImsService.
      *
      * @param slotId The slot that the ImsService is associated with.
      * @param isCarrierImsService true, if the ImsService is a carrier override, false if it is
      *         the device default.
+     * @param featureType The feature associated with the queried configuration.
      * @return the package name of the ImsService configuration.
      */
-    public String getImsService(int slotId, boolean isCarrierImsService) {
+    public String getBoundImsServicePackage(int slotId, boolean isCarrierImsService,
+            @ImsFeature.FeatureType int featureType) {
         int[] subIds = SubscriptionManager.getSubId(slotId);
-        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
-                (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
-                "getImsService");
+        TelephonyPermissions
+                .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
+                mApp, (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
+                "getBoundImsServicePackage");
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            ImsResolver resolver = PhoneFactory.getImsResolver();
-            if (resolver == null) {
+            if (mImsResolver == null) {
                 // may happen if the device does not support IMS.
                 return "";
             }
             // TODO: change API to query RCS separately.
-            return resolver.getImsServiceConfiguration(slotId, isCarrierImsService,
-                    ImsFeature.FEATURE_MMTEL);
+            return mImsResolver.getImsServiceConfiguration(slotId, isCarrierImsService,
+                    featureType);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -4743,13 +4867,15 @@
      * Scans for available networks.
      */
     @Override
-    public CellNetworkScanResult getCellNetworkScanResults(int subId, String callingPackage) {
+    public CellNetworkScanResult getCellNetworkScanResults(int subId, String callingPackage,
+            String callingFeatureId) {
         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
                 mApp, subId, "getCellNetworkScanResults");
         LocationAccessPolicy.LocationPermissionResult locationResult =
                 LocationAccessPolicy.checkLocationPermission(mApp,
                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
                                 .setCallingPackage(callingPackage)
+                                .setCallingFeatureId(callingFeatureId)
                                 .setCallingPid(Binder.getCallingPid())
                                 .setCallingUid(Binder.getCallingUid())
                                 .setMethod("getCellNetworkScanResults")
@@ -4783,13 +4909,14 @@
      */
     @Override
     public int requestNetworkScan(int subId, NetworkScanRequest request, Messenger messenger,
-            IBinder binder, String callingPackage) {
+            IBinder binder, String callingPackage, String callingFeatureId) {
         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
                 mApp, subId, "requestNetworkScan");
         LocationAccessPolicy.LocationPermissionResult locationResult =
                 LocationAccessPolicy.checkLocationPermission(mApp,
                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
                                 .setCallingPackage(callingPackage)
+                                .setCallingFeatureId(callingFeatureId)
                                 .setCallingPid(Binder.getCallingPid())
                                 .setCallingUid(Binder.getCallingUid())
                                 .setMethod("requestNetworkScan")
@@ -4870,10 +4997,10 @@
      * @return the preferred network type, defined in RILConstants.java.
      */
     @Override
-    public int getCalculatedPreferredNetworkType(String callingPackage) {
+    public int getCalculatedPreferredNetworkType(String callingPackage, String callingFeatureId) {
         final Phone defaultPhone = getDefaultPhone();
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
-                callingPackage, "getCalculatedPreferredNetworkType")) {
+                callingPackage, callingFeatureId, "getCalculatedPreferredNetworkType")) {
             return RILConstants.PREFERRED_NETWORK_MODE;
         }
 
@@ -5330,10 +5457,11 @@
     }
 
     @Override
-    public String getLine1NumberForDisplay(int subId, String callingPackage) {
+    public String getLine1NumberForDisplay(int subId, String callingPackage,
+            String callingFeatureId) {
         // This is open to apps with WRITE_SMS.
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
-                mApp, subId, callingPackage, "getLine1NumberForDisplay")) {
+                mApp, subId, callingPackage, callingFeatureId, "getLine1NumberForDisplay")) {
             if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
             return null;
         }
@@ -5357,9 +5485,10 @@
     }
 
     @Override
-    public String getLine1AlphaTagForDisplay(int subId, String callingPackage) {
+    public String getLine1AlphaTagForDisplay(int subId, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getLine1AlphaTagForDisplay")) {
+                mApp, subId, callingPackage, callingFeatureId, "getLine1AlphaTagForDisplay")) {
             return null;
         }
 
@@ -5377,12 +5506,13 @@
     }
 
     @Override
-    public String[] getMergedSubscriberIds(int subId, String callingPackage) {
+    public String[] getMergedSubscriberIds(int subId, String callingPackage,
+            String callingFeatureId) {
         // This API isn't public, so no need to provide a valid subscription ID - we're not worried
         // about carrier-privileged callers not having access.
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
-                "getMergedSubscriberIds")) {
+                callingFeatureId, "getMergedSubscriberIds")) {
             return null;
         }
 
@@ -5487,7 +5617,8 @@
             // Get all subscriberIds from the group.
             final List<String> mergedSubscriberIds = new ArrayList<>();
             final List<SubscriptionInfo> groupInfos = SubscriptionController.getInstance()
-                    .getSubscriptionsInGroup(groupUuid, mApp.getOpPackageName());
+                    .getSubscriptionsInGroup(groupUuid, mApp.getOpPackageName(),
+                            null);
             for (SubscriptionInfo subInfo : groupInfos) {
                 subscriberId = telephonyManager.getSubscriberId(subInfo.getSubscriptionId());
                 if (subscriberId != null) {
@@ -5611,10 +5742,10 @@
     }
 
     @Override
-    public boolean isVideoCallingEnabled(String callingPackage) {
+    public boolean isVideoCallingEnabled(String callingPackage, String callingFeatureId) {
         final Phone defaultPhone = getDefaultPhone();
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, defaultPhone.getSubId(), callingPackage, "isVideoCallingEnabled")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
+                callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
             return false;
         }
 
@@ -5635,9 +5766,11 @@
     }
 
     @Override
-    public boolean canChangeDtmfToneLength(int subId, String callingPackage) {
+    public boolean canChangeDtmfToneLength(int subId, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "isVideoCallingEnabled")) {
+                mApp, subId, callingPackage, callingFeatureId,
+                "isVideoCallingEnabled")) {
             return false;
         }
 
@@ -5653,9 +5786,9 @@
     }
 
     @Override
-    public boolean isWorldPhone(int subId, String callingPackage) {
+    public boolean isWorldPhone(int subId, String callingPackage, String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "isVideoCallingEnabled")) {
+                mApp, subId, callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
             return false;
         }
 
@@ -5725,6 +5858,12 @@
         }
     }
 
+    @Deprecated
+    @Override
+    public String getDeviceId(String callingPackage) {
+        return getDeviceIdWithFeature(callingPackage, null);
+    }
+
     /**
      * Returns the unique device ID of phone, for example, the IMEI for
      * GSM and the MEID for CDMA phones. Return null if device ID is not available.
@@ -5733,14 +5872,14 @@
      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      */
     @Override
-    public String getDeviceId(String callingPackage) {
+    public String getDeviceIdWithFeature(String callingPackage, String callingFeatureId) {
         final Phone phone = PhoneFactory.getPhone(0);
         if (phone == null) {
             return null;
         }
         int subId = phone.getSubId();
         if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
-                callingPackage, "getDeviceId")) {
+                callingPackage, callingFeatureId, "getDeviceId")) {
             return null;
         }
 
@@ -5779,9 +5918,9 @@
 
     @Override
     public int getSubIdForPhoneAccountHandle(
-            PhoneAccountHandle phoneAccountHandle, String callingPackage) {
+            PhoneAccountHandle phoneAccountHandle, String callingPackage, String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, getDefaultSubscription(),
-                callingPackage, "getSubIdForPhoneAccountHandle")) {
+                callingPackage, callingFeatureId, "getSubIdForPhoneAccountHandle")) {
             throw new SecurityException("Requires READ_PHONE_STATE permission.");
         }
         final long identity = Binder.clearCallingIdentity();
@@ -5915,7 +6054,7 @@
         final long identity = Binder.clearCallingIdentity();
         try {
             final SubscriptionInfo info = mSubscriptionController.getActiveSubscriptionInfo(subId,
-                    phone.getContext().getOpPackageName());
+                    phone.getContext().getOpPackageName(), null);
             if (info == null) {
                 log("getSimLocaleForSubscriber, inactive subId: " + subId);
                 return null;
@@ -5939,7 +6078,7 @@
             // exact locale (e.g. fr_FR = French/France). So, if the locale returned from
             // the SIM and carrier preferences does not include a country we add the country
             // determined from the SIM MCC to provide an exact locale.
-            final Locale mccLocale = MccTable.getLocaleFromMcc(mApp, mcc, simLanguage);
+            final Locale mccLocale = LocaleUtils.getLocaleFromMcc(mApp, mcc, simLanguage);
             if (mccLocale != null) {
                 if (DBG) log("No locale from SIM, using mcc locale:" + mccLocale);
                 return mccLocale.toLanguageTag();
@@ -5953,18 +6092,20 @@
     }
 
     private List<SubscriptionInfo> getAllSubscriptionInfoList() {
-        return mSubscriptionController.getAllSubInfoList(mApp.getOpPackageName());
+        return mSubscriptionController.getAllSubInfoList(mApp.getOpPackageName(),
+                null);
     }
 
     /**
      * NOTE: this method assumes permission checks are done and caller identity has been cleared.
      */
     private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
-        return mSubscriptionController.getActiveSubscriptionInfoList(mApp.getOpPackageName());
+        return mSubscriptionController.getActiveSubscriptionInfoList(mApp.getOpPackageName(),
+                null);
     }
 
     private final ModemActivityInfo mLastModemActivityInfo =
-            new ModemActivityInfo(0, 0, 0, new int[0], 0, 0);
+            new ModemActivityInfo(0, 0, 0, new int[0], 0);
 
     /**
      * Responds to the ResultReceiver with the {@link android.telephony.ModemActivityInfo} object
@@ -5988,27 +6129,27 @@
                         null, workSource);
                 if (isModemActivityInfoValid(info)) {
                     int[] mergedTxTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS];
+                    int[] txTimeMs = info.getTransmitTimeMillis();
+                    int[] lastModemTxTimeMs = mLastModemActivityInfo.getTransmitTimeMillis();
                     for (int i = 0; i < mergedTxTimeMs.length; i++) {
-                        mergedTxTimeMs[i] = info.getTxTimeMillis()[i]
-                                + mLastModemActivityInfo.getTxTimeMillis()[i];
+                        mergedTxTimeMs[i] = txTimeMs[i] + lastModemTxTimeMs[i];
                     }
                     mLastModemActivityInfo.setTimestamp(info.getTimestamp());
                     mLastModemActivityInfo.setSleepTimeMillis(info.getSleepTimeMillis()
                             + mLastModemActivityInfo.getSleepTimeMillis());
                     mLastModemActivityInfo.setIdleTimeMillis(
                             info.getIdleTimeMillis() + mLastModemActivityInfo.getIdleTimeMillis());
-                    mLastModemActivityInfo.setTxTimeMillis(mergedTxTimeMs);
-                    mLastModemActivityInfo.setRxTimeMillis(
-                            info.getRxTimeMillis() + mLastModemActivityInfo.getRxTimeMillis());
-                    mLastModemActivityInfo.setEnergyUsed(
-                            info.getEnergyUsed() + mLastModemActivityInfo.getEnergyUsed());
+                    mLastModemActivityInfo.setTransmitTimeMillis(mergedTxTimeMs);
+                    mLastModemActivityInfo.setReceiveTimeMillis(
+                            info.getReceiveTimeMillis() + mLastModemActivityInfo
+                                .getReceiveTimeMillis());
                 }
+
                 ret = new ModemActivityInfo(mLastModemActivityInfo.getTimestamp(),
                         mLastModemActivityInfo.getSleepTimeMillis(),
                         mLastModemActivityInfo.getIdleTimeMillis(),
-                        mLastModemActivityInfo.getTxTimeMillis(),
-                        mLastModemActivityInfo.getRxTimeMillis(),
-                        mLastModemActivityInfo.getEnergyUsed());
+                        mLastModemActivityInfo.getTransmitTimeMillis(),
+                        mLastModemActivityInfo.getReceiveTimeMillis());
             }
             Bundle bundle = new Bundle();
             bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY, ret);
@@ -6027,13 +6168,14 @@
         int activityDurationMs =
             (int) (info.getTimestamp() - mLastModemActivityInfo.getTimestamp());
         int totalTxTimeMs = 0;
-        for (int i = 0; i < info.getTxTimeMillis().length; i++) {
-            totalTxTimeMs += info.getTxTimeMillis()[i];
+        int[] txTimeMs = info.getTransmitTimeMillis();
+        for (int i = 0; i < info.getTransmitPowerInfo().size(); i++) {
+            totalTxTimeMs += txTimeMs[i];
         }
         return (info.isValid()
             && (info.getSleepTimeMillis() <= activityDurationMs)
             && (info.getIdleTimeMillis() <= activityDurationMs)
-            && (info.getRxTimeMillis() <= activityDurationMs)
+            && (info.getReceiveTimeMillis() <= activityDurationMs)
             && (totalTxTimeMs <= activityDurationMs));
     }
 
@@ -6042,9 +6184,10 @@
      * Returns the service state information on specified subscription.
      */
     @Override
-    public ServiceState getServiceStateForSubscriber(int subId, String callingPackage) {
+    public ServiceState getServiceStateForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getServiceStateForSubscriber")) {
+                mApp, subId, callingPackage, callingFeatureId, "getServiceStateForSubscriber")) {
             return null;
         }
 
@@ -6052,6 +6195,7 @@
                 LocationAccessPolicy.checkLocationPermission(mApp,
                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
                                 .setCallingPackage(callingPackage)
+                                .setCallingFeatureId(callingFeatureId)
                                 .setCallingPid(Binder.getCallingPid())
                                 .setCallingUid(Binder.getCallingUid())
                                 .setMethod("getServiceStateForSubscriber")
@@ -6063,6 +6207,7 @@
                 LocationAccessPolicy.checkLocationPermission(mApp,
                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
                                 .setCallingPackage(callingPackage)
+                                .setCallingFeatureId(callingFeatureId)
                                 .setCallingPid(Binder.getCallingPid())
                                 .setCallingUid(Binder.getCallingUid())
                                 .setMethod("getServiceStateForSubscriber")
@@ -6087,8 +6232,8 @@
             // Scrub out the location info in ServiceState depending on what level of access
             // the caller has.
             if (hasFinePermission) return ss;
-            if (hasCoarsePermission) return ss.sanitizeLocationInfo(false);
-            return ss.sanitizeLocationInfo(true);
+            if (hasCoarsePermission) return ss.createLocationInfoSanitizedCopy(false);
+            return ss.createLocationInfoSanitizedCopy(true);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -6592,9 +6737,10 @@
      * @hide
      */
     @Override
-    public List<ClientRequestStats> getClientRequestStats(String callingPackage, int subId) {
+    public List<ClientRequestStats> getClientRequestStats(String callingPackage,
+            String callingFeatureId, int subId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getClientRequestStats")) {
+                mApp, subId, callingPackage, callingFeatureId, "getClientRequestStats")) {
             return null;
         }
         Phone phone = getPhone(subId);
@@ -6705,14 +6851,15 @@
      * Get the current modem radio state for the given slot.
      * @param slotIndex slot index.
      * @param callingPackage the name of the package making the call.
+     * @param callingFeatureId The feature in the package.
      * @return the current radio power state from the modem
      */
     @Override
-    public int getRadioPowerState(int slotIndex, String callingPackage) {
+    public int getRadioPowerState(int slotIndex, String callingPackage, String callingFeatureId) {
         Phone phone = PhoneFactory.getPhone(slotIndex);
         if (phone != null) {
-            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                    mApp, phone.getSubId(), callingPackage, "getRadioPowerState")) {
+            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, phone.getSubId(),
+                    callingPackage, callingFeatureId, "getRadioPowerState")) {
                 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
             }
 
@@ -6786,7 +6933,8 @@
 
     @Override
     public boolean isManualNetworkSelectionAllowed(int subId) {
-        TelephonyPermissions.enforeceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
+        TelephonyPermissions
+                .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
                 mApp, subId, "isManualNetworkSelectionAllowed");
 
         boolean isAllowed = true;
@@ -6994,8 +7142,7 @@
      * Returns false if the mobile data is disabled by default, otherwise return true.
      */
     private boolean getDefaultDataEnabled() {
-        return "true".equalsIgnoreCase(
-                SystemProperties.get(DEFAULT_MOBILE_DATA_PROPERTY_NAME, "true"));
+        return TelephonyProperties.mobile_data().orElse(true);
     }
 
     /**
@@ -7006,8 +7153,7 @@
     private boolean getDefaultDataRoamingEnabled(int subId) {
         final CarrierConfigManager configMgr = (CarrierConfigManager)
                 mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        boolean isDataRoamingEnabled = "true".equalsIgnoreCase(
-                SystemProperties.get(DEFAULT_DATA_ROAMING_PROPERTY_NAME, "false"));
+        boolean isDataRoamingEnabled = TelephonyProperties.data_roaming().orElse(true);
         isDataRoamingEnabled |= configMgr.getConfigForSubId(subId).getBoolean(
                 CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
         return isDataRoamingEnabled;
@@ -7018,11 +7164,12 @@
      * not set, return {@link Phone#PREFERRED_NT_MODE}.
      */
     private int getDefaultNetworkType(int subId) {
-        return Integer.parseInt(
-                TelephonyManager.getTelephonyProperty(
-                        mSubscriptionController.getPhoneId(subId),
-                        DEFAULT_NETWORK_MODE_PROPERTY_NAME,
-                        String.valueOf(Phone.PREFERRED_NT_MODE)));
+        List<Integer> list = TelephonyProperties.default_network();
+        int phoneId = mSubscriptionController.getPhoneId(subId);
+        if (phoneId >= 0 && phoneId < list.size() && list.get(phoneId) != null) {
+            return list.get(phoneId);
+        }
+        return Phone.PREFERRED_NT_MODE;
     }
 
     @Override
@@ -7062,9 +7209,11 @@
     }
 
     @Override
-    public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage) {
+    public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getNumberOfModemsWithSimultaneousDataConnections")) {
+                mApp, subId, callingPackage, callingFeatureId,
+                "getNumberOfModemsWithSimultaneousDataConnections")) {
             return -1;
         }
 
@@ -7117,9 +7266,10 @@
 
     @Override
     public Map<Integer, List<EmergencyNumber>> getEmergencyNumberList(
-            String callingPackage) {
+            String callingPackage, String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, getDefaultSubscription(), callingPackage, "getEmergencyNumberList")) {
+                mApp, getDefaultSubscription(), callingPackage, callingFeatureId,
+                "getEmergencyNumberList")) {
             throw new SecurityException("Requires READ_PHONE_STATE permission.");
         }
         final long identity = Binder.clearCallingIdentity();
@@ -7305,12 +7455,14 @@
      * Whether a modem stack is enabled or not.
      */
     @Override
-    public boolean isModemEnabledForSlot(int slotIndex, String callingPackage) {
+    public boolean isModemEnabledForSlot(int slotIndex, String callingPackage,
+            String callingFeatureId) {
         Phone phone = PhoneFactory.getPhone(slotIndex);
         if (phone == null) return false;
 
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, phone.getSubId(), callingPackage, "isModemEnabledForSlot")) {
+                mApp, phone.getSubId(), callingPackage, callingFeatureId,
+                "isModemEnabledForSlot")) {
             throw new SecurityException("Requires READ_PHONE_STATE permission.");
         }
 
@@ -7342,9 +7494,10 @@
 
     @Override
     @TelephonyManager.IsMultiSimSupportedResult
-    public int isMultiSimSupported(String callingPackage) {
+    public int isMultiSimSupported(String callingPackage, String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp,
-                getDefaultPhone().getSubId(), callingPackage, "isMultiSimSupported")) {
+                getDefaultPhone().getSubId(), callingPackage, callingFeatureId,
+                "isMultiSimSupported")) {
             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
         }
 
@@ -7445,9 +7598,11 @@
      * Return value defaults to true.
      */
     @Override
-    public boolean doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage) {
+    public boolean doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "doesSwitchMultiSimConfigTriggerReboot")) {
+                mApp, subId, callingPackage, callingFeatureId,
+                "doesSwitchMultiSimConfigTriggerReboot")) {
             return false;
         }
         final long identity = Binder.clearCallingIdentity();
@@ -7546,6 +7701,17 @@
     }
 
     @Override
+    public boolean isMvnoMatched(int subId, int mvnoType, @NonNull String mvnoMatchData) {
+        IccRecords iccRecords = UiccController.getInstance().getIccRecords(
+                SubscriptionManager.getPhoneId(subId), UiccController.APP_FAM_3GPP);
+        if (iccRecords == null) {
+            Log.d(LOG_TAG, "isMvnoMatched# IccRecords is null");
+            return false;
+        }
+        return ApnSettingUtils.mvnoMatches(iccRecords, mvnoType, mvnoMatchData);
+    }
+
+    @Override
     public void enqueueSmsPickResult(String callingPackage, IIntegerConsumer pendingSubIdResult) {
         SmsPermissions permissions = new SmsPermissions(getDefaultPhone(), mApp,
                 (AppOpsManager) mApp.getSystemService(Context.APP_OPS_SERVICE));
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index 9835ba1..20a818e 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -31,7 +31,7 @@
 import android.telecom.VideoProfile;
 import android.telephony.CarrierConfigManager;
 import android.telephony.PhoneNumberUtils;
-import android.telephony.Rlog;
+import com.android.telephony.Rlog;
 import android.telephony.SubscriptionManager;
 import android.text.TextUtils;
 import android.util.Log;
@@ -701,7 +701,7 @@
      * {@code false} otherwise.
      */
     public static boolean isPhoneAccountActive(SubscriptionManager sm, PhoneAccountHandle handle) {
-        return sm.getActiveSubscriptionInfoForIccIndex(handle.getId()) != null;
+        return sm.getActiveSubscriptionInfoForIcc(handle.getId()) != null;
     }
 
     private static ComponentName getPstnConnectionServiceName() {
diff --git a/src/com/android/phone/TelephonyShellCommand.java b/src/com/android/phone/TelephonyShellCommand.java
index 0806fd1..53b3356 100644
--- a/src/com/android/phone/TelephonyShellCommand.java
+++ b/src/com/android/phone/TelephonyShellCommand.java
@@ -26,6 +26,7 @@
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.emergency.EmergencyNumber;
+import android.telephony.ims.feature.ImsFeature;
 import android.util.Log;
 
 import com.android.internal.telephony.ITelephony;
@@ -35,6 +36,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.TreeSet;
 
@@ -180,13 +182,15 @@
     private void onHelpIms() {
         PrintWriter pw = getOutPrintWriter();
         pw.println("IMS Commands:");
-        pw.println("  ims set-ims-service [-s SLOT_ID] (-c | -d) PACKAGE_NAME");
+        pw.println("  ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
         pw.println("    Sets the ImsService defined in PACKAGE_NAME to to be the bound");
         pw.println("    ImsService. Options are:");
         pw.println("      -s: the slot ID that the ImsService should be bound for. If no option");
         pw.println("          is specified, it will choose the default voice SIM slot.");
         pw.println("      -c: Override the ImsService defined in the carrier configuration.");
         pw.println("      -d: Override the ImsService defined in the device overlay.");
+        pw.println("      -f: Set the feature that this override if for, if no option is");
+        pw.println("          specified, the new package name will be used for all features.");
         pw.println("  ims get-ims-service [-s SLOT_ID] [-c | -d]");
         pw.println("    Gets the package name of the currently defined ImsService.");
         pw.println("    Options are:");
@@ -194,6 +198,8 @@
         pw.println("          is specified, it will choose the default voice SIM slot.");
         pw.println("      -c: The ImsService defined as the carrier configured ImsService.");
         pw.println("      -c: The ImsService defined as the device default ImsService.");
+        pw.println("      -f: The feature type that the query will be requested for. If none is");
+        pw.println("          specified, the returned package name will correspond to MMTEL.");
         pw.println("  ims enable [-s SLOT_ID]");
         pw.println("    enables IMS for the SIM slot specified, or for the default voice SIM slot");
         pw.println("    if none is specified.");
@@ -444,6 +450,7 @@
         PrintWriter errPw = getErrPrintWriter();
         int slotId = getDefaultSlot();
         Boolean isCarrierService = null;
+        List<Integer> featuresList = new ArrayList<>();
 
         String opt;
         while ((opt = getNextOption()) != null) {
@@ -465,6 +472,26 @@
                     isCarrierService = false;
                     break;
                 }
+                case "-f": {
+                    String featureString = getNextArgRequired();
+                    String[] features = featureString.split(",");
+                    for (int i = 0; i < features.length; i++) {
+                        try {
+                            Integer result = Integer.parseInt(features[i]);
+                            if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
+                                    || result >= ImsFeature.FEATURE_MAX) {
+                                errPw.println("ims set-ims-service -f " + result
+                                        + " is an invalid feature.");
+                                return -1;
+                            }
+                            featuresList.add(result);
+                        } catch (NumberFormatException e) {
+                            errPw.println("ims set-ims-service -f tried to parse " + features[i]
+                                            + " as an integer.");
+                            return -1;
+                        }
+                    }
+                }
             }
         }
         // Mandatory param, either -c or -d
@@ -479,16 +506,24 @@
             if (packageName == null) {
                 packageName = "";
             }
-            boolean result = mInterface.setImsService(slotId, isCarrierService, packageName);
+            int[] featureArray = new int[featuresList.size()];
+            for (int i = 0; i < featuresList.size(); i++) {
+                featureArray[i] = featuresList.get(i);
+            }
+            boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
+                    featureArray, packageName);
             if (VDBG) {
                 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
-                        + (isCarrierService ? "-c " : "-d ") + packageName + ", result=" + result);
+                        + (isCarrierService ? "-c " : "-d ")
+                        + "-f " + featuresList + " "
+                        + packageName + ", result=" + result);
             }
             getOutPrintWriter().println(result);
         } catch (RemoteException e) {
             Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
-                    + (isCarrierService ? "-c " : "-d ") + packageName + ", error"
-                    + e.getMessage());
+                    + (isCarrierService ? "-c " : "-d ")
+                    + "-f " + featuresList + " "
+                    + packageName + ", error" + e.getMessage());
             errPw.println("Exception: " + e.getMessage());
             return -1;
         }
@@ -500,6 +535,7 @@
         PrintWriter errPw = getErrPrintWriter();
         int slotId = getDefaultSlot();
         Boolean isCarrierService = null;
+        Integer featureType = ImsFeature.FEATURE_MMTEL;
 
         String opt;
         while ((opt = getNextOption()) != null) {
@@ -521,23 +557,38 @@
                     isCarrierService = false;
                     break;
                 }
+                case "-f": {
+                    try {
+                        featureType = Integer.parseInt(getNextArg());
+                    } catch (NumberFormatException e) {
+                        errPw.println("ims get-ims-service -f requires valid integer as feature.");
+                        return -1;
+                    }
+                    if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
+                            || featureType >= ImsFeature.FEATURE_MAX) {
+                        errPw.println("ims get-ims-service -f invalid feature.");
+                        return -1;
+                    }
+                }
             }
         }
         // Mandatory param, either -c or -d
         if (isCarrierService == null) {
-            errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
+            errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
             return -1;
         }
 
         String result;
         try {
-            result = mInterface.getImsService(slotId, isCarrierService);
+            result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
         } catch (RemoteException e) {
             return -1;
         }
         if (VDBG) {
             Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
-                    + (isCarrierService ? "-c " : "-d ") + ", returned: " + result);
+                    + (isCarrierService ? "-c " : "-d ")
+                    + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
+                    + result);
         }
         getOutPrintWriter().println(result);
         return 0;
diff --git a/src/com/android/phone/settings/RadioInfo.java b/src/com/android/phone/settings/RadioInfo.java
index ce5b839..77f1135 100644
--- a/src/com/android/phone/settings/RadioInfo.java
+++ b/src/com/android/phone/settings/RadioInfo.java
@@ -111,28 +111,40 @@
     private static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
 
     private static final String[] PREFERRED_NETWORK_LABELS = {
-            "WCDMA preferred",
+            "GSM/WCDMA preferred",
             "GSM only",
             "WCDMA only",
-            "GSM auto (PRL)",
-            "CDMA auto (PRL)",
+            "GSM/WCDMA auto (PRL)",
+            "CDMA/EvDo auto (PRL)",
             "CDMA only",
             "EvDo only",
-            "Global auto (PRL)",
-            "LTE/CDMA auto (PRL)",
-            "LTE/UMTS auto (PRL)",
-            "LTE/CDMA/UMTS auto (PRL)",
+            "CDMA/EvDo/GSM/WCDMA (PRL)",
+            "CDMA + LTE/EvDo (PRL)",
+            "GSM/WCDMA/LTE (PRL)",
+            "LTE/CDMA/EvDo/GSM/WCDMA (PRL)",
             "LTE only",
             "LTE/WCDMA",
-            "TD-SCDMA only",
-            "TD-SCDMA/WCDMA",
-            "LTE/TD-SCDMA",
-            "TD-SCDMA/GSM",
-            "TD-SCDMA/UMTS",
-            "LTE/TD-SCDMA/WCDMA",
-            "LTE/TD-SCDMA/UMTS",
-            "TD-SCDMA/CDMA/UMTS",
-            "Global/TD-SCDMA",
+            "TDSCDMA only",
+            "TDSCDMA/WCDMA",
+            "LTE/TDSCDMA",
+            "TDSCDMA/GSM",
+            "LTE/TDSCDMA/GSM",
+            "TDSCDMA/GSM/WCDMA",
+            "LTE/TDSCDMA/WCDMA",
+            "LTE/TDSCDMA/GSM/WCDMA",
+            "TDSCDMA/CDMA/EvDo/GSM/WCDMA ",
+            "LTE/TDSCDMA/CDMA/EvDo/GSM/WCDMA",
+            "NR only",
+            "NR/LTE",
+            "NR/LTE/CDMA/EvDo",
+            "NR/LTE/GSM/WCDMA",
+            "NR/LTE/CDMA/EvDo/GSM/WCDMA",
+            "NR/LTE/WCDMA",
+            "NR/LTE/TDSCDMA",
+            "NR/LTE/TDSCDMA/GSM",
+            "NR/LTE/TDSCDMA/WCDMA",
+            "NR/LTE/TDSCDMA/GSM/WCDMA",
+            "NR/LTE/TDSCDMA/CDMA/EvDo/GSM/WCDMA",
             "Unknown"
     };
 
diff --git a/src/com/android/phone/settings/fdn/EditFdnContactScreen.java b/src/com/android/phone/settings/fdn/EditFdnContactScreen.java
index 0eda140..140cc74 100644
--- a/src/com/android/phone/settings/fdn/EditFdnContactScreen.java
+++ b/src/com/android/phone/settings/fdn/EditFdnContactScreen.java
@@ -443,7 +443,7 @@
             }
 
             if (v == mNameField) {
-                mNumberField.requestFocus();
+                mButton.requestFocus();
             } else if (v == mNumberField) {
                 mButton.requestFocus();
             } else if (v == mButton) {
diff --git a/src/com/android/phone/settings/fdn/EditPinPreference.java b/src/com/android/phone/settings/fdn/EditPinPreference.java
index 9596f39..a9d1948 100644
--- a/src/com/android/phone/settings/fdn/EditPinPreference.java
+++ b/src/com/android/phone/settings/fdn/EditPinPreference.java
@@ -23,8 +23,6 @@
 import android.util.AttributeSet;
 import android.view.View;
 
-import com.android.phone.R;
-
 /**
  * Class similar to the com.android.settings.EditPinPreference
  * class, with a couple of modifications, including a different layout
@@ -62,27 +60,12 @@
         super(context, attrs, defStyle);
     }
 
-    /**
-     * Overridden to setup the correct dialog layout, as well as setting up
-     * other properties for the pin / puk entry field.
-     */
-    @Override
-    protected View onCreateDialogView() {
-        // set the dialog layout
-        setDialogLayoutResource(R.layout.pref_dialog_editpin);
-
-        View dialog = super.onCreateDialogView();
-
-        getEditText().setInputType(InputType.TYPE_CLASS_NUMBER |
-            InputType.TYPE_NUMBER_VARIATION_PASSWORD);
-
-        return dialog;
-    }
-
     @Override
     protected void onBindDialogView(View view) {
         super.onBindDialogView(view);
 
+        getEditText().setInputType(InputType.TYPE_CLASS_NUMBER
+                | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
         // If the layout does not contain an edittext, hide the buttons.
         shouldHideButtons = (view.findViewById(android.R.id.edit) == null);
     }
diff --git a/src/com/android/services/telephony/ConferenceParticipantConnection.java b/src/com/android/services/telephony/ConferenceParticipantConnection.java
index ed92e7f..ac3928f 100644
--- a/src/com/android/services/telephony/ConferenceParticipantConnection.java
+++ b/src/com/android/services/telephony/ConferenceParticipantConnection.java
@@ -19,7 +19,7 @@
 import android.net.Uri;
 import android.telecom.Connection;
 import android.telecom.DisconnectCause;
-import android.telephony.Rlog;
+import com.android.telephony.Rlog;
 import android.telephony.SubscriptionInfo;
 import android.text.TextUtils;
 
diff --git a/src/com/android/services/telephony/ImsConference.java b/src/com/android/services/telephony/ImsConference.java
index 4c3f9c9..e8386e8 100644
--- a/src/com/android/services/telephony/ImsConference.java
+++ b/src/com/android/services/telephony/ImsConference.java
@@ -30,7 +30,7 @@
 import android.telecom.VideoProfile;
 import android.telephony.CarrierConfigManager;
 import android.telephony.PhoneNumberUtils;
-import android.telephony.Rlog;
+import com.android.telephony.Rlog;
 import android.util.Pair;
 
 import com.android.ims.internal.ConferenceParticipant;
diff --git a/src/com/android/services/telephony/ImsConferenceController.java b/src/com/android/services/telephony/ImsConferenceController.java
index 1e10055..5445cc4 100644
--- a/src/com/android/services/telephony/ImsConferenceController.java
+++ b/src/com/android/services/telephony/ImsConferenceController.java
@@ -22,7 +22,7 @@
 import android.telecom.ConnectionService;
 import android.telecom.DisconnectCause;
 import android.telecom.PhoneAccountHandle;
-import android.telephony.Rlog;
+import com.android.telephony.Rlog;
 
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
diff --git a/src/com/android/services/telephony/PstnIncomingCallNotifier.java b/src/com/android/services/telephony/PstnIncomingCallNotifier.java
index 2dfeaed..b99be81 100644
--- a/src/com/android/services/telephony/PstnIncomingCallNotifier.java
+++ b/src/com/android/services/telephony/PstnIncomingCallNotifier.java
@@ -25,7 +25,7 @@
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
-import android.telephony.Rlog;
+import com.android.telephony.Rlog;
 import android.text.TextUtils;
 
 import com.android.internal.telephony.Call;
diff --git a/src/com/android/services/telephony/RadioOnHelper.java b/src/com/android/services/telephony/RadioOnHelper.java
index 981dc96..116c61d 100644
--- a/src/com/android/services/telephony/RadioOnHelper.java
+++ b/src/com/android/services/telephony/RadioOnHelper.java
@@ -110,6 +110,11 @@
             Settings.Global.putInt(mContext.getContentResolver(),
                     Settings.Global.AIRPLANE_MODE_ON, 0);
 
+            for (Phone phone : PhoneFactory.getPhones()) {
+                Log.d(this, "powerOnRadio, enabling Radio");
+                phone.setRadioPower(true);
+            }
+
             // Post the broadcast intend for change in airplane mode
             // TODO: We really should not be in charge of sending this broadcast.
             // If changing the setting is sufficient to trigger all of the rest of the logic,
diff --git a/src/com/android/services/telephony/RadioOnStateListener.java b/src/com/android/services/telephony/RadioOnStateListener.java
index 52bd9cf..43269b4 100644
--- a/src/com/android/services/telephony/RadioOnStateListener.java
+++ b/src/com/android/services/telephony/RadioOnStateListener.java
@@ -56,6 +56,9 @@
     @VisibleForTesting
     public static final int MSG_SERVICE_STATE_CHANGED = 2;
     private static final int MSG_RETRY_TIMEOUT = 3;
+    @VisibleForTesting
+    public static final int MSG_RADIO_ON = 4;
+    public static final int MSG_RADIO_OFF_OR_NOT_AVAILABLE = 5;
 
     private final Handler mHandler = new Handler(Looper.getMainLooper()) {
         @Override
@@ -75,6 +78,12 @@
                 case MSG_SERVICE_STATE_CHANGED:
                     onServiceStateChanged((ServiceState) ((AsyncResult) msg.obj).result);
                     break;
+                case MSG_RADIO_ON:
+                    onRadioOn();
+                    break;
+                case MSG_RADIO_OFF_OR_NOT_AVAILABLE:
+                    registerForRadioOn();
+                    break;
                 case MSG_RETRY_TIMEOUT:
                     onRetryTimeout();
                     break;
@@ -135,6 +144,9 @@
         mCallback = callback;
 
         registerForServiceStateChanged();
+        // Register for RADIO_OFF to handle cases where emergency call is dialed before
+        // we receive UNSOL_RESPONSE_RADIO_STATE_CHANGED with RADIO_OFF.
+        registerForRadioOff();
         // Next step: when the SERVICE_STATE_CHANGED event comes in, we'll retry the call; see
         // onServiceStateChanged(). But also, just in case, start a timer to make sure we'll retry
         // the call even if the SERVICE_STATE_CHANGED event never comes in for some reason.
@@ -169,6 +181,17 @@
         }
     }
 
+    private void onRadioOn() {
+        ServiceState state =  mPhone.getServiceState();
+        Log.d(this, "onRadioOn, state = %s, Phone = %s", state,
+                mPhone.getPhoneId());
+        if (isOkToCall(state.getState())) {
+            onComplete(true);
+            cleanup();
+        } else {
+            Log.d(this, "onRadioOn: not ready to call yet, keep waiting.");
+        }
+    }
     /**
      * Callback to see if it is okay to call yet, given the current conditions.
      */
@@ -239,6 +262,8 @@
         onComplete(false);
 
         unregisterForServiceStateChanged();
+        unregisterForRadioOff();
+        unregisterForRadioOn();
         cancelRetryTimer();
 
         // Used for unregisterForServiceStateChanged() so we null it out here instead.
@@ -271,6 +296,31 @@
         mHandler.removeMessages(MSG_SERVICE_STATE_CHANGED);  // Clean up any pending messages too
     }
 
+    private void registerForRadioOff() {
+        mPhone.mCi.registerForOffOrNotAvailable(mHandler, MSG_RADIO_OFF_OR_NOT_AVAILABLE, null);
+    }
+
+    private void unregisterForRadioOff() {
+        // This method is safe to call even if we haven't set mPhone yet.
+        if (mPhone != null) {
+            mPhone.mCi.unregisterForOffOrNotAvailable(mHandler);  // Safe even if unnecessary
+        }
+        mHandler.removeMessages(MSG_RADIO_OFF_OR_NOT_AVAILABLE);  // Clean up any pending messages
+    }
+
+    private void registerForRadioOn() {
+        unregisterForRadioOff();
+        mPhone.mCi.registerForOn(mHandler, MSG_RADIO_ON, null);
+    }
+
+    private void unregisterForRadioOn() {
+        // This method is safe to call even if we haven't set mPhone yet.
+        if (mPhone != null) {
+            mPhone.mCi.unregisterForOn(mHandler);  // Safe even if unnecessary
+        }
+        mHandler.removeMessages(MSG_RADIO_ON);  // Clean up any pending messages too
+    }
+
     private void onComplete(boolean isRadioReady) {
         if (mCallback != null) {
             Callback tempCallback = mCallback;
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index 5a1e6a6..90512b6 100644
--- a/src/com/android/services/telephony/TelecomAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecomAccountRegistry.java
@@ -41,7 +41,7 @@
 import android.telecom.TelecomManager;
 import android.telephony.CarrierConfigManager;
 import android.telephony.PhoneStateListener;
-import android.telephony.Rlog;
+import com.android.telephony.Rlog;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index fb865b4..7d7b72b 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -37,12 +37,12 @@
 import android.telecom.StatusHints;
 import android.telecom.TelecomManager;
 import android.telecom.VideoProfile;
-import android.telephony.Annotation.RilRadioTechnology;
 import android.telephony.CarrierConfigManager;
 import android.telephony.DisconnectCause;
 import android.telephony.PhoneNumberUtils;
-import android.telephony.Rlog;
+import com.android.telephony.Rlog;
 import android.telephony.ServiceState;
+import android.telephony.ServiceState.RilRadioTechnology;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.ims.ImsCallProfile;
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 3340302..bac4793 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -662,7 +662,7 @@
                         // been powered on and isn't in the UNAVAILABLE state, even if it is
                         // reporting the OUT_OF_SERVICE state.
                         return (phone.getState() == PhoneConstants.State.OFFHOOK)
-                            || phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
+                            || phone.getServiceStateTracker().isRadioOn();
                     } else {
                         // Wait until we are in service and ready to make calls. This can happen
                         // when we power down the radio on bluetooth to save power on watches or if
@@ -816,7 +816,8 @@
             // TODO: Switch out the underlying connection instead of creating a new
             // one and causing UI Jank.
             boolean noActiveSimCard = SubscriptionController.getInstance()
-                    .getActiveSubInfoCount(phone.getContext().getOpPackageName()) == 0;
+                    .getActiveSubInfoCount(phone.getContext().getOpPackageName(),
+                            null) == 0;
             // If there's no active sim card and the device is in emergency mode, use E account.
             addExistingConnection(mPhoneUtilsProxy.makePstnPhoneAccountHandleWithPrefix(
                     phone, "", isEmergencyNumber && noActiveSimCard), repConnection);
diff --git a/tests/src/com/android/services/telephony/RadioOnStateListenerTest.java b/tests/src/com/android/services/telephony/RadioOnStateListenerTest.java
index 8b46bf0..afdfab5 100644
--- a/tests/src/com/android/services/telephony/RadioOnStateListenerTest.java
+++ b/tests/src/com/android/services/telephony/RadioOnStateListenerTest.java
@@ -34,6 +34,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.TelephonyTestBase;
+import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
 
@@ -55,6 +56,7 @@
 
     @Mock Phone mMockPhone;
     @Mock RadioOnStateListener.Callback mCallback;
+    @Mock CommandsInterface mMockCi;
     RadioOnStateListener mListener;
 
     @Override
@@ -80,6 +82,7 @@
     @Test
     @SmallTest
     public void testRegisterForCallback() {
+        mMockPhone.mCi = mMockCi;
         mListener.waitForRadioOn(mMockPhone, mCallback);
 
         waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
@@ -87,6 +90,9 @@
         verify(mMockPhone).unregisterForServiceStateChanged(any(Handler.class));
         verify(mMockPhone).registerForServiceStateChanged(any(Handler.class),
                 eq(RadioOnStateListener.MSG_SERVICE_STATE_CHANGED), isNull());
+
+        verify(mMockCi).registerForOffOrNotAvailable(any(Handler.class),
+                eq(RadioOnStateListener.MSG_RADIO_OFF_OR_NOT_AVAILABLE), isNull());
     }
 
     /**
@@ -101,6 +107,7 @@
         state.setState(ServiceState.STATE_IN_SERVICE);
         when(mMockPhone.getState()).thenReturn(PhoneConstants.State.IDLE);
         when(mCallback.isOkToCall(eq(mMockPhone), anyInt())).thenReturn(true);
+        mMockPhone.mCi = mMockCi;
         mListener.waitForRadioOn(mMockPhone, mCallback);
         waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
 
@@ -124,6 +131,7 @@
         when(mMockPhone.getState()).thenReturn(PhoneConstants.State.IDLE);
         when(mCallback.isOkToCall(eq(mMockPhone), anyInt())).thenReturn(false);
         when(mMockPhone.getServiceState()).thenReturn(state);
+        mMockPhone.mCi = mMockCi;
         mListener.waitForRadioOn(mMockPhone, mCallback);
         waitForHandlerAction(mListener.getHandler(), TIMEOUT_MS);
 
@@ -152,6 +160,7 @@
         mListener.setMaxNumRetries(2);
 
         // Wait for the timer to expire and check state manually in onRetryTimeout
+        mMockPhone.mCi = mMockCi;
         mListener.waitForRadioOn(mMockPhone, mCallback);
         waitForHandlerActionDelayed(mListener.getHandler(), TIMEOUT_MS, TIMEOUT_MS /*delay*/);