From 110cdf82bf8165451bc803983964be96a373bf4b Mon Sep 17 00:00:00 2001 From: "allu.haribabu" Date: Thu, 12 May 2016 20:45:34 +0530 Subject: Add handling of MMS Read report. MMS Read report handling is missing on 13.0. Added support for this. Change-Id: I6db874537beee246499537a76e419b1991a423b9 Issue-Id: CYNGNOS-2734 --- .../datamodel/action/MarkAsReadAction.java | 3 +- .../action/ProcessDownloadedMmsAction.java | 6 ++ .../datamodel/action/ReceiveMmsMessageAction.java | 3 + .../messaging/datamodel/data/MessageData.java | 3 + src/com/android/messaging/sms/MmsSender.java | 32 ++++++++ src/com/android/messaging/sms/MmsUtils.java | 93 +++++++++++++++------- .../ui/conversation/MessageDetailsDialog.java | 7 ++ 7 files changed, 118 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/com/android/messaging/datamodel/action/MarkAsReadAction.java b/src/com/android/messaging/datamodel/action/MarkAsReadAction.java index 31bc59d..2e45fb5 100644 --- a/src/com/android/messaging/datamodel/action/MarkAsReadAction.java +++ b/src/com/android/messaging/datamodel/action/MarkAsReadAction.java @@ -28,6 +28,7 @@ import com.android.messaging.datamodel.DatabaseHelper.MessageColumns; import com.android.messaging.datamodel.DatabaseWrapper; import com.android.messaging.datamodel.MessagingContentProvider; import com.android.messaging.sms.MmsUtils; +import com.android.messaging.mmslib.pdu.PduHeaders; import com.android.messaging.util.LogUtil; /** @@ -60,9 +61,9 @@ public class MarkAsReadAction extends Action implements Parcelable { // Mark all messages in thread as read in telephony final long threadId = BugleDatabaseOperations.getThreadId(db, conversationId); if (threadId != -1) { + MmsUtils.sendMmsReadReport(threadId, PduHeaders.READ_STATUS_READ); MmsUtils.updateSmsReadStatus(threadId, Long.MAX_VALUE); } - // Update local db db.beginTransaction(); try { diff --git a/src/com/android/messaging/datamodel/action/ProcessDownloadedMmsAction.java b/src/com/android/messaging/datamodel/action/ProcessDownloadedMmsAction.java index 93f738f..7332153 100644 --- a/src/com/android/messaging/datamodel/action/ProcessDownloadedMmsAction.java +++ b/src/com/android/messaging/datamodel/action/ProcessDownloadedMmsAction.java @@ -464,6 +464,9 @@ public class ProcessDownloadedMmsAction extends Action { // TODO: Also write these values to the telephony provider mms.mRead = messageInFocusedConversation; mms.mSeen = messageInObservableConversation; + if (messageInFocusedConversation) { + MmsUtils.sendMmsReadReport(mms.mThreadId, PduHeaders.READ_STATUS_READ); + } // Translate to our format message = MmsUtils.createMmsMessage(mms, conversationId, senderParticipantId, @@ -534,6 +537,9 @@ public class ProcessDownloadedMmsAction extends Action { values.put(Mms.READ, messageInFocusedConversation); SqliteWrapper.update(context, context.getContentResolver(), mmsUri, values, null, null); + if (messageInFocusedConversation) { + MmsUtils.sendMmsReadReport(mms.mThreadId, PduHeaders.READ_STATUS_READ); + } } // Show a notification to let the user know a new message has arrived diff --git a/src/com/android/messaging/datamodel/action/ReceiveMmsMessageAction.java b/src/com/android/messaging/datamodel/action/ReceiveMmsMessageAction.java index 4ebc8b4..f21e062 100644 --- a/src/com/android/messaging/datamodel/action/ReceiveMmsMessageAction.java +++ b/src/com/android/messaging/datamodel/action/ReceiveMmsMessageAction.java @@ -101,6 +101,9 @@ public class ReceiveMmsMessageAction extends Action implements Parcelable { // TODO: Also write these values to the telephony provider mms.mRead = messageInFocusedConversation; mms.mSeen = messageInObservableConversation || blocked; + if (messageInFocusedConversation) { + MmsUtils.sendMmsReadReport(mms.mThreadId, PduHeaders.READ_STATUS_READ); + } // Write received placeholder message to our DB db.beginTransaction(); diff --git a/src/com/android/messaging/datamodel/data/MessageData.java b/src/com/android/messaging/datamodel/data/MessageData.java index a3698a9..01bb382 100644 --- a/src/com/android/messaging/datamodel/data/MessageData.java +++ b/src/com/android/messaging/datamodel/data/MessageData.java @@ -130,6 +130,7 @@ public class MessageData implements Parcelable { public static final int BUGLE_STATUS_OUTGOING_AWAITING_RETRY = 7; public static final int BUGLE_STATUS_OUTGOING_FAILED = 8; public static final int BUGLE_STATUS_OUTGOING_FAILED_EMERGENCY_NUMBER = 9; + public static final int BUGLE_STATUS_OUTGOING_COMPLETE_AND_READ = 10; // Incoming public static final int BUGLE_STATUS_INCOMING_COMPLETE = 100; @@ -179,6 +180,8 @@ public class MessageData implements Parcelable { return "INCOMING_DOWNLOAD_FAILED"; case BUGLE_STATUS_INCOMING_EXPIRED_OR_NOT_AVAILABLE: return "INCOMING_EXPIRED_OR_NOT_AVAILABLE"; + case BUGLE_STATUS_OUTGOING_COMPLETE_AND_READ: + return "OUTGOING_COMPLETE_AND_READ"; default: return String.valueOf(status) + " (check MessageData)"; } diff --git a/src/com/android/messaging/sms/MmsSender.java b/src/com/android/messaging/sms/MmsSender.java index 6dfa81a..e0b295b 100644 --- a/src/com/android/messaging/sms/MmsSender.java +++ b/src/com/android/messaging/sms/MmsSender.java @@ -22,6 +22,7 @@ import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Bundle; +import android.provider.Telephony; import android.support.v7.mms.MmsManager; import android.telephony.SmsManager; @@ -29,6 +30,7 @@ import com.android.messaging.datamodel.MmsFileProvider; import com.android.messaging.datamodel.action.SendMessageAction; import com.android.messaging.datamodel.data.MessageData; import com.android.messaging.mmslib.InvalidHeaderValueException; +import com.android.messaging.mmslib.MmsException; import com.android.messaging.mmslib.pdu.AcknowledgeInd; import com.android.messaging.mmslib.pdu.EncodedStringValue; import com.android.messaging.mmslib.pdu.GenericPdu; @@ -36,6 +38,8 @@ import com.android.messaging.mmslib.pdu.NotifyRespInd; import com.android.messaging.mmslib.pdu.PduComposer; import com.android.messaging.mmslib.pdu.PduHeaders; import com.android.messaging.mmslib.pdu.PduParser; +import com.android.messaging.mmslib.pdu.PduPersister; +import com.android.messaging.mmslib.pdu.ReadRecInd; import com.android.messaging.mmslib.pdu.RetrieveConf; import com.android.messaging.mmslib.pdu.SendConf; import com.android.messaging.mmslib.pdu.SendReq; @@ -309,4 +313,32 @@ public class MmsSender { return MmsUtils.MMS_REQUEST_MANUAL_RETRY; } } + + public static void sendReadReceipt(final Context context, final String to, final int subId, + final String subPhoneNumber, final String messageId, final int status) { + String selfNumber = PhoneUtils.get(subId).getCanonicalForSelf(true/*allowOverride*/); + EncodedStringValue[] sender = new EncodedStringValue[1]; + sender[0] = new EncodedStringValue(to); + try { + final ReadRecInd readRec = new ReadRecInd( + new EncodedStringValue(PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR.getBytes()), + messageId.getBytes(), + PduHeaders.CURRENT_MMS_VERSION, + status, + sender); + + readRec.setDate(System.currentTimeMillis() / 1000); + readRec.setFrom(new EncodedStringValue(selfNumber)); + PduPersister persister = PduPersister.getPduPersister(context); + Uri messageUri = persister.persist(readRec, Telephony.Mms.Sent.CONTENT_URI, subId, subPhoneNumber, + null); + MmsSender.sendMms(context, subId, messageUri, null, readRec, false, null); + } catch (InvalidHeaderValueException e) { + LogUtil.e(TAG, "Invalide header value", e); + } catch (MmsException e) { + LogUtil.e(TAG, "Persist message failed", e); + } catch (MmsFailureException e) { + LogUtil.e(TAG, "Persist message failed", e); + } + } } diff --git a/src/com/android/messaging/sms/MmsUtils.java b/src/com/android/messaging/sms/MmsUtils.java index b819fc4..0728639 100644 --- a/src/com/android/messaging/sms/MmsUtils.java +++ b/src/com/android/messaging/sms/MmsUtils.java @@ -1431,6 +1431,42 @@ public class MmsUtils { return deleted; } + public static void sendMmsReadReport(final long threadId, final int status) { + final Context context = Factory.get().getApplicationContext(); + final DatabaseWrapper db = DataModel.get().getDatabase(); + List recipients = null; + String selection = Mms.MESSAGE_TYPE + " = " + PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF + + " AND " + Mms.READ + " = 0" + + " AND " + Mms.READ_REPORT + " = " + PduHeaders.VALUE_YES + + " AND " + Mms.THREAD_ID + " = ?"; + + if (threadId != -1) { + recipients = MmsUtils.getRecipientsByThread(threadId); + } + + final String[] projection = new String[] { Mms._ID, Mms.MESSAGE_ID, Mms.SUBSCRIPTION_ID }; + final Cursor c = SqliteWrapper.query(context, context.getContentResolver(), + Mms.Inbox.CONTENT_URI, projection, selection, + new String[]{String.valueOf(threadId)}, null); + try { + if (c == null || c.getCount() == 0) { + return; + } + while (c.moveToNext()) { + Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, c.getLong(0)); + String from = MmsUtils.getMmsSender(recipients, uri.toString()); + final ParticipantData self = BugleDatabaseOperations.getOrCreateSelf(db, c.getInt(2)); + MmsSender.sendReadReceipt(context, from, c.getInt(2), + self.getNormalizedDestination(), c.getString(1), status); + } + } finally { + if (c != null) { + c.close(); + } + } + + } + /** * Update the read status of SMS/MMS messages by thread and timestamp * @@ -2329,11 +2365,11 @@ public class MmsUtils { Uri messageUri = null; long threadId = -1; switch (type) { - case PduHeaders.MESSAGE_TYPE_DELIVERY_IND: { + case PduHeaders.MESSAGE_TYPE_DELIVERY_IND: + case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND: { long localId = -1; - String messageId = new String(((DeliveryInd) pdu).getMessageId()); //Update Telephony DB - Cursor cursor = getCursorFromMessageId(context, messageId); + Cursor cursor = getCursorFromMessageId(context, pdu, type); if (cursor != null) { try { if ((cursor.getCount() == 1) && cursor.moveToFirst()) { @@ -2353,7 +2389,7 @@ public class MmsUtils { try { inboxUri = p.persist(pdu, Mms.Inbox.CONTENT_URI, subId, subPhoneNumber, null); - // Update thread ID for ReadOrigInd & DeliveryInd. + // Update thread ID for DeliveryInd. ContentValues values = new ContentValues(1); values.put(Mms.THREAD_ID, threadId); SqliteWrapper.update(context, context.getContentResolver(), inboxUri, values, @@ -2365,48 +2401,43 @@ public class MmsUtils { final DatabaseWrapper db = DataModel.get().getDatabase(); db.beginTransaction(); try { - int status = ((DeliveryInd) pdu).getStatus(); - if (status == PduHeaders.STATUS_RETRIEVED || - status == PduHeaders.STATUS_FORWARDED) { + int status = 0; + if (type == PduHeaders.MESSAGE_TYPE_DELIVERY_IND) { + status = ((DeliveryInd) pdu).getStatus(); + if (status == PduHeaders.STATUS_RETRIEVED || + status == PduHeaders.STATUS_FORWARDED) { + status = MessageData.BUGLE_STATUS_OUTGOING_DELIVERED; + } + } else { + status = ((ReadOrigInd) pdu).getReadStatus(); + if (status == PduHeaders.READ_STATUS_READ) { + status = MessageData.BUGLE_STATUS_OUTGOING_COMPLETE_AND_READ; + } + } + if (status == MessageData.BUGLE_STATUS_OUTGOING_DELIVERED || + status == MessageData.BUGLE_STATUS_OUTGOING_COMPLETE_AND_READ) { final ContentValues values = new ContentValues(); - status = MessageData.BUGLE_STATUS_OUTGOING_DELIVERED; values.put(DatabaseHelper.MessageColumns.STATUS, status); Uri mUri = Uri.withAppendedPath(Mms.CONTENT_URI, String.valueOf(localId)); final MessageData messageData = BugleDatabaseOperations.readMessageData(db, mUri); // Check the message was not removed before the delivery report comes in if (messageData != null) { + LogUtil.e(TAG, "Check for URI path : " + mUri.equals( + messageData.getSmsMessageUri())); // Row must exist as was just loaded above (on ActionService thread) BugleDatabaseOperations.updateMessageRow(db, messageData.getMessageId(), values); MessagingContentProvider.notifyMessagesChanged( messageData.getConversationId()); } - db.setTransactionSuccessful(); } + db.setTransactionSuccessful(); } finally { db.endTransaction(); } break; } - case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND: { - // TODO: Should this be commented out? -// threadId = findThreadId(context, pdu, type); -// if (threadId == -1) { -// // The associated SendReq isn't found, therefore skip -// // processing this PDU. -// break; -// } - -// Uri uri = p.persist(pdu, Inbox.CONTENT_URI, true, -// MessagingPreferenceActivity.getIsGroupMmsEnabled(mContext), null); -// // Update thread ID for ReadOrigInd & DeliveryInd. -// ContentValues values = new ContentValues(1); -// values.put(Mms.THREAD_ID, threadId); -// SqliteWrapper.update(mContext, cr, uri, values, null, null); - LogUtil.w(TAG, "Received unsupported WAP Push, type=" + type); - break; - } case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND: { final NotificationInd nInd = (NotificationInd) pdu; @@ -2472,7 +2503,13 @@ public class MmsUtils { return mms; } - private static Cursor getCursorFromMessageId(Context context, String messageId) { + private static Cursor getCursorFromMessageId(Context context, GenericPdu pdu, int type) { + String messageId; + if (type == PduHeaders.MESSAGE_TYPE_DELIVERY_IND) { + messageId = new String(((DeliveryInd) pdu).getMessageId()); + } else { + messageId = new String(((ReadOrigInd) pdu).getMessageId()); + } StringBuilder sb = new StringBuilder('('); sb.append(Mms.MESSAGE_ID); sb.append('='); diff --git a/src/com/android/messaging/ui/conversation/MessageDetailsDialog.java b/src/com/android/messaging/ui/conversation/MessageDetailsDialog.java index 89b9148..6e0b94e 100644 --- a/src/com/android/messaging/ui/conversation/MessageDetailsDialog.java +++ b/src/com/android/messaging/ui/conversation/MessageDetailsDialog.java @@ -27,6 +27,7 @@ import com.android.messaging.Factory; import com.android.messaging.R; import com.android.messaging.datamodel.BugleDatabaseOperations; import com.android.messaging.datamodel.DataModel; +import com.android.messaging.datamodel.data.MessageData; import com.android.messaging.datamodel.data.ConversationMessageData; import com.android.messaging.datamodel.data.ConversationParticipantsData; import com.android.messaging.datamodel.data.ParticipantData; @@ -206,6 +207,12 @@ public class MessageDetailsDialog { appendSimInfo(res, self, details); + if (data.getStatus() == MessageData.BUGLE_STATUS_OUTGOING_COMPLETE_AND_READ) { + details.append('\n'); + details.append(res.getString(R.string.status_label)); + details.append(res.getString(R.string.status_read)); + } + if (DebugUtils.isDebugEnabled()) { appendDebugInfo(details, data); } -- cgit v1.2.3