Merge "Change title of "Enhanced 4G LTE Mode" per carrier config" into nyc-mr1-dev
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 35c31c0..c003662 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -349,6 +349,8 @@
     <string name="vm_change_pin_error_invalid">The new PIN contains invalid characters.</string>
     <!-- Error message for the voicemail PIN change if operation has failed -->
     <string name="vm_change_pin_error_system_error">Unable to change PIN</string>
+    <!-- Message to replace the transcription if a visual voicemail message is not supported-->
+    <string name="vvm_unsupported_message_format">Unsupported message type, call <xliff:g id="number" example="*86">%s</xliff:g> to listen.</string>
 
     <!-- networks setting strings --><skip/>
     <!-- Mobile network settings screen title -->
diff --git a/src/com/android/phone/vvm/omtp/fetch/FetchVoicemailReceiver.java b/src/com/android/phone/vvm/omtp/fetch/FetchVoicemailReceiver.java
index 5ba0fb3..9bda638 100644
--- a/src/com/android/phone/vvm/omtp/fetch/FetchVoicemailReceiver.java
+++ b/src/com/android/phone/vvm/omtp/fetch/FetchVoicemailReceiver.java
@@ -191,7 +191,8 @@
                         try (ImapHelper imapHelper = new ImapHelper(mContext, mPhoneAccount,
                             network, status)) {
                             boolean success = imapHelper.fetchVoicemailPayload(
-                                    new VoicemailFetchedCallback(mContext, mUri), mUid);
+                                    new VoicemailFetchedCallback(mContext, mUri, mPhoneAccount),
+                                    mUid);
                             if (!success && mRetryCount > 0) {
                                 VvmLog.i(TAG, "fetch voicemail failed, retrying");
                                 mRetryCount--;
diff --git a/src/com/android/phone/vvm/omtp/fetch/VoicemailFetchedCallback.java b/src/com/android/phone/vvm/omtp/fetch/VoicemailFetchedCallback.java
index 387ca5a..e70ba49 100644
--- a/src/com/android/phone/vvm/omtp/fetch/VoicemailFetchedCallback.java
+++ b/src/com/android/phone/vvm/omtp/fetch/VoicemailFetchedCallback.java
@@ -15,19 +15,20 @@
  */
 package com.android.phone.vvm.omtp.fetch;
 
+import android.annotation.Nullable;
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
 import android.net.Uri;
 import android.provider.VoicemailContract.Voicemails;
-
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import com.android.phone.R;
 import com.android.phone.vvm.omtp.VvmLog;
 import com.android.phone.vvm.omtp.imap.VoicemailPayload;
-
-import libcore.io.IoUtils;
-
 import java.io.IOException;
 import java.io.OutputStream;
+import libcore.io.IoUtils;
 
 /**
  * Callback for when a voicemail payload is fetched. It copies the returned stream to the data
@@ -36,12 +37,17 @@
 public class VoicemailFetchedCallback {
     private static final String TAG = "VoicemailFetchedCallback";
 
-    private ContentResolver mContentResolver;
-    private Uri mUri;
+    private final Context mContext;
+    private final ContentResolver mContentResolver;
+    private final Uri mUri;
+    private final PhoneAccountHandle mPhoneAccountHandle;
 
-    public VoicemailFetchedCallback(Context context, Uri uri) {
+    public VoicemailFetchedCallback(Context context, Uri uri,
+        PhoneAccountHandle phoneAccountHandle) {
+        mContext = context;
         mContentResolver = context.getContentResolver();
         mUri = uri;
+        mPhoneAccountHandle = phoneAccountHandle;
     }
 
     /**
@@ -50,7 +56,17 @@
      *
      * @param voicemailPayload The object containing the content data for the voicemail
      */
-    public void setVoicemailContent(VoicemailPayload voicemailPayload) {
+    public void setVoicemailContent(@Nullable VoicemailPayload voicemailPayload) {
+        if (voicemailPayload == null) {
+            VvmLog.i(TAG, "Payload not found, message has unsupported format");
+            ContentValues values = new ContentValues();
+            values.put(Voicemails.TRANSCRIPTION,
+                mContext.getString(R.string.vvm_unsupported_message_format,
+                    TelecomManager.from(mContext).getVoiceMailNumber(mPhoneAccountHandle)));
+            updateVoicemail(values);
+            return;
+        }
+
         VvmLog.d(TAG, String.format("Writing new voicemail content: %s", mUri));
         OutputStream outputStream = null;
 
@@ -71,10 +87,14 @@
         ContentValues values = new ContentValues();
         values.put(Voicemails.MIME_TYPE, voicemailPayload.getMimeType());
         values.put(Voicemails.HAS_CONTENT, true);
+        updateVoicemail(values);
+    }
+
+    private void updateVoicemail(ContentValues values) {
         int updatedCount = mContentResolver.update(mUri, values, null, null);
         if (updatedCount != 1) {
             VvmLog
-                    .e(TAG, "Updating voicemail should have updated 1 row, was: " + updatedCount);
+                .e(TAG, "Updating voicemail should have updated 1 row, was: " + updatedCount);
         }
     }
 }
diff --git a/src/com/android/phone/vvm/omtp/imap/ImapHelper.java b/src/com/android/phone/vvm/omtp/imap/ImapHelper.java
index d2df8de..a03e421 100644
--- a/src/com/android/phone/vvm/omtp/imap/ImapHelper.java
+++ b/src/com/android/phone/vvm/omtp/imap/ImapHelper.java
@@ -325,11 +325,6 @@
                 return false;
             }
             VoicemailPayload voicemailPayload = fetchVoicemailPayload(message);
-
-            if (voicemailPayload == null) {
-                return false;
-            }
-
             callback.setVoicemailContent(voicemailPayload);
             return true;
         } catch (MessagingException e) {
diff --git a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java b/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java
index 4628fa4..3cc25c3 100644
--- a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java
+++ b/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java
@@ -161,7 +161,7 @@
             PhoneAccountHandle account) {
         if (shouldPerformPrefetch(account, imapHelper)) {
             VoicemailFetchedCallback callback = new VoicemailFetchedCallback(mContext,
-                    voicemail.getUri());
+                    voicemail.getUri(), account);
             imapHelper.fetchVoicemailPayload(callback, voicemail.getSourceData());
         }
 
@@ -237,7 +237,7 @@
             Uri uri = VoicemailContract.Voicemails.insert(mContext, remoteVoicemail);
             if (prefetchEnabled) {
                 VoicemailFetchedCallback fetchedCallback =
-                        new VoicemailFetchedCallback(mContext, uri);
+                        new VoicemailFetchedCallback(mContext, uri, account);
                 imapHelper.fetchVoicemailPayload(fetchedCallback, remoteVoicemail.getSourceData());
             }
         }
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 241d54c..cefd6c0 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -384,6 +384,10 @@
             Log.i(this, "onCallPullFailed - pull failed; swapping back to call: %s",
                     externalConnection);
 
+            // Inform the InCallService of the fact that the call pull failed (it may choose to
+            // display a message informing the user of the pull failure).
+            sendConnectionEvent(Connection.EVENT_CALL_PULL_FAILED, null);
+
             // Swap the ImsPhoneConnection we used to do the pull for the ImsExternalConnection
             // which originally represented the call.
             setOriginalConnection(externalConnection);