Replace transcription for unsupported VVM message type

The VVM client only supports audio messages. Most other message types
are filtered the moment the SYNC SMS is received, but some message type
such as VVM3 DSN is indistinguishable from audio message and will pass
through.

DSN (Delivery Status Notification) is the notification when sending a
email to some address has failed. VVM3 DSN triggers a SYNC SMS that is
completely identical to normal audio messages, and can only be
identified after accessing the IMAP server.

Although DSN is not supported in the VVM client, some carrier has this
feature in their voicemail telephone interface, and will send the DSN
to the client, this must be handled or a unplayable message will be
shown with no indication of errors.

In this CL, if the client is unable to find the audio data for a
voicemail, it will be deemed a an unsupported message, and its'
transcription field will be replaced by an error message. This covers
not only DSN but also any other unplayable message.

While this solution is far from ideal, it is not expected to have a lot
of users that use the DSN feature or other unknown message types.

Change-Id: I482479b746776b563ebf5694a58a8c2cf534b0f2
Fixes: 30588635
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d549653..c7c2541 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 d5e627f..4b595ab 100644
--- a/src/com/android/phone/vvm/omtp/fetch/FetchVoicemailReceiver.java
+++ b/src/com/android/phone/vvm/omtp/fetch/FetchVoicemailReceiver.java
@@ -162,7 +162,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 87b68e5..4f7efd3 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());
             }
         }