1d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/* 2d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Copyright (C) 2015 The Android Open Source Project 3d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 4d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Licensed under the Apache License, Version 2.0 (the "License"); 5d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * you may not use this file except in compliance with the License. 6d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * You may obtain a copy of the License at 7d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 8d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * http://www.apache.org/licenses/LICENSE-2.0 9d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 10d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Unless required by applicable law or agreed to in writing, software 11d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * distributed under the License is distributed on an "AS IS" BASIS, 12d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * See the License for the specific language governing permissions and 14d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * limitations under the License. 15d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 16d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 17d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpackage com.android.messaging.datamodel.action; 18d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 19d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.ContentValues; 20d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.content.Context; 21d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.net.Uri; 22d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.os.Bundle; 23d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.os.Parcel; 24d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.os.Parcelable; 25d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 26d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.Factory; 27d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.BugleDatabaseOperations; 28d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.DataModel; 29d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.DatabaseHelper.MessageColumns; 30d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.DatabaseWrapper; 31d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.MessagingContentProvider; 32d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.SyncManager; 33d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.data.MessageData; 34d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.data.ParticipantData; 35d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.sms.MmsUtils; 36d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.Assert; 37d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.Assert.RunsOnMainThread; 38d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.LogUtil; 39d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 40d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/** 41d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Downloads an MMS message. 42d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * <p> 43d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * This class is public (not package-private) because the SMS/MMS (e.g. MmsUtils) classes need to 44d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * access the EXTRA_* fields for setting up the 'downloaded' pending intent. 45d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 46d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpublic class DownloadMmsAction extends Action implements Parcelable { 47d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String TAG = LogUtil.BUGLE_DATAMODEL_TAG; 48d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 49d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 50d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Interface for DownloadMmsAction listeners 51d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 52d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public interface DownloadMmsActionListener { 53d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @RunsOnMainThread 54d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd abstract void onDownloadMessageStarting(final ActionMonitor monitor, 55d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Object data, final MessageData message); 56d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @RunsOnMainThread 57d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd abstract void onDownloadMessageSucceeded(final ActionMonitor monitor, 58d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Object data, final MessageData message); 59d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @RunsOnMainThread 60d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd abstract void onDownloadMessageFailed(final ActionMonitor monitor, 61d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Object data, final MessageData message); 62d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 63d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 64d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 65d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Queue download of an mms notification message (can only be called during execute of action) 66d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 67d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd static boolean queueMmsForDownloadInBackground(final String messageId, 68d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Action processingAction) { 69d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // When this method is being called, it is always from auto download 70d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final DownloadMmsAction action = new DownloadMmsAction(); 71d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // This could queue nothing 72d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return action.queueAction(messageId, processingAction); 73d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 74d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 75d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String KEY_MESSAGE_ID = "message_id"; 76d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String KEY_CONVERSATION_ID = "conversation_id"; 77d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String KEY_PARTICIPANT_ID = "participant_id"; 78d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String KEY_CONTENT_LOCATION = "content_location"; 79d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String KEY_TRANSACTION_ID = "transaction_id"; 80d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String KEY_NOTIFICATION_URI = "notification_uri"; 81d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String KEY_SUB_ID = "sub_id"; 82d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String KEY_SUB_PHONE_NUMBER = "sub_phone_number"; 83d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String KEY_AUTO_DOWNLOAD = "auto_download"; 84d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String KEY_FAILURE_STATUS = "failure_status"; 85d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 86d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Values we attach to the pending intent that's fired when the message is downloaded. 87d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Only applicable when downloading via the platform APIs on L+. 88d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String EXTRA_MESSAGE_ID = "message_id"; 89d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String EXTRA_CONTENT_URI = "content_uri"; 90d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String EXTRA_NOTIFICATION_URI = "notification_uri"; 91d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String EXTRA_SUB_ID = "sub_id"; 92d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String EXTRA_SUB_PHONE_NUMBER = "sub_phone_number"; 93d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String EXTRA_TRANSACTION_ID = "transaction_id"; 94d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String EXTRA_CONTENT_LOCATION = "content_location"; 95d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String EXTRA_AUTO_DOWNLOAD = "auto_download"; 96d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String EXTRA_RECEIVED_TIMESTAMP = "received_timestamp"; 97d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String EXTRA_CONVERSATION_ID = "conversation_id"; 98d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String EXTRA_PARTICIPANT_ID = "participant_id"; 99d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String EXTRA_STATUS_IF_FAILED = "status_if_failed"; 100d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 101d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private DownloadMmsAction() { 102d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd super(); 103d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 104d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 105d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 106d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected Object executeAction() { 107d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Assert.fail("DownloadMmsAction must be queued rather than started"); 108d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 109d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 110d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 111d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected boolean queueAction(final String messageId, final Action processingAction) { 112d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd actionParameters.putString(KEY_MESSAGE_ID, messageId); 113d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 114d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final DatabaseWrapper db = DataModel.get().getDatabase(); 115d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Read the message from local db 116d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final MessageData message = BugleDatabaseOperations.readMessage(db, messageId); 117d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (message != null && message.canDownloadMessage()) { 118d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Uri notificationUri = message.getSmsMessageUri(); 119d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String conversationId = message.getConversationId(); 120d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int status = message.getStatus(); 121d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 122d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String selfId = message.getSelfId(); 123d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final ParticipantData self = BugleDatabaseOperations 124d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd .getExistingParticipant(db, selfId); 125d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int subId = self.getSubId(); 126d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd actionParameters.putInt(KEY_SUB_ID, subId); 127d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd actionParameters.putString(KEY_CONVERSATION_ID, conversationId); 128d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd actionParameters.putString(KEY_PARTICIPANT_ID, message.getParticipantId()); 129d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd actionParameters.putString(KEY_CONTENT_LOCATION, message.getMmsContentLocation()); 130d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd actionParameters.putString(KEY_TRANSACTION_ID, message.getMmsTransactionId()); 131d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd actionParameters.putParcelable(KEY_NOTIFICATION_URI, notificationUri); 132d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd actionParameters.putBoolean(KEY_AUTO_DOWNLOAD, isAutoDownload(status)); 133d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 134d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final long now = System.currentTimeMillis(); 135d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (message.getInDownloadWindow(now)) { 136d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // We can still retry 137d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd actionParameters.putString(KEY_SUB_PHONE_NUMBER, self.getNormalizedDestination()); 138d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 139d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int downloadingStatus = getDownloadingStatus(status); 140d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Update message status to indicate downloading. 141d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd updateMessageStatus(notificationUri, messageId, conversationId, 142d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd downloadingStatus, MessageData.RAW_TELEPHONY_STATUS_UNDEFINED); 143d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Pre-compute the next status when failed so we don't have to load from db again 144d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd actionParameters.putInt(KEY_FAILURE_STATUS, getFailureStatus(downloadingStatus)); 145d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 146d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Actual download happens in background 147d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd processingAction.requestBackgroundWork(this); 148d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 149d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LogUtil.isLoggable(TAG, LogUtil.DEBUG)) { 150d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.d(TAG, 151d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd "DownloadMmsAction: Queued download of MMS message " + messageId); 152d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 153d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return true; 154d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 155d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.w(TAG, "DownloadMmsAction: Download of MMS message " + messageId 156d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + " failed (outside download window)"); 157d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 158d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Retries depleted and we failed. Update the message status so we won't retry again 159d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd updateMessageStatus(notificationUri, messageId, conversationId, 160d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd MessageData.BUGLE_STATUS_INCOMING_DOWNLOAD_FAILED, 161d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd MessageData.RAW_TELEPHONY_STATUS_UNDEFINED); 162d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (status == MessageData.BUGLE_STATUS_INCOMING_RETRYING_AUTO_DOWNLOAD) { 163d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // For auto download failure, we should send a DEFERRED NotifyRespInd 164d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // to carrier to indicate we will manual download later 165d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ProcessDownloadedMmsAction.sendDeferredRespStatus( 166d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd messageId, message.getMmsTransactionId(), 167d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd message.getMmsContentLocation(), subId); 168d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return true; 169d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 170d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 171d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 172d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 173d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 174d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 175d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 176d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Find out the auto download state of this message based on its starting status 177d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 178d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param status The starting status of the message. 179d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return True if this is a message doing auto downloading, false otherwise 180d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 181d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static boolean isAutoDownload(final int status) { 182d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd switch (status) { 183d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case MessageData.BUGLE_STATUS_INCOMING_RETRYING_MANUAL_DOWNLOAD: 184d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 185d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case MessageData.BUGLE_STATUS_INCOMING_RETRYING_AUTO_DOWNLOAD: 186d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return true; 187d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd default: 188d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Assert.fail("isAutoDownload: invalid input status " + status); 189d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return false; 190d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 191d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 192d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 193d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 194d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Get the corresponding downloading status based on the starting status of the message 195d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 196d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param status The starting status of the message. 197d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return The downloading status 198d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 199d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static int getDownloadingStatus(final int status) { 200d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd switch (status) { 201d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case MessageData.BUGLE_STATUS_INCOMING_RETRYING_MANUAL_DOWNLOAD: 202d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return MessageData.BUGLE_STATUS_INCOMING_MANUAL_DOWNLOADING; 203d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case MessageData.BUGLE_STATUS_INCOMING_RETRYING_AUTO_DOWNLOAD: 204d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return MessageData.BUGLE_STATUS_INCOMING_AUTO_DOWNLOADING; 205d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd default: 206d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Assert.fail("isAutoDownload: invalid input status " + status); 207d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return MessageData.BUGLE_STATUS_INCOMING_MANUAL_DOWNLOADING; 208d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 209d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 210d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 211d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 212d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Get the corresponding failed status based on the current downloading status 213d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * 214d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @param status The downloading status 215d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * @return The status the message should have if downloading failed 216d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 217d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static int getFailureStatus(final int status) { 218d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd switch (status) { 219d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case MessageData.BUGLE_STATUS_INCOMING_AUTO_DOWNLOADING: 220d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return MessageData.BUGLE_STATUS_INCOMING_RETRYING_AUTO_DOWNLOAD; 221d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd case MessageData.BUGLE_STATUS_INCOMING_MANUAL_DOWNLOADING: 222d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return MessageData.BUGLE_STATUS_INCOMING_RETRYING_MANUAL_DOWNLOAD; 223d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd default: 224d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Assert.fail("isAutoDownload: invalid input status " + status); 225d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return MessageData.BUGLE_STATUS_INCOMING_RETRYING_MANUAL_DOWNLOAD; 226d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 227d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 228d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 229d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 230d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected Bundle doBackgroundWork() { 231d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Context context = Factory.get().getApplicationContext(); 232d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int subId = actionParameters.getInt(KEY_SUB_ID); 233d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String messageId = actionParameters.getString(KEY_MESSAGE_ID); 234d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Uri notificationUri = actionParameters.getParcelable(KEY_NOTIFICATION_URI); 235d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String subPhoneNumber = actionParameters.getString(KEY_SUB_PHONE_NUMBER); 236d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String transactionId = actionParameters.getString(KEY_TRANSACTION_ID); 237d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String contentLocation = actionParameters.getString(KEY_CONTENT_LOCATION); 238d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final boolean autoDownload = actionParameters.getBoolean(KEY_AUTO_DOWNLOAD); 239d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String conversationId = actionParameters.getString(KEY_CONVERSATION_ID); 240d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String participantId = actionParameters.getString(KEY_PARTICIPANT_ID); 241d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int statusIfFailed = actionParameters.getInt(KEY_FAILURE_STATUS); 242d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 243d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final long receivedTimestampRoundedToSecond = 244d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 1000 * ((System.currentTimeMillis() + 500) / 1000); 245d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 246d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.i(TAG, "DownloadMmsAction: Downloading MMS message " + messageId 247d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + " (" + (autoDownload ? "auto" : "manual") + ")"); 248d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 249d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Bundle some values we'll need after the message is downloaded (via platform APIs) 250d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Bundle extras = new Bundle(); 251d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd extras.putString(EXTRA_MESSAGE_ID, messageId); 252d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd extras.putString(EXTRA_CONVERSATION_ID, conversationId); 253d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd extras.putString(EXTRA_PARTICIPANT_ID, participantId); 254d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd extras.putInt(EXTRA_STATUS_IF_FAILED, statusIfFailed); 255d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 256d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Start the download 257d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final MmsUtils.StatusPlusUri status = MmsUtils.downloadMmsMessage(context, 258d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd notificationUri, subId, subPhoneNumber, transactionId, contentLocation, 259d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd autoDownload, receivedTimestampRoundedToSecond / 1000L, extras); 260d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (status == MmsUtils.STATUS_PENDING) { 261d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Async download; no status yet 262d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LogUtil.isLoggable(TAG, LogUtil.DEBUG)) { 263d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.d(TAG, "DownloadMmsAction: Downloading MMS message " + messageId 264d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + " asynchronously; waiting for pending intent to signal completion"); 265d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 266d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 267d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Inform sync that message has been added at local received timestamp 268d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final SyncManager syncManager = DataModel.get().getSyncManager(); 269d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd syncManager.onNewMessageInserted(receivedTimestampRoundedToSecond); 270d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Handle downloaded message 271d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ProcessDownloadedMmsAction.processMessageDownloadFastFailed(messageId, 272d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd notificationUri, conversationId, participantId, contentLocation, subId, 273d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd subPhoneNumber, statusIfFailed, autoDownload, transactionId, 274d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd status.resultCode); 275d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 276d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 277d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 278d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 279d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 280d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected Object processBackgroundResponse(final Bundle response) { 281d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Nothing to do here; post-download actions handled by ProcessDownloadedMmsAction 282d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 283d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 284d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 285d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 286d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected Object processBackgroundFailure() { 287d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String messageId = actionParameters.getString(KEY_MESSAGE_ID); 288d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String transactionId = actionParameters.getString(KEY_TRANSACTION_ID); 289d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String conversationId = actionParameters.getString(KEY_CONVERSATION_ID); 290d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String participantId = actionParameters.getString(KEY_PARTICIPANT_ID); 291d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int statusIfFailed = actionParameters.getInt(KEY_FAILURE_STATUS); 292d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int subId = actionParameters.getInt(KEY_SUB_ID); 293d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 294d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ProcessDownloadedMmsAction.processDownloadActionFailure(messageId, 295d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd MmsUtils.MMS_REQUEST_MANUAL_RETRY, MessageData.RAW_TELEPHONY_STATUS_UNDEFINED, 296d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd conversationId, participantId, statusIfFailed, subId, transactionId); 297d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 298d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 299d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 300d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 301d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd static void updateMessageStatus(final Uri messageUri, final String messageId, 302d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String conversationId, final int status, final int rawStatus) { 303d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Context context = Factory.get().getApplicationContext(); 304d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Downloading status just kept in local DB but need to fix up telephony DB first 305d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (status == MessageData.BUGLE_STATUS_INCOMING_AUTO_DOWNLOADING || 306d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd status == MessageData.BUGLE_STATUS_INCOMING_MANUAL_DOWNLOADING) { 307d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd MmsUtils.clearMmsStatus(context, messageUri); 308d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 309d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Then mark downloading status in our local DB 310d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final ContentValues values = new ContentValues(); 311d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd values.put(MessageColumns.STATUS, status); 312d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd values.put(MessageColumns.RAW_TELEPHONY_STATUS, rawStatus); 313d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final DatabaseWrapper db = DataModel.get().getDatabase(); 314d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd BugleDatabaseOperations.updateMessageRowIfExists(db, messageId, values); 315d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 316d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd MessagingContentProvider.notifyMessagesChanged(conversationId); 317d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 318d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 319d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private DownloadMmsAction(final Parcel in) { 320d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd super(in); 321d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 322d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 323d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final Parcelable.Creator<DownloadMmsAction> CREATOR 324d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd = new Parcelable.Creator<DownloadMmsAction>() { 325d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 326d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public DownloadMmsAction createFromParcel(final Parcel in) { 327d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return new DownloadMmsAction(in); 328d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 329d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 330d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 331d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public DownloadMmsAction[] newArray(final int size) { 332d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return new DownloadMmsAction[size]; 333d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 334d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd }; 335d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 336d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 337d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void writeToParcel(final Parcel parcel, final int flags) { 338d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd writeActionToParcel(parcel, flags); 339d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 340d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd} 341