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.app.Activity; 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 Doddimport android.telephony.PhoneNumberUtils; 26d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport android.telephony.SmsManager; 27d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 28d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.Factory; 29d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.BugleDatabaseOperations; 30d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.BugleNotifications; 31d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.DataModel; 32d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.DatabaseWrapper; 33d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.MmsFileProvider; 34d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.data.MessageData; 35d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.data.MessagePartData; 36d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.datamodel.data.ParticipantData; 37d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.mmslib.pdu.SendConf; 38d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.sms.MmsConfig; 39d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.sms.MmsSender; 40d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.sms.MmsUtils; 41d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.Assert; 42d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport com.android.messaging.util.LogUtil; 43d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 44d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.io.File; 45d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddimport java.util.ArrayList; 46d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 47d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd/** 48d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd* Update message status to reflect success or failure 49d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd* Can also update the message itself if a "final" message is now available from telephony db 50d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd*/ 51d3b009ae55651f1e60950342468e3c37fdeb0796Mike Doddpublic class ProcessSentMessageAction extends Action { 52d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String TAG = LogUtil.BUGLE_DATAMODEL_TAG; 53d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 54d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // These are always set 55d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String KEY_SMS = "is_sms"; 56d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String KEY_SENT_BY_PLATFORM = "sent_by_platform"; 57d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 58d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // These are set when we're processing a message sent by the user. They are null for messages 59d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // sent automatically (e.g. a NotifyRespInd/AcknowledgeInd sent in response to a download). 60d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String KEY_MESSAGE_ID = "message_id"; 61d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String KEY_MESSAGE_URI = "message_uri"; 62d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String KEY_UPDATED_MESSAGE_URI = "updated_message_uri"; 63d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String KEY_SUB_ID = "sub_id"; 64d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 65d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // These are set for messages sent by the platform (L+) 66d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String KEY_RESULT_CODE = "result_code"; 67d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final String KEY_HTTP_STATUS_CODE = "http_status_code"; 68d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String KEY_CONTENT_URI = "content_uri"; 69d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String KEY_RESPONSE = "response"; 70d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String KEY_RESPONSE_IMPORTANT = "response_important"; 71d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 72d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // These are set for messages we sent ourself (legacy), or which we fast-failed before sending. 73d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String KEY_STATUS = "status"; 74d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private static final String KEY_RAW_STATUS = "raw_status"; 75d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 76d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // This is called when MMS lib API returns via PendingIntent 77d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static void processMmsSent(final int resultCode, final Uri messageUri, 78d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Bundle extras) { 79d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final ProcessSentMessageAction action = new ProcessSentMessageAction(); 80d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Bundle params = action.actionParameters; 81d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.putBoolean(KEY_SMS, false); 82d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.putBoolean(KEY_SENT_BY_PLATFORM, true); 83d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.putString(KEY_MESSAGE_ID, extras.getString(SendMessageAction.EXTRA_MESSAGE_ID)); 84d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.putParcelable(KEY_MESSAGE_URI, messageUri); 85d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.putParcelable(KEY_UPDATED_MESSAGE_URI, 86d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd extras.getParcelable(SendMessageAction.EXTRA_UPDATED_MESSAGE_URI)); 87d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.putInt(KEY_SUB_ID, 88d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd extras.getInt(SendMessageAction.KEY_SUB_ID, ParticipantData.DEFAULT_SELF_SUB_ID)); 89d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.putInt(KEY_RESULT_CODE, resultCode); 90d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.putInt(KEY_HTTP_STATUS_CODE, extras.getInt(SmsManager.EXTRA_MMS_HTTP_STATUS, 0)); 91d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.putParcelable(KEY_CONTENT_URI, 92d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd extras.getParcelable(SendMessageAction.EXTRA_CONTENT_URI)); 93d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.putByteArray(KEY_RESPONSE, extras.getByteArray(SmsManager.EXTRA_MMS_DATA)); 94d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.putBoolean(KEY_RESPONSE_IMPORTANT, 95d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd extras.getBoolean(SendMessageAction.EXTRA_RESPONSE_IMPORTANT)); 96d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd action.start(); 97d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 98d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 99d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static void processMessageSentFastFailed(final String messageId, 100d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Uri messageUri, final Uri updatedMessageUri, final int subId, final boolean isSms, 101d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int status, final int rawStatus, final int resultCode) { 102d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final ProcessSentMessageAction action = new ProcessSentMessageAction(); 103d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Bundle params = action.actionParameters; 104d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.putBoolean(KEY_SMS, isSms); 105d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.putBoolean(KEY_SENT_BY_PLATFORM, false); 106d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.putString(KEY_MESSAGE_ID, messageId); 107d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.putParcelable(KEY_MESSAGE_URI, messageUri); 108d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.putParcelable(KEY_UPDATED_MESSAGE_URI, updatedMessageUri); 109d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.putInt(KEY_SUB_ID, subId); 110d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.putInt(KEY_STATUS, status); 111d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.putInt(KEY_RAW_STATUS, rawStatus); 112d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd params.putInt(KEY_RESULT_CODE, resultCode); 113d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd action.start(); 114d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 115d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 116d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private ProcessSentMessageAction() { 117d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Callers must use one of the static methods above 118d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 119d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 120d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd /** 121d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Update message status to reflect success or failure 122d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd * Can also update the message itself if a "final" message is now available from telephony db 123d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd */ 124d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 125d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd protected Object executeAction() { 126d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Context context = Factory.get().getApplicationContext(); 127d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String messageId = actionParameters.getString(KEY_MESSAGE_ID); 128d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Uri messageUri = actionParameters.getParcelable(KEY_MESSAGE_URI); 129d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Uri updatedMessageUri = actionParameters.getParcelable(KEY_UPDATED_MESSAGE_URI); 130d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final boolean isSms = actionParameters.getBoolean(KEY_SMS); 131d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final boolean sentByPlatform = actionParameters.getBoolean(KEY_SENT_BY_PLATFORM); 132d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 133d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int status = actionParameters.getInt(KEY_STATUS, MmsUtils.MMS_REQUEST_MANUAL_RETRY); 134d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd int rawStatus = actionParameters.getInt(KEY_RAW_STATUS, 135d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd MmsUtils.PDU_HEADER_VALUE_UNDEFINED); 136d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int subId = actionParameters.getInt(KEY_SUB_ID, ParticipantData.DEFAULT_SELF_SUB_ID); 137d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 138d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (sentByPlatform) { 139d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Delete temporary file backing the contentUri passed to MMS service 140d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final Uri contentUri = actionParameters.getParcelable(KEY_CONTENT_URI); 141d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd Assert.isTrue(contentUri != null); 142d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final File tempFile = MmsFileProvider.getFile(contentUri); 143d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd long messageSize = 0; 144d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (tempFile.exists()) { 145d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd messageSize = tempFile.length(); 146d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd tempFile.delete(); 147d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LogUtil.isLoggable(TAG, LogUtil.VERBOSE)) { 148d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.v(TAG, "ProcessSentMessageAction: Deleted temp file with outgoing " 149d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + "MMS pdu: " + contentUri); 150d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 151d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 152d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 153d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int resultCode = actionParameters.getInt(KEY_RESULT_CODE); 154d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final boolean responseImportant = actionParameters.getBoolean(KEY_RESPONSE_IMPORTANT); 155d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (resultCode == Activity.RESULT_OK) { 156d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (responseImportant) { 157d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Get the status from the response PDU and update telephony 158d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final byte[] response = actionParameters.getByteArray(KEY_RESPONSE); 159d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final SendConf sendConf = MmsSender.parseSendConf(response, subId); 160d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (sendConf != null) { 161d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final MmsUtils.StatusPlusUri result = 162d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd MmsUtils.updateSentMmsMessageStatus(context, messageUri, sendConf); 163d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd status = result.status; 164d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd rawStatus = result.rawStatus; 165d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 166d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 167d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 168d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd String errorMsg = "ProcessSentMessageAction: Platform returned error resultCode: " 169d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + resultCode; 170d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int httpStatusCode = actionParameters.getInt(KEY_HTTP_STATUS_CODE); 171d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (httpStatusCode != 0) { 172d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd errorMsg += (", HTTP status code: " + httpStatusCode); 173d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 174d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.w(TAG, errorMsg); 175d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd status = MmsSender.getErrorResultStatus(resultCode, httpStatusCode); 176d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 177d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Check for MMS messages that failed because they exceeded the maximum size, 178d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // indicated by an I/O error from the platform. 179d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (resultCode == SmsManager.MMS_ERROR_IO_ERROR) { 180d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (messageSize > MmsConfig.get(subId).getMaxMessageSize()) { 181d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd rawStatus = MessageData.RAW_TELEPHONY_STATUS_MESSAGE_TOO_BIG; 182d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 183d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 184d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 185d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 186d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (messageId != null) { 187d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int resultCode = actionParameters.getInt(KEY_RESULT_CODE); 188d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int httpStatusCode = actionParameters.getInt(KEY_HTTP_STATUS_CODE); 189d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd processResult( 190d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd messageId, updatedMessageUri, status, rawStatus, isSms, this, subId, 191d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd resultCode, httpStatusCode); 192d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 193d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (LogUtil.isLoggable(TAG, LogUtil.VERBOSE)) { 194d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.v(TAG, "ProcessSentMessageAction: No sent message to process (it was " 195d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + "probably a notify response for an MMS download)"); 196d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 197d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 198d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return null; 199d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 200d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 201d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd static void processResult(final String messageId, Uri updatedMessageUri, int status, 202d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int rawStatus, final boolean isSms, final Action processingAction, 203d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final int subId, final int resultCode, final int httpStatusCode) { 204d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final DatabaseWrapper db = DataModel.get().getDatabase(); 205d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd MessageData message = BugleDatabaseOperations.readMessage(db, messageId); 206d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final MessageData originalMessage = message; 207d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (message == null) { 208d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.w(TAG, "ProcessSentMessageAction: Sent message " + messageId 209d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + " missing from local database"); 210d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return; 211d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 212d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final String conversationId = message.getConversationId(); 213d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (updatedMessageUri != null) { 214d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Update message if we have newly written final message in the telephony db 215d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final MessageData update = MmsUtils.readSendingMmsMessage(updatedMessageUri, 216d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd conversationId, message.getParticipantId(), message.getSelfId()); 217d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (update != null) { 218d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Set message Id of final message to that of the existing place holder. 219d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd update.updateMessageId(message.getMessageId()); 220d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Update image sizes. 221d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd update.updateSizesForImageParts(); 222d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Temp attachments are no longer needed 223d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (final MessagePartData part : message.getParts()) { 224d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd part.destroySync(); 225d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 226d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd message = update; 227d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // processResult will rewrite the complete message as part of update 228d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 229d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd updatedMessageUri = null; 230d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd status = MmsUtils.MMS_REQUEST_MANUAL_RETRY; 231d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.e(TAG, "ProcessSentMessageAction: Unable to read sending message"); 232d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 233d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 234d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 235d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final long timestamp = System.currentTimeMillis(); 236d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd boolean failed; 237d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (status == MmsUtils.MMS_REQUEST_SUCCEEDED) { 238d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd message.markMessageSent(timestamp); 239d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd failed = false; 240d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else if (status == MmsUtils.MMS_REQUEST_AUTO_RETRY 241d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd && message.getInResendWindow(timestamp)) { 242d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd message.markMessageNotSent(timestamp); 243d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd message.setRawTelephonyStatus(rawStatus); 244d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd failed = false; 245d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } else { 246d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd message.markMessageFailed(timestamp); 247d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd message.setRawTelephonyStatus(rawStatus); 248d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd message.setMessageSeen(false); 249d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd failed = true; 250d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 251d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 252d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // We have special handling for when a message to an emergency number fails. In this case, 253d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // we notify immediately of any failure (even if we auto-retry), and instruct the user to 254d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // try calling the emergency number instead. 255d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (status != MmsUtils.MMS_REQUEST_SUCCEEDED) { 256d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd final ArrayList<String> recipients = 257d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd BugleDatabaseOperations.getRecipientsForConversation(db, conversationId); 258d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd for (final String recipient : recipients) { 259d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (PhoneNumberUtils.isEmergencyNumber(recipient)) { 260d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd BugleNotifications.notifyEmergencySmsFailed(recipient, conversationId); 261d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd message.markMessageFailedEmergencyNumber(timestamp); 262d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd failed = true; 263d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd break; 264d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 265d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 266d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 267d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 268d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Update the message status and optionally refresh the message with final parts/values. 269d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (SendMessageAction.updateMessageAndStatus(isSms, message, updatedMessageUri, failed)) { 270d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // We shouldn't show any notifications if we're not allowed to modify Telephony for 271d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // this message. 272d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd if (failed) { 273d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd BugleNotifications.update(false, BugleNotifications.UPDATE_ERRORS); 274d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 275d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd BugleActionToasts.onSendMessageOrManualDownloadActionCompleted( 276d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd conversationId, !failed, status, isSms, subId, true/*isSend*/); 277d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 278d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 279d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd LogUtil.i(TAG, "ProcessSentMessageAction: Done sending " + (isSms ? "SMS" : "MMS") 280d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + " message " + message.getMessageId() 281d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + " in conversation " + conversationId 282d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd + "; status is " + MmsUtils.getRequestStatusDescription(status)); 283d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 284d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd // Whether we succeeded or failed we will check and maybe schedule some more work 285d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd ProcessPendingMessagesAction.scheduleProcessPendingMessagesAction( 286d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd status != MmsUtils.MMS_REQUEST_SUCCEEDED, processingAction); 287d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 288d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 289d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd private ProcessSentMessageAction(final Parcel in) { 290d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd super(in); 291d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 292d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 293d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public static final Parcelable.Creator<ProcessSentMessageAction> CREATOR 294d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd = new Parcelable.Creator<ProcessSentMessageAction>() { 295d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 296d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public ProcessSentMessageAction createFromParcel(final Parcel in) { 297d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return new ProcessSentMessageAction(in); 298d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 299d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 300d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 301d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public ProcessSentMessageAction[] newArray(final int size) { 302d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd return new ProcessSentMessageAction[size]; 303d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 304d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd }; 305d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd 306d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd @Override 307d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd public void writeToParcel(final Parcel parcel, final int flags) { 308d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd writeActionToParcel(parcel, flags); 309d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd } 310d3b009ae55651f1e60950342468e3c37fdeb0796Mike Dodd} 311