Merge "Return shared Emergency Country Iso for Multi-sim country iso" into qt-r1-dev
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 9d21933..f365139 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -564,8 +564,13 @@
          lose data connectivity because you're roaming and you have the
          "data roaming" feature turned off. -->
     <string name="roaming_reenable_message">Data roaming is turned off. Tap to turn on.</string>
+    <!-- Mobile network settings UI: notification message shown when you
+         are roaming and you have the "data roaming" feature turned on. -->
+    <string name="roaming_enabled_message">Roaming charges may apply. Tap to modify.</string>
     <!-- Roaming notification tile, notifying lost of roaming data connection -->
     <string name="roaming_notification_title">Lost mobile data connection</string>
+    <!-- Roaming notification tile, notifying continued roaming data connection -->
+    <string name="roaming_on_notification_title">Data roaming is on</string>
     <!-- Mobile network settings screen, dialog message when user selects the Data roaming check box -->
     <string name="roaming_warning">You may incur significant charges.</string>
     <!-- Mobile network settings screen, message asking the user to check their pricing with their Carrier, when enabling Data roaming. -->
@@ -574,10 +579,10 @@
     <string name="roaming_alert_title">Allow data roaming?</string>
     <!-- Notification title for limited sim function during dual sim -->
     <string name="limited_sim_function_notification_title">Limited SIM functionality</string>
-    <!-- Notification message for limited sim function during dual sim -->
+    <!-- Notification message for limited sim function during dual sim [CHAR LIMIT=80]-->
     <string name="limited_sim_function_with_phone_num_notification_message"><xliff:g id="carrier_name">%1$s</xliff:g> calls and data services may be blocked while using <xliff:g id="phone_number">%2$s</xliff:g>.</string>
-    <!-- Notification message for limited sim function during dual sim -->
-    <string name="limited_sim_function_notification_message"><xliff:g id="carrier_name">%1$s</xliff:g> calls and data services may be blocked while using another SIM. Tap to make changes.</string>
+    <!-- Notification message for limited sim function during dual sim [CHAR LIMIT=80]-->
+    <string name="limited_sim_function_notification_message"><xliff:g id="carrier_name">%1$s</xliff:g> calls and data services may be blocked while using another SIM.</string>
     <!-- Mobile network settings screen, data usage setting check box name -->
     <string name="data_usage_title">App data usage</string>
     <!-- Summary about how much data has been used in a date range [CHAR LIMIT=100] -->
@@ -1542,6 +1547,15 @@
          message is shown when an in-progress call is ended due to the battery being low. -->
     <string name="callFailed_low_battery">Video call ended due to low battery.</string>
 
+    <!-- In-call screen: error message shown when the user attempts to place an emergency call
+         over wifi calling (WFC), but emergency services are not available in the current
+         location. -->
+    <string name="callFailed_emergency_call_over_wfc_not_available">Emergency calls over Wi-Fi calling not available in this location.</string>
+
+    <!-- In-call screen: error message shown when the user attempts to place a call over wifi
+         calling (WFC), but wifi calling is not available in the current location. -->
+    <string name="callFailed_wfc_service_not_available_in_this_location">Wi-Fi calling is not available in this location.</string>
+
     <!-- The title for the change voicemail PIN activity -->
     <string name="change_pin_title">Change Voicemail PIN</string>
     <!-- The label for the continue button in change voicemail PIN activity -->
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index 26ae699..320fc24 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -387,15 +387,9 @@
                 .createForSubscriptionId(mPhone.getSubId());
         PersistableBundle carrierConfig =
                 PhoneGlobals.getInstance().getCarrierConfigForSubId(mPhone.getSubId());
-        boolean editableWfcRoamingMode = true;
-        boolean useWfcHomeModeForRoaming = false;
-        if (carrierConfig != null) {
-            editableWfcRoamingMode = carrierConfig.getBoolean(
-                    CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL);
-            useWfcHomeModeForRoaming = carrierConfig.getBoolean(
+        boolean useWfcHomeModeForRoaming = carrierConfig.getBoolean(
                     CarrierConfigManager.KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL,
                     false);
-        }
         if (mImsMgr.isVtEnabledByPlatform() && mImsMgr.isVtProvisionedOnDevice()
                 && (carrierConfig.getBoolean(
                         CarrierConfigManager.KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS)
@@ -439,8 +433,8 @@
             int resId = com.android.internal.R.string.wifi_calling_off_summary;
             if (mImsMgr.isWfcEnabledByUser()) {
                 boolean isRoaming = telephonyManager.isNetworkRoaming();
-                boolean wfcRoamingEnabled = editableWfcRoamingMode && !useWfcHomeModeForRoaming;
-                int wfcMode = mImsMgr.getWfcMode(isRoaming && wfcRoamingEnabled);
+                // Also check carrier config for roaming mode
+                int wfcMode = mImsMgr.getWfcMode(isRoaming && !useWfcHomeModeForRoaming);
                 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/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index 3b9f996..1012a9e 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -92,7 +92,7 @@
     static final int NETWORK_SELECTION_NOTIFICATION = 2;
     static final int VOICEMAIL_NOTIFICATION = 3;
     static final int CALL_FORWARD_NOTIFICATION = 4;
-    static final int DATA_DISCONNECTED_ROAMING_NOTIFICATION = 5;
+    static final int DATA_ROAMING_NOTIFICATION = 5;
     static final int SELECTED_OPERATOR_FAIL_NOTIFICATION = 6;
     static final int LIMITED_SIM_FUNCTION_NOTIFICATION = 7;
 
@@ -569,23 +569,39 @@
     }
 
     /**
-     * Shows the "data disconnected due to roaming" notification, which
+     * Shows either:
+     * 1) the "Data roaming is on" notification, which
+     * appears when you're roaming and you have the "data roaming" feature turned on for the
+     * given {@code subId}.
+     * or
+     * 2) the "data disconnected due to roaming" notification, which
      * appears when you lose data connectivity because you're roaming and
      * you have the "data roaming" feature turned off for the given {@code subId}.
+     * @param subId which subscription it's notifying about.
+     * @param roamingOn whether currently roaming is on or off. If true, we show notification
+     *                  1) above; else we show notification 2).
      */
-    /* package */ void showDataDisconnectedRoaming(int subId) {
-        if (DBG) log("showDataDisconnectedRoaming()...");
+    /* package */ void showDataRoamingNotification(int subId, boolean roamingOn) {
+        if (DBG) {
+            log("showDataRoamingNotification() roaming " + (roamingOn ? "on" : "off")
+                    + " on subId " + subId);
+        }
 
         // "Mobile network settings" screen / dialog
         Intent intent = new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS);
         intent.putExtra(Settings.EXTRA_SUB_ID, subId);
         PendingIntent contentIntent = PendingIntent.getActivity(mContext, subId, intent, 0);
 
-        final CharSequence contentText = mContext.getText(R.string.roaming_reenable_message);
+        CharSequence contentTitle = mContext.getText(roamingOn
+                ? R.string.roaming_on_notification_title
+                : R.string.roaming_notification_title);
+        CharSequence contentText = mContext.getText(roamingOn
+                ? R.string.roaming_enabled_message
+                : R.string.roaming_reenable_message);
 
         final Notification.Builder builder = new Notification.Builder(mContext)
                 .setSmallIcon(android.R.drawable.stat_sys_warning)
-                .setContentTitle(mContext.getText(R.string.roaming_notification_title))
+                .setContentTitle(contentTitle)
                 .setColor(mContext.getResources().getColor(R.color.dialer_theme_color))
                 .setContentText(contentText)
                 .setChannel(NotificationChannelController.CHANNEL_ID_MOBILE_DATA_STATUS)
@@ -593,15 +609,15 @@
         final Notification notif =
                 new Notification.BigTextStyle(builder).bigText(contentText).build();
         mNotificationManager.notifyAsUser(
-                null /* tag */, DATA_DISCONNECTED_ROAMING_NOTIFICATION, notif, UserHandle.ALL);
+                null /* tag */, DATA_ROAMING_NOTIFICATION, notif, UserHandle.ALL);
     }
 
     /**
-     * Turns off the "data disconnected due to roaming" notification.
+     * Turns off the "data disconnected due to roaming" or "Data roaming is on" notification.
      */
-    /* package */ void hideDataDisconnectedRoaming() {
-        if (DBG) log("hideDataDisconnectedRoaming()...");
-        mNotificationManager.cancel(DATA_DISCONNECTED_ROAMING_NOTIFICATION);
+    /* package */ void hideDataRoamingNotification() {
+        if (DBG) log("hideDataRoamingNotification()...");
+        mNotificationManager.cancel(DATA_ROAMING_NOTIFICATION);
     }
 
     /**
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 8d3027a..9953a43 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -16,6 +16,7 @@
 
 package com.android.phone;
 
+import android.annotation.IntDef;
 import android.app.Activity;
 import android.app.KeyguardManager;
 import android.app.ProgressDialog;
@@ -74,6 +75,8 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.List;
 
 /**
@@ -109,11 +112,12 @@
     private static final int EVENT_SIM_NETWORK_LOCKED = 3;
     private static final int EVENT_SIM_STATE_CHANGED = 8;
     private static final int EVENT_DATA_ROAMING_DISCONNECTED = 10;
-    private static final int EVENT_DATA_ROAMING_OK = 11;
-    private static final int EVENT_UNSOL_CDMA_INFO_RECORD = 12;
-    private static final int EVENT_RESTART_SIP = 13;
-    private static final int EVENT_DATA_ROAMING_SETTINGS_CHANGED = 14;
-    private static final int EVENT_MOBILE_DATA_SETTINGS_CHANGED = 15;
+    private static final int EVENT_DATA_ROAMING_CONNECTED = 11;
+    private static final int EVENT_DATA_ROAMING_OK = 12;
+    private static final int EVENT_UNSOL_CDMA_INFO_RECORD = 13;
+    private static final int EVENT_RESTART_SIP = 14;
+    private static final int EVENT_DATA_ROAMING_SETTINGS_CHANGED = 15;
+    private static final int EVENT_MOBILE_DATA_SETTINGS_CHANGED = 16;
 
     // The MMI codes are also used by the InCallScreen.
     public static final int MMI_INITIATE = 51;
@@ -160,7 +164,21 @@
     private Activity mPUKEntryActivity;
     private ProgressDialog mPUKEntryProgressDialog;
 
-    private boolean mNoDataDueToRoaming = false;
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"ROAMING_NOTIFICATION_"},
+            value = {
+                    ROAMING_NOTIFICATION_NO_NOTIFICATION,
+                    ROAMING_NOTIFICATION_CONNECTED,
+                    ROAMING_NOTIFICATION_DISCONNECTED})
+    public @interface RoamingNotification {}
+
+    private static final int ROAMING_NOTIFICATION_NO_NOTIFICATION = 0;
+    private static final int ROAMING_NOTIFICATION_CONNECTED       = 1;
+    private static final int ROAMING_NOTIFICATION_DISCONNECTED    = 2;
+
+    @RoamingNotification
+    private int mPrevRoamingNotification = ROAMING_NOTIFICATION_NO_NOTIFICATION;
 
     private WakeState mWakeState = WakeState.SLEEP;
 
@@ -209,11 +227,15 @@
                     break;
 
                 case EVENT_DATA_ROAMING_DISCONNECTED:
-                    notificationMgr.showDataDisconnectedRoaming(msg.arg1);
+                    notificationMgr.showDataRoamingNotification(msg.arg1, false);
+                    break;
+
+                case EVENT_DATA_ROAMING_CONNECTED:
+                    notificationMgr.showDataRoamingNotification(msg.arg1, true);
                     break;
 
                 case EVENT_DATA_ROAMING_OK:
-                    notificationMgr.hideDataDisconnectedRoaming();
+                    notificationMgr.hideDataRoamingNotification();
                     break;
 
                 case MMI_COMPLETE:
@@ -721,6 +743,16 @@
     }
 
     /**
+     * @return whether or not we should show a notification when connecting to data roaming if the
+     * user has data roaming enabled
+     */
+    private boolean shouldShowDataConnectedRoaming(int subId) {
+        PersistableBundle config = getCarrierConfigForSubId(subId);
+        return config.getBoolean(CarrierConfigManager
+                .KEY_SHOW_DATA_CONNECTED_ROAMING_NOTIFICATION_BOOL);
+    }
+
+    /**
      * When roaming, if mobile data cannot be established due to data roaming not enabled, we need
      * to notify the user so they can enable it through settings. Vise versa if the condition
      * changes, we need to dismiss the notification.
@@ -737,27 +769,48 @@
         boolean dataAllowed = phone.isDataAllowed(ApnSetting.TYPE_DEFAULT, reasons);
         mDataRoamingNotifLog.log("dataAllowed=" + dataAllowed + ", reasons=" + reasons);
         if (VDBG) Log.v(LOG_TAG, "dataAllowed=" + dataAllowed + ", reasons=" + reasons);
-        if (!mNoDataDueToRoaming
-                && !dataAllowed
-                && reasons.containsOnly(DataDisallowedReasonType.ROAMING_DISABLED)) {
+        if (!dataAllowed && reasons.containsOnly(DataDisallowedReasonType.ROAMING_DISABLED)) {
+            // No need to show it again if we never cancelled it explicitly.
+            if (mPrevRoamingNotification == ROAMING_NOTIFICATION_DISCONNECTED) return;
             // If the only reason of no data is data roaming disabled, then we notify the user
             // so the user can turn on data roaming.
-            mNoDataDueToRoaming = true;
+            mPrevRoamingNotification = ROAMING_NOTIFICATION_DISCONNECTED;
             Log.d(LOG_TAG, "Show roaming disconnected notification");
-            mDataRoamingNotifLog.log("Show");
+            mDataRoamingNotifLog.log("Show roaming off.");
             Message msg = mHandler.obtainMessage(EVENT_DATA_ROAMING_DISCONNECTED);
             msg.arg1 = mDefaultDataSubId;
             msg.sendToTarget();
-        } else if (mNoDataDueToRoaming && (dataAllowed
-                || !reasons.containsOnly(DataDisallowedReasonType.ROAMING_DISABLED))) {
-            // Otherwise dismiss the notification we showed earlier.
-            mNoDataDueToRoaming = false;
-            Log.d(LOG_TAG, "Dismiss roaming disconnected notification");
+        } else if (dataAllowed && dataIsNowRoaming(mDefaultDataSubId)
+                && shouldShowDataConnectedRoaming(mDefaultDataSubId)) {
+            // No need to show it again if we never cancelled it explicitly, or carrier config
+            // indicates this is not needed.
+            if (mPrevRoamingNotification == ROAMING_NOTIFICATION_CONNECTED) return;
+            mPrevRoamingNotification = ROAMING_NOTIFICATION_CONNECTED;
+            Log.d(LOG_TAG, "Show roaming connected notification");
+            mDataRoamingNotifLog.log("Show roaming on.");
+            Message msg = mHandler.obtainMessage(EVENT_DATA_ROAMING_CONNECTED);
+            msg.arg1 = mDefaultDataSubId;
+            msg.sendToTarget();
+        } else if (mPrevRoamingNotification != ROAMING_NOTIFICATION_NO_NOTIFICATION) {
+            // Otherwise we either 1) we are not roaming or 2) roaming is off but ROAMING_DISABLED
+            // is not the only data disable reason. In this case we dismiss the notification we
+            // showed earlier.
+            mPrevRoamingNotification = ROAMING_NOTIFICATION_NO_NOTIFICATION;
+            Log.d(LOG_TAG, "Dismiss roaming notification");
             mDataRoamingNotifLog.log("Hide. data allowed=" + dataAllowed + ", reasons=" + reasons);
             mHandler.sendEmptyMessage(EVENT_DATA_ROAMING_OK);
         }
     }
 
+    /**
+     *
+     * @param subId to check roaming on
+     * @return whether we have transitioned to dataRoaming
+     */
+    private boolean dataIsNowRoaming(int subId) {
+        return getPhone(subId).getServiceState().getDataRoaming();
+    }
+
     private void updateLimitedSimFunctionForDualSim() {
         if (DBG) Log.d(LOG_TAG, "updateLimitedSimFunctionForDualSim");
         // check conditions to display limited SIM function notification under dual SIM
@@ -828,7 +881,7 @@
         IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
         pw.println("------- PhoneGlobals -------");
         pw.increaseIndent();
-        pw.println("mNoDataDueToRoaming=" + mNoDataDueToRoaming);
+        pw.println("mPrevRoamingNotification=" + mPrevRoamingNotification);
         pw.println("mDefaultDataSubId=" + mDefaultDataSubId);
         pw.println("mDataRoamingNotifLog:");
         pw.println("isSmsCapable=" + TelephonyManager.from(this).isSmsCapable());
diff --git a/src/com/android/services/telephony/DisconnectCauseUtil.java b/src/com/android/services/telephony/DisconnectCauseUtil.java
index e3155f3..20c16fe 100644
--- a/src/com/android/services/telephony/DisconnectCauseUtil.java
+++ b/src/com/android/services/telephony/DisconnectCauseUtil.java
@@ -166,6 +166,8 @@
             case android.telephony.DisconnectCause.POWER_OFF:
             case android.telephony.DisconnectCause.LOW_BATTERY:
             case android.telephony.DisconnectCause.DIAL_LOW_BATTERY:
+            case android.telephony.DisconnectCause.EMERGENCY_CALL_OVER_WFC_NOT_AVAILABLE:
+            case android.telephony.DisconnectCause.WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION:
             case android.telephony.DisconnectCause.SERVER_ERROR:
             case android.telephony.DisconnectCause.SERVER_UNREACHABLE:
             case android.telephony.DisconnectCause.TIMED_OUT:
@@ -356,6 +358,12 @@
             case android.telephony.DisconnectCause.OTASP_PROVISIONING_IN_PROCESS:
                 resourceId = R.string.callFailed_otasp_provisioning_in_process;
                 break;
+            case android.telephony.DisconnectCause.EMERGENCY_CALL_OVER_WFC_NOT_AVAILABLE:
+                resourceId = R.string.callFailed_emergency_call_over_wfc_not_available;
+                break;
+            case android.telephony.DisconnectCause.WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION:
+                resourceId = R.string.callFailed_wfc_service_not_available_in_this_location;
+                break;
             default:
                 break;
         }
@@ -743,6 +751,12 @@
             case android.telephony.DisconnectCause.OTASP_PROVISIONING_IN_PROCESS:
                 resourceId = R.string.callFailed_otasp_provisioning_in_process;
                 break;
+            case android.telephony.DisconnectCause.EMERGENCY_CALL_OVER_WFC_NOT_AVAILABLE:
+                resourceId = R.string.callFailed_emergency_call_over_wfc_not_available;
+                break;
+            case android.telephony.DisconnectCause.WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION:
+                resourceId = R.string.callFailed_wfc_service_not_available_in_this_location;
+                break;
             default:
                 break;
         }