Loading android/app/src/com/android/bluetooth/map/BluetoothMapContent.java +97 −4 Original line number Diff line number Diff line Loading @@ -27,11 +27,14 @@ import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.PhoneLookup; import android.provider.Telephony.Mms; import android.provider.Telephony.Sms; import android.provider.Telephony.MmsSms; import android.provider.Telephony.CanonicalAddressesColumns; import android.provider.Telephony.Threads; import android.telephony.PhoneNumberUtils; import android.telephony.TelephonyManager; import android.text.util.Rfc822Token; import android.text.util.Rfc822Tokenizer; import android.text.TextUtils; import android.util.Log; import android.util.SparseArray; Loading Loading @@ -693,6 +696,14 @@ public class BluetoothMapContent { size = subject.length(); } else if (fi.mMsgType == FilterInfo.TYPE_MMS) { size = c.getInt(fi.mMmsColSize); //MMS complete size = attachment_size + subject length String subject = e.getSubject(); if (subject == null || subject.length() == 0 ) { // Handle setSubject if not done case setSubject(e, c, fi, ap); } if (subject != null && subject.length() != 0 ) size += subject.length(); } else if (fi.mMsgType == FilterInfo.TYPE_EMAIL || fi.mMsgType == FilterInfo.TYPE_IM) { size = c.getInt(fi.mMessageColSize); Loading Loading @@ -923,11 +934,18 @@ public class BluetoothMapContent { String address = null; if (fi.mMsgType == FilterInfo.TYPE_SMS) { int msgType = c.getInt(fi.mSmsColType); if (msgType == 1) { if (msgType == Sms.MESSAGE_TYPE_INBOX ) { address = fi.mPhoneNum; } else { address = c.getString(c.getColumnIndex(Sms.ADDRESS)); } if ((address == null) && msgType == Sms.MESSAGE_TYPE_DRAFT) { //Fetch address for Drafts folder from "canonical_address" table int threadIdInd = c.getColumnIndex(Sms.THREAD_ID); String threadIdStr = c.getString(threadIdInd); address = getCanonicalAddressSms(mResolver, Integer.valueOf(threadIdStr)); if(V) Log.v(TAG, "threadId = " + threadIdStr + " adress:" + address +"\n"); } } else if (fi.mMsgType == FilterInfo.TYPE_MMS) { long id = c.getLong(c.getColumnIndex(BaseColumns._ID)); address = getAddressMms(mResolver, id, MMS_TO); Loading Loading @@ -1271,6 +1289,10 @@ public class BluetoothMapContent { * caching. */ public static String getContactNameFromPhone(String phone, ContentResolver resolver) { String name = null; //Handle possible exception for empty phone address if (TextUtils.isEmpty(phone)) { return name; } Uri uri = Uri.withAppendedPath(PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI, Uri.encode(phone)); Loading @@ -1293,6 +1315,71 @@ public class BluetoothMapContent { } return name; } /** * Get SMS RecipientAddresses for DRAFT folder based on threadId * */ static public String getCanonicalAddressSms(ContentResolver r, int threadId) { String [] RECIPIENT_ID_PROJECTION = { Threads.RECIPIENT_IDS }; /* 1. Get Recipient Ids from Threads.CONTENT_URI 2. Get Recipient Address for corresponding Id from canonical-addresses table. */ //Uri sAllCanonical = Uri.parse("content://mms-sms/canonical-addresses"); Uri sAllCanonical = MmsSms.CONTENT_URI.buildUpon().appendPath("canonical-addresses").build(); Uri sAllThreadsUri = Threads.CONTENT_URI.buildUpon().appendQueryParameter("simple", "true").build(); Cursor cr = null; String recipientAddress = ""; String recipientIds = null; String whereClause = "_id="+threadId; if (V) Log.v(TAG, "whereClause is "+ whereClause); try { cr = r.query(sAllThreadsUri, RECIPIENT_ID_PROJECTION, whereClause, null, null); if (cr != null && cr.moveToFirst()) { recipientIds = cr.getString(0); if (V) Log.v(TAG, "cursor.getCount(): " + cr.getCount() + "recipientIds: " + recipientIds + "selection: "+ whereClause ); } } finally { if(cr != null) { cr.close(); cr = null; } } if (V) Log.v(TAG, "recipientIds with spaces: "+ recipientIds +"\n"); if(recipientIds != null) { String recipients[] = null; whereClause = ""; recipients = recipientIds.split(" "); for (String id: recipients) { if(whereClause.length() != 0) whereClause +=" OR "; whereClause +="_id="+id; } if (V) Log.v(TAG, "whereClause is "+ whereClause); try { cr = r.query(sAllCanonical , null, whereClause, null, null); if (cr != null && cr.moveToFirst()) { do { //TODO: Multiple Recipeints are appended with ";" for now. if(recipientAddress.length() != 0 ) recipientAddress+=";"; recipientAddress += cr.getString( cr.getColumnIndex(CanonicalAddressesColumns.ADDRESS)); } while(cr.moveToNext()); } } finally { if(cr != null) cr.close(); } } if(V) Log.v(TAG,"Final recipientAddress : "+ recipientAddress); return recipientAddress; } static public String getAddressMms(ContentResolver r, long id, int type) { String selection = new String("msg_id=" + id + " AND type=" + type); Loading Loading @@ -3224,10 +3311,13 @@ public class BluetoothMapContent { } private String setVCardFromPhoneNumber(BluetoothMapbMessage message, String phone, boolean incoming) { String phone, boolean incoming) { String contactId = null, contactName = null; String[] phoneNumbers = new String[1]; //Handle possible exception for empty phone address if (TextUtils.isEmpty(phone)) { return contactName; } // // Use only actual phone number, because the MCE cannot know which // number the message is from. Loading Loading @@ -3328,7 +3418,10 @@ public class BluetoothMapContent { msgBody = c.getString(c.getColumnIndex(Sms.BODY)); String phone = c.getString(c.getColumnIndex(Sms.ADDRESS)); if ((phone == null) && type == Sms.MESSAGE_TYPE_DRAFT) { //Fetch address for Drafts folder from "canonical_address" table phone = getCanonicalAddressSms(mResolver, threadId); } time = c.getLong(c.getColumnIndex(Sms.DATE)); if(type == 1) // Inbox message needs to set the vCard as originator setVCardFromPhoneNumber(message, phone, true); Loading android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java +60 −49 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ import android.telephony.TelephonyManager; import android.text.format.DateUtils; import android.util.Log; import android.util.Xml; import android.text.TextUtils; import org.xmlpull.v1.XmlSerializer; Loading Loading @@ -1371,9 +1372,9 @@ public class BluetoothMapContentObserver { // We shall only use the folder attribute, but can't remember // wether to set it to "deleted" or the name of the folder // from which the message have been deleted. // "old_folder" used only for MessageShift event Event evt = new Event(EVENT_TYPE_DELETE, id, BluetoothMapContract.FOLDER_NAME_DELETED, getSmsFolderName(msg.type), mSmsType); getSmsFolderName(msg.type), null, mSmsType); sendEvent(evt); msg.threadId = threadId; } else { // Undelete Loading Loading @@ -1403,9 +1404,9 @@ public class BluetoothMapContentObserver { } for (Msg msg : getMsgListSms().values()) { // "old_folder" used only for MessageShift event Event evt = new Event(EVENT_TYPE_DELETE, msg.id, BluetoothMapContract.FOLDER_NAME_DELETED, getSmsFolderName(msg.type), mSmsType); getSmsFolderName(msg.type), null, mSmsType); sendEvent(evt); listChanged = true; } Loading Loading @@ -1526,9 +1527,9 @@ public class BluetoothMapContentObserver { + msg.threadId); listChanged = true; if(threadId == DELETED_THREAD_ID) { // Message deleted // "old_folder" used only for MessageShift event Event evt = new Event(EVENT_TYPE_DELETE, id, BluetoothMapContract.FOLDER_NAME_DELETED, getMmsFolderName(msg.type), TYPE.MMS); getMmsFolderName(msg.type), null, TYPE.MMS); sendEvent(evt); msg.threadId = threadId; } else { // Undelete Loading Loading @@ -1558,9 +1559,9 @@ public class BluetoothMapContentObserver { if (c != null) c.close(); } for (Msg msg : getMsgListMms().values()) { // "old_folder" used only for MessageShift event Event evt = new Event(EVENT_TYPE_DELETE, msg.id, BluetoothMapContract.FOLDER_NAME_DELETED, getMmsFolderName(msg.type), TYPE.MMS); getMmsFolderName(msg.type), null, TYPE.MMS); sendEvent(evt); listChanged = true; } Loading Loading @@ -1669,8 +1670,9 @@ public class BluetoothMapContentObserver { */ if(deletedFolder != null && deletedFolder.getFolderId() == folderId) { Event evt = new Event(EVENT_TYPE_DELETE, msg.id, newFolder, oldFolder, mAccount.getType()); // "old_folder" used only for MessageShift event Event evt = new Event(EVENT_TYPE_DELETE, msg.id, oldFolder, null, mAccount.getType()); sendEvent(evt); } else if(sentFolder != null && sentFolder.getFolderId() == folderId Loading Loading @@ -1741,8 +1743,9 @@ public class BluetoothMapContentObserver { */ if (!msg.transparent) { Event evt = new Event(EVENT_TYPE_DELETE, msg.id, null, oldFolder, mAccount.getType()); // "old_folder" used only for MessageShift event Event evt = new Event(EVENT_TYPE_DELETE, msg.id, oldFolder, null, mAccount.getType()); sendEvent(evt); } } Loading Loading @@ -2505,6 +2508,11 @@ public class BluetoothMapContentObserver { if(msgBody == null) msgBody = ((BluetoothMapbMessageSms) msg).getSmsBody(); if (TextUtils.isEmpty(msgBody)) { Log.d(TAG, "PushMsg: Empty msgBody "); /* not allowed to push empty message */ throw new IllegalArgumentException("push EMPTY message: Invalid Body"); } /* We need to lock the SMS list while updating the database, * to avoid sending events on MCE initiated operation. */ Uri contentUri = Uri.parse(Sms.CONTENT_URI+ "/" + folder); Loading Loading @@ -2914,6 +2922,7 @@ public class BluetoothMapContentObserver { * The correct solution would be to create a service that will start based on * the intent, if BT is turned off. */ if (parts != null && parts.size() > 0) { for (int i = 0; i < msgInfo.parts; i++) { Intent intentDelivery, intentSent; Loading @@ -2922,7 +2931,8 @@ public class BluetoothMapContentObserver { * thereby get an intent for each msg part. * setType is needed to create different intents for each message id/ time stamp, * as the extras are not used when comparing. */ intentDelivery.setType("message/" + Long.toString(msgInfo.id) + msgInfo.timestamp + i); intentDelivery.setType("message/" + Long.toString(msgInfo.id) + msgInfo.timestamp + i); intentDelivery.putExtra(EXTRA_MESSAGE_SENT_HANDLE, msgInfo.id); intentDelivery.putExtra(EXTRA_MESSAGE_SENT_TIMESTAMP, msgInfo.timestamp); PendingIntent pendingIntentDelivery = PendingIntent.getBroadcast(mContext, 0, Loading Loading @@ -2952,6 +2962,7 @@ public class BluetoothMapContentObserver { smsMng.sendMultipartTextMessage(msgInfo.phone, null, parts, sentIntents, deliveryIntents); } } private class SmsBroadcastReceiver extends BroadcastReceiver { private final String[] ID_PROJECTION = new String[] { Sms._ID }; Loading Loading
android/app/src/com/android/bluetooth/map/BluetoothMapContent.java +97 −4 Original line number Diff line number Diff line Loading @@ -27,11 +27,14 @@ import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.PhoneLookup; import android.provider.Telephony.Mms; import android.provider.Telephony.Sms; import android.provider.Telephony.MmsSms; import android.provider.Telephony.CanonicalAddressesColumns; import android.provider.Telephony.Threads; import android.telephony.PhoneNumberUtils; import android.telephony.TelephonyManager; import android.text.util.Rfc822Token; import android.text.util.Rfc822Tokenizer; import android.text.TextUtils; import android.util.Log; import android.util.SparseArray; Loading Loading @@ -693,6 +696,14 @@ public class BluetoothMapContent { size = subject.length(); } else if (fi.mMsgType == FilterInfo.TYPE_MMS) { size = c.getInt(fi.mMmsColSize); //MMS complete size = attachment_size + subject length String subject = e.getSubject(); if (subject == null || subject.length() == 0 ) { // Handle setSubject if not done case setSubject(e, c, fi, ap); } if (subject != null && subject.length() != 0 ) size += subject.length(); } else if (fi.mMsgType == FilterInfo.TYPE_EMAIL || fi.mMsgType == FilterInfo.TYPE_IM) { size = c.getInt(fi.mMessageColSize); Loading Loading @@ -923,11 +934,18 @@ public class BluetoothMapContent { String address = null; if (fi.mMsgType == FilterInfo.TYPE_SMS) { int msgType = c.getInt(fi.mSmsColType); if (msgType == 1) { if (msgType == Sms.MESSAGE_TYPE_INBOX ) { address = fi.mPhoneNum; } else { address = c.getString(c.getColumnIndex(Sms.ADDRESS)); } if ((address == null) && msgType == Sms.MESSAGE_TYPE_DRAFT) { //Fetch address for Drafts folder from "canonical_address" table int threadIdInd = c.getColumnIndex(Sms.THREAD_ID); String threadIdStr = c.getString(threadIdInd); address = getCanonicalAddressSms(mResolver, Integer.valueOf(threadIdStr)); if(V) Log.v(TAG, "threadId = " + threadIdStr + " adress:" + address +"\n"); } } else if (fi.mMsgType == FilterInfo.TYPE_MMS) { long id = c.getLong(c.getColumnIndex(BaseColumns._ID)); address = getAddressMms(mResolver, id, MMS_TO); Loading Loading @@ -1271,6 +1289,10 @@ public class BluetoothMapContent { * caching. */ public static String getContactNameFromPhone(String phone, ContentResolver resolver) { String name = null; //Handle possible exception for empty phone address if (TextUtils.isEmpty(phone)) { return name; } Uri uri = Uri.withAppendedPath(PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI, Uri.encode(phone)); Loading @@ -1293,6 +1315,71 @@ public class BluetoothMapContent { } return name; } /** * Get SMS RecipientAddresses for DRAFT folder based on threadId * */ static public String getCanonicalAddressSms(ContentResolver r, int threadId) { String [] RECIPIENT_ID_PROJECTION = { Threads.RECIPIENT_IDS }; /* 1. Get Recipient Ids from Threads.CONTENT_URI 2. Get Recipient Address for corresponding Id from canonical-addresses table. */ //Uri sAllCanonical = Uri.parse("content://mms-sms/canonical-addresses"); Uri sAllCanonical = MmsSms.CONTENT_URI.buildUpon().appendPath("canonical-addresses").build(); Uri sAllThreadsUri = Threads.CONTENT_URI.buildUpon().appendQueryParameter("simple", "true").build(); Cursor cr = null; String recipientAddress = ""; String recipientIds = null; String whereClause = "_id="+threadId; if (V) Log.v(TAG, "whereClause is "+ whereClause); try { cr = r.query(sAllThreadsUri, RECIPIENT_ID_PROJECTION, whereClause, null, null); if (cr != null && cr.moveToFirst()) { recipientIds = cr.getString(0); if (V) Log.v(TAG, "cursor.getCount(): " + cr.getCount() + "recipientIds: " + recipientIds + "selection: "+ whereClause ); } } finally { if(cr != null) { cr.close(); cr = null; } } if (V) Log.v(TAG, "recipientIds with spaces: "+ recipientIds +"\n"); if(recipientIds != null) { String recipients[] = null; whereClause = ""; recipients = recipientIds.split(" "); for (String id: recipients) { if(whereClause.length() != 0) whereClause +=" OR "; whereClause +="_id="+id; } if (V) Log.v(TAG, "whereClause is "+ whereClause); try { cr = r.query(sAllCanonical , null, whereClause, null, null); if (cr != null && cr.moveToFirst()) { do { //TODO: Multiple Recipeints are appended with ";" for now. if(recipientAddress.length() != 0 ) recipientAddress+=";"; recipientAddress += cr.getString( cr.getColumnIndex(CanonicalAddressesColumns.ADDRESS)); } while(cr.moveToNext()); } } finally { if(cr != null) cr.close(); } } if(V) Log.v(TAG,"Final recipientAddress : "+ recipientAddress); return recipientAddress; } static public String getAddressMms(ContentResolver r, long id, int type) { String selection = new String("msg_id=" + id + " AND type=" + type); Loading Loading @@ -3224,10 +3311,13 @@ public class BluetoothMapContent { } private String setVCardFromPhoneNumber(BluetoothMapbMessage message, String phone, boolean incoming) { String phone, boolean incoming) { String contactId = null, contactName = null; String[] phoneNumbers = new String[1]; //Handle possible exception for empty phone address if (TextUtils.isEmpty(phone)) { return contactName; } // // Use only actual phone number, because the MCE cannot know which // number the message is from. Loading Loading @@ -3328,7 +3418,10 @@ public class BluetoothMapContent { msgBody = c.getString(c.getColumnIndex(Sms.BODY)); String phone = c.getString(c.getColumnIndex(Sms.ADDRESS)); if ((phone == null) && type == Sms.MESSAGE_TYPE_DRAFT) { //Fetch address for Drafts folder from "canonical_address" table phone = getCanonicalAddressSms(mResolver, threadId); } time = c.getLong(c.getColumnIndex(Sms.DATE)); if(type == 1) // Inbox message needs to set the vCard as originator setVCardFromPhoneNumber(message, phone, true); Loading
android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java +60 −49 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ import android.telephony.TelephonyManager; import android.text.format.DateUtils; import android.util.Log; import android.util.Xml; import android.text.TextUtils; import org.xmlpull.v1.XmlSerializer; Loading Loading @@ -1371,9 +1372,9 @@ public class BluetoothMapContentObserver { // We shall only use the folder attribute, but can't remember // wether to set it to "deleted" or the name of the folder // from which the message have been deleted. // "old_folder" used only for MessageShift event Event evt = new Event(EVENT_TYPE_DELETE, id, BluetoothMapContract.FOLDER_NAME_DELETED, getSmsFolderName(msg.type), mSmsType); getSmsFolderName(msg.type), null, mSmsType); sendEvent(evt); msg.threadId = threadId; } else { // Undelete Loading Loading @@ -1403,9 +1404,9 @@ public class BluetoothMapContentObserver { } for (Msg msg : getMsgListSms().values()) { // "old_folder" used only for MessageShift event Event evt = new Event(EVENT_TYPE_DELETE, msg.id, BluetoothMapContract.FOLDER_NAME_DELETED, getSmsFolderName(msg.type), mSmsType); getSmsFolderName(msg.type), null, mSmsType); sendEvent(evt); listChanged = true; } Loading Loading @@ -1526,9 +1527,9 @@ public class BluetoothMapContentObserver { + msg.threadId); listChanged = true; if(threadId == DELETED_THREAD_ID) { // Message deleted // "old_folder" used only for MessageShift event Event evt = new Event(EVENT_TYPE_DELETE, id, BluetoothMapContract.FOLDER_NAME_DELETED, getMmsFolderName(msg.type), TYPE.MMS); getMmsFolderName(msg.type), null, TYPE.MMS); sendEvent(evt); msg.threadId = threadId; } else { // Undelete Loading Loading @@ -1558,9 +1559,9 @@ public class BluetoothMapContentObserver { if (c != null) c.close(); } for (Msg msg : getMsgListMms().values()) { // "old_folder" used only for MessageShift event Event evt = new Event(EVENT_TYPE_DELETE, msg.id, BluetoothMapContract.FOLDER_NAME_DELETED, getMmsFolderName(msg.type), TYPE.MMS); getMmsFolderName(msg.type), null, TYPE.MMS); sendEvent(evt); listChanged = true; } Loading Loading @@ -1669,8 +1670,9 @@ public class BluetoothMapContentObserver { */ if(deletedFolder != null && deletedFolder.getFolderId() == folderId) { Event evt = new Event(EVENT_TYPE_DELETE, msg.id, newFolder, oldFolder, mAccount.getType()); // "old_folder" used only for MessageShift event Event evt = new Event(EVENT_TYPE_DELETE, msg.id, oldFolder, null, mAccount.getType()); sendEvent(evt); } else if(sentFolder != null && sentFolder.getFolderId() == folderId Loading Loading @@ -1741,8 +1743,9 @@ public class BluetoothMapContentObserver { */ if (!msg.transparent) { Event evt = new Event(EVENT_TYPE_DELETE, msg.id, null, oldFolder, mAccount.getType()); // "old_folder" used only for MessageShift event Event evt = new Event(EVENT_TYPE_DELETE, msg.id, oldFolder, null, mAccount.getType()); sendEvent(evt); } } Loading Loading @@ -2505,6 +2508,11 @@ public class BluetoothMapContentObserver { if(msgBody == null) msgBody = ((BluetoothMapbMessageSms) msg).getSmsBody(); if (TextUtils.isEmpty(msgBody)) { Log.d(TAG, "PushMsg: Empty msgBody "); /* not allowed to push empty message */ throw new IllegalArgumentException("push EMPTY message: Invalid Body"); } /* We need to lock the SMS list while updating the database, * to avoid sending events on MCE initiated operation. */ Uri contentUri = Uri.parse(Sms.CONTENT_URI+ "/" + folder); Loading Loading @@ -2914,6 +2922,7 @@ public class BluetoothMapContentObserver { * The correct solution would be to create a service that will start based on * the intent, if BT is turned off. */ if (parts != null && parts.size() > 0) { for (int i = 0; i < msgInfo.parts; i++) { Intent intentDelivery, intentSent; Loading @@ -2922,7 +2931,8 @@ public class BluetoothMapContentObserver { * thereby get an intent for each msg part. * setType is needed to create different intents for each message id/ time stamp, * as the extras are not used when comparing. */ intentDelivery.setType("message/" + Long.toString(msgInfo.id) + msgInfo.timestamp + i); intentDelivery.setType("message/" + Long.toString(msgInfo.id) + msgInfo.timestamp + i); intentDelivery.putExtra(EXTRA_MESSAGE_SENT_HANDLE, msgInfo.id); intentDelivery.putExtra(EXTRA_MESSAGE_SENT_TIMESTAMP, msgInfo.timestamp); PendingIntent pendingIntentDelivery = PendingIntent.getBroadcast(mContext, 0, Loading Loading @@ -2952,6 +2962,7 @@ public class BluetoothMapContentObserver { smsMng.sendMultipartTextMessage(msgInfo.phone, null, parts, sentIntents, deliveryIntents); } } private class SmsBroadcastReceiver extends BroadcastReceiver { private final String[] ID_PROJECTION = new String[] { Sms._ID }; Loading