Merge "Do not use notifyAsUser or cancelAsUser" am: 6f999ea9d2 am: d43187494c
am: e48b34ae63

Change-Id: Ib3c0330b3a24503b42ccbd14e707d5e2babe27c0
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 938d714..f744bdf 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -62,6 +62,7 @@
     <protected-broadcast android:name= "com.android.internal.telephony.CARRIER_SIGNAL_RESET" />
     <protected-broadcast android:name= "com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE" />
     <protected-broadcast android:name= "com.android.internal.telephony.ACTION_LINE1_NUMBER_ERROR_DETECTED" />
+    <protected-broadcast android:name= "com.android.internal.telephony.ACTION_REPORT_RADIO_BUG" />
     <protected-broadcast android:name= "com.android.internal.provider.action.VOICEMAIL_SMS_RECEIVED" />
     <protected-broadcast android:name= "com.android.intent.isim_refresh" />
     <protected-broadcast android:name= "com.android.ims.ACTION_RCS_SERVICE_AVAILABLE" />
diff --git a/assets/eri_311480_BA01450000000000.xml b/assets/eri_311480_BA01450000000000.xml
new file mode 100644
index 0000000..ea18c73
--- /dev/null
+++ b/assets/eri_311480_BA01450000000000.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** 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.
+*/
+-->
+
+<!-- Note that IconMode can be only 0, ON or 1, FLASHING
+     The icon is turned OFF if then IconIndex = 1 -->
+
+<EriFile VersionNumber="7"
+    NumberOfEriEntries="7"
+    EriFileType="2">
+
+  <CallPromptId Id="0"
+      CallPromptText="CallPromptId0"/>
+
+  <CallPromptId Id="1"
+      CallPromptText="CallPromptId1"/>
+
+  <CallPromptId Id="2"
+      CallPromptText="CallPromptId2"/>
+
+  <EriInfo RoamingIndicator="64"
+      IconIndex="1"
+      IconMode="0"
+      EriText="Xfinity Mobile"
+      CallPromptId="0"
+      AlertId="0"
+      DataServiceSupport="1"/>
+
+  <EriInfo RoamingIndicator="65"
+      IconIndex="1"
+      IconMode="0"
+      EriText="Xfinity Mobile"
+      CallPromptId="0"
+      AlertId="0"
+      DataServiceSupport="1"/>
+
+  <EriInfo RoamingIndicator="66"
+      IconIndex="1"
+      IconMode="0"
+      EriText="Extended Network"
+      CallPromptId="0"
+      AlertId="4"
+      DataServiceSupport="0"/>
+
+  <EriInfo RoamingIndicator="67"
+      IconIndex="0"
+      IconMode="0"
+      EriText="Extended Network"
+      CallPromptId="0"
+      AlertId="4"
+      DataServiceSupport="0"/>
+
+  <EriInfo RoamingIndicator="68"
+      IconIndex="0"
+      IconMode="0"
+      EriText="Roaming"
+      CallPromptId="0"
+      AlertId="5"
+      DataServiceSupport="0"/>
+
+  <EriInfo RoamingIndicator="69"
+      IconIndex="2"
+      IconMode="0"
+      EriText="Extended Network"
+      CallPromptId="0"
+      AlertId="4"
+      DataServiceSupport="0"/>
+
+  <EriInfo RoamingIndicator="70"
+      IconIndex="2"
+      IconMode="0"
+      EriText="Roaming"
+      CallPromptId="0"
+      AlertId="5"
+      DataServiceSupport="0"/>
+
+</EriFile>
diff --git a/ecc/input/eccdata.txt b/ecc/input/eccdata.txt
index bf5d92c..403cad7 100644
--- a/ecc/input/eccdata.txt
+++ b/ecc/input/eccdata.txt
@@ -600,11 +600,8 @@
 countries {
   iso_code: "DE"
   eccs {
-    phone_number: "110"
-    types: POLICE
-  }
-  eccs {
     phone_number: "112"
+    types: POLICE
     types: AMBULANCE
     types: FIRE
   }
diff --git a/ecc/output/eccdata b/ecc/output/eccdata
index 2b9007a..917273d 100644
--- a/ecc/output/eccdata
+++ b/ecc/output/eccdata
Binary files differ
diff --git a/res/drawable/btn_emergency_information.xml b/res/drawable/btn_emergency_information.xml
index 29b4a7a..cd57bd3 100644
--- a/res/drawable/btn_emergency_information.xml
+++ b/res/drawable/btn_emergency_information.xml
@@ -16,7 +16,7 @@
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
     <corners android:radius="8dp"/>
-    <!-- White, Opacity 16% -->
+    <solid android:color="@color/emergency_info_btn_background_color"/>
     <stroke android:width="1dp"
-            android:color="#40FFFFFF"/>
-</shape>
\ No newline at end of file
+            android:color="@color/emergency_info_btn_bolder"/>
+</shape>
diff --git a/res/drawable/btn_emergency_shortcuts.xml b/res/drawable/btn_emergency_shortcuts.xml
index 449e4e0..9717e81 100644
--- a/res/drawable/btn_emergency_shortcuts.xml
+++ b/res/drawable/btn_emergency_shortcuts.xml
@@ -17,4 +17,4 @@
        android:shape="rectangle">
     <corners android:radius="8dp"/>
     <solid android:color="@color/emergency_shortcut_button_background_color"/>
-</shape>
\ No newline at end of file
+</shape>
diff --git a/res/drawable/ic_sim_card.xml b/res/drawable/ic_sim_card.xml
new file mode 100644
index 0000000..f563d23
--- /dev/null
+++ b/res/drawable/ic_sim_card.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Copyright (C) 2019 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+<path
+    android:fillColor="#757575"
+    android:pathData="M18,2h-8L4.02,8 4,20c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,4c0,-1.1 -0.9,-2 -2,-2zM13,17h-2v-2h2v2zM13,13h-2L11,8h2v5z"/>
+</vector>
diff --git a/res/drawable/phone_type_icon_background.xml b/res/drawable/phone_type_icon_background.xml
index b51c3b2..352db2e 100644
--- a/res/drawable/phone_type_icon_background.xml
+++ b/res/drawable/phone_type_icon_background.xml
@@ -15,5 +15,5 @@
 -->
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="oval">
-    <solid android:color="@color/emergency_shortcut_confirm_button_background_color"/>
-</shape>
\ No newline at end of file
+    <solid android:color="@color/emergency_shortcut_phone_type_icon_color"/>
+</shape>
diff --git a/res/layout/emergency_dialer.xml b/res/layout/emergency_dialer.xml
index 6247379..bea01fe 100644
--- a/res/layout/emergency_dialer.xml
+++ b/res/layout/emergency_dialer.xml
@@ -46,7 +46,9 @@
                 android:layout_height="@dimen/dialpad_button_height"
                 android:background="@drawable/floating_action_button_red"
                 android:contentDescription="@string/description_dialpad_button"
-                android:src="@drawable/ic_dialpad_white_24"/>
+                android:src="@drawable/ic_dialpad_white_24"
+                android:scaleType="centerInside"
+                android:backgroundTint="@color/emergency_dialpad_fab_tint_color"/>
         </FrameLayout>
     </FrameLayout>
 
diff --git a/res/layout/emergency_information.xml b/res/layout/emergency_information.xml
index 524387f..3ed1748 100644
--- a/res/layout/emergency_information.xml
+++ b/res/layout/emergency_information.xml
@@ -19,7 +19,8 @@
     android:layout_height="@dimen/emergency_info_button_height"
     android:layout_width="match_parent"
     android:layout_marginHorizontal="@dimen/emergency_shortcut_buttons_margin_horizontal"
-    android:layout_marginVertical="@dimen/emergency_info_button_margin_vertical">
+    android:layout_marginTop="@dimen/emergency_info_button_margin_top"
+    android:layout_marginBottom="@dimen/emergency_info_button_margin_bottom">
     <FrameLayout
         android:id="@+id/emergency_info_view"
         android:layout_height="match_parent"
@@ -38,7 +39,7 @@
                 android:layout_marginEnd="@dimen/emergency_dialer_image_margin_end"
                 android:layout_height="@dimen/emergency_info_image_height"
                 android:layout_width="@dimen/emergency_info_image_width"
-                android:scaleType="centerCrop"/>
+                android:scaleType="centerInside"/>
             <LinearLayout
                 android:layout_height="wrap_content"
                 android:layout_width="match_parent"
@@ -53,8 +54,7 @@
                     android:maxLines="1"
                     android:ellipsize="end"
                     android:lineHeight="@dimen/emergency_info_name_line_height"
-                    android:fontFamily="@*android:string/config_headlineFontFamily"
-                    android:textAppearance="@style/HeadlineTextAppearance"/>
+                    android:textAppearance="@style/EmergencyInfoNameTextAppearance"/>
                 <TextView
                     android:id="@+id/emergency_info_hint"
                     android:layout_height="wrap_content"
@@ -62,8 +62,7 @@
                     android:maxLines="2"
                     android:ellipsize="end"
                     android:lineHeight="@dimen/emergency_info_hint_line_height"
-                    android:alpha="0.7"
-                    android:textAppearance="@style/SubtitleTextAppearance"
+                    android:textAppearance="@style/EmergencyInfoHintTextAppearance"
                     android:text="@string/emergency_information_hint"/>
             </LinearLayout>
         </LinearLayout>
@@ -88,7 +87,7 @@
                 android:layout_width="@dimen/emergency_info_image_width"
                 android:layout_marginStart="@dimen/emergency_dialer_image_margin_start"
                 android:layout_marginEnd="@dimen/emergency_dialer_image_margin_end"
-                android:scaleType="centerCrop"/>
+                android:scaleType="centerInside"/>
             <TextView
                 android:id="@+id/confirmed_emergency_info"
                 android:layout_height="wrap_content"
@@ -99,8 +98,7 @@
                 android:maxLines="2"
                 android:ellipsize="end"
                 android:lineHeight="@dimen/confirmed_emergency_info_line_height"
-                android:fontFamily="@*android:string/config_headlineFontFamily"
-                android:textAppearance="@style/PhoneCallHintTextAppearance"
+                android:textAppearance="@style/EmergencyInfoTapHintTextAppearance"
                 android:text="@string/emergency_information_confirm_hint"/>
         </LinearLayout>
     </FrameLayout>
diff --git a/res/layout/emergency_shortcut_button.xml b/res/layout/emergency_shortcut_button.xml
index 3c5eaa2..ce4d60e 100644
--- a/res/layout/emergency_shortcut_button.xml
+++ b/res/layout/emergency_shortcut_button.xml
@@ -16,7 +16,8 @@
 <com.android.phone.EmergencyShortcutButton
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_height="@dimen/emergency_shortcut_button_height"
-    android:layout_width="match_parent">
+    android:layout_width="match_parent"
+    android:layout_marginBottom="@dimen/emergency_shortcut_button_margin_bottom">
     <!-- Normal emergency call button view -->
     <FrameLayout
         android:id="@+id/emergency_call_number_info_view"
@@ -42,7 +43,8 @@
                     android:id="@+id/phone_type_icon"
                     android:layout_width="@dimen/phone_number_type_image_height"
                     android:layout_height="@dimen/phone_number_type_image_width"
-                    android:layout_gravity="center"/>
+                    android:layout_gravity="center"
+                    android:scaleType="centerInside"/>
             </FrameLayout>
             <LinearLayout
                 android:layout_height="wrap_content"
@@ -57,7 +59,6 @@
                     android:maxLines="1"
                     android:ellipsize="end"
                     android:lineHeight="@dimen/phone_number_line_height"
-                    android:fontFamily="@*android:string/config_headlineFontFamily"
                     android:textAppearance="@style/PhoneNumberTextAppearance"/>
                 <TextView
                     android:id="@+id/phone_number_description"
@@ -66,8 +67,7 @@
                     android:alpha="0.7"
                     android:maxLines="1"
                     android:ellipsize="end"
-                    android:fontFamily="sans-serif-medium"
-                    android:textAppearance="@style/SubtitleTextAppearance"/>
+                    android:textAppearance="@style/PhoneNumberTypeAppearance"/>
             </LinearLayout>
         </LinearLayout>
         <FrameLayout
@@ -79,7 +79,9 @@
                 android:id="@+id/microphone_icon"
                 android:layout_height="@dimen/phone_icon_height"
                 android:layout_width="@dimen/phone_icon_width"
-                android:src="@drawable/ic_emergency_callback_mode"/>
+                android:src="@drawable/ic_emergency_callback_mode"
+                android:tint="@color/emergency_call_icon_color"
+                android:scaleType="centerInside"/>
         </FrameLayout>
     </FrameLayout>
 
@@ -111,6 +113,7 @@
                     android:layout_width="@dimen/phone_number_type_image_height"
                     android:layout_height="@dimen/phone_number_type_image_width"
                     android:layout_gravity="center"
+                    android:scaleType="centerInside"
                     android:tint="@color/emergency_shortcut_confirm_button_background_color"/>
             </FrameLayout>
             <FrameLayout
@@ -124,8 +127,7 @@
                     android:maxLines="2"
                     android:ellipsize="end"
                     android:lineHeight="@dimen/phone_call_hint_line_height"
-                    android:fontFamily="@*android:string/config_headlineFontFamily"
-                    android:textAppearance="@style/PhoneCallHintTextAppearance"/>
+                    android:textAppearance="@style/PhoneNumberTapHintAppearance"/>
             </FrameLayout>
         </LinearLayout>
         <FrameLayout
@@ -137,7 +139,9 @@
             <ImageView
                 android:layout_height="@dimen/phone_icon_height"
                 android:layout_width="@dimen/phone_icon_width"
-                android:src="@drawable/ic_emergency_callback_mode"/>
+                android:src="@drawable/ic_emergency_callback_mode"
+                android:tint="@color/emergency_call_icon_color"
+                android:scaleType="centerInside"/>
         </FrameLayout>
     </FrameLayout>
 </com.android.phone.EmergencyShortcutButton>
diff --git a/res/layout/emergency_shortcut_buttons_group.xml b/res/layout/emergency_shortcut_buttons_group.xml
index 54563c9..8e2c256 100644
--- a/res/layout/emergency_shortcut_buttons_group.xml
+++ b/res/layout/emergency_shortcut_buttons_group.xml
@@ -37,8 +37,7 @@
                 android:maxLines="2"
                 android:ellipsize="end"
                 android:lineHeight="@dimen/emergency_number_title_line_height"
-                android:fontFamily="sans-serif-medium"
-                android:textColor="@android:color/white"
+                android:textAppearance="@style/ShortcutViewHintTextAppearance"
                 android:textSize="@dimen/emergency_number_title_text_size"
                 android:text="@string/single_emergency_number_title"/>
         </FrameLayout>
@@ -49,13 +48,13 @@
             android:layout_marginStart="@dimen/emergency_number_title_container_width"
             android:layout_gravity="center_vertical|end"
             android:gravity="center_vertical"
-            android:orientation="horizontal"
-            android:alpha="0.7">
+            android:orientation="horizontal">
             <ImageView
                 android:id="@+id/location_icon"
                 android:layout_width="@dimen/location_image_width"
                 android:layout_height="@dimen/location_image_height"
-                android:src="@drawable/place_gm2_24px"/>
+                android:src="@drawable/place_gm2_24px"
+                android:scaleType="centerInside"/>
             <TextView
                 android:id="@+id/location_text"
                 android:layout_height="wrap_content"
@@ -64,7 +63,7 @@
                 android:maxLines="2"
                 android:ellipsize="end"
                 android:lineHeight="@dimen/location_text_line_height"
-                android:textColor="@android:color/white"
+                android:textAppearance="@style/ShortcutViewHintTextAppearance"
                 android:textSize="@dimen/emergency_location_text_size"/>
         </LinearLayout>
     </FrameLayout>
@@ -73,8 +72,6 @@
         android:layout_height="wrap_content"
         android:layout_width="match_parent"
         android:layout_marginHorizontal="@dimen/emergency_shortcut_buttons_margin_horizontal"
-        android:orientation="vertical"
-        android:divider="@drawable/emergency_shortcuts_divider"
-        android:showDividers="middle">
+        android:orientation="vertical">
     </LinearLayout>
 </LinearLayout>
diff --git a/res/values-h535dp/dimens.xml b/res/values-h535dp/dimens.xml
new file mode 100644
index 0000000..c3b2341
--- /dev/null
+++ b/res/values-h535dp/dimens.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+
+<resources>
+    <!-- Height and vertical margin for the emergency information button. -->
+    <dimen name="emergency_info_button_height">80dp</dimen>
+    <dimen name="emergency_info_button_margin_top">35dp</dimen>
+    <dimen name="emergency_info_button_margin_bottom">40dp</dimen>
+
+    <!-- The text size of emergency info name and hint -->
+    <dimen name="emergency_info_name_text_size">18.3sp</dimen>
+    <dimen name="emergency_info_hint_text_size">13.3sp</dimen>
+    <dimen name="emergency_info_tap_hint_text_size">15sp</dimen>
+
+    <!-- The height for title of emergency number and location info. -->
+    <dimen name="emergency_number_title_height">40dp</dimen>
+    <!-- The text size for emergency number title.-->
+    <dimen name="emergency_number_title_text_size">11.6sp</dimen>
+
+    <!-- The height and width for the image of location info.-->
+    <dimen name="location_image_height">13.3dp</dimen>
+    <dimen name="location_image_width">13.3dp</dimen>
+
+    <!-- The text size for emergency location.-->
+    <dimen name="emergency_location_text_size">11.6sp</dimen>
+
+    <!-- The height and margin for button of emergency shortcut. -->
+    <dimen name="emergency_shortcut_button_height">80dp</dimen>
+    <dimen name="emergency_shortcut_button_margin_bottom">6.7dp</dimen>
+
+    <!-- The text size of emergency number, type and hint -->
+    <dimen name="emergency_shortcut_number_text_size">27sp</dimen>
+    <dimen name="emergency_shortcut_type_text_size">11.6sp</dimen>
+    <dimen name="emergency_shortcut_tap_hint_text_size">15sp</dimen>
+
+    <!-- The height and width for the image of phone number type.-->
+    <dimen name="phone_number_type_image_height">33dp</dimen>
+    <dimen name="phone_number_type_image_width">33dp</dimen>
+
+    <!-- The height and width of phone icon.-->
+    <dimen name="phone_icon_height">20dp</dimen>
+    <dimen name="phone_icon_width">20dp</dimen>
+
+    <!-- Margin of dialpad button -->
+    <dimen name="emergency_dialer_dialpad_button_margin">27dp</dimen>
+
+    <!-- The height and width for the dialpad button -->
+    <dimen name="dialpad_button_height">47dp</dimen>
+    <dimen name="dialpad_button_width">47dp</dimen>
+</resources>
diff --git a/res/values-h590dp/dimens.xml b/res/values-h590dp/dimens.xml
new file mode 100644
index 0000000..3684f4c
--- /dev/null
+++ b/res/values-h590dp/dimens.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+
+<resources>
+    <!-- Height and vertical margin for the emergency information button. -->
+    <dimen name="emergency_info_button_height">87dp</dimen>
+    <dimen name="emergency_info_button_margin_top">44dp</dimen>
+    <dimen name="emergency_info_button_margin_bottom">44dp</dimen>
+
+    <!-- The text size of emergency info name and hint -->
+    <dimen name="emergency_info_name_text_size">20sp</dimen>
+    <dimen name="emergency_info_hint_text_size">14.5sp</dimen>
+    <dimen name="emergency_info_tap_hint_text_size">16.4sp</dimen>
+
+    <!-- The height for title of emergency number and location info. -->
+    <dimen name="emergency_number_title_height">44dp</dimen>
+    <!-- The text size for emergency number title.-->
+    <dimen name="emergency_number_title_text_size">12.7sp</dimen>
+
+    <!-- The height and width for the image of location info.-->
+    <dimen name="location_image_height">14.5dp</dimen>
+    <dimen name="location_image_width">14.5dp</dimen>
+
+    <!-- The text size for emergency location.-->
+    <dimen name="emergency_location_text_size">12.7sp</dimen>
+
+    <!-- The height and margin for button of emergency shortcut. -->
+    <dimen name="emergency_shortcut_button_height">87dp</dimen>
+    <dimen name="emergency_shortcut_button_margin_bottom">7.3dp</dimen>
+
+    <!-- The text size of emergency number, type and hint -->
+    <dimen name="emergency_shortcut_number_text_size">29sp</dimen>
+    <dimen name="emergency_shortcut_type_text_size">12.7sp</dimen>
+    <dimen name="emergency_shortcut_tap_hint_text_size">16.4sp</dimen>
+
+    <!-- The height and width for the image of phone number type.-->
+    <dimen name="phone_number_type_image_height">36dp</dimen>
+    <dimen name="phone_number_type_image_width">36dp</dimen>
+
+    <!-- The height and width of phone icon.-->
+    <dimen name="phone_icon_height">22dp</dimen>
+    <dimen name="phone_icon_width">22dp</dimen>
+
+    <!-- Margin of dialpad button -->
+    <dimen name="emergency_dialer_dialpad_button_margin">29dp</dimen>
+
+    <!-- The height and width for the dialpad button -->
+    <dimen name="dialpad_button_height">51dp</dimen>
+    <dimen name="dialpad_button_width">51dp</dimen>
+</resources>
diff --git a/res/values-h720dp/dimens.xml b/res/values-h720dp/dimens.xml
new file mode 100644
index 0000000..7bb1f27
--- /dev/null
+++ b/res/values-h720dp/dimens.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+
+<resources>
+    <!-- Height and vertical margin for the emergency information button. -->
+    <dimen name="emergency_info_button_height">96dp</dimen>
+    <dimen name="emergency_info_button_margin_top">72dp</dimen>
+    <dimen name="emergency_info_button_margin_bottom">60dp</dimen>
+
+    <!-- The text size of emergency info name and hint -->
+    <dimen name="emergency_info_name_text_size">22sp</dimen>
+    <dimen name="emergency_info_hint_text_size">16sp</dimen>
+    <dimen name="emergency_info_tap_hint_text_size">18sp</dimen>
+
+    <!-- The height for title of emergency number and location info. -->
+    <dimen name="emergency_number_title_height">48dp</dimen>
+    <!-- The text size for emergency number title.-->
+    <dimen name="emergency_number_title_text_size">14sp</dimen>
+
+    <!-- The height and width for the image of location info.-->
+    <dimen name="location_image_height">16dp</dimen>
+    <dimen name="location_image_width">16dp</dimen>
+
+    <!-- The text size for emergency location.-->
+    <dimen name="emergency_location_text_size">14sp</dimen>
+
+    <!-- The height and margin for button of emergency shortcut. -->
+    <dimen name="emergency_shortcut_button_height">96dp</dimen>
+    <dimen name="emergency_shortcut_button_margin_bottom">8dp</dimen>
+
+    <!-- The text size of emergency number, type and hint -->
+    <dimen name="emergency_shortcut_number_text_size">32sp</dimen>
+    <dimen name="emergency_shortcut_type_text_size">14sp</dimen>
+    <dimen name="emergency_shortcut_tap_hint_text_size">18sp</dimen>
+
+    <!-- The height and width for the image of phone number type.-->
+    <dimen name="phone_number_type_image_height">40dp</dimen>
+    <dimen name="phone_number_type_image_width">40dp</dimen>
+
+    <!-- The height and width of phone icon.-->
+    <dimen name="phone_icon_height">24dp</dimen>
+    <dimen name="phone_icon_width">24dp</dimen>
+
+    <!-- Margin of dialpad button -->
+    <dimen name="emergency_dialer_dialpad_button_margin">64dp</dimen>
+
+    <!-- The height and width for the dialpad button -->
+    <dimen name="dialpad_button_height">56dp</dimen>
+    <dimen name="dialpad_button_width">56dp</dimen>
+</resources>
diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml
new file mode 100644
index 0000000..1f336b9
--- /dev/null
+++ b/res/values-night/colors.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+
+<resources>
+
+    <!-- Colors for shortcut view -->
+    <color name="emergency_info_btn_bolder">#85ffffff</color>
+    <color name="emergency_info_btn_background_color">#202124</color>
+    <color name="emergency_shortcut_button_background_color">#202124</color>
+    <color name="emergency_shortcut_phone_type_icon_color">#f28b82</color>
+    <color name="emergency_shortcut_confirm_button_background_color">#3c4043</color>
+    <color name="emergency_shortcut_confirm_phone_type_icon_color">#f28b82</color>
+    <color name="emergency_call_icon_color">#e8eaed</color>
+    <color name="emergency_dialpad_fab_tint_color">#f28b82</color>
+</resources>
diff --git a/res/values-night/styles.xml b/res/values-night/styles.xml
index 648ceeb..fa5c8a1 100644
--- a/res/values-night/styles.xml
+++ b/res/values-night/styles.xml
@@ -27,4 +27,44 @@
         <item name="android:dialogTheme">@style/DialerAlertDialogTheme</item>
     </style>
 
+    <style name="EmergencyInfoNameTextAppearance">
+        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+        <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>
+        <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>
+        <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/white</item>
+    </style>
+
+    <style name="PhoneNumberTextAppearance">
+        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+        <item name="android:textColor">@android:color/white</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">@color/white_70_percent</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>
+        <item name="android:textColor">@android:color/white</item>
+        <item name="android:textSize">@dimen/emergency_shortcut_tap_hint_text_size</item>
+    </style>
 </resources>
diff --git a/res/values-sw345dp/dimens.xml b/res/values-sw345dp/dimens.xml
deleted file mode 100644
index 84db80b..0000000
--- a/res/values-sw345dp/dimens.xml
+++ /dev/null
@@ -1,24 +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
-  -->
-
-<resources>
-    <dimen name="emergency_info_button_height">88dp</dimen>
-    <dimen name="emergency_info_button_margin_vertical">48dp</dimen>
-    <dimen name="emergency_shortcut_button_height">88dp</dimen>
-    <dimen name="emergency_number_title_text_size">12sp</dimen>
-    <dimen name="emergency_location_text_size">12sp</dimen>
-</resources>
\ No newline at end of file
diff --git a/res/values-sw360dp/dimens.xml b/res/values-sw360dp/dimens.xml
deleted file mode 100644
index c578065..0000000
--- a/res/values-sw360dp/dimens.xml
+++ /dev/null
@@ -1,24 +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
-  -->
-
-<resources>
-    <dimen name="emergency_info_button_height">96dp</dimen>
-    <dimen name="emergency_info_button_margin_vertical">56dp</dimen>
-    <dimen name="emergency_shortcut_button_height">96dp</dimen>
-    <dimen name="emergency_number_title_text_size">14sp</dimen>
-    <dimen name="emergency_location_text_size">14sp</dimen>
-</resources>
\ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 679eba6..2db3aa0 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -54,8 +54,6 @@
 
     <color name="dialer_dialpad_touch_tint">#330288d1</color>
     <color name="floating_action_button_touch_tint">#80ffffff</color>
-    <color name="emergency_shortcut_button_background_color">#40FFFFFF</color>
-    <color name="emergency_shortcut_confirm_button_background_color">#E25142</color>
 
     <!-- Color matches dialer settings light M2 theme.-->
     <color name="dialer_background_color">#ffffff</color>
@@ -63,4 +61,14 @@
     <color name="dialer_primary_text_color">#202124</color>
     <color name="dialer_secondary_text_color">#5f6368</color>
 
+    <!-- Colors for shortcut view -->
+    <color name="emergency_info_btn_bolder">#40ffffff</color>
+    <color name="emergency_info_btn_background_color">@android:color/transparent</color>
+    <color name="emergency_shortcut_button_background_color">#eae8e9</color>
+    <color name="emergency_shortcut_phone_type_icon_color">#e25142</color>
+    <color name="emergency_shortcut_confirm_button_background_color">#e25142</color>
+    <color name="emergency_shortcut_confirm_phone_type_icon_color">#e25142</color>
+    <color name="emergency_call_icon_color">#3c4043</color>
+    <color name="emergency_dialpad_fab_tint_color">@null</color>
+    <color name="white_70_percent">#b3ffffff</color>
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 23d20fc..e1742d8 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -118,20 +118,12 @@
     <dimen name="emergency_dialer_image_margin_start">20dp</dimen>
     <dimen name="emergency_dialer_image_margin_end">16dp</dimen>
 
-    <!-- Margin of dialpad button -->
-    <dimen name="emergency_dialer_dialpad_button_margin">40dp</dimen>
-
     <!-- Horizontal margin for button of emergency shortcut. -->
     <dimen name="emergency_shortcut_buttons_margin_horizontal">16dp</dimen>
 
     <!-- Horizontal padding for group of emergency number title-->
     <dimen name="emergency_number_title_group_padding_horizontal">16dp</dimen>
 
-    <!-- Height and vertical margin for the emergency information button. -->
-    <dimen name="emergency_info_button_height">80dp</dimen>
-    <dimen name="emergency_info_button_margin_vertical">40dp</dimen>
-    <dimen name="emergency_info_button_fix_margin_vertical">40dp</dimen>
-
     <!-- Margin for the emergency information button text. -->
     <dimen name="emergency_info_text_margin_end">20dp</dimen>
 
@@ -143,32 +135,10 @@
     <dimen name="emergency_shortcuts_function_icon_height">24dp</dimen>
     <dimen name="emergency_shortcuts_function_icon_width">24dp</dimen>
 
-    <!-- The height and width for the dialpad button -->
-    <dimen name="dialpad_button_height">56dp</dimen>
-    <dimen name="dialpad_button_width">56dp</dimen>
-
-    <!-- The height for title of emergency number and location info. -->
-    <dimen name="emergency_number_title_height">48dp</dimen>
-
-    <!-- The height and width for the image of location info.-->
-    <dimen name="location_image_height">16dp</dimen>
-    <dimen name="location_image_width">16dp</dimen>
-
-    <!-- The height for button of emergency shortcut. -->
-    <dimen name="emergency_shortcut_button_height">80dp</dimen>
-
     <!-- The height and width for the circle image of phone number type.-->
     <dimen name="phone_number_type_circle_image_height">40dp</dimen>
     <dimen name="phone_number_type_circle_image_width">40dp</dimen>
 
-    <!-- The height and width for the image of phone number type.-->
-    <dimen name="phone_number_type_image_height">24dp</dimen>
-    <dimen name="phone_number_type_image_width">24dp</dimen>
-
-    <!-- The height and width of phone icon.-->
-    <dimen name="phone_icon_height">24dp</dimen>
-    <dimen name="phone_icon_width">24dp</dimen>
-
     <!-- Margin for the emergency shortcut button.-->
     <dimen name="emergency_shortcuts_margin_end">60dp</dimen>
 
@@ -197,12 +167,6 @@
     <!-- The width for emergency number title container.-->
     <dimen name="emergency_number_title_container_width">210dp</dimen>
 
-    <!-- The text size for emergency number title.-->
-    <dimen name="emergency_number_title_text_size">13sp</dimen>
-
-    <!-- The text size for emergency location.-->
-    <dimen name="emergency_location_text_size">13sp</dimen>
-
     <!-- The text size for titles in settings page.-->
     <dimen name="dialer_head1_font_size">18dp</dimen>
 
@@ -211,4 +175,54 @@
 
     <!-- The text size for description in settings page.-->
     <dimen name="dialer_secondary_font_size">14dp</dimen>
+
+
+    <!-- Shortcut view vertical dimens. These values are tuned according to display
+         height in values-h<height>dp/dimens.xml -->
+    <!-- Height and vertical margin for the emergency information button. -->
+    <dimen name="emergency_info_button_height">74dp</dimen>
+    <dimen name="emergency_info_button_margin_top">32dp</dimen>
+    <dimen name="emergency_info_button_margin_bottom">37dp</dimen>
+
+    <!-- The text size of emergency info name and hint -->
+    <dimen name="emergency_info_name_text_size">16.9sp</dimen>
+    <dimen name="emergency_info_hint_text_size">12.3sp</dimen>
+    <dimen name="emergency_info_tap_hint_text_size">13.8sp</dimen>
+
+    <!-- The height for title of emergency number and location info. -->
+    <dimen name="emergency_number_title_height">37dp</dimen>
+    <!-- The text size for emergency number title.-->
+    <dimen name="emergency_number_title_text_size">10.7sp</dimen>
+
+    <!-- The height and width for the image of location info.-->
+    <dimen name="location_image_height">12.3dp</dimen>
+    <dimen name="location_image_width">12.3dp</dimen>
+
+    <!-- The text size for emergency location.-->
+    <dimen name="emergency_location_text_size">10.7sp</dimen>
+
+    <!-- The height and margin for button of emergency shortcut. -->
+    <dimen name="emergency_shortcut_button_height">74dp</dimen>
+    <dimen name="emergency_shortcut_button_margin_bottom">6.2dp</dimen>
+
+    <!-- The text size of emergency number, type and hint -->
+    <dimen name="emergency_shortcut_number_text_size">25sp</dimen>
+    <dimen name="emergency_shortcut_type_text_size">10.7sp</dimen>
+    <dimen name="emergency_shortcut_tap_hint_text_size">13.8sp</dimen>
+
+    <!-- The height and width for the image of phone number type.-->
+    <dimen name="phone_number_type_image_height">31dp</dimen>
+    <dimen name="phone_number_type_image_width">31dp</dimen>
+
+    <!-- The height and width of phone icon.-->
+    <dimen name="phone_icon_height">18.4dp</dimen>
+    <dimen name="phone_icon_width">18.4dp</dimen>
+
+    <!-- Margin of dialpad button -->
+    <dimen name="emergency_dialer_dialpad_button_margin">25dp</dimen>
+
+    <!-- The height and width for the dialpad button -->
+    <dimen name="dialpad_button_height">43dp</dimen>
+    <dimen name="dialpad_button_width">43dp</dimen>
+    <!-- End of Shortcut view vertical dimens. -->
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index c68deb2..3e821dc 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -581,6 +581,12 @@
     <string name="roaming_check_price_warning">Check with your network provider for pricing.</string>
     <!-- Mobile network settings screen, dialog message title when user selects the Data roaming check box -->
     <string name="roaming_alert_title">Allow data roaming?</string>
+    <!-- Notification title for limited sim function during dual sim -->
+    <string name="limited_sim_function_notification_title">Limited SIM functionality</string>
+    <!-- Notification message for limited sim function during dual sim [CHAR LIMIT=80]-->
+    <string name="limited_sim_function_with_phone_num_notification_message"><xliff:g id="carrier_name">%1$s</xliff:g> calls and data services may be blocked while using <xliff:g id="phone_number">%2$s</xliff:g>.</string>
+    <!-- Notification message for limited sim function during dual sim [CHAR LIMIT=80]-->
+    <string name="limited_sim_function_notification_message"><xliff:g id="carrier_name">%1$s</xliff:g> calls and data services may be blocked while using another SIM.</string>
     <!-- Mobile network settings screen, data usage setting check box name -->
     <string name="data_usage_title">App data usage</string>
     <!-- Summary about how much data has been used in a date range [CHAR LIMIT=100] -->
@@ -1547,6 +1553,15 @@
          message is shown when an in-progress call is ended due to the battery being low. -->
     <string name="callFailed_low_battery">Video call ended due to low battery.</string>
 
+    <!-- In-call screen: error message shown when the user attempts to place an emergency call
+         over wifi calling (WFC), but emergency services are not available in the current
+         location. -->
+    <string name="callFailed_emergency_call_over_wfc_not_available">Emergency calls over Wi-Fi calling not available in this location.</string>
+
+    <!-- In-call screen: error message shown when the user attempts to place a call over wifi
+         calling (WFC), but wifi calling is not available in the current location. -->
+    <string name="callFailed_wfc_service_not_available_in_this_location">Wi-Fi calling is not available in this location.</string>
+
     <!-- The title for the change voicemail PIN activity -->
     <string name="change_pin_title">Change Voicemail PIN</string>
     <!-- The label for the continue button in change voicemail PIN activity -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 5f9a453..1d5e7dc 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -335,25 +335,44 @@
         <item name="android:listDivider">@null</item>
     </style>
 
-    <style name="HeadlineTextAppearance">
-        <item name="android:textColor">@android:color/white</item>
-        <item name="android:textSize">22sp</item>
+    <style name="EmergencyInfoNameTextAppearance">
+        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+        <item name="android:textColor">@*android:color/primary_text_default_material_dark</item>
+        <item name="android:textSize">@dimen/emergency_info_name_text_size</item>
     </style>
 
-    <style name="SubtitleTextAppearance" parent="@style/HeadlineTextAppearance">
-        <item name="android:textSize">14sp</item>
+    <style name="EmergencyInfoHintTextAppearance">
+        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+        <item name="android:textColor">@*android: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>
+        <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>
 
     <style name="PhoneNumberTextAppearance">
+        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
+        <item name="android:textColor">@*android: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:textSize">@dimen/emergency_shortcut_type_text_size</item>
+    </style>
+
+    <style name="PhoneNumberTapHintAppearance">
+        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
         <item name="android:textColor">@android:color/white</item>
-        <item name="android:textSize">32sp</item>
-    </style>
-
-    <style name="PhoneCallHintTextAppearance" parent="@style/PhoneNumberTextAppearance">
-        <item name="android:textSize">18sp</item>
-    </style>
-
-    <style name="ShortcutsHintTextAppearance" parent="@style/HeadlineTextAppearance">
-        <item name="android:textSize">16sp</item>
+        <item name="android:textSize">@dimen/emergency_shortcut_tap_hint_text_size</item>
     </style>
 </resources>
diff --git a/src/com/android/phone/EmergencyDialer.java b/src/com/android/phone/EmergencyDialer.java
index 3cf74c8..03a2e57 100644
--- a/src/com/android/phone/EmergencyDialer.java
+++ b/src/com/android/phone/EmergencyDialer.java
@@ -1097,11 +1097,6 @@
                 if (mEmergencyShortcutButtonList.size() > 1) {
                     emergencyNumberTitle.setText(getString(
                             R.string.numerous_emergency_numbers_title));
-                    // Update mEmergencyInfoGroup margin to avoid UI overlay when
-                    // emergency shortcut button more than 2.
-                    if (mEmergencyShortcutButtonList.size() > 2) {
-                        mEmergencyInfoGroup.updateLayoutMargin();
-                    }
                 } else {
                     emergencyNumberTitle.setText(getText(R.string.single_emergency_number_title));
                 }
diff --git a/src/com/android/phone/EmergencyInfoGroup.java b/src/com/android/phone/EmergencyInfoGroup.java
index 14c24d8..9f1c906 100644
--- a/src/com/android/phone/EmergencyInfoGroup.java
+++ b/src/com/android/phone/EmergencyInfoGroup.java
@@ -35,7 +35,6 @@
 import android.view.accessibility.AccessibilityManager;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
-import android.widget.LinearLayout;
 import android.widget.TextView;
 
 import androidx.core.graphics.drawable.RoundedBitmapDrawable;
@@ -284,18 +283,4 @@
             hideSelectedButton();
         }
     };
-
-    /**
-     * Update layout margin when emergency shortcut button more than 2.
-     */
-    public void updateLayoutMargin() {
-        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) getLayoutParams();
-
-        params.topMargin = getResources().getDimensionPixelSize(
-                R.dimen.emergency_info_button_fix_margin_vertical);
-        params.bottomMargin = getResources().getDimensionPixelSize(
-                R.dimen.emergency_info_button_fix_margin_vertical);
-
-        setLayoutParams(params);
-    }
 }
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index 5a5b444..f0473c9 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -18,6 +18,7 @@
 
 import static android.Manifest.permission.READ_PHONE_STATE;
 
+import android.annotation.Nullable;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -63,6 +64,7 @@
 import com.android.internal.telephony.util.NotificationChannelController;
 import com.android.phone.settings.VoicemailSettingsActivity;
 
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
@@ -93,6 +95,7 @@
     static final int CALL_FORWARD_NOTIFICATION = 4;
     static final int DATA_ROAMING_NOTIFICATION = 5;
     static final int SELECTED_OPERATOR_FAIL_NOTIFICATION = 6;
+    static final int LIMITED_SIM_FUNCTION_NOTIFICATION = 7;
 
     // Event for network selection notification.
     private static final int EVENT_PENDING_NETWORK_SELECTION_NOTIFICATION = 1;
@@ -102,6 +105,8 @@
 
     private static final int STATE_UNKNOWN_SERVICE = -1;
 
+    private static final String ACTION_MOBILE_NETWORK_LIST = "android.settings.MOBILE_NETWORK_LIST";
+
     /** The singleton NotificationMgr instance. */
     private static NotificationMgr sInstance;
 
@@ -118,6 +123,9 @@
     // used to track the notification of selected network unavailable, per subscription id.
     private SparseArray<Boolean> mSelectedUnavailableNotify = new SparseArray<>();
 
+    // used to track the notification of limited sim function under dual sim, per subscription id.
+    private Set<Integer> mLimitedSimFunctionNotify = new HashSet<>();
+
     // used to track whether the message waiting indicator is visible, per subscription id.
     private ArrayMap<Integer, Boolean> mMwiVisible = new ArrayMap<Integer, Boolean>();
 
@@ -638,6 +646,88 @@
     }
 
     /**
+     * Shows the "Limited SIM functionality" warning notification, which appears when using a
+     * special carrier under dual sim. limited function applies for DSDS in general when two SIM
+     * cards share a single radio, thus the voice & data maybe impaired under certain scenarios.
+     */
+    public void showLimitedSimFunctionWarningNotification(int subId, @Nullable String carrierName) {
+        if (DBG) log("showLimitedSimFunctionWarningNotification carrier: " + carrierName
+                + " subId: " + subId);
+        if (mLimitedSimFunctionNotify.contains(subId)) {
+            // handle the case that user swipe the notification but condition triggers
+            // frequently which cause the same notification consistently displayed.
+            if (DBG) log("showLimitedSimFunctionWarningNotification, "
+                    + "not display again if already displayed");
+            return;
+        }
+        // Navigate to "Network Selection Settings" which list all subscriptions.
+        PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0,
+                new Intent(ACTION_MOBILE_NETWORK_LIST), 0);
+        String line1Num = mTelephonyManager.getLine1Number(subId);
+
+        final CharSequence contentText = TextUtils.isEmpty(line1Num) ?
+            String.format(mContext.getText(
+                R.string.limited_sim_function_notification_message).toString(),
+                carrierName, line1Num) :
+            String.format(mContext.getText(
+                R.string.limited_sim_function_with_phone_num_notification_message).toString(),
+                carrierName);
+        final Notification.Builder builder = new Notification.Builder(mContext)
+                .setSmallIcon(R.drawable.ic_sim_card)
+                .setContentTitle(mContext.getText(
+                        R.string.limited_sim_function_notification_title))
+                .setContentText(contentText)
+                .setOnlyAlertOnce(true)
+                .setOngoing(true)
+                .setChannel(NotificationChannelController.CHANNEL_ID_SIM_HIGH_PRIORITY)
+                .setContentIntent(contentIntent);
+        final Notification notification = new Notification.BigTextStyle(builder).bigText(
+                contentText).build();
+
+        mNotificationManager.notifyAsUser(Integer.toString(subId),
+                LIMITED_SIM_FUNCTION_NOTIFICATION,
+                notification, UserHandle.ALL);
+        mLimitedSimFunctionNotify.add(subId);
+    }
+
+    /**
+     * Dismiss the "Limited SIM functionality" warning notification for the given subId.
+     */
+    public void dismissLimitedSimFunctionWarningNotification(int subId) {
+        if (DBG) log("dismissLimitedSimFunctionWarningNotification subId: " + subId);
+        if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            // dismiss all notifications
+            for (int id : mLimitedSimFunctionNotify) {
+                mNotificationManager.cancelAsUser(Integer.toString(id),
+                        LIMITED_SIM_FUNCTION_NOTIFICATION, UserHandle.ALL);
+            }
+            mLimitedSimFunctionNotify.clear();
+        } else if (mLimitedSimFunctionNotify.contains(subId)) {
+            mNotificationManager.cancelAsUser(Integer.toString(subId),
+                    LIMITED_SIM_FUNCTION_NOTIFICATION, UserHandle.ALL);
+            mLimitedSimFunctionNotify.remove(subId);
+        }
+    }
+
+    /**
+     * Dismiss the "Limited SIM functionality" warning notification for all inactive subscriptions.
+     */
+    public void dismissLimitedSimFunctionWarningNotificationForInactiveSubs() {
+        if (DBG) log("dismissLimitedSimFunctionWarningNotificationForInactiveSubs");
+        // dismiss notification for inactive subscriptions.
+        // handle the corner case that SIM change by SIM refresh doesn't clear the notification
+        // from the old SIM if both old & new SIM configured to display the notification.
+        mLimitedSimFunctionNotify.removeIf(id -> {
+            if (!mSubscriptionManager.isActiveSubId(id)) {
+                mNotificationManager.cancelAsUser(Integer.toString(id),
+                        LIMITED_SIM_FUNCTION_NOTIFICATION, UserHandle.ALL);
+                return true;
+            }
+            return false;
+        });
+    }
+
+    /**
      * Display the network selection "no service" notification
      * @param operator is the numeric operator number
      * @param subId is the subscription ID
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 05c2d8b..252dbc1 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -47,6 +47,7 @@
 import android.telephony.AnomalyReporter;
 import android.telephony.CarrierConfigManager;
 import android.telephony.ServiceState;
+import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.data.ApnSetting;
@@ -76,6 +77,7 @@
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.List;
 
 /**
  * Global state for the telephony subsystem when running in the primary
@@ -674,6 +676,7 @@
                 // Roaming status could be overridden by carrier config, so we need to update it.
                 if (VDBG) Log.v(LOG_TAG, "carrier config changed.");
                 updateDataRoamingStatus();
+                updateLimitedSimFunctionForDualSim();
             } else if (action.equals(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)) {
                 // We also need to pay attention when default data subscription changes.
                 if (VDBG) Log.v(LOG_TAG, "default data sub changed.");
@@ -811,6 +814,38 @@
         return getPhone(subId).getServiceState().getDataRoaming();
     }
 
+    private void updateLimitedSimFunctionForDualSim() {
+        if (DBG) Log.d(LOG_TAG, "updateLimitedSimFunctionForDualSim");
+        // check conditions to display limited SIM function notification under dual SIM
+        SubscriptionManager subMgr = (SubscriptionManager) getSystemService(
+                Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+        List<SubscriptionInfo> subList = subMgr.getActiveSubscriptionInfoList(false);
+        if (subList != null && subList.size() > 1) {
+            CarrierConfigManager configMgr = (CarrierConfigManager)
+                    getSystemService(Context.CARRIER_CONFIG_SERVICE);
+            for (SubscriptionInfo info : subList) {
+                PersistableBundle b = configMgr.getConfigForSubId(info.getSubscriptionId());
+                if (b != null) {
+                    if (b.getBoolean(CarrierConfigManager
+                            .KEY_LIMITED_SIM_FUNCTION_NOTIFICATION_FOR_DSDS_BOOL)) {
+                        notificationMgr.showLimitedSimFunctionWarningNotification(
+                                info.getSubscriptionId(),
+                                info.getDisplayName().toString());
+                    } else {
+                        notificationMgr.dismissLimitedSimFunctionWarningNotification(
+                                info.getSubscriptionId());
+                    }
+                }
+            }
+        } else {
+            // cancel notifications for all subs
+            notificationMgr.dismissLimitedSimFunctionWarningNotification(
+                    SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        }
+        notificationMgr.dismissLimitedSimFunctionWarningNotificationForInactiveSubs();
+
+    }
+
     public Phone getPhoneInEcm() {
         return phoneInEcm;
     }
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 0469d7d..97f3a77 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -44,6 +44,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.Messenger;
+import android.os.ParcelUuid;
 import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
@@ -5107,6 +5108,49 @@
     }
 
     @Override
+    public String[] getMergedSubscriberIdsFromGroup(int subId, String callingPackage) {
+        enforceReadPrivilegedPermission("getMergedSubscriberIdsFromGroup");
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            final TelephonyManager telephonyManager = mApp.getSystemService(
+                    TelephonyManager.class);
+            String subscriberId = telephonyManager.getSubscriberId(subId);
+            if (subscriberId == null) {
+                if (DBG) {
+                    log("getMergedSubscriberIdsFromGroup can't find subscriberId for subId "
+                            + subId);
+                }
+                return null;
+            }
+
+            final SubscriptionInfo info = SubscriptionController.getInstance()
+                    .getSubscriptionInfo(subId);
+            final ParcelUuid groupUuid = info.getGroupUuid();
+            // If it doesn't belong to any group, return just subscriberId of itself.
+            if (groupUuid == null) {
+                return new String[]{subscriberId};
+            }
+
+            // Get all subscriberIds from the group.
+            final List<String> mergedSubscriberIds = new ArrayList<>();
+            final List<SubscriptionInfo> groupInfos = SubscriptionController.getInstance()
+                    .getSubscriptionsInGroup(groupUuid, mApp.getOpPackageName());
+            for (SubscriptionInfo subInfo : groupInfos) {
+                subscriberId = telephonyManager.getSubscriberId(subInfo.getSubscriptionId());
+                if (subscriberId != null) {
+                    mergedSubscriberIds.add(subscriberId);
+                }
+            }
+
+            return mergedSubscriberIds.toArray(new String[mergedSubscriberIds.size()]);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+
+        }
+    }
+
+    @Override
     public boolean setOperatorBrandOverride(int subId, String brand) {
         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
                 subId, "setOperatorBrandOverride");
diff --git a/src/com/android/phone/ShortcutViewUtils.java b/src/com/android/phone/ShortcutViewUtils.java
index 8e5ab42..47ca5ee 100644
--- a/src/com/android/phone/ShortcutViewUtils.java
+++ b/src/com/android/phone/ShortcutViewUtils.java
@@ -33,6 +33,8 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.internal.util.ArrayUtils;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -225,8 +227,8 @@
         PhoneAccountHandle defaultHandle = telecomManager.getDefaultOutgoingPhoneAccount(
                 PhoneAccount.SCHEME_TEL);
         if (defaultHandle != null) {
-            PhoneInfo phone = loadPhoneInfo(defaultHandle, telephonyManager, telecomManager,
-                    promotedLists);
+            PhoneInfo phone = loadPhoneInfo(context, defaultHandle, telephonyManager,
+                    telecomManager, promotedLists);
             if (phone.isSufficientForEmergencyCall(context)) {
                 return phone;
             }
@@ -240,7 +242,7 @@
         List<PhoneAccountHandle> allHandles = telecomManager.getCallCapablePhoneAccounts();
         if (allHandles != null && !allHandles.isEmpty()) {
             for (PhoneAccountHandle handle : allHandles) {
-                PhoneInfo phone = loadPhoneInfo(handle, telephonyManager, telecomManager,
+                PhoneInfo phone = loadPhoneInfo(context, handle, telephonyManager, telecomManager,
                         promotedLists);
                 if (phone.isSufficientForEmergencyCall(context)) {
                     return phone;
@@ -272,8 +274,11 @@
         return false;
     }
 
-    private static PhoneInfo loadPhoneInfo(@NonNull PhoneAccountHandle handle,
-            @NonNull TelephonyManager telephonyManager, @NonNull TelecomManager telecomManager,
+    private static PhoneInfo loadPhoneInfo(
+            @NonNull Context context,
+            @NonNull PhoneAccountHandle handle,
+            @NonNull TelephonyManager telephonyManager,
+            @NonNull TelecomManager telecomManager,
             Map<Integer, List<EmergencyNumber>> promotedLists) {
         boolean canPlaceEmergencyCall = false;
         int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
@@ -293,12 +298,69 @@
         }
 
         if (promotedLists != null) {
-            emergencyNumberList = promotedLists.get(subId);
+            emergencyNumberList = removeCarrierSpecificPrefixes(context, subId,
+                    promotedLists.get(subId));
         }
 
         return new PhoneInfo(handle, canPlaceEmergencyCall, subId, countryIso, emergencyNumberList);
     }
 
+    @Nullable
+    private static String[] getCarrierSpecificPrefixes(@NonNull Context context, int subId) {
+        CarrierConfigManager configMgr = context.getSystemService(CarrierConfigManager.class);
+        if (configMgr == null) {
+            return null;
+        }
+        PersistableBundle b = configMgr.getConfigForSubId(subId);
+        return b == null ? null : b.getStringArray(
+                CarrierConfigManager.KEY_EMERGENCY_NUMBER_PREFIX_STRING_ARRAY);
+    }
+
+    // Removes carrier specific emergency number prefixes (if there is any) from every emergency
+    // number and create a new list without duplications. Returns the original list if there is no
+    // prefixes.
+    @NonNull
+    private static List<EmergencyNumber> removeCarrierSpecificPrefixes(
+            @NonNull Context context,
+            int subId,
+            @NonNull List<EmergencyNumber> emergencyNumberList) {
+        String[] prefixes = getCarrierSpecificPrefixes(context, subId);
+        if (ArrayUtils.isEmpty(prefixes)) {
+            return emergencyNumberList;
+        }
+
+        List<EmergencyNumber> newList = new ArrayList<>(emergencyNumberList.size());
+        for (EmergencyNumber emergencyNumber : emergencyNumberList) {
+            // If no prefix was removed from emergencyNumber, add it to the newList directly.
+            EmergencyNumber newNumber = emergencyNumber;
+            String number = emergencyNumber.getNumber();
+            for (String prefix : prefixes) {
+                // If emergencyNumber starts with this prefix, remove this prefix to retrieve the
+                // actual emergency number.
+                // However, if emergencyNumber is exactly the same with this prefix, it could be
+                // either a real emergency number, or composed with another prefix. It shouldn't be
+                // processed with this prefix whatever.
+                if (!TextUtils.isEmpty(prefix) && number.startsWith(prefix)
+                        && !number.equals(prefix)) {
+                    newNumber = new EmergencyNumber(
+                            number.substring(prefix.length()),
+                            emergencyNumber.getCountryIso(),
+                            emergencyNumber.getMnc(),
+                            emergencyNumber.getEmergencyServiceCategoryBitmask(),
+                            emergencyNumber.getEmergencyUrns(),
+                            emergencyNumber.getEmergencyNumberSourceBitmask(),
+                            emergencyNumber.getEmergencyCallRouting());
+                    // There should not be more than one prefix attached to a number.
+                    break;
+                }
+            }
+            if (!newList.contains(newNumber)) {
+                newList.add(newNumber);
+            }
+        }
+        return newList;
+    }
+
     @NonNull
     private static Map<Integer, List<EmergencyNumber>> getPromotedEmergencyNumberLists(
             @NonNull TelephonyManager telephonyManager) {
diff --git a/src/com/android/phone/settings/PhoneAccountSettingsFragment.java b/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
index 0846be1..aa6b155 100644
--- a/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
+++ b/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
@@ -8,7 +8,6 @@
 import android.graphics.drawable.Icon;
 import android.net.sip.SipManager;
 import android.os.Bundle;
-import android.os.PersistableBundle;
 import android.os.UserManager;
 import android.preference.ListPreference;
 import android.preference.Preference;
@@ -558,12 +557,18 @@
 
         List<SubscriptionInfo> subscriptions =
                 mSubscriptionManager.getActiveSubscriptionInfoList();
-        if ((subscriptions == null) || (subscriptions.size() <= 1)) {
+        if (subscriptions == null) {
             return null;
         }
 
-        List<String> componentNames = subscriptions
-                .stream()
+        List<SubscriptionInfo> effectiveSubscriptions = subscriptions.stream()
+                .filter(subInfo -> !subInfo.isOpportunistic())
+                .collect(Collectors.toList());
+        if (effectiveSubscriptions.size() < 2) {
+            return null;
+        }
+
+        List<String> componentNames = effectiveSubscriptions.stream()
                 .map(subInfo -> configManager.getConfigForSubId(subInfo.getSubscriptionId()))
                 .filter(bundle -> (bundle != null))
                 .map(bundle -> bundle.getString(
diff --git a/src/com/android/phone/settings/TtyModeListPreference.java b/src/com/android/phone/settings/TtyModeListPreference.java
index 89cac47..ba415c5 100644
--- a/src/com/android/phone/settings/TtyModeListPreference.java
+++ b/src/com/android/phone/settings/TtyModeListPreference.java
@@ -18,17 +18,23 @@
 
 import android.content.Context;
 import android.content.Intent;
+import android.os.PersistableBundle;
 import android.os.UserHandle;
 import android.preference.ListPreference;
 import android.preference.Preference;
 import android.provider.Settings;
+import android.provider.Settings.Secure;
 import android.telecom.TelecomManager;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
 import android.util.AttributeSet;
 import android.util.Log;
 
 import com.android.phone.PhoneGlobals;
 import com.android.phone.R;
 
+import java.util.Arrays;
+
 public class TtyModeListPreference extends ListPreference
         implements Preference.OnPreferenceChangeListener {
     private static final String LOG_TAG = TtyModeListPreference.class.getSimpleName();
@@ -44,6 +50,19 @@
         int settingsTtyMode = Settings.Secure.getInt(getContext().getContentResolver(),
                 Settings.Secure.PREFERRED_TTY_MODE,
                 TelecomManager.TTY_MODE_OFF);
+        if (shouldHideHcoAndVco()) {
+            setEntries(Arrays.copyOfRange(
+                    getContext().getResources().getTextArray(R.array.tty_mode_entries), 0, 2));
+            setEntryValues(Arrays.copyOfRange(
+                    getContext().getResources().getTextArray(R.array.tty_mode_values), 0, 2));
+            if (settingsTtyMode == TelecomManager.TTY_MODE_HCO
+                    || settingsTtyMode == TelecomManager.TTY_MODE_VCO) {
+                // If the persisted setting is HCO or VCO, set it to full here
+                settingsTtyMode = TelecomManager.TTY_MODE_FULL;
+                Settings.Secure.putInt(getContext().getContentResolver(), Secure.PREFERRED_TTY_MODE,
+                        settingsTtyMode);
+            }
+        }
         setValue(Integer.toString(settingsTtyMode));
         updatePreferredTtyModeSummary(settingsTtyMode);
     }
@@ -101,6 +120,18 @@
         }
     }
 
+    private boolean shouldHideHcoAndVco() {
+        CarrierConfigManager carrierConfigManager =
+                getContext().getSystemService(CarrierConfigManager.class);
+        PersistableBundle config = carrierConfigManager.getConfigForSubId(
+                SubscriptionManager.getDefaultVoiceSubscriptionId());
+        boolean carrierShouldHideHcoVco = config != null && config.getBoolean(
+                CarrierConfigManager.KEY_HIDE_TTY_HCO_VCO_WITH_RTT_BOOL, false);
+        boolean isRttSupported = PhoneGlobals.getInstance().phoneMgr.isRttSupported(
+                SubscriptionManager.getDefaultVoiceSubscriptionId());
+        return carrierShouldHideHcoVco && isRttSupported;
+    }
+
     private static void log(String msg) {
         Log.d(LOG_TAG, msg);
     }
diff --git a/src/com/android/services/telephony/DisconnectCauseUtil.java b/src/com/android/services/telephony/DisconnectCauseUtil.java
index cf3f913..5227e8b 100644
--- a/src/com/android/services/telephony/DisconnectCauseUtil.java
+++ b/src/com/android/services/telephony/DisconnectCauseUtil.java
@@ -166,6 +166,8 @@
             case android.telephony.DisconnectCause.POWER_OFF:
             case android.telephony.DisconnectCause.LOW_BATTERY:
             case android.telephony.DisconnectCause.DIAL_LOW_BATTERY:
+            case android.telephony.DisconnectCause.EMERGENCY_CALL_OVER_WFC_NOT_AVAILABLE:
+            case android.telephony.DisconnectCause.WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION:
             case android.telephony.DisconnectCause.SERVER_ERROR:
             case android.telephony.DisconnectCause.SERVER_UNREACHABLE:
             case android.telephony.DisconnectCause.TIMED_OUT:
@@ -357,6 +359,12 @@
             case android.telephony.DisconnectCause.OTASP_PROVISIONING_IN_PROCESS:
                 resourceId = R.string.callFailed_otasp_provisioning_in_process;
                 break;
+            case android.telephony.DisconnectCause.EMERGENCY_CALL_OVER_WFC_NOT_AVAILABLE:
+                resourceId = R.string.callFailed_emergency_call_over_wfc_not_available;
+                break;
+            case android.telephony.DisconnectCause.WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION:
+                resourceId = R.string.callFailed_wfc_service_not_available_in_this_location;
+                break;
             default:
                 break;
         }
@@ -744,6 +752,12 @@
             case android.telephony.DisconnectCause.OTASP_PROVISIONING_IN_PROCESS:
                 resourceId = R.string.callFailed_otasp_provisioning_in_process;
                 break;
+            case android.telephony.DisconnectCause.EMERGENCY_CALL_OVER_WFC_NOT_AVAILABLE:
+                resourceId = R.string.callFailed_emergency_call_over_wfc_not_available;
+                break;
+            case android.telephony.DisconnectCause.WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION:
+                resourceId = R.string.callFailed_wfc_service_not_available_in_this_location;
+                break;
             default:
                 break;
         }
diff --git a/src/com/android/services/telephony/ImsConference.java b/src/com/android/services/telephony/ImsConference.java
index 245f2e8..bf0374f 100644
--- a/src/com/android/services/telephony/ImsConference.java
+++ b/src/com/android/services/telephony/ImsConference.java
@@ -212,6 +212,12 @@
 
         @Override
         public void onConnectionEvent(Connection c, String event, Bundle extras) {
+            if (Connection.EVENT_MERGE_START.equals(event)) {
+                // Do not pass a merge start event on the underlying host connection; we only
+                // indicate a merge has started on the connections which are merged into a
+                // conference.
+                return;
+            }
             sendConnectionEvent(event, extras);
         }
     };
@@ -744,6 +750,10 @@
             // Determine if the conference event package represents a single party conference.
             // A single party conference is one where there is no other participant other than the
             // conference host and one other participant.
+            // We purposely exclude participants which have a disconnected state in the conference
+            // event package; some carriers are known to keep a disconnected participant around in
+            // subsequent CEP updates with a state of disconnected, even though its no longer part
+            // of the conference.
             // Note: We consider 0 to still be a single party conference since some carriers will
             // send a conference event package with JUST the host in it when the conference is
             // disconnected.  We don't want to change back to conference mode prior to disconnection
@@ -751,7 +761,8 @@
             boolean isSinglePartyConference = participants.stream()
                     .filter(p -> {
                         Pair<Uri, Uri> pIdent = new Pair<>(p.getHandle(), p.getEndpoint());
-                        return !Objects.equals(mHostParticipantIdentity, pIdent);
+                        return !Objects.equals(mHostParticipantIdentity, pIdent)
+                                && p.getState() != Connection.STATE_DISCONNECTED;
                     })
                     .count() <= 1;
 
@@ -766,7 +777,14 @@
                     Pair<Uri, Uri> userEntity = new Pair<>(participant.getHandle(),
                             participant.getEndpoint());
 
-                    participantUserEntities.add(userEntity);
+                    // We will exclude disconnected participants from the hash set of tracked
+                    // participants.  Some carriers are known to leave disconnected participants in
+                    // the conference event package data which would cause them to be present in the
+                    // conference even though they're disconnected.  Removing them from the hash set
+                    // here means we'll clean them up below.
+                    if (participant.getState() != Connection.STATE_DISCONNECTED) {
+                        participantUserEntities.add(userEntity);
+                    }
                     if (!mConferenceParticipantConnections.containsKey(userEntity)) {
                         // Some carriers will also include the conference host in the CEP.  We will
                         // filter that out here.
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 7bb6b7d..996c8ea 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -2205,6 +2205,8 @@
         if (isIms) {
             isVoWifiEnabled = ImsUtil.isWfcEnabled(phone.getContext(), phone.getPhoneId());
         }
+        boolean isRttMergeSupported = getCarrierConfig()
+                .getBoolean(CarrierConfigManager.KEY_ALLOW_MERGING_RTT_CALLS_BOOL);
         PhoneAccountHandle phoneAccountHandle = isIms ? PhoneUtils
                 .makePstnPhoneAccountHandle(phone.getDefaultPhone())
                 : PhoneUtils.makePstnPhoneAccountHandle(phone);
@@ -2229,7 +2231,7 @@
         if (mTreatAsEmergencyCall) {
             isConferenceSupported = false;
             Log.d(this, "refreshConferenceSupported = false; emergency call");
-        } else if (isRtt()) {
+        } else if (isRtt() && !isRttMergeSupported) {
             isConferenceSupported = false;
             Log.d(this, "refreshConferenceSupported = false; rtt call");
         } else if (!isConferencingSupported || isIms && !isImsConferencingSupported) {
diff --git a/tests/src/com/android/services/telephony/ImsConferenceTest.java b/tests/src/com/android/services/telephony/ImsConferenceTest.java
index 68b5b3b..eaec5b6 100644
--- a/tests/src/com/android/services/telephony/ImsConferenceTest.java
+++ b/tests/src/com/android/services/telephony/ImsConferenceTest.java
@@ -119,6 +119,189 @@
     }
 
     /**
+     * Tests CEPs with disconnected participants present with disconnected state.
+     */
+    @Test
+    @SmallTest
+    public void testDisconnectParticipantViaDisconnectState() {
+        when(mMockTelecomAccountRegistry.isUsingSimCallManager(any(PhoneAccountHandle.class)))
+                .thenReturn(false);
+
+        ImsConference imsConference = new ImsConference(mMockTelecomAccountRegistry,
+                mMockTelephonyConnectionServiceProxy, mConferenceHost,
+                null /* phoneAccountHandle */, () -> true /* featureFlagProxy */);
+
+        // Start off with 3 participants.
+        ConferenceParticipant participant1 = new ConferenceParticipant(
+                Uri.parse("tel:6505551212"),
+                "A",
+                Uri.parse("sip:6505551212@testims.com"),
+                Connection.STATE_ACTIVE,
+                Call.Details.DIRECTION_INCOMING);
+        ConferenceParticipant participant2 = new ConferenceParticipant(
+                Uri.parse("tel:6505551213"),
+                "A",
+                Uri.parse("sip:6505551213@testims.com"),
+                Connection.STATE_ACTIVE,
+                Call.Details.DIRECTION_INCOMING);
+
+        ConferenceParticipant participant3 = new ConferenceParticipant(
+                Uri.parse("tel:6505551214"),
+                "A",
+                Uri.parse("sip:6505551214@testims.com"),
+                Connection.STATE_ACTIVE,
+                Call.Details.DIRECTION_INCOMING);
+        imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
+                Arrays.asList(participant1, participant2, participant3));
+        assertEquals(3, imsConference.getNumberOfParticipants());
+        verify(mMockTelephonyConnectionServiceProxy, times(3)).addExistingConnection(
+                any(PhoneAccountHandle.class), any(Connection.class),
+                eq(imsConference));
+
+
+        // Mark one participant as disconnected.
+        ConferenceParticipant participant3Disconnected = new ConferenceParticipant(
+                Uri.parse("tel:6505551214"),
+                "A",
+                Uri.parse("sip:6505551214@testims.com"),
+                Connection.STATE_DISCONNECTED,
+                Call.Details.DIRECTION_INCOMING);
+        imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
+                Arrays.asList(participant1, participant2, participant3Disconnected));
+        assertEquals(2, imsConference.getNumberOfParticipants());
+        verify(mMockTelephonyConnectionServiceProxy, times(1)).removeConnection(
+                any(Connection.class));
+        reset(mMockTelephonyConnectionServiceProxy);
+
+        // Now remove it from another CEP update; should still be the same number of participants
+        // and no updates.
+        imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
+                Arrays.asList(participant1, participant2));
+        assertEquals(2, imsConference.getNumberOfParticipants());
+        verify(mMockTelephonyConnectionServiceProxy, never()).removeConnection(
+                any(Connection.class));
+        verify(mMockTelephonyConnectionServiceProxy, never()).addExistingConnection(
+                any(PhoneAccountHandle.class), any(Connection.class),
+                any(Conference.class));
+    }
+
+    /**
+     * Tests CEPs with removed participants.
+     */
+    @Test
+    @SmallTest
+    public void testDisconnectParticipantViaRemoval() {
+        when(mMockTelecomAccountRegistry.isUsingSimCallManager(any(PhoneAccountHandle.class)))
+                .thenReturn(false);
+
+        ImsConference imsConference = new ImsConference(mMockTelecomAccountRegistry,
+                mMockTelephonyConnectionServiceProxy, mConferenceHost,
+                null /* phoneAccountHandle */, () -> true /* featureFlagProxy */);
+
+        // Start off with 3 participants.
+        ConferenceParticipant participant1 = new ConferenceParticipant(
+                Uri.parse("tel:6505551212"),
+                "A",
+                Uri.parse("sip:6505551212@testims.com"),
+                Connection.STATE_ACTIVE,
+                Call.Details.DIRECTION_INCOMING);
+        ConferenceParticipant participant2 = new ConferenceParticipant(
+                Uri.parse("tel:6505551213"),
+                "A",
+                Uri.parse("sip:6505551213@testims.com"),
+                Connection.STATE_ACTIVE,
+                Call.Details.DIRECTION_INCOMING);
+
+        ConferenceParticipant participant3 = new ConferenceParticipant(
+                Uri.parse("tel:6505551214"),
+                "A",
+                Uri.parse("sip:6505551214@testims.com"),
+                Connection.STATE_ACTIVE,
+                Call.Details.DIRECTION_INCOMING);
+        imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
+                Arrays.asList(participant1, participant2, participant3));
+        assertEquals(3, imsConference.getNumberOfParticipants());
+        verify(mMockTelephonyConnectionServiceProxy, times(3)).addExistingConnection(
+                any(PhoneAccountHandle.class), any(Connection.class),
+                eq(imsConference));
+        reset(mMockTelephonyConnectionServiceProxy);
+
+        // Remove one from the CEP (don't disconnect first); should have 2 participants now.
+        imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
+                Arrays.asList(participant1, participant2));
+        assertEquals(2, imsConference.getNumberOfParticipants());
+        verify(mMockTelephonyConnectionServiceProxy, times(1)).removeConnection(
+                any(Connection.class));
+        verify(mMockTelephonyConnectionServiceProxy, never()).addExistingConnection(
+                any(PhoneAccountHandle.class), any(Connection.class),
+                any(Conference.class));
+    }
+
+    /**
+     * Typically when a participant disconnects from a conference it is either:
+     * 1. Removed from a subsequent CEP update.
+     * 2. Marked as disconnected in a CEP update, and then removed from another CEP update.
+     *
+     * When a participant disconnects from a conference, some carriers will mark the disconnected
+     * participant as disconnected, but fail to send another CEP update with it removed.
+     *
+     * This test verifies that we can still enter single party emulation in this case.
+     */
+    @Test
+    @SmallTest
+    public void testSinglePartyEmulationEnterOnDisconnectParticipant() {
+        when(mMockTelecomAccountRegistry.isUsingSimCallManager(any(PhoneAccountHandle.class)))
+                .thenReturn(false);
+
+        ImsConference imsConference = new ImsConference(mMockTelecomAccountRegistry,
+                mMockTelephonyConnectionServiceProxy, mConferenceHost,
+                null /* phoneAccountHandle */, () -> true /* featureFlagProxy */);
+
+        // Setup the initial conference state with 2 participants.
+        ConferenceParticipant participant1 = new ConferenceParticipant(
+                Uri.parse("tel:6505551212"),
+                "A",
+                Uri.parse("sip:6505551212@testims.com"),
+                Connection.STATE_ACTIVE,
+                Call.Details.DIRECTION_INCOMING);
+        ConferenceParticipant participant2 = new ConferenceParticipant(
+                Uri.parse("tel:6505551213"),
+                "A",
+                Uri.parse("sip:6505551213@testims.com"),
+                Connection.STATE_ACTIVE,
+                Call.Details.DIRECTION_INCOMING);
+        imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
+                Arrays.asList(participant1, participant2));
+        assertEquals(2, imsConference.getNumberOfParticipants());
+        verify(mMockTelephonyConnectionServiceProxy, times(2)).addExistingConnection(
+                any(PhoneAccountHandle.class), any(Connection.class),
+                eq(imsConference));
+
+        // Some carriers keep disconnected participants around in the CEP; this will cause problems
+        // when we want to enter single party conference mode. Verify that this case is handled.
+        ConferenceParticipant participant2Disconnected = new ConferenceParticipant(
+                Uri.parse("tel:6505551213"),
+                "A",
+                Uri.parse("sip:6505551213@testims.com"),
+                Connection.STATE_DISCONNECTED,
+                Call.Details.DIRECTION_INCOMING);
+        imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
+                Arrays.asList(participant1, participant2Disconnected));
+        assertEquals(0, imsConference.getNumberOfParticipants());
+        verify(mMockTelephonyConnectionServiceProxy, times(2)).removeConnection(
+                any(Connection.class));
+        reset(mMockTelephonyConnectionServiceProxy);
+
+        // Pretend to merge someone else into the conference.
+        imsConference.handleConferenceParticipantsUpdate(mConferenceHost,
+                Arrays.asList(participant1, participant2));
+        assertEquals(2, imsConference.getNumberOfParticipants());
+        verify(mMockTelephonyConnectionServiceProxy, times(2)).addExistingConnection(
+                any(PhoneAccountHandle.class), any(Connection.class),
+                eq(imsConference));
+    }
+
+    /**
      * We have seen a scenario on a carrier where a conference event package comes in just prior to
      * the call disconnecting with only the conference host in it.  This caused a problem because
      * it triggered exiting single party conference mode (due to a bug) and caused the call to not