Merge "Rename key usage to start with "KEY""
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index fb7408e..51bf40e 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -506,7 +506,7 @@
     <string name="ota_skip_activation_dialog_title" msgid="2943366608272261306">"Praleisti aktyvinimą?"</string>
     <string name="ota_skip_activation_dialog_message" msgid="2440770373498870550">"Jei praleisite aktyvinimą, negalėsite skambinti ar prisijungti prie mobilių duomenų tinklų (nors ir galite prisijungti prie „Wi-Fi“ tinklų). Iki tol, kol suaktyvinsite telefoną, aktyvinkite jį kaskart jį įjungdami."</string>
     <string name="ota_skip_activation_dialog_skip_label" msgid="3458532775091563208">"Praleisti"</string>
-    <string name="ota_activate" msgid="1368528132525626264">"Aktyvinti"</string>
+    <string name="ota_activate" msgid="1368528132525626264">"Suaktyvinti"</string>
     <string name="ota_title_activate_success" msgid="6570240212263372046">"Telefonas suaktyvintas."</string>
     <string name="ota_title_problem_with_activation" msgid="7095824491970084367">"Aktyvinimo problema"</string>
     <string name="ota_listen" msgid="162923839877584937">"Vadovaukitės girdimomis instrukcijomis, kol išgirsite, kad aktyvinimas baigtas."</string>
diff --git a/res/values-si-rLK/strings.xml b/res/values-si-rLK/strings.xml
index 106a817..a881412 100644
--- a/res/values-si-rLK/strings.xml
+++ b/res/values-si-rLK/strings.xml
@@ -79,8 +79,8 @@
     <string name="networks" msgid="8873030692174541976">"ජාල ක්‍රියාකරුවන්"</string>
     <string name="cell_broadcast_settings" msgid="8740238216690502563">"හදිසි විකාශන"</string>
     <string name="call_settings" msgid="6112441768261754562">"ඇමතුම් සැකසුම්"</string>
-    <string name="additional_gsm_call_settings" msgid="1391795981938800617">"අමතර සැකසීම්"</string>
-    <string name="additional_gsm_call_settings_with_label" msgid="1385241520708457376">"අමතර සැකසීම් (<xliff:g id="SUBSCRIPTIONLABEL">%s</xliff:g>)"</string>
+    <string name="additional_gsm_call_settings" msgid="1391795981938800617">"අතිරේක සැකසීම්"</string>
+    <string name="additional_gsm_call_settings_with_label" msgid="1385241520708457376">"අතිරේක සැකසීම් (<xliff:g id="SUBSCRIPTIONLABEL">%s</xliff:g>)"</string>
     <string name="sum_gsm_call_settings" msgid="4076647190996778012">"අමතර GSM පමණක් ඇමතුම් සැකසුම්"</string>
     <string name="additional_cdma_call_settings" msgid="8628958775721886909">"අමතර CDMA ඇමතුම් සැකසුම්"</string>
     <string name="sum_cdma_call_settings" msgid="284753265979035549">"අමතර CDMA පමණක් ඇමතුම් සැකසුම්"</string>
diff --git a/res/values/config.xml b/res/values/config.xml
index 12b35c4..1f23c6b 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -210,9 +210,6 @@
     <!-- 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..b5e8026 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(
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index 159d8bc..d1192e9 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -20,7 +20,7 @@
 import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
 
 import android.annotation.NonNull;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -390,8 +390,7 @@
         Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
         SubscriptionManager.putPhoneIdAndSubIdExtra(intent, phoneId);
-        ActivityManagerNative.broadcastStickyIntent(intent, READ_PHONE_STATE,
-                UserHandle.USER_ALL);
+        ActivityManager.broadcastStickyIntent(intent, UserHandle.USER_ALL);
     }
 
     /** Binds to the default or carrier config app. */
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index d40b08e..abe5397 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -16,6 +16,8 @@
 
 package com.android.phone;
 
+import static android.Manifest.permission.READ_PHONE_STATE;
+
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -24,6 +26,7 @@
 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;
@@ -33,6 +36,7 @@
 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;
@@ -93,7 +97,6 @@
 
     private Context mContext;
     private NotificationManager mNotificationManager;
-    private final ComponentName mNotificationComponent;
     private StatusBarManager mStatusBarManager;
     private UserManager mUserManager;
     private Toast mToast;
@@ -124,12 +127,6 @@
         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
@@ -383,8 +380,8 @@
                 if (!mUserManager.hasUserRestriction(
                         UserManager.DISALLOW_OUTGOING_CALLS, userHandle)
                         && !user.isManagedProfile()) {
-                    if (!sendNotificationCustomComponent(vmCount, vmNumber, pendingIntent,
-                            isSettingsIntent)) {
+                    if (!maybeSendVoicemailNotificationUsingDefaultDialer(vmCount, vmNumber,
+                            pendingIntent, isSettingsIntent, userHandle)) {
                         mNotificationManager.notifyAsUser(
                                 Integer.toString(subId) /* tag */,
                                 VOICEMAIL_NOTIFICATION,
@@ -394,19 +391,29 @@
                 }
             }
         } else {
-            if (!sendNotificationCustomComponent(0, null, null, false)) {
-                mNotificationManager.cancelAsUser(
-                        Integer.toString(subId) /* tag */,
-                        VOICEMAIL_NOTIFICATION,
-                        UserHandle.ALL);
+            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);
+                    }
+                }
             }
         }
     }
 
     /**
-     * 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
+     * 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
      * 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.
@@ -414,14 +421,16 @@
      * @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.
-     * @return {@code true} if a custom component was notified of the notification.
+     * @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.
      */
-    private boolean sendNotificationCustomComponent(Integer count, String number,
-            PendingIntent pendingIntent, boolean isSettingsIntent) {
-        if (mNotificationComponent != null) {
-            Intent intent = new Intent();
+    private boolean maybeSendVoicemailNotificationUsingDefaultDialer(Integer count, String number,
+            PendingIntent pendingIntent, boolean isSettingsIntent, UserHandle userHandle) {
+
+        if (shouldManageNotificationThroughDefaultDialer(userHandle)) {
+            Intent intent = getShowVoicemailIntentForDefaultDialer(userHandle);
             intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
-            intent.setComponent(mNotificationComponent);
             intent.setAction(TelephonyManager.ACTION_SHOW_VOICEMAIL_NOTIFICATION);
 
             if (count != null) {
@@ -443,14 +452,31 @@
                             pendingIntent);
                 }
             }
-
-            mContext.sendBroadcast(intent);
+            mContext.sendBroadcastAsUser(intent, userHandle, READ_PHONE_STATE);
             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/OutgoingCallBroadcaster.java b/src/com/android/phone/OutgoingCallBroadcaster.java
index cfe6f32..9a10a1b 100644
--- a/src/com/android/phone/OutgoingCallBroadcaster.java
+++ b/src/com/android/phone/OutgoingCallBroadcaster.java
@@ -18,7 +18,7 @@
 
 import android.Manifest;
 import android.app.Activity;
-import android.app.ActivityManagerNative;
+import android.app.ActivityManager;
 import android.app.AlertDialog;
 import android.app.AppOpsManager;
 import android.app.Dialog;
@@ -429,9 +429,9 @@
         int launchedFromUid;
         String launchedFromPackage;
         try {
-            launchedFromUid = ActivityManagerNative.getDefault().getLaunchedFromUid(
+            launchedFromUid = ActivityManager.getService().getLaunchedFromUid(
                     getActivityToken());
-            launchedFromPackage = ActivityManagerNative.getDefault().getLaunchedFromPackage(
+            launchedFromPackage = ActivityManager.getService().getLaunchedFromPackage(
                     getActivityToken());
         } catch (RemoteException e) {
             launchedFromUid = -1;
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index ac4510a..3e5438f 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -2507,7 +2507,7 @@
      */
     @Override
     public void setDataEnabled(int subId, boolean enable) {
-        enforceModifyPermission();
+        enforceModifyPermissionOrCarrierPrivilege(subId);
         int phoneId = mSubscriptionController.getPhoneId(subId);
         if (DBG) log("getDataEnabled: subId=" + subId + " phoneId=" + phoneId);
         Phone phone = PhoneFactory.getPhone(phoneId);
@@ -2522,9 +2522,7 @@
     /**
      * Get whether mobile data is enabled.
      *
-     * Note that this used to be available from ConnectivityService, gated by
-     * ACCESS_NETWORK_STATE permission, so this will accept either that or
-     * our MODIFY_PHONE_STATE.
+     * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
      *
      * @return {@code true} if data is enabled else {@code false}
      */
@@ -2534,8 +2532,7 @@
             mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
                     null);
         } catch (Exception e) {
-            mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE,
-                    null);
+            enforceModifyPermissionOrCarrierPrivilege(subId);
         }
         int phoneId = mSubscriptionController.getPhoneId(subId);
         if (DBG) log("getDataEnabled: subId=" + subId + " phoneId=" + phoneId);
@@ -3017,22 +3014,41 @@
                 Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED) {
             return true;
         }
+
         try {
             return canReadPhoneState(callingPackage, message);
         } catch (SecurityException readPhoneStateSecurityException) {
-            try {
-                // Can be read with READ_SMS too.
-                mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_SMS, message);
-                return mAppOps.noteOp(AppOpsManager.OP_READ_SMS,
-                        Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED;
-            } catch (SecurityException readSmsSecurityException) {
-                // Throw exception with message including both READ_PHONE_STATE and READ_SMS
-                // permissions
-                throw new SecurityException(message + ": Neither user " + Binder.getCallingUid() +
-                        " nor current process has " + android.Manifest.permission.READ_PHONE_STATE +
-                        " or " + android.Manifest.permission.READ_SMS + ".");
-            }
         }
+        // Can be read with READ_SMS too.
+        try {
+            mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_SMS, message);
+            int opCode = mAppOps.permissionToOpCode(android.Manifest.permission.READ_SMS);
+            if (opCode != AppOpsManager.OP_NONE) {
+                return mAppOps.noteOp(opCode, Binder.getCallingUid(), callingPackage)
+                        == AppOpsManager.MODE_ALLOWED;
+            } else {
+                return true;
+            }
+        } catch (SecurityException readSmsSecurityException) {
+        }
+        // Can be read with READ_PHONE_NUMBER too.
+        try {
+            mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_NUMBER,
+                    message);
+            int opCode = mAppOps.permissionToOpCode(android.Manifest.permission.READ_PHONE_NUMBER);
+            if (opCode != AppOpsManager.OP_NONE) {
+                return mAppOps.noteOp(opCode, Binder.getCallingUid(), callingPackage)
+                        == AppOpsManager.MODE_ALLOWED;
+            } else {
+                return true;
+            }
+        } catch (SecurityException readPhoneNumberSecurityException) {
+        }
+
+        throw new SecurityException(message + ": Neither user " + Binder.getCallingUid() +
+                " nor current process has" + android.Manifest.permission.READ_PHONE_STATE +
+                ", " + android.Manifest.permission.READ_SMS + ", or " +
+                android.Manifest.permission.READ_PHONE_NUMBER);
     }
 
     @Override
diff --git a/src/com/android/phone/vvm/omtp/SimChangeReceiver.java b/src/com/android/phone/vvm/omtp/SimChangeReceiver.java
index c5d0c3c..5b201aa 100644
--- a/src/com/android/phone/vvm/omtp/SimChangeReceiver.java
+++ b/src/com/android/phone/vvm/omtp/SimChangeReceiver.java
@@ -26,6 +26,7 @@
 import android.telephony.CarrierConfigManager;
 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;
@@ -69,6 +70,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);