1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 package com.android.voicemail.impl.fetch; 17 18 import android.content.ContentResolver; 19 import android.content.ContentValues; 20 import android.content.Context; 21 import android.net.Uri; 22 import android.provider.VoicemailContract.Voicemails; 23 import android.support.annotation.Nullable; 24 import android.telecom.PhoneAccountHandle; 25 import android.telecom.TelecomManager; 26 import com.android.dialer.common.Assert; 27 import com.android.dialer.common.concurrent.ThreadUtil; 28 import com.android.voicemail.impl.R; 29 import com.android.voicemail.impl.VvmLog; 30 import com.android.voicemail.impl.imap.VoicemailPayload; 31 import com.android.voicemail.impl.transcribe.TranscriptionService; 32 import java.io.IOException; 33 import java.io.OutputStream; 34 import org.apache.commons.io.IOUtils; 35 36 /** 37 * Callback for when a voicemail payload is fetched. It copies the returned stream to the data file 38 * corresponding to the voicemail. 39 */ 40 public class VoicemailFetchedCallback { 41 private static final String TAG = "VoicemailFetchedCallback"; 42 43 private final Context context; 44 private final ContentResolver contentResolver; 45 private final Uri uri; 46 private final PhoneAccountHandle phoneAccountHandle; 47 48 public VoicemailFetchedCallback(Context context, Uri uri, PhoneAccountHandle phoneAccountHandle) { 49 this.context = context; 50 contentResolver = context.getContentResolver(); 51 this.uri = uri; 52 this.phoneAccountHandle = phoneAccountHandle; 53 } 54 55 /** 56 * Saves the voicemail payload data into the voicemail provider then sets the "has_content" bit of 57 * the voicemail to "1". 58 * 59 * @param voicemailPayload The object containing the content data for the voicemail 60 */ 61 public void setVoicemailContent(@Nullable VoicemailPayload voicemailPayload) { 62 Assert.isWorkerThread(); 63 if (voicemailPayload == null) { 64 VvmLog.i(TAG, "Payload not found, message has unsupported format"); 65 ContentValues values = new ContentValues(); 66 values.put( 67 Voicemails.TRANSCRIPTION, 68 context.getString( 69 R.string.vvm_unsupported_message_format, 70 context 71 .getSystemService(TelecomManager.class) 72 .getVoiceMailNumber(phoneAccountHandle))); 73 updateVoicemail(values); 74 return; 75 } 76 77 VvmLog.d(TAG, String.format("Writing new voicemail content: %s", uri)); 78 OutputStream outputStream = null; 79 80 try { 81 outputStream = contentResolver.openOutputStream(uri); 82 byte[] inputBytes = voicemailPayload.getBytes(); 83 if (inputBytes != null) { 84 outputStream.write(inputBytes); 85 } 86 } catch (IOException e) { 87 VvmLog.w(TAG, String.format("File not found for %s", uri)); 88 return; 89 } finally { 90 IOUtils.closeQuietly(outputStream); 91 } 92 93 // Update mime_type & has_content after we are done with file update. 94 ContentValues values = new ContentValues(); 95 values.put(Voicemails.MIME_TYPE, voicemailPayload.getMimeType()); 96 values.put(Voicemails.HAS_CONTENT, true); 97 if (updateVoicemail(values)) { 98 ThreadUtil.postOnUiThread( 99 () -> { 100 if (!TranscriptionService.scheduleNewVoicemailTranscriptionJob( 101 context, uri, phoneAccountHandle, true)) { 102 VvmLog.w(TAG, String.format("Failed to schedule transcription for %s", uri)); 103 } 104 }); 105 } 106 } 107 108 private boolean updateVoicemail(ContentValues values) { 109 int updatedCount = contentResolver.update(uri, values, null, null); 110 if (updatedCount != 1) { 111 VvmLog.e(TAG, "Updating voicemail should have updated 1 row, was: " + updatedCount); 112 return false; 113 } else { 114 return true; 115 } 116 } 117 } 118