Merge "When voicemail number is unknown, show voicemail setup on notification click." 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/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/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 =