DO NOT MERGE Set Settings.Global.CELL_ON default to CELL_ON_FLAG if not defined.
am: 89dd33541f

Change-Id: Ief123beee9e3697707f9be2a41b2ea1bab742d1d
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index b5fd399..f611706 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -585,6 +585,7 @@
 
         <activity android:name="com.android.phone.settings.VoicemailSettingsActivity"
             android:label="@string/voicemail"
+            android:configChanges="orientation|screenSize|keyboardHidden"
             android:theme="@style/DialerSettingsLight">
             <intent-filter >
                 <!-- DO NOT RENAME. There are existing apps which use this string. -->
diff --git a/res/values-bn-rBD/strings.xml b/res/values-bn-rBD/strings.xml
index 4acd204..0b14bd9 100644
--- a/res/values-bn-rBD/strings.xml
+++ b/res/values-bn-rBD/strings.xml
@@ -388,7 +388,7 @@
     <string name="simContacts_emptyLoading" msgid="2203331234764498011">"সিম কার্ড থেকে পড়া হচ্ছে…"</string>
     <string name="simContacts_empty" msgid="5270660846489561932">"আপনার সিম কার্ডে কোনো পরিচিত নেই৷"</string>
     <string name="simContacts_title" msgid="1861472842524839921">"পরিচিতগুলি আমদানি করুন"</string>
-    <string name="simContacts_airplaneMode" msgid="5254946758982621072">"SIM কার্ডটি থেকে পরিচিতিগুলি আমদানি করতে বিমান মোড বন্ধ করুন৷"</string>
+    <string name="simContacts_airplaneMode" msgid="5254946758982621072">"সিম কার্ডটি থেকে পরিচিতিগুলি আমদানি করতে বিমান মোড বন্ধ করুন৷"</string>
     <string name="enable_pin" msgid="5422767284133234860">"সিম পিন সক্ষম/অক্ষম করুন"</string>
     <string name="change_pin" msgid="9174186126330785343">"সিম পিন পরিবর্তন করুন"</string>
     <string name="enter_pin_text" msgid="8532615714751931951">"সিম পিন:"</string>
@@ -398,8 +398,8 @@
     <string name="badPin" msgid="8955102849303984935">"আপনার দ্বারা টাইপ করা পুরানো পিন সঠিক নয়৷ আবার চেষ্টা করুন৷"</string>
     <string name="mismatchPin" msgid="5923253370683071889">"আপনার টাইপ করা PINগুলি মিলছে না৷ আবার চেষ্টা করুন৷"</string>
     <string name="invalidPin" msgid="5981171102258684792">"৪ থেকে ৮ সংখ্যা বিশিষ্ট একটি পিন টাইপ করুন৷"</string>
-    <string name="disable_sim_pin" msgid="3419351358300716472">"SIM এর পিন সাফ করুন"</string>
-    <string name="enable_sim_pin" msgid="4845145659651484248">"SIM এর পিন সেট করুন"</string>
+    <string name="disable_sim_pin" msgid="3419351358300716472">"সিম এর পিন সাফ করুন"</string>
+    <string name="enable_sim_pin" msgid="4845145659651484248">"সিম এর পিন সেট করুন"</string>
     <string name="enable_in_progress" msgid="3417917024688497010">"পিন সেটিং…"</string>
     <string name="enable_pin_ok" msgid="2918545971413270063">"পিন সেট করুন"</string>
     <string name="disable_pin_ok" msgid="2109571368635883688">"পিন সাফ করা হয়েছে"</string>
@@ -418,11 +418,11 @@
     <string name="pin2_changed" msgid="3724522579945610956">"PIN2 আপডেট হয়েছে"</string>
     <string name="label_puk2_code" msgid="4688069961795341948">"PUK2 কোড লিখুন"</string>
     <string name="fdn_enable_puk2_requested" msgid="4991074891459554705">"পাসওয়ার্ডটি ভুল৷ পিন2 এখন অবরুদ্ধ৷ আবার চেষ্টা করতে, পিন 2 পরিবর্তন করুন৷"</string>
-    <string name="puk2_requested" msgid="5831015200030161434">"পাসওয়ার্ডটি ভুল৷ SIM এখন অবরুদ্ধ৷ PUK2 লিখুন৷"</string>
+    <string name="puk2_requested" msgid="5831015200030161434">"পাসওয়ার্ডটি ভুল৷ সিম এখন অবরুদ্ধ৷ PUK2 লিখুন৷"</string>
     <string name="puk2_blocked" msgid="3150263853077280049">"PUK2 স্থায়ীভাবে অবরুদ্ধ করা হয়েছে৷"</string>
     <string name="pin2_attempts" msgid="720736232885011507">\n"আপনার কাছে <xliff:g id="NUMBER">%d</xliff:g>টি প্রচেষ্টা অবশিষ্ট রয়েছে৷"</string>
     <string name="pin2_unblocked" msgid="7791600368153469078">"PIN2 এখন আর অবরুদ্ধ নয়"</string>
-    <string name="pin2_error_exception" msgid="1088689322248996699">"নেটওয়ার্ক বা SIM কার্ড ত্রুটি৷"</string>
+    <string name="pin2_error_exception" msgid="1088689322248996699">"নেটওয়ার্ক বা সিম কার্ড ত্রুটি৷"</string>
     <string name="doneButton" msgid="2859593360997984240">"সম্পন্ন হয়েছে"</string>
     <string name="voicemail_settings_number_label" msgid="8524164258691887790">"ভয়েসমেল নম্বর"</string>
     <string name="card_title_dialing" msgid="5769417478498348054">"ডায়াল করা হচ্ছে"</string>
@@ -565,13 +565,13 @@
     <string name="enable_video_calling_dialog_close" msgid="7411471282167927991">"বন্ধ করুন"</string>
     <string name="sim_label_emergency_calls" msgid="4847699229529306397">"জরুরি কলগুলি"</string>
     <string name="sim_description_emergency_calls" msgid="7535215397212301562">"শুধুমাত্র জরুরী কলিং"</string>
-    <string name="sim_description_default" msgid="4778679519938775515">"SIM কার্ড, স্লট: <xliff:g id="SLOT_ID">%s</xliff:g>"</string>
+    <string name="sim_description_default" msgid="4778679519938775515">"সিম কার্ড, স্লট: <xliff:g id="SLOT_ID">%s</xliff:g>"</string>
     <string name="accessibility_settings_activity_title" msgid="8562004288733103868">"অ্যাক্সেসযোগ্যতা"</string>
     <string name="status_hint_label_incoming_wifi_call" msgid="5932176406432044638">"এর থেকে Wi-Fi কল"</string>
     <string name="status_hint_label_wifi_call" msgid="8900805254974653903">"ওয়াই-ফাই কল"</string>
     <string name="emergency_action_launch_hint" msgid="4906759256275562674">"খোলার জন্য আবার আলতো চাপুন"</string>
     <string name="message_decode_error" msgid="3456481534066924855">"বার্তাটি ডিকোড করার সময় একটি ত্রুটি ঘটেছে৷"</string>
-    <string name="callFailed_cdma_activation" msgid="2307989779233262164">"একটি SIM কার্ড আপনার পরিষেবা সক্রিয় করেছে এবং আপনার ফোনের রোমিং ক্ষমতা আপডেট করা হয়েছে৷"</string>
+    <string name="callFailed_cdma_activation" msgid="2307989779233262164">"একটি সিম কার্ড আপনার পরিষেবা সক্রিয় করেছে এবং আপনার ফোনের রোমিং ক্ষমতা আপডেট করা হয়েছে৷"</string>
     <string name="callFailed_cdma_call_limit" msgid="1556916577171457086">"অনেকগুলি কল সক্রিয় রয়েছে। অনুগ্রহ করে একটি নতুন কল করার আগে বিদ্যমান কলগুলি কেটে দিন বা এটিকে সেই কলগুলিতে অন্তর্ভুক্ত করুন।"</string>
     <string name="change_pin_title" msgid="7790232089699034029">"ভয়েসমেলের PIN পরিবর্তন করুন"</string>
     <string name="change_pin_continue_label" msgid="2135088662420163447">"চালিয়ে যান"</string>
diff --git a/res/values-gl-rES/strings.xml b/res/values-gl-rES/strings.xml
index 5f65254..3a16652 100644
--- a/res/values-gl-rES/strings.xml
+++ b/res/values-gl-rES/strings.xml
@@ -228,9 +228,9 @@
     <string name="throttle_help" msgid="243651091785169900">"Máis información"</string>
     <string name="throttle_status_subtext" msgid="1657318943142085170">"<xliff:g id="USED_0">%1$s</xliff:g> (<xliff:g id="USED_1">%2$d</xliff:g>٪) de <xliff:g id="USED_2">%3$s</xliff:g> de período máximo\nO seguinte período comeza dentro de <xliff:g id="USED_3">%4$d</xliff:g> días (<xliff:g id="USED_4">%5$s</xliff:g>)"</string>
     <string name="throttle_data_usage_subtext" msgid="6029276011123694701">"<xliff:g id="USED_0">%1$s</xliff:g> (<xliff:g id="USED_1">%2$d</xliff:g>٪) de <xliff:g id="USED_2">%3$s</xliff:g> de período máximo"</string>
-    <string name="throttle_data_rate_reduced_subtext" msgid="7492763592720107737">"<xliff:g id="USED_0">%1$s</xliff:g> máximo superado\nTaxa de datos reducida a <xliff:g id="USED_1">%2$d</xliff:g> Kb/s"</string>
+    <string name="throttle_data_rate_reduced_subtext" msgid="7492763592720107737">"<xliff:g id="USED_0">%1$s</xliff:g> máximo superado\nTaxa de datos reducida a <xliff:g id="USED_1">%2$d</xliff:g> kb/s"</string>
     <string name="throttle_time_frame_subtext" msgid="7732763021560399960">"<xliff:g id="USED_0">%1$d</xliff:g>٪ do ciclo transcorrido\nO seguinte período comeza dentro de <xliff:g id="USED_1">%2$d</xliff:g> días (<xliff:g id="USED_2">%3$s</xliff:g>)"</string>
-    <string name="throttle_rate_subtext" msgid="2149102656120726855">"A velocidade de datos redúcese a <xliff:g id="USED">%1$d</xliff:g> Kb/s se se supera o límite de uso de datos"</string>
+    <string name="throttle_rate_subtext" msgid="2149102656120726855">"A velocidade de datos redúcese a <xliff:g id="USED">%1$d</xliff:g> kb/s se se supera o límite de uso de datos"</string>
     <string name="throttle_help_subtext" msgid="3633091498168446044">"Máis información sobre a política de uso de datos da rede móbil do teu operador"</string>
     <string name="cell_broadcast_sms" msgid="5584192824053625842">"SMS de difusión móbil"</string>
     <string name="enable_disable_cell_bc_sms" msgid="4851147873691392255">"SMS de difusión móbil"</string>
diff --git a/res/values-ml-rIN/strings.xml b/res/values-ml-rIN/strings.xml
index 6249b5d..97a3890 100644
--- a/res/values-ml-rIN/strings.xml
+++ b/res/values-ml-rIN/strings.xml
@@ -566,7 +566,7 @@
     <string name="sim_label_emergency_calls" msgid="4847699229529306397">"അടിയന്തിര കോളുകൾ"</string>
     <string name="sim_description_emergency_calls" msgid="7535215397212301562">"അടിയന്തിര കോൾചെയ്യൽ മാത്രം"</string>
     <string name="sim_description_default" msgid="4778679519938775515">"SIM കാർഡ്, സ്ലോട്ട്: <xliff:g id="SLOT_ID">%s</xliff:g>"</string>
-    <string name="accessibility_settings_activity_title" msgid="8562004288733103868">"പ്രവേശനക്ഷമത"</string>
+    <string name="accessibility_settings_activity_title" msgid="8562004288733103868">"ഉപയോഗസഹായി"</string>
     <string name="status_hint_label_incoming_wifi_call" msgid="5932176406432044638">"ഈ വ്യക്തിയിൽ നിന്നുള്ള Wi-Fi കോൾ"</string>
     <string name="status_hint_label_wifi_call" msgid="8900805254974653903">"വൈഫൈ കോൾ"</string>
     <string name="emergency_action_launch_hint" msgid="4906759256275562674">"തുറക്കുന്നതിന് വീണ്ടും ടാപ്പുചെയ്യുക"</string>
diff --git a/res/values-mr-rIN/strings.xml b/res/values-mr-rIN/strings.xml
index c8a2d26..e0e5390 100644
--- a/res/values-mr-rIN/strings.xml
+++ b/res/values-mr-rIN/strings.xml
@@ -85,7 +85,7 @@
     <string name="additional_cdma_call_settings" msgid="8628958775721886909">"अतिरिक्‍त CDMA कॉल सेटिंग्‍ज"</string>
     <string name="sum_cdma_call_settings" msgid="284753265979035549">"अतिरिक्त CDMA केवळ कॉल सेटिंग्‍ज"</string>
     <string name="labelNwService" msgid="4699970172021870983">"नेटवर्क सेवा सेटिंग्ज"</string>
-    <string name="labelCallerId" msgid="3888899447379069198">"कॉलर ID"</string>
+    <string name="labelCallerId" msgid="3888899447379069198">"कॉलर आयडी"</string>
     <string name="sum_loading_settings" msgid="1826692909391168620">"सेटिंग्ज लोड करीत आहे..."</string>
     <string name="sum_hide_caller_id" msgid="1071407020290873782">"केल्‍या जाणार्‍या कॉलमध्‍ये नंबर लपविला"</string>
     <string name="sum_show_caller_id" msgid="6768534125447290401">"केल्‍या जाणार्‍या कॉलमध्‍ये नंबर प्रदर्शित केला"</string>
diff --git a/res/values/config.xml b/res/values/config.xml
index 2ec3388..7d5af52 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -210,6 +210,9 @@
     <!-- Flag to enable VVM3 visual voicemail. VVM3 is used by Verizon Wireless. -->
     <bool name="vvm3_enabled">false</bool>
 
+    <!-- Component for custom voicemail notification handling. [DO NOT TRANSLATE] -->
+    <string name="config_customVoicemailComponent">@null</string>
+
     <!-- Flag indicating whether to allow pstn phone accounts [DO NOT TRANSLATE] -->
     <bool name="config_pstn_phone_accounts_enabled">true</bool>
 
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index 111e263..a6d54ef 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -284,7 +284,9 @@
 
         if (ImsManager.isVtEnabledByPlatform(mPhone.getContext()) &&
                 ImsManager.isVtProvisionedOnDevice(mPhone.getContext()) &&
-                mPhone.mDcTracker.isDataEnabled(true)) {
+                (carrierConfig.getBoolean(
+                        CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS)
+                        || mPhone.mDcTracker.isDataEnabled(true))) {
             boolean currentValue =
                     ImsManager.isEnhanced4gLteModeSettingEnabledByUser(mPhone.getContext())
                     ? PhoneGlobals.getInstance().phoneMgr.isVideoCallingEnabled(
@@ -328,7 +330,8 @@
         } else {
             int resId = com.android.internal.R.string.wifi_calling_off_summary;
             if (ImsManager.isWfcEnabledByUser(mPhone.getContext())) {
-                int wfcMode = ImsManager.getWfcMode(mPhone.getContext());
+                boolean isRoaming = telephonyManager.isNetworkRoaming();
+                int wfcMode = ImsManager.getWfcMode(mPhone.getContext(), isRoaming);
                 switch (wfcMode) {
                     case ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY:
                         resId = com.android.internal.R.string.wfc_mode_wifi_only_summary;
diff --git a/src/com/android/phone/NetworkSetting.java b/src/com/android/phone/NetworkSetting.java
index a09c5c5..29608da 100644
--- a/src/com/android/phone/NetworkSetting.java
+++ b/src/com/android/phone/NetworkSetting.java
@@ -161,8 +161,6 @@
         public void onServiceConnected(ComponentName className, IBinder service) {
             if (DBG) log("connection created, binding local service.");
             mNetworkQueryService = ((NetworkQueryService.LocalBinder) service).getService();
-            // as soon as it is bound, run a query.
-            loadNetworksList();
         }
 
         /** Handle the task of cleaning up the local binding */
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index abe5397..d40b08e 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -16,8 +16,6 @@
 
 package com.android.phone;
 
-import static android.Manifest.permission.READ_PHONE_STATE;
-
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -26,7 +24,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
-import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.net.Uri;
@@ -36,7 +33,6 @@
 import android.os.UserManager;
 import android.preference.PreferenceManager;
 import android.provider.ContactsContract.PhoneLookup;
-import android.telecom.DefaultDialerManager;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
@@ -97,6 +93,7 @@
 
     private Context mContext;
     private NotificationManager mNotificationManager;
+    private final ComponentName mNotificationComponent;
     private StatusBarManager mStatusBarManager;
     private UserManager mUserManager;
     private Toast mToast;
@@ -127,6 +124,12 @@
         mTelecomManager = TelecomManager.from(mContext);
         mTelephonyManager = (TelephonyManager) app.getSystemService(Context.TELEPHONY_SERVICE);
 
+        final String notificationComponent = mContext.getString(
+                R.string.config_customVoicemailComponent);
+
+        mNotificationComponent = notificationComponent != null
+                ? ComponentName.unflattenFromString(notificationComponent) : null;
+
         mSubscriptionManager.addOnSubscriptionsChangedListener(
                 new OnSubscriptionsChangedListener() {
                     @Override
@@ -380,8 +383,8 @@
                 if (!mUserManager.hasUserRestriction(
                         UserManager.DISALLOW_OUTGOING_CALLS, userHandle)
                         && !user.isManagedProfile()) {
-                    if (!maybeSendVoicemailNotificationUsingDefaultDialer(vmCount, vmNumber,
-                            pendingIntent, isSettingsIntent, userHandle)) {
+                    if (!sendNotificationCustomComponent(vmCount, vmNumber, pendingIntent,
+                            isSettingsIntent)) {
                         mNotificationManager.notifyAsUser(
                                 Integer.toString(subId) /* tag */,
                                 VOICEMAIL_NOTIFICATION,
@@ -391,29 +394,19 @@
                 }
             }
         } else {
-            List<UserInfo> users = mUserManager.getUsers(true /* excludeDying */);
-            for (int i = 0; i < users.size(); i++) {
-                final UserInfo user = users.get(i);
-                final UserHandle userHandle = user.getUserHandle();
-                if (!mUserManager.hasUserRestriction(
-                        UserManager.DISALLOW_OUTGOING_CALLS, userHandle)
-                        && !user.isManagedProfile()) {
-                    if (!maybeSendVoicemailNotificationUsingDefaultDialer(0, null, null, false,
-                            userHandle)) {
-                        mNotificationManager.cancelAsUser(
-                                Integer.toString(subId) /* tag */,
-                                VOICEMAIL_NOTIFICATION,
-                                userHandle);
-                    }
-                }
+            if (!sendNotificationCustomComponent(0, null, null, false)) {
+                mNotificationManager.cancelAsUser(
+                        Integer.toString(subId) /* tag */,
+                        VOICEMAIL_NOTIFICATION,
+                        UserHandle.ALL);
             }
         }
     }
 
     /**
-     * Sends a broadcast with the voicemail notification information to the default dialer. This
-     * method is also used to indicate to the default dialer when to clear the
-     * notification. A pending intent can be passed to the default dialer to indicate an action to
+     * Sends a broadcast with the voicemail notification information to a custom component to
+     * handle. This method is also used to indicate to the custom component when to clear the
+     * notification. A pending intent can be passed to the custom component to indicate an action to
      * be taken as it would by a notification produced in this class.
      * @param count The number of pending voicemail messages to indicate on the notification. A
      *              Value of 0 is passed here to indicate that the notification should be cleared.
@@ -421,16 +414,14 @@
      * @param pendingIntent The intent that should be passed as the action to be taken.
      * @param isSettingsIntent {@code true} to indicate the pending intent is to launch settings.
      *                         otherwise, {@code false} to indicate the intent launches voicemail.
-     * @param userHandle The user to receive the notification. Each user can have their own default
-     *                   dialer.
-     * @return {@code true} if the default was notified of the notification.
+     * @return {@code true} if a custom component was notified of the notification.
      */
-    private boolean maybeSendVoicemailNotificationUsingDefaultDialer(Integer count, String number,
-            PendingIntent pendingIntent, boolean isSettingsIntent, UserHandle userHandle) {
-
-        if (shouldManageNotificationThroughDefaultDialer(userHandle)) {
-            Intent intent = getShowVoicemailIntentForDefaultDialer(userHandle);
+    private boolean sendNotificationCustomComponent(Integer count, String number,
+            PendingIntent pendingIntent, boolean isSettingsIntent) {
+        if (mNotificationComponent != null) {
+            Intent intent = new Intent();
             intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+            intent.setComponent(mNotificationComponent);
             intent.setAction(TelephonyManager.ACTION_SHOW_VOICEMAIL_NOTIFICATION);
 
             if (count != null) {
@@ -452,31 +443,14 @@
                             pendingIntent);
                 }
             }
-            mContext.sendBroadcastAsUser(intent, userHandle, READ_PHONE_STATE);
+
+            mContext.sendBroadcast(intent);
             return true;
         }
 
         return false;
     }
 
-    private Intent getShowVoicemailIntentForDefaultDialer(UserHandle userHandle) {
-        String dialerPackage = DefaultDialerManager
-                .getDefaultDialerApplication(mContext, userHandle.getIdentifier());
-        return new Intent(TelephonyManager.ACTION_SHOW_VOICEMAIL_NOTIFICATION)
-                .setPackage(dialerPackage);
-    }
-
-    private boolean shouldManageNotificationThroughDefaultDialer(UserHandle userHandle) {
-        Intent intent = getShowVoicemailIntentForDefaultDialer(userHandle);
-        if (intent == null) {
-            return false;
-        }
-
-        List<ResolveInfo> receivers = mContext.getPackageManager()
-                .queryBroadcastReceivers(intent, 0);
-        return receivers.size() > 0;
-    }
-
     /**
      * Updates the message call forwarding indicator notification.
      *
diff --git a/src/com/android/phone/settings/AccessibilitySettingsFragment.java b/src/com/android/phone/settings/AccessibilitySettingsFragment.java
index ea19f75..0c186a9 100644
--- a/src/com/android/phone/settings/AccessibilitySettingsFragment.java
+++ b/src/com/android/phone/settings/AccessibilitySettingsFragment.java
@@ -24,7 +24,6 @@
 import android.preference.PreferenceFragment;
 import android.preference.PreferenceScreen;
 import android.provider.Settings;
-import android.telecom.TelecomManager;
 import android.telephony.CarrierConfigManager;
 import android.telephony.PhoneStateListener;
 import android.telephony.TelephonyManager;
@@ -35,9 +34,6 @@
 import com.android.internal.telephony.PhoneFactory;
 import com.android.phone.PhoneGlobals;
 import com.android.phone.R;
-import com.android.phone.settings.TtyModeListPreference;
-
-import java.util.List;
 
 public class AccessibilitySettingsFragment extends PreferenceFragment {
     private static final String LOG_TAG = AccessibilitySettingsFragment.class.getSimpleName();
@@ -60,7 +56,7 @@
             if (pref != null) {
                 final boolean isVolteTtySupported = ImsManager.isVolteEnabledByPlatform(mContext)
                         && getVolteTtySupported();
-                pref.setEnabled((isVolteTtySupported && !isVideoCallInProgress()) ||
+                pref.setEnabled((isVolteTtySupported && !isVideoCallOrConferenceInProgress()) ||
                         (state == TelephonyManager.CALL_STATE_IDLE));
             }
         }
@@ -144,15 +140,15 @@
                 CarrierConfigManager.KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL);
     }
 
-    private boolean isVideoCallInProgress() {
+    private boolean isVideoCallOrConferenceInProgress() {
         final Phone[] phones = PhoneFactory.getPhones();
         if (phones == null) {
-            if (DBG) Log.d(LOG_TAG, "isVideoCallInProgress: No phones found. Return false");
+            if (DBG) Log.d(LOG_TAG, "isVideoCallOrConferenceInProgress: No phones found.");
             return false;
         }
 
         for (Phone phone : phones) {
-            if (phone.isVideoCallPresent()) {
+            if (phone.isImsVideoCallOrConferencePresent()) {
                 return true;
             }
         }
diff --git a/src/com/android/phone/settings/VoicemailSettingsActivity.java b/src/com/android/phone/settings/VoicemailSettingsActivity.java
index 35d9a1c..6bb481f 100644
--- a/src/com/android/phone/settings/VoicemailSettingsActivity.java
+++ b/src/com/android/phone/settings/VoicemailSettingsActivity.java
@@ -537,7 +537,11 @@
                     if (DBG) log("onActivityResult: bad contact data, no results found.");
                     return;
                 }
-                mSubMenuVoicemailSettings.onPickActivityResult(cursor.getString(0));
+                if (mSubMenuVoicemailSettings != null) {
+                    mSubMenuVoicemailSettings.onPickActivityResult(cursor.getString(0));
+                } else {
+                    Log.w(LOG_TAG, "VoicemailSettingsActivity destroyed while setting contacts.");
+                }
                 return;
             } finally {
                 if (cursor != null) {
diff --git a/src/com/android/phone/vvm/omtp/ActivationTask.java b/src/com/android/phone/vvm/omtp/ActivationTask.java
index 72f1f54..6fd42fd 100644
--- a/src/com/android/phone/vvm/omtp/ActivationTask.java
+++ b/src/com/android/phone/vvm/omtp/ActivationTask.java
@@ -27,7 +27,6 @@
 import android.telecom.PhoneAccountHandle;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
-
 import com.android.phone.Assert;
 import com.android.phone.PhoneGlobals;
 import com.android.phone.VoicemailStatus;
@@ -40,7 +39,6 @@
 import com.android.phone.vvm.omtp.sync.OmtpVvmSyncService;
 import com.android.phone.vvm.omtp.sync.SyncTask;
 import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
-
 import java.io.IOException;
 import java.util.HashSet;
 import java.util.Set;
@@ -135,7 +133,7 @@
         OmtpVvmCarrierConfigHelper helper = new OmtpVvmCarrierConfigHelper(getContext(), subId);
         if (!helper.isValid()) {
             VvmLog.i(TAG, "VVM not supported on subId " + subId);
-            VoicemailStatus.disable(getContext(), phoneAccountHandle);
+            OmtpVvmSourceManager.getInstance(getContext()).removeSource(phoneAccountHandle);
             return;
         }
 
diff --git a/src/com/android/phone/vvm/omtp/SimChangeReceiver.java b/src/com/android/phone/vvm/omtp/SimChangeReceiver.java
index 25c27db..a506a12 100644
--- a/src/com/android/phone/vvm/omtp/SimChangeReceiver.java
+++ b/src/com/android/phone/vvm/omtp/SimChangeReceiver.java
@@ -24,12 +24,13 @@
 import android.os.UserManager;
 import android.telecom.PhoneAccountHandle;
 import android.telephony.CarrierConfigManager;
+import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.text.TextUtils;
 import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.TelephonyIntents;
-import com.android.phone.VoicemailStatus;
 import com.android.phone.settings.VisualVoicemailSettingsUtil;
 import com.android.phone.vvm.omtp.sync.OmtpVvmSourceManager;
 import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
@@ -70,6 +71,25 @@
                     VvmLog.i(TAG, "Received SIM change for invalid subscription id.");
                     return;
                 }
+
+                TelephonyManager telephonyManager = context
+                        .getSystemService(TelephonyManager.class);
+                if(TextUtils.isEmpty(telephonyManager.getSimOperator())){
+                    VvmLog.e(TAG,
+                            "Empty MCCMNC, possible modem crash."
+                                    + " Ignoring carrier config changed event");
+                    return;
+                }
+
+                PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter
+                        .fromSubId(subId);
+                if("null".equals(phoneAccountHandle.getId())){
+                    VvmLog.e(TAG,
+                            "null phone account handle ID, possible modem crash."
+                                    + " Ignoring carrier config changed event");
+                    return;
+                }
+
                 VvmLog.d(TAG, "Carrier config changed");
                 if (UserManager.get(context).isUserUnlocked() && !isCryptKeeperMode()) {
                     processSubId(context, subId);
@@ -99,6 +119,12 @@
                 // can be recorded.
                 OmtpVvmSourceManager.getInstance(context).addPhoneStateListener(
                         phoneAccount);
+                if (context.getSystemService(TelephonyManager.class)
+                        .getServiceStateForSubscriber(subId).getState()
+                        != ServiceState.STATE_IN_SERVICE) {
+                    VvmLog.i(TAG, "Cellular signal not available, not activating");
+                    return;
+                }
                 carrierConfigHelper.startActivation();
             } else {
                 if (carrierConfigHelper.isLegacyModeEnabled()) {
@@ -115,7 +141,7 @@
             String mccMnc = context.getSystemService(TelephonyManager.class).getSimOperator(subId);
             VvmLog.d(TAG,
                     "visual voicemail not supported for carrier " + mccMnc + " on subId " + subId);
-            VoicemailStatus.disable(context, phoneAccount);
+            OmtpVvmSourceManager.getInstance(context).removeSource(phoneAccount);
         }
     }
 
diff --git a/src/com/android/phone/vvm/omtp/protocol/OmtpProtocol.java b/src/com/android/phone/vvm/omtp/protocol/OmtpProtocol.java
index d002652..7ec3dba 100644
--- a/src/com/android/phone/vvm/omtp/protocol/OmtpProtocol.java
+++ b/src/com/android/phone/vvm/omtp/protocol/OmtpProtocol.java
@@ -28,6 +28,7 @@
     public OmtpMessageSender createMessageSender(SmsManager smsManager, short applicationPort,
             String destinationNumber) {
         return new OmtpStandardMessageSender(smsManager, applicationPort, destinationNumber,
-                null, OmtpConstants.PROTOCOL_VERSION1_1, null);
+                OmtpConstants.CLIENT_TYPE_GOOGLE_10, OmtpConstants.PROTOCOL_VERSION1_1,
+                null /*clientPrefix*/);
     }
 }
diff --git a/src/com/android/phone/vvm/omtp/protocol/Vvm3EventHandler.java b/src/com/android/phone/vvm/omtp/protocol/Vvm3EventHandler.java
index d95879f..524c96d 100644
--- a/src/com/android/phone/vvm/omtp/protocol/Vvm3EventHandler.java
+++ b/src/com/android/phone/vvm/omtp/protocol/Vvm3EventHandler.java
@@ -18,13 +18,17 @@
 
 import android.annotation.IntDef;
 import android.content.Context;
+import android.provider.VoicemailContract.Status;
+import android.telecom.PhoneAccountHandle;
 import android.util.Log;
+
 import com.android.phone.VoicemailStatus;
 import com.android.phone.settings.VoicemailChangePinActivity;
 import com.android.phone.vvm.omtp.DefaultOmtpEventHandler;
 import com.android.phone.vvm.omtp.OmtpEvents;
 import com.android.phone.vvm.omtp.OmtpEvents.Type;
 import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
@@ -113,19 +117,22 @@
         OmtpEvents event) {
         switch (event) {
             case CONFIG_REQUEST_STATUS_SUCCESS:
-                if (status.getPhoneAccountHandle() == null) {
-                    // This should never happen.
-                    Log.e(TAG, "status editor has null phone account handle");
-                    return true;
-                }
-
-                if (!VoicemailChangePinActivity
-                    .isDefaultOldPinSet(context, status.getPhoneAccountHandle())) {
+                if (!isPinRandomized(context, status.getPhoneAccountHandle())) {
                     return false;
                 } else {
                     postError(status, PIN_NOT_SET);
                 }
                 break;
+            case CONFIG_ACTIVATING_SUBSEQUENT:
+                if (isPinRandomized(context, status.getPhoneAccountHandle())) {
+                    status.setConfigurationState(PIN_NOT_SET);
+                } else {
+                    status.setConfigurationState(Status.CONFIGURATION_STATE_OK);
+                }
+                status
+                        .setNotificationChannelState(Status.NOTIFICATION_CHANNEL_STATE_OK)
+                        .setDataChannelState(Status.DATA_CHANNEL_STATE_OK).apply();
+                break;
             case CONFIG_DEFAULT_PIN_REPLACED:
                 postError(status, PIN_NOT_SET);
                 break;
@@ -269,4 +276,13 @@
         }
         editor.apply();
     }
+
+    private static boolean isPinRandomized(Context context, PhoneAccountHandle phoneAccountHandle) {
+        if (phoneAccountHandle == null) {
+            // This should never happen.
+            Log.e(TAG, "status editor has null phone account handle");
+            return false;
+        }
+        return VoicemailChangePinActivity.isDefaultOldPinSet(context, phoneAccountHandle);
+    }
 }
diff --git a/src/com/android/phone/vvm/omtp/sms/OmtpCvvmMessageSender.java b/src/com/android/phone/vvm/omtp/sms/OmtpCvvmMessageSender.java
index 7f45254..98d8594 100644
--- a/src/com/android/phone/vvm/omtp/sms/OmtpCvvmMessageSender.java
+++ b/src/com/android/phone/vvm/omtp/sms/OmtpCvvmMessageSender.java
@@ -48,7 +48,7 @@
     private void sendCvvmMessage(String request, PendingIntent sentIntent) {
         StringBuilder sb = new StringBuilder().append(request);
         sb.append(OmtpConstants.SMS_PREFIX_SEPARATOR);
-        appendField(sb, "dt", "15");
+        appendField(sb, "dt" /* device type */, "6" /* no VTT (transcription) support*/);
         sendSms(sb.toString(), sentIntent);
     }
 }
diff --git a/src/com/android/services/telephony/CdmaConferenceController.java b/src/com/android/services/telephony/CdmaConferenceController.java
index 0a7c18b..846df61 100644
--- a/src/com/android/services/telephony/CdmaConferenceController.java
+++ b/src/com/android/services/telephony/CdmaConferenceController.java
@@ -122,8 +122,18 @@
                 }
             }, ADD_OUTGOING_CONNECTION_DELAY_MILLIS);
         } else {
-            // This is the first connection, or it is incoming, so let it flow through.
-            addInternal(connection);
+            // Post the call to addInternal to the handler with no delay.
+            // Why you ask?  In TelephonyConnectionService#
+            // onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest) or
+            // TelephonyConnectionService#onCreateOutgoingConnection(PhoneAccountHandle,
+            // ConnectionRequest) we can create a new connection it will trigger a call to
+            // TelephonyConnectionService#addConnectionToConferenceController, which will cause us
+            // to get here.  HOWEVER, at this point ConnectionService#addConnection has not yet run,
+            // so if we end up calling ConnectionService#addConference, the connection service will
+            // not yet know about the new connection, so it won't get added to the conference.
+            // Posting to the handler ensures addConnection has a chance to happen before we add the
+            // conference.
+            mHandler.post(() -> addInternal(connection));
         }
     }
 
diff --git a/src/com/android/services/telephony/DisconnectCauseUtil.java b/src/com/android/services/telephony/DisconnectCauseUtil.java
index 6eb4a4e..92f202a 100644
--- a/src/com/android/services/telephony/DisconnectCauseUtil.java
+++ b/src/com/android/services/telephony/DisconnectCauseUtil.java
@@ -27,11 +27,10 @@
 public class DisconnectCauseUtil {
 
    /**
-    * Converts from a disconnect code in {@link android.telephony.DisconnectCause} into a more generic
-    * {@link android.telecom.DisconnectCause}.object, possibly populated with a localized message
-    * and tone.
+    * Converts from a disconnect code in {@link android.telephony.DisconnectCause} into a more
+    * generic {@link android.telecom.DisconnectCause} object, possibly populated with a localized
+    * message and tone.
     *
-    * @param context The context.
     * @param telephonyDisconnectCause The code for the reason for the disconnect.
     */
     public static DisconnectCause toTelecomDisconnectCause(int telephonyDisconnectCause) {
@@ -39,11 +38,10 @@
     }
 
    /**
-    * Converts from a disconnect code in {@link android.telephony.DisconnectCause} into a more generic
-    * {@link android.telecom.DisconnectCause}.object, possibly populated with a localized message
-    * and tone.
+    * Converts from a disconnect code in {@link android.telephony.DisconnectCause} into a more
+    * generic {@link android.telecom.DisconnectCause}.object, possibly populated with a localized
+    * message and tone.
     *
-    * @param context The context.
     * @param telephonyDisconnectCause The code for the reason for the disconnect.
     * @param reason Description of the reason for the disconnect, not intended for the user to see..
     */
@@ -54,7 +52,7 @@
                 toTelecomDisconnectCauseCode(telephonyDisconnectCause),
                 toTelecomDisconnectCauseLabel(context, telephonyDisconnectCause),
                 toTelecomDisconnectCauseDescription(context, telephonyDisconnectCause),
-                toTelecomDisconnectReason(telephonyDisconnectCause, reason),
+                toTelecomDisconnectReason(context,telephonyDisconnectCause, reason),
                 toTelecomDisconnectCauseTone(telephonyDisconnectCause));
     }
 
@@ -129,6 +127,7 @@
             case android.telephony.DisconnectCause.DATA_DISABLED:
             case android.telephony.DisconnectCause.DATA_LIMIT_REACHED:
             case android.telephony.DisconnectCause.DIALED_ON_WRONG_SLOT:
+            case android.telephony.DisconnectCause.DIALED_CALL_FORWARDING_WHILE_ROAMING:
                 return DisconnectCause.ERROR;
 
             case android.telephony.DisconnectCause.DIALED_MMI:
@@ -380,6 +379,9 @@
             case android.telephony.DisconnectCause.DATA_LIMIT_REACHED:
                 resourceId = R.string.callFailed_data_limit_reached_description;
                 break;
+            case android.telephony.DisconnectCause.DIALED_CALL_FORWARDING_WHILE_ROAMING:
+                resourceId = com.android.internal.R.string.mmiErrorWhileRoaming;
+                break;
 
             default:
                 break;
@@ -387,7 +389,36 @@
         return resourceId == null ? "" : context.getResources().getString(resourceId);
     }
 
-    private static String toTelecomDisconnectReason(int telephonyDisconnectCause, String reason) {
+    /**
+     * Maps the telephony {@link android.telephony.DisconnectCause} into a reason string which is
+     * returned in the Telecom {@link DisconnectCause#getReason()}.
+     *
+     * @param context The current context.
+     * @param telephonyDisconnectCause The {@link android.telephony.DisconnectCause} code.
+     * @param reason A reason provided by the caller; only used if a more specific reason cannot
+     *               be determined here.
+     * @return The disconnect reason.
+     */
+    private static String toTelecomDisconnectReason(Context context, int telephonyDisconnectCause,
+            String reason) {
+
+        if (context == null) {
+            return "";
+        }
+
+        switch (telephonyDisconnectCause) {
+            case android.telephony.DisconnectCause.POWER_OFF:
+                // Airplane mode (radio off)
+                // intentional fall-through
+            case android.telephony.DisconnectCause.OUT_OF_SERVICE:
+                // No network connection.
+                if (ImsUtil.shouldPromoteWfc(context)) {
+                    return android.telecom.DisconnectCause.REASON_WIFI_ON_BUT_WFC_OFF;
+                }
+                break;
+        }
+
+        // If no specific code-mapping found, then fall back to using the reason.
         String causeAsString = android.telephony.DisconnectCause.toString(telephonyDisconnectCause);
         if (reason == null) {
             return causeAsString;
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index c4f9c9a..4199d5d 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -960,6 +960,12 @@
                 b != null && b.getBoolean(CarrierConfigManager.KEY_WIFI_CALLS_CAN_BE_HD_AUDIO);
         boolean canVideoCallsBeHdAudio =
                 b != null && b.getBoolean(CarrierConfigManager.KEY_VIDEO_CALLS_CAN_BE_HD_AUDIO);
+        boolean shouldDisplayHdAudio =
+                b != null && b.getBoolean(CarrierConfigManager.KEY_DISPLAY_HD_AUDIO_PROPERTY_BOOL);
+
+        if (!shouldDisplayHdAudio) {
+            return false;
+        }
 
         if (isVideoCall && !canVideoCallsBeHdAudio) {
             return false;
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 612600e..b33769a 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -479,6 +479,15 @@
             return failedConnection;
         }
 
+        // Check roaming status to see if we should block custom call forwarding codes
+        if (blockCallForwardingNumberWhileRoaming(phone, number)) {
+            return Connection.createFailedConnection(
+                    DisconnectCauseUtil.toTelecomDisconnectCause(
+                            android.telephony.DisconnectCause.DIALED_CALL_FORWARDING_WHILE_ROAMING,
+                            "Call forwarding while roaming"));
+        }
+
+
         final TelephonyConnection connection =
                 createConnectionFor(phone, null, true /* isOutgoing */, request.getAccountHandle(),
                         request.getTelecomCallId(), request.getAddress(), request.getVideoState());
@@ -690,6 +699,28 @@
         }
     }
 
+    private boolean blockCallForwardingNumberWhileRoaming(Phone phone, String number) {
+        if (phone == null || TextUtils.isEmpty(number) || !phone.getServiceState().getRoaming()) {
+            return false;
+        }
+        String[] blockPrefixes = null;
+        CarrierConfigManager cfgManager = (CarrierConfigManager)
+                phone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        if (cfgManager != null) {
+            blockPrefixes = cfgManager.getConfigForSubId(phone.getSubId()).getStringArray(
+                    CarrierConfigManager.KEY_CALL_FORWARDING_BLOCKS_WHILE_ROAMING_STRING_ARRAY);
+        }
+
+        if (blockPrefixes != null) {
+            for (String prefix : blockPrefixes) {
+                if (number.startsWith(prefix)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     private boolean isRadioOn() {
         boolean result = false;
         for (Phone phone : PhoneFactory.getPhones()) {