Merge "Add slot based ICC channel APIs"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index f68b72e..0028e63 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -87,11 +87,11 @@
     <protected-broadcast android:name= "android.telephony.action.SIM_APPLICATION_STATE_CHANGED" />
     <protected-broadcast android:name= "android.telephony.action.SIM_SLOT_STATUS_CHANGED" />
     <protected-broadcast android:name= "android.telephony.action.SUBSCRIPTION_CARRIER_IDENTITY_CHANGED" />
-    <protected-broadcast android:name= "android.telephony.action.SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED" />
+    <protected-broadcast android:name= "android.telephony.action.SUBSCRIPTION_SPECIFIC_CARRIER_IDENTITY_CHANGED" />
     <protected-broadcast android:name= "android.telephony.action.NETWORK_COUNTRY_CHANGED" />
 
     <!-- For Vendor Debugging in Telephony -->
-    <protected-broadcast android:name="android.telephony.debug.action.DEBUG_EVENT" />
+    <protected-broadcast android:name="android.telephony.action.ANOMALY_REPORTED" />
 
     <uses-permission android:name="android.permission.BROADCAST_STICKY" />
     <uses-permission android:name="android.permission.CALL_PHONE" />
@@ -458,6 +458,24 @@
             </intent-filter>
         </activity>
 
+        <!--
+            Handler for EuiccManager's privileged action intents. These are locked down so that only
+            privileged processes can start them.
+        -->
+        <activity android:name=".euicc.EuiccPrivilegedActionUiDispatcherActivity"
+                  android:permission="android.permission.CALL_PRIVILEGED">
+            <!-- Max out priority to ensure nobody else will handle these intents. -->
+            <intent-filter android:priority="1000">
+                <action android:name=
+                            "android.telephony.euicc.action.TOGGLE_SUBSCRIPTION_PRIVILEGED" />
+                <action android:name=
+                            "android.telephony.euicc.action.DELETE_SUBSCRIPTION_PRIVILEGED" />
+                <action android:name=
+                            "android.telephony.euicc.action.RENAME_SUBSCRIPTION_PRIVILEGED" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
         <activity android:name="EmergencyCallbackModeExitDialog"
             android:excludeFromRecents="true"
             android:label="@string/ecm_exit_dialog"
@@ -534,6 +552,7 @@
         <activity android:name="com.android.phone.settings.VoicemailSettingsActivity"
             android:label="@string/voicemail"
             android:configChanges="orientation|screenSize|keyboardHidden|screenLayout"
+            android:screenOrientation="portrait"
             android:theme="@style/DialerSettingsLight">
             <intent-filter >
                 <!-- DO NOT RENAME. There are existing apps which use this string. -->
diff --git a/ecc/conversion_toolset_v1/verify_eccdata_compatibility.sh b/ecc/conversion_toolset_v1/verify_eccdata_compatibility.sh
new file mode 100644
index 0000000..8686722
--- /dev/null
+++ b/ecc/conversion_toolset_v1/verify_eccdata_compatibility.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+set -o errexit
+
+# Copyright 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.
+
+LOCAL_TOOLSET_DIR="${ECC_ROOT}/conversion_toolset_v1"
+source "${LOCAL_TOOLSET_DIR}/env.sh"
+
+echo "Starting compatibility verification v1"
+echo "Decoding and decompressing eccdata"
+gunzip -c < "${OUTPUT_DATA}" > "${RAW_DATA}"
+${PYTHON_COMMAND} -B \
+  "${LOCAL_TOOLSET_DIR}/verify_protobuf_compatibility.py" \
+  --input="${RAW_DATA}"
+echo "Passed compatibility verification v1"
+
diff --git a/ecc/conversion_toolset_v1/verify_protobuf_compatibility.py b/ecc/conversion_toolset_v1/verify_protobuf_compatibility.py
new file mode 100644
index 0000000..bc707eb
--- /dev/null
+++ b/ecc/conversion_toolset_v1/verify_protobuf_compatibility.py
@@ -0,0 +1,85 @@
+#!/usr/bin/python -B
+
+# Copyright 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.
+
+# Notice:
+# - verify_eccdata_strict.py: Verify data which is generated by this
+# version of this toolset.
+# - verify_eccdata_compatibility.py: Verify data which is generated by any
+# newer version of this tool set for ensuring backward compatibility.
+
+import sys
+import argparse
+import protobuf_ecc_data_pb2
+
+parser = argparse.ArgumentParser()
+parser.add_argument("--input", required=True)
+parser.add_argument("--strict", action="store_true")
+args = parser.parse_args()
+
+all_ecc_info = protobuf_ecc_data_pb2.AllInfo()
+
+with open(args.input, "rb") as ecc_data_source_file:
+  all_ecc_info.ParseFromString(ecc_data_source_file.read())
+
+if (args.strict):
+  print("Verify in strict mode")
+
+assert all_ecc_info.HasField("revision")
+assert all_ecc_info.revision > 0
+assert len(all_ecc_info.countries) > 0
+
+loaded_iso = []
+for country_info in all_ecc_info.countries:
+  assert country_info.HasField("iso_code")
+  assert len(country_info.iso_code) > 0
+  assert country_info.iso_code == country_info.iso_code.strip().upper()
+  assert country_info.iso_code not in loaded_iso
+  loaded_iso.append(country_info.iso_code)
+  assert country_info.HasField("ecc_fallback")
+  assert len(country_info.ecc_fallback) > 0
+
+  if len(country_info.eccs) > 0:
+    loaded_phone_number = []
+    for ecc_info in country_info.eccs:
+      assert ecc_info.HasField("phone_number")
+      phone_number = ecc_info.phone_number.strip()
+      assert len(phone_number) > 0
+      assert phone_number not in loaded_phone_number
+      loaded_phone_number.append(phone_number)
+
+      if (args.strict):
+        assert len(ecc_info.types) > 0
+        loaded_types = []
+        for ecc_type in ecc_info.types:
+          assert ecc_type == protobuf_ecc_data_pb2.EccInfo.POLICE or \
+              ecc_type == protobuf_ecc_data_pb2.EccInfo.AMBULANCE or \
+              ecc_type == protobuf_ecc_data_pb2.EccInfo.FIRE
+          assert ecc_type not in loaded_types
+          loaded_types.append(ecc_type)
+      else:
+        # For forward compatibility, ecc_info.types could be null if a phone
+        # number contains only new types which is not defined now. Just leave
+        # a warning message for this case.
+        if len(ecc_info.types) == 0:
+          print("WARNING: No recognizable type for " + \
+              country_info.iso_code + " - " + ecc_info.phone_number)
+        else:
+          loaded_types = []
+          for ecc_type in ecc_info.types:
+            assert ecc_type not in loaded_types
+            loaded_types.append(ecc_type)
+  elif (args.strict):
+    print("Warning: Empty ecc list for country " + country_info.iso_code)
diff --git a/res/layout/emergency_shortcut_buttons_group.xml b/res/layout/emergency_shortcut_buttons_group.xml
index 7911f30..54563c9 100644
--- a/res/layout/emergency_shortcut_buttons_group.xml
+++ b/res/layout/emergency_shortcut_buttons_group.xml
@@ -77,4 +77,4 @@
         android:divider="@drawable/emergency_shortcuts_divider"
         android:showDividers="middle">
     </LinearLayout>
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index c483565..37d5af3 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -131,7 +131,7 @@
     <string name="stk_cc_ss_to_ussd_error" msgid="6095812685884176176">"SS zahtjev je izmijenjen u USSD zahtjev"</string>
     <string name="stk_cc_ss_to_ss_error" msgid="7920654012697945858">"Izmijenjeno u novi SS zahtjev"</string>
     <string name="stk_cc_ss_to_dial_video_error" msgid="3873905132181743781">"SS zahtjev je izmijenjen u video poziv"</string>
-    <string name="fdn_check_failure" msgid="18200614306525434">"Uključena je postavka brojeva fiksnog biranja u Aplikaciji za telefon. Zbog toga ne rade neke funkcije vezane za pozive."</string>
+    <string name="fdn_check_failure" msgid="18200614306525434">"Uključena je postavka brojeva fiksnog biranja u aplikaciji Telefon. Zbog toga ne rade neke funkcije vezane za pozive."</string>
     <string name="radio_off_error" msgid="2304459933248513376">"Uključite radio prije prikazivanja ovih postavki."</string>
     <string name="close_dialog" msgid="2365884406356986917">"Uredu"</string>
     <string name="enable" msgid="7248657275000173526">"Uključi"</string>
@@ -172,7 +172,7 @@
     <string name="select_automatically" msgid="1046727200631770962">"Automatski odaberi mrežu"</string>
     <string name="manual_mode_disallowed_summary" msgid="70662262085937277">"Nedostupno kada ste povezani na mrežu %1$s"</string>
     <string name="network_select_title" msgid="7733107364757544558">"Mreža"</string>
-    <string name="register_automatically" msgid="6017849844573519637">"Automatska registracija u toku…"</string>
+    <string name="register_automatically" msgid="6017849844573519637">"Automatska registracija…"</string>
     <string name="preferred_network_mode_title" msgid="2336624679902659306">"Preferirana vrsta mreže"</string>
     <string name="preferred_network_mode_summary" msgid="1434820673166126609">"Promijeni način rada mreže"</string>
     <string name="preferred_network_mode_dialogtitle" msgid="4048082093347807230">"Preferirana vrsta mreže"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 58565c8..707d731 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -385,7 +385,7 @@
     <item msgid="6043847456049107742">"1"</item>
   </string-array>
     <string name="cdma_activate_device" msgid="3793805892364814518">"Activació del dispositiu"</string>
-    <string name="cdma_lte_data_service" msgid="4255018217292548962">"Configuració del servei de dades"</string>
+    <string name="cdma_lte_data_service" msgid="4255018217292548962">"Configura el servei de dades"</string>
     <string name="carrier_settings_title" msgid="9028166176523012300">"Configuració d\'operador"</string>
     <string name="fdn" msgid="7878832555095183202">"Números de marcatge fix"</string>
     <string name="fdn_with_label" msgid="187084204115493366">"Números de marcatge fix (<xliff:g id="SUBSCRIPTIONLABEL">%s</xliff:g>)"</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index b44d876..24caf82 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="phoneAppLabel" product="tablet" msgid="8576272342240415145">"Données mobiles"</string>
+    <string name="phoneAppLabel" product="tablet" msgid="8576272342240415145">"Données cellulaires"</string>
     <string name="phoneAppLabel" product="default" msgid="6790717591729922998">"Services téléphoniques"</string>
     <string name="emergencyDialerIconLabel" msgid="7812140032168171053">"Appels d\'urgence"</string>
     <string name="phoneIconLabel" msgid="2331230813161304895">"Téléphone"</string>
@@ -245,7 +245,7 @@
     <string name="roaming_enable" msgid="7331106985174381987">"Se connecter aux services de données lors de l\'itinérance"</string>
     <string name="roaming_disable" msgid="1843417228755568110">"Se connecter aux services de données lors de l\'itinérance"</string>
     <string name="roaming_reenable_message" msgid="6843814381576397939">"L\'itinérance des données est désactivée. Touchez pour l\'activer."</string>
-    <string name="roaming_notification_title" msgid="4749053220884743110">"Connexion de données mobiles perdue"</string>
+    <string name="roaming_notification_title" msgid="4749053220884743110">"Connexion de données cellulaires perdue"</string>
     <string name="roaming_warning" msgid="1603164667540144353">"Des frais importants peuvent s\'appliquer."</string>
     <string name="roaming_check_price_warning" msgid="7497570906830902550">"Communiquez avec votre fournisseur réseau pour connaître les tarifs."</string>
     <string name="roaming_alert_title" msgid="3654815360303826008">"Autoriser les données en itinérance?"</string>
@@ -260,7 +260,7 @@
     <string name="data_usage_disable_mobile" msgid="3577275288809667615">"Désactiver les données mobiles?"</string>
     <string name="sim_selection_required_pref" msgid="7049424902961844236">"Sélection requise"</string>
     <string name="sim_change_data_title" msgid="5332425991853799280">"Changer de SIM pour les données?"</string>
-    <string name="sim_change_data_message" msgid="2163963581444907496">"Utiliser la carte SIM <xliff:g id="NEW_SIM">%1$s</xliff:g> au lieu de la carte <xliff:g id="OLD_SIM">%2$s</xliff:g> pour les données mobiles?"</string>
+    <string name="sim_change_data_message" msgid="2163963581444907496">"Utiliser la carte SIM <xliff:g id="NEW_SIM">%1$s</xliff:g> au lieu de la carte <xliff:g id="OLD_SIM">%2$s</xliff:g> pour les données cellulaires?"</string>
     <string name="wifi_calling_settings_title" msgid="7741961465416430470">"Appels Wi-Fi"</string>
     <string name="video_calling_settings_title" msgid="539714564273795574">"Appels vidéo par l\'entremise du fournisseur de services"</string>
     <string name="gsm_umts_options" msgid="6538311689850981686">"Options GSM/UMTS"</string>
@@ -570,7 +570,7 @@
     <string name="ota_hfa_activation_title" msgid="2234246934160473981">"Activation en cours…"</string>
     <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"Le téléphone est en train d\'activer votre service de données cellulaires.\n\nCela peut prendre jusqu\'à cinq minutes."</string>
     <string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Ignorer l\'activation?"</string>
-    <string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Si vous poursuivez sans activer votre mobile, vous ne pourrez ni téléphoner, ni vous connecter à des réseaux de données mobiles. La connexion à un réseau Wi-Fi reste possible. Vous serez invité à effectuer l\'activation à chaque démarrage du téléphone."</string>
+    <string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Si vous poursuivez sans activer votre appareil mobile, vous ne pourrez ni téléphoner, ni vous connecter à des réseaux de données cellulaires. La connexion à un réseau Wi-Fi reste possible. Vous serez invité à effectuer l\'activation à chaque démarrage du téléphone."</string>
     <string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Passer"</string>
     <string name="ota_activate" msgid="1368528132525626264">"Activer"</string>
     <string name="ota_title_activate_success" msgid="6570240212263372046">"Votre téléphone est activé"</string>
@@ -654,12 +654,12 @@
     <string name="mobile_data_status_roaming_turned_on_subtext" msgid="1335176927083781041">"L\'itinérance de données est activée"</string>
     <string name="mobile_data_status_roaming_without_plan_subtext" msgid="3568412513831673037">"En itinérance. Un forfait de données est requis"</string>
     <string name="mobile_data_status_roaming_with_plan_subtext" msgid="8721998948811064377">"En itinérance. Le forfait de données est actif"</string>
-    <string name="mobile_data_status_no_plan_subtext" msgid="4887747337017565725">"Il ne reste plus de données mobiles"</string>
-    <string name="mobile_data_activate_prepaid" msgid="7447025165850512683">"Il ne reste plus de données mobiles"</string>
-    <string name="mobile_data_activate_prepaid_summary" msgid="5705389791791637666">"Ajouter des données mobiles par l\'intermédiaire de <xliff:g id="PROVIDER_NAME">%s</xliff:g>"</string>
+    <string name="mobile_data_status_no_plan_subtext" msgid="4887747337017565725">"Il ne reste plus de données cellulaires"</string>
+    <string name="mobile_data_activate_prepaid" msgid="7447025165850512683">"Il ne reste plus de données cellulaires"</string>
+    <string name="mobile_data_activate_prepaid_summary" msgid="5705389791791637666">"Ajouter des données cellulaires par l\'intermédiaire de <xliff:g id="PROVIDER_NAME">%s</xliff:g>"</string>
     <string name="mobile_data_activate_roaming_plan" msgid="5998161536947086264">"Aucun forfait d\'itinérance"</string>
     <string name="mobile_data_activate_roaming_plan_summary" msgid="511202908883425459">"Ajouter un forfait d\'itinérance par l\'intermédiaire de <xliff:g id="PROVIDER_NAME">%s</xliff:g>"</string>
-    <string name="mobile_data_activate_footer" msgid="5979019929980140594">"Vous pouvez ajouter des données mobiles ou un forfait d\'itinérance par l\'intermédiaire de votre fournisseur de services, <xliff:g id="PROVIDER_NAME">%s</xliff:g>."</string>
+    <string name="mobile_data_activate_footer" msgid="5979019929980140594">"Vous pouvez ajouter des données cellulaires ou un forfait d\'itinérance par l\'intermédiaire de votre fournisseur de services, <xliff:g id="PROVIDER_NAME">%s</xliff:g>."</string>
     <string name="mobile_data_activate_diag_title" msgid="9044252207707864493">"Ajouter des données?"</string>
     <string name="mobile_data_activate_diag_message" msgid="8216154678758451453">"Vous devrez peut-être ajouter des données par l\'intermédiaire de <xliff:g id="PROVIDER_NAME">%s</xliff:g>"</string>
     <string name="mobile_data_activate_button" msgid="3682400969184405446">"AJOUTER DES DONNÉES"</string>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index 8efa8c7..e2616ae 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -276,11 +276,11 @@
     <!-- String.format failed for translation -->
     <!-- no translation found for throttle_data_usage_subtext (6029276011123694701) -->
     <skip />
-    <string name="throttle_data_rate_reduced_subtext" msgid="7492763592720107737">"<xliff:g id="USED_0">%1$s</xliff:g> առավելագույնը գերազանցվել է\nՏվյալների արժեքը նվազել է մինչև <xliff:g id="USED_1">%2$d</xliff:g> կբիթ/վ"</string>
+    <string name="throttle_data_rate_reduced_subtext" msgid="7492763592720107737">"<xliff:g id="USED_0">%1$s</xliff:g> առավելագույնը գերազանցվել է\nՏվյալների արժեքը նվազել է մինչև <xliff:g id="USED_1">%2$d</xliff:g> Կբիթ/վ"</string>
     <!-- String.format failed for translation -->
     <!-- no translation found for throttle_time_frame_subtext (7732763021560399960) -->
     <skip />
-    <string name="throttle_rate_subtext" msgid="2149102656120726855">"Տվյալների ծավալը կնվազի մինչև <xliff:g id="USED">%1$d</xliff:g> կբիթ/վ, եթե տվյալների օգտագործման սահմանաչափը գերազանցվի"</string>
+    <string name="throttle_rate_subtext" msgid="2149102656120726855">"Տվյալների ծավալը կնվազի մինչև <xliff:g id="USED">%1$d</xliff:g> Կբիթ/վ, եթե տվյալների օգտագործման սահմանաչափը գերազանցվի"</string>
     <string name="throttle_help_subtext" msgid="5217706521499010816">"Լրացուցիչ տեղեկություններ ձեր սպասարկողի բջջային ցանցի տվյալների օգտագործման քաղաքականության մասին"</string>
     <string name="cell_broadcast_sms" msgid="5584192824053625842">"Բջջային հեռարձակման SMS"</string>
     <string name="enable_disable_cell_bc_sms" msgid="4851147873691392255">"Բջջային հեռարձակման SMS"</string>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index 26efa51..d112f09 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -46,7 +46,7 @@
     <string name="no_vm_number_msg" msgid="1300729501030053828">"सिम कार्डवर कोणताही व्हॉइसमेल नंबर स्टोअर केला नाही."</string>
     <string name="add_vm_number_str" msgid="4676479471644687453">"नंबर जोडा"</string>
     <string name="voice_number_setting_primary_user_only" msgid="6596604364907022416">"केवळ प्राथमिक वापरकर्ता व्हॉइसमेल सेटिंग्ज बदलू शकतो."</string>
-    <string name="puk_unlocked" msgid="2284912838477558454">"आपले सिम कार्ड अवरोधित करणे रद्द केले गेले आहे. आपला फोन अनलॉक होत आहे…"</string>
+    <string name="puk_unlocked" msgid="2284912838477558454">"तुमचे सिम कार्ड अवरोधित करणे रद्द केले गेले आहे. तुमचा फोन अनलॉक होत आहे…"</string>
     <string name="label_ndp" msgid="780479633159517250">"सिम नेटवर्क अनलॉक पिन"</string>
     <string name="sim_ndp_unlock_text" msgid="683628237760543009">"अनलॉक करा"</string>
     <string name="sim_ndp_dismiss_text" msgid="1604823375752456947">"डिसमिस करा"</string>
@@ -107,17 +107,17 @@
     <string name="messageCFB" msgid="3711089705936187129">"नंबर व्‍यस्‍त असताना"</string>
     <string name="sum_cfb_enabled" msgid="5984198104833116690">"<xliff:g id="PHONENUMBER">{0}</xliff:g> वर अग्रेषित करत आहे"</string>
     <string name="sum_cfb_disabled" msgid="4913145177320506827">"बंद"</string>
-    <string name="disable_cfb_forbidden" msgid="3506984333877998061">"आपला फोन व्‍यस्‍त असताना आपला ऑपरेटर कॉल अग्रेषण करणे अक्षम करण्‍यास समर्थन करीत नाही."</string>
+    <string name="disable_cfb_forbidden" msgid="3506984333877998061">"तुमचा फोन व्‍यस्‍त असताना तुमचा ऑपरेटर कॉल अग्रेषण करणे अक्षम करण्‍यास समर्थन करीत नाही."</string>
     <string name="labelCFNRy" msgid="1736067178393744351">"उत्तर न दिल्यास"</string>
     <string name="messageCFNRy" msgid="672317899884380374">"नंबर अनुत्तरित असताना"</string>
     <string name="sum_cfnry_enabled" msgid="6955775691317662910">"<xliff:g id="PHONENUMBER">{0}</xliff:g> वर अग्रेषित करत आहे"</string>
     <string name="sum_cfnry_disabled" msgid="3884684060443538097">"बंद"</string>
-    <string name="disable_cfnry_forbidden" msgid="4308233959150658058">"आपला फोन उत्तर देत नसताना आपला ऑपरेटर कॉल अग्रेषण करणे अक्षम करण्‍यास समर्थन करीत नाही."</string>
+    <string name="disable_cfnry_forbidden" msgid="4308233959150658058">"तुमचा फोन उत्तर देत नसताना तुमचा ऑपरेटर कॉल अग्रेषण करणे अक्षम करण्‍यास समर्थन करीत नाही."</string>
     <string name="labelCFNRc" msgid="2614827454402079766">"पोहचण्‍यायोग्‍य नसताना"</string>
     <string name="messageCFNRc" msgid="6380695421020295119">"नंबर पोहचण्‍यायोग्‍य नसताना"</string>
     <string name="sum_cfnrc_enabled" msgid="7010898346095497421">"<xliff:g id="PHONENUMBER">{0}</xliff:g> वर अग्रेषित करत आहे"</string>
     <string name="sum_cfnrc_disabled" msgid="2684474391807469832">"बंद"</string>
-    <string name="disable_cfnrc_forbidden" msgid="5646361343094064333">"आपला फोन पोहचण्‍यायोग्‍य नसताना आपला वाहक कॉल अग्रेषण करणे अक्षम करण्‍यास समर्थन करीत नाही."</string>
+    <string name="disable_cfnrc_forbidden" msgid="5646361343094064333">"तुमचा फोन पोहचण्‍यायोग्‍य नसताना तुमचा वाहक कॉल अग्रेषण करणे अक्षम करण्‍यास समर्थन करीत नाही."</string>
     <string name="updating_title" msgid="6146755386174019046">"कॉल सेटिंग्ज"</string>
     <string name="call_settings_admin_user_only" msgid="4526094783818216374">"कॉल सेटिंग्ज केवळ प्रशासक वापरकर्त्याद्वारे बदलल्‍या जाऊ शकतात."</string>
     <string name="call_settings_with_label" msgid="3401177261468593519">"सेटिंग्ज (<xliff:g id="SUBSCRIPTIONLABEL">%s</xliff:g>)"</string>
@@ -148,7 +148,7 @@
     <string name="fw_get_in_vm_failed" msgid="8862896836093833973">"वर्तमान अग्रेषण नंबर सेटिंग्‍ज पुनर्प्राप्त करू शकलो नाही आणि सेव्ह करू शकलो नाही.\nतरीही नवीन प्रदात्‍यावर स्‍विच करायचे?"</string>
     <string name="no_change" msgid="3186040086622435212">"कोणतेही बदल केले नाहीत."</string>
     <string name="sum_voicemail_choose_provider" msgid="59911196126278922">"व्हॉइसमेल सेवा निवडा"</string>
-    <string name="voicemail_default" msgid="2001233554889016880">"आपला वाहक"</string>
+    <string name="voicemail_default" msgid="2001233554889016880">"तुमचा वाहक"</string>
     <string name="vm_change_pin_old_pin" msgid="7295220109886682573">"जुना पिन"</string>
     <string name="vm_change_pin_new_pin" msgid="5412922262839438097">"नवीन पिन"</string>
     <string name="vm_change_pin_progress_message" msgid="3977357361934350336">"कृपया प्रतीक्षा करा."</string>
@@ -165,7 +165,7 @@
     <string name="empty_networks_list" msgid="4249426905018815316">"कोणतीही नेटवर्क आढळली नाहीत."</string>
     <string name="network_query_error" msgid="8466081377231178298">"नेटवर्क मिळू शकले नाहीत. पुन्‍हा प्रयत्‍न करा."</string>
     <string name="register_on_network" msgid="9055203954040805084">"<xliff:g id="NETWORK">%s</xliff:g> वर नोंदणी करत आहे…"</string>
-    <string name="not_allowed" msgid="5613353860205691579">"आपले सिम कार्ड या नेटवर्कच्‍या कनेक्‍शनला अनुमती देत नाही."</string>
+    <string name="not_allowed" msgid="5613353860205691579">"तुमचे सिम कार्ड या नेटवर्कच्‍या कनेक्‍शनला अनुमती देत नाही."</string>
     <string name="connect_later" msgid="2308119155752343975">"आत्ता या नेटवर्कशी कनेक्‍ट करू शकत नाही. नंतर पुन्‍हा प्रयत्‍न करा."</string>
     <string name="registration_done" msgid="495135664535876612">"नेटवर्कवर नोंदणी केली."</string>
     <string name="already_auto" msgid="6067116884321285507">"आपोआप निवडीमध्‍ये आधीपासून आहे."</string>
@@ -426,7 +426,7 @@
     <string name="delete_fdn_contact" msgid="6668958073074151717">"निश्चित डायलिंग नंबर हटवा"</string>
     <string name="deleting_fdn_contact" msgid="5669163206349319969">"निश्चित डायलिंग नंबर हटवित आहे..."</string>
     <string name="fdn_contact_deleted" msgid="7154162327112259569">"निश्चित डायलिंग नंबर हटवला."</string>
-    <string name="pin2_invalid" msgid="5470854099230755944">"आपण चुकीचा पिन टाईप केल्‍याने FDN अपडेट केले नव्‍हते."</string>
+    <string name="pin2_invalid" msgid="5470854099230755944">"तुम्ही चुकीचा पिन टाईप केल्‍याने FDN अपडेट केले नव्‍हते."</string>
     <string name="fdn_invalid_number" msgid="2062898833049589309">"FDN अपडेट केलेले नाही, कारण क्रमांक २० अंकांनी जास्‍त होत आहेत."</string>
     <string name="pin2_or_fdn_invalid" msgid="6025144083384701197">"FDN अपडेट केले नव्‍हते. PIN2 चुकीचा होता किंवा फोन नंबरला नकार दिला."</string>
     <string name="fdn_failed" msgid="540018079008319747">"FDN कार्य अयशस्‍वी झाले."</string>
@@ -440,8 +440,8 @@
     <string name="oldPinLabel" msgid="5287773661246368314">"जुना पिन"</string>
     <string name="newPinLabel" msgid="207488227285336897">"नवीन पिन"</string>
     <string name="confirmPinLabel" msgid="257597715098070206">"नवीन पिन ची पुष्‍टी करा"</string>
-    <string name="badPin" msgid="8955102849303984935">"आपण टाईप केलेला जुना पिन बरोबर नाही. पुन्‍हा प्रयत्‍न करा."</string>
-    <string name="mismatchPin" msgid="5923253370683071889">"आपण टाईप केले ते पिन जुळत नाहीत. पुन्‍हा प्रयत्‍न करा."</string>
+    <string name="badPin" msgid="8955102849303984935">"तुम्ही टाईप केलेला जुना पिन बरोबर नाही. पुन्‍हा प्रयत्‍न करा."</string>
+    <string name="mismatchPin" msgid="5923253370683071889">"तुम्ही टाईप केले ते पिन जुळत नाहीत. पुन्‍हा प्रयत्‍न करा."</string>
     <string name="invalidPin" msgid="5981171102258684792">"4 ते 8 अंकांचा पिन टाईप करा."</string>
     <string name="disable_sim_pin" msgid="3419351358300716472">"सिम पिन साफ करा"</string>
     <string name="enable_sim_pin" msgid="4845145659651484248">"सिम पिन सेट करा"</string>
@@ -561,12 +561,12 @@
   </string-array>
     <string name="network_info_message" msgid="7738596060242881930">"नेटवर्क मेसेज"</string>
     <string name="network_error_message" msgid="3394780436230411413">"एरर मेसेज"</string>
-    <string name="ota_title_activate" msgid="8616918561356194398">"आपला फोन सक्रिय करा"</string>
-    <string name="ota_touch_activate" msgid="6553212803262586244">"तुमची फोन सेवा सक्रिय करण्‍यासाठी एक विशिष्‍ट कॉल केला जाणे आवश्‍यक आहे. \n\n“सक्रिय करा” दाबल्‍यानंतर, आपला फोन सक्रिय करण्‍यासाठी प्रदान केलेल्‍या सूचना ऐका."</string>
+    <string name="ota_title_activate" msgid="8616918561356194398">"तुमचा फोन सक्रिय करा"</string>
+    <string name="ota_touch_activate" msgid="6553212803262586244">"तुमची फोन सेवा सक्रिय करण्‍यासाठी एक विशिष्‍ट कॉल केला जाणे आवश्‍यक आहे. \n\n“सक्रिय करा” दाबल्‍यानंतर, तुमचा फोन सक्रिय करण्‍यासाठी प्रदान केलेल्‍या सूचना ऐका."</string>
     <string name="ota_hfa_activation_title" msgid="2234246934160473981">"सक्रिय करत आहे..."</string>
     <string name="ota_hfa_activation_dialog_message" msgid="8092479227918463415">"फोन तुमची मोबाइल डेटा सेवा सक्रिय करत आहे.\n\nयास सुमारे 5 मिनिटे लागतील."</string>
     <string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"सक्रिय करणे वगळायचे?"</string>
-    <string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"आपण सक्रिय करणे वगळल्‍यास, आपण कॉल करू शकत नाही किंवा मोबाइल डेटा नेटवर्कशी कनेक्‍ट करू शकत नाही (आपण वाय-फाय नेटवर्कशी कनेक्‍ट करू शकत असला तरीही). आपण आपला फोन सक्रिय करेपर्यंत, आपण तो प्रत्‍येक वेळी चालू करताना आपल्‍याला तो सक्रिय करण्‍यास सांगितले जाईल."</string>
+    <string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"तुम्ही सक्रिय करणे वगळल्‍यास, तुम्ही कॉल करू शकत नाही किंवा मोबाइल डेटा नेटवर्कशी कनेक्‍ट करू शकत नाही (तुम्ही वाय-फाय नेटवर्कशी कनेक्‍ट करू शकत असला तरीही). तुम्ही तुमचा फोन सक्रिय करेपर्यंत, तुम्ही तो प्रत्‍येक वेळी चालू करताना आपल्‍याला तो सक्रिय करण्‍यास सांगितले जाईल."</string>
     <string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"वगळा"</string>
     <string name="ota_activate" msgid="1368528132525626264">"सक्रिय करा"</string>
     <string name="ota_title_activate_success" msgid="6570240212263372046">"फोन सक्रिय केला आहे."</string>
@@ -574,9 +574,9 @@
     <string name="ota_listen" msgid="162923839877584937">"सक्रिय करणे पूर्ण झाले आहे असे आपल्‍याला ऐकू येईपर्यंत बोललेल्‍या सूचनांचे फॉलो करा."</string>
     <string name="ota_speaker" msgid="6904589278542719647">"स्पीकर"</string>
     <string name="ota_progress" msgid="460876637828044519">"आपल्‍या फोनचे प्रोग्रामिंग करत आहे…"</string>
-    <string name="ota_failure" msgid="7713756181204620397">"आपला फोन प्रोग्राम करणे शक्य झाले नाही"</string>
-    <string name="ota_successful" msgid="1880780692887077407">"आपला फोन आता सक्रिय केला आहे. सेवा सुरू होण्‍यास सुमारे 15 मिनिटे लागू शकतात."</string>
-    <string name="ota_unsuccessful" msgid="8072141612635635357">"आपला फोन सक्रिय केला नव्‍हता. \nआपल्‍याला अधिक चांगले कव्‍हरेज असलेले क्षेत्र (खिडकीजवळ किंवा बाहेर) शोधण्‍याची आवश्‍यकता असू शकते. \n\nपुन्‍हा प्रयत्‍न करा किंवा अधिक पर्यायांसाठी ग्राहक सेवेस कॉल करा."</string>
+    <string name="ota_failure" msgid="7713756181204620397">"तुमचा फोन प्रोग्राम करणे शक्य झाले नाही"</string>
+    <string name="ota_successful" msgid="1880780692887077407">"तुमचा फोन आता सक्रिय केला आहे. सेवा सुरू होण्‍यास सुमारे 15 मिनिटे लागू शकतात."</string>
+    <string name="ota_unsuccessful" msgid="8072141612635635357">"तुमचा फोन सक्रिय केला नव्‍हता. \nआपल्‍याला अधिक चांगले कव्‍हरेज असलेले क्षेत्र (खिडकीजवळ किंवा बाहेर) शोधण्‍याची आवश्‍यकता असू शकते. \n\nपुन्‍हा प्रयत्‍न करा किंवा अधिक पर्यायांसाठी ग्राहक सेवेस कॉल करा."</string>
     <string name="ota_spc_failure" msgid="3909983542575030796">"अत्‍याधिक SPC अपयश"</string>
     <string name="ota_call_end" msgid="4537279738134612388">"मागील"</string>
     <string name="ota_try_again" msgid="7685477206465902290">"पुन्हा प्रयत्न करा"</string>
@@ -587,12 +587,12 @@
     <string name="phone_in_ecm_call_notification_text" msgid="4611608947314729773">"डेटा कनेक्शन अक्षम केले"</string>
     <string name="phone_in_ecm_notification_complete_time" msgid="7730376844178948351">"<xliff:g id="COMPLETETIME">%s</xliff:g> पर्यंत कोणतेही डेटा कनेक्‍शन नाही"</string>
     <plurals name="alert_dialog_exit_ecm" formatted="false" msgid="7179911675595441201">
-      <item quantity="one">फोन <xliff:g id="COUNT_1">%s</xliff:g> मिनिटासाठी आणीबाणी कॉलबॅक मोडमध्ये राहील. या मोडमध्ये असताना डेटा कनेक्शन वापरणारे कोणतेही अॅप्लिकेशन वापरले जाऊ शकत नाहीत. आपण आता बाहेर पडू इच्छिता?</item>
-      <item quantity="other">फोन <xliff:g id="COUNT_1">%s</xliff:g> मिनिटांसाठी आणीबाणी कॉलबॅक मोडमध्ये राहील. या मोडमध्ये असताना डेटा कनेक्शन वापरणारे कोणतेही अॅप्लिकेशन वापरले जाऊ शकत नाहीत. आपण आता बाहेर पडू इच्छिता?</item>
+      <item quantity="one">फोन <xliff:g id="COUNT_1">%s</xliff:g> मिनिटासाठी आणीबाणी कॉलबॅक मोडमध्ये राहील. या मोडमध्ये असताना डेटा कनेक्शन वापरणारे कोणतेही अॅप्लिकेशन वापरले जाऊ शकत नाहीत. तुम्ही आता बाहेर पडू इच्छिता?</item>
+      <item quantity="other">फोन <xliff:g id="COUNT_1">%s</xliff:g> मिनिटांसाठी आणीबाणी कॉलबॅक मोडमध्ये राहील. या मोडमध्ये असताना डेटा कनेक्शन वापरणारे कोणतेही अॅप्लिकेशन वापरले जाऊ शकत नाहीत. तुम्ही आता बाहेर पडू इच्छिता?</item>
     </plurals>
     <plurals name="alert_dialog_not_avaialble_in_ecm" formatted="false" msgid="8042973425225093895">
-      <item quantity="one">आणीबाणी कॉलबॅक मोडमध्ये असताना निवडलेली क्रिया उपलब्ध नसते. फोन <xliff:g id="COUNT_1">%s</xliff:g> मिनिटासाठी या मोडमध्ये राहील. आपण आता बाहेर पडू इच्छिता?</item>
-      <item quantity="other">आणीबाणी कॉलबॅक मोडमध्ये असताना निवडलेली क्रिया उपलब्ध नसते. फोन <xliff:g id="COUNT_1">%s</xliff:g> मिनिटांसाठी या मोडमध्ये राहील. आपण आता बाहेर पडू इच्छिता?</item>
+      <item quantity="one">आणीबाणी कॉलबॅक मोडमध्ये असताना निवडलेली क्रिया उपलब्ध नसते. फोन <xliff:g id="COUNT_1">%s</xliff:g> मिनिटासाठी या मोडमध्ये राहील. तुम्ही आता बाहेर पडू इच्छिता?</item>
+      <item quantity="other">आणीबाणी कॉलबॅक मोडमध्ये असताना निवडलेली क्रिया उपलब्ध नसते. फोन <xliff:g id="COUNT_1">%s</xliff:g> मिनिटांसाठी या मोडमध्ये राहील. तुम्ही आता बाहेर पडू इच्छिता?</item>
     </plurals>
     <string name="alert_dialog_in_ecm_call" msgid="1886723687211887104">"आणीबाणीच्‍या कॉलमध्‍ये असताना निवडलेली क्रिया उपलब्‍ध नसते."</string>
     <string name="progress_dialog_exiting_ecm" msgid="4835734101617817074">"आणीबाणी कॉलबॅक मोडमधून बाहेर पडत आहे"</string>
@@ -639,7 +639,7 @@
     <string name="change_pin_cancel_label" msgid="353535488390948596">"रद्द करा"</string>
     <string name="change_pin_ok_label" msgid="6204308560844889926">"ठीक आहे"</string>
     <string name="change_pin_enter_old_pin_header" msgid="419179847657548887">"आपल्या जुन्या पिनची पुष्टी करा"</string>
-    <string name="change_pin_enter_old_pin_hint" msgid="8579171678763615453">"सुरु ठेवण्‍यासाठी आपला व्हॉइसमेल पिन प्रविष्‍ट करा."</string>
+    <string name="change_pin_enter_old_pin_hint" msgid="8579171678763615453">"सुरु ठेवण्‍यासाठी तुमचा व्हॉइसमेल पिन प्रविष्‍ट करा."</string>
     <string name="change_pin_enter_new_pin_header" msgid="2611191814590251532">"नवीन पिन सेट करा"</string>
     <string name="change_pin_enter_new_pin_hint" msgid="2322940054329689309">"पिन <xliff:g id="MIN">%1$d</xliff:g>-<xliff:g id="MAX">%2$d</xliff:g> अंकी असणे आवश्‍यक आहे."</string>
     <string name="change_pin_confirm_pin_header" msgid="8113764019347322170">"आपल्या पिनची पुष्टी करा"</string>
@@ -655,9 +655,9 @@
     <string name="mobile_data_activate_prepaid_summary" msgid="5705389791791637666">"<xliff:g id="PROVIDER_NAME">%s</xliff:g> द्वारे मोबाइल डेटा जोडा"</string>
     <string name="mobile_data_activate_roaming_plan" msgid="5998161536947086264">"कोणतीही रोमिंग योजना नाही"</string>
     <string name="mobile_data_activate_roaming_plan_summary" msgid="511202908883425459">"<xliff:g id="PROVIDER_NAME">%s</xliff:g> द्वारे रोमिंग योजना जोडा"</string>
-    <string name="mobile_data_activate_footer" msgid="5979019929980140594">"आपण आपल्या <xliff:g id="PROVIDER_NAME">%s</xliff:g> वाहकाद्वारे मोबाइल डेटा किंवा रोमिंग योजना जोडू शकता."</string>
+    <string name="mobile_data_activate_footer" msgid="5979019929980140594">"तुम्ही आपल्या <xliff:g id="PROVIDER_NAME">%s</xliff:g> वाहकाद्वारे मोबाइल डेटा किंवा रोमिंग योजना जोडू शकता."</string>
     <string name="mobile_data_activate_diag_title" msgid="9044252207707864493">"डेटा जोडायचा?"</string>
-    <string name="mobile_data_activate_diag_message" msgid="8216154678758451453">"आपल्याला <xliff:g id="PROVIDER_NAME">%s</xliff:g> द्वारे डेटा जोडण्याची आवश्यकता असू शकते"</string>
+    <string name="mobile_data_activate_diag_message" msgid="8216154678758451453">"तुम्हाला <xliff:g id="PROVIDER_NAME">%s</xliff:g> द्वारे डेटा जोडण्याची आवश्यकता असू शकते"</string>
     <string name="mobile_data_activate_button" msgid="3682400969184405446">"डेटा जोडा"</string>
     <string name="mobile_data_activate_cancel_button" msgid="1708022171547398765">"रद्द करा"</string>
     <string name="clh_card_title_call_ended_txt" msgid="4072101334811753823">"कॉल संपला"</string>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 9a137ff..3a71328 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -386,7 +386,7 @@
   </string-array>
     <string name="cdma_activate_device" msgid="3793805892364814518">"Kích hoạt thiết bị"</string>
     <string name="cdma_lte_data_service" msgid="4255018217292548962">"Thiết lập dịch vụ dữ liệu"</string>
-    <string name="carrier_settings_title" msgid="9028166176523012300">"Cài đặt nhà cung cấp dịch vụ"</string>
+    <string name="carrier_settings_title" msgid="9028166176523012300">"Cài đặt nhà mạng"</string>
     <string name="fdn" msgid="7878832555095183202">"Số gọi định sẵn"</string>
     <string name="fdn_with_label" msgid="187084204115493366">"Số gọi định sẵn (<xliff:g id="SUBSCRIPTIONLABEL">%s</xliff:g>)"</string>
     <string name="manage_fdn_list" msgid="8777755791892122369">"Danh sách FDN"</string>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index cc6f727..065515a 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -40,9 +40,9 @@
     <color name="phone_settings_actionbar_text_color">#FFFFFF</color>
     <!-- Background color of action bars.  Ensure this stays in sync with Dialer
          actionbar_background_color. -->
-    <color name="actionbar_background_color">@color/dialer_theme_color</color>
+    <color name="actionbar_background_color">#fafafa</color>
     <!-- Dark variant of the action bar color.  Ensure this stays in sync with Dialer version. -->
-    <color name="actionbar_background_color_dark">@color/dialer_theme_color_dark</color>
+    <color name="actionbar_background_color_dark">#fafafa</color>
     <!-- Color for icons in the actionbar. Ensure this stays in sync with Dialer version. -->
     <color name="actionbar_icon_color">#ffffff</color>
 
@@ -56,4 +56,11 @@
     <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">#fafafa</color>
+    <color name="dialer_divider_color">#d8d8d8</color>
+    <color name="dialer_primary_text_color">#202124</color>
+    <color name="dialer_secondary_text_color">#5f6368</color>
+
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 38241de..23d20fc 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -202,4 +202,13 @@
 
     <!-- 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>
+
+    <!-- The text size for items in settings page.-->
+    <dimen name="dialer_primary2_font_size">16dp</dimen>
+
+    <!-- The text size for description in settings page.-->
+    <dimen name="dialer_secondary_font_size">14dp</dimen>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 8fd194a..d2845ae 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1761,6 +1761,9 @@
     <string name="call_barring_settings">Call barring settings</string>
     <!-- Call barring settings screen, deactivate all call barring settings -->
     <string name="call_barring_deactivate_all_no_password">Deactivate all call barring settings?</string>
+    <!-- In-call screen: error message shown when the user attempts to place a call, but the network
+         does not have enough resources (e.g. it is busy) and the call cannot be placed. -->
+    <string name="callFailed_NetworkBusy">Network is busy.  Please try your call again later.</string>
     <!-- Message displayed to the user when an outgoing call is deflected.  This means that the
          party the user is calling has chosen to send the call to another phone number. -->
     <string name="supp_service_notification_call_deflected">Call deflected.</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 6093cee..f2db63d 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -159,7 +159,6 @@
         <item name="android:actionBarStyle">@style/DialtactsActionBarStyle</item>
         <item name="android:actionMenuTextColor">@color/phone_settings_actionbar_text_color</item>
         <item name="android:actionOverflowButtonStyle">@style/DialtactsActionBarOverflow</item>
-        <item name="android:homeAsUpIndicator">@drawable/ic_back_arrow</item>
         <item name="android:windowActionBarOverlay">false</item>
         <item name="android:colorPrimaryDark">@color/actionbar_background_color_dark</item>
         <!-- Setting text. -->
@@ -169,6 +168,15 @@
     </style>
 
     <style name="DialerSettingsLight" parent="SettingsLight">
+        <!-- Action bar.-->
+        <item name="android:tint">@color/dialer_secondary_text_color</item>
+        <item name="android:windowBackground">@color/dialer_background_color</item>
+        <item name="android:actionModeBackground">@color/dialer_background_color</item>
+        <item name="android:windowLightStatusBar">true</item>
+        <!-- Navigation bar.-->
+        <item name="android:navigationBarColor">@color/dialer_background_color</item>
+        <item name="android:navigationBarDividerColor">@color/dialer_divider_color</item>
+        <item name="android:windowLightNavigationBar">true</item>
         <item name="android:colorAccent">@color/dialer_theme_color</item>
         <item name="android:dialogTheme">@style/DialerAlertDialogTheme</item>
     </style>
@@ -248,7 +256,9 @@
     <!-- Text in the action bar at the top of the screen.  Should be kept in sync with Dialer. -->
     <style name="DialtactsActionBarTitleText"
            parent="@android:style/TextAppearance.Material.Widget.ActionBar.Title">
-        <item name="android:textColor">@color/phone_settings_actionbar_text_color</item>
+        <item name="android:textColor">@color/dialer_primary_text_color</item>
+        <item name="android:textSize">@dimen/dialer_head1_font_size</item>
+        <item name="android:fontFamily">sans-serif-regular</item>
     </style>
 
     <!-- Action bar overflow menu icon. -->
diff --git a/sip/res/values-mr/strings.xml b/sip/res/values-mr/strings.xml
index 5c05fe9..e09b33d 100644
--- a/sip/res/values-mr/strings.xml
+++ b/sip/res/values-mr/strings.xml
@@ -71,8 +71,8 @@
     <string name="all_empty_alert" msgid="4087734950375192387">"नवीन SIP खात्याचा तपशील एंटर करा."</string>
     <string name="empty_alert" msgid="6659484914371384024">"<xliff:g id="INPUT_FIELD_NAME">%s</xliff:g> आवश्‍यक आहे आणि रिक्त सोडले जाऊ शकत नाही."</string>
     <string name="not_a_valid_port" msgid="7931422555587011830">"पोर्ट नंबर 1000 आणि 65534 मध्‍ये असावा."</string>
-    <string name="no_internet_available" msgid="5523747991760017298">"एक SIP कॉल करण्‍यासाठी, प्रथम आपले इंटरनेट कनेक्‍शन तपासा."</string>
-    <string name="no_wifi_available" msgid="1955023904229673488">"SIP कॉलसाठी आपण वाय-फाय नेटवर्कशी कनेक्‍ट केलेले असणे आवश्‍यक आहे (वायरलेस &amp; नेटवर्क सेटिंग्ज वापरा)."</string>
+    <string name="no_internet_available" msgid="5523747991760017298">"एक SIP कॉल करण्‍यासाठी, प्रथम तुमचे इंटरनेट कनेक्‍शन तपासा."</string>
+    <string name="no_wifi_available" msgid="1955023904229673488">"SIP कॉलसाठी तुम्ही वाय-फाय नेटवर्कशी कनेक्‍ट केलेले असणे आवश्‍यक आहे (वायरलेस &amp; नेटवर्क सेटिंग्ज वापरा)."</string>
     <string name="no_voip" msgid="3038021971231952704">"SIP कॉल करणे समर्थित नाही"</string>
     <string name="sip_system_decide" msgid="5577696249416700671">"स्वयंचलित"</string>
     <string name="sip_always_send_keepalive" msgid="4773022409239823318">"नेहमी पाठवा"</string>
diff --git a/sip/src/com/android/services/telephony/sip/SipUtil.java b/sip/src/com/android/services/telephony/sip/SipUtil.java
index d674225..ff38754 100644
--- a/sip/src/com/android/services/telephony/sip/SipUtil.java
+++ b/sip/src/com/android/services/telephony/sip/SipUtil.java
@@ -134,7 +134,7 @@
                 .setAddress(sipUri)
                 .setShortDescription(sipAddress)
                 .setIcon(Icon.createWithResource(
-                        context.getResources(), R.drawable.ic_dialer_sip_black_24dp))
+                        context, R.drawable.ic_dialer_sip_black_24dp))
                 .setExtras(phoneAccountExtras)
                 .setSupportedUriSchemes(supportedUriSchemes);
 
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index 92af129..0cb93aa 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -37,7 +37,9 @@
 import android.telecom.TelecomManager;
 import android.telephony.CarrierConfigManager;
 import android.telephony.PhoneStateListener;
+import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.telephony.ims.ProvisioningManager;
 import android.telephony.ims.feature.ImsFeature;
 import android.util.Log;
 import android.view.MenuItem;
@@ -214,10 +216,32 @@
         }
     };
 
+    private final ProvisioningManager.Callback mProvisioningCallback =
+            new ProvisioningManager.Callback() {
+        @Override
+        public void onProvisioningIntChanged(int item, int value) {
+            if (item == ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED
+                    || item == ImsConfig.ConfigConstants.VLT_SETTING_ENABLED
+                    || item == ImsConfig.ConfigConstants.LVC_SETTING_ENABLED) {
+                updateVtWfc();
+            }
+        }
+    };
+
     @Override
     protected void onPause() {
         super.onPause();
         listenPhoneState(false);
+
+        // Remove callback for provisioning changes.
+        try {
+            if (mImsMgr != null) {
+                mImsMgr.getConfigInterface().removeConfigCallback(
+                        mProvisioningCallback.getBinder());
+            }
+        } catch (ImsException e) {
+            Log.w(LOG_TAG, "onPause: Unable to remove callback for provisioning changes");
+        }
     }
 
     @Override
@@ -310,7 +334,24 @@
                 }
             }
         }
+        updateVtWfc();
 
+        // Register callback for provisioning changes.
+        try {
+            if (mImsMgr != null) {
+                mImsMgr.getConfigInterface().addConfigCallback(mProvisioningCallback);
+            }
+        } catch (ImsException e) {
+            Log.w(LOG_TAG, "onResume: Unable to register callback for provisioning changes.");
+        }
+    }
+
+    private void updateVtWfc() {
+        PreferenceScreen prefSet = getPreferenceScreen();
+        TelephonyManager telephonyManager = getSystemService(TelephonyManager.class)
+                .createForSubscriptionId(mPhone.getSubId());
+        PersistableBundle carrierConfig =
+                PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
         if (mImsMgr.isVtEnabledByPlatform() && mImsMgr.isVtProvisionedOnDevice()
                 && (carrierConfig.getBoolean(
                         CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS)
@@ -320,6 +361,7 @@
                     ? mImsMgr.isVtEnabledByUser() : false;
             mEnableVideoCalling.setChecked(currentValue);
             mEnableVideoCalling.setOnPreferenceChangeListener(this);
+            prefSet.addPreference(mEnableVideoCalling);
         } else {
             prefSet.removePreference(mEnableVideoCalling);
         }
@@ -335,6 +377,7 @@
                     mButtonWifiCalling.setTitle(resolutions.get(0).loadLabel(pm));
                     mButtonWifiCalling.setSummary(null);
                     mButtonWifiCalling.setIntent(intent);
+                    prefSet.addPreference(mButtonWifiCalling);
                 } else {
                     prefSet.removePreference(mButtonWifiCalling);
                 }
@@ -344,6 +387,10 @@
         } else if (!mImsMgr.isWfcEnabledByPlatform() || !mImsMgr.isWfcProvisionedOnDevice()) {
             prefSet.removePreference(mButtonWifiCalling);
         } else {
+            String title = SubscriptionManager.getResourcesForSubId(mPhone.getContext(),
+                    mPhone.getSubId()).getString(R.string.wifi_calling);
+            mButtonWifiCalling.setTitle(title);
+
             int resId = com.android.internal.R.string.wifi_calling_off_summary;
             if (mImsMgr.isWfcEnabledByUser()) {
                 boolean isRoaming = telephonyManager.isNetworkRoaming();
@@ -363,6 +410,7 @@
                 }
             }
             mButtonWifiCalling.setSummary(resId);
+            prefSet.addPreference(mButtonWifiCalling);
         }
 
         try {
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index bd97b69..3796e64 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -552,7 +552,8 @@
     }
 
     public void updatePhoneStateListeners(boolean isRefresh, int updateType, int subIdToUpdate) {
-        List<SubscriptionInfo> subInfos = mSubscriptionManager.getActiveSubscriptionInfoList();
+        List<SubscriptionInfo> subInfos = SubscriptionController.getInstance()
+                .getActiveSubscriptionInfoList(mApplication.getOpPackageName());
 
         // 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 1e9e286..137d3d1 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -532,8 +532,8 @@
         if (addSubIdExtra && (simApplicationState != TelephonyManager.SIM_STATE_UNKNOWN
                 && simApplicationState != TelephonyManager.SIM_STATE_NOT_READY)) {
             SubscriptionManager.putPhoneIdAndSubIdExtra(intent, phoneId);
-            intent.putExtra(TelephonyManager.EXTRA_PRECISE_CARRIER_ID,
-                    getPreciseCarrierIdForPhoneId(phoneId));
+            intent.putExtra(TelephonyManager.EXTRA_SPECIFIC_CARRIER_ID,
+                    getSpecificCarrierIdForPhoneId(phoneId));
             intent.putExtra(TelephonyManager.EXTRA_CARRIER_ID, getCarrierIdForPhoneId(phoneId));
         }
         intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, phoneId);
@@ -564,7 +564,7 @@
         String spn = TelephonyManager.from(mContext).getSimOperatorNameForPhone(phoneId);
         String simOperator = TelephonyManager.from(mContext).getSimOperatorNumericForPhone(phoneId);
         int carrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
-        int preciseCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
+        int specificCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
         // A valid simOperator should be 5 or 6 digits, depending on the length of the MNC.
         if (simOperator != null && simOperator.length() >= 3) {
             mcc = simOperator.substring(0, 3);
@@ -576,9 +576,9 @@
             gid1 = phone.getGroupIdLevel1();
             gid2 = phone.getGroupIdLevel2();
             carrierId = phone.getCarrierId();
-            preciseCarrierId = phone.getPreciseCarrierId();
+            specificCarrierId = phone.getSpecificCarrierId();
         }
-        return new CarrierIdentifier(mcc, mnc, spn, imsi, gid1, gid2, carrierId, preciseCarrierId);
+        return new CarrierIdentifier(mcc, mnc, spn, imsi, gid1, gid2, carrierId, specificCarrierId);
     }
 
     /** Returns the package name of a priveleged carrier app, or null if there is none. */
@@ -605,9 +605,9 @@
     }
 
     /**
-     * Get the sim precise carrier id {@link TelephonyManager#getSimPreciseCarrierId()}
+     * Get the sim specific carrier id {@link TelephonyManager#getSimSpecificCarrierId()}
      */
-    private int getPreciseCarrierIdForPhoneId(int phoneId) {
+    private int getSpecificCarrierIdForPhoneId(int phoneId) {
         if (!SubscriptionManager.isValidPhoneId(phoneId)) {
             return TelephonyManager.UNKNOWN_CARRIER_ID;
         }
@@ -615,7 +615,7 @@
         if (phone == null) {
             return TelephonyManager.UNKNOWN_CARRIER_ID;
         }
-        return phone.getPreciseCarrierId();
+        return phone.getSpecificCarrierId();
     }
 
     /**
@@ -636,7 +636,7 @@
      * Writes a bundle to an XML file.
      *
      * The bundle will be written to a file named after the package name, ICCID and
-     * precise carrier id {@link TelephonyManager#getSimPreciseCarrierId()}. the same carrier
+     * specific carrier id {@link TelephonyManager#getSimSpecificCarrierId()}. the same carrier
      * should have a single copy of XML file named after carrier id. However, it's still possible
      * that platform doesn't recognize the current sim carrier, we will use iccid + carrierid as
      * the canonical file name. carrierid can also handle the cases SIM OTA resolves to different
@@ -659,7 +659,7 @@
         }
 
         final String iccid = getIccIdForPhoneId(phoneId);
-        final int cid = getPreciseCarrierIdForPhoneId(phoneId);
+        final int cid = getSpecificCarrierIdForPhoneId(phoneId);
         if (packageName == null || iccid == null) {
             loge("Cannot save config with null packageName or iccid.");
             return;
@@ -734,7 +734,7 @@
         }
 
         final String iccid = getIccIdForPhoneId(phoneId);
-        final int cid = getPreciseCarrierIdForPhoneId(phoneId);
+        final int cid = getSpecificCarrierIdForPhoneId(phoneId);
         if (packageName == null || iccid == null) {
             loge("Cannot restore config with null packageName or iccid.");
             return null;
diff --git a/src/com/android/phone/EccShortcutAdapter.java b/src/com/android/phone/EccShortcutAdapter.java
index 19b1fec..a5d955b 100644
--- a/src/com/android/phone/EccShortcutAdapter.java
+++ b/src/com/android/phone/EccShortcutAdapter.java
@@ -38,6 +38,9 @@
  * view container calls {@link #getView}.
  */
 public abstract class EccShortcutAdapter extends BaseAdapter {
+    // GSM default emergency number, used when country's fallback ECC(112 or 911) not available.
+    private static final String FALLBACK_EMERGENCY_NUMBER = "112";
+
     private List<EccDisplayMaterial> mEccDisplayMaterialList;
 
     private CharSequence mPoliceDescription;
diff --git a/src/com/android/phone/EmergencyDialer.java b/src/com/android/phone/EmergencyDialer.java
index d7443d5..cff27b1 100644
--- a/src/com/android/phone/EmergencyDialer.java
+++ b/src/com/android/phone/EmergencyDialer.java
@@ -111,13 +111,6 @@
         EmergencyInfoGroup.OnConfirmClickListener {
 
     private class MetricsWriter {
-        // Metrics constants indicating the entry type that user opened emergency dialer.
-        // This info is sent from system UI with EXTRA_ENTRY_TYPE. Please make them being
-        // in sync with those in com.android.systemui.util.EmergencyDialerConstants.
-        public static final int ENTRY_TYPE_UNKNOWN = 0;
-        public static final int ENTRY_TYPE_LOCKSCREEN_BUTTON = 1;
-        public static final int ENTRY_TYPE_POWER_MENU = 2;
-
         // Metrics constants indicating the UI that user made phone call.
         public static final int CALL_SOURCE_DIALPAD = 0;
         public static final int CALL_SOURCE_SHORTCUT = 1;
@@ -136,29 +129,27 @@
         private MetricsLogger mMetricsLogger = new MetricsLogger();
 
         public void writeMetricsForEnter() {
-            if (!mIsShortcutViewEnabled) {
+            if (!mShortcutViewConfig.isEnabled()) {
                 return;
             }
 
-            int entryType = getIntent().getIntExtra(EXTRA_ENTRY_TYPE, ENTRY_TYPE_UNKNOWN);
             KeyguardManager keyguard = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
             mMetricsLogger.write(new LogMaker(MetricsEvent.EMERGENCY_DIALER)
                     .setType(MetricsEvent.TYPE_OPEN)
-                    .setSubtype(entryType)
+                    .setSubtype(mEntryType)
                     .addTaggedData(MetricsEvent.FIELD_EMERGENCY_DIALER_IS_SCREEN_LOCKED,
                             keyguard.isKeyguardLocked() ? 1 : 0));
         }
 
         public void writeMetricsForExit() {
-            if (!mIsShortcutViewEnabled) {
+            if (!mShortcutViewConfig.isEnabled()) {
                 return;
             }
 
-            int entryType = getIntent().getIntExtra(EXTRA_ENTRY_TYPE, ENTRY_TYPE_UNKNOWN);
             long userStayDuration = SystemClock.elapsedRealtime() - mUserEnterTimeMillis;
             mMetricsLogger.write(new LogMaker(MetricsEvent.EMERGENCY_DIALER)
                     .setType(MetricsEvent.TYPE_CLOSE)
-                    .setSubtype(entryType)
+                    .setSubtype(mEntryType)
                     .addTaggedData(MetricsEvent.FIELD_EMERGENCY_DIALER_USER_ACTIONS, mUserActions)
                     .addTaggedData(
                             MetricsEvent.FIELD_EMERGENCY_DIALER_DURATION_MS, userStayDuration));
@@ -166,7 +157,7 @@
 
         public void writeMetricsForMakingCall(int callSource, int phoneNumberType,
                 boolean hasShortcut) {
-            if (!mIsShortcutViewEnabled) {
+            if (!mShortcutViewConfig.isEnabled()) {
                 return;
             }
 
@@ -195,6 +186,13 @@
     public static final String EXTRA_ENTRY_TYPE =
             "com.android.phone.EmergencyDialer.extra.ENTRY_TYPE";
 
+    // Constants indicating the entry type that user opened emergency dialer.
+    // This info is sent from system UI with EXTRA_ENTRY_TYPE. Please make them being
+    // in sync with those in com.android.systemui.util.EmergencyDialerConstants.
+    public static final int ENTRY_TYPE_UNKNOWN = 0;
+    public static final int ENTRY_TYPE_LOCKSCREEN_BUTTON = 1;
+    public static final int ENTRY_TYPE_POWER_MENU = 2;
+
     // List of dialer button IDs.
     private static final int[] DIALER_KEYS = new int[]{
             R.id.one, R.id.two, R.id.three,
@@ -232,8 +230,6 @@
     private View mEmergencyShortcutView;
     private View mDialpadView;
 
-    private ShortcutViewUtils.PhoneInfo mPhoneInfo;
-
     private List<EmergencyShortcutButton> mEmergencyShortcutButtonList;
     private EccShortcutAdapter mShortcutAdapter;
     private DataSetObserver mShortcutDataSetObserver = null;
@@ -292,7 +288,8 @@
     private boolean mIsWfcEmergencyCallingWarningEnabled;
     private float mDefaultDigitsTextSize;
 
-    private boolean mIsShortcutViewEnabled;
+    private int mEntryType;
+    private ShortcutViewUtils.Config mShortcutViewConfig;
 
     private MetricsWriter mMetricsWriter;
     private SensorManager mSensorManager;
@@ -344,6 +341,9 @@
     protected void onCreate(Bundle icicle) {
         super.onCreate(icicle);
 
+        mEntryType = getIntent().getIntExtra(EXTRA_ENTRY_TYPE, ENTRY_TYPE_UNKNOWN);
+        Log.d(LOG_TAG, "Launched from " + entryTypeToString(mEntryType));
+
         mMetricsWriter = new MetricsWriter();
         mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
         if (mSensorManager != null) {
@@ -359,20 +359,13 @@
         PersistableBundle carrierConfig =
                 configMgr.getConfigForSubId(SubscriptionManager.getDefaultVoiceSubscriptionId());
 
-        mIsShortcutViewEnabled = false;
-        mPhoneInfo = null;
-        if (canEnableShortcutView(carrierConfig)) {
-            mPhoneInfo = ShortcutViewUtils.pickPreferredPhone(this);
-            if (mPhoneInfo != null) {
-                mIsShortcutViewEnabled = true;
-            }
-        }
+        mShortcutViewConfig = new ShortcutViewUtils.Config(this, carrierConfig, mEntryType);
         Log.d(LOG_TAG, "Enable emergency dialer shortcut: "
-                + mIsShortcutViewEnabled);
+                + mShortcutViewConfig.isEnabled());
 
         mColorExtractor = new ColorExtractor(this);
 
-        if (mIsShortcutViewEnabled) {
+        if (mShortcutViewConfig.isEnabled()) {
             // Shortcut view doesn't support dark text theme.
             updateTheme(false);
         } else {
@@ -397,7 +390,7 @@
         ((WindowManager) getSystemService(Context.WINDOW_SERVICE))
                 .getDefaultDisplay().getSize(displaySize);
         mBackgroundGradient.setScreenSize(displaySize.x, displaySize.y);
-        mBackgroundGradient.setAlpha(mIsShortcutViewEnabled
+        mBackgroundGradient.setAlpha(mShortcutViewConfig.isEnabled()
                 ? BLACK_BACKGROUND_GRADIENT_ALPHA : BACKGROUND_GRADIENT_ALPHA);
         getWindow().setBackgroundDrawable(mBackgroundGradient);
 
@@ -461,7 +454,7 @@
 
         mEmergencyInfoGroup = (EmergencyInfoGroup) findViewById(R.id.emergency_info_button);
 
-        if (mIsShortcutViewEnabled) {
+        if (mShortcutViewConfig.isEnabled()) {
             setupEmergencyShortcutsView();
         }
     }
@@ -527,7 +520,7 @@
     public void onBackPressed() {
         // If shortcut view is enabled and Dialpad view is visible, pressing the back key will
         // back to display EmergencyShortcutView view. Otherwise, it would finish the activity.
-        if (mIsShortcutViewEnabled && mDialpadView != null
+        if (mShortcutViewConfig.isEnabled() && mDialpadView != null
                 && mDialpadView.getVisibility() == View.VISIBLE) {
             switchView(mEmergencyShortcutView, mDialpadView, true);
             return;
@@ -604,7 +597,7 @@
         if (!TextUtils.isEmpty(phoneNumber)) {
             if (DBG) Log.d(LOG_TAG, "dial emergency number: " + Rlog.pii(LOG_TAG, phoneNumber));
             placeCall(phoneNumber, ParcelableCallAnalytics.CALL_SOURCE_EMERGENCY_SHORTCUT,
-                    mPhoneInfo);
+                    mShortcutViewConfig.getPhoneInfo());
         } else {
             Log.d(LOG_TAG, "emergency number is empty");
         }
@@ -745,7 +738,7 @@
         mUserActions = MetricsWriter.USER_ACTION_NONE;
         mMetricsWriter.writeMetricsForEnter();
 
-        if (mIsShortcutViewEnabled) {
+        if (mShortcutViewConfig.isEnabled()) {
             // Shortcut view doesn't support dark text theme.
             mBackgroundGradient.setColors(Color.BLACK, Color.BLACK, false);
             updateTheme(false);
@@ -758,8 +751,7 @@
             updateTheme(lockScreenColors.supportsDarkText());
         }
 
-        if (mIsShortcutViewEnabled) {
-            mPhoneInfo = ShortcutViewUtils.pickPreferredPhone(this);
+        if (mShortcutViewConfig.isEnabled()) {
             updateLocationAndEccInfo();
         }
     }
@@ -809,15 +801,6 @@
         mColorExtractor.removeOnColorsChangedListener(this);
     }
 
-    private boolean canEnableShortcutView(PersistableBundle carrierConfig) {
-        if (!carrierConfig.getBoolean(
-                CarrierConfigManager.KEY_SUPPORT_EMERGENCY_DIALER_SHORTCUT_BOOL)) {
-            Log.d(LOG_TAG, "Disables shortcut view by carrier requirement");
-            return false;
-        }
-        return true;
-    }
-
     /**
      * Sets theme based on gradient colors
      *
@@ -861,15 +844,12 @@
         // nothing and just returns input number.
         mLastNumber = PhoneNumberUtils.convertToEmergencyNumber(this, mLastNumber);
 
-        boolean isEmergencyNumber = false;
+        boolean isEmergencyNumber;
         ShortcutViewUtils.PhoneInfo phoneToMakeCall = null;
-        if (mPhoneInfo != null) {
-            isEmergencyNumber = mPhoneInfo.hasPromotedEmergencyNumber(mLastNumber);
-            if (isEmergencyNumber) {
-                phoneToMakeCall = mPhoneInfo;
-            }
-        }
-        if (!isEmergencyNumber) {
+        if (mShortcutViewConfig.hasPromotedEmergencyNumber(mLastNumber)) {
+            isEmergencyNumber = true;
+            phoneToMakeCall = mShortcutViewConfig.getPhoneInfo();
+        } else {
             TelephonyManager tm = getSystemService(TelephonyManager.class);
             isEmergencyNumber = tm.isCurrentEmergencyNumber(mLastNumber);
         }
@@ -903,8 +883,18 @@
     }
 
     private void placeCall(String number, int callSource, ShortcutViewUtils.PhoneInfo phone) {
+        Log.d(LOG_TAG, "Place emergency call from " + callSourceToString(callSource)
+                + ", entry = " + entryTypeToString(mEntryType));
+
         Bundle extras = new Bundle();
         extras.putInt(TelecomManager.EXTRA_CALL_SOURCE, callSource);
+        /**
+         * This is used for Telecom and Telephony to tell modem user's intent is emergency call,
+         * when the dialed number is ambiguous and identified as both emergency number and any
+         * other non-emergency number; e.g. in some situation, 611 could be both an emergency
+         * number in a country and a non-emergency number of a carrier's customer service hotline.
+         */
+        extras.putBoolean(TelecomManager.EXTRA_IS_USER_INTENT_EMERGENCY_CALL, true);
 
         if (phone != null && phone.getPhoneAccountHandle() != null) {
             // Requests to dial through the specified phone.
@@ -1139,7 +1129,7 @@
     private void setLocationInfo() {
         final View locationInfo = findViewById(R.id.location_info);
 
-        String countryIso = mPhoneInfo != null ? mPhoneInfo.getCountryIso() : null;
+        String countryIso = mShortcutViewConfig.getCountryIso();
         String countryName = null;
         if (!TextUtils.isEmpty(countryIso)) {
             Locale locale = Locale.getDefault();
@@ -1220,7 +1210,7 @@
         if (!isFinishing() && !isDestroyed()) {
             setLocationInfo();
             if (mShortcutAdapter != null) {
-                mShortcutAdapter.updateCountryEccInfo(this, mPhoneInfo);
+                mShortcutAdapter.updateCountryEccInfo(this, mShortcutViewConfig.getPhoneInfo());
             }
         }
     }
@@ -1331,4 +1321,26 @@
         }
         return isShortcut;
     }
+
+    private String entryTypeToString(int entryType) {
+        switch (entryType) {
+            case ENTRY_TYPE_LOCKSCREEN_BUTTON:
+                return "LockScreen";
+            case ENTRY_TYPE_POWER_MENU:
+                return "PowerMenu";
+            default:
+                return "Unknown-" + entryType;
+        }
+    }
+
+    private String callSourceToString(int callSource) {
+        switch (callSource) {
+            case ParcelableCallAnalytics.CALL_SOURCE_EMERGENCY_DIALPAD:
+                return "DialPad";
+            case ParcelableCallAnalytics.CALL_SOURCE_EMERGENCY_SHORTCUT:
+                return "Shortcut";
+            default:
+                return "Unknown-" + callSource;
+        }
+    }
 }
diff --git a/src/com/android/phone/ImsUtil.java b/src/com/android/phone/ImsUtil.java
index ee23e6f..18fc534 100644
--- a/src/com/android/phone/ImsUtil.java
+++ b/src/com/android/phone/ImsUtil.java
@@ -113,7 +113,7 @@
     public static boolean shouldPromoteWfc(Context context, int phoneId) {
         CarrierConfigManager cfgManager = (CarrierConfigManager) context
                 .getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        if (cfgManager == null || cfgManager.getConfigForSubId(getSubId(phoneId))
+        if (cfgManager == null || !cfgManager.getConfigForSubId(getSubId(phoneId))
                 .getBoolean(CarrierConfigManager.KEY_CARRIER_PROMOTE_WFC_ON_CALL_FAIL_BOOL)) {
             return false;
         }
diff --git a/src/com/android/phone/MobileNetworkSettings.java b/src/com/android/phone/MobileNetworkSettings.java
index 465b89a..6375f90 100644
--- a/src/com/android/phone/MobileNetworkSettings.java
+++ b/src/com/android/phone/MobileNetworkSettings.java
@@ -57,6 +57,7 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.euicc.EuiccManager;
+import android.telephony.ims.ProvisioningManager;
 import android.telephony.ims.feature.ImsFeature;
 import android.text.TextUtils;
 import android.util.Log;
@@ -891,6 +892,18 @@
             }
         }
 
+        private final ProvisioningManager.Callback mProvisioningCallback =
+                new ProvisioningManager.Callback() {
+            @Override
+            public void onProvisioningIntChanged(int item, int value) {
+                if (item == ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED
+                        || item == ImsConfig.ConfigConstants.VLT_SETTING_ENABLED
+                        || item == ImsConfig.ConfigConstants.LVC_SETTING_ENABLED) {
+                    updateBody();
+                }
+            }
+        };
+
         @Override
         public void onDestroy() {
             super.onDestroy();
@@ -940,6 +953,15 @@
             context.getContentResolver().registerContentObserver(ENFORCE_MANAGED_URI, false,
                     mDpcEnforcedContentObserver);
 
+            // Register callback for provisioning changes.
+            try {
+                if (mImsMgr != null) {
+                    mImsMgr.getConfigInterface().addConfigCallback(mProvisioningCallback);
+                }
+            } catch (ImsException e) {
+                Log.w(LOG_TAG, "onResume: Unable to register callback for provisioning changes.");
+            }
+
             Log.i(LOG_TAG, "onResume:-");
 
         }
@@ -1332,6 +1354,17 @@
             final Context context = getActivity();
             context.unregisterReceiver(mPhoneChangeReceiver);
             context.getContentResolver().unregisterContentObserver(mDpcEnforcedContentObserver);
+
+            // Remove callback for provisioning changes.
+            try {
+                if (mImsMgr != null) {
+                    mImsMgr.getConfigInterface().removeConfigCallback(
+                            mProvisioningCallback.getBinder());
+                }
+            } catch (ImsException e) {
+                Log.w(LOG_TAG, "onPause: Unable to remove callback for provisioning changes");
+            }
+
             if (DBG) log("onPause:-");
         }
 
@@ -1867,10 +1900,23 @@
                 return;
             }
 
+            // See what Telecom thinks the SIM call manager is.
             final PhoneAccountHandle simCallManager =
                     TelecomManager.from(getContext()).getSimCallManager();
 
-            if (simCallManager != null) {
+            // Check which SIM call manager is for the current sub ID.
+            PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(mSubId);
+            String currentSubSimCallManager = null;
+            if (carrierConfig != null) {
+                currentSubSimCallManager = carrierConfig.getString(
+                        CarrierConfigManager.KEY_DEFAULT_SIM_CALL_MANAGER_STRING);
+            }
+
+            // Only try to configure the phone account if this is the sim call manager for the
+            // current sub.
+            if (simCallManager != null
+                    && simCallManager.getComponentName().flattenToString().equals(
+                    currentSubSimCallManager)) {
                 Intent intent = MobileNetworkSettings.buildPhoneAccountConfigureIntent(
                         getContext(), simCallManager);
                 PackageManager pm = getContext().getPackageManager();
@@ -1879,6 +1925,10 @@
                 mWiFiCallingPref.setSummary(null);
                 mWiFiCallingPref.setIntent(intent);
             } else {
+                String title = SubscriptionManager.getResourcesForSubId(getContext(), mSubId)
+                        .getString(R.string.wifi_calling_settings_title);
+                mWiFiCallingPref.setTitle(title);
+
                 int resId = com.android.internal.R.string.wifi_calling_off_summary;
                 if (mImsMgr.isWfcEnabledByUser()) {
                     boolean isRoaming = mTelephonyManager.isNetworkRoaming();
diff --git a/src/com/android/phone/NetworkSelectSetting.java b/src/com/android/phone/NetworkSelectSetting.java
index d9731be..edbceb4 100644
--- a/src/com/android/phone/NetworkSelectSetting.java
+++ b/src/com/android/phone/NetworkSelectSetting.java
@@ -397,7 +397,7 @@
             // Try to get the network registration states
             ServiceState ss = mTelephonyManager.getServiceState();
             List<NetworkRegistrationState> networkList =
-                    ss.getNetworkRegistrationStates(AccessNetworkConstants.TransportType.WWAN);
+                    ss.getNetworkRegistrationStates(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
             if (networkList == null || networkList.size() == 0) {
                 loge("getNetworkRegistrationStates return null");
                 // Remove the connected network operators category
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 3d82e74..94cd0f6 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -43,8 +43,8 @@
 import android.preference.PreferenceManager;
 import android.provider.Settings;
 import android.telecom.TelecomManager;
+import android.telephony.AnomalyReporter;
 import android.telephony.CarrierConfigManager;
-import android.telephony.DebugEventReporter;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
@@ -284,8 +284,8 @@
         //   getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_VOICE_CALLS);
 
         if (mCM == null) {
-            // Initialize DebugEventReporter early so that it can be used
-            DebugEventReporter.initialize(this);
+            // Initialize AnomalyReporter early so that it can be used
+            AnomalyReporter.initialize(this);
 
             // Inject telephony component factory if configured using other jars.
             XmlResourceParser parser = getResources().getXml(R.xml.telephony_injection);
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index fcd6660..af556c4 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -24,6 +24,7 @@
 import android.app.AppOpsManager;
 import android.app.PendingIntent;
 import android.content.ComponentName;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
@@ -53,6 +54,7 @@
 import android.os.WorkSource;
 import android.preference.PreferenceManager;
 import android.provider.Settings;
+import android.provider.Telephony;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
@@ -69,6 +71,7 @@
 import android.telephony.ModemActivityInfo;
 import android.telephony.NeighboringCellInfo;
 import android.telephony.NetworkScanRequest;
+import android.telephony.PhoneCapability;
 import android.telephony.PhoneNumberRange;
 import android.telephony.RadioAccessFamily;
 import android.telephony.Rlog;
@@ -114,6 +117,7 @@
 import com.android.internal.telephony.CellNetworkScanResult;
 import com.android.internal.telephony.CommandException;
 import com.android.internal.telephony.DefaultPhoneNotifier;
+import com.android.internal.telephony.HalVersion;
 import com.android.internal.telephony.INumberVerificationCallback;
 import com.android.internal.telephony.ITelephony;
 import com.android.internal.telephony.IccCard;
@@ -136,6 +140,7 @@
 import com.android.internal.telephony.TelephonyPermissions;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
 import com.android.internal.telephony.euicc.EuiccConnector;
+import com.android.internal.telephony.ims.ImsResolver;
 import com.android.internal.telephony.metrics.TelephonyMetrics;
 import com.android.internal.telephony.uicc.IccIoResult;
 import com.android.internal.telephony.uicc.IccUtils;
@@ -1098,6 +1103,7 @@
                     request = (MainThreadRequest) msg.obj;
                     boolean enable = (boolean) request.argument;
                     onCompleted = obtainMessage(EVENT_ENABLE_MODEM_DONE, request);
+                    onCompleted.arg1 = enable ? 1 : 0;
                     PhoneConfigurationManager.getInstance()
                             .enablePhone(request.phone, enable, onCompleted);
                     break;
@@ -1105,6 +1111,9 @@
                     ar = (AsyncResult) msg.obj;
                     request = (MainThreadRequest) ar.userObj;
                     request.result = (ar.exception == null);
+                    //update the cache as modem status has changed
+                    mPhoneConfigurationManager.addToPhoneStatusCache(
+                            request.phone.getPhoneId(), msg.arg1 == 1);
                     updateModemStateMetrics();
                     notifyRequester(request);
                     break;
@@ -2024,6 +2033,7 @@
                                 .setCallingPid(Binder.getCallingPid())
                                 .setCallingUid(Binder.getCallingUid())
                                 .setMethod("getAllCellInfo")
+                                .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
                                 .build());
         switch (locationResult) {
@@ -2213,23 +2223,23 @@
     }
 
     @Override
-    public int getSubscriptionPreciseCarrierId(int subId) {
+    public int getSubscriptionSpecificCarrierId(int subId) {
         final long identity = Binder.clearCallingIdentity();
         try {
             final Phone phone = getPhone(subId);
             return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID
-                    : phone.getPreciseCarrierId();
+                    : phone.getSpecificCarrierId();
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
     }
 
     @Override
-    public String getSubscriptionPreciseCarrierName(int subId) {
+    public String getSubscriptionSpecificCarrierName(int subId) {
         final long identity = Binder.clearCallingIdentity();
         try {
             final Phone phone = getPhone(subId);
-            return phone == null ? null : phone.getPreciseCarrierName();
+            return phone == null ? null : phone.getSpecificCarrierName();
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -2467,7 +2477,7 @@
         }
 
         timeoutMillis = Math.min(timeoutMillis,
-                TelephonyManager.MAX_NUMBER_VERIFICATION_TIMEOUT_MILLIS);
+                TelephonyManager.getMaxNumberVerificationTimeoutMillis());
 
         NumberVerificationManager.getInstance().requestVerification(range, callback, timeoutMillis);
     }
@@ -2901,9 +2911,9 @@
     }
 
     @Override
-    public void setAdvancedCallingSetting(int subId, boolean isEnabled) {
+    public void setAdvancedCallingSettingEnabled(int subId, boolean isEnabled) {
         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
-                "setAdvancedCallingSetting");
+                "setAdvancedCallingSettingEnabled");
         final long identity = Binder.clearCallingIdentity();
         try {
             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
@@ -2928,9 +2938,9 @@
     }
 
     @Override
-    public void setVtSetting(int subId, boolean isEnabled) {
+    public void setVtSettingEnabled(int subId, boolean isEnabled) {
         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
-                "setVtSetting");
+                "setVtSettingEnabled");
         final long identity = Binder.clearCallingIdentity();
         try {
             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
@@ -2954,9 +2964,9 @@
     }
 
     @Override
-    public void setVoWiFiSetting(int subId, boolean isEnabled) {
+    public void setVoWiFiSettingEnabled(int subId, boolean isEnabled) {
         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
-                "setVoWiFiSetting");
+                "setVoWiFiSettingEnabled");
         final long identity = Binder.clearCallingIdentity();
         try {
             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
@@ -2980,9 +2990,9 @@
     }
 
     @Override
-    public void setVoWiFiRoamingSetting(int subId, boolean isEnabled) {
+    public void setVoWiFiRoamingSettingEnabled(int subId, boolean isEnabled) {
         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
-                "setVoWiFiRoamingSetting");
+                "setVoWiFiRoamingSettingEnabled");
         final long identity = Binder.clearCallingIdentity();
         try {
             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
@@ -4109,7 +4119,12 @@
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            PhoneFactory.getImsResolver().enableIms(slotId);
+            ImsResolver resolver = PhoneFactory.getImsResolver();
+            if (resolver == null) {
+                // may happen if the device does not support IMS.
+                return;
+            }
+            resolver.enableIms(slotId);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -4124,7 +4139,12 @@
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            PhoneFactory.getImsResolver().disableIms(slotId);
+            ImsResolver resolver = PhoneFactory.getImsResolver();
+            if (resolver == null) {
+                // may happen if the device does not support IMS.
+                return;
+            }
+            resolver.disableIms(slotId);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -4141,7 +4161,12 @@
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            return PhoneFactory.getImsResolver().getMmTelFeatureAndListen(slotId, callback);
+            ImsResolver resolver = PhoneFactory.getImsResolver();
+            if (resolver == null) {
+                // may happen if the device does not support IMS.
+                return null;
+            }
+            return resolver.getMmTelFeatureAndListen(slotId, callback);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -4158,7 +4183,12 @@
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            return PhoneFactory.getImsResolver().getRcsFeatureAndListen(slotId, callback);
+            ImsResolver resolver = PhoneFactory.getImsResolver();
+            if (resolver == null) {
+                // may happen if the device does not support IMS.
+                return null;
+            }
+            return resolver.getRcsFeatureAndListen(slotId, callback);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -4166,14 +4196,19 @@
 
     /**
      * Returns the {@link IImsRegistration} structure associated with the slotId and feature
-     * specified.
+     * specified or null if IMS is not supported on the slot specified.
      */
     public IImsRegistration getImsRegistration(int slotId, int feature) throws RemoteException {
         enforceModifyPermission();
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            return PhoneFactory.getImsResolver().getImsRegistration(slotId, feature);
+            ImsResolver resolver = PhoneFactory.getImsResolver();
+            if (resolver == null) {
+                // may happen if the device does not support IMS.
+                return null;
+            }
+            return resolver.getImsRegistration(slotId, feature);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -4181,14 +4216,19 @@
 
     /**
      * Returns the {@link IImsConfig} structure associated with the slotId and feature
-     * specified.
+     * specified or null if IMS is not supported on the slot specified.
      */
     public IImsConfig getImsConfig(int slotId, int feature) throws RemoteException {
         enforceModifyPermission();
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            return PhoneFactory.getImsResolver().getImsConfig(slotId, feature);
+            ImsResolver resolver = PhoneFactory.getImsResolver();
+            if (resolver == null) {
+                // may happen if the device does not support IMS.
+                return null;
+            }
+            return resolver.getImsConfig(slotId, feature);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -4213,8 +4253,13 @@
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            return PhoneFactory.getImsResolver().overrideImsServiceConfiguration(slotId,
-                    isCarrierImsService, packageName);
+            ImsResolver resolver = PhoneFactory.getImsResolver();
+            if (resolver == null) {
+                // may happen if the device does not support IMS.
+                return false;
+            }
+            return resolver.overrideImsServiceConfiguration(slotId, isCarrierImsService,
+                    packageName);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -4236,8 +4281,12 @@
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            return PhoneFactory.getImsResolver().getImsServiceConfiguration(slotId,
-                    isCarrierImsService);
+            ImsResolver resolver = PhoneFactory.getImsResolver();
+            if (resolver == null) {
+                // may happen if the device does not support IMS.
+                return "";
+            }
+            return resolver.getImsServiceConfiguration(slotId, isCarrierImsService);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -4475,27 +4524,18 @@
     }
 
     /**
-     * Check TETHER_DUN_REQUIRED and TETHER_DUN_APN settings, net.tethering.noprovisioning
-     * SystemProperty to decide whether DUN APN is required for
-     * tethering.
+     * Check whether DUN APN is required for tethering.
      *
-     * @return 0: Not required. 1: required. 2: Not set.
+     * @return {@code true} if DUN APN is required for tethering.
      * @hide
      */
     @Override
-    public int getTetherApnRequired() {
+    public boolean getTetherApnRequired() {
         enforceModifyPermission();
-
         final long identity = Binder.clearCallingIdentity();
         final Phone defaultPhone = getDefaultPhone();
         try {
-            int dunRequired = Settings.Global.getInt(defaultPhone.getContext().getContentResolver(),
-                    Settings.Global.TETHER_DUN_REQUIRED, 2);
-            // If not set, check net.tethering.noprovisioning, TETHER_DUN_APN setting
-            if (dunRequired == 2 && defaultPhone.hasMatchedTetherApnSetting()) {
-                dunRequired = 1;
-            }
-            return dunRequired;
+            return defaultPhone.hasMatchedTetherApnSetting();
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -5273,11 +5313,22 @@
                 setDataRoamingEnabled(subId, getDefaultDataRoamingEnabled(subId));
                 CarrierInfoManager.deleteAllCarrierKeysForImsiEncryption(mApp);
             }
+            // There has been issues when Sms raw table somehow stores orphan
+            // fragments. They lead to garbled message when new fragments come
+            // in and combined with those stale ones. In case this happens again,
+            // user can reset all network settings which will clean up this table.
+            cleanUpSmsRawTable(getDefaultPhone().getContext());
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
     }
 
+    private void cleanUpSmsRawTable(Context context) {
+        ContentResolver resolver = context.getContentResolver();
+        Uri uri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw/permanentDelete");
+        resolver.delete(uri, null, null);
+    }
+
     @Override
     public String getSimLocaleForSubscriber(int subId) {
         enforceReadPrivilegedPermission("getSimLocaleForSubscriber, subId: " + subId);
@@ -6242,7 +6293,8 @@
                         cardId,
                         cardState,
                         slot.getPhoneId(),
-                        slot.isExtendedApduSupported());
+                        slot.isExtendedApduSupported(),
+                        slot.isRemovable());
             }
             return infos;
         } finally {
@@ -6663,49 +6715,71 @@
     }
 
     @Override
-    public boolean isMultisimCarrierRestricted() {
-        enforceReadPrivilegedPermission("isMultisimCarrierRestricted");
+    public boolean isMultisimSupported(String callingPackage) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp,
+                getDefaultPhone().getSubId(), callingPackage, "isMultisimSupported")) {
+            return false;
+        }
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            // If the device has less than 2 SIM cards, indicate that multisim is restricted.
-            int numPhysicalSlots = UiccController.getInstance().getUiccSlots().length;
-            if (numPhysicalSlots < 2) {
-                loge("isMultisimCarrierRestricted: requires at least 2 cards");
-                return true;
-            }
-
-            // Default value is false. Multi SIM is allowed unless explicitly restricted.
-            return mTelephonySharedPreferences.getBoolean(PREF_MULTI_SIM_RESTRICTED, false);
+            return isMultisimSupportedInternal();
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
     }
 
+    private boolean isMultisimSupportedInternal() {
+        // If the device has less than 2 SIM cards, indicate that multisim is restricted.
+        int numPhysicalSlots = UiccController.getInstance().getUiccSlots().length;
+        if (numPhysicalSlots < 2) {
+            loge("isMultisimSupportedInternal: requires at least 2 cards");
+            return false;
+        }
+        // Check if the hardware supports multisim functionality. If usage of multisim is not
+        // supported by the modem, indicate that it is restricted.
+        PhoneCapability staticCapability =
+                mPhoneConfigurationManager.getStaticPhoneCapability();
+        if (staticCapability == null) {
+            loge("isMultisimSupportedInternal: no static configuration available");
+            return false;
+        }
+        if (staticCapability.logicalModemList.size() < 2) {
+            loge("isMultisimSupportedInternal: maximum number of modem is < 2");
+            return false;
+        }
+        // Check if support of multiple SIMs is restricted by carrier
+        if (mTelephonySharedPreferences.getBoolean(PREF_MULTI_SIM_RESTRICTED, false)) {
+            return false;
+        }
+
+        return true;
+    }
+
     /**
      * Switch configs to enable multi-sim or switch back to single-sim
+     * Note: Switch from multi-sim to single-sim is only possible with MODIFY_PHONE_STATE
+     * permission, but the other way around is possible with either MODIFY_PHONE_STATE
+     * or carrier privileges
      * @param numOfSims number of active sims we want to switch to
      */
     @Override
     public void switchMultiSimConfig(int numOfSims) {
-        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
-                mApp, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, "switchMultiSimConfig");
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            mPhoneConfigurationManager.switchMultiSimConfig(numOfSims);
-        } finally {
-            Binder.restoreCallingIdentity(identity);
+        if (numOfSims == 1) {
+            enforceModifyPermission();
+        } else {
+            TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                    mApp, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, "switchMultiSimConfig");
         }
-    }
-
-    /**
-     * Get how many sims have been activated on the phone
-     */
-    @Override
-    public int getNumOfActiveSims() {
         final long identity = Binder.clearCallingIdentity();
+
         try {
-            return mPhoneConfigurationManager.getNumOfActiveSims();
+            //only proceed if multi-sim is not restricted
+            if (!isMultisimSupportedInternal()) {
+                loge("switchMultiSimConfig not possible. It is restricted or not supported.");
+                return;
+            }
+            mPhoneConfigurationManager.switchMultiSimConfig(numOfSims);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -6752,4 +6826,16 @@
             Binder.restoreCallingIdentity(identity);
         }
     }
+
+    /**
+     * Get the IRadio HAL Version
+     */
+    @Override
+    public int getRadioHalVersion() {
+        Phone phone = getDefaultPhone();
+        if (phone == null) return -1;
+        HalVersion hv = phone.getHalVersion();
+        if (hv.equals(HalVersion.UNKNOWN)) return -1;
+        return hv.major * 100 + hv.minor;
+    }
 }
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index 6f1f0a6..d3f780f 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -428,6 +428,12 @@
             // been assigned for the PUK unlock / SIM READY process.
             app.setPukEntryProgressDialog(pd);
 
+        } else if ((app.getPUKEntryActivity() != null) && (state == MmiCode.State.FAILED)) {
+            createUssdDialog(app, context, text,
+                    WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+            // In case of failure to unlock, we'll need to reset the
+            // PUK unlock activity, so that the user may try again.
+            app.setPukEntryActivity(null);
         } else {
             // In case of failure to unlock, we'll need to reset the
             // PUK unlock activity, so that the user may try again.
@@ -438,42 +444,8 @@
             // A USSD in a pending state means that it is still
             // interacting with the user.
             if (state != MmiCode.State.PENDING) {
-                log("displayMMIComplete: MMI code has finished running.");
-
-                log("displayMMIComplete: Extended NW displayMMIInitiate (" + text + ")");
-                if (text == null || text.length() == 0)
-                    return;
-
-                // displaying system alert dialog on the screen instead of
-                // using another activity to display the message.  This
-                // places the message at the forefront of the UI.
-
-                if (sUssdDialog == null) {
-                    sUssdDialog = new AlertDialog.Builder(context, THEME)
-                            .setPositiveButton(R.string.ok, null)
-                            .setCancelable(true)
-                            .setOnDismissListener(new DialogInterface.OnDismissListener() {
-                                @Override
-                                public void onDismiss(DialogInterface dialog) {
-                                    sUssdMsg.setLength(0);
-                                }
-                            })
-                            .create();
-
-                    sUssdDialog.getWindow().setType(
-                            WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
-                    sUssdDialog.getWindow().addFlags(
-                            WindowManager.LayoutParams.FLAG_DIM_BEHIND);
-                }
-                if (sUssdMsg.length() != 0) {
-                    sUssdMsg
-                            .insert(0, "\n")
-                            .insert(0, app.getResources().getString(R.string.ussd_dialog_sep))
-                            .insert(0, "\n");
-                }
-                sUssdMsg.insert(0, text);
-                sUssdDialog.setMessage(sUssdMsg.toString());
-                sUssdDialog.show();
+                createUssdDialog(app, context, text,
+                        WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
             } else {
                 log("displayMMIComplete: USSD code has requested user input. Constructing input "
                         + "dialog.");
@@ -587,6 +559,46 @@
         }
     }
 
+    private static void createUssdDialog(PhoneGlobals app, Context context, CharSequence text,
+            int windowType) {
+        log("displayMMIComplete: MMI code has finished running.");
+
+        log("displayMMIComplete: Extended NW displayMMIInitiate (" + text + ")");
+        if (text == null || text.length() == 0) {
+            return;
+        }
+
+        // displaying system alert dialog on the screen instead of
+        // using another activity to display the message.  This
+        // places the message at the forefront of the UI.
+
+        if (sUssdDialog == null) {
+            sUssdDialog = new AlertDialog.Builder(context, THEME)
+                    .setPositiveButton(R.string.ok, null)
+                    .setCancelable(true)
+                    .setOnDismissListener(new DialogInterface.OnDismissListener() {
+                        @Override
+                        public void onDismiss(DialogInterface dialog) {
+                            sUssdMsg.setLength(0);
+                        }
+                    })
+                    .create();
+
+            sUssdDialog.getWindow().setType(windowType);
+            sUssdDialog.getWindow().addFlags(
+                    WindowManager.LayoutParams.FLAG_DIM_BEHIND);
+        }
+        if (sUssdMsg.length() != 0) {
+            sUssdMsg
+                    .insert(0, "\n")
+                    .insert(0, app.getResources().getString(R.string.ussd_dialog_sep))
+                    .insert(0, "\n");
+        }
+        sUssdMsg.insert(0, text);
+        sUssdDialog.setMessage(sUssdMsg.toString());
+        sUssdDialog.show();
+    }
+
     /**
      * Cancels the current pending MMI operation, if applicable.
      * @return true if we canceled an MMI operation, or false
diff --git a/src/com/android/phone/ShortcutViewUtils.java b/src/com/android/phone/ShortcutViewUtils.java
index 595ea86..7e24c7a 100644
--- a/src/com/android/phone/ShortcutViewUtils.java
+++ b/src/com/android/phone/ShortcutViewUtils.java
@@ -17,9 +17,12 @@
 package com.android.phone;
 
 import android.content.Context;
+import android.os.PersistableBundle;
+import android.provider.Settings;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
+import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.emergency.EmergencyNumber;
@@ -54,6 +57,64 @@
         PROMOTED_CATEGORIES_BITMASK = bitmask;
     }
 
+    static class Config {
+        private final boolean mCanEnableShortcutView;
+        private PhoneInfo mPhoneInfo = null;
+
+        Config(@NonNull Context context, PersistableBundle carrierConfig, int entryType) {
+            mCanEnableShortcutView = canEnableShortcutView(carrierConfig, entryType);
+            refresh(context);
+        }
+
+        void refresh(@NonNull Context context) {
+            if (mCanEnableShortcutView && !isAirplaneModeOn(context)) {
+                mPhoneInfo = ShortcutViewUtils.pickPreferredPhone(context);
+            } else {
+                mPhoneInfo = null;
+            }
+        }
+
+        boolean isEnabled() {
+            return mPhoneInfo != null;
+        }
+
+        PhoneInfo getPhoneInfo() {
+            return mPhoneInfo;
+        }
+
+        String getCountryIso() {
+            if (mPhoneInfo == null) {
+                return null;
+            }
+            return mPhoneInfo.getCountryIso();
+        }
+
+        boolean hasPromotedEmergencyNumber(String number) {
+            if (mPhoneInfo == null) {
+                return false;
+            }
+            return mPhoneInfo.hasPromotedEmergencyNumber(number);
+        }
+
+        private boolean canEnableShortcutView(PersistableBundle carrierConfig, int entryType) {
+            if (entryType != EmergencyDialer.ENTRY_TYPE_POWER_MENU) {
+                Log.d(LOG_TAG, "Disables shortcut view since it's not launched from power menu");
+                return false;
+            }
+            if (carrierConfig == null || !carrierConfig.getBoolean(
+                    CarrierConfigManager.KEY_SUPPORT_EMERGENCY_DIALER_SHORTCUT_BOOL)) {
+                Log.d(LOG_TAG, "Disables shortcut view by carrier requirement");
+                return false;
+            }
+            return true;
+        }
+
+        private boolean isAirplaneModeOn(@NonNull Context context) {
+            return Settings.Global.getInt(context.getContentResolver(),
+                    Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
+        }
+    }
+
     // Info and emergency call capability of every phone.
     static class PhoneInfo {
         private final PhoneAccountHandle mHandle;
diff --git a/src/com/android/phone/ecc/CountryEccInfo.java b/src/com/android/phone/ecc/CountryEccInfo.java
new file mode 100644
index 0000000..bc7ec84
--- /dev/null
+++ b/src/com/android/phone/ecc/CountryEccInfo.java
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+package com.android.phone.ecc;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.util.Collection;
+
+/**
+ * ECC info of a country.
+ */
+public class CountryEccInfo {
+    private final String mFallbackEcc;
+    private final EccInfo[] mEccInfoList;
+
+    public CountryEccInfo(String eccFallback, @NonNull Collection<EccInfo> eccInfoList) {
+        mFallbackEcc = eccFallback;
+        mEccInfoList = eccInfoList.toArray(new EccInfo[eccInfoList.size()]);
+    }
+
+    /**
+     * @return fallback ECC, null if not available.
+     */
+    public @Nullable String getFallbackEcc() {
+        return mFallbackEcc;
+    }
+
+    public @NonNull EccInfo[] getEccInfoList() {
+        return mEccInfoList.clone();
+    }
+}
diff --git a/src/com/android/phone/ecc/EccInfo.java b/src/com/android/phone/ecc/EccInfo.java
new file mode 100644
index 0000000..a219bae
--- /dev/null
+++ b/src/com/android/phone/ecc/EccInfo.java
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+
+package com.android.phone.ecc;
+
+import android.annotation.NonNull;
+
+import java.util.Collection;
+
+/**
+ * Emergency call code info.
+ */
+public class EccInfo {
+    /**
+     * ECC Types.
+     */
+    public enum Type {
+        POLICE,
+        AMBULANCE,
+        FIRE,
+    }
+
+    private final String mNumber;
+    private final Type[] mTypes;
+
+    public EccInfo(@NonNull String number, @NonNull Type type) {
+        mNumber = number;
+        mTypes = new Type[]{ type };
+    }
+
+    public EccInfo(@NonNull String number, @NonNull Collection<Type> types) {
+        mNumber = number;
+        mTypes = types.toArray(new Type[types.size()]);
+    }
+
+    /**
+     * @return ECC number.
+     */
+    public @NonNull String getNumber() {
+        return mNumber;
+    }
+
+    /**
+     * Check whether the ECC number has any matches to the target type.
+     *
+     * @param target The target type to check.
+     * @return true if the target matches.
+     */
+    public boolean containsType(@NonNull Type target) {
+        for (Type type : mTypes) {
+            if (target.equals(type)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Get the types of the ECC number.
+     *
+     * @return Copied types array.
+     */
+    public Type[] getTypes() {
+        return mTypes.clone();
+    }
+
+    /**
+     * Get how many types the ECC number is.
+     *
+     * @return Count of types.
+     */
+    public int getTypesCount() {
+        return mTypes.length;
+    }
+}
diff --git a/src/com/android/phone/ecc/EccInfoHelper.java b/src/com/android/phone/ecc/EccInfoHelper.java
new file mode 100644
index 0000000..875442a
--- /dev/null
+++ b/src/com/android/phone/ecc/EccInfoHelper.java
@@ -0,0 +1,226 @@
+/*
+ * 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.
+ */
+
+package com.android.phone.ecc;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.os.AsyncTask;
+import android.provider.Settings;
+import android.telephony.CellIdentityGsm;
+import android.telephony.CellIdentityLte;
+import android.telephony.CellIdentityWcdma;
+import android.telephony.CellInfo;
+import android.telephony.CellInfoGsm;
+import android.telephony.CellInfoLte;
+import android.telephony.CellInfoWcdma;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.Rlog;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Pair;
+
+import com.android.internal.telephony.MccTable;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Helper for retrieve ECC info for current country.
+ */
+public class EccInfoHelper {
+    // Debug constants.
+    private static final boolean DBG = false;
+    private static final String LOG_TAG = "EccInfoHelper";
+
+    // country ISO to ECC list data source
+    private IsoToEccRepository mEccRepo;
+
+    /**
+     * Callback for {@link #getCountryEccInfoAsync}.
+     */
+    public interface CountryEccInfoResultCallback {
+        /**
+         * Called if successfully get country ECC info.
+         *
+         * @param iso Detected current country ISO.
+         * @param countryEccInfo The EccInfo of current country.
+         */
+        void onSuccess(@NonNull String iso, @NonNull CountryEccInfo countryEccInfo);
+
+        /**
+         * Called if failed to get country ISO.
+         */
+        void onDetectCountryFailed();
+
+        /**
+         * Called if failed to get ECC info for given country ISO.
+         *
+         * @param iso Detected current country ISO.
+         */
+        void onRetrieveCountryEccInfoFailed(@NonNull String iso);
+    }
+
+    /**
+     * Constructor of EccInfoHelper
+     *
+     * @param eccRepository A repository for ECC info, indexed by country ISO.
+     */
+    public EccInfoHelper(@NonNull IsoToEccRepository eccRepository) {
+        mEccRepo = eccRepository;
+    }
+
+    /**
+     * Get ECC info for current location, base on detected country ISO.
+     * It's possible we cannot detect current country, ex. device is in airplane mode,
+     * or there's no available base station near by.
+     *
+     * @param context The context used to access resources.
+     * @param callback Callback for result.
+     */
+    public void getCountryEccInfoAsync(final @NonNull Context context,
+            final CountryEccInfoResultCallback callback) {
+        new AsyncTask<Void, Void, Pair<String, CountryEccInfo>>() {
+            @Override
+            protected Pair<String, CountryEccInfo> doInBackground(Void... voids) {
+                String iso = getCurrentCountryIso(context);
+                if (TextUtils.isEmpty(iso)) {
+                    return null;
+                }
+
+                CountryEccInfo dialableCountryEccInfo;
+                try {
+                    // access data source in background thread to avoid possible file IO caused ANR.
+                    CountryEccInfo rawEccInfo = mEccRepo.getCountryEccInfo(context, iso);
+                    dialableCountryEccInfo = getDialableCountryEccInfo(rawEccInfo);
+                } catch (IOException e) {
+                    Log.e(LOG_TAG, "Failed to retrieve ECC: " + e.getMessage());
+                    dialableCountryEccInfo = null;
+                }
+                return new Pair<>(iso, dialableCountryEccInfo);
+            }
+
+            @Override
+            protected void onPostExecute(Pair<String, CountryEccInfo> result) {
+                if (callback != null) {
+                    if (result == null) {
+                        callback.onDetectCountryFailed();
+                    } else {
+                        String iso = result.first;
+                        CountryEccInfo countryEccInfo = result.second;
+                        if (countryEccInfo == null) {
+                            callback.onRetrieveCountryEccInfoFailed(iso);
+                        } else {
+                            callback.onSuccess(iso, countryEccInfo);
+                        }
+                    }
+                }
+            }
+        }.execute();
+    }
+
+    private @NonNull CountryEccInfo getDialableCountryEccInfo(CountryEccInfo countryEccInfo) {
+        ArrayList<EccInfo> dialableECCList = new ArrayList<>();
+        String dialableFallback = null;
+
+        // filter out non-dialable ECC
+        if (countryEccInfo != null) {
+            for (EccInfo entry : countryEccInfo.getEccInfoList()) {
+                if (PhoneNumberUtils.isEmergencyNumber(entry.getNumber())) {
+                    dialableECCList.add(entry);
+                }
+            }
+            String defaultFallback = countryEccInfo.getFallbackEcc();
+            if (PhoneNumberUtils.isEmergencyNumber(defaultFallback)) {
+                dialableFallback = defaultFallback;
+            }
+        }
+        return new CountryEccInfo(dialableFallback, dialableECCList);
+    }
+
+    private @Nullable String getCurrentCountryIso(@NonNull Context context) {
+        // Do not detect country ISO if airplane mode is on
+        int airplaneMode = Settings.System.getInt(context.getContentResolver(),
+                Settings.Global.AIRPLANE_MODE_ON, 0);
+        if (airplaneMode != 0) {
+            Log.d(LOG_TAG, "Airplane mode is on, do not get country ISO.");
+            return null;
+        }
+
+        TelephonyManager tm = (TelephonyManager) context.getSystemService(
+                Context.TELEPHONY_SERVICE);
+        String iso = tm.getNetworkCountryIso();
+        if (DBG) Log.d(LOG_TAG, "Current country ISO is " + Rlog.pii(LOG_TAG, iso));
+
+        if (TextUtils.isEmpty(iso)) {
+            // XXX: according to ServiceStateTracker's implementation, retrieve cell info in a
+            // thread other than TelephonyManager's main thread.
+            String mcc = getCurrentMccFromCellInfo(context);
+            iso = countryCodeForMcc(mcc);
+            if (DBG) {
+                Log.d(LOG_TAG, "Current mcc is " + Rlog.pii(LOG_TAG, mcc) + ", mapping to ISO: "
+                        + Rlog.pii(LOG_TAG, iso));
+            }
+        }
+        return iso;
+    }
+
+    private String countryCodeForMcc(String mcc) {
+        try {
+            return MccTable.countryCodeForMcc(Integer.parseInt(mcc));
+        } catch (NumberFormatException ex) {
+            return "";
+        }
+    }
+
+    // XXX: According to ServiceStateTracker implementation, to actually get current cell info,
+    // this method must be called in a separate thread from ServiceStateTracker, which is the
+    // main thread of Telephony service.
+    private @Nullable String getCurrentMccFromCellInfo(@NonNull Context context) {
+        // retrieve mcc info from base station even no SIM present.
+        TelephonyManager tm = (TelephonyManager) context.getSystemService(
+                Context.TELEPHONY_SERVICE);
+        List<CellInfo> cellInfos = tm.getAllCellInfo();
+        String mcc = null;
+        if (cellInfos != null) {
+            for (CellInfo ci : cellInfos) {
+                if (ci instanceof CellInfoGsm) {
+                    CellInfoGsm cellInfoGsm = (CellInfoGsm) ci;
+                    CellIdentityGsm cellIdentityGsm = cellInfoGsm.getCellIdentity();
+                    mcc = cellIdentityGsm.getMccString();
+                    break;
+                } else if (ci instanceof CellInfoWcdma) {
+                    CellInfoWcdma cellInfoWcdma = (CellInfoWcdma) ci;
+                    CellIdentityWcdma cellIdentityWcdma = cellInfoWcdma.getCellIdentity();
+                    mcc = cellIdentityWcdma.getMccString();
+                    break;
+                } else if (ci instanceof CellInfoLte) {
+                    CellInfoLte cellInfoLte = (CellInfoLte) ci;
+                    CellIdentityLte cellIdentityLte = cellInfoLte.getCellIdentity();
+                    mcc = cellIdentityLte.getMccString();
+                    break;
+                }
+            }
+            if (DBG) Log.d(LOG_TAG, "Retrieve MCC from cell info list: " + Rlog.pii(LOG_TAG, mcc));
+        } else {
+            Log.w(LOG_TAG, "Cannot get cell info list.");
+        }
+        return mcc;
+    }
+}
diff --git a/src/com/android/phone/ecc/IsoToEccProtobufRepository.java b/src/com/android/phone/ecc/IsoToEccProtobufRepository.java
new file mode 100644
index 0000000..d44de9a
--- /dev/null
+++ b/src/com/android/phone/ecc/IsoToEccProtobufRepository.java
@@ -0,0 +1,157 @@
+/*
+ * 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.
+ */
+
+package com.android.phone.ecc;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.os.SystemClock;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.Log;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.zip.GZIPInputStream;
+
+/**
+ * Provide the mapping of country ISO to ECC. The data is stored in Protocol Buffers format,
+ * compressed with GZIP and encoded to base64 string.
+ */
+public class IsoToEccProtobufRepository implements IsoToEccRepository {
+    private static final String LOG_TAG = "EccRepository";
+
+    private Map<String, CountryEccInfo> mEccTable = null;
+
+    @Override
+    @Nullable
+    public CountryEccInfo getCountryEccInfo(@NonNull Context context, @Nullable String iso)
+            throws IOException {
+        if (iso != null) {
+            iso = iso.toUpperCase();
+        } else {
+            return null;
+        }
+
+        if (mEccTable == null) {
+            mEccTable = initMappingTable(context);
+        }
+        return mEccTable.get(iso);
+    }
+
+    private Map<String, CountryEccInfo> initMappingTable(@NonNull Context context)
+            throws IOException {
+        ProtobufEccData.AllInfo allEccData = null;
+
+        long startTime = SystemClock.uptimeMillis();
+        allEccData = parseEccData(new BufferedInputStream(
+                context.getAssets().open("eccdata")));
+        long endTime = SystemClock.uptimeMillis();
+
+        if (allEccData == null) {
+            // Return an empty table.
+            return new HashMap<>();
+        }
+
+        if (Log.isLoggable(LOG_TAG, Log.DEBUG)) {
+            Log.d(LOG_TAG, "Loading time = " + (endTime - startTime) + "ms"
+                    + ", Country Count = " + allEccData.getCountriesCount()
+                    + ", initialized = " + allEccData.isInitialized());
+        }
+
+        // Convert to run-time data from Protobuf data.
+        Map<String, CountryEccInfo> table = new HashMap<>();
+        for (ProtobufEccData.CountryInfo countryData : allEccData.getCountriesList()) {
+            if (countryData.hasIsoCode()) {
+                CountryEccInfo countryInfo = loadCountryEccInfo(countryData);
+                if (countryInfo != null) {
+                    table.put(countryData.getIsoCode().toUpperCase(), countryInfo);
+                }
+            }
+        }
+        return table;
+    }
+
+    private ProtobufEccData.AllInfo parseEccData(InputStream input) throws IOException {
+        return ProtobufEccData.AllInfo.parseFrom(new GZIPInputStream(input));
+    }
+
+    private EccInfo loadEccInfo(String isoCode, ProtobufEccData.EccInfo eccData) {
+        String phoneNumber = eccData.getPhoneNumber().trim();
+        if (phoneNumber.isEmpty()) {
+            Log.i(LOG_TAG, "Discard ecc " + phoneNumber
+                    + " for " + isoCode + " due to empty phone number");
+            return null;
+        }
+
+        ArraySet<EccInfo.Type> eccTypes = new ArraySet<>(eccData.getTypesCount());
+        for (ProtobufEccData.EccInfo.Type typeData : eccData.getTypesList()) {
+            switch (typeData) {
+                case POLICE:
+                    eccTypes.add(EccInfo.Type.POLICE);
+                    break;
+                case AMBULANCE:
+                    eccTypes.add(EccInfo.Type.AMBULANCE);
+                    break;
+                case FIRE:
+                    eccTypes.add(EccInfo.Type.FIRE);
+                    break;
+                default:
+                    // Ignore unknown types.
+            }
+        }
+
+        if (eccTypes.isEmpty()) {
+            Log.i(LOG_TAG, "Discard ecc " + phoneNumber
+                    + " for " + isoCode + " due to no valid type");
+            return null;
+        }
+        return new EccInfo(phoneNumber, eccTypes);
+    }
+
+    private CountryEccInfo loadCountryEccInfo(ProtobufEccData.CountryInfo countryData) {
+        ArrayMap<String, EccInfo> eccInfoMap = new ArrayMap<>(countryData.getEccsCount());
+        for (ProtobufEccData.EccInfo eccData : countryData.getEccsList()) {
+            EccInfo eccInfo = loadEccInfo(countryData.getIsoCode(), eccData);
+            String key = eccInfo.getNumber().trim();
+            EccInfo existentEccInfo = eccInfoMap.get(key);
+            if (existentEccInfo == null) {
+                eccInfoMap.put(key, eccInfo);
+            } else {
+                // Merge types of duplicated ecc info objects.
+                ArraySet<EccInfo.Type> eccTypes = new ArraySet<>(
+                        eccInfo.getTypesCount() + existentEccInfo.getTypesCount());
+                for (EccInfo.Type type : eccInfo.getTypes()) {
+                    eccTypes.add(type);
+                }
+                for (EccInfo.Type type : existentEccInfo.getTypes()) {
+                    eccTypes.add(type);
+                }
+                eccInfoMap.put(key, new EccInfo(eccInfo.getNumber(), eccTypes));
+            }
+        }
+
+        if (eccInfoMap.isEmpty() && !countryData.hasEccFallback()) {
+            Log.i(LOG_TAG, "Discard empty data for " + countryData.getIsoCode());
+            return null;
+        }
+        return new CountryEccInfo(countryData.getEccFallback(), eccInfoMap.values());
+    }
+}
diff --git a/src/com/android/phone/ecc/IsoToEccRepository.java b/src/com/android/phone/ecc/IsoToEccRepository.java
new file mode 100644
index 0000000..fd5ac83
--- /dev/null
+++ b/src/com/android/phone/ecc/IsoToEccRepository.java
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+package com.android.phone.ecc;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+
+import java.io.IOException;
+
+/**
+ * Data source for country ISO to ECC info list mapping.
+ */
+public interface IsoToEccRepository {
+    /**
+     * Get available emergency numbers for given country ISO. Because the possible of IO wait
+     * (depends on the implementation), this method should not be called in the main thread.
+     *
+     * @param context The context used to access resources.
+     * @param iso For which ECC info list is returned.
+     * @return The ECC info of given ISO. Null if no match.
+     * @throws IOException if an error occurs while initialize the repository or retrieving
+     * the {@link CountryEccInfo}.
+     */
+    @Nullable CountryEccInfo getCountryEccInfo(@NonNull Context context, @Nullable String iso)
+            throws IOException;
+}
diff --git a/src/com/android/phone/euicc/EuiccPrivilegedActionUiDispatcherActivity.java b/src/com/android/phone/euicc/EuiccPrivilegedActionUiDispatcherActivity.java
new file mode 100644
index 0000000..389795b
--- /dev/null
+++ b/src/com/android/phone/euicc/EuiccPrivilegedActionUiDispatcherActivity.java
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+package com.android.phone.euicc;
+
+import android.annotation.Nullable;
+import android.content.Intent;
+import android.service.euicc.EuiccService;
+import android.telephony.euicc.EuiccManager;
+import android.util.Log;
+
+/**
+ * Trampoline activity to forward privileged eUICC intents from the system to the active UI
+ * implementation.
+ *
+ * <p>Unlike {@link EuiccUiDispatcherActivity}, this activity requires a locked-down permission to
+ * start.
+ */
+public class EuiccPrivilegedActionUiDispatcherActivity extends EuiccUiDispatcherActivity {
+    private static final String TAG = "EuiccPrivUiDispatcher";
+
+    @Override
+    @Nullable
+    protected Intent getEuiccUiIntent() {
+        String action = getIntent().getAction();
+
+        Intent intent = new Intent();
+        // Propagate the extras from the original Intent.
+        intent.putExtras(getIntent());
+        switch (action) {
+            case EuiccManager.ACTION_TOGGLE_SUBSCRIPTION_PRIVILEGED:
+                intent.setAction(EuiccService.ACTION_TOGGLE_SUBSCRIPTION_PRIVILEGED);
+                break;
+            case EuiccManager.ACTION_DELETE_SUBSCRIPTION_PRIVILEGED:
+                intent.setAction(EuiccService.ACTION_DELETE_SUBSCRIPTION_PRIVILEGED);
+                break;
+            case EuiccManager.ACTION_RENAME_SUBSCRIPTION_PRIVILEGED:
+                intent.setAction(EuiccService.ACTION_RENAME_SUBSCRIPTION_PRIVILEGED);
+                break;
+            default:
+                Log.w(TAG, "Unsupported action: " + action);
+                return null;
+        }
+
+        return intent;
+    }
+}
diff --git a/src/com/android/phone/settings/AccessibilitySettingsFragment.java b/src/com/android/phone/settings/AccessibilitySettingsFragment.java
index 5c614d9..d540fba 100644
--- a/src/com/android/phone/settings/AccessibilitySettingsFragment.java
+++ b/src/com/android/phone/settings/AccessibilitySettingsFragment.java
@@ -93,7 +93,7 @@
         mButtonHac = (SwitchPreference) findPreference(BUTTON_HAC_KEY);
         mButtonRtt = (SwitchPreference) findPreference(BUTTON_RTT_KEY);
 
-        if (PhoneGlobals.getInstance().phoneMgr.isTtyModeSupported()) {
+        if (PhoneGlobals.getInstance().phoneMgr.isTtyModeSupported() && isTtySupportedByCarrier()) {
             mButtonTty.init();
         } else {
             getPreferenceScreen().removePreference(mButtonTty);
@@ -191,4 +191,15 @@
         }
         return false;
     }
+
+    /**
+     * Determines if the device supports TTY per carrier config.
+     * @return {@code true} if the carrier supports TTY, {@code false} otherwise.
+     */
+    private boolean isTtySupportedByCarrier() {
+        CarrierConfigManager configManager =
+                (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        return configManager.getConfig().getBoolean(
+                CarrierConfigManager.KEY_TTY_SUPPORTED_BOOL);
+    }
 }
diff --git a/src/com/android/services/telephony/DisconnectCauseUtil.java b/src/com/android/services/telephony/DisconnectCauseUtil.java
index a92dea7..8ef9565 100644
--- a/src/com/android/services/telephony/DisconnectCauseUtil.java
+++ b/src/com/android/services/telephony/DisconnectCauseUtil.java
@@ -249,6 +249,10 @@
                 resourceId = R.string.callFailed_userBusy;
                 break;
 
+            case android.telephony.DisconnectCause.CDMA_REORDER:
+                resourceId = R.string.callFailed_NetworkBusy;
+                break;
+
             case android.telephony.DisconnectCause.CONGESTION:
                 resourceId = R.string.callFailed_congestion;
                 break;
@@ -557,6 +561,10 @@
                 resourceId = R.string.callFailed_cdma_activation;
                 break;
 
+            case android.telephony.DisconnectCause.CDMA_REORDER:
+                resourceId = R.string.callFailed_NetworkBusy;
+                break;
+
             case android.telephony.DisconnectCause.FDN_BLOCKED:
                 resourceId = R.string.callFailed_fdn_only;
                 break;
diff --git a/src/com/android/services/telephony/ImsConference.java b/src/com/android/services/telephony/ImsConference.java
index c992c74..cada504 100644
--- a/src/com/android/services/telephony/ImsConference.java
+++ b/src/com/android/services/telephony/ImsConference.java
@@ -1170,8 +1170,7 @@
                 setStatusHints(new StatusHints(
                         context.getString(R.string.status_hint_label_wifi_call),
                         Icon.createWithResource(
-                                context.getResources(),
-                                R.drawable.ic_signal_wifi_4_bar_24dp),
+                                context, R.drawable.ic_signal_wifi_4_bar_24dp),
                         null /* extras */));
             }
         } else {
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index f925dd6..d6c1da6 100644
--- a/src/com/android/services/telephony/TelecomAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecomAccountRegistry.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.graphics.Bitmap;
@@ -115,7 +116,10 @@
             }
 
             try {
-                mMmTelManager = ImsMmTelManager.createForSubscriptionId(getSubId());
+                if (mPhone.getContext().getPackageManager().hasSystemFeature(
+                        PackageManager.FEATURE_TELEPHONY_IMS)) {
+                    mMmTelManager = ImsMmTelManager.createForSubscriptionId(getSubId());
+                }
             } catch (IllegalArgumentException e) {
                 Log.i(this, "Not registering MmTel capabilities listener because the subid '"
                         + getSubId() + "' is invalid: " + e.getMessage());
@@ -267,7 +271,14 @@
                 capabilities |= PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS;
             }
 
-            mIsVideoCapable = mPhone.isVideoEnabled();
+            if (isRttCurrentlySupported()) {
+                capabilities |= PhoneAccount.CAPABILITY_RTT;
+                mIsRttCapable = true;
+            } else {
+                mIsRttCapable = false;
+            }
+
+            mIsVideoCapable = mPhone.isVideoEnabled() && !mIsRttCapable;
             boolean isVideoEnabledByPlatform = ImsManager.getInstance(mPhone.getContext(),
                     mPhone.getPhoneId()).isVtEnabledByPlatform();
 
@@ -317,14 +328,6 @@
                 extras.putBoolean(PhoneAccount.EXTRA_PLAY_CALL_RECORDING_TONE, true);
             }
 
-            if (PhoneGlobals.getInstance().phoneMgr.isRttEnabled(subId)
-                    && isImsVoiceAvailable()) {
-                capabilities |= PhoneAccount.CAPABILITY_RTT;
-                mIsRttCapable = true;
-            } else {
-                mIsRttCapable = false;
-            }
-
             extras.putBoolean(PhoneAccount.EXTRA_SUPPORTS_VIDEO_CALLING_FALLBACK,
                     mContext.getResources()
                             .getBoolean(R.bool.config_support_video_calling_fallback));
@@ -586,17 +589,28 @@
         }
 
         public void updateRttCapability() {
-            boolean hasVoiceAvailability = isImsVoiceAvailable();
-
-            boolean isRttSupported = PhoneGlobals.getInstance().phoneMgr
-                    .isRttEnabled(mPhone.getSubId());
-
-            boolean isRttEnabled = hasVoiceAvailability && isRttSupported;
+            boolean isRttEnabled = isRttCurrentlySupported();
             if (isRttEnabled != mIsRttCapable) {
                 Log.i(this, "updateRttCapability - changed, new value: " + isRttEnabled);
                 mAccount = registerPstnPhoneAccount(mIsEmergency, mIsDummy);
             }
         }
+
+        /**
+         * Determines whether RTT is supported given the current state of the
+         * device.
+         */
+        private boolean isRttCurrentlySupported() {
+            boolean hasVoiceAvailability = isImsVoiceAvailable();
+
+            boolean isRttSupported = PhoneGlobals.getInstance().phoneMgr
+                    .isRttEnabled(mPhone.getSubId());
+
+            boolean isRoaming = mTelephonyManager.isNetworkRoaming(mPhone.getSubId());
+
+            return hasVoiceAvailability && isRttSupported && !isRoaming;
+        }
+
         /**
          * Indicates whether this account supports pausing video calls.
          * @return {@code true} if the account supports pausing video calls, {@code false}
@@ -719,6 +733,12 @@
             if (newState == ServiceState.STATE_IN_SERVICE && mServiceState != newState) {
                 tearDownAccounts();
                 setupAccounts();
+            } else {
+                synchronized (mAccountsLock) {
+                    for (AccountEntry account : mAccounts) {
+                        account.updateRttCapability();
+                    }
+                }
             }
             mServiceState = newState;
         }
@@ -1015,10 +1035,16 @@
                     Log.d(this, "Phone with subscription id %d", subscriptionId);
                     // setupAccounts can be called multiple times during service changes. Don't add an
                     // account if the Icc has not been set yet.
-                    if (subscriptionId >= 0 && phone.getFullIccSerialNumber() != null) {
-                        mAccounts.add(new AccountEntry(phone, false /* emergency */,
-                                false /* isDummy */));
-                    }
+                    if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)
+                            || phone.getFullIccSerialNumber() == null) return;
+                    // Don't add account if it's opportunistic subscription, which is considered
+                    // data only for now.
+                    SubscriptionInfo info = SubscriptionManager.from(mContext)
+                            .getActiveSubscriptionInfo(subscriptionId);
+                    if (info == null || info.isOpportunistic()) return;
+
+                    mAccounts.add(new AccountEntry(phone, false /* emergency */,
+                            false /* isDummy */));
                 }
             }
 
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 3886e58..632e9ac 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -46,7 +46,6 @@
 import com.android.internal.telephony.Call;
 import com.android.internal.telephony.CallFailCause;
 import com.android.internal.telephony.CallStateException;
-import com.android.internal.telephony.Call.HoldingRequestState;
 import com.android.internal.telephony.Connection.Capability;
 import com.android.internal.telephony.Connection.PostDialListener;
 import com.android.internal.telephony.Phone;
@@ -933,12 +932,6 @@
             try {
                 Phone phone = mOriginalConnection.getCall().getPhone();
 
-                // New behavior for IMS -- don't use the clunky switchHoldingAndActive logic.
-                if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) {
-                    ImsPhone imsPhone = (ImsPhone) phone;
-                    imsPhone.holdActiveCall();
-                    return;
-                }
                 Call ringingCall = phone.getRingingCall();
 
                 // Although the method says switchHoldingAndActive, it eventually calls a RIL method
@@ -952,8 +945,13 @@
                 // could "fake" hold by silencing the audio and microphone streams for this call
                 // instead of actually putting it on hold.
                 if (ringingCall.getState() != Call.State.WAITING) {
+                    // New behavior for IMS -- don't use the clunky switchHoldingAndActive logic.
+                    if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) {
+                        ImsPhone imsPhone = (ImsPhone) phone;
+                        imsPhone.holdActiveCall();
+                        return;
+                    }
                     phone.switchHoldingAndActive();
-                    mOriginalConnection.getCall().updateHoldingRequestState(HoldingRequestState.STARTED);
                 }
 
                 // TODO: Cdma calls are slightly different.
@@ -2109,8 +2107,7 @@
             setStatusHints(new StatusHints(
                     context.getString(labelId),
                     Icon.createWithResource(
-                            context.getResources(),
-                            R.drawable.ic_signal_wifi_4_bar_24dp),
+                            context, R.drawable.ic_signal_wifi_4_bar_24dp),
                     null /* extras */));
         } else {
             setStatusHints(null);
diff --git a/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/ImsRegistrationActivity.java b/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/ImsRegistrationActivity.java
index 84ec7b9..4ee9355 100644
--- a/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/ImsRegistrationActivity.java
+++ b/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/ImsRegistrationActivity.java
@@ -121,8 +121,8 @@
         }
 
         @Override
-        public void onDeregistered(ImsReasonInfo info) {
-            Log.i("ImsRegistrationActivity", "onDeregistered: " + info);
+        public void onUnregistered(ImsReasonInfo info) {
+            Log.i("ImsRegistrationActivity", "onUnregistered: " + info);
             mRegItems.add(new RegItem("Deregistered", info.toString()));
             triggerAdapterChange();
         }
@@ -151,8 +151,8 @@
     private static final Map<Integer, String> REG_TECH_STRING = new ArrayMap<>(2);
     static {
         REG_TECH_STRING.put(ImsRegistrationImplBase.REGISTRATION_TECH_NONE, "NONE");
-        REG_TECH_STRING.put(AccessNetworkConstants.TransportType.WWAN, "WWAN");
-        REG_TECH_STRING.put(AccessNetworkConstants.TransportType.WLAN, "WLAN");
+        REG_TECH_STRING.put(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, "WWAN");
+        REG_TECH_STRING.put(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, "WLAN");
     }