Merge "Add text-to-speech annotations to emergency dialer edit field" into lmp-mr1-dev
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index 9956397..1d054a6 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -131,6 +131,12 @@
      */
     public static final String IGNORE_PROVIDER_EXTRA = "com.android.phone.ProviderToIgnore";
 
+    /**
+     * String Extra put into ACTION_ADD_VOICEMAIL to indicate that the voicemail setup screen should
+     * be opened.
+     */
+    public static final String SETUP_VOICEMAIL_EXTRA = "com.android.phone.SetupVoicemail";
+
     // string constants
     private static final String NUM_PROJECTION[] = {CommonDataKinds.Phone.NUMBER};
 
@@ -287,6 +293,11 @@
      */
     private boolean mShowVoicemailPreference = false;
 
+    /**
+     * Used to indicate that the voicemail setup screen should be shown.
+     */
+    private boolean mSetupVoicemail = false;
+
     /*
      * Click Listeners, handle click based on objects attached to UI.
      */
@@ -713,6 +724,9 @@
         } else {
             saveVoiceMailAndForwardingNumberStage2();
         }
+
+        // Refresh the MWI indicator if it is already showing.
+        PhoneGlobals.getInstance().refreshMwiIndicator(mSubscriptionInfoHelper.getSubId());
     }
 
     private final Handler mGetOptionComplete = new Handler() {
@@ -1107,6 +1121,8 @@
         // ACTION_ADD_VOICEMAIL action.
         mShowVoicemailPreference = (icicle == null) &&
                 TextUtils.equals(getIntent().getAction(), ACTION_ADD_VOICEMAIL);
+        mSetupVoicemail = mShowVoicemailPreference &&
+                getIntent().getBooleanExtra(SETUP_VOICEMAIL_EXTRA, false);
 
         mSubscriptionInfoHelper = new SubscriptionInfoHelper(getIntent());
         mSubscriptionInfoHelper.setActionBarTitle(
@@ -1268,7 +1284,10 @@
         // We only bring up the dialog the first time we are called (not after orientation change)
         if (mShowVoicemailPreference) {
             if (DBG) log("ACTION_ADD_VOICEMAIL Intent is thrown");
-            if (mVoicemailProviders.hasMoreThanOneVoicemailProvider()) {
+            if (mSetupVoicemail) {
+                simulatePreferenceClick(mVoicemailSettingsScreen);
+                mSetupVoicemail = false;
+            } else if (mVoicemailProviders.hasMoreThanOneVoicemailProvider()) {
                 if (DBG) log("Voicemail data has more than one provider.");
                 simulatePreferenceClick(mVoicemailProviders);
             } else {
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index 6f9c9dd..5b60f8a 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -901,18 +901,24 @@
     /**
      * Displays a notification when the phone receives a notice that a supplemental
      * service has failed.
-     * TODO: This is a NOOP if it isn't for conferences right now.
+     * TODO: This is a NOOP if it isn't for conferences or resuming call failures right now.
      */
     private void onSuppServiceFailed(AsyncResult r) {
-        if (r.result != Phone.SuppService.CONFERENCE) {
-            if (DBG) log("onSuppServiceFailed: not a merge failure event");
+        if (r.result != Phone.SuppService.CONFERENCE && r.result != Phone.SuppService.RESUME) {
+            if (DBG) log("onSuppServiceFailed: not a merge or resume failure event");
             return;
         }
 
-        if (DBG) log("onSuppServiceFailed: displaying merge failure message");
-
-        String mergeFailedString = mApplication.getResources().getString(
-                R.string.incall_error_supp_service_conference);
+        String mergeFailedString = "";
+        if (r.result == Phone.SuppService.CONFERENCE) {
+            if (DBG) log("onSuppServiceFailed: displaying merge failure message");
+            mergeFailedString = mApplication.getResources().getString(
+                    R.string.incall_error_supp_service_conference);
+        } else if (r.result == Phone.SuppService.RESUME) {
+            if (DBG) log("onSuppServiceFailed: displaying merge failure message");
+            mergeFailedString = mApplication.getResources().getString(
+                    R.string.incall_error_supp_service_switch);
+        }
         PhoneDisplayMessage.displayErrorMessage(mApplication, mergeFailedString);
 
         // start a timer that kills the dialog
diff --git a/src/com/android/phone/EmergencyDialer.java b/src/com/android/phone/EmergencyDialer.java
index 424ddde..6995d89 100644
--- a/src/com/android/phone/EmergencyDialer.java
+++ b/src/com/android/phone/EmergencyDialer.java
@@ -88,7 +88,6 @@
     private static final String LOG_TAG = "EmergencyDialer";
 
     private StatusBarManager mStatusBarManager;
-    private AccessibilityManager mAccessibilityManager;
 
     /** The length of DTMF tones in milliseconds */
     private static final int TONE_LENGTH_MS = 150;
@@ -163,7 +162,6 @@
         super.onCreate(icicle);
 
         mStatusBarManager = (StatusBarManager) getSystemService(Context.STATUS_BAR_SERVICE);
-        mAccessibilityManager = (AccessibilityManager) getSystemService(ACCESSIBILITY_SERVICE);
 
         // Allow this activity to be displayed in front of the keyguard / lockscreen.
         WindowManager.LayoutParams lp = getWindow().getAttributes();
@@ -182,10 +180,6 @@
         mDigits.setOnClickListener(this);
         mDigits.setOnKeyListener(this);
         mDigits.setLongClickable(false);
-        if (mAccessibilityManager.isEnabled()) {
-            // The text view must be selected to send accessibility events.
-            mDigits.setSelected(true);
-        }
         maybeAddNumberFormatting();
 
         // Check for the presence of the keypad
diff --git a/src/com/android/phone/GsmUmtsOptions.java b/src/com/android/phone/GsmUmtsOptions.java
index 8964cb5..ee6a738 100644
--- a/src/com/android/phone/GsmUmtsOptions.java
+++ b/src/com/android/phone/GsmUmtsOptions.java
@@ -40,10 +40,13 @@
     private static final String BUTTON_CARRIER_SETTINGS_KEY = "carrier_settings_key";
     private PreferenceActivity mPrefActivity;
     private PreferenceScreen mPrefScreen;
+    private int mSubId;
 
-    public GsmUmtsOptions(PreferenceActivity prefActivity, PreferenceScreen prefScreen) {
+    public GsmUmtsOptions(PreferenceActivity prefActivity, PreferenceScreen prefScreen,
+            final int subId) {
         mPrefActivity = prefActivity;
         mPrefScreen = prefScreen;
+        mSubId = subId;
         create();
     }
 
@@ -106,6 +109,7 @@
                             final Intent intent = new Intent(Settings.ACTION_APN_SETTINGS);
                             // This will setup the Home and Search affordance
                             intent.putExtra(":settings:show_fragment_as_subsetting", true);
+                            intent.putExtra("sub_id", mSubId);
                             mPrefActivity.startActivity(intent);
                             return true;
                         }
diff --git a/src/com/android/phone/MobileNetworkSettings.java b/src/com/android/phone/MobileNetworkSettings.java
index ff3f066..efb61f6 100644
--- a/src/com/android/phone/MobileNetworkSettings.java
+++ b/src/com/android/phone/MobileNetworkSettings.java
@@ -412,7 +412,7 @@
             mButtonPreferredNetworkMode.setOnPreferenceChangeListener(this);
 
             mCdmaOptions = new CdmaOptions(this, prefSet, mPhone);
-            mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet);
+            mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet, phoneSubId);
         } else {
             prefSet.removePreference(mButtonPreferredNetworkMode);
             final int phoneType = mPhone.getPhoneType();
@@ -488,7 +488,7 @@
                     mButtonEnabledNetworks.setEntryValues(
                             R.array.enabled_networks_values);
                 }
-                mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet);
+                mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet, phoneSubId);
             } else {
                 throw new IllegalStateException("Unexpected phone type: " + phoneType);
             }
@@ -601,14 +601,14 @@
                         return true;
                 }
 
-                UpdatePreferredNetworkModeSummary(buttonNetworkMode);
-
                 android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
                         android.provider.Settings.Global.PREFERRED_NETWORK_MODE + phoneSubId,
                         buttonNetworkMode );
                 //Set the modem network mode
                 mPhone.setPreferredNetworkType(modemNetworkMode, mHandler
                         .obtainMessage(MyHandler.MESSAGE_SET_PREFERRED_NETWORK_TYPE));
+
+                updateBody();
             }
         } else if (preference == mButtonEnabledNetworks) {
             mButtonEnabledNetworks.setValue((String) objValue);
@@ -1051,7 +1051,7 @@
         }
 
         if (mGsmUmtsOptions == null) {
-            mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet);
+            mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet, mPhone.getSubId());
         }
         PreferenceScreen apnExpand =
                 (PreferenceScreen) prefSet.findPreference(BUTTON_APN_EXPAND_KEY);
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index 65f7594..f026442 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -41,6 +41,7 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.widget.Toast;
 
@@ -48,8 +49,12 @@
 import com.android.internal.telephony.PhoneBase;
 import com.android.internal.telephony.TelephonyCapabilities;
 import com.android.phone.settings.VoicemailNotificationSettingsUtil;
+import com.android.phone.settings.VoicemailProviderSettingsUtil;
 
+import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * NotificationManager-related utility code for the Phone app.
@@ -95,6 +100,9 @@
     // used to track the notification of selected network unavailable
     private boolean mSelectedUnavailableNotify = false;
 
+    // used to track whether the message waiting indicator is visible, per subscription id.
+    private ArrayMap<Integer, Boolean> mMwiVisible = new ArrayMap<Integer, Boolean>();
+
     /**
      * Private constructor (this is a singleton).
      * @see #init(PhoneGlobals)
@@ -236,12 +244,52 @@
     };
 
     /**
+     * Re-creates the message waiting indicator (voicemail) notification if it is showing.  Used to
+     * refresh the voicemail intent on the indicator when the user changes it via the voicemail
+     * settings screen.  The voicemail notification sound is suppressed.
+     *
+     * @param subId The subscription Id.
+     */
+    /* package */ void refreshMwi(int subId) {
+        // In a single-sim device, subId can be -1 which means "no sub id".  In this case we will
+        // reference the single subid stored in the mMwiVisible map.
+        if (subId == SubscriptionInfoHelper.NO_SUB_ID) {
+            if (mMwiVisible.keySet().size() == 1) {
+                Set<Integer> keySet = mMwiVisible.keySet();
+                Iterator<Integer> keyIt = keySet.iterator();
+                if (!keyIt.hasNext()) {
+                    return;
+                }
+                subId = keyIt.next();
+            }
+        }
+        if (mMwiVisible.containsKey(subId)) {
+            boolean mwiVisible = mMwiVisible.get(subId);
+            if (mwiVisible) {
+                updateMwi(subId, mwiVisible, false /* enableNotificationSound */);
+            }
+        }
+    }
+
+    /**
      * Updates the message waiting indicator (voicemail) notification.
      *
      * @param visible true if there are messages waiting
      */
     /* package */ void updateMwi(int subId, boolean visible) {
+        updateMwi(subId, visible, true /* enableNotificationSound */);
+    }
+
+    /**
+     * Updates the message waiting indicator (voicemail) notification.
+     *
+     * @param subId the subId to update.
+     * @param visible true if there are messages waiting
+     * @param enableNotificationSound {@code true} if the notification sound should be played.
+     */
+    void updateMwi(int subId, boolean visible, boolean enableNotificationSound) {
         if (DBG) log("updateMwi(): subId " + subId + " update to " + visible);
+        mMwiVisible.put(subId, visible);
 
         if (!PhoneGlobals.sVoiceCapable) {
             // Do not show the message waiting indicator on devices which are not voice capable.
@@ -296,28 +344,44 @@
                 notificationTitle = String.format(titleFormat, vmCount);
             }
 
+            // This pathway only applies to PSTN accounts; only SIMS have subscription ids.
+            PhoneAccountHandle phoneAccountHandle = PhoneUtils.makePstnPhoneAccountHandle(phone);
+
+            Intent intent;
             String notificationText;
-            if (mTelephonyManager.getPhoneCount() > 1) {
-                notificationText = subInfo.getDisplayName().toString();
+            if (TextUtils.isEmpty(vmNumber)) {
+                notificationText = mContext.getString(
+                        R.string.notification_voicemail_no_vm_number);
+
+                // If the voicemail number if unknown, instead of calling voicemail, take the user
+                // to the voicemail settings.
+                notificationText = mContext.getString(
+                        R.string.notification_voicemail_no_vm_number);
+                intent = new Intent(CallFeaturesSetting.ACTION_ADD_VOICEMAIL);
+                intent.putExtra(CallFeaturesSetting.SETUP_VOICEMAIL_EXTRA, true);
+                intent.putExtra(SubscriptionInfoHelper.SUB_ID_EXTRA, subId);
+                intent.setClass(mContext, CallFeaturesSetting.class);
             } else {
-                if (TextUtils.isEmpty(vmNumber)) {
-                    notificationText = mContext.getString(
-                            R.string.notification_voicemail_no_vm_number);
+                if (mTelephonyManager.getPhoneCount() > 1) {
+                    notificationText = subInfo.getDisplayName().toString();
                 } else {
                     notificationText = String.format(
                             mContext.getString(R.string.notification_voicemail_text_format),
                             PhoneNumberUtils.formatNumber(vmNumber));
                 }
+                intent = new Intent(
+                        Intent.ACTION_CALL, Uri.fromParts(PhoneAccount.SCHEME_VOICEMAIL, "",
+                        null));
+                intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
             }
 
-            // This pathway only applies to PSTN accounts; only SIMS have subscription ids.
-            PhoneAccountHandle phoneAccountHandle = PhoneUtils.makePstnPhoneAccountHandle(phone);
-            Intent intent = new Intent(
-                    Intent.ACTION_CALL, Uri.fromParts(PhoneAccount.SCHEME_VOICEMAIL, "", null));
-            intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
             PendingIntent pendingIntent =
                     PendingIntent.getActivity(mContext, subId /* requestCode */, intent, 0);
-            Uri ringtoneUri = VoicemailNotificationSettingsUtil.getRingtoneUri(phone);
+            Uri ringtoneUri = null;
+
+            if (enableNotificationSound) {
+                ringtoneUri = VoicemailNotificationSettingsUtil.getRingtoneUri(mPhone);
+            }
 
             Notification.Builder builder = new Notification.Builder(mContext);
             builder.setSmallIcon(resId)
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 03827ce..2fcce90 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -924,6 +924,15 @@
     }
 
     /**
+     * Triggers a refresh of the message waiting (voicemail) indicator.
+     *
+     * @param subId the subscription id we should refresh the notification for.
+     */
+    public void refreshMwiIndicator(int subId) {
+        notificationMgr.refreshMwi(subId);
+    }
+
+    /**
      * "Call origin" may be used by Contacts app to specify where the phone call comes from.
      * Currently, the only permitted value for this extra is {@link #ALLOWED_EXTRA_CALL_ORIGIN}.
      * Any other value will be ignored, to make sure that malicious apps can't trick the in-call
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 30c3a39..d20df1b 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -1917,9 +1917,17 @@
      * @param enable {@code true} turn turn data on, else {@code false}
      */
     @Override
-    public void setDataEnabled(boolean enable) {
+    public void setDataEnabled(int subId, boolean enable) {
         enforceModifyPermission();
-        mPhone.setDataEnabled(enable);
+        int phoneId = mSubscriptionController.getPhoneId(subId);
+        log("getDataEnabled: subId=" + subId + " phoneId=" + phoneId);
+        Phone phone = PhoneFactory.getPhone(phoneId);
+        if (phone != null) {
+            log("setDataEnabled: subId=" + subId + " enable=" + enable);
+            phone.setDataEnabled(enable);
+        } else {
+            loge("setDataEnabled: no phone for subId=" + subId);
+        }
     }
 
     /**
@@ -1932,7 +1940,7 @@
      * @return {@code true} if data is enabled else {@code false}
      */
     @Override
-    public boolean getDataEnabled() {
+    public boolean getDataEnabled(int subId) {
         try {
             mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
                     null);
@@ -1940,7 +1948,17 @@
             mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE,
                     null);
         }
-        return mPhone.getDataEnabled();
+        int phoneId = mSubscriptionController.getPhoneId(subId);
+        log("getDataEnabled: subId=" + subId + " phoneId=" + phoneId);
+        Phone phone = PhoneFactory.getPhone(phoneId);
+        if (phone != null) {
+            boolean retVal = phone.getDataEnabled();
+            log("getDataEnabled: subId=" + subId + " retVal=" + retVal);
+            return retVal;
+        } else {
+            loge("getDataEnabled: no phone subId=" + subId + " retVal=false");
+            return false;
+        }
     }
 
     @Override
diff --git a/src/com/android/phone/SubscriptionInfoHelper.java b/src/com/android/phone/SubscriptionInfoHelper.java
index 347d00e..f325b1a 100644
--- a/src/com/android/phone/SubscriptionInfoHelper.java
+++ b/src/com/android/phone/SubscriptionInfoHelper.java
@@ -36,10 +36,10 @@
  * helping extract this info and perform common operations using this info.
  */
 public class SubscriptionInfoHelper {
-    private static final int NO_SUB_ID = -1;
+    public static final int NO_SUB_ID = -1;
 
     // Extra on intent containing the id of a subscription.
-    private static final String SUB_ID_EXTRA =
+    public static final String SUB_ID_EXTRA =
             "com.android.phone.settings.SubscriptionInfoHelper.SubscriptionId";
     // Extra on intent containing the label of a subscription.
     private static final String SUB_LABEL_EXTRA =