From d02b0b273f4915d1873bbb5472492380451b84ff Mon Sep 17 00:00:00 2001 From: Tom Taylor Date: Tue, 28 Aug 2012 16:20:07 -0700 Subject: Support group mms Bug 6282172 Add some logging code (turned off) to the pdu parser to make it easy to see what's in the pdu. When we're looking for a thread that an incoming message belongs to, use all the recipients the message was addressed to. Change-Id: I791c9594d9645903bb392f0fb29dc8522159c424 --- src/java/com/google/android/mms/pdu/PduParser.java | 97 +++++++++++++++++++++- .../com/google/android/mms/pdu/PduPersister.java | 47 ++++++++--- 2 files changed, 133 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/java/com/google/android/mms/pdu/PduParser.java b/src/java/com/google/android/mms/pdu/PduParser.java index 015d864..b42a9fd 100755 --- a/src/java/com/google/android/mms/pdu/PduParser.java +++ b/src/java/com/google/android/mms/pdu/PduParser.java @@ -19,6 +19,7 @@ package com.google.android.mms.pdu; import com.google.android.mms.ContentType; import com.google.android.mms.InvalidHeaderValueException; +import com.google.android.mms.pdu.EncodedStringValue; import android.util.Log; @@ -135,20 +136,35 @@ public class PduParser { switch (messageType) { case PduHeaders.MESSAGE_TYPE_SEND_REQ: + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parse: MESSAGE_TYPE_SEND_REQ"); + } SendReq sendReq = new SendReq(mHeaders, mBody); return sendReq; case PduHeaders.MESSAGE_TYPE_SEND_CONF: + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parse: MESSAGE_TYPE_SEND_CONF"); + } SendConf sendConf = new SendConf(mHeaders); return sendConf; case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND: + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parse: MESSAGE_TYPE_NOTIFICATION_IND"); + } NotificationInd notificationInd = new NotificationInd(mHeaders); return notificationInd; case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND: + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parse: MESSAGE_TYPE_NOTIFYRESP_IND"); + } NotifyRespInd notifyRespInd = new NotifyRespInd(mHeaders); return notifyRespInd; case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF: + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parse: MESSAGE_TYPE_RETRIEVE_CONF"); + } RetrieveConf retrieveConf = new RetrieveConf(mHeaders, mBody); @@ -174,18 +190,30 @@ public class PduParser { } return null; case PduHeaders.MESSAGE_TYPE_DELIVERY_IND: + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parse: MESSAGE_TYPE_DELIVERY_IND"); + } DeliveryInd deliveryInd = new DeliveryInd(mHeaders); return deliveryInd; case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND: + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parse: MESSAGE_TYPE_ACKNOWLEDGE_IND"); + } AcknowledgeInd acknowledgeInd = new AcknowledgeInd(mHeaders); return acknowledgeInd; case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND: + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parse: MESSAGE_TYPE_READ_ORIG_IND"); + } ReadOrigInd readOrigInd = new ReadOrigInd(mHeaders); return readOrigInd; case PduHeaders.MESSAGE_TYPE_READ_REC_IND: + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parse: MESSAGE_TYPE_READ_REC_IND"); + } ReadRecInd readRecInd = new ReadRecInd(mHeaders); return readRecInd; @@ -205,7 +233,6 @@ public class PduParser { if (pduDataStream == null) { return null; } - boolean keepParsing = true; PduHeaders headers = new PduHeaders(); @@ -226,6 +253,9 @@ public class PduParser { case PduHeaders.MESSAGE_TYPE: { int messageType = extractByteValue(pduDataStream); + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parseHeaders: messageType: " + messageType); + } switch (messageType) { // We don't support these kind of messages now. case PduHeaders.MESSAGE_TYPE_FORWARD_REQ: @@ -287,6 +317,10 @@ public class PduParser { case PduHeaders.RESPONSE_STATUS: { int value = extractByteValue(pduDataStream); + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parseHeaders: byte: " + headerField + " value: " + + value); + } try { headers.setOctet(value, headerField); @@ -308,6 +342,10 @@ public class PduParser { { try { long value = parseLongInteger(pduDataStream); + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parseHeaders: longint: " + headerField + " value: " + + value); + } headers.setLongInteger(value, headerField); } catch(RuntimeException e) { log(headerField + "is not Long-Integer header field!"); @@ -323,6 +361,10 @@ public class PduParser { { try { long value = parseIntegerValue(pduDataStream); + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parseHeaders: int: " + headerField + " value: " + + value); + } headers.setLongInteger(value, headerField); } catch(RuntimeException e) { log(headerField + "is not Long-Integer header field!"); @@ -355,6 +397,10 @@ public class PduParser { byte[] value = parseWapString(pduDataStream, TYPE_TEXT_STRING); if (null != value) { try { + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parseHeaders: string: " + headerField + " value: " + + new String(value)); + } headers.setTextString(value, headerField); } catch(NullPointerException e) { log("null pointer error!"); @@ -380,6 +426,10 @@ public class PduParser { parseEncodedStringValue(pduDataStream); if (null != value) { try { + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parseHeaders: encoded string: " + headerField + + " value: " + value.getString()); + } headers.setEncodedStringValue(value, headerField); } catch(NullPointerException e) { log("null pointer error!"); @@ -402,6 +452,10 @@ public class PduParser { byte[] address = value.getTextString(); if (null != address) { String str = new String(address); + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parseHeaders: (to/cc/bcc) address: " + headerField + + " value: " + str); + } int endIndex = str.indexOf("/"); if (endIndex > 0) { str = str.substring(0, endIndex); @@ -453,6 +507,10 @@ public class PduParser { } try { + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parseHeaders: time value: " + headerField + + " value: " + timeValue); + } headers.setLongInteger(timeValue, headerField); } catch(RuntimeException e) { log(headerField + "is not Long-Integer header field!"); @@ -503,6 +561,10 @@ public class PduParser { } try { + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parseHeaders: from address: " + headerField + + " value: " + from.getString()); + } headers.setEncodedStringValue(from, PduHeaders.FROM); } catch(NullPointerException e) { log("null pointer error!"); @@ -517,6 +579,10 @@ public class PduParser { /* Message-class-value = Class-identifier | Token-text */ pduDataStream.mark(1); int messageClass = extractByteValue(pduDataStream); + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parseHeaders: MESSAGE_CLASS: " + headerField + + " value: " + messageClass); + } if (messageClass >= PduHeaders.MESSAGE_CLASS_PERSONAL) { /* Class-identifier */ @@ -566,6 +632,10 @@ public class PduParser { int version = parseShortInteger(pduDataStream); try { + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parseHeaders: MMS_VERSION: " + headerField + + " value: " + version); + } headers.setOctet(version, PduHeaders.MMS_VERSION); } catch(InvalidHeaderValueException e) { log("Set invalid Octet value: " + version + @@ -597,6 +667,10 @@ public class PduParser { parseEncodedStringValue(pduDataStream); if (null != previouslySentBy) { try { + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parseHeaders: PREVIOUSLY_SENT_BY: " + headerField + + " value: " + previouslySentBy.getString()); + } headers.setEncodedStringValue(previouslySentBy, PduHeaders.PREVIOUSLY_SENT_BY); } catch(NullPointerException e) { @@ -626,6 +700,10 @@ public class PduParser { /* Date-value */ try { long perviouslySentDate = parseLongInteger(pduDataStream); + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parseHeaders: PREVIOUSLY_SENT_DATE: " + headerField + + " value: " + perviouslySentDate); + } headers.setLongInteger(perviouslySentDate, PduHeaders.PREVIOUSLY_SENT_DATE); } catch(RuntimeException e) { @@ -641,6 +719,10 @@ public class PduParser { * ( Add-token | Remove-token | Filter-token ) * Encoded-string-value */ + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parseHeaders: MM_FLAGS: " + headerField + + " NOT REALLY SUPPORTED"); + } /* parse Value-length */ parseValueLength(pduDataStream); @@ -661,6 +743,9 @@ public class PduParser { case PduHeaders.MBOX_TOTALS: case PduHeaders.MBOX_QUOTAS: { + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parseHeaders: MBOX_TOTALS: " + headerField); + } /* Value-length */ parseValueLength(pduDataStream); @@ -681,6 +766,9 @@ public class PduParser { } case PduHeaders.ELEMENT_DESCRIPTOR: { + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parseHeaders: ELEMENT_DESCRIPTOR: " + headerField); + } parseContentType(pduDataStream, null); /* not store this header filed in "headers", @@ -696,6 +784,10 @@ public class PduParser { if (null != contentType) { try { + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parseHeaders: CONTENT_TYPE: " + headerField + + contentType.toString()); + } headers.setTextString(contentType, PduHeaders.CONTENT_TYPE); } catch(NullPointerException e) { log("null pointer error!"); @@ -719,6 +811,9 @@ public class PduParser { case PduHeaders.ADDITIONAL_HEADERS: case PduHeaders.ATTRIBUTES: default: { + if (LOCAL_LOGV) { + Log.v(LOG_TAG, "parseHeaders: Unknown header: " + headerField); + } log("Unknown header"); } } diff --git a/src/java/com/google/android/mms/pdu/PduPersister.java b/src/java/com/google/android/mms/pdu/PduPersister.java index ee285aa..6568e0a 100644 --- a/src/java/com/google/android/mms/pdu/PduPersister.java +++ b/src/java/com/google/android/mms/pdu/PduPersister.java @@ -44,6 +44,8 @@ import android.provider.Telephony.Threads; import android.provider.Telephony.Mms.Addr; import android.provider.Telephony.Mms.Part; import android.provider.Telephony.MmsSms.PendingMessages; +import android.telephony.PhoneNumberUtils; +import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; @@ -279,11 +281,14 @@ public class PduPersister { private final Context mContext; private final ContentResolver mContentResolver; private final DrmManagerClient mDrmManagerClient; + private final TelephonyManager mTelephonyManager; private PduPersister(Context context) { mContext = context; mContentResolver = context.getContentResolver(); mDrmManagerClient = new DrmManagerClient(context); + mTelephonyManager = (TelephonyManager)context + .getSystemService(Context.TELEPHONY_SERVICE); } /** Get(or create if not exist) an instance of PduPersister */ @@ -1308,25 +1313,24 @@ public class PduPersister { if ((msgType == PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND) || (msgType == PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF) || (msgType == PduHeaders.MESSAGE_TYPE_SEND_REQ)) { - EncodedStringValue[] array = null; switch (msgType) { case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND: case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF: - array = addressMap.get(PduHeaders.FROM); + // For received messages, we want to associate this message with the thread + // composed of all the recipients. This includes the person who sent the + // message or the FROM field in addition to the other people the message + // was addressed to or the TO field. + loadRecipients(PduHeaders.FROM, recipients, addressMap); + loadRecipients(PduHeaders.TO, recipients, addressMap); break; case PduHeaders.MESSAGE_TYPE_SEND_REQ: - array = addressMap.get(PduHeaders.TO); + loadRecipients(PduHeaders.TO, recipients, addressMap); break; } - if (array != null) { - for (EncodedStringValue v : array) { - if (v != null) { - recipients.add(v.getString()); - } - } - } if (!recipients.isEmpty()) { + // Given all the recipients associated with this message, find (or create) the + // correct thread. long threadId = Threads.getOrCreateThreadId(mContext, recipients); values.put(Mms.THREAD_ID, threadId); } @@ -1387,6 +1391,29 @@ public class PduPersister { return res; } + /** + * For a given address type, extract the recipients from the headers. + * + * @param addressType can be PduHeaders.FROM or PduHeaders.TO + * @param recipients a HashSet that is loaded with the recipients from the FROM or TO headers + * @param addressMap a HashMap of the addresses from the ADDRESS_FIELDS header + */ + private void loadRecipients(int addressType, HashSet recipients, + HashMap addressMap) { + EncodedStringValue[] array = addressMap.get(addressType); + String myNumber = mTelephonyManager.getLine1Number(); + for (EncodedStringValue v : array) { + if (v != null) { + String number = v.getString(); + if ((myNumber == null || !PhoneNumberUtils.compare(number, myNumber)) && + !recipients.contains(number)) { + // Only add numbers which aren't my own number. + recipients.add(number); + } + } + } + } + /** * Move a PDU object from one location to another. * -- cgit v1.2.3