1fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie/* 25a60e47497f21f64e6d79420dc4c56c1907df22akschulz * Copyright (C) 2014 Samsung System LSI 35a60e47497f21f64e6d79420dc4c56c1907df22akschulz * Licensed under the Apache License, Version 2.0 (the "License"); 45a60e47497f21f64e6d79420dc4c56c1907df22akschulz * you may not use this file except in compliance with the License. 55a60e47497f21f64e6d79420dc4c56c1907df22akschulz * You may obtain a copy of the License at 65a60e47497f21f64e6d79420dc4c56c1907df22akschulz * 75a60e47497f21f64e6d79420dc4c56c1907df22akschulz * http://www.apache.org/licenses/LICENSE-2.0 85a60e47497f21f64e6d79420dc4c56c1907df22akschulz * 95a60e47497f21f64e6d79420dc4c56c1907df22akschulz * Unless required by applicable law or agreed to in writing, software 105a60e47497f21f64e6d79420dc4c56c1907df22akschulz * distributed under the License is distributed on an "AS IS" BASIS, 115a60e47497f21f64e6d79420dc4c56c1907df22akschulz * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 125a60e47497f21f64e6d79420dc4c56c1907df22akschulz * See the License for the specific language governing permissions and 135a60e47497f21f64e6d79420dc4c56c1907df22akschulz * limitations under the License. 145a60e47497f21f64e6d79420dc4c56c1907df22akschulz */ 15fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xiepackage com.android.bluetooth.map; 16fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 175a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport android.annotation.TargetApi; 18fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.app.Activity; 19fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.app.PendingIntent; 20fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.content.BroadcastReceiver; 21326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bondeimport android.content.ContentProviderClient; 22fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.content.ContentResolver; 23fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.content.ContentUris; 24fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.content.ContentValues; 25fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.content.Context; 26fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.content.Intent; 27fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.content.IntentFilter; 28326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bondeimport android.content.IntentFilter.MalformedMimeTypeException; 29edb6da171b8b7a6f9d4aa5a773d734a464f1ec66Miao Chouimport android.content.pm.PackageManager; 30fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.database.ContentObserver; 31fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.database.Cursor; 320905a86a66d6754469c00b5d154ffafe35f630b7Ajay Panickerimport android.database.sqlite.SQLiteException; 33fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.net.Uri; 34edb6da171b8b7a6f9d4aa5a773d734a464f1ec66Miao Chouimport android.os.Binder; 35fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.os.Handler; 365a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport android.os.Looper; 37326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bondeimport android.os.Message; 38326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bondeimport android.os.ParcelFileDescriptor; 39edb6da171b8b7a6f9d4aa5a773d734a464f1ec66Miao Chouimport android.os.Process; 40326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bondeimport android.os.RemoteException; 41db8d8ae565b3db6a5e3187170dcb7b281a79f9daAjay Panickerimport android.os.UserManager; 42fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.provider.Telephony; 43fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.provider.Telephony.Mms; 44fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.provider.Telephony.MmsSms; 45fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.provider.Telephony.Sms; 46fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.provider.Telephony.Sms.Inbox; 47fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.telephony.PhoneStateListener; 48fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.telephony.ServiceState; 49fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.telephony.SmsManager; 50fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.telephony.SmsMessage; 51fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.telephony.TelephonyManager; 52326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bondeimport android.text.format.DateUtils; 53eb7b90f5b93db1230a5b64caa3d8d05a642e33a6Marie Janssenimport android.text.TextUtils; 54fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.util.Log; 55fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.util.Xml; 565a60e47497f21f64e6d79420dc4c56c1907df22akschulz 575a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport org.xmlpull.v1.XmlSerializer; 58fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 59fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport com.android.bluetooth.map.BluetoothMapUtils.TYPE; 605a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport com.android.bluetooth.map.BluetoothMapbMessageMime.MimePart; 615a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport com.android.bluetooth.mapapi.BluetoothMapContract; 625a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport com.android.bluetooth.mapapi.BluetoothMapContract.MessageColumns; 63fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport com.google.android.mms.pdu.PduHeaders; 64fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 655a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport java.io.FileNotFoundException; 665a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport java.io.FileOutputStream; 675a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport java.io.IOException; 685a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport java.io.OutputStream; 695a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport java.io.StringWriter; 705a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport java.io.UnsupportedEncodingException; 715a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport java.util.ArrayList; 725a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport java.util.Arrays; 735a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport java.util.Calendar; 745a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport java.util.Collections; 755a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport java.util.HashMap; 765a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport java.util.HashSet; 775a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport java.util.Map; 785a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport java.util.Set; 795a60e47497f21f64e6d79420dc4c56c1907df22akschulz 805a60e47497f21f64e6d79420dc4c56c1907df22akschulzimport javax.obex.ResponseCodes; 815a60e47497f21f64e6d79420dc4c56c1907df22akschulz 825a60e47497f21f64e6d79420dc4c56c1907df22akschulz@TargetApi(19) 83fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xiepublic class BluetoothMapContentObserver { 84fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private static final String TAG = "BluetoothMapContentObserver"; 85fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 86326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private static final boolean D = BluetoothMapService.DEBUG; 87326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private static final boolean V = BluetoothMapService.VERBOSE; 88326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 895a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static final String EVENT_TYPE_NEW = "NewMessage"; 905a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static final String EVENT_TYPE_DELETE = "MessageDeleted"; 915a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static final String EVENT_TYPE_REMOVED = "MessageRemoved"; 925a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static final String EVENT_TYPE_SHIFT = "MessageShift"; 93326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private static final String EVENT_TYPE_DELEVERY_SUCCESS = "DeliverySuccess"; 94326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private static final String EVENT_TYPE_SENDING_SUCCESS = "SendingSuccess"; 95326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private static final String EVENT_TYPE_SENDING_FAILURE = "SendingFailure"; 96326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private static final String EVENT_TYPE_DELIVERY_FAILURE = "DeliveryFailure"; 975a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static final String EVENT_TYPE_READ_STATUS = "ReadStatusChanged"; 985a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static final String EVENT_TYPE_CONVERSATION = "ConversationChanged"; 995a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static final String EVENT_TYPE_PRESENCE = "ParticipantPresenceChanged"; 1005a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static final String EVENT_TYPE_CHAT_STATE = "ParticipantChatStateChanged"; 1015a60e47497f21f64e6d79420dc4c56c1907df22akschulz 1025a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static final long EVENT_FILTER_NEW_MESSAGE = 1L; 1035a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static final long EVENT_FILTER_MESSAGE_DELETED = 1L<<1; 1045a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static final long EVENT_FILTER_MESSAGE_SHIFT = 1L<<2; 1055a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static final long EVENT_FILTER_SENDING_SUCCESS = 1L<<3; 1065a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static final long EVENT_FILTER_SENDING_FAILED = 1L<<4; 1075a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static final long EVENT_FILTER_DELIVERY_SUCCESS = 1L<<5; 1085a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static final long EVENT_FILTER_DELIVERY_FAILED = 1L<<6; 1095a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static final long EVENT_FILTER_MEMORY_FULL = 1L<<7; // Unused 1105a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static final long EVENT_FILTER_MEMORY_AVAILABLE = 1L<<8; // Unused 1115a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static final long EVENT_FILTER_READ_STATUS_CHANGED = 1L<<9; 1125a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static final long EVENT_FILTER_CONVERSATION_CHANGED = 1L<<10; 1135a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static final long EVENT_FILTER_PARTICIPANT_PRESENCE_CHANGED = 1L<<11; 1145a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static final long EVENT_FILTER_PARTICIPANT_CHATSTATE_CHANGED= 1L<<12; 1155a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static final long EVENT_FILTER_MESSAGE_REMOVED = 1L<<13; 1165a60e47497f21f64e6d79420dc4c56c1907df22akschulz 1175a60e47497f21f64e6d79420dc4c56c1907df22akschulz // TODO: If we are requesting a large message from the network, on a slow connection 1185a60e47497f21f64e6d79420dc4c56c1907df22akschulz // 20 seconds might not be enough... But then again 20 seconds is long for other 1195a60e47497f21f64e6d79420dc4c56c1907df22akschulz // cases. 120326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private static final long PROVIDER_ANR_TIMEOUT = 20 * DateUtils.SECOND_IN_MILLIS; 121fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 122fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private Context mContext; 123fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private ContentResolver mResolver; 124326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private ContentProviderClient mProviderClient = null; 125fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private BluetoothMnsObexClient mMnsClient; 126326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private BluetoothMapMasInstance mMasInstance = null; 127fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private int mMasId; 128326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private boolean mEnableSmsMms = false; 129326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private boolean mObserverRegistered = false; 1305a60e47497f21f64e6d79420dc4c56c1907df22akschulz private BluetoothMapAccountItem mAccount; 131326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private String mAuthority = null; 132326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 1335a60e47497f21f64e6d79420dc4c56c1907df22akschulz // Default supported feature bit mask is 0x1f 1345a60e47497f21f64e6d79420dc4c56c1907df22akschulz private int mMapSupportedFeatures = BluetoothMapUtils.MAP_FEATURE_DEFAULT_BITMASK; 1355a60e47497f21f64e6d79420dc4c56c1907df22akschulz // Default event report version is 1.0 1365a60e47497f21f64e6d79420dc4c56c1907df22akschulz private int mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V10; 1375a60e47497f21f64e6d79420dc4c56c1907df22akschulz 138326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private BluetoothMapFolderElement mFolders = 139326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde new BluetoothMapFolderElement("DUMMY", null); // Will be set by the MAS when generated. 140326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private Uri mMessageUri = null; 1415a60e47497f21f64e6d79420dc4c56c1907df22akschulz private Uri mContactUri = null; 1425a60e47497f21f64e6d79420dc4c56c1907df22akschulz 1435a60e47497f21f64e6d79420dc4c56c1907df22akschulz private boolean mTransmitEvents = true; 1445a60e47497f21f64e6d79420dc4c56c1907df22akschulz 1455a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* To make the filter update atomic, we declare it volatile. 1465a60e47497f21f64e6d79420dc4c56c1907df22akschulz * To avoid a penalty when using it, copy the value to a local 1475a60e47497f21f64e6d79420dc4c56c1907df22akschulz * non-volatile variable when used more than once. 1485a60e47497f21f64e6d79420dc4c56c1907df22akschulz * Actually we only ever use the lower 4 bytes of this variable, 1495a60e47497f21f64e6d79420dc4c56c1907df22akschulz * hence we could manage without the volatile keyword, but as 1505a60e47497f21f64e6d79420dc4c56c1907df22akschulz * we tend to copy ways of doing things, we better do it right:-) */ 1515a60e47497f21f64e6d79420dc4c56c1907df22akschulz private volatile long mEventFilter = 0xFFFFFFFFL; 152fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 153fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public static final int DELETED_THREAD_ID = -1; 154fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 155326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // X-Mms-Message-Type field types. These are from PduHeaders.java 156fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public static final int MESSAGE_TYPE_RETRIEVE_CONF = 0x84; 157fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 158326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // Text only MMS converted to SMS if sms parts less than or equal to defined count 159326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private static final int CONVERT_MMS_TO_SMS_PART_COUNT = 10; 160326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 161fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private TYPE mSmsType; 162fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 163ed70219e41ba68196798dcbf75b782d13fb88603kschulz private static final String ACTION_MESSAGE_DELIVERY = 164ed70219e41ba68196798dcbf75b782d13fb88603kschulz "com.android.bluetooth.BluetoothMapContentObserver.action.MESSAGE_DELIVERY"; 165ed70219e41ba68196798dcbf75b782d13fb88603kschulz /*package*/ static final String ACTION_MESSAGE_SENT = 166ed70219e41ba68196798dcbf75b782d13fb88603kschulz "com.android.bluetooth.BluetoothMapContentObserver.action.MESSAGE_SENT"; 167ed70219e41ba68196798dcbf75b782d13fb88603kschulz 168ed70219e41ba68196798dcbf75b782d13fb88603kschulz public static final String EXTRA_MESSAGE_SENT_HANDLE = "HANDLE"; 169ed70219e41ba68196798dcbf75b782d13fb88603kschulz public static final String EXTRA_MESSAGE_SENT_RESULT = "result"; 170ed70219e41ba68196798dcbf75b782d13fb88603kschulz public static final String EXTRA_MESSAGE_SENT_MSG_TYPE = "type"; 171ed70219e41ba68196798dcbf75b782d13fb88603kschulz public static final String EXTRA_MESSAGE_SENT_URI = "uri"; 172ed70219e41ba68196798dcbf75b782d13fb88603kschulz public static final String EXTRA_MESSAGE_SENT_RETRY = "retry"; 173ed70219e41ba68196798dcbf75b782d13fb88603kschulz public static final String EXTRA_MESSAGE_SENT_TRANSPARENT = "transparent"; 174ed70219e41ba68196798dcbf75b782d13fb88603kschulz public static final String EXTRA_MESSAGE_SENT_TIMESTAMP = "timestamp"; 175ed70219e41ba68196798dcbf75b782d13fb88603kschulz 176ed70219e41ba68196798dcbf75b782d13fb88603kschulz private SmsBroadcastReceiver mSmsBroadcastReceiver = new SmsBroadcastReceiver(); 177725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker private CeBroadcastReceiver mCeBroadcastReceiver = new CeBroadcastReceiver(); 178ed70219e41ba68196798dcbf75b782d13fb88603kschulz 179725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker private boolean mStorageUnlocked = false; 180ed70219e41ba68196798dcbf75b782d13fb88603kschulz private boolean mInitialized = false; 181ed70219e41ba68196798dcbf75b782d13fb88603kschulz 182ed70219e41ba68196798dcbf75b782d13fb88603kschulz 183fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie static final String[] SMS_PROJECTION = new String[] { 184326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Sms._ID, 185fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Sms.THREAD_ID, 186fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Sms.ADDRESS, 187fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Sms.BODY, 188fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Sms.DATE, 189fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Sms.READ, 190fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Sms.TYPE, 191fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Sms.STATUS, 192fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Sms.LOCKED, 193326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Sms.ERROR_CODE 194fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie }; 195fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 196326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde static final String[] SMS_PROJECTION_SHORT = new String[] { 197326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Sms._ID, 198326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Sms.THREAD_ID, 1995a60e47497f21f64e6d79420dc4c56c1907df22akschulz Sms.TYPE, 2005a60e47497f21f64e6d79420dc4c56c1907df22akschulz Sms.READ 2015a60e47497f21f64e6d79420dc4c56c1907df22akschulz }; 2025a60e47497f21f64e6d79420dc4c56c1907df22akschulz 2035a60e47497f21f64e6d79420dc4c56c1907df22akschulz static final String[] SMS_PROJECTION_SHORT_EXT = new String[] { 2045a60e47497f21f64e6d79420dc4c56c1907df22akschulz Sms._ID, 2055a60e47497f21f64e6d79420dc4c56c1907df22akschulz Sms.THREAD_ID, 2065a60e47497f21f64e6d79420dc4c56c1907df22akschulz Sms.ADDRESS, 2075a60e47497f21f64e6d79420dc4c56c1907df22akschulz Sms.BODY, 2085a60e47497f21f64e6d79420dc4c56c1907df22akschulz Sms.DATE, 2095a60e47497f21f64e6d79420dc4c56c1907df22akschulz Sms.READ, 2105a60e47497f21f64e6d79420dc4c56c1907df22akschulz Sms.TYPE, 211326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde }; 212326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 213326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde static final String[] MMS_PROJECTION_SHORT = new String[] { 214326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Mms._ID, 215fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Mms.THREAD_ID, 216fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Mms.MESSAGE_TYPE, 2175a60e47497f21f64e6d79420dc4c56c1907df22akschulz Mms.MESSAGE_BOX, 2185a60e47497f21f64e6d79420dc4c56c1907df22akschulz Mms.READ 2195a60e47497f21f64e6d79420dc4c56c1907df22akschulz }; 2205a60e47497f21f64e6d79420dc4c56c1907df22akschulz 2215a60e47497f21f64e6d79420dc4c56c1907df22akschulz static final String[] MMS_PROJECTION_SHORT_EXT = new String[] { 2225a60e47497f21f64e6d79420dc4c56c1907df22akschulz Mms._ID, 2235a60e47497f21f64e6d79420dc4c56c1907df22akschulz Mms.THREAD_ID, 2245a60e47497f21f64e6d79420dc4c56c1907df22akschulz Mms.MESSAGE_TYPE, 2255a60e47497f21f64e6d79420dc4c56c1907df22akschulz Mms.MESSAGE_BOX, 2265a60e47497f21f64e6d79420dc4c56c1907df22akschulz Mms.READ, 2275a60e47497f21f64e6d79420dc4c56c1907df22akschulz Mms.DATE, 2285a60e47497f21f64e6d79420dc4c56c1907df22akschulz Mms.SUBJECT, 2295a60e47497f21f64e6d79420dc4c56c1907df22akschulz Mms.PRIORITY 230fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie }; 231fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2325a60e47497f21f64e6d79420dc4c56c1907df22akschulz static final String[] MSG_PROJECTION_SHORT = new String[] { 233326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde BluetoothMapContract.MessageColumns._ID, 234326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde BluetoothMapContract.MessageColumns.FOLDER_ID, 235326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde BluetoothMapContract.MessageColumns.FLAG_READ 236326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde }; 237326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 2385a60e47497f21f64e6d79420dc4c56c1907df22akschulz static final String[] MSG_PROJECTION_SHORT_EXT = new String[] { 2395a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns._ID, 2405a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns.FOLDER_ID, 2415a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns.FLAG_READ, 2425a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns.DATE, 2435a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns.SUBJECT, 2445a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns.FROM_LIST, 2455a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns.FLAG_HIGH_PRIORITY 2465a60e47497f21f64e6d79420dc4c56c1907df22akschulz }; 2475a60e47497f21f64e6d79420dc4c56c1907df22akschulz 2485a60e47497f21f64e6d79420dc4c56c1907df22akschulz static final String[] MSG_PROJECTION_SHORT_EXT2 = new String[] { 2495a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns._ID, 2505a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns.FOLDER_ID, 2515a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns.FLAG_READ, 2525a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns.DATE, 2535a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns.SUBJECT, 2545a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns.FROM_LIST, 2555a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns.FLAG_HIGH_PRIORITY, 2565a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns.THREAD_ID, 2575a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns.THREAD_NAME 2585a60e47497f21f64e6d79420dc4c56c1907df22akschulz }; 259326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 260326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde public BluetoothMapContentObserver(final Context context, 2615a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMnsObexClient mnsClient, 2625a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapMasInstance masInstance, 2635a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapAccountItem account, 2645a60e47497f21f64e6d79420dc4c56c1907df22akschulz boolean enableSmsMms) throws RemoteException { 265fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mContext = context; 266fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mResolver = mContext.getContentResolver(); 267326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mAccount = account; 268326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mMasInstance = masInstance; 269326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mMasId = mMasInstance.getMasId(); 2705a60e47497f21f64e6d79420dc4c56c1907df22akschulz 2715a60e47497f21f64e6d79420dc4c56c1907df22akschulz mMapSupportedFeatures = mMasInstance.getRemoteFeatureMask(); 2725a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (D) Log.d(TAG, "BluetoothMapContentObserver: Supported features " + 2735a60e47497f21f64e6d79420dc4c56c1907df22akschulz Integer.toHexString(mMapSupportedFeatures) ) ; 2745a60e47497f21f64e6d79420dc4c56c1907df22akschulz 2755a60e47497f21f64e6d79420dc4c56c1907df22akschulz if((BluetoothMapUtils.MAP_FEATURE_EXTENDED_EVENT_REPORT_11_BIT 2765a60e47497f21f64e6d79420dc4c56c1907df22akschulz & mMapSupportedFeatures) != 0){ 2775a60e47497f21f64e6d79420dc4c56c1907df22akschulz mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V11; 2785a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 2795a60e47497f21f64e6d79420dc4c56c1907df22akschulz // Make sure support for all formats result in latest version returned 2805a60e47497f21f64e6d79420dc4c56c1907df22akschulz if((BluetoothMapUtils.MAP_FEATURE_EVENT_REPORT_V12_BIT 2815a60e47497f21f64e6d79420dc4c56c1907df22akschulz & mMapSupportedFeatures) != 0){ 2825a60e47497f21f64e6d79420dc4c56c1907df22akschulz mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V12; 2835a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 2845a60e47497f21f64e6d79420dc4c56c1907df22akschulz 285326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(account != null) { 286326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mAuthority = Uri.parse(account.mBase_uri).getAuthority(); 287326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mMessageUri = Uri.parse(account.mBase_uri + "/" + BluetoothMapContract.TABLE_MESSAGE); 2885a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (mAccount.getType() == TYPE.IM) { 2895a60e47497f21f64e6d79420dc4c56c1907df22akschulz mContactUri = Uri.parse(account.mBase_uri + "/" 2905a60e47497f21f64e6d79420dc4c56c1907df22akschulz + BluetoothMapContract.TABLE_CONVOCONTACT); 2915a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 2925a60e47497f21f64e6d79420dc4c56c1907df22akschulz // TODO: We need to release this again! 293326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mProviderClient = mResolver.acquireUnstableContentProviderClient(mAuthority); 294326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (mProviderClient == null) { 295326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde throw new RemoteException("Failed to acquire provider for " + mAuthority); 296326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 297326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mProviderClient.setDetectNotResponding(PROVIDER_ANR_TIMEOUT); 2985a60e47497f21f64e6d79420dc4c56c1907df22akschulz mContactList = mMasInstance.getContactList(); 2995a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(mContactList == null) { 3005a60e47497f21f64e6d79420dc4c56c1907df22akschulz setContactList(new HashMap<String, BluetoothMapConvoContactElement>(), false); 3015a60e47497f21f64e6d79420dc4c56c1907df22akschulz initContactsList(); 3025a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 303326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 304326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mEnableSmsMms = enableSmsMms; 305fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mSmsType = getSmsType(); 306326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mMnsClient = mnsClient; 3075a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* Get the cached list - if any, else create */ 3085a60e47497f21f64e6d79420dc4c56c1907df22akschulz mMsgListSms = mMasInstance.getMsgListSms(); 3095a60e47497f21f64e6d79420dc4c56c1907df22akschulz boolean doInit = false; 3105a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(mEnableSmsMms) { 3115a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(mMsgListSms == null) { 3125a60e47497f21f64e6d79420dc4c56c1907df22akschulz setMsgListSms(new HashMap<Long, Msg>(), false); 3135a60e47497f21f64e6d79420dc4c56c1907df22akschulz doInit = true; 3145a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 3155a60e47497f21f64e6d79420dc4c56c1907df22akschulz mMsgListMms = mMasInstance.getMsgListMms(); 3165a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(mMsgListMms == null) { 3175a60e47497f21f64e6d79420dc4c56c1907df22akschulz setMsgListMms(new HashMap<Long, Msg>(), false); 3185a60e47497f21f64e6d79420dc4c56c1907df22akschulz doInit = true; 3195a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 3205a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 3215a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(mAccount != null) { 3225a60e47497f21f64e6d79420dc4c56c1907df22akschulz mMsgListMsg = mMasInstance.getMsgListMsg(); 3235a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(mMsgListMsg == null) { 3245a60e47497f21f64e6d79420dc4c56c1907df22akschulz setMsgListMsg(new HashMap<Long, Msg>(), false); 3255a60e47497f21f64e6d79420dc4c56c1907df22akschulz doInit = true; 3265a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 3275a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 3285a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(doInit) { 3295a60e47497f21f64e6d79420dc4c56c1907df22akschulz initMsgList(); 3305a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 3315a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 3325a60e47497f21f64e6d79420dc4c56c1907df22akschulz 333e6564029f132077c8a4877431a95899db201e506Ashwini Munigala public int getObserverRemoteFeatureMask() { 334e6564029f132077c8a4877431a95899db201e506Ashwini Munigala if (V) Log.v(TAG, "getObserverRemoteFeatureMask : " + mMapEventReportVersion 335e6564029f132077c8a4877431a95899db201e506Ashwini Munigala + " mMapSupportedFeatures: " + mMapSupportedFeatures); 336e6564029f132077c8a4877431a95899db201e506Ashwini Munigala return mMapSupportedFeatures; 337e6564029f132077c8a4877431a95899db201e506Ashwini Munigala } 338e6564029f132077c8a4877431a95899db201e506Ashwini Munigala 339e6564029f132077c8a4877431a95899db201e506Ashwini Munigala public void setObserverRemoteFeatureMask(int remoteSupportedFeatures) { 340e6564029f132077c8a4877431a95899db201e506Ashwini Munigala mMapSupportedFeatures = remoteSupportedFeatures; 341e6564029f132077c8a4877431a95899db201e506Ashwini Munigala if ((BluetoothMapUtils.MAP_FEATURE_EXTENDED_EVENT_REPORT_11_BIT 342e6564029f132077c8a4877431a95899db201e506Ashwini Munigala & mMapSupportedFeatures) != 0) { 343e6564029f132077c8a4877431a95899db201e506Ashwini Munigala mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V11; 344e6564029f132077c8a4877431a95899db201e506Ashwini Munigala } 345e6564029f132077c8a4877431a95899db201e506Ashwini Munigala // Make sure support for all formats result in latest version returned 346e6564029f132077c8a4877431a95899db201e506Ashwini Munigala if ((BluetoothMapUtils.MAP_FEATURE_EVENT_REPORT_V12_BIT 347e6564029f132077c8a4877431a95899db201e506Ashwini Munigala & mMapSupportedFeatures) != 0) { 348e6564029f132077c8a4877431a95899db201e506Ashwini Munigala mMapEventReportVersion = BluetoothMapUtils.MAP_EVENT_REPORT_V12; 349e6564029f132077c8a4877431a95899db201e506Ashwini Munigala } 350e6564029f132077c8a4877431a95899db201e506Ashwini Munigala if (V) Log.d(TAG, "setObserverRemoteFeatureMask : " + mMapEventReportVersion 351e6564029f132077c8a4877431a95899db201e506Ashwini Munigala + " mMapSupportedFeatures : " + mMapSupportedFeatures); 352e6564029f132077c8a4877431a95899db201e506Ashwini Munigala } 3535a60e47497f21f64e6d79420dc4c56c1907df22akschulz 3545a60e47497f21f64e6d79420dc4c56c1907df22akschulz private Map<Long, Msg> getMsgListSms() { 3555a60e47497f21f64e6d79420dc4c56c1907df22akschulz return mMsgListSms; 3565a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 3575a60e47497f21f64e6d79420dc4c56c1907df22akschulz 3585a60e47497f21f64e6d79420dc4c56c1907df22akschulz private void setMsgListSms(Map<Long, Msg> msgListSms, boolean changesDetected) { 3595a60e47497f21f64e6d79420dc4c56c1907df22akschulz mMsgListSms = msgListSms; 3605a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(changesDetected) { 3615a60e47497f21f64e6d79420dc4c56c1907df22akschulz mMasInstance.updateFolderVersionCounter(); 3625a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 3635a60e47497f21f64e6d79420dc4c56c1907df22akschulz mMasInstance.setMsgListSms(msgListSms); 3645a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 3655a60e47497f21f64e6d79420dc4c56c1907df22akschulz 3665a60e47497f21f64e6d79420dc4c56c1907df22akschulz 3675a60e47497f21f64e6d79420dc4c56c1907df22akschulz private Map<Long, Msg> getMsgListMms() { 3685a60e47497f21f64e6d79420dc4c56c1907df22akschulz return mMsgListMms; 3695a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 3705a60e47497f21f64e6d79420dc4c56c1907df22akschulz 3715a60e47497f21f64e6d79420dc4c56c1907df22akschulz 3725a60e47497f21f64e6d79420dc4c56c1907df22akschulz private void setMsgListMms(Map<Long, Msg> msgListMms, boolean changesDetected) { 3735a60e47497f21f64e6d79420dc4c56c1907df22akschulz mMsgListMms = msgListMms; 3745a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(changesDetected) { 3755a60e47497f21f64e6d79420dc4c56c1907df22akschulz mMasInstance.updateFolderVersionCounter(); 3765a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 3775a60e47497f21f64e6d79420dc4c56c1907df22akschulz mMasInstance.setMsgListMms(msgListMms); 378326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 379326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 3805a60e47497f21f64e6d79420dc4c56c1907df22akschulz 3815a60e47497f21f64e6d79420dc4c56c1907df22akschulz private Map<Long, Msg> getMsgListMsg() { 3825a60e47497f21f64e6d79420dc4c56c1907df22akschulz return mMsgListMsg; 3835a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 3845a60e47497f21f64e6d79420dc4c56c1907df22akschulz 3855a60e47497f21f64e6d79420dc4c56c1907df22akschulz 3865a60e47497f21f64e6d79420dc4c56c1907df22akschulz private void setMsgListMsg(Map<Long, Msg> msgListMsg, boolean changesDetected) { 3875a60e47497f21f64e6d79420dc4c56c1907df22akschulz mMsgListMsg = msgListMsg; 3885a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(changesDetected) { 3895a60e47497f21f64e6d79420dc4c56c1907df22akschulz mMasInstance.updateFolderVersionCounter(); 3905a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 3915a60e47497f21f64e6d79420dc4c56c1907df22akschulz mMasInstance.setMsgListMsg(msgListMsg); 3925a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 3935a60e47497f21f64e6d79420dc4c56c1907df22akschulz 3945a60e47497f21f64e6d79420dc4c56c1907df22akschulz private Map<String, BluetoothMapConvoContactElement> getContactList() { 3955a60e47497f21f64e6d79420dc4c56c1907df22akschulz return mContactList; 3965a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 3975a60e47497f21f64e6d79420dc4c56c1907df22akschulz 3985a60e47497f21f64e6d79420dc4c56c1907df22akschulz 399326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /** 4005a60e47497f21f64e6d79420dc4c56c1907df22akschulz * Currently we only have data for IM / email contacts 4015a60e47497f21f64e6d79420dc4c56c1907df22akschulz * @param contactList 4025a60e47497f21f64e6d79420dc4c56c1907df22akschulz * @param changesDetected that is not chat state changed nor presence state changed. 403326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde */ 4045a60e47497f21f64e6d79420dc4c56c1907df22akschulz private void setContactList(Map<String, BluetoothMapConvoContactElement> contactList, 4055a60e47497f21f64e6d79420dc4c56c1907df22akschulz boolean changesDetected) { 4065a60e47497f21f64e6d79420dc4c56c1907df22akschulz mContactList = contactList; 4075a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(changesDetected) { 4085a60e47497f21f64e6d79420dc4c56c1907df22akschulz mMasInstance.updateImEmailConvoListVersionCounter(); 4095a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 4105a60e47497f21f64e6d79420dc4c56c1907df22akschulz mMasInstance.setContactList(contactList); 4115a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 4125a60e47497f21f64e6d79420dc4c56c1907df22akschulz 4135a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static boolean sendEventNewMessage(long eventFilter) { 4145a60e47497f21f64e6d79420dc4c56c1907df22akschulz return ((eventFilter & EVENT_FILTER_NEW_MESSAGE) > 0); 4155a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 4165a60e47497f21f64e6d79420dc4c56c1907df22akschulz 4175a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static boolean sendEventMessageDeleted(long eventFilter) { 4185a60e47497f21f64e6d79420dc4c56c1907df22akschulz return ((eventFilter & EVENT_FILTER_MESSAGE_DELETED) > 0); 4195a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 4205a60e47497f21f64e6d79420dc4c56c1907df22akschulz 4215a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static boolean sendEventMessageShift(long eventFilter) { 4225a60e47497f21f64e6d79420dc4c56c1907df22akschulz return ((eventFilter & EVENT_FILTER_MESSAGE_SHIFT) > 0); 4235a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 4245a60e47497f21f64e6d79420dc4c56c1907df22akschulz 4255a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static boolean sendEventSendingSuccess(long eventFilter) { 4265a60e47497f21f64e6d79420dc4c56c1907df22akschulz return ((eventFilter & EVENT_FILTER_SENDING_SUCCESS) > 0); 4275a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 4285a60e47497f21f64e6d79420dc4c56c1907df22akschulz 4295a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static boolean sendEventSendingFailed(long eventFilter) { 4305a60e47497f21f64e6d79420dc4c56c1907df22akschulz return ((eventFilter & EVENT_FILTER_SENDING_FAILED) > 0); 4315a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 4325a60e47497f21f64e6d79420dc4c56c1907df22akschulz 4335a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static boolean sendEventDeliverySuccess(long eventFilter) { 4345a60e47497f21f64e6d79420dc4c56c1907df22akschulz return ((eventFilter & EVENT_FILTER_DELIVERY_SUCCESS) > 0); 4355a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 4365a60e47497f21f64e6d79420dc4c56c1907df22akschulz 4375a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static boolean sendEventDeliveryFailed(long eventFilter) { 4385a60e47497f21f64e6d79420dc4c56c1907df22akschulz return ((eventFilter & EVENT_FILTER_DELIVERY_FAILED) > 0); 4395a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 4405a60e47497f21f64e6d79420dc4c56c1907df22akschulz 4415a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static boolean sendEventReadStatusChanged(long eventFilter) { 4425a60e47497f21f64e6d79420dc4c56c1907df22akschulz return ((eventFilter & EVENT_FILTER_READ_STATUS_CHANGED) > 0); 4435a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 4445a60e47497f21f64e6d79420dc4c56c1907df22akschulz 4455a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static boolean sendEventConversationChanged(long eventFilter) { 4465a60e47497f21f64e6d79420dc4c56c1907df22akschulz return ((eventFilter & EVENT_FILTER_CONVERSATION_CHANGED) > 0); 4475a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 4485a60e47497f21f64e6d79420dc4c56c1907df22akschulz 4495a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static boolean sendEventParticipantPresenceChanged(long eventFilter) { 4505a60e47497f21f64e6d79420dc4c56c1907df22akschulz return ((eventFilter & EVENT_FILTER_PARTICIPANT_PRESENCE_CHANGED) > 0); 4515a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 4525a60e47497f21f64e6d79420dc4c56c1907df22akschulz 4535a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static boolean sendEventParticipantChatstateChanged(long eventFilter) { 4545a60e47497f21f64e6d79420dc4c56c1907df22akschulz return ((eventFilter & EVENT_FILTER_PARTICIPANT_CHATSTATE_CHANGED) > 0); 4555a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 4565a60e47497f21f64e6d79420dc4c56c1907df22akschulz 4575a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static boolean sendEventMessageRemoved(long eventFilter) { 4585a60e47497f21f64e6d79420dc4c56c1907df22akschulz return ((eventFilter & EVENT_FILTER_MESSAGE_REMOVED) > 0); 459fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 460fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 461fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private TYPE getSmsType() { 462fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie TYPE smsType = null; 4635a60e47497f21f64e6d79420dc4c56c1907df22akschulz TelephonyManager tm = (TelephonyManager) mContext.getSystemService( 4645a60e47497f21f64e6d79420dc4c56c1907df22akschulz Context.TELEPHONY_SERVICE); 465fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 4662e7dd83a6b3b4bf15e0dec6aad9ab826e6e2531bHemant Gupta if (tm.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA) { 467fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie smsType = TYPE.SMS_CDMA; 4682e7dd83a6b3b4bf15e0dec6aad9ab826e6e2531bHemant Gupta } else { 4692e7dd83a6b3b4bf15e0dec6aad9ab826e6e2531bHemant Gupta smsType = TYPE.SMS_GSM; 470fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 471fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 472fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return smsType; 473fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 474fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 475b6fdf260e28b4eb6b5cdb19f53710c0470ffcad2Hemant Gupta private final ContentObserver mObserver = new ContentObserver(new Handler()) { 476fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie @Override 477fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void onChange(boolean selfChange) { 478fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie onChange(selfChange, null); 479fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 480fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 481fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie @Override 482fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void onChange(boolean selfChange, Uri uri) { 4835a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(uri == null) { 4845a60e47497f21f64e6d79420dc4c56c1907df22akschulz Log.w(TAG, "onChange() with URI == null - not handled."); 4855a60e47497f21f64e6d79420dc4c56c1907df22akschulz return; 4865a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 487725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker 488725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker if (!mStorageUnlocked) { 489725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker Log.v(TAG, "Ignore events until storage is completely unlocked"); 490725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker return; 491725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker } 492725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker 493fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (V) Log.d(TAG, "onChange on thread: " + Thread.currentThread().getId() 4945a60e47497f21f64e6d79420dc4c56c1907df22akschulz + " Uri: " + uri.toString() + " selfchange: " + selfChange); 495fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 4965a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(uri.toString().contains(BluetoothMapContract.TABLE_CONVOCONTACT)) 4975a60e47497f21f64e6d79420dc4c56c1907df22akschulz handleContactListChanges(uri); 4985a60e47497f21f64e6d79420dc4c56c1907df22akschulz else 4995a60e47497f21f64e6d79420dc4c56c1907df22akschulz handleMsgListChanges(uri); 500fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 501fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie }; 502fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 5035a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static final HashMap<Integer, String> FOLDER_SMS_MAP; 5045a60e47497f21f64e6d79420dc4c56c1907df22akschulz static { 5055a60e47497f21f64e6d79420dc4c56c1907df22akschulz FOLDER_SMS_MAP = new HashMap<Integer, String>(); 5065a60e47497f21f64e6d79420dc4c56c1907df22akschulz FOLDER_SMS_MAP.put(Sms.MESSAGE_TYPE_INBOX, BluetoothMapContract.FOLDER_NAME_INBOX); 5075a60e47497f21f64e6d79420dc4c56c1907df22akschulz FOLDER_SMS_MAP.put(Sms.MESSAGE_TYPE_SENT, BluetoothMapContract.FOLDER_NAME_SENT); 5085a60e47497f21f64e6d79420dc4c56c1907df22akschulz FOLDER_SMS_MAP.put(Sms.MESSAGE_TYPE_DRAFT, BluetoothMapContract.FOLDER_NAME_DRAFT); 5095a60e47497f21f64e6d79420dc4c56c1907df22akschulz FOLDER_SMS_MAP.put(Sms.MESSAGE_TYPE_OUTBOX, BluetoothMapContract.FOLDER_NAME_OUTBOX); 5105a60e47497f21f64e6d79420dc4c56c1907df22akschulz FOLDER_SMS_MAP.put(Sms.MESSAGE_TYPE_FAILED, BluetoothMapContract.FOLDER_NAME_OUTBOX); 5115a60e47497f21f64e6d79420dc4c56c1907df22akschulz FOLDER_SMS_MAP.put(Sms.MESSAGE_TYPE_QUEUED, BluetoothMapContract.FOLDER_NAME_OUTBOX); 5125a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 513fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 5145a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static String getSmsFolderName(int type) { 5155a60e47497f21f64e6d79420dc4c56c1907df22akschulz String name = FOLDER_SMS_MAP.get(type); 5165a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(name != null) { 5175a60e47497f21f64e6d79420dc4c56c1907df22akschulz return name; 5185a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 5195a60e47497f21f64e6d79420dc4c56c1907df22akschulz Log.e(TAG, "New SMS mailbox types have been introduced, without an update in BT..."); 5205a60e47497f21f64e6d79420dc4c56c1907df22akschulz return "Unknown"; 5215a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 5225a60e47497f21f64e6d79420dc4c56c1907df22akschulz 5235a60e47497f21f64e6d79420dc4c56c1907df22akschulz 5245a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static final HashMap<Integer, String> FOLDER_MMS_MAP; 5255a60e47497f21f64e6d79420dc4c56c1907df22akschulz static { 5265a60e47497f21f64e6d79420dc4c56c1907df22akschulz FOLDER_MMS_MAP = new HashMap<Integer, String>(); 5275a60e47497f21f64e6d79420dc4c56c1907df22akschulz FOLDER_MMS_MAP.put(Mms.MESSAGE_BOX_INBOX, BluetoothMapContract.FOLDER_NAME_INBOX); 5285a60e47497f21f64e6d79420dc4c56c1907df22akschulz FOLDER_MMS_MAP.put(Mms.MESSAGE_BOX_SENT, BluetoothMapContract.FOLDER_NAME_SENT); 5295a60e47497f21f64e6d79420dc4c56c1907df22akschulz FOLDER_MMS_MAP.put(Mms.MESSAGE_BOX_DRAFTS, BluetoothMapContract.FOLDER_NAME_DRAFT); 5305a60e47497f21f64e6d79420dc4c56c1907df22akschulz FOLDER_MMS_MAP.put(Mms.MESSAGE_BOX_OUTBOX, BluetoothMapContract.FOLDER_NAME_OUTBOX); 5315a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 5325a60e47497f21f64e6d79420dc4c56c1907df22akschulz 5335a60e47497f21f64e6d79420dc4c56c1907df22akschulz private static String getMmsFolderName(int mailbox) { 5345a60e47497f21f64e6d79420dc4c56c1907df22akschulz String name = FOLDER_MMS_MAP.get(mailbox); 5355a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(name != null) { 5365a60e47497f21f64e6d79420dc4c56c1907df22akschulz return name; 5375a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 5385a60e47497f21f64e6d79420dc4c56c1907df22akschulz Log.e(TAG, "New MMS mailboxes have been introduced, without an update in BT..."); 5395a60e47497f21f64e6d79420dc4c56c1907df22akschulz return "Unknown"; 5405a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 5415a60e47497f21f64e6d79420dc4c56c1907df22akschulz 5425a60e47497f21f64e6d79420dc4c56c1907df22akschulz /** 5435a60e47497f21f64e6d79420dc4c56c1907df22akschulz * Set the folder structure to be used for this instance. 5445a60e47497f21f64e6d79420dc4c56c1907df22akschulz * @param folderStructure 5455a60e47497f21f64e6d79420dc4c56c1907df22akschulz */ 5465a60e47497f21f64e6d79420dc4c56c1907df22akschulz public void setFolderStructure(BluetoothMapFolderElement folderStructure) { 5475a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.mFolders = folderStructure; 5485a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 5495a60e47497f21f64e6d79420dc4c56c1907df22akschulz 5505a60e47497f21f64e6d79420dc4c56c1907df22akschulz private class ConvoContactInfo { 5515a60e47497f21f64e6d79420dc4c56c1907df22akschulz public int mConvoColConvoId = -1; 5525a60e47497f21f64e6d79420dc4c56c1907df22akschulz public int mConvoColLastActivity = -1; 5535a60e47497f21f64e6d79420dc4c56c1907df22akschulz public int mConvoColName = -1; 5545a60e47497f21f64e6d79420dc4c56c1907df22akschulz // public int mConvoColRead = -1; 5555a60e47497f21f64e6d79420dc4c56c1907df22akschulz // public int mConvoColVersionCounter = -1; 5565a60e47497f21f64e6d79420dc4c56c1907df22akschulz public int mContactColUci = -1; 5575a60e47497f21f64e6d79420dc4c56c1907df22akschulz public int mContactColConvoId = -1; 5585a60e47497f21f64e6d79420dc4c56c1907df22akschulz public int mContactColName = -1; 5595a60e47497f21f64e6d79420dc4c56c1907df22akschulz public int mContactColNickname = -1; 5605a60e47497f21f64e6d79420dc4c56c1907df22akschulz public int mContactColBtUid = -1; 5615a60e47497f21f64e6d79420dc4c56c1907df22akschulz public int mContactColChatState = -1; 5625a60e47497f21f64e6d79420dc4c56c1907df22akschulz public int mContactColContactId = -1; 5635a60e47497f21f64e6d79420dc4c56c1907df22akschulz public int mContactColLastActive = -1; 5645a60e47497f21f64e6d79420dc4c56c1907df22akschulz public int mContactColPresenceState = -1; 5655a60e47497f21f64e6d79420dc4c56c1907df22akschulz public int mContactColPresenceText = -1; 5665a60e47497f21f64e6d79420dc4c56c1907df22akschulz public int mContactColPriority = -1; 5675a60e47497f21f64e6d79420dc4c56c1907df22akschulz public int mContactColLastOnline = -1; 5685a60e47497f21f64e6d79420dc4c56c1907df22akschulz 5695a60e47497f21f64e6d79420dc4c56c1907df22akschulz public void setConvoColunms(Cursor c) { 5705a60e47497f21f64e6d79420dc4c56c1907df22akschulz // mConvoColConvoId = c.getColumnIndex( 5715a60e47497f21f64e6d79420dc4c56c1907df22akschulz // BluetoothMapContract.ConversationColumns.THREAD_ID); 5725a60e47497f21f64e6d79420dc4c56c1907df22akschulz // mConvoColLastActivity = c.getColumnIndex( 5735a60e47497f21f64e6d79420dc4c56c1907df22akschulz // BluetoothMapContract.ConversationColumns.LAST_THREAD_ACTIVITY); 5745a60e47497f21f64e6d79420dc4c56c1907df22akschulz // mConvoColName = c.getColumnIndex( 5755a60e47497f21f64e6d79420dc4c56c1907df22akschulz // BluetoothMapContract.ConversationColumns.THREAD_NAME); 5765a60e47497f21f64e6d79420dc4c56c1907df22akschulz mContactColConvoId = c.getColumnIndex( 5775a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.ConvoContactColumns.CONVO_ID); 5785a60e47497f21f64e6d79420dc4c56c1907df22akschulz mContactColName = c.getColumnIndex( 5795a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.ConvoContactColumns.NAME); 5805a60e47497f21f64e6d79420dc4c56c1907df22akschulz mContactColNickname = c.getColumnIndex( 5815a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.ConvoContactColumns.NICKNAME); 5825a60e47497f21f64e6d79420dc4c56c1907df22akschulz mContactColBtUid = c.getColumnIndex( 5835a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.ConvoContactColumns.X_BT_UID); 5845a60e47497f21f64e6d79420dc4c56c1907df22akschulz mContactColChatState = c.getColumnIndex( 5855a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.ConvoContactColumns.CHAT_STATE); 5865a60e47497f21f64e6d79420dc4c56c1907df22akschulz mContactColUci = c.getColumnIndex( 5875a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.ConvoContactColumns.UCI); 5885a60e47497f21f64e6d79420dc4c56c1907df22akschulz mContactColNickname = c.getColumnIndex( 5895a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.ConvoContactColumns.NICKNAME); 5905a60e47497f21f64e6d79420dc4c56c1907df22akschulz mContactColLastActive = c.getColumnIndex( 5915a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.ConvoContactColumns.LAST_ACTIVE); 5925a60e47497f21f64e6d79420dc4c56c1907df22akschulz mContactColName = c.getColumnIndex( 5935a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.ConvoContactColumns.NAME); 5945a60e47497f21f64e6d79420dc4c56c1907df22akschulz mContactColPresenceState = c.getColumnIndex( 5955a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.ConvoContactColumns.PRESENCE_STATE); 5965a60e47497f21f64e6d79420dc4c56c1907df22akschulz mContactColPresenceText = c.getColumnIndex( 5975a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.ConvoContactColumns.STATUS_TEXT); 5985a60e47497f21f64e6d79420dc4c56c1907df22akschulz mContactColPriority = c.getColumnIndex( 5995a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.ConvoContactColumns.PRIORITY); 6005a60e47497f21f64e6d79420dc4c56c1907df22akschulz mContactColLastOnline = c.getColumnIndex( 6015a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.ConvoContactColumns.LAST_ONLINE); 6025a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 6035a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 604fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 605fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private class Event { 606fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie String eventType; 607fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie long handle; 6085a60e47497f21f64e6d79420dc4c56c1907df22akschulz String folder = null; 6095a60e47497f21f64e6d79420dc4c56c1907df22akschulz String oldFolder = null; 610fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie TYPE msgType; 6115a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* Extended event parameters in MAP Event version 1.1 */ 6125a60e47497f21f64e6d79420dc4c56c1907df22akschulz String datetime = null; // OBEX time "YYYYMMDDTHHMMSS" 6135a60e47497f21f64e6d79420dc4c56c1907df22akschulz String uci = null; 6145a60e47497f21f64e6d79420dc4c56c1907df22akschulz String subject = null; 6155a60e47497f21f64e6d79420dc4c56c1907df22akschulz String senderName = null; 6165a60e47497f21f64e6d79420dc4c56c1907df22akschulz String priority = null; 6175a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* Event parameters in MAP Event version 1.2 */ 6185a60e47497f21f64e6d79420dc4c56c1907df22akschulz String conversationName = null; 6195a60e47497f21f64e6d79420dc4c56c1907df22akschulz long conversationID = -1; 6205a60e47497f21f64e6d79420dc4c56c1907df22akschulz int presenceState = BluetoothMapContract.PresenceState.UNKNOWN; 6215a60e47497f21f64e6d79420dc4c56c1907df22akschulz String presenceStatus = null; 6225a60e47497f21f64e6d79420dc4c56c1907df22akschulz int chatState = BluetoothMapContract.ChatState.UNKNOWN; 623fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 624326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde final static String PATH = "telecom/msg/"; 625326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 6265a60e47497f21f64e6d79420dc4c56c1907df22akschulz private void setFolderPath(String name, TYPE type) { 6275a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (name != null) { 6285a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(type == TYPE.EMAIL || type == TYPE.IM) { 6295a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.folder = name; 630326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 6315a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.folder = PATH + name; 632326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 633fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else { 634fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.folder = null; 635fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 6365a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 6375a60e47497f21f64e6d79420dc4c56c1907df22akschulz 6385a60e47497f21f64e6d79420dc4c56c1907df22akschulz public Event(String eventType, long handle, String folder, 6395a60e47497f21f64e6d79420dc4c56c1907df22akschulz String oldFolder, TYPE msgType) { 6405a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.eventType = eventType; 6415a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.handle = handle; 6425a60e47497f21f64e6d79420dc4c56c1907df22akschulz setFolderPath(folder, msgType); 643fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (oldFolder != null) { 6445a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(msgType == TYPE.EMAIL || msgType == TYPE.IM) { 645326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde this.oldFolder = oldFolder; 646326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 647326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde this.oldFolder = PATH + oldFolder; 648326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 649fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else { 650fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.oldFolder = null; 651fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 652fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.msgType = msgType; 653fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 654fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 6555a60e47497f21f64e6d79420dc4c56c1907df22akschulz public Event(String eventType, long handle, String folder, TYPE msgType) { 6565a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.eventType = eventType; 6575a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.handle = handle; 6585a60e47497f21f64e6d79420dc4c56c1907df22akschulz setFolderPath(folder, msgType); 6595a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.msgType = msgType; 6605a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 6615a60e47497f21f64e6d79420dc4c56c1907df22akschulz 6625a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* extended event type 1.1 */ 6635a60e47497f21f64e6d79420dc4c56c1907df22akschulz public Event(String eventType, long handle, String folder, TYPE msgType, 6645a60e47497f21f64e6d79420dc4c56c1907df22akschulz String datetime, String subject, String senderName, String priority) { 6655a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.eventType = eventType; 6665a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.handle = handle; 6675a60e47497f21f64e6d79420dc4c56c1907df22akschulz setFolderPath(folder, msgType); 6685a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.msgType = msgType; 6695a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.datetime = datetime; 6705a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (subject != null) { 6715a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.subject = BluetoothMapUtils.stripInvalidChars(subject); 6725a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 6735a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (senderName != null) { 6745a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.senderName = BluetoothMapUtils.stripInvalidChars(senderName); 6755a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 6765a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.priority = priority; 6775a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 6785a60e47497f21f64e6d79420dc4c56c1907df22akschulz 6795a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* extended event type 1.2 message events */ 6805a60e47497f21f64e6d79420dc4c56c1907df22akschulz public Event(String eventType, long handle, String folder, TYPE msgType, 6815a60e47497f21f64e6d79420dc4c56c1907df22akschulz String datetime, String subject, String senderName, String priority, 6825a60e47497f21f64e6d79420dc4c56c1907df22akschulz long conversationID, String conversationName) { 6835a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.eventType = eventType; 6845a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.handle = handle; 6855a60e47497f21f64e6d79420dc4c56c1907df22akschulz setFolderPath(folder, msgType); 6865a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.msgType = msgType; 6875a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.datetime = datetime; 6885a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (subject != null) { 6895a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.subject = BluetoothMapUtils.stripInvalidChars(subject); 6905a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 6915a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (senderName != null) { 6925a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.senderName = BluetoothMapUtils.stripInvalidChars(senderName); 6935a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 6945a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (conversationID != 0) { 6955a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.conversationID = conversationID; 6965a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 6975a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (conversationName != null) { 6985a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.conversationName = BluetoothMapUtils.stripInvalidChars(conversationName); 6995a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 7005a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.priority = priority; 7015a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 7025a60e47497f21f64e6d79420dc4c56c1907df22akschulz 7035a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* extended event type 1.2 for conversation, presence or chat state changed events */ 7045a60e47497f21f64e6d79420dc4c56c1907df22akschulz public Event(String eventType, String uci, TYPE msgType, String name, String priority, 7055a60e47497f21f64e6d79420dc4c56c1907df22akschulz String lastActivity, long conversationID, String conversationName, 7065a60e47497f21f64e6d79420dc4c56c1907df22akschulz int presenceState, String presenceStatus, int chatState) { 7075a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.eventType = eventType; 7085a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.uci = uci; 7095a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.msgType = msgType; 7105a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (name != null) { 7115a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.senderName = BluetoothMapUtils.stripInvalidChars(name); 7125a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 7135a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.priority = priority; 7145a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.datetime = lastActivity; 7155a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (conversationID != 0) { 7165a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.conversationID = conversationID; 7175a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 7185a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (conversationName != null) { 7195a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.conversationName = BluetoothMapUtils.stripInvalidChars(conversationName); 7205a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 7215a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (presenceState != BluetoothMapContract.PresenceState.UNKNOWN) { 7225a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.presenceState = presenceState; 7235a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 7245a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (presenceStatus != null) { 7255a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.presenceStatus = BluetoothMapUtils.stripInvalidChars(presenceStatus); 7265a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 7275a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (chatState != BluetoothMapContract.ChatState.UNKNOWN) { 7285a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.chatState = chatState; 7295a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 7305a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 7315a60e47497f21f64e6d79420dc4c56c1907df22akschulz 732fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public byte[] encode() throws UnsupportedEncodingException { 733fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie StringWriter sw = new StringWriter(); 734fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie XmlSerializer xmlEvtReport = Xml.newSerializer(); 7355a60e47497f21f64e6d79420dc4c56c1907df22akschulz 736fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie try { 737fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie xmlEvtReport.setOutput(sw); 7385a60e47497f21f64e6d79420dc4c56c1907df22akschulz xmlEvtReport.startDocument("UTF-8", true); 739326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde xmlEvtReport.text("\r\n"); 74070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz xmlEvtReport.startTag("", "MAP-event-report"); 7415a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (mMapEventReportVersion == BluetoothMapUtils.MAP_EVENT_REPORT_V10) { 7425a60e47497f21f64e6d79420dc4c56c1907df22akschulz xmlEvtReport.attribute("", "version", BluetoothMapUtils.MAP_V10_STR); 7435a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else if (mMapEventReportVersion == BluetoothMapUtils.MAP_EVENT_REPORT_V11) { 7445a60e47497f21f64e6d79420dc4c56c1907df22akschulz xmlEvtReport.attribute("", "version", BluetoothMapUtils.MAP_V11_STR); 7455a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else { 7465a60e47497f21f64e6d79420dc4c56c1907df22akschulz xmlEvtReport.attribute("", "version", BluetoothMapUtils.MAP_V12_STR); 7475a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 748fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie xmlEvtReport.startTag("", "event"); 749fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie xmlEvtReport.attribute("", "type", eventType); 7505a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (eventType.equals(EVENT_TYPE_CONVERSATION) || 7515a60e47497f21f64e6d79420dc4c56c1907df22akschulz eventType.equals(EVENT_TYPE_PRESENCE) || 7525a60e47497f21f64e6d79420dc4c56c1907df22akschulz eventType.equals(EVENT_TYPE_CHAT_STATE)) { 7535a60e47497f21f64e6d79420dc4c56c1907df22akschulz xmlEvtReport.attribute("", "participant_uci", uci); 7545a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else { 7555a60e47497f21f64e6d79420dc4c56c1907df22akschulz xmlEvtReport.attribute("", "handle", 7565a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapUtils.getMapHandle(handle, msgType)); 7575a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 7585a60e47497f21f64e6d79420dc4c56c1907df22akschulz 759fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (folder != null) { 760fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie xmlEvtReport.attribute("", "folder", folder); 761fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 762fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (oldFolder != null) { 763fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie xmlEvtReport.attribute("", "old_folder", oldFolder); 764fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 7652e7dd83a6b3b4bf15e0dec6aad9ab826e6e2531bHemant Gupta /* Avoid possible NPE for "msgType" "null" value. "msgType" 7662e7dd83a6b3b4bf15e0dec6aad9ab826e6e2531bHemant Gupta * is a implied attribute and will be set "null" for events 7672e7dd83a6b3b4bf15e0dec6aad9ab826e6e2531bHemant Gupta * like "memory full" or "memory available" */ 7682e7dd83a6b3b4bf15e0dec6aad9ab826e6e2531bHemant Gupta if (msgType != null) { 7692e7dd83a6b3b4bf15e0dec6aad9ab826e6e2531bHemant Gupta xmlEvtReport.attribute("", "msg_type", msgType.name()); 7702e7dd83a6b3b4bf15e0dec6aad9ab826e6e2531bHemant Gupta } 7715a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* If MAP event report version is above 1.0 send 7725a60e47497f21f64e6d79420dc4c56c1907df22akschulz * extended event report parameters */ 7735a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (datetime != null) { 7745a60e47497f21f64e6d79420dc4c56c1907df22akschulz xmlEvtReport.attribute("", "datetime", datetime); 7755a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 7765a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (subject != null) { 7775a60e47497f21f64e6d79420dc4c56c1907df22akschulz xmlEvtReport.attribute("", "subject", 7785a60e47497f21f64e6d79420dc4c56c1907df22akschulz subject.substring(0,subject.length() < 256 ? subject.length() : 256)); 7795a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 7805a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (senderName != null) { 7819a18a9fc4349f90e49d036ccafc91d8b5befe973Ajay Panicker xmlEvtReport.attribute("", "sender_name", senderName); 7825a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 7835a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (priority != null) { 7845a60e47497f21f64e6d79420dc4c56c1907df22akschulz xmlEvtReport.attribute("", "priority", priority); 7855a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 7865a60e47497f21f64e6d79420dc4c56c1907df22akschulz 7875a60e47497f21f64e6d79420dc4c56c1907df22akschulz //} 7885a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* Include conversation information from event version 1.2 */ 7895a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (mMapEventReportVersion > BluetoothMapUtils.MAP_EVENT_REPORT_V11 ) { 7905a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (conversationName != null) { 7915a60e47497f21f64e6d79420dc4c56c1907df22akschulz xmlEvtReport.attribute("", "conversation_name", conversationName); 7925a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 7935a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (conversationID != -1) { 7945a60e47497f21f64e6d79420dc4c56c1907df22akschulz // Convert provider conversation handle to string incl type 7955a60e47497f21f64e6d79420dc4c56c1907df22akschulz xmlEvtReport.attribute("", "conversation_id", 7965a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapUtils.getMapConvoHandle(conversationID, msgType)); 7975a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 7985a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (eventType.equals(EVENT_TYPE_PRESENCE)) { 7995a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (presenceState != 0) { 8005a60e47497f21f64e6d79420dc4c56c1907df22akschulz // Convert provider conversation handle to string incl type 8015a60e47497f21f64e6d79420dc4c56c1907df22akschulz xmlEvtReport.attribute("", "presence_availability", 8025a60e47497f21f64e6d79420dc4c56c1907df22akschulz String.valueOf(presenceState)); 8035a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 8045a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (presenceStatus != null) { 8055a60e47497f21f64e6d79420dc4c56c1907df22akschulz // Convert provider conversation handle to string incl type 8065a60e47497f21f64e6d79420dc4c56c1907df22akschulz xmlEvtReport.attribute("", "presence_status", 8075a60e47497f21f64e6d79420dc4c56c1907df22akschulz presenceStatus.substring( 8085a60e47497f21f64e6d79420dc4c56c1907df22akschulz 0,presenceStatus.length() < 256 ? subject.length() : 256)); 8095a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 8105a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 8115a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (eventType.equals(EVENT_TYPE_PRESENCE)) { 8125a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (chatState != 0) { 8135a60e47497f21f64e6d79420dc4c56c1907df22akschulz // Convert provider conversation handle to string incl type 8145a60e47497f21f64e6d79420dc4c56c1907df22akschulz xmlEvtReport.attribute("", "chat_state", String.valueOf(chatState)); 8155a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 8165a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 8175a60e47497f21f64e6d79420dc4c56c1907df22akschulz 8185a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 8195a60e47497f21f64e6d79420dc4c56c1907df22akschulz xmlEvtReport.endTag("", "event"); 82070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz xmlEvtReport.endTag("", "MAP-event-report"); 821fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie xmlEvtReport.endDocument(); 822fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } catch (IllegalArgumentException e) { 823326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(D) Log.w(TAG,e); 824fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } catch (IllegalStateException e) { 825326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(D) Log.w(TAG,e); 826fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } catch (IOException e) { 827326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(D) Log.w(TAG,e); 828fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 829fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 830326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (V) Log.d(TAG, sw.toString()); 831fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 832fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return sw.toString().getBytes("UTF-8"); 833fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 834fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 835fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 8365a60e47497f21f64e6d79420dc4c56c1907df22akschulz /*package*/ class Msg { 837fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie long id; 838326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde int type; // Used as folder for SMS/MMS 839326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde int threadId; // Used for SMS/MMS at delete 840326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde long folderId = -1; // Email folder ID 841326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde long oldFolderId = -1; // Used for email undelete 842326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde boolean localInitiatedSend = false; // Used for MMS to filter out events 843326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde boolean transparent = false; // Used for EMAIL to delete message sent with transparency 8445a60e47497f21f64e6d79420dc4c56c1907df22akschulz int flagRead = -1; // Message status read/unread 845326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 8465a60e47497f21f64e6d79420dc4c56c1907df22akschulz public Msg(long id, int type, int threadId, int readFlag) { 847fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.id = id; 848fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.type = type; 849326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde this.threadId = threadId; 8505a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.flagRead = readFlag; 851326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 8525a60e47497f21f64e6d79420dc4c56c1907df22akschulz public Msg(long id, long folderId, int readFlag) { 853326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde this.id = id; 854326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde this.folderId = folderId; 8555a60e47497f21f64e6d79420dc4c56c1907df22akschulz this.flagRead = readFlag; 856326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 857326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 858326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* Eclipse generated hashCode() and equals() to make 859326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * hashMap lookup work independent of whether the obj 860326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * is used for email or SMS/MMS and whether or not the 861326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * oldFolder is set. */ 862326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde @Override 863326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde public int hashCode() { 864326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde final int prime = 31; 865326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde int result = 1; 866326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde result = prime * result + (int) (id ^ (id >>> 32)); 867326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde return result; 868fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 869fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 870326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde @Override 871326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde public boolean equals(Object obj) { 872326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (this == obj) 873326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde return true; 874326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (obj == null) 875326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde return false; 876326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (getClass() != obj.getClass()) 877326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde return false; 878326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Msg other = (Msg) obj; 879326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (id != other.id) 880326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde return false; 881326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde return true; 882326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 883326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 884fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 8855a60e47497f21f64e6d79420dc4c56c1907df22akschulz private Map<Long, Msg> mMsgListSms = null; 8865a60e47497f21f64e6d79420dc4c56c1907df22akschulz 8875a60e47497f21f64e6d79420dc4c56c1907df22akschulz private Map<Long, Msg> mMsgListMms = null; 888326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 8895a60e47497f21f64e6d79420dc4c56c1907df22akschulz private Map<Long, Msg> mMsgListMsg = null; 890326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 8915a60e47497f21f64e6d79420dc4c56c1907df22akschulz private Map<String, BluetoothMapConvoContactElement> mContactList = null; 892326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 893326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde public int setNotificationRegistration(int notificationStatus) throws RemoteException { 894326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // Forward the request to the MNS thread as a message - including the MAS instance ID. 895326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(D) Log.d(TAG,"setNotificationRegistration() enter"); 896e6564029f132077c8a4877431a95899db201e506Ashwini Munigala if (mMnsClient == null) { 897e6564029f132077c8a4877431a95899db201e506Ashwini Munigala return ResponseCodes.OBEX_HTTP_UNAVAILABLE; 898e6564029f132077c8a4877431a95899db201e506Ashwini Munigala } 899326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Handler mns = mMnsClient.getMessageHandler(); 900e6564029f132077c8a4877431a95899db201e506Ashwini Munigala if (mns != null) { 901326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Message msg = mns.obtainMessage(); 902e6564029f132077c8a4877431a95899db201e506Ashwini Munigala if (mMnsClient.isValidMnsRecord()) { 903e6564029f132077c8a4877431a95899db201e506Ashwini Munigala msg.what = BluetoothMnsObexClient.MSG_MNS_NOTIFICATION_REGISTRATION; 904e6564029f132077c8a4877431a95899db201e506Ashwini Munigala } else { 905e6564029f132077c8a4877431a95899db201e506Ashwini Munigala //Trigger SDP Search and notificaiton registration , if SDP record not found. 906e6564029f132077c8a4877431a95899db201e506Ashwini Munigala msg.what = BluetoothMnsObexClient.MSG_MNS_SDP_SEARCH_REGISTRATION; 907e6564029f132077c8a4877431a95899db201e506Ashwini Munigala if (mMnsClient.mMnsLstRegRqst != null && 908e6564029f132077c8a4877431a95899db201e506Ashwini Munigala (mMnsClient.mMnsLstRegRqst.isSearchInProgress())) { 909e6564029f132077c8a4877431a95899db201e506Ashwini Munigala /* 1. Disallow next Notification ON Request : 910e6564029f132077c8a4877431a95899db201e506Ashwini Munigala * - Respond "Service Unavailable" as SDP Search and last notification 911e6564029f132077c8a4877431a95899db201e506Ashwini Munigala * registration ON request is already InProgress. 912e6564029f132077c8a4877431a95899db201e506Ashwini Munigala * - Next notification ON Request will be allowed ONLY after search 913e6564029f132077c8a4877431a95899db201e506Ashwini Munigala * and connect for last saved request [Replied with OK ] is processed. 914e6564029f132077c8a4877431a95899db201e506Ashwini Munigala */ 915e6564029f132077c8a4877431a95899db201e506Ashwini Munigala if (notificationStatus == BluetoothMapAppParams.NOTIFICATION_STATUS_YES) { 916e6564029f132077c8a4877431a95899db201e506Ashwini Munigala return ResponseCodes.OBEX_HTTP_UNAVAILABLE; 917e6564029f132077c8a4877431a95899db201e506Ashwini Munigala } else { 918e6564029f132077c8a4877431a95899db201e506Ashwini Munigala /* 2. Allow next Notification OFF Request: 919e6564029f132077c8a4877431a95899db201e506Ashwini Munigala * - Keep the SDP search still in progress. 920e6564029f132077c8a4877431a95899db201e506Ashwini Munigala * - Disconnect and Deregister the contentObserver. 921e6564029f132077c8a4877431a95899db201e506Ashwini Munigala */ 922e6564029f132077c8a4877431a95899db201e506Ashwini Munigala msg.what = BluetoothMnsObexClient.MSG_MNS_NOTIFICATION_REGISTRATION; 923e6564029f132077c8a4877431a95899db201e506Ashwini Munigala } 924e6564029f132077c8a4877431a95899db201e506Ashwini Munigala } 925e6564029f132077c8a4877431a95899db201e506Ashwini Munigala } 926326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde msg.arg1 = mMasId; 927326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde msg.arg2 = notificationStatus; 928326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mns.sendMessageDelayed(msg, 10); // Send message without forcing a context switch 929326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* Some devices - e.g. PTS needs to get the unregister confirm before we actually 930326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * disconnect the MNS. */ 931e6564029f132077c8a4877431a95899db201e506Ashwini Munigala if(D) Log.d(TAG,"setNotificationRegistration() send : " + msg.what + " to MNS "); 932e6564029f132077c8a4877431a95899db201e506Ashwini Munigala return ResponseCodes.OBEX_HTTP_OK; 933326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 934326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // This should not happen except at shutdown. 935326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(D) Log.d(TAG,"setNotificationRegistration() Unable to send registration request"); 936326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde return ResponseCodes.OBEX_HTTP_UNAVAILABLE; 937326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 938326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 939fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 9405a60e47497f21f64e6d79420dc4c56c1907df22akschulz boolean eventMaskContainsContacts(long mask) { 9415a60e47497f21f64e6d79420dc4c56c1907df22akschulz return sendEventParticipantPresenceChanged(mask); 9425a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 9435a60e47497f21f64e6d79420dc4c56c1907df22akschulz 9445a60e47497f21f64e6d79420dc4c56c1907df22akschulz boolean eventMaskContainsCovo(long mask) { 9455a60e47497f21f64e6d79420dc4c56c1907df22akschulz return (sendEventConversationChanged(mask) 9465a60e47497f21f64e6d79420dc4c56c1907df22akschulz || sendEventParticipantChatstateChanged(mask)); 9475a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 9485a60e47497f21f64e6d79420dc4c56c1907df22akschulz 9495a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* Overwrite the existing notification filter. Will register/deregister observers for 9505a60e47497f21f64e6d79420dc4c56c1907df22akschulz * the Contacts and Conversation table as needed. We keep the message observer 9515a60e47497f21f64e6d79420dc4c56c1907df22akschulz * at all times. */ 9525a60e47497f21f64e6d79420dc4c56c1907df22akschulz /*package*/ synchronized void setNotificationFilter(long newFilter) { 9535a60e47497f21f64e6d79420dc4c56c1907df22akschulz long oldFilter = mEventFilter; 9545a60e47497f21f64e6d79420dc4c56c1907df22akschulz mEventFilter = newFilter; 9555a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* Contacts */ 9565a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(!eventMaskContainsContacts(oldFilter) && 9575a60e47497f21f64e6d79420dc4c56c1907df22akschulz eventMaskContainsContacts(newFilter)) { 9585a60e47497f21f64e6d79420dc4c56c1907df22akschulz // TODO: 9595a60e47497f21f64e6d79420dc4c56c1907df22akschulz // Enable the observer 9605a60e47497f21f64e6d79420dc4c56c1907df22akschulz // Reset the contacts list 9615a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 9625a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* Conversations */ 9635a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(!eventMaskContainsCovo(oldFilter) && 9645a60e47497f21f64e6d79420dc4c56c1907df22akschulz eventMaskContainsCovo(newFilter)) { 9655a60e47497f21f64e6d79420dc4c56c1907df22akschulz // TODO: 9665a60e47497f21f64e6d79420dc4c56c1907df22akschulz // Enable the observer 9675a60e47497f21f64e6d79420dc4c56c1907df22akschulz // Reset the conversations list 9685a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 9695a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 9705a60e47497f21f64e6d79420dc4c56c1907df22akschulz 971326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde public void registerObserver() throws RemoteException{ 972fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (V) Log.d(TAG, "registerObserver"); 973326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 974326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (mObserverRegistered) 975326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde return; 976326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 977326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(mAccount != null) { 978326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 979326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mProviderClient = mResolver.acquireUnstableContentProviderClient(mAuthority); 980326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (mProviderClient == null) { 981326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde throw new RemoteException("Failed to acquire provider for " + mAuthority); 982326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 983326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mProviderClient.setDetectNotResponding(PROVIDER_ANR_TIMEOUT); 984326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 9855a60e47497f21f64e6d79420dc4c56c1907df22akschulz // If there is a change in the database before we init the lists we will be sending 9865a60e47497f21f64e6d79420dc4c56c1907df22akschulz // loads of events - hence init before register. 9875a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(mAccount.getType() == TYPE.IM) { 9885a60e47497f21f64e6d79420dc4c56c1907df22akschulz // Further add contact list tracking 9895a60e47497f21f64e6d79420dc4c56c1907df22akschulz initContactsList(); 9905a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 9915a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 9925a60e47497f21f64e6d79420dc4c56c1907df22akschulz // If there is a change in the database before we init the lists we will be sending 9935a60e47497f21f64e6d79420dc4c56c1907df22akschulz // loads of events - hence init before register. 9945a60e47497f21f64e6d79420dc4c56c1907df22akschulz initMsgList(); 9955a60e47497f21f64e6d79420dc4c56c1907df22akschulz 9965a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* Use MmsSms Uri since the Sms Uri is not notified on deletes */ 9975a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(mEnableSmsMms){ 9985a60e47497f21f64e6d79420dc4c56c1907df22akschulz //this is sms/mms 9995a60e47497f21f64e6d79420dc4c56c1907df22akschulz mResolver.registerContentObserver(MmsSms.CONTENT_URI, false, mObserver); 10005a60e47497f21f64e6d79420dc4c56c1907df22akschulz mObserverRegistered = true; 10015a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 10025a60e47497f21f64e6d79420dc4c56c1907df22akschulz 10035a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(mAccount != null) { 1004326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* For URI's without account ID */ 10055a60e47497f21f64e6d79420dc4c56c1907df22akschulz Uri uri = Uri.parse(mAccount.mBase_uri_no_account + "/" 10065a60e47497f21f64e6d79420dc4c56c1907df22akschulz + BluetoothMapContract.TABLE_MESSAGE); 1007326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(D) Log.d(TAG, "Registering observer for: " + uri); 1008326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mResolver.registerContentObserver(uri, true, mObserver); 1009326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 1010326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* For URI's with account ID - is handled the same way as without ID, but is 1011326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * only triggered for MAS instances with matching account ID. */ 1012326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde uri = Uri.parse(mAccount.mBase_uri + "/" + BluetoothMapContract.TABLE_MESSAGE); 1013326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(D) Log.d(TAG, "Registering observer for: " + uri); 1014326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mResolver.registerContentObserver(uri, true, mObserver); 10155a60e47497f21f64e6d79420dc4c56c1907df22akschulz 10165a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(mAccount.getType() == TYPE.IM) { 10175a60e47497f21f64e6d79420dc4c56c1907df22akschulz 10185a60e47497f21f64e6d79420dc4c56c1907df22akschulz uri = Uri.parse(mAccount.mBase_uri_no_account + "/" 10195a60e47497f21f64e6d79420dc4c56c1907df22akschulz + BluetoothMapContract.TABLE_CONVOCONTACT); 10205a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(D) Log.d(TAG, "Registering observer for: " + uri); 10215a60e47497f21f64e6d79420dc4c56c1907df22akschulz mResolver.registerContentObserver(uri, true, mObserver); 10225a60e47497f21f64e6d79420dc4c56c1907df22akschulz 10235a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* For URI's with account ID - is handled the same way as without ID, but is 10245a60e47497f21f64e6d79420dc4c56c1907df22akschulz * only triggered for MAS instances with matching account ID. */ 10255a60e47497f21f64e6d79420dc4c56c1907df22akschulz uri = Uri.parse(mAccount.mBase_uri + "/" + BluetoothMapContract.TABLE_CONVOCONTACT); 10265a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(D) Log.d(TAG, "Registering observer for: " + uri); 10275a60e47497f21f64e6d79420dc4c56c1907df22akschulz mResolver.registerContentObserver(uri, true, mObserver); 10285a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 10295a60e47497f21f64e6d79420dc4c56c1907df22akschulz 1030326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mObserverRegistered = true; 1031326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 1032fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1033fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 10345a60e47497f21f64e6d79420dc4c56c1907df22akschulz public void unregisterObserver() { 10355a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (V) Log.d(TAG, "unregisterObserver"); 10365a60e47497f21f64e6d79420dc4c56c1907df22akschulz mResolver.unregisterContentObserver(mObserver); 10375a60e47497f21f64e6d79420dc4c56c1907df22akschulz mObserverRegistered = false; 10385a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(mProviderClient != null){ 10395a60e47497f21f64e6d79420dc4c56c1907df22akschulz mProviderClient.release(); 10405a60e47497f21f64e6d79420dc4c56c1907df22akschulz mProviderClient = null; 10415a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 10425a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 10435a60e47497f21f64e6d79420dc4c56c1907df22akschulz 10445a60e47497f21f64e6d79420dc4c56c1907df22akschulz /** 10455a60e47497f21f64e6d79420dc4c56c1907df22akschulz * Per design it is only possible to call the refreshXxxx functions sequentially, hence it 10465a60e47497f21f64e6d79420dc4c56c1907df22akschulz * is safe to modify mTransmitEvents without synchronization. 10475a60e47497f21f64e6d79420dc4c56c1907df22akschulz */ 10485a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* package */ void refreshFolderVersionCounter() { 10495a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (mObserverRegistered) { 10505a60e47497f21f64e6d79420dc4c56c1907df22akschulz // As we have observers, we already keep the counter up-to-date. 10515a60e47497f21f64e6d79420dc4c56c1907df22akschulz return; 10525a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 10535a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* We need to perform the same functionality, as when we receive a notification change, 10545a60e47497f21f64e6d79420dc4c56c1907df22akschulz hence we: 10555a60e47497f21f64e6d79420dc4c56c1907df22akschulz - disable the event transmission 10565a60e47497f21f64e6d79420dc4c56c1907df22akschulz - triggers the code for updates 10575a60e47497f21f64e6d79420dc4c56c1907df22akschulz - enable the event transmission */ 10585a60e47497f21f64e6d79420dc4c56c1907df22akschulz mTransmitEvents = false; 10595a60e47497f21f64e6d79420dc4c56c1907df22akschulz try { 10605a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(mEnableSmsMms) { 10615a60e47497f21f64e6d79420dc4c56c1907df22akschulz handleMsgListChangesSms(); 10625a60e47497f21f64e6d79420dc4c56c1907df22akschulz handleMsgListChangesMms(); 10635a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 10645a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(mAccount != null) { 10655a60e47497f21f64e6d79420dc4c56c1907df22akschulz try { 10665a60e47497f21f64e6d79420dc4c56c1907df22akschulz handleMsgListChangesMsg(mMessageUri); 10675a60e47497f21f64e6d79420dc4c56c1907df22akschulz } catch (RemoteException e) { 10685a60e47497f21f64e6d79420dc4c56c1907df22akschulz Log.e(TAG, "Unable to update FolderVersionCounter. - Not fatal, but can cause" + 10695a60e47497f21f64e6d79420dc4c56c1907df22akschulz " undesirable user experience!", e); 10705a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 10715a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 10725a60e47497f21f64e6d79420dc4c56c1907df22akschulz } finally { 10735a60e47497f21f64e6d79420dc4c56c1907df22akschulz // Ensure we always enable events again 10745a60e47497f21f64e6d79420dc4c56c1907df22akschulz mTransmitEvents = true; 10755a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 10765a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 10775a60e47497f21f64e6d79420dc4c56c1907df22akschulz 10785a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* package */ void refreshConvoListVersionCounter() { 10795a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (mObserverRegistered) { 10805a60e47497f21f64e6d79420dc4c56c1907df22akschulz // As we have observers, we already keep the counter up-to-date. 10815a60e47497f21f64e6d79420dc4c56c1907df22akschulz return; 10825a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 10835a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* We need to perform the same functionality, as when we receive a notification change, 10845a60e47497f21f64e6d79420dc4c56c1907df22akschulz hence we: 10855a60e47497f21f64e6d79420dc4c56c1907df22akschulz - disable event transmission 10865a60e47497f21f64e6d79420dc4c56c1907df22akschulz - triggers the code for updates 10875a60e47497f21f64e6d79420dc4c56c1907df22akschulz - enable event transmission */ 10885a60e47497f21f64e6d79420dc4c56c1907df22akschulz mTransmitEvents = false; 10895a60e47497f21f64e6d79420dc4c56c1907df22akschulz try { 10905a60e47497f21f64e6d79420dc4c56c1907df22akschulz if((mAccount != null) && (mContactUri != null)) { 10915a60e47497f21f64e6d79420dc4c56c1907df22akschulz handleContactListChanges(mContactUri); 10925a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 10935a60e47497f21f64e6d79420dc4c56c1907df22akschulz } finally { 10945a60e47497f21f64e6d79420dc4c56c1907df22akschulz // Ensure we always enable events again 10955a60e47497f21f64e6d79420dc4c56c1907df22akschulz mTransmitEvents = true; 1096326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 1097fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1098fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1099fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private void sendEvent(Event evt) { 11005a60e47497f21f64e6d79420dc4c56c1907df22akschulz 11015a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(mTransmitEvents == false) { 11025a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(V) Log.v(TAG, "mTransmitEvents == false - don't send event."); 11035a60e47497f21f64e6d79420dc4c56c1907df22akschulz return; 11045a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 11055a60e47497f21f64e6d79420dc4c56c1907df22akschulz 11065a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(D)Log.d(TAG, "sendEvent: " + evt.eventType + " " + evt.handle + " " + evt.folder + " " 11075a60e47497f21f64e6d79420dc4c56c1907df22akschulz + evt.oldFolder + " " + evt.msgType.name() + " " + evt.datetime + " " 11085a60e47497f21f64e6d79420dc4c56c1907df22akschulz + evt.subject + " " + evt.senderName + " " + evt.priority ); 1109fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 11100e7e149687b0b5e340991b20c9d8e5232e8d3e39Hemant Gupta if (mMnsClient == null || mMnsClient.isConnected() == false) { 11110e7e149687b0b5e340991b20c9d8e5232e8d3e39Hemant Gupta Log.d(TAG, "sendEvent: No MNS client registered or connected- don't send event"); 1112fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return; 1113fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1114fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 11155a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* Enable use of the cache for checking the filter */ 11165a60e47497f21f64e6d79420dc4c56c1907df22akschulz long eventFilter = mEventFilter; 11175a60e47497f21f64e6d79420dc4c56c1907df22akschulz 11185a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* This should have been a switch on the string, but it is not allowed in Java 1.6 */ 11195a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* WARNING: Here we do pointer compare for the string to speed up things, that is. 11205a60e47497f21f64e6d79420dc4c56c1907df22akschulz * HENCE: always use the EVENT_TYPE_"defines" */ 11215a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(evt.eventType == EVENT_TYPE_NEW) { 11225a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(!sendEventNewMessage(eventFilter)) { 11235a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(D)Log.d(TAG, "Skip sending event of type: " + evt.eventType); 11245a60e47497f21f64e6d79420dc4c56c1907df22akschulz return; 11255a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 11265a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else if(evt.eventType == EVENT_TYPE_DELETE) { 11275a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(!sendEventMessageDeleted(eventFilter)) { 11285a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(D)Log.d(TAG, "Skip sending event of type: " + evt.eventType); 11295a60e47497f21f64e6d79420dc4c56c1907df22akschulz return; 11305a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 11315a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else if(evt.eventType == EVENT_TYPE_REMOVED) { 11325a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(!sendEventMessageRemoved(eventFilter)) { 11335a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(D)Log.d(TAG, "Skip sending event of type: " + evt.eventType); 11345a60e47497f21f64e6d79420dc4c56c1907df22akschulz return; 11355a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 11365a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else if(evt.eventType == EVENT_TYPE_SHIFT) { 11375a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(!sendEventMessageShift(eventFilter)) { 11385a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(D)Log.d(TAG, "Skip sending event of type: " + evt.eventType); 11395a60e47497f21f64e6d79420dc4c56c1907df22akschulz return; 11405a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 11415a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else if(evt.eventType == EVENT_TYPE_DELEVERY_SUCCESS) { 11425a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(!sendEventDeliverySuccess(eventFilter)) { 11435a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(D)Log.d(TAG, "Skip sending event of type: " + evt.eventType); 11445a60e47497f21f64e6d79420dc4c56c1907df22akschulz return; 11455a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 11465a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else if(evt.eventType == EVENT_TYPE_SENDING_SUCCESS) { 11475a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(!sendEventSendingSuccess(eventFilter)) { 11485a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(D)Log.d(TAG, "Skip sending event of type: " + evt.eventType); 11495a60e47497f21f64e6d79420dc4c56c1907df22akschulz return; 11505a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 11515a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else if(evt.eventType == EVENT_TYPE_SENDING_FAILURE) { 11525a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(!sendEventSendingFailed(eventFilter)) { 11535a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(D)Log.d(TAG, "Skip sending event of type: " + evt.eventType); 11545a60e47497f21f64e6d79420dc4c56c1907df22akschulz return; 11555a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 11565a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else if(evt.eventType == EVENT_TYPE_DELIVERY_FAILURE) { 11575a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(!sendEventDeliveryFailed(eventFilter)) { 11585a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(D)Log.d(TAG, "Skip sending event of type: " + evt.eventType); 11595a60e47497f21f64e6d79420dc4c56c1907df22akschulz return; 11605a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 11615a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else if(evt.eventType == EVENT_TYPE_READ_STATUS) { 11625a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(!sendEventReadStatusChanged(eventFilter)) { 11635a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(D)Log.d(TAG, "Skip sending event of type: " + evt.eventType); 11645a60e47497f21f64e6d79420dc4c56c1907df22akschulz return; 11655a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 11665a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else if(evt.eventType == EVENT_TYPE_CONVERSATION) { 11675a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(!sendEventConversationChanged(eventFilter)) { 11685a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(D)Log.d(TAG, "Skip sending event of type: " + evt.eventType); 11695a60e47497f21f64e6d79420dc4c56c1907df22akschulz return; 11705a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 11715a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else if(evt.eventType == EVENT_TYPE_PRESENCE) { 11725a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(!sendEventParticipantPresenceChanged(eventFilter)) { 11735a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(D)Log.d(TAG, "Skip sending event of type: " + evt.eventType); 11745a60e47497f21f64e6d79420dc4c56c1907df22akschulz return; 11755a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 11765a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else if(evt.eventType == EVENT_TYPE_CHAT_STATE) { 11775a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(!sendEventParticipantChatstateChanged(eventFilter)) { 11785a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(D)Log.d(TAG, "Skip sending event of type: " + evt.eventType); 11795a60e47497f21f64e6d79420dc4c56c1907df22akschulz return; 11805a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 11815a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 11825a60e47497f21f64e6d79420dc4c56c1907df22akschulz 1183fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie try { 1184fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mMnsClient.sendEvent(evt.encode(), mMasId); 1185fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } catch (UnsupportedEncodingException ex) { 1186fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* do nothing */ 11875a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (D) Log.e(TAG, "Exception - should not happen: ",ex); 1188fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1189fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1190fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1191326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private void initMsgList() throws RemoteException { 1192fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (V) Log.d(TAG, "initMsgList"); 1193db8d8ae565b3db6a5e3187170dcb7b281a79f9daAjay Panicker UserManager manager = UserManager.get(mContext); 119429cab6e8ea1014179fd15fb067e621ae4b066085Ajay Panicker if (manager == null || !manager.isUserUnlocked()) return; 1195fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1196db8d8ae565b3db6a5e3187170dcb7b281a79f9daAjay Panicker if (mEnableSmsMms) { 1197326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde HashMap<Long, Msg> msgListSms = new HashMap<Long, Msg>(); 1198fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 11990905a86a66d6754469c00b5d154ffafe35f630b7Ajay Panicker Cursor c; 12000905a86a66d6754469c00b5d154ffafe35f630b7Ajay Panicker try { 12010905a86a66d6754469c00b5d154ffafe35f630b7Ajay Panicker c = mResolver.query(Sms.CONTENT_URI, 12025a60e47497f21f64e6d79420dc4c56c1907df22akschulz SMS_PROJECTION_SHORT, null, null, null); 12030905a86a66d6754469c00b5d154ffafe35f630b7Ajay Panicker } catch (SQLiteException e) { 12040905a86a66d6754469c00b5d154ffafe35f630b7Ajay Panicker Log.e(TAG, "Failed to initialize the list of messages: " + e.toString()); 12050905a86a66d6754469c00b5d154ffafe35f630b7Ajay Panicker return; 12060905a86a66d6754469c00b5d154ffafe35f630b7Ajay Panicker } 12070905a86a66d6754469c00b5d154ffafe35f630b7Ajay Panicker 120828446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz try { 12095a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null && c.moveToFirst()) { 12105a60e47497f21f64e6d79420dc4c56c1907df22akschulz do { 12115a60e47497f21f64e6d79420dc4c56c1907df22akschulz long id = c.getLong(c.getColumnIndex(Sms._ID)); 12125a60e47497f21f64e6d79420dc4c56c1907df22akschulz int type = c.getInt(c.getColumnIndex(Sms.TYPE)); 12135a60e47497f21f64e6d79420dc4c56c1907df22akschulz int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID)); 12145a60e47497f21f64e6d79420dc4c56c1907df22akschulz int read = c.getInt(c.getColumnIndex(Sms.READ)); 1215fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 12165a60e47497f21f64e6d79420dc4c56c1907df22akschulz Msg msg = new Msg(id, type, threadId, read); 12175a60e47497f21f64e6d79420dc4c56c1907df22akschulz msgListSms.put(id, msg); 12185a60e47497f21f64e6d79420dc4c56c1907df22akschulz } while (c.moveToNext()); 121928446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } 122028446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } finally { 12215a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null) c.close(); 1222326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 122328446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz 12245a60e47497f21f64e6d79420dc4c56c1907df22akschulz synchronized(getMsgListSms()) { 12255a60e47497f21f64e6d79420dc4c56c1907df22akschulz getMsgListSms().clear(); 12265a60e47497f21f64e6d79420dc4c56c1907df22akschulz setMsgListSms(msgListSms, true); // Set initial folder version counter 1227326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 1228fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1229326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde HashMap<Long, Msg> msgListMms = new HashMap<Long, Msg>(); 1230fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1231326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde c = mResolver.query(Mms.CONTENT_URI, MMS_PROJECTION_SHORT, null, null, null); 123228446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz try { 12335a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null && c.moveToFirst()) { 12345a60e47497f21f64e6d79420dc4c56c1907df22akschulz do { 12355a60e47497f21f64e6d79420dc4c56c1907df22akschulz long id = c.getLong(c.getColumnIndex(Mms._ID)); 12365a60e47497f21f64e6d79420dc4c56c1907df22akschulz int type = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX)); 12375a60e47497f21f64e6d79420dc4c56c1907df22akschulz int threadId = c.getInt(c.getColumnIndex(Mms.THREAD_ID)); 12385a60e47497f21f64e6d79420dc4c56c1907df22akschulz int read = c.getInt(c.getColumnIndex(Mms.READ)); 1239fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 12405a60e47497f21f64e6d79420dc4c56c1907df22akschulz Msg msg = new Msg(id, type, threadId, read); 12415a60e47497f21f64e6d79420dc4c56c1907df22akschulz msgListMms.put(id, msg); 12425a60e47497f21f64e6d79420dc4c56c1907df22akschulz } while (c.moveToNext()); 124328446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } 124428446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } finally { 12455a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null) c.close(); 1246326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 124728446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz 12485a60e47497f21f64e6d79420dc4c56c1907df22akschulz synchronized(getMsgListMms()) { 12495a60e47497f21f64e6d79420dc4c56c1907df22akschulz getMsgListMms().clear(); 12505a60e47497f21f64e6d79420dc4c56c1907df22akschulz setMsgListMms(msgListMms, true); // Set initial folder version counter 1251326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 1252fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1253fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1254326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(mAccount != null) { 12555a60e47497f21f64e6d79420dc4c56c1907df22akschulz HashMap<Long, Msg> msgList = new HashMap<Long, Msg>(); 1256326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Uri uri = mMessageUri; 12575a60e47497f21f64e6d79420dc4c56c1907df22akschulz Cursor c = mProviderClient.query(uri, MSG_PROJECTION_SHORT, null, null, null); 1258326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 125928446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz try { 12605a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null && c.moveToFirst()) { 12615a60e47497f21f64e6d79420dc4c56c1907df22akschulz do { 12625a60e47497f21f64e6d79420dc4c56c1907df22akschulz long id = c.getLong(c.getColumnIndex(MessageColumns._ID)); 12635a60e47497f21f64e6d79420dc4c56c1907df22akschulz long folderId = c.getInt(c.getColumnIndex( 12645a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns.FOLDER_ID)); 12655a60e47497f21f64e6d79420dc4c56c1907df22akschulz int readFlag = c.getInt(c.getColumnIndex( 12665a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns.FLAG_READ)); 12675a60e47497f21f64e6d79420dc4c56c1907df22akschulz Msg msg = new Msg(id, folderId, readFlag); 12685a60e47497f21f64e6d79420dc4c56c1907df22akschulz msgList.put(id, msg); 12695a60e47497f21f64e6d79420dc4c56c1907df22akschulz } while (c.moveToNext()); 127028446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } 127128446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } finally { 12725a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null) c.close(); 12735a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 12745a60e47497f21f64e6d79420dc4c56c1907df22akschulz 12755a60e47497f21f64e6d79420dc4c56c1907df22akschulz synchronized(getMsgListMsg()) { 12765a60e47497f21f64e6d79420dc4c56c1907df22akschulz getMsgListMsg().clear(); 12775a60e47497f21f64e6d79420dc4c56c1907df22akschulz setMsgListMsg(msgList, true); 1278326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 12795a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 12805a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 128128446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz 12825a60e47497f21f64e6d79420dc4c56c1907df22akschulz private void initContactsList() throws RemoteException { 12835a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (V) Log.d(TAG, "initContactsList"); 12845a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(mContactUri == null) { 12855a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (D) Log.d(TAG, "initContactsList() no mContactUri - nothing to init"); 12865a60e47497f21f64e6d79420dc4c56c1907df22akschulz return; 12875a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 12885a60e47497f21f64e6d79420dc4c56c1907df22akschulz Uri uri = mContactUri; 12895a60e47497f21f64e6d79420dc4c56c1907df22akschulz Cursor c = mProviderClient.query(uri, 12905a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.BT_CONTACT_CHATSTATE_PRESENCE_PROJECTION, 12915a60e47497f21f64e6d79420dc4c56c1907df22akschulz null, null, null); 12925a60e47497f21f64e6d79420dc4c56c1907df22akschulz Map<String, BluetoothMapConvoContactElement> contactList = 12935a60e47497f21f64e6d79420dc4c56c1907df22akschulz new HashMap<String, BluetoothMapConvoContactElement>(); 12945a60e47497f21f64e6d79420dc4c56c1907df22akschulz try { 12955a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null && c.moveToFirst()) { 12965a60e47497f21f64e6d79420dc4c56c1907df22akschulz ConvoContactInfo cInfo = new ConvoContactInfo(); 12975a60e47497f21f64e6d79420dc4c56c1907df22akschulz cInfo.setConvoColunms(c); 12985a60e47497f21f64e6d79420dc4c56c1907df22akschulz do { 12995a60e47497f21f64e6d79420dc4c56c1907df22akschulz long convoId = c.getLong(cInfo.mContactColConvoId); 13005a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (convoId == 0) 13015a60e47497f21f64e6d79420dc4c56c1907df22akschulz continue; 13025a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (V) BluetoothMapUtils.printCursor(c); 13035a60e47497f21f64e6d79420dc4c56c1907df22akschulz String uci = c.getString(cInfo.mContactColUci); 13045a60e47497f21f64e6d79420dc4c56c1907df22akschulz String name = c.getString(cInfo.mContactColName); 13055a60e47497f21f64e6d79420dc4c56c1907df22akschulz String displayName = c.getString(cInfo.mContactColNickname); 13065a60e47497f21f64e6d79420dc4c56c1907df22akschulz String presenceStatus = c.getString(cInfo.mContactColPresenceText); 13075a60e47497f21f64e6d79420dc4c56c1907df22akschulz int presenceState = c.getInt(cInfo.mContactColPresenceState); 13085a60e47497f21f64e6d79420dc4c56c1907df22akschulz long lastActivity = c.getLong(cInfo.mContactColLastActive); 13095a60e47497f21f64e6d79420dc4c56c1907df22akschulz int chatState = c.getInt(cInfo.mContactColChatState); 13105a60e47497f21f64e6d79420dc4c56c1907df22akschulz int priority = c.getInt(cInfo.mContactColPriority); 13115a60e47497f21f64e6d79420dc4c56c1907df22akschulz String btUid = c.getString(cInfo.mContactColBtUid); 13125a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapConvoContactElement contact = 13135a60e47497f21f64e6d79420dc4c56c1907df22akschulz new BluetoothMapConvoContactElement(uci, name, displayName, 13145a60e47497f21f64e6d79420dc4c56c1907df22akschulz presenceStatus, presenceState, lastActivity, chatState, 13155a60e47497f21f64e6d79420dc4c56c1907df22akschulz priority, btUid); 13165a60e47497f21f64e6d79420dc4c56c1907df22akschulz contactList.put(uci, contact); 13175a60e47497f21f64e6d79420dc4c56c1907df22akschulz } while (c.moveToNext()); 1318326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 13195a60e47497f21f64e6d79420dc4c56c1907df22akschulz } finally { 13205a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null) c.close(); 13215a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 13225a60e47497f21f64e6d79420dc4c56c1907df22akschulz synchronized(getContactList()) { 13235a60e47497f21f64e6d79420dc4c56c1907df22akschulz getContactList().clear(); 13245a60e47497f21f64e6d79420dc4c56c1907df22akschulz setContactList(contactList, true); 1325326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 1326fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1327fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1328fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private void handleMsgListChangesSms() { 1329fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (V) Log.d(TAG, "handleMsgListChangesSms"); 1330fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1331fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie HashMap<Long, Msg> msgListSms = new HashMap<Long, Msg>(); 13325a60e47497f21f64e6d79420dc4c56c1907df22akschulz boolean listChanged = false; 1333fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 13345a60e47497f21f64e6d79420dc4c56c1907df22akschulz Cursor c; 13355a60e47497f21f64e6d79420dc4c56c1907df22akschulz synchronized(getMsgListSms()) { 1336ea6b2c977e8a621f160f37ef0d36db91d5c29834Hemant Gupta if (mMapEventReportVersion == BluetoothMapUtils.MAP_EVENT_REPORT_V10) { 1337ea6b2c977e8a621f160f37ef0d36db91d5c29834Hemant Gupta c = mResolver.query(Sms.CONTENT_URI, 1338ea6b2c977e8a621f160f37ef0d36db91d5c29834Hemant Gupta SMS_PROJECTION_SHORT, null, null, null); 1339ea6b2c977e8a621f160f37ef0d36db91d5c29834Hemant Gupta } else { 1340ea6b2c977e8a621f160f37ef0d36db91d5c29834Hemant Gupta c = mResolver.query(Sms.CONTENT_URI, 1341ea6b2c977e8a621f160f37ef0d36db91d5c29834Hemant Gupta SMS_PROJECTION_SHORT_EXT, null, null, null); 1342ea6b2c977e8a621f160f37ef0d36db91d5c29834Hemant Gupta } 134328446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz try { 13445a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null && c.moveToFirst()) { 13455a60e47497f21f64e6d79420dc4c56c1907df22akschulz do { 13465a60e47497f21f64e6d79420dc4c56c1907df22akschulz long id = c.getLong(c.getColumnIndex(Sms._ID)); 13475a60e47497f21f64e6d79420dc4c56c1907df22akschulz int type = c.getInt(c.getColumnIndex(Sms.TYPE)); 13485a60e47497f21f64e6d79420dc4c56c1907df22akschulz int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID)); 13495a60e47497f21f64e6d79420dc4c56c1907df22akschulz int read = c.getInt(c.getColumnIndex(Sms.READ)); 13505a60e47497f21f64e6d79420dc4c56c1907df22akschulz 13515a60e47497f21f64e6d79420dc4c56c1907df22akschulz Msg msg = getMsgListSms().remove(id); 13525a60e47497f21f64e6d79420dc4c56c1907df22akschulz 13535a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* We must filter out any actions made by the MCE, hence do not send e.g. 13545a60e47497f21f64e6d79420dc4c56c1907df22akschulz * a message deleted and/or MessageShift for messages deleted by the MCE. */ 13555a60e47497f21f64e6d79420dc4c56c1907df22akschulz 13565a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (msg == null) { 13575a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* New message */ 13585a60e47497f21f64e6d79420dc4c56c1907df22akschulz msg = new Msg(id, type, threadId, read); 13595a60e47497f21f64e6d79420dc4c56c1907df22akschulz msgListSms.put(id, msg); 13605a60e47497f21f64e6d79420dc4c56c1907df22akschulz listChanged = true; 13615a60e47497f21f64e6d79420dc4c56c1907df22akschulz Event evt; 13625a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (mTransmitEvents == true && // extract contact details only if needed 13635a60e47497f21f64e6d79420dc4c56c1907df22akschulz mMapEventReportVersion > 13645a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapUtils.MAP_EVENT_REPORT_V10) { 13655a60e47497f21f64e6d79420dc4c56c1907df22akschulz String date = BluetoothMapUtils.getDateTimeString( 13665a60e47497f21f64e6d79420dc4c56c1907df22akschulz c.getLong(c.getColumnIndex(Sms.DATE))); 13675a60e47497f21f64e6d79420dc4c56c1907df22akschulz String subject = c.getString(c.getColumnIndex(Sms.BODY)); 13685a60e47497f21f64e6d79420dc4c56c1907df22akschulz String name = ""; 13695a60e47497f21f64e6d79420dc4c56c1907df22akschulz String phone = ""; 13705a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (type == 1) { //inbox 13715a60e47497f21f64e6d79420dc4c56c1907df22akschulz phone = c.getString(c.getColumnIndex(Sms.ADDRESS)); 13725a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (phone != null && !phone.isEmpty()) { 13735a60e47497f21f64e6d79420dc4c56c1907df22akschulz name = BluetoothMapContent.getContactNameFromPhone(phone, 13745a60e47497f21f64e6d79420dc4c56c1907df22akschulz mResolver); 13755a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(name == null || name.isEmpty()){ 13765a60e47497f21f64e6d79420dc4c56c1907df22akschulz name = phone; 13775a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 13785a60e47497f21f64e6d79420dc4c56c1907df22akschulz }else{ 13795a60e47497f21f64e6d79420dc4c56c1907df22akschulz name = phone; 13805a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 13815a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else { 13825a60e47497f21f64e6d79420dc4c56c1907df22akschulz TelephonyManager tm = 13835a60e47497f21f64e6d79420dc4c56c1907df22akschulz (TelephonyManager)mContext.getSystemService( 13845a60e47497f21f64e6d79420dc4c56c1907df22akschulz Context.TELEPHONY_SERVICE); 13855a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (tm != null) { 13865a60e47497f21f64e6d79420dc4c56c1907df22akschulz phone = tm.getLine1Number(); 13875a60e47497f21f64e6d79420dc4c56c1907df22akschulz name = tm.getLine1AlphaTag(); 13885a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(name == null || name.isEmpty()){ 13895a60e47497f21f64e6d79420dc4c56c1907df22akschulz name = phone; 13905a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 13915a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 13925a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 13935a60e47497f21f64e6d79420dc4c56c1907df22akschulz String priority = "no";// no priority for sms 13945a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* Incoming message from the network */ 13955a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (mMapEventReportVersion == 13965a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapUtils.MAP_EVENT_REPORT_V11) { 13975a60e47497f21f64e6d79420dc4c56c1907df22akschulz evt = new Event(EVENT_TYPE_NEW, id, getSmsFolderName(type), 13985a60e47497f21f64e6d79420dc4c56c1907df22akschulz mSmsType, date, subject, name, priority); 13995a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else { 14005a60e47497f21f64e6d79420dc4c56c1907df22akschulz evt = new Event(EVENT_TYPE_NEW, id, getSmsFolderName(type), 14015a60e47497f21f64e6d79420dc4c56c1907df22akschulz mSmsType, date, subject, name, priority, 14025a60e47497f21f64e6d79420dc4c56c1907df22akschulz (long)threadId, null); 14035a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 14045a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else { 14055a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* Incoming message from the network */ 14065a60e47497f21f64e6d79420dc4c56c1907df22akschulz evt = new Event(EVENT_TYPE_NEW, id, getSmsFolderName(type), 14075a60e47497f21f64e6d79420dc4c56c1907df22akschulz null, mSmsType); 14085a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 14095a60e47497f21f64e6d79420dc4c56c1907df22akschulz sendEvent(evt); 14105a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else { 14115a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* Existing message */ 14125a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (type != msg.type) { 14135a60e47497f21f64e6d79420dc4c56c1907df22akschulz listChanged = true; 14145a60e47497f21f64e6d79420dc4c56c1907df22akschulz Log.d(TAG, "new type: " + type + " old type: " + msg.type); 14155a60e47497f21f64e6d79420dc4c56c1907df22akschulz String oldFolder = getSmsFolderName(msg.type); 14165a60e47497f21f64e6d79420dc4c56c1907df22akschulz String newFolder = getSmsFolderName(type); 14175a60e47497f21f64e6d79420dc4c56c1907df22akschulz // Filter out the intermediate outbox steps 14185a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(!oldFolder.equalsIgnoreCase(newFolder)) { 14195a60e47497f21f64e6d79420dc4c56c1907df22akschulz Event evt = new Event(EVENT_TYPE_SHIFT, id, 14205a60e47497f21f64e6d79420dc4c56c1907df22akschulz getSmsFolderName(type), oldFolder, mSmsType); 14215a60e47497f21f64e6d79420dc4c56c1907df22akschulz sendEvent(evt); 14225a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 14235a60e47497f21f64e6d79420dc4c56c1907df22akschulz msg.type = type; 14245a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else if(threadId != msg.threadId) { 14255a60e47497f21f64e6d79420dc4c56c1907df22akschulz listChanged = true; 14265a60e47497f21f64e6d79420dc4c56c1907df22akschulz Log.d(TAG, "Message delete change: type: " + type 14275a60e47497f21f64e6d79420dc4c56c1907df22akschulz + " old type: " + msg.type 14285a60e47497f21f64e6d79420dc4c56c1907df22akschulz + "\n threadId: " + threadId 14295a60e47497f21f64e6d79420dc4c56c1907df22akschulz + " old threadId: " + msg.threadId); 14305a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(threadId == DELETED_THREAD_ID) { // Message deleted 14315a60e47497f21f64e6d79420dc4c56c1907df22akschulz // TODO: 14325a60e47497f21f64e6d79420dc4c56c1907df22akschulz // We shall only use the folder attribute, but can't remember 14335a60e47497f21f64e6d79420dc4c56c1907df22akschulz // wether to set it to "deleted" or the name of the folder 14345a60e47497f21f64e6d79420dc4c56c1907df22akschulz // from which the message have been deleted. 1435cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta // "old_folder" used only for MessageShift event 14365a60e47497f21f64e6d79420dc4c56c1907df22akschulz Event evt = new Event(EVENT_TYPE_DELETE, id, 1437cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta getSmsFolderName(msg.type), null, mSmsType); 14385a60e47497f21f64e6d79420dc4c56c1907df22akschulz sendEvent(evt); 14395a60e47497f21f64e6d79420dc4c56c1907df22akschulz msg.threadId = threadId; 14405a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else { // Undelete 14415a60e47497f21f64e6d79420dc4c56c1907df22akschulz Event evt = new Event(EVENT_TYPE_SHIFT, id, 14425a60e47497f21f64e6d79420dc4c56c1907df22akschulz getSmsFolderName(msg.type), 14435a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.FOLDER_NAME_DELETED, mSmsType); 14445a60e47497f21f64e6d79420dc4c56c1907df22akschulz sendEvent(evt); 14455a60e47497f21f64e6d79420dc4c56c1907df22akschulz msg.threadId = threadId; 14465a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 1447326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 14485a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(read != msg.flagRead) { 14495a60e47497f21f64e6d79420dc4c56c1907df22akschulz listChanged = true; 14505a60e47497f21f64e6d79420dc4c56c1907df22akschulz msg.flagRead = read; 14515a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (mMapEventReportVersion > 14525a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapUtils.MAP_EVENT_REPORT_V10) { 14535a60e47497f21f64e6d79420dc4c56c1907df22akschulz Event evt = new Event(EVENT_TYPE_READ_STATUS, id, 14545a60e47497f21f64e6d79420dc4c56c1907df22akschulz getSmsFolderName(msg.type), mSmsType); 14555a60e47497f21f64e6d79420dc4c56c1907df22akschulz sendEvent(evt); 14565a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 1457326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 14585a60e47497f21f64e6d79420dc4c56c1907df22akschulz msgListSms.put(id, msg); 1459fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 14605a60e47497f21f64e6d79420dc4c56c1907df22akschulz } while (c.moveToNext()); 146128446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } 146228446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } finally { 14635a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null) c.close(); 1464fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1465fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 14665a60e47497f21f64e6d79420dc4c56c1907df22akschulz for (Msg msg : getMsgListSms().values()) { 1467cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta // "old_folder" used only for MessageShift event 1468326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Event evt = new Event(EVENT_TYPE_DELETE, msg.id, 1469cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta getSmsFolderName(msg.type), null, mSmsType); 1470fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie sendEvent(evt); 14715a60e47497f21f64e6d79420dc4c56c1907df22akschulz listChanged = true; 1472fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1473fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 14745a60e47497f21f64e6d79420dc4c56c1907df22akschulz setMsgListSms(msgListSms, listChanged); 1475fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1476fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1477fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1478fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private void handleMsgListChangesMms() { 1479fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (V) Log.d(TAG, "handleMsgListChangesMms"); 1480fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1481fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie HashMap<Long, Msg> msgListMms = new HashMap<Long, Msg>(); 14825a60e47497f21f64e6d79420dc4c56c1907df22akschulz boolean listChanged = false; 14835a60e47497f21f64e6d79420dc4c56c1907df22akschulz Cursor c; 14845a60e47497f21f64e6d79420dc4c56c1907df22akschulz synchronized(getMsgListMms()) { 1485ea6b2c977e8a621f160f37ef0d36db91d5c29834Hemant Gupta if (mMapEventReportVersion == BluetoothMapUtils.MAP_EVENT_REPORT_V10) { 1486ea6b2c977e8a621f160f37ef0d36db91d5c29834Hemant Gupta c = mResolver.query(Mms.CONTENT_URI, 1487ea6b2c977e8a621f160f37ef0d36db91d5c29834Hemant Gupta MMS_PROJECTION_SHORT, null, null, null); 1488ea6b2c977e8a621f160f37ef0d36db91d5c29834Hemant Gupta } else { 1489ea6b2c977e8a621f160f37ef0d36db91d5c29834Hemant Gupta c = mResolver.query(Mms.CONTENT_URI, 1490ea6b2c977e8a621f160f37ef0d36db91d5c29834Hemant Gupta MMS_PROJECTION_SHORT_EXT, null, null, null); 1491ea6b2c977e8a621f160f37ef0d36db91d5c29834Hemant Gupta } 1492ea6b2c977e8a621f160f37ef0d36db91d5c29834Hemant Gupta 14935a60e47497f21f64e6d79420dc4c56c1907df22akschulz try{ 14945a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null && c.moveToFirst()) { 14955a60e47497f21f64e6d79420dc4c56c1907df22akschulz do { 14965a60e47497f21f64e6d79420dc4c56c1907df22akschulz long id = c.getLong(c.getColumnIndex(Mms._ID)); 14975a60e47497f21f64e6d79420dc4c56c1907df22akschulz int type = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX)); 14985a60e47497f21f64e6d79420dc4c56c1907df22akschulz int mtype = c.getInt(c.getColumnIndex(Mms.MESSAGE_TYPE)); 14995a60e47497f21f64e6d79420dc4c56c1907df22akschulz int threadId = c.getInt(c.getColumnIndex(Mms.THREAD_ID)); 15005a60e47497f21f64e6d79420dc4c56c1907df22akschulz // TODO: Go through code to see if we have an issue with mismatch in types 15015a60e47497f21f64e6d79420dc4c56c1907df22akschulz // for threadId. Seems to be a long in DB?? 15025a60e47497f21f64e6d79420dc4c56c1907df22akschulz int read = c.getInt(c.getColumnIndex(Mms.READ)); 15035a60e47497f21f64e6d79420dc4c56c1907df22akschulz 15045a60e47497f21f64e6d79420dc4c56c1907df22akschulz Msg msg = getMsgListMms().remove(id); 15055a60e47497f21f64e6d79420dc4c56c1907df22akschulz 15065a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* We must filter out any actions made by the MCE, hence do not send 15075a60e47497f21f64e6d79420dc4c56c1907df22akschulz * e.g. a message deleted and/or MessageShift for messages deleted by the 15085a60e47497f21f64e6d79420dc4c56c1907df22akschulz * MCE.*/ 15095a60e47497f21f64e6d79420dc4c56c1907df22akschulz 15105a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (msg == null) { 15115a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* New message - only notify on retrieve conf */ 15125a60e47497f21f64e6d79420dc4c56c1907df22akschulz listChanged = true; 15135a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (getMmsFolderName(type).equalsIgnoreCase( 15145a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.FOLDER_NAME_INBOX) && 15155a60e47497f21f64e6d79420dc4c56c1907df22akschulz mtype != MESSAGE_TYPE_RETRIEVE_CONF) { 1516fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie continue; 15175a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 15185a60e47497f21f64e6d79420dc4c56c1907df22akschulz msg = new Msg(id, type, threadId, read); 15195a60e47497f21f64e6d79420dc4c56c1907df22akschulz msgListMms.put(id, msg); 1520326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Event evt; 15215a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (mTransmitEvents == true && // extract contact details only if needed 15225a60e47497f21f64e6d79420dc4c56c1907df22akschulz mMapEventReportVersion != 15235a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapUtils.MAP_EVENT_REPORT_V10) { 15245a60e47497f21f64e6d79420dc4c56c1907df22akschulz String date = BluetoothMapUtils.getDateTimeString( 15255a60e47497f21f64e6d79420dc4c56c1907df22akschulz c.getLong(c.getColumnIndex(Mms.DATE))); 15265a60e47497f21f64e6d79420dc4c56c1907df22akschulz String subject = c.getString(c.getColumnIndex(Mms.SUBJECT)); 15275a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (subject == null || subject.length() == 0) { 15285a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* Get subject from mms text body parts - if any exists */ 15295a60e47497f21f64e6d79420dc4c56c1907df22akschulz subject = BluetoothMapContent.getTextPartsMms(mResolver, id); 15305a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 15315a60e47497f21f64e6d79420dc4c56c1907df22akschulz int tmpPri = c.getInt(c.getColumnIndex(Mms.PRIORITY)); 15325a60e47497f21f64e6d79420dc4c56c1907df22akschulz Log.d(TAG, "TEMP handleMsgListChangesMms, " + 15335a60e47497f21f64e6d79420dc4c56c1907df22akschulz "newMessage 'read' state: " + read + 15345a60e47497f21f64e6d79420dc4c56c1907df22akschulz "priority: " + tmpPri); 15355a60e47497f21f64e6d79420dc4c56c1907df22akschulz 15365a60e47497f21f64e6d79420dc4c56c1907df22akschulz String address = BluetoothMapContent.getAddressMms( 15375a60e47497f21f64e6d79420dc4c56c1907df22akschulz mResolver,id,BluetoothMapContent.MMS_FROM); 15385a60e47497f21f64e6d79420dc4c56c1907df22akschulz String priority = "no"; 15395a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(tmpPri == PduHeaders.PRIORITY_HIGH) 15405a60e47497f21f64e6d79420dc4c56c1907df22akschulz priority = "yes"; 15415a60e47497f21f64e6d79420dc4c56c1907df22akschulz 15425a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* Incoming message from the network */ 15435a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (mMapEventReportVersion == 15445a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapUtils.MAP_EVENT_REPORT_V11) { 15455a60e47497f21f64e6d79420dc4c56c1907df22akschulz evt = new Event(EVENT_TYPE_NEW, id, getMmsFolderName(type), 15465a60e47497f21f64e6d79420dc4c56c1907df22akschulz TYPE.MMS, date, subject, address, priority); 15475a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else { 15485a60e47497f21f64e6d79420dc4c56c1907df22akschulz evt = new Event(EVENT_TYPE_NEW, id, getMmsFolderName(type), 15495a60e47497f21f64e6d79420dc4c56c1907df22akschulz TYPE.MMS, date, subject, address, priority, 15505a60e47497f21f64e6d79420dc4c56c1907df22akschulz (long)threadId, null); 15515a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 15525a60e47497f21f64e6d79420dc4c56c1907df22akschulz 15535a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else { 15545a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* Incoming message from the network */ 15555a60e47497f21f64e6d79420dc4c56c1907df22akschulz evt = new Event(EVENT_TYPE_NEW, id, getMmsFolderName(type), 15565a60e47497f21f64e6d79420dc4c56c1907df22akschulz null, TYPE.MMS); 1557326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 15585a60e47497f21f64e6d79420dc4c56c1907df22akschulz 15595a60e47497f21f64e6d79420dc4c56c1907df22akschulz sendEvent(evt); 15605a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else { 15615a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* Existing message */ 15625a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (type != msg.type) { 15635a60e47497f21f64e6d79420dc4c56c1907df22akschulz Log.d(TAG, "new type: " + type + " old type: " + msg.type); 15645a60e47497f21f64e6d79420dc4c56c1907df22akschulz Event evt; 15655a60e47497f21f64e6d79420dc4c56c1907df22akschulz listChanged = true; 15665a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(msg.localInitiatedSend == false) { 15675a60e47497f21f64e6d79420dc4c56c1907df22akschulz // Only send events about local initiated changes 15685a60e47497f21f64e6d79420dc4c56c1907df22akschulz evt = new Event(EVENT_TYPE_SHIFT, id, getMmsFolderName(type), 15695a60e47497f21f64e6d79420dc4c56c1907df22akschulz getMmsFolderName(msg.type), TYPE.MMS); 15705a60e47497f21f64e6d79420dc4c56c1907df22akschulz sendEvent(evt); 15715a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 15725a60e47497f21f64e6d79420dc4c56c1907df22akschulz msg.type = type; 15735a60e47497f21f64e6d79420dc4c56c1907df22akschulz 15745a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (getMmsFolderName(type).equalsIgnoreCase( 15755a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.FOLDER_NAME_SENT) 15765a60e47497f21f64e6d79420dc4c56c1907df22akschulz && msg.localInitiatedSend == true) { 15775a60e47497f21f64e6d79420dc4c56c1907df22akschulz // Stop tracking changes for this message 15785a60e47497f21f64e6d79420dc4c56c1907df22akschulz msg.localInitiatedSend = false; 15795a60e47497f21f64e6d79420dc4c56c1907df22akschulz evt = new Event(EVENT_TYPE_SENDING_SUCCESS, id, 15805a60e47497f21f64e6d79420dc4c56c1907df22akschulz getMmsFolderName(type), null, TYPE.MMS); 15815a60e47497f21f64e6d79420dc4c56c1907df22akschulz sendEvent(evt); 15825a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 15835a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else if(threadId != msg.threadId) { 15845a60e47497f21f64e6d79420dc4c56c1907df22akschulz Log.d(TAG, "Message delete change: type: " + type + " old type: " 15855a60e47497f21f64e6d79420dc4c56c1907df22akschulz + msg.type 15865a60e47497f21f64e6d79420dc4c56c1907df22akschulz + "\n threadId: " + threadId + " old threadId: " 15875a60e47497f21f64e6d79420dc4c56c1907df22akschulz + msg.threadId); 15885a60e47497f21f64e6d79420dc4c56c1907df22akschulz listChanged = true; 15895a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(threadId == DELETED_THREAD_ID) { // Message deleted 1590cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta // "old_folder" used only for MessageShift event 15915a60e47497f21f64e6d79420dc4c56c1907df22akschulz Event evt = new Event(EVENT_TYPE_DELETE, id, 1592cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta getMmsFolderName(msg.type), null, TYPE.MMS); 15935a60e47497f21f64e6d79420dc4c56c1907df22akschulz sendEvent(evt); 15945a60e47497f21f64e6d79420dc4c56c1907df22akschulz msg.threadId = threadId; 15955a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else { // Undelete 15965a60e47497f21f64e6d79420dc4c56c1907df22akschulz Event evt = new Event(EVENT_TYPE_SHIFT, id, 15975a60e47497f21f64e6d79420dc4c56c1907df22akschulz getMmsFolderName(msg.type), 15985a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.FOLDER_NAME_DELETED, TYPE.MMS); 15995a60e47497f21f64e6d79420dc4c56c1907df22akschulz sendEvent(evt); 16005a60e47497f21f64e6d79420dc4c56c1907df22akschulz msg.threadId = threadId; 16015a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 1602fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 16035a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(read != msg.flagRead) { 16045a60e47497f21f64e6d79420dc4c56c1907df22akschulz listChanged = true; 16055a60e47497f21f64e6d79420dc4c56c1907df22akschulz msg.flagRead = read; 16065a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (mMapEventReportVersion > 16075a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapUtils.MAP_EVENT_REPORT_V10) { 16085a60e47497f21f64e6d79420dc4c56c1907df22akschulz Event evt = new Event(EVENT_TYPE_READ_STATUS, id, 16095a60e47497f21f64e6d79420dc4c56c1907df22akschulz getMmsFolderName(msg.type), TYPE.MMS); 16105a60e47497f21f64e6d79420dc4c56c1907df22akschulz sendEvent(evt); 16115a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 1612326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 16135a60e47497f21f64e6d79420dc4c56c1907df22akschulz msgListMms.put(id, msg); 1614fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 16155a60e47497f21f64e6d79420dc4c56c1907df22akschulz } while (c.moveToNext()); 16165a60e47497f21f64e6d79420dc4c56c1907df22akschulz 161728446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } 161828446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } finally { 16195a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null) c.close(); 1620fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 16215a60e47497f21f64e6d79420dc4c56c1907df22akschulz for (Msg msg : getMsgListMms().values()) { 1622cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta // "old_folder" used only for MessageShift event 1623326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Event evt = new Event(EVENT_TYPE_DELETE, msg.id, 1624cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta getMmsFolderName(msg.type), null, TYPE.MMS); 1625fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie sendEvent(evt); 16265a60e47497f21f64e6d79420dc4c56c1907df22akschulz listChanged = true; 1627fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 16285a60e47497f21f64e6d79420dc4c56c1907df22akschulz setMsgListMms(msgListMms, listChanged); 1629fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1630fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1631fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 16325a60e47497f21f64e6d79420dc4c56c1907df22akschulz private void handleMsgListChangesMsg(Uri uri) throws RemoteException{ 16335a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (V) Log.v(TAG, "handleMsgListChangesMsg uri: " + uri.toString()); 1634326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 1635326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // TODO: Change observer to handle accountId and message ID if present 1636326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 16375a60e47497f21f64e6d79420dc4c56c1907df22akschulz HashMap<Long, Msg> msgList = new HashMap<Long, Msg>(); 16385a60e47497f21f64e6d79420dc4c56c1907df22akschulz Cursor c; 16395a60e47497f21f64e6d79420dc4c56c1907df22akschulz boolean listChanged = false; 16405a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (mMapEventReportVersion == BluetoothMapUtils.MAP_EVENT_REPORT_V10) { 16415a60e47497f21f64e6d79420dc4c56c1907df22akschulz c = mProviderClient.query(mMessageUri, MSG_PROJECTION_SHORT, null, null, null); 16425a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else if (mMapEventReportVersion == BluetoothMapUtils.MAP_EVENT_REPORT_V11) { 16435a60e47497f21f64e6d79420dc4c56c1907df22akschulz c = mProviderClient.query(mMessageUri, MSG_PROJECTION_SHORT_EXT, null, null, null); 16445a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else { 16455a60e47497f21f64e6d79420dc4c56c1907df22akschulz c = mProviderClient.query(mMessageUri, MSG_PROJECTION_SHORT_EXT2, null, null, null); 16465a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 16475a60e47497f21f64e6d79420dc4c56c1907df22akschulz synchronized(getMsgListMsg()) { 164828446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz try { 16495a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null && c.moveToFirst()) { 16505a60e47497f21f64e6d79420dc4c56c1907df22akschulz do { 16515a60e47497f21f64e6d79420dc4c56c1907df22akschulz long id = c.getLong(c.getColumnIndex( 16525a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns._ID)); 16535a60e47497f21f64e6d79420dc4c56c1907df22akschulz int folderId = c.getInt(c.getColumnIndex( 16545a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns.FOLDER_ID)); 16555a60e47497f21f64e6d79420dc4c56c1907df22akschulz int readFlag = c.getInt(c.getColumnIndex( 16565a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns.FLAG_READ)); 16575a60e47497f21f64e6d79420dc4c56c1907df22akschulz Msg msg = getMsgListMsg().remove(id); 16585a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapFolderElement folderElement = mFolders.getFolderById(folderId); 16595a60e47497f21f64e6d79420dc4c56c1907df22akschulz String newFolder; 16605a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(folderElement != null) { 16615a60e47497f21f64e6d79420dc4c56c1907df22akschulz newFolder = folderElement.getFullPath(); 16625a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else { 16635a60e47497f21f64e6d79420dc4c56c1907df22akschulz // This can happen if a new folder is created while connected 16645a60e47497f21f64e6d79420dc4c56c1907df22akschulz newFolder = "unknown"; 16655a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 16665a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* We must filter out any actions made by the MCE, hence do not send e.g. 16675a60e47497f21f64e6d79420dc4c56c1907df22akschulz * a message deleted and/or MessageShift for messages deleted by the MCE. */ 16685a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (msg == null) { 16695a60e47497f21f64e6d79420dc4c56c1907df22akschulz listChanged = true; 16705a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* New message - created with message unread */ 16715a60e47497f21f64e6d79420dc4c56c1907df22akschulz msg = new Msg(id, folderId, 0, readFlag); 16725a60e47497f21f64e6d79420dc4c56c1907df22akschulz msgList.put(id, msg); 16735a60e47497f21f64e6d79420dc4c56c1907df22akschulz Event evt; 16745a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* Incoming message from the network */ 16755a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (mMapEventReportVersion != BluetoothMapUtils.MAP_EVENT_REPORT_V10) { 16765a60e47497f21f64e6d79420dc4c56c1907df22akschulz String date = BluetoothMapUtils.getDateTimeString( 16775a60e47497f21f64e6d79420dc4c56c1907df22akschulz c.getLong(c.getColumnIndex( 16785a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns.DATE))); 16795a60e47497f21f64e6d79420dc4c56c1907df22akschulz String subject = c.getString(c.getColumnIndex( 16805a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns.SUBJECT)); 16815a60e47497f21f64e6d79420dc4c56c1907df22akschulz String address = c.getString(c.getColumnIndex( 16825a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns.FROM_LIST)); 16835a60e47497f21f64e6d79420dc4c56c1907df22akschulz String priority = "no"; 16845a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(c.getInt(c.getColumnIndex( 16855a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns.FLAG_HIGH_PRIORITY)) 16865a60e47497f21f64e6d79420dc4c56c1907df22akschulz == 1) 16875a60e47497f21f64e6d79420dc4c56c1907df22akschulz priority = "yes"; 16885a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (mMapEventReportVersion == 16895a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapUtils.MAP_EVENT_REPORT_V11) { 16905a60e47497f21f64e6d79420dc4c56c1907df22akschulz evt = new Event(EVENT_TYPE_NEW, id, newFolder, 16915a60e47497f21f64e6d79420dc4c56c1907df22akschulz mAccount.getType(), date, subject, address, priority); 16925a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else { 16935a60e47497f21f64e6d79420dc4c56c1907df22akschulz long thread_id = c.getLong(c.getColumnIndex( 16945a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns.THREAD_ID)); 16955a60e47497f21f64e6d79420dc4c56c1907df22akschulz String thread_name = c.getString(c.getColumnIndex( 16965a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.MessageColumns.THREAD_NAME)); 16975a60e47497f21f64e6d79420dc4c56c1907df22akschulz evt = new Event(EVENT_TYPE_NEW, id, newFolder, 16985a60e47497f21f64e6d79420dc4c56c1907df22akschulz mAccount.getType(), date, subject, address, priority, 16995a60e47497f21f64e6d79420dc4c56c1907df22akschulz thread_id, thread_name); 17005a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 1701326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 17025a60e47497f21f64e6d79420dc4c56c1907df22akschulz evt = new Event(EVENT_TYPE_NEW, id, newFolder, null, TYPE.EMAIL); 1703326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 17045a60e47497f21f64e6d79420dc4c56c1907df22akschulz sendEvent(evt); 17055a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else { 17065a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* Existing message */ 17075a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (folderId != msg.folderId && msg.folderId != -1) { 17085a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (D) Log.d(TAG, "new folderId: " + folderId + " old folderId: " 17095a60e47497f21f64e6d79420dc4c56c1907df22akschulz + msg.folderId); 17105a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapFolderElement oldFolderElement = 17115a60e47497f21f64e6d79420dc4c56c1907df22akschulz mFolders.getFolderById(msg.folderId); 17125a60e47497f21f64e6d79420dc4c56c1907df22akschulz String oldFolder; 17135a60e47497f21f64e6d79420dc4c56c1907df22akschulz listChanged = true; 17145a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(oldFolderElement != null) { 17155a60e47497f21f64e6d79420dc4c56c1907df22akschulz oldFolder = oldFolderElement.getFullPath(); 1716326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 17175a60e47497f21f64e6d79420dc4c56c1907df22akschulz // This can happen if a new folder is created while connected 17185a60e47497f21f64e6d79420dc4c56c1907df22akschulz oldFolder = "unknown"; 17195a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 17205a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapFolderElement deletedFolder = 17215a60e47497f21f64e6d79420dc4c56c1907df22akschulz mFolders.getFolderByName( 17225a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.FOLDER_NAME_DELETED); 17235a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapFolderElement sentFolder = 17245a60e47497f21f64e6d79420dc4c56c1907df22akschulz mFolders.getFolderByName( 17255a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.FOLDER_NAME_SENT); 17265a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* 17275a60e47497f21f64e6d79420dc4c56c1907df22akschulz * If the folder is now 'deleted', send a deleted-event in stead of 17285a60e47497f21f64e6d79420dc4c56c1907df22akschulz * a shift or if message is sent initiated by MAP Client, then send 17295a60e47497f21f64e6d79420dc4c56c1907df22akschulz * sending-success otherwise send folderShift 17305a60e47497f21f64e6d79420dc4c56c1907df22akschulz */ 17315a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(deletedFolder != null && deletedFolder.getFolderId() 17325a60e47497f21f64e6d79420dc4c56c1907df22akschulz == folderId) { 1733cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta // "old_folder" used only for MessageShift event 1734cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta Event evt = new Event(EVENT_TYPE_DELETE, msg.id, oldFolder, 1735cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta null, mAccount.getType()); 17365a60e47497f21f64e6d79420dc4c56c1907df22akschulz sendEvent(evt); 17375a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else if(sentFolder != null 17385a60e47497f21f64e6d79420dc4c56c1907df22akschulz && sentFolder.getFolderId() == folderId 17395a60e47497f21f64e6d79420dc4c56c1907df22akschulz && msg.localInitiatedSend == true) { 17405a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(msg.transparent) { 17415a60e47497f21f64e6d79420dc4c56c1907df22akschulz mResolver.delete( 17425a60e47497f21f64e6d79420dc4c56c1907df22akschulz ContentUris.withAppendedId(mMessageUri, id), 17435a60e47497f21f64e6d79420dc4c56c1907df22akschulz null, null); 17445a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else { 17455a60e47497f21f64e6d79420dc4c56c1907df22akschulz msg.localInitiatedSend = false; 17465a60e47497f21f64e6d79420dc4c56c1907df22akschulz Event evt = new Event(EVENT_TYPE_SENDING_SUCCESS, msg.id, 17475a60e47497f21f64e6d79420dc4c56c1907df22akschulz oldFolder, null, mAccount.getType()); 17485a60e47497f21f64e6d79420dc4c56c1907df22akschulz sendEvent(evt); 17495a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 17505a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else { 17515a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (!oldFolder.equalsIgnoreCase("root")) { 17525a60e47497f21f64e6d79420dc4c56c1907df22akschulz Event evt = new Event(EVENT_TYPE_SHIFT, id, newFolder, 17535a60e47497f21f64e6d79420dc4c56c1907df22akschulz oldFolder, mAccount.getType()); 17545a60e47497f21f64e6d79420dc4c56c1907df22akschulz sendEvent(evt); 17555a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 17565a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 17575a60e47497f21f64e6d79420dc4c56c1907df22akschulz msg.folderId = folderId; 17585a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 17595a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(readFlag != msg.flagRead) { 17605a60e47497f21f64e6d79420dc4c56c1907df22akschulz listChanged = true; 17615a60e47497f21f64e6d79420dc4c56c1907df22akschulz 17625a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (mMapEventReportVersion > 17635a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapUtils.MAP_EVENT_REPORT_V10) { 17645a60e47497f21f64e6d79420dc4c56c1907df22akschulz Event evt = new Event(EVENT_TYPE_READ_STATUS, id, newFolder, 17655a60e47497f21f64e6d79420dc4c56c1907df22akschulz mAccount.getType()); 1766326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde sendEvent(evt); 17675a60e47497f21f64e6d79420dc4c56c1907df22akschulz msg.flagRead = readFlag; 1768326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 1769326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 17705a60e47497f21f64e6d79420dc4c56c1907df22akschulz 17715a60e47497f21f64e6d79420dc4c56c1907df22akschulz msgList.put(id, msg); 1772326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 17735a60e47497f21f64e6d79420dc4c56c1907df22akschulz } while (c.moveToNext()); 177428446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } 177528446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } finally { 17765a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null) c.close(); 1777326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 1778326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // For all messages no longer in the database send a delete notification 17795a60e47497f21f64e6d79420dc4c56c1907df22akschulz for (Msg msg : getMsgListMsg().values()) { 17805a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapFolderElement oldFolderElement = mFolders.getFolderById(msg.folderId); 1781326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde String oldFolder; 17825a60e47497f21f64e6d79420dc4c56c1907df22akschulz listChanged = true; 1783326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(oldFolderElement != null) { 1784326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde oldFolder = oldFolderElement.getFullPath(); 1785326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 1786326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde oldFolder = "unknown"; 1787326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 17885a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* Some e-mail clients delete the message after sending, and creates a 17895a60e47497f21f64e6d79420dc4c56c1907df22akschulz * new message in sent. We cannot track the message anymore, hence send both a 17905a60e47497f21f64e6d79420dc4c56c1907df22akschulz * send success and delete message. 1791326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde */ 1792326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(msg.localInitiatedSend == true) { 1793326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde msg.localInitiatedSend = false; 1794326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // If message is send with transparency don't set folder as message is deleted 1795326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (msg.transparent) 1796326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde oldFolder = null; 17975a60e47497f21f64e6d79420dc4c56c1907df22akschulz Event evt = new Event(EVENT_TYPE_SENDING_SUCCESS, msg.id, oldFolder, null, 17985a60e47497f21f64e6d79420dc4c56c1907df22akschulz mAccount.getType()); 1799326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde sendEvent(evt); 1800326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 1801326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* As this message deleted is only send on a real delete - don't set folder. 1802326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * - only send delete event if message is not sent with transparency 1803326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde */ 1804326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (!msg.transparent) { 1805326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 1806cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta // "old_folder" used only for MessageShift event 1807cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta Event evt = new Event(EVENT_TYPE_DELETE, msg.id, oldFolder, 1808cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta null, mAccount.getType()); 1809326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde sendEvent(evt); 1810326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 1811326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 18125a60e47497f21f64e6d79420dc4c56c1907df22akschulz setMsgListMsg(msgList, listChanged); 1813326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 1814326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 1815326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 1816326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private void handleMsgListChanges(Uri uri) { 1817326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(uri.getAuthority().equals(mAuthority)) { 1818326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde try { 18195a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(D) Log.d(TAG, "handleMsgListChanges: account type = " 18205a60e47497f21f64e6d79420dc4c56c1907df22akschulz + mAccount.getType().toString()); 18215a60e47497f21f64e6d79420dc4c56c1907df22akschulz handleMsgListChangesMsg(uri); 18225a60e47497f21f64e6d79420dc4c56c1907df22akschulz } catch(RemoteException e) { 1823326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mMasInstance.restartObexServerSession(); 18245a60e47497f21f64e6d79420dc4c56c1907df22akschulz Log.w(TAG, "Problems contacting the ContentProvider in mas Instance " 18255a60e47497f21f64e6d79420dc4c56c1907df22akschulz + mMasId + " restaring ObexServerSession"); 1826326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 1827326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 18285a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 18295a60e47497f21f64e6d79420dc4c56c1907df22akschulz // TODO: check to see if there could be problem with IM and SMS in one instance 18305a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (mEnableSmsMms) { 1831326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde handleMsgListChangesSms(); 1832326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde handleMsgListChangesMms(); 1833326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 1834326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 1835326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 18365a60e47497f21f64e6d79420dc4c56c1907df22akschulz private void handleContactListChanges(Uri uri) { 18375a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (uri.getAuthority().equals(mAuthority)) { 18385a60e47497f21f64e6d79420dc4c56c1907df22akschulz try { 18395a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (V) Log.v(TAG,"handleContactListChanges uri: " + uri.toString()); 18405a60e47497f21f64e6d79420dc4c56c1907df22akschulz Cursor c = null; 18415a60e47497f21f64e6d79420dc4c56c1907df22akschulz boolean listChanged = false; 18425a60e47497f21f64e6d79420dc4c56c1907df22akschulz try { 18435a60e47497f21f64e6d79420dc4c56c1907df22akschulz ConvoContactInfo cInfo = new ConvoContactInfo(); 18445a60e47497f21f64e6d79420dc4c56c1907df22akschulz 18455a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (mMapEventReportVersion != BluetoothMapUtils.MAP_EVENT_REPORT_V10 18465a60e47497f21f64e6d79420dc4c56c1907df22akschulz && mMapEventReportVersion != BluetoothMapUtils.MAP_EVENT_REPORT_V11) { 18475a60e47497f21f64e6d79420dc4c56c1907df22akschulz c = mProviderClient 18485a60e47497f21f64e6d79420dc4c56c1907df22akschulz .query(mContactUri, 18495a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract. 18505a60e47497f21f64e6d79420dc4c56c1907df22akschulz BT_CONTACT_CHATSTATE_PRESENCE_PROJECTION, 18515a60e47497f21f64e6d79420dc4c56c1907df22akschulz null, null, null); 18525a60e47497f21f64e6d79420dc4c56c1907df22akschulz cInfo.setConvoColunms(c); 18535a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else { 18545a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (V) Log.v(TAG,"handleContactListChanges MAP version does not" + 18555a60e47497f21f64e6d79420dc4c56c1907df22akschulz "support convocontact notifications"); 18565a60e47497f21f64e6d79420dc4c56c1907df22akschulz return; 18575a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 18585a60e47497f21f64e6d79420dc4c56c1907df22akschulz 18595a60e47497f21f64e6d79420dc4c56c1907df22akschulz HashMap<String, BluetoothMapConvoContactElement> contactList = 18605a60e47497f21f64e6d79420dc4c56c1907df22akschulz new HashMap<String, 18615a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapConvoContactElement>(getContactList().size()); 18625a60e47497f21f64e6d79420dc4c56c1907df22akschulz 18635a60e47497f21f64e6d79420dc4c56c1907df22akschulz synchronized (getContactList()) { 18645a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null && c.moveToFirst()) { 18655a60e47497f21f64e6d79420dc4c56c1907df22akschulz do { 18665a60e47497f21f64e6d79420dc4c56c1907df22akschulz String uci = c.getString(cInfo.mContactColUci); 18675a60e47497f21f64e6d79420dc4c56c1907df22akschulz long convoId = c.getLong(cInfo.mContactColConvoId); 18685a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (convoId == 0) 18695a60e47497f21f64e6d79420dc4c56c1907df22akschulz continue; 18705a60e47497f21f64e6d79420dc4c56c1907df22akschulz 18715a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (V) BluetoothMapUtils.printCursor(c); 18725a60e47497f21f64e6d79420dc4c56c1907df22akschulz 18735a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapConvoContactElement contact = 18745a60e47497f21f64e6d79420dc4c56c1907df22akschulz getContactList().remove(uci); 18755a60e47497f21f64e6d79420dc4c56c1907df22akschulz 18765a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* 18775a60e47497f21f64e6d79420dc4c56c1907df22akschulz * We must filter out any actions made by the 18785a60e47497f21f64e6d79420dc4c56c1907df22akschulz * MCE, hence do not send e.g. a message deleted 18795a60e47497f21f64e6d79420dc4c56c1907df22akschulz * and/or MessageShift for messages deleted by 18805a60e47497f21f64e6d79420dc4c56c1907df22akschulz * the MCE. 18815a60e47497f21f64e6d79420dc4c56c1907df22akschulz */ 18825a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (contact == null) { 18835a60e47497f21f64e6d79420dc4c56c1907df22akschulz listChanged = true; 18845a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* 18855a60e47497f21f64e6d79420dc4c56c1907df22akschulz * New contact - added to conversation and 18865a60e47497f21f64e6d79420dc4c56c1907df22akschulz * tracked here 18875a60e47497f21f64e6d79420dc4c56c1907df22akschulz */ 18885a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (mMapEventReportVersion 18895a60e47497f21f64e6d79420dc4c56c1907df22akschulz != BluetoothMapUtils.MAP_EVENT_REPORT_V10 18905a60e47497f21f64e6d79420dc4c56c1907df22akschulz && mMapEventReportVersion 18915a60e47497f21f64e6d79420dc4c56c1907df22akschulz != BluetoothMapUtils.MAP_EVENT_REPORT_V11) { 18925a60e47497f21f64e6d79420dc4c56c1907df22akschulz Event evt; 18935a60e47497f21f64e6d79420dc4c56c1907df22akschulz String name = c 18945a60e47497f21f64e6d79420dc4c56c1907df22akschulz .getString(cInfo.mContactColName); 18955a60e47497f21f64e6d79420dc4c56c1907df22akschulz String displayName = c 18965a60e47497f21f64e6d79420dc4c56c1907df22akschulz .getString(cInfo.mContactColNickname); 18975a60e47497f21f64e6d79420dc4c56c1907df22akschulz String presenceStatus = c 18985a60e47497f21f64e6d79420dc4c56c1907df22akschulz .getString(cInfo.mContactColPresenceText); 18995a60e47497f21f64e6d79420dc4c56c1907df22akschulz int presenceState = c 19005a60e47497f21f64e6d79420dc4c56c1907df22akschulz .getInt(cInfo.mContactColPresenceState); 19015a60e47497f21f64e6d79420dc4c56c1907df22akschulz long lastActivity = c 19025a60e47497f21f64e6d79420dc4c56c1907df22akschulz .getLong(cInfo.mContactColLastActive); 19035a60e47497f21f64e6d79420dc4c56c1907df22akschulz int chatState = c 19045a60e47497f21f64e6d79420dc4c56c1907df22akschulz .getInt(cInfo.mContactColChatState); 19055a60e47497f21f64e6d79420dc4c56c1907df22akschulz int priority = c 19065a60e47497f21f64e6d79420dc4c56c1907df22akschulz .getInt(cInfo.mContactColPriority); 19075a60e47497f21f64e6d79420dc4c56c1907df22akschulz String btUid = c 19085a60e47497f21f64e6d79420dc4c56c1907df22akschulz .getString(cInfo.mContactColBtUid); 19095a60e47497f21f64e6d79420dc4c56c1907df22akschulz 19105a60e47497f21f64e6d79420dc4c56c1907df22akschulz // Get Conversation information for 19115a60e47497f21f64e6d79420dc4c56c1907df22akschulz // event 19125a60e47497f21f64e6d79420dc4c56c1907df22akschulz// Uri convoUri = Uri 19135a60e47497f21f64e6d79420dc4c56c1907df22akschulz// .parse(mAccount.mBase_uri 19145a60e47497f21f64e6d79420dc4c56c1907df22akschulz// + "/" 19155a60e47497f21f64e6d79420dc4c56c1907df22akschulz// + BluetoothMapContract.TABLE_CONVERSATION); 19165a60e47497f21f64e6d79420dc4c56c1907df22akschulz// String whereClause = "contacts._id = " 19175a60e47497f21f64e6d79420dc4c56c1907df22akschulz// + convoId; 19185a60e47497f21f64e6d79420dc4c56c1907df22akschulz// Cursor cConvo = mProviderClient 19195a60e47497f21f64e6d79420dc4c56c1907df22akschulz// .query(convoUri, 19205a60e47497f21f64e6d79420dc4c56c1907df22akschulz// BluetoothMapContract.BT_CONVERSATION_PROJECTION, 19215a60e47497f21f64e6d79420dc4c56c1907df22akschulz// whereClause, null, null); 19225a60e47497f21f64e6d79420dc4c56c1907df22akschulz // TODO: will move out of the loop when merged with CB's 19235a60e47497f21f64e6d79420dc4c56c1907df22akschulz // changes make sure to look up col index out side loop 19245a60e47497f21f64e6d79420dc4c56c1907df22akschulz String convoName = null; 19255a60e47497f21f64e6d79420dc4c56c1907df22akschulz// if (cConvo != null 19265a60e47497f21f64e6d79420dc4c56c1907df22akschulz// && cConvo.moveToFirst()) { 19275a60e47497f21f64e6d79420dc4c56c1907df22akschulz// convoName = cConvo 19285a60e47497f21f64e6d79420dc4c56c1907df22akschulz// .getString(cConvo 19295a60e47497f21f64e6d79420dc4c56c1907df22akschulz// .getColumnIndex(BluetoothMapContract.ConvoContactColumns.NAME)); 19305a60e47497f21f64e6d79420dc4c56c1907df22akschulz// } 19315a60e47497f21f64e6d79420dc4c56c1907df22akschulz 19325a60e47497f21f64e6d79420dc4c56c1907df22akschulz contact = new BluetoothMapConvoContactElement( 19335a60e47497f21f64e6d79420dc4c56c1907df22akschulz uci, name, displayName, 19345a60e47497f21f64e6d79420dc4c56c1907df22akschulz presenceStatus, presenceState, 19355a60e47497f21f64e6d79420dc4c56c1907df22akschulz lastActivity, chatState, 19365a60e47497f21f64e6d79420dc4c56c1907df22akschulz priority, btUid); 19375a60e47497f21f64e6d79420dc4c56c1907df22akschulz 19385a60e47497f21f64e6d79420dc4c56c1907df22akschulz contactList.put(uci, contact); 19395a60e47497f21f64e6d79420dc4c56c1907df22akschulz 19405a60e47497f21f64e6d79420dc4c56c1907df22akschulz evt = new Event( 19415a60e47497f21f64e6d79420dc4c56c1907df22akschulz EVENT_TYPE_CONVERSATION, 19425a60e47497f21f64e6d79420dc4c56c1907df22akschulz uci, 19435a60e47497f21f64e6d79420dc4c56c1907df22akschulz mAccount.getType(), 19445a60e47497f21f64e6d79420dc4c56c1907df22akschulz name, 19455a60e47497f21f64e6d79420dc4c56c1907df22akschulz String.valueOf(priority), 19465a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapUtils 19475a60e47497f21f64e6d79420dc4c56c1907df22akschulz .getDateTimeString(lastActivity), 19485a60e47497f21f64e6d79420dc4c56c1907df22akschulz convoId, convoName, 19495a60e47497f21f64e6d79420dc4c56c1907df22akschulz presenceState, presenceStatus, 19505a60e47497f21f64e6d79420dc4c56c1907df22akschulz chatState); 19515a60e47497f21f64e6d79420dc4c56c1907df22akschulz 19525a60e47497f21f64e6d79420dc4c56c1907df22akschulz sendEvent(evt); 19535a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 19545a60e47497f21f64e6d79420dc4c56c1907df22akschulz 19555a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else { 19565a60e47497f21f64e6d79420dc4c56c1907df22akschulz // Not new - compare updated content 19575a60e47497f21f64e6d79420dc4c56c1907df22akschulz// Uri convoUri = Uri 19585a60e47497f21f64e6d79420dc4c56c1907df22akschulz// .parse(mAccount.mBase_uri 19595a60e47497f21f64e6d79420dc4c56c1907df22akschulz// + "/" 19605a60e47497f21f64e6d79420dc4c56c1907df22akschulz// + BluetoothMapContract.TABLE_CONVERSATION); 19615a60e47497f21f64e6d79420dc4c56c1907df22akschulz // TODO: Should be changed to own provider interface name 19625a60e47497f21f64e6d79420dc4c56c1907df22akschulz// String whereClause = "contacts._id = " 19635a60e47497f21f64e6d79420dc4c56c1907df22akschulz// + convoId; 19645a60e47497f21f64e6d79420dc4c56c1907df22akschulz// Cursor cConvo = mProviderClient 19655a60e47497f21f64e6d79420dc4c56c1907df22akschulz// .query(convoUri, 19665a60e47497f21f64e6d79420dc4c56c1907df22akschulz// BluetoothMapContract.BT_CONVERSATION_PROJECTION, 19675a60e47497f21f64e6d79420dc4c56c1907df22akschulz// whereClause, null, null); 19685a60e47497f21f64e6d79420dc4c56c1907df22akschulz// // TODO: will move out of the loop when merged with CB's 19695a60e47497f21f64e6d79420dc4c56c1907df22akschulz// // changes make sure to look up col index out side loop 19705a60e47497f21f64e6d79420dc4c56c1907df22akschulz String convoName = null; 19715a60e47497f21f64e6d79420dc4c56c1907df22akschulz// if (cConvo != null && cConvo.moveToFirst()) { 19725a60e47497f21f64e6d79420dc4c56c1907df22akschulz// convoName = cConvo 19735a60e47497f21f64e6d79420dc4c56c1907df22akschulz// .getString(cConvo 19745a60e47497f21f64e6d79420dc4c56c1907df22akschulz// .getColumnIndex(BluetoothMapContract.ConvoContactColumns.NAME)); 19755a60e47497f21f64e6d79420dc4c56c1907df22akschulz// } 19765a60e47497f21f64e6d79420dc4c56c1907df22akschulz 19775a60e47497f21f64e6d79420dc4c56c1907df22akschulz // Check if presence is updated 19785a60e47497f21f64e6d79420dc4c56c1907df22akschulz int presenceState = c.getInt(cInfo.mContactColPresenceState); 19795a60e47497f21f64e6d79420dc4c56c1907df22akschulz String presenceStatus = c.getString( 19805a60e47497f21f64e6d79420dc4c56c1907df22akschulz cInfo.mContactColPresenceText); 19815a60e47497f21f64e6d79420dc4c56c1907df22akschulz String currentPresenceStatus = contact 19825a60e47497f21f64e6d79420dc4c56c1907df22akschulz .getPresenceStatus(); 19835a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (contact.getPresenceAvailability() != presenceState 19845a60e47497f21f64e6d79420dc4c56c1907df22akschulz || currentPresenceStatus != presenceStatus) { 19855a60e47497f21f64e6d79420dc4c56c1907df22akschulz long lastOnline = c 19865a60e47497f21f64e6d79420dc4c56c1907df22akschulz .getLong(cInfo.mContactColLastOnline); 19875a60e47497f21f64e6d79420dc4c56c1907df22akschulz contact.setPresenceAvailability(presenceState); 19885a60e47497f21f64e6d79420dc4c56c1907df22akschulz contact.setLastActivity(lastOnline); 19895a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (currentPresenceStatus != null 19905a60e47497f21f64e6d79420dc4c56c1907df22akschulz && !currentPresenceStatus 19915a60e47497f21f64e6d79420dc4c56c1907df22akschulz .equals(presenceStatus)) { 19925a60e47497f21f64e6d79420dc4c56c1907df22akschulz contact.setPresenceStatus(presenceStatus); 19935a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 19945a60e47497f21f64e6d79420dc4c56c1907df22akschulz Event evt = new Event( 19955a60e47497f21f64e6d79420dc4c56c1907df22akschulz EVENT_TYPE_PRESENCE, 19965a60e47497f21f64e6d79420dc4c56c1907df22akschulz uci, 19975a60e47497f21f64e6d79420dc4c56c1907df22akschulz mAccount.getType(), 19985a60e47497f21f64e6d79420dc4c56c1907df22akschulz contact.getName(), 19995a60e47497f21f64e6d79420dc4c56c1907df22akschulz String.valueOf(contact 20005a60e47497f21f64e6d79420dc4c56c1907df22akschulz .getPriority()), 20015a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapUtils 20025a60e47497f21f64e6d79420dc4c56c1907df22akschulz .getDateTimeString(lastOnline), 20035a60e47497f21f64e6d79420dc4c56c1907df22akschulz convoId, convoName, 20045a60e47497f21f64e6d79420dc4c56c1907df22akschulz presenceState, presenceStatus, 20055a60e47497f21f64e6d79420dc4c56c1907df22akschulz 0); 20065a60e47497f21f64e6d79420dc4c56c1907df22akschulz sendEvent(evt); 20075a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 20085a60e47497f21f64e6d79420dc4c56c1907df22akschulz 20095a60e47497f21f64e6d79420dc4c56c1907df22akschulz // Check if chat state is updated 20105a60e47497f21f64e6d79420dc4c56c1907df22akschulz int chatState = c.getInt(cInfo.mContactColChatState); 20115a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (contact.getChatState() != chatState) { 20125a60e47497f21f64e6d79420dc4c56c1907df22akschulz // Get DB timestamp 20135a60e47497f21f64e6d79420dc4c56c1907df22akschulz long lastActivity = c.getLong(cInfo.mContactColLastActive); 20145a60e47497f21f64e6d79420dc4c56c1907df22akschulz contact.setLastActivity(lastActivity); 20155a60e47497f21f64e6d79420dc4c56c1907df22akschulz contact.setChatState(chatState); 20165a60e47497f21f64e6d79420dc4c56c1907df22akschulz Event evt = new Event( 20175a60e47497f21f64e6d79420dc4c56c1907df22akschulz EVENT_TYPE_CHAT_STATE, 20185a60e47497f21f64e6d79420dc4c56c1907df22akschulz uci, 20195a60e47497f21f64e6d79420dc4c56c1907df22akschulz mAccount.getType(), 20205a60e47497f21f64e6d79420dc4c56c1907df22akschulz contact.getName(), 20215a60e47497f21f64e6d79420dc4c56c1907df22akschulz String.valueOf(contact 20225a60e47497f21f64e6d79420dc4c56c1907df22akschulz .getPriority()), 20235a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapUtils 20245a60e47497f21f64e6d79420dc4c56c1907df22akschulz .getDateTimeString(lastActivity), 20255a60e47497f21f64e6d79420dc4c56c1907df22akschulz convoId, convoName, 0, null, 20265a60e47497f21f64e6d79420dc4c56c1907df22akschulz chatState); 20275a60e47497f21f64e6d79420dc4c56c1907df22akschulz sendEvent(evt); 20285a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 20295a60e47497f21f64e6d79420dc4c56c1907df22akschulz contactList.put(uci, contact); 20305a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 20315a60e47497f21f64e6d79420dc4c56c1907df22akschulz } while (c.moveToNext()); 20325a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 20335a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(getContactList().size() > 0) { 20345a60e47497f21f64e6d79420dc4c56c1907df22akschulz // one or more contacts were deleted, hence the conversation listing 20355a60e47497f21f64e6d79420dc4c56c1907df22akschulz // version counter should change. 20365a60e47497f21f64e6d79420dc4c56c1907df22akschulz listChanged = true; 20375a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 20385a60e47497f21f64e6d79420dc4c56c1907df22akschulz setContactList(contactList, listChanged); 20395a60e47497f21f64e6d79420dc4c56c1907df22akschulz } // end synchronized 20405a60e47497f21f64e6d79420dc4c56c1907df22akschulz } finally { 20415a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null) c.close(); 20425a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 20435a60e47497f21f64e6d79420dc4c56c1907df22akschulz } catch (RemoteException e) { 20445a60e47497f21f64e6d79420dc4c56c1907df22akschulz mMasInstance.restartObexServerSession(); 20455a60e47497f21f64e6d79420dc4c56c1907df22akschulz Log.w(TAG, 20465a60e47497f21f64e6d79420dc4c56c1907df22akschulz "Problems contacting the ContentProvider in mas Instance " 20475a60e47497f21f64e6d79420dc4c56c1907df22akschulz + mMasId + " restaring ObexServerSession"); 20485a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 20495a60e47497f21f64e6d79420dc4c56c1907df22akschulz 20505a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 20515a60e47497f21f64e6d79420dc4c56c1907df22akschulz // TODO: conversation contact updates if IM and SMS(MMS in one instance 20525a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 20535a60e47497f21f64e6d79420dc4c56c1907df22akschulz 2054326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private boolean setEmailMessageStatusDelete(BluetoothMapFolderElement mCurrentFolder, 2055326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde String uriStr, long handle, int status) { 2056326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde boolean res = false; 2057326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Uri uri = Uri.parse(uriStr + BluetoothMapContract.TABLE_MESSAGE); 2058326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 2059326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde int updateCount = 0; 2060326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde ContentValues contentValues = new ContentValues(); 2061326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde BluetoothMapFolderElement deleteFolder = mFolders. 20625a60e47497f21f64e6d79420dc4c56c1907df22akschulz getFolderByName(BluetoothMapContract.FOLDER_NAME_DELETED); 2063326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde contentValues.put(BluetoothMapContract.MessageColumns._ID, handle); 20645a60e47497f21f64e6d79420dc4c56c1907df22akschulz synchronized(getMsgListMsg()) { 20655a60e47497f21f64e6d79420dc4c56c1907df22akschulz Msg msg = getMsgListMsg().get(handle); 2066326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (status == BluetoothMapAppParams.STATUS_VALUE_YES) { 2067326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* Set deleted folder id */ 2068326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde long folderId = -1; 2069326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(deleteFolder != null) { 20705a60e47497f21f64e6d79420dc4c56c1907df22akschulz folderId = deleteFolder.getFolderId(); 2071326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2072326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde contentValues.put(BluetoothMapContract.MessageColumns.FOLDER_ID,folderId); 2073326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde updateCount = mResolver.update(uri, contentValues, null, null); 2074326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* The race between updating the value in our cached values and the database 2075326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * is handled by the synchronized statement. */ 2076326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(updateCount > 0) { 2077326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde res = true; 2078326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (msg != null) { 2079326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde msg.oldFolderId = msg.folderId; 20805a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* Update the folder ID to avoid triggering an event for MCE 20815a60e47497f21f64e6d79420dc4c56c1907df22akschulz * initiated actions. */ 2082326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde msg.folderId = folderId; 2083326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2084326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(D) Log.d(TAG, "Deleted MSG: " + handle + " from folderId: " + folderId); 2085326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 2086326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.w(TAG, "Msg: " + handle + " - Set delete status " + status 2087326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde + " failed for folderId " + folderId); 2088326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2089326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else if (status == BluetoothMapAppParams.STATUS_VALUE_NO) { 2090326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* Undelete message. move to old folder if we know it, 2091326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * else move to inbox - as dictated by the spec. */ 2092326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(msg != null && deleteFolder != null && 20935a60e47497f21f64e6d79420dc4c56c1907df22akschulz msg.folderId == deleteFolder.getFolderId()) { 2094326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* Only modify messages in the 'Deleted' folder */ 2095326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde long folderId = -1; 20965a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapFolderElement inboxFolder = mCurrentFolder. 20975a60e47497f21f64e6d79420dc4c56c1907df22akschulz getFolderByName(BluetoothMapContract.FOLDER_NAME_INBOX); 2098326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (msg != null && msg.oldFolderId != -1) { 2099326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde folderId = msg.oldFolderId; 2100326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 2101326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(inboxFolder != null) { 21025a60e47497f21f64e6d79420dc4c56c1907df22akschulz folderId = inboxFolder.getFolderId(); 2103326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 21045a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(D)Log.d(TAG,"We did not delete the message, hence the old folder " + 21055a60e47497f21f64e6d79420dc4c56c1907df22akschulz "is unknown. Moving to inbox."); 2106326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2107326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde contentValues.put(BluetoothMapContract.MessageColumns.FOLDER_ID, folderId); 2108326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde updateCount = mResolver.update(uri, contentValues, null, null); 2109326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(updateCount > 0) { 2110326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde res = true; 21115a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* Update the folder ID to avoid triggering an event for MCE 21125a60e47497f21f64e6d79420dc4c56c1907df22akschulz * initiated actions. */ 21135a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* UPDATE: Actually the BT-Spec. states that an undelete is a move of the 21145a60e47497f21f64e6d79420dc4c56c1907df22akschulz * message to INBOX - clearified in errata 5591. 21155a60e47497f21f64e6d79420dc4c56c1907df22akschulz * Therefore we update the cache to INBOX-folderId - to trigger a message 21165a60e47497f21f64e6d79420dc4c56c1907df22akschulz * shift event to the old-folder. */ 21175a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(inboxFolder != null) { 21185a60e47497f21f64e6d79420dc4c56c1907df22akschulz msg.folderId = inboxFolder.getFolderId(); 21195a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else { 21205a60e47497f21f64e6d79420dc4c56c1907df22akschulz msg.folderId = folderId; 21215a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 2122326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 21235a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(D)Log.d(TAG,"We did not delete the message, hence the old folder " + 21245a60e47497f21f64e6d79420dc4c56c1907df22akschulz "is unknown. Moving to inbox."); 2125326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2126326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2127326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2128326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(V) { 2129326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde BluetoothMapFolderElement folderElement; 2130326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde String folderName = "unknown"; 2131326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (msg != null) { 21325a60e47497f21f64e6d79420dc4c56c1907df22akschulz folderElement = mCurrentFolder.getFolderById(msg.folderId); 2133326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(folderElement != null) { 2134326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde folderName = folderElement.getName(); 2135326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2136326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2137326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.d(TAG,"setEmailMessageStatusDelete: " + handle + " from " + folderName 2138326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde + " status: " + status); 2139326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2140326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2141326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(res == false) { 2142326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.w(TAG, "Set delete status " + status + " failed."); 2143326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2144326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde return res; 2145326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2146326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 2147326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private void updateThreadId(Uri uri, String valueString, long threadId) { 2148326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde ContentValues contentValues = new ContentValues(); 2149326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde contentValues.put(valueString, threadId); 2150326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mResolver.update(uri, contentValues, null, null); 2151fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2152fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2153fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private boolean deleteMessageMms(long handle) { 2154fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie boolean res = false; 2155fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, handle); 2156fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Cursor c = mResolver.query(uri, null, null, null, null); 215728446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz try { 215828446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz if (c != null && c.moveToFirst()) { 215928446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz /* Move to deleted folder, or delete if already in deleted folder */ 216028446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz int threadId = c.getInt(c.getColumnIndex(Mms.THREAD_ID)); 216128446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz if (threadId != DELETED_THREAD_ID) { 216228446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz /* Set deleted thread id */ 21635a60e47497f21f64e6d79420dc4c56c1907df22akschulz synchronized(getMsgListMms()) { 21645a60e47497f21f64e6d79420dc4c56c1907df22akschulz Msg msg = getMsgListMms().get(handle); 216528446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz if(msg != null) { // This will always be the case 216628446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz msg.threadId = DELETED_THREAD_ID; 216728446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } 2168326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 216928446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz updateThreadId(uri, Mms.THREAD_ID, DELETED_THREAD_ID); 217028446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } else { 217128446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz /* Delete from observer message list to avoid delete notifications */ 21725a60e47497f21f64e6d79420dc4c56c1907df22akschulz synchronized(getMsgListMms()) { 21735a60e47497f21f64e6d79420dc4c56c1907df22akschulz getMsgListMms().remove(handle); 217428446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } 217528446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz /* Delete message */ 217628446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz mResolver.delete(uri, null, null); 2177326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 217828446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz res = true; 2179fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 218028446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } finally { 21815a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null) c.close(); 2182fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 218328446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz 2184fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return res; 2185fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2186fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2187fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private boolean unDeleteMessageMms(long handle) { 2188fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie boolean res = false; 2189fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, handle); 2190fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Cursor c = mResolver.query(uri, null, null, null, null); 219128446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz try { 219228446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz if (c != null && c.moveToFirst()) { 219328446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz int threadId = c.getInt(c.getColumnIndex(Mms.THREAD_ID)); 219428446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz if (threadId == DELETED_THREAD_ID) { 219528446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz /* Restore thread id from address, or if no thread for address 21965a60e47497f21f64e6d79420dc4c56c1907df22akschulz * create new thread by insert and remove of fake message */ 219728446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz String address; 219828446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz long id = c.getLong(c.getColumnIndex(Mms._ID)); 219928446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz int msgBox = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX)); 220028446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz if (msgBox == Mms.MESSAGE_BOX_INBOX) { 220128446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz address = BluetoothMapContent.getAddressMms(mResolver, id, 22025a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContent.MMS_FROM); 220328446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } else { 220428446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz address = BluetoothMapContent.getAddressMms(mResolver, id, 22055a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContent.MMS_TO); 220628446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } 220728446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz Set<String> recipients = new HashSet<String>(); 220828446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz recipients.addAll(Arrays.asList(address)); 220928446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz Long oldThreadId = Telephony.Threads.getOrCreateThreadId(mContext, recipients); 22105a60e47497f21f64e6d79420dc4c56c1907df22akschulz synchronized(getMsgListMms()) { 22115a60e47497f21f64e6d79420dc4c56c1907df22akschulz Msg msg = getMsgListMms().get(handle); 221228446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz if(msg != null) { // This will always be the case 221328446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz msg.threadId = oldThreadId.intValue(); 22145a60e47497f21f64e6d79420dc4c56c1907df22akschulz // Spec. states that undelete shall shift the message to Inbox. 22155a60e47497f21f64e6d79420dc4c56c1907df22akschulz // Hence we need to trigger a message shift from INBOX to old-folder 22165a60e47497f21f64e6d79420dc4c56c1907df22akschulz // after undelete. 22175a60e47497f21f64e6d79420dc4c56c1907df22akschulz // We do this by changing the cached folder value to being inbox - hence 22185a60e47497f21f64e6d79420dc4c56c1907df22akschulz // the event handler will se the update as the message have been shifted 22195a60e47497f21f64e6d79420dc4c56c1907df22akschulz // from INBOX to old-folder. (Errata 5591 clearifies this) 22205a60e47497f21f64e6d79420dc4c56c1907df22akschulz msg.type = Mms.MESSAGE_BOX_INBOX; 222128446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } 2222326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 222328446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz updateThreadId(uri, Mms.THREAD_ID, oldThreadId); 222428446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } else { 222528446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz Log.d(TAG, "Message not in deleted folder: handle " + handle 22265a60e47497f21f64e6d79420dc4c56c1907df22akschulz + " threadId " + threadId); 2227326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 222828446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz res = true; 2229fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 223028446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } finally { 22315a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null) c.close(); 2232fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2233fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return res; 2234fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2235fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2236fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private boolean deleteMessageSms(long handle) { 2237fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie boolean res = false; 2238fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Uri uri = ContentUris.withAppendedId(Sms.CONTENT_URI, handle); 2239fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Cursor c = mResolver.query(uri, null, null, null, null); 224028446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz try { 224128446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz if (c != null && c.moveToFirst()) { 224228446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz /* Move to deleted folder, or delete if already in deleted folder */ 224328446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID)); 224428446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz if (threadId != DELETED_THREAD_ID) { 22455a60e47497f21f64e6d79420dc4c56c1907df22akschulz synchronized(getMsgListSms()) { 22465a60e47497f21f64e6d79420dc4c56c1907df22akschulz Msg msg = getMsgListSms().get(handle); 224728446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz if(msg != null) { // This will always be the case 224828446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz msg.threadId = DELETED_THREAD_ID; 224928446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } 2250326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 225128446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz /* Set deleted thread id */ 225228446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz updateThreadId(uri, Sms.THREAD_ID, DELETED_THREAD_ID); 225328446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } else { 225428446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz /* Delete from observer message list to avoid delete notifications */ 22555a60e47497f21f64e6d79420dc4c56c1907df22akschulz synchronized(getMsgListSms()) { 22565a60e47497f21f64e6d79420dc4c56c1907df22akschulz getMsgListSms().remove(handle); 225728446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } 225828446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz /* Delete message */ 225928446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz mResolver.delete(uri, null, null); 2260326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 226128446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz res = true; 2262fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 226328446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } finally { 22645a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null) c.close(); 2265fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2266fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return res; 2267fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2268fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2269fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private boolean unDeleteMessageSms(long handle) { 2270fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie boolean res = false; 2271fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Uri uri = ContentUris.withAppendedId(Sms.CONTENT_URI, handle); 2272fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Cursor c = mResolver.query(uri, null, null, null, null); 227328446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz try { 227428446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz if (c != null && c.moveToFirst()) { 227528446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID)); 227628446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz if (threadId == DELETED_THREAD_ID) { 227728446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz String address = c.getString(c.getColumnIndex(Sms.ADDRESS)); 227828446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz Set<String> recipients = new HashSet<String>(); 227928446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz recipients.addAll(Arrays.asList(address)); 228028446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz Long oldThreadId = Telephony.Threads.getOrCreateThreadId(mContext, recipients); 22815a60e47497f21f64e6d79420dc4c56c1907df22akschulz synchronized(getMsgListSms()) { 22825a60e47497f21f64e6d79420dc4c56c1907df22akschulz Msg msg = getMsgListSms().get(handle); 22835a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(msg != null) { 22845a60e47497f21f64e6d79420dc4c56c1907df22akschulz msg.threadId = oldThreadId.intValue(); 22855a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* This will always be the case 22865a60e47497f21f64e6d79420dc4c56c1907df22akschulz * The threadId is specified as an int, so it is safe to truncate 22875a60e47497f21f64e6d79420dc4c56c1907df22akschulz * TODO: Test that this will trigger a message-shift from Inbox 22885a60e47497f21f64e6d79420dc4c56c1907df22akschulz * to old-folder 22895a60e47497f21f64e6d79420dc4c56c1907df22akschulz **/ 22905a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* Spec. states that undelete shall shift the message to Inbox. 22915a60e47497f21f64e6d79420dc4c56c1907df22akschulz * Hence we need to trigger a message shift from INBOX to old-folder 22925a60e47497f21f64e6d79420dc4c56c1907df22akschulz * after undelete. 22935a60e47497f21f64e6d79420dc4c56c1907df22akschulz * We do this by changing the cached folder value to being inbox - hence 22945a60e47497f21f64e6d79420dc4c56c1907df22akschulz * the event handler will se the update as the message have been shifted 22955a60e47497f21f64e6d79420dc4c56c1907df22akschulz * from INBOX to old-folder. (Errata 5591 clearifies this) 22965a60e47497f21f64e6d79420dc4c56c1907df22akschulz * */ 22975a60e47497f21f64e6d79420dc4c56c1907df22akschulz msg.type = Sms.MESSAGE_TYPE_INBOX; 229828446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } 2299326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 230028446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz updateThreadId(uri, Sms.THREAD_ID, oldThreadId); 230128446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } else { 230228446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz Log.d(TAG, "Message not in deleted folder: handle " + handle 23035a60e47497f21f64e6d79420dc4c56c1907df22akschulz + " threadId " + threadId); 2304326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 230528446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz res = true; 2306fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 230728446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } finally { 23085a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null) c.close(); 2309fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2310fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return res; 2311fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2312fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 23135a60e47497f21f64e6d79420dc4c56c1907df22akschulz /** 23145a60e47497f21f64e6d79420dc4c56c1907df22akschulz * 23155a60e47497f21f64e6d79420dc4c56c1907df22akschulz * @param handle 23165a60e47497f21f64e6d79420dc4c56c1907df22akschulz * @param type 23175a60e47497f21f64e6d79420dc4c56c1907df22akschulz * @param mCurrentFolder 23185a60e47497f21f64e6d79420dc4c56c1907df22akschulz * @param uriStr 23195a60e47497f21f64e6d79420dc4c56c1907df22akschulz * @param statusValue 23205a60e47497f21f64e6d79420dc4c56c1907df22akschulz * @return true is success 23215a60e47497f21f64e6d79420dc4c56c1907df22akschulz */ 2322326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde public boolean setMessageStatusDeleted(long handle, TYPE type, 2323326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde BluetoothMapFolderElement mCurrentFolder, String uriStr, int statusValue) { 2324fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie boolean res = false; 2325fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (D) Log.d(TAG, "setMessageStatusDeleted: handle " + handle 23265a60e47497f21f64e6d79420dc4c56c1907df22akschulz + " type " + type + " value " + statusValue); 2327fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2328326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (type == TYPE.EMAIL) { 2329326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde res = setEmailMessageStatusDelete(mCurrentFolder, uriStr, handle, statusValue); 23305a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else if (type == TYPE.IM) { 23315a60e47497f21f64e6d79420dc4c56c1907df22akschulz // TODO: to do when deleting IM message 23325a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (D) Log.d(TAG, "setMessageStatusDeleted: IM not handled" ); 2333326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 2334326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (statusValue == BluetoothMapAppParams.STATUS_VALUE_YES) { 2335326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (type == TYPE.SMS_GSM || type == TYPE.SMS_CDMA) { 2336326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde res = deleteMessageSms(handle); 2337326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else if (type == TYPE.MMS) { 2338326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde res = deleteMessageMms(handle); 2339326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2340326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else if (statusValue == BluetoothMapAppParams.STATUS_VALUE_NO) { 2341326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (type == TYPE.SMS_GSM || type == TYPE.SMS_CDMA) { 2342326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde res = unDeleteMessageSms(handle); 2343326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else if (type == TYPE.MMS) { 2344326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde res = unDeleteMessageMms(handle); 2345326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2346fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2347fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2348fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return res; 2349fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2350fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2351326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /** 2352326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * 2353326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * @param handle 2354326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * @param type 2355326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * @param uriStr 2356326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * @param statusValue 2357326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * @return true at success 2358326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde */ 23595a60e47497f21f64e6d79420dc4c56c1907df22akschulz public boolean setMessageStatusRead(long handle, TYPE type, String uriStr, int statusValue) 23605a60e47497f21f64e6d79420dc4c56c1907df22akschulz throws RemoteException{ 2361326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde int count = 0; 2362fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2363fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (D) Log.d(TAG, "setMessageStatusRead: handle " + handle 23645a60e47497f21f64e6d79420dc4c56c1907df22akschulz + " type " + type + " value " + statusValue); 2365fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 23665a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* Approved MAP spec errata 3445 states that read status initiated 23675a60e47497f21f64e6d79420dc4c56c1907df22akschulz * by the MCE shall change the MSE read status. */ 2368fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (type == TYPE.SMS_GSM || type == TYPE.SMS_CDMA) { 2369cdf75c3f2b9e0e367ea2a4ce92018a6de662f4cdAjay Panicker Uri uri = ContentUris.withAppendedId(Sms.CONTENT_URI, handle); 2370fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ContentValues contentValues = new ContentValues(); 2371fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie contentValues.put(Sms.READ, statusValue); 2372326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde contentValues.put(Sms.SEEN, statusValue); 2373326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde String values = contentValues.toString(); 2374cdf75c3f2b9e0e367ea2a4ce92018a6de662f4cdAjay Panicker if (D) Log.d(TAG, " -> SMS Uri: " + uri.toString() + " values " + values); 23755a60e47497f21f64e6d79420dc4c56c1907df22akschulz synchronized(getMsgListSms()) { 23765a60e47497f21f64e6d79420dc4c56c1907df22akschulz Msg msg = getMsgListSms().get(handle); 23775a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(msg != null) { // This will always be the case 23785a60e47497f21f64e6d79420dc4c56c1907df22akschulz msg.flagRead = statusValue; 23795a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 23805a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 2381cdf75c3f2b9e0e367ea2a4ce92018a6de662f4cdAjay Panicker count = mResolver.update(uri, contentValues, null, null); 2382326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (D) Log.d(TAG, " -> "+count +" rows updated!"); 238328446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz 2384fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else if (type == TYPE.MMS) { 2385fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, handle); 2386326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (D) Log.d(TAG, " -> MMS Uri: " + uri.toString()); 2387fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ContentValues contentValues = new ContentValues(); 2388fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie contentValues.put(Mms.READ, statusValue); 23895a60e47497f21f64e6d79420dc4c56c1907df22akschulz synchronized(getMsgListMms()) { 23905a60e47497f21f64e6d79420dc4c56c1907df22akschulz Msg msg = getMsgListMms().get(handle); 23915a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(msg != null) { // This will always be the case 23925a60e47497f21f64e6d79420dc4c56c1907df22akschulz msg.flagRead = statusValue; 23935a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 23945a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 2395326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde count = mResolver.update(uri, contentValues, null, null); 2396326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (D) Log.d(TAG, " -> "+count +" rows updated!"); 23975a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else if (type == TYPE.EMAIL || 23985a60e47497f21f64e6d79420dc4c56c1907df22akschulz type == TYPE.IM) { 2399326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Uri uri = mMessageUri; 2400326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde ContentValues contentValues = new ContentValues(); 2401326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde contentValues.put(BluetoothMapContract.MessageColumns.FLAG_READ, statusValue); 2402326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde contentValues.put(BluetoothMapContract.MessageColumns._ID, handle); 24035a60e47497f21f64e6d79420dc4c56c1907df22akschulz synchronized(getMsgListMsg()) { 24045a60e47497f21f64e6d79420dc4c56c1907df22akschulz Msg msg = getMsgListMsg().get(handle); 24055a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(msg != null) { // This will always be the case 24065a60e47497f21f64e6d79420dc4c56c1907df22akschulz msg.flagRead = statusValue; 24075a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 24085a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 2409326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde count = mProviderClient.update(uri, contentValues, null, null); 2410326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 241128446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz 241228446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz return (count > 0); 2413fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2414fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2415fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private class PushMsgInfo { 2416fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie long id; 2417fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int transparent; 2418fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int retry; 2419fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie String phone; 2420fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Uri uri; 2421326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde long timestamp; 2422fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int parts; 2423fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int partsSent; 2424fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int partsDelivered; 2425fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie boolean resend; 2426326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde boolean sendInProgress; 2427326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde boolean failedSent; // Set to true if a single part sent fail is received. 2428326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde int statusDelivered; // Set to != 0 if a single part deliver fail is received. 2429fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2430fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public PushMsgInfo(long id, int transparent, 24315a60e47497f21f64e6d79420dc4c56c1907df22akschulz int retry, String phone, Uri uri) { 2432fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.id = id; 2433fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.transparent = transparent; 2434fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.retry = retry; 2435fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.phone = phone; 2436fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.uri = uri; 2437fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie this.resend = false; 2438326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde this.sendInProgress = false; 2439326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde this.failedSent = false; 2440326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde this.statusDelivered = 0; /* Assume success */ 2441326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde this.timestamp = 0; 2442fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie }; 2443fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2444fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2445fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private Map<Long, PushMsgInfo> mPushMsgList = 24465a60e47497f21f64e6d79420dc4c56c1907df22akschulz Collections.synchronizedMap(new HashMap<Long, PushMsgInfo>()); 2447fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2448326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde public long pushMessage(BluetoothMapbMessage msg, BluetoothMapFolderElement folderElement, 2449326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde BluetoothMapAppParams ap, String emailBaseUri) 2450326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde throws IllegalArgumentException, RemoteException, IOException { 2451fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (D) Log.d(TAG, "pushMessage"); 2452fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ArrayList<BluetoothMapbMessage.vCard> recipientList = msg.getRecipients(); 2453fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int transparent = (ap.getTransparent() == BluetoothMapAppParams.INVALID_VALUE_PARAMETER) ? 2454fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 0 : ap.getTransparent(); 2455fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int retry = ap.getRetry(); 2456fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int charset = ap.getCharset(); 2457fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie long handle = -1; 2458326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde long folderId = -1; 2459fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2460fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (recipientList == null) { 2461c06dad4b6c213f57da06fe74903a25733ef6579fAjay Panicker if (folderElement.getName().equalsIgnoreCase(BluetoothMapContract.FOLDER_NAME_DRAFT)) { 2462c06dad4b6c213f57da06fe74903a25733ef6579fAjay Panicker BluetoothMapbMessage.vCard empty = 2463c06dad4b6c213f57da06fe74903a25733ef6579fAjay Panicker new BluetoothMapbMessage.vCard("", "", null, null, 0); 2464c06dad4b6c213f57da06fe74903a25733ef6579fAjay Panicker recipientList = new ArrayList<BluetoothMapbMessage.vCard>(); 2465c06dad4b6c213f57da06fe74903a25733ef6579fAjay Panicker recipientList.add(empty); 2466c06dad4b6c213f57da06fe74903a25733ef6579fAjay Panicker Log.w(TAG, "Added empty recipient to draft message"); 2467c06dad4b6c213f57da06fe74903a25733ef6579fAjay Panicker } else { 2468c06dad4b6c213f57da06fe74903a25733ef6579fAjay Panicker Log.e(TAG, "Trying to send a message with no recipients"); 2469c06dad4b6c213f57da06fe74903a25733ef6579fAjay Panicker return -1; 2470c06dad4b6c213f57da06fe74903a25733ef6579fAjay Panicker } 2471fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2472fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2473326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if ( msg.getType().equals(TYPE.EMAIL) ) { 2474326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* Write the message to the database */ 2475326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde String msgBody = ((BluetoothMapbMessageEmail) msg).getEmailBody(); 2476326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (V) { 2477326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde int length = msgBody.length(); 2478326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.v(TAG, "pushMessage: message string length = " + length); 2479326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde String messages[] = msgBody.split("\r\n"); 2480326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.v(TAG, "pushMessage: messages count=" + messages.length); 2481326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde for(int i = 0; i < messages.length; i++) { 2482326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.v(TAG, "part " + i + ":" + messages[i]); 2483326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2484326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2485326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde FileOutputStream os = null; 2486326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde ParcelFileDescriptor fdOut = null; 2487326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Uri uriInsert = Uri.parse(emailBaseUri + BluetoothMapContract.TABLE_MESSAGE); 2488326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (D) Log.d(TAG, "pushMessage - uriInsert= " + uriInsert.toString() + 24895a60e47497f21f64e6d79420dc4c56c1907df22akschulz ", intoFolder id=" + folderElement.getFolderId()); 2490326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 24915a60e47497f21f64e6d79420dc4c56c1907df22akschulz synchronized(getMsgListMsg()) { 2492326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // Now insert the empty message into folder 2493326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde ContentValues values = new ContentValues(); 24945a60e47497f21f64e6d79420dc4c56c1907df22akschulz folderId = folderElement.getFolderId(); 2495326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(BluetoothMapContract.MessageColumns.FOLDER_ID, folderId); 2496326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Uri uriNew = mProviderClient.insert(uriInsert, values); 2497326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (D) Log.d(TAG, "pushMessage - uriNew= " + uriNew.toString()); 2498326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde handle = Long.parseLong(uriNew.getLastPathSegment()); 2499326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 2500326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde try { 2501326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde fdOut = mProviderClient.openFile(uriNew, "w"); 2502326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde os = new FileOutputStream(fdOut.getFileDescriptor()); 2503326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // Write Email to DB 2504326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde os.write(msgBody.getBytes(), 0, msgBody.getBytes().length); 2505326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } catch (FileNotFoundException e) { 2506326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.w(TAG, e); 2507326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde throw(new IOException("Unable to open file stream")); 2508326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } catch (NullPointerException e) { 2509326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.w(TAG, e); 2510326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde throw(new IllegalArgumentException("Unable to parse message.")); 2511326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } finally { 2512326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde try { 2513326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(os != null) 2514326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde os.close(); 2515326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } catch (IOException e) {Log.w(TAG, e);} 2516326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde try { 2517326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(fdOut != null) 25185a60e47497f21f64e6d79420dc4c56c1907df22akschulz fdOut.close(); 2519326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } catch (IOException e) {Log.w(TAG, e);} 2520326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2521326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 2522326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* Extract the data for the inserted message, and store in local mirror, to 2523326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * avoid sending a NewMessage Event. */ 25245a60e47497f21f64e6d79420dc4c56c1907df22akschulz /*TODO: We need to add the new 1.1 parameter as well:-) e.g. read*/ 25255a60e47497f21f64e6d79420dc4c56c1907df22akschulz Msg newMsg = new Msg(handle, folderId, 1); // TODO: Create define for read-state 2526326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde newMsg.transparent = (transparent == 1) ? true : false; 25275a60e47497f21f64e6d79420dc4c56c1907df22akschulz if ( folderId == folderElement.getFolderByName( 25285a60e47497f21f64e6d79420dc4c56c1907df22akschulz BluetoothMapContract.FOLDER_NAME_OUTBOX).getFolderId() ) { 2529326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde newMsg.localInitiatedSend = true; 2530326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 25315a60e47497f21f64e6d79420dc4c56c1907df22akschulz getMsgListMsg().put(handle, newMsg); 2532326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2533326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { // type SMS_* of MMS 2534326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde for (BluetoothMapbMessage.vCard recipient : recipientList) { 25355a60e47497f21f64e6d79420dc4c56c1907df22akschulz // Only send the message to the top level recipient 25365a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(recipient.getEnvLevel() == 0) 2537326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde { 2538326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* Only send to first address */ 2539326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde String phone = recipient.getFirstPhoneNumber(); 2540326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde String email = recipient.getFirstEmail(); 2541326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde String folder = folderElement.getName(); 2542326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde boolean read = false; 2543326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde boolean deliveryReport = true; 2544326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde String msgBody = null; 2545326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 2546326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* If MMS contains text only and the size is less than ten SMS's 2547326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * then convert the MMS to type SMS and then proceed 2548326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde */ 2549326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (msg.getType().equals(TYPE.MMS) && 25505a60e47497f21f64e6d79420dc4c56c1907df22akschulz (((BluetoothMapbMessageMime) msg).getTextOnly() == true)) { 25515a60e47497f21f64e6d79420dc4c56c1907df22akschulz msgBody = ((BluetoothMapbMessageMime) msg).getMessageAsText(); 2552326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde SmsManager smsMng = SmsManager.getDefault(); 2553326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde ArrayList<String> parts = smsMng.divideMessage(msgBody); 2554326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde int smsParts = parts.size(); 2555326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (smsParts <= CONVERT_MMS_TO_SMS_PART_COUNT ) { 25565a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (D) Log.d(TAG, "pushMessage - converting MMS to SMS, sms parts=" 25575a60e47497f21f64e6d79420dc4c56c1907df22akschulz + smsParts ); 2558326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde msg.setType(mSmsType); 2559326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 25605a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (D) Log.d(TAG, "pushMessage - MMS text only but to big to " + 25615a60e47497f21f64e6d79420dc4c56c1907df22akschulz "convert to SMS"); 2562326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde msgBody = null; 2563326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2564326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 2565fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2566326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 2567326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (msg.getType().equals(TYPE.MMS)) { 2568326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* Send message if folder is outbox else just store in draft*/ 2569ed70219e41ba68196798dcbf75b782d13fb88603kschulz handle = sendMmsMessage(folder, phone, (BluetoothMapbMessageMime)msg, 2570ed70219e41ba68196798dcbf75b782d13fb88603kschulz transparent, retry); 2571326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else if (msg.getType().equals(TYPE.SMS_GSM) || 2572326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde msg.getType().equals(TYPE.SMS_CDMA) ) { 2573fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Add the message to the database */ 2574326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(msgBody == null) 2575326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde msgBody = ((BluetoothMapbMessageSms) msg).getSmsBody(); 2576326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 2577cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta if (TextUtils.isEmpty(msgBody)) { 2578cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta Log.d(TAG, "PushMsg: Empty msgBody "); 2579cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta /* not allowed to push empty message */ 2580cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta throw new IllegalArgumentException("push EMPTY message: Invalid Body"); 2581cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta } 25825a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* We need to lock the SMS list while updating the database, 25835a60e47497f21f64e6d79420dc4c56c1907df22akschulz * to avoid sending events on MCE initiated operation. */ 2584326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Uri contentUri = Uri.parse(Sms.CONTENT_URI+ "/" + folder); 2585326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Uri uri; 25865a60e47497f21f64e6d79420dc4c56c1907df22akschulz synchronized(getMsgListSms()) { 2587326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde uri = Sms.addMessageToUri(mResolver, contentUri, phone, msgBody, 25885a60e47497f21f64e6d79420dc4c56c1907df22akschulz "", System.currentTimeMillis(), read, deliveryReport); 2589326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 2590326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(V) Log.v(TAG, "Sms.addMessageToUri() returned: " + uri); 2591326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (uri == null) { 25925a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (D) Log.d(TAG, "pushMessage - failure on add to uri " 25935a60e47497f21f64e6d79420dc4c56c1907df22akschulz + contentUri); 2594326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde return -1; 2595326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2596326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Cursor c = mResolver.query(uri, SMS_PROJECTION_SHORT, null, null, null); 25975a60e47497f21f64e6d79420dc4c56c1907df22akschulz 25985a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* Extract the data for the inserted message, and store in local mirror, 25995a60e47497f21f64e6d79420dc4c56c1907df22akschulz * to avoid sending a NewMessage Event. */ 260028446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz try { 260128446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz if (c != null && c.moveToFirst()) { 260228446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz long id = c.getLong(c.getColumnIndex(Sms._ID)); 260328446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz int type = c.getInt(c.getColumnIndex(Sms.TYPE)); 260428446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz int threadId = c.getInt(c.getColumnIndex(Sms.THREAD_ID)); 26055a60e47497f21f64e6d79420dc4c56c1907df22akschulz int readFlag = c.getInt(c.getColumnIndex(Sms.READ)); 26065a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(V) Log.v(TAG, "add message with id=" + id + 26075a60e47497f21f64e6d79420dc4c56c1907df22akschulz " type=" + type + " threadId=" + threadId + 26085a60e47497f21f64e6d79420dc4c56c1907df22akschulz " readFlag=" + readFlag + "to mMsgListSms"); 26095a60e47497f21f64e6d79420dc4c56c1907df22akschulz Msg newMsg = new Msg(id, type, threadId, readFlag); 26105a60e47497f21f64e6d79420dc4c56c1907df22akschulz getMsgListSms().put(id, newMsg); 26115a60e47497f21f64e6d79420dc4c56c1907df22akschulz c.close(); 261228446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } else { 26135a60e47497f21f64e6d79420dc4c56c1907df22akschulz Log.w(TAG,"Message: " + uri + " no longer exist!"); 26145a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* This can only happen, if the message is deleted 26155a60e47497f21f64e6d79420dc4c56c1907df22akschulz * just as it is added */ 26165a60e47497f21f64e6d79420dc4c56c1907df22akschulz return -1; 261728446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } 261828446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } finally { 26195a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null) c.close(); 2620326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2621fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2622326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde handle = Long.parseLong(uri.getLastPathSegment()); 2623fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2624326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* Send message if folder is outbox */ 26255a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (folder.equalsIgnoreCase(BluetoothMapContract.FOLDER_NAME_OUTBOX)) { 2626326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde PushMsgInfo msgInfo = new PushMsgInfo(handle, transparent, 26275a60e47497f21f64e6d79420dc4c56c1907df22akschulz retry, phone, uri); 2628326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mPushMsgList.put(handle, msgInfo); 2629326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde sendMessage(msgInfo, msgBody); 2630326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(V) Log.v(TAG, "sendMessage returned..."); 26315a60e47497f21f64e6d79420dc4c56c1907df22akschulz } /* else just added to draft */ 26325a60e47497f21f64e6d79420dc4c56c1907df22akschulz 26335a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* sendMessage causes the message to be deleted and reinserted, 26345a60e47497f21f64e6d79420dc4c56c1907df22akschulz * hence we need to lock the list while this is happening. */ 2635fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2636326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 2637326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (D) Log.d(TAG, "pushMessage - failure on type " ); 2638326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde return -1; 2639fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2640fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2641fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2642fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2643fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2644fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* If multiple recipients return handle of last */ 2645fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return handle; 2646fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2647fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2648ed70219e41ba68196798dcbf75b782d13fb88603kschulz public long sendMmsMessage(String folder, String to_address, BluetoothMapbMessageMime msg, 2649ed70219e41ba68196798dcbf75b782d13fb88603kschulz int transparent, int retry) { 2650fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* 2651fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie *strategy: 2652fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie *1) parse message into parts 2653fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie *if folder is outbox/drafts: 2654fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie *2) push message to draft 2655fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie *if folder is outbox: 2656fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie *3) move message to outbox (to trigger the mms app to add msg to pending_messages list) 2657fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie *4) send intent to mms app in order to wake it up. 2658fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie *else if folder !outbox: 2659fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie *1) push message to folder 2660fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * */ 2661326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (folder != null && (folder.equalsIgnoreCase(BluetoothMapContract.FOLDER_NAME_OUTBOX) 2662326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde || folder.equalsIgnoreCase(BluetoothMapContract.FOLDER_NAME_DRAFT))) { 2663326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde long handle = pushMmsToFolder(Mms.MESSAGE_BOX_DRAFTS, to_address, msg); 26645a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* if invalid handle (-1) then just return the handle 26655a60e47497f21f64e6d79420dc4c56c1907df22akschulz * - else continue sending (if folder is outbox) */ 26665a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (BluetoothMapAppParams.INVALID_VALUE_PARAMETER != handle && 26675a60e47497f21f64e6d79420dc4c56c1907df22akschulz folder.equalsIgnoreCase(BluetoothMapContract.FOLDER_NAME_OUTBOX)) { 2668ed70219e41ba68196798dcbf75b782d13fb88603kschulz Uri btMmsUri = MmsFileProvider.CONTENT_URI.buildUpon() 2669ed70219e41ba68196798dcbf75b782d13fb88603kschulz .appendPath(Long.toString(handle)).build(); 2670ed70219e41ba68196798dcbf75b782d13fb88603kschulz Intent sentIntent = new Intent(ACTION_MESSAGE_SENT); 2671ed70219e41ba68196798dcbf75b782d13fb88603kschulz // TODO: update the mmsMsgList <- done in pushMmsToFolder() but check 2672ed70219e41ba68196798dcbf75b782d13fb88603kschulz sentIntent.setType("message/" + Long.toString(handle)); 2673ed70219e41ba68196798dcbf75b782d13fb88603kschulz sentIntent.putExtra(EXTRA_MESSAGE_SENT_MSG_TYPE, TYPE.MMS.ordinal()); 2674ed70219e41ba68196798dcbf75b782d13fb88603kschulz sentIntent.putExtra(EXTRA_MESSAGE_SENT_HANDLE, handle); // needed for notification 2675ed70219e41ba68196798dcbf75b782d13fb88603kschulz sentIntent.putExtra(EXTRA_MESSAGE_SENT_TRANSPARENT, transparent); 2676ed70219e41ba68196798dcbf75b782d13fb88603kschulz sentIntent.putExtra(EXTRA_MESSAGE_SENT_RETRY, retry); 2677ed70219e41ba68196798dcbf75b782d13fb88603kschulz //sentIntent.setDataAndNormalize(btMmsUri); 2678ed70219e41ba68196798dcbf75b782d13fb88603kschulz PendingIntent pendingSendIntent = PendingIntent.getBroadcast(mContext, 0, 2679ed70219e41ba68196798dcbf75b782d13fb88603kschulz sentIntent, 0); 2680ed70219e41ba68196798dcbf75b782d13fb88603kschulz SmsManager.getDefault().sendMultimediaMessage(mContext, 2681ed70219e41ba68196798dcbf75b782d13fb88603kschulz btMmsUri, null/*locationUrl*/, null/*configOverrides*/, 2682ed70219e41ba68196798dcbf75b782d13fb88603kschulz pendingSendIntent); 2683326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2684326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde return handle; 2685326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 2686326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* not allowed to push mms to anything but outbox/draft */ 26875a60e47497f21f64e6d79420dc4c56c1907df22akschulz throw new IllegalArgumentException("Cannot push message to other " + 26885a60e47497f21f64e6d79420dc4c56c1907df22akschulz "folders than outbox/draft"); 2689fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2690fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2691fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2692fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private void moveDraftToOutbox(long handle) { 2693ed70219e41ba68196798dcbf75b782d13fb88603kschulz moveMmsToFolder(handle, mResolver, Mms.MESSAGE_BOX_OUTBOX); 2694ed70219e41ba68196798dcbf75b782d13fb88603kschulz } 2695ed70219e41ba68196798dcbf75b782d13fb88603kschulz 2696ed70219e41ba68196798dcbf75b782d13fb88603kschulz /** 2697ed70219e41ba68196798dcbf75b782d13fb88603kschulz * Move a MMS to another folder. 2698ed70219e41ba68196798dcbf75b782d13fb88603kschulz * @param handle the CP handle of the message to move 2699ed70219e41ba68196798dcbf75b782d13fb88603kschulz * @param resolver the ContentResolver to use 2700ed70219e41ba68196798dcbf75b782d13fb88603kschulz * @param folder the destination folder - use Mms.MESSAGE_BOX_xxx 2701ed70219e41ba68196798dcbf75b782d13fb88603kschulz */ 2702ed70219e41ba68196798dcbf75b782d13fb88603kschulz private static void moveMmsToFolder(long handle, ContentResolver resolver, int folder) { 2703fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /*Move message by changing the msg_box value in the content provider database */ 27045a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (handle != -1) { 27055a60e47497f21f64e6d79420dc4c56c1907df22akschulz String whereClause = " _id= " + handle; 27065a60e47497f21f64e6d79420dc4c56c1907df22akschulz Uri uri = Mms.CONTENT_URI; 2707ed70219e41ba68196798dcbf75b782d13fb88603kschulz Cursor queryResult = resolver.query(uri, null, whereClause, null, null); 27085a60e47497f21f64e6d79420dc4c56c1907df22akschulz try { 27095a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (queryResult != null) { 27105a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (queryResult.getCount() > 0) { 27115a60e47497f21f64e6d79420dc4c56c1907df22akschulz queryResult.moveToFirst(); 27125a60e47497f21f64e6d79420dc4c56c1907df22akschulz ContentValues data = new ContentValues(); 27135a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* set folder to be outbox */ 2714ed70219e41ba68196798dcbf75b782d13fb88603kschulz data.put(Mms.MESSAGE_BOX, folder); 2715ed70219e41ba68196798dcbf75b782d13fb88603kschulz resolver.update(uri, data, whereClause, null); 2716ed70219e41ba68196798dcbf75b782d13fb88603kschulz if (D) Log.d(TAG, "moved MMS message to " + getMmsFolderName(folder)); 27175a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 27185a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else { 2719ed70219e41ba68196798dcbf75b782d13fb88603kschulz Log.w(TAG, "Could not move MMS message to " + getMmsFolderName(folder)); 27205a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 27215a60e47497f21f64e6d79420dc4c56c1907df22akschulz } finally { 27225a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (queryResult != null) queryResult.close(); 2723fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2724fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2725fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 27265a60e47497f21f64e6d79420dc4c56c1907df22akschulz private long pushMmsToFolder(int folder, String to_address, BluetoothMapbMessageMime msg) { 2727fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /** 2728fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * strategy: 2729fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * 1) parse msg into parts + header 2730fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * 2) create thread id (abuse the ease of adding an SMS to get id for thread) 2731fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * 3) push parts into content://mms/parts/ table 2732fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * 3) 2733fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie */ 2734fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2735fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ContentValues values = new ContentValues(); 2736326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.MESSAGE_BOX, folder); 2737326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.READ, 0); 2738326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.SEEN, 0); 2739326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(msg.getSubject() != null) { 2740326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.SUBJECT, msg.getSubject()); 2741326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 2742326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.SUBJECT, ""); 2743326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 274470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz 2745326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(msg.getSubject() != null && msg.getSubject().length() > 0) { 2746326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.SUBJECT_CHARSET, 106); 2747326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2748326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.CONTENT_TYPE, "application/vnd.wap.multipart.related"); 2749326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.EXPIRY, 604800); 2750326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.MESSAGE_CLASS, PduHeaders.MESSAGE_CLASS_PERSONAL_STR); 2751326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.MESSAGE_TYPE, PduHeaders.MESSAGE_TYPE_SEND_REQ); 2752326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.MMS_VERSION, PduHeaders.CURRENT_MMS_VERSION); 2753326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.PRIORITY, PduHeaders.PRIORITY_NORMAL); 2754326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.READ_REPORT, PduHeaders.VALUE_NO); 2755326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.TRANSACTION_ID, "T"+ Long.toHexString(System.currentTimeMillis())); 2756326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.DELIVERY_REPORT, PduHeaders.VALUE_NO); 2757326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.LOCKED, 0); 2758326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(msg.getTextOnly() == true) 2759326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.TEXT_ONLY, true); 2760326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.MESSAGE_SIZE, msg.getSize()); 276170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz 2762326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // Get thread id 2763fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Set<String> recipients = new HashSet<String>(); 2764fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie recipients.addAll(Arrays.asList(to_address)); 2765326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.THREAD_ID, Telephony.Threads.getOrCreateThreadId(mContext, recipients)); 2766326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Uri uri = Mms.CONTENT_URI; 2767fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 27685a60e47497f21f64e6d79420dc4c56c1907df22akschulz synchronized (getMsgListMms()) { 27695a60e47497f21f64e6d79420dc4c56c1907df22akschulz 2770326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde uri = mResolver.insert(uri, values); 2771326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 2772326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (uri == null) { 2773326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // unable to insert MMS 2774326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.e(TAG, "Unabled to insert MMS " + values + "Uri: " + uri); 2775326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde return -1; 2776326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2777326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* As we already have all the values we need, we could skip the query, but 2778326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde doing the query ensures we get any changes made by the content provider 2779326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde at insert. */ 2780326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Cursor c = mResolver.query(uri, MMS_PROJECTION_SHORT, null, null, null); 278128446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz try { 278228446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz if (c != null && c.moveToFirst()) { 278328446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz long id = c.getLong(c.getColumnIndex(Mms._ID)); 278428446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz int type = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX)); 278528446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz int threadId = c.getInt(c.getColumnIndex(Mms.THREAD_ID)); 2786ed70219e41ba68196798dcbf75b782d13fb88603kschulz int readStatus = c.getInt(c.getColumnIndex(Mms.READ)); 2787326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 278828446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz /* We must filter out any actions made by the MCE. Add the new message to 278928446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz * the list of known messages. */ 2790326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 2791ed70219e41ba68196798dcbf75b782d13fb88603kschulz Msg newMsg = new Msg(id, type, threadId, readStatus); 279228446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz newMsg.localInitiatedSend = true; 27935a60e47497f21f64e6d79420dc4c56c1907df22akschulz getMsgListMms().put(id, newMsg); 27945a60e47497f21f64e6d79420dc4c56c1907df22akschulz c.close(); 279528446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } 279628446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } finally { 27975a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null) c.close(); 2798326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2799326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } // Done adding changes, unlock access to mMsgListMms to allow sending MMS events again 2800fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2801fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie long handle = Long.parseLong(uri.getLastPathSegment()); 2802326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (V) Log.v(TAG, " NEW URI " + uri.toString()); 2803326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 2804fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie try { 2805326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(msg.getMimeParts() == null) { 28065a60e47497f21f64e6d79420dc4c56c1907df22akschulz /* Perhaps this message have been deleted, and no longer have any content, 28075a60e47497f21f64e6d79420dc4c56c1907df22akschulz * but only headers */ 2808326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.w(TAG, "No MMS parts present..."); 2809326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 28105a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(V) Log.v(TAG, "Adding " + msg.getMimeParts().size() 28115a60e47497f21f64e6d79420dc4c56c1907df22akschulz + " parts to the data base."); 2812326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde for(MimePart part : msg.getMimeParts()) { 28135a60e47497f21f64e6d79420dc4c56c1907df22akschulz int count = 0; 28145a60e47497f21f64e6d79420dc4c56c1907df22akschulz count++; 2815326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.clear(); 28165a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(part.mContentType != null && 28175a60e47497f21f64e6d79420dc4c56c1907df22akschulz part.mContentType.toUpperCase().contains("TEXT")) { 2818326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.CONTENT_TYPE, "text/plain"); 2819326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.CHARSET, 106); 2820326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(part.mPartName != null) { 2821326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.FILENAME, part.mPartName); 2822326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.NAME, part.mPartName); 2823326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 2824326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.FILENAME, "text_" + count +".txt"); 2825326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.NAME, "text_" + count +".txt"); 2826326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2827326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // Ensure we have "ci" set 2828326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(part.mContentId != null) { 2829326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.CONTENT_ID, part.mContentId); 2830326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 2831326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(part.mPartName != null) { 2832326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.CONTENT_ID, "<" + part.mPartName + ">"); 2833326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 2834326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.CONTENT_ID, "<text_" + count + ">"); 2835326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2836326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2837326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // Ensure we have "cl" set 2838326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(part.mContentLocation != null) { 2839326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.CONTENT_LOCATION, part.mContentLocation); 2840326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 2841326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(part.mPartName != null) { 2842326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.CONTENT_LOCATION, part.mPartName + ".txt"); 2843326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 2844326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.CONTENT_LOCATION, "text_" + count + ".txt"); 2845326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2846326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2847326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 2848326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(part.mContentDisposition != null) { 2849326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.CONTENT_DISPOSITION, part.mContentDisposition); 2850326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2851326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.TEXT, part.getDataAsString()); 2852326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde uri = Uri.parse(Mms.CONTENT_URI + "/" + handle + "/part"); 2853326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde uri = mResolver.insert(uri, values); 2854326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(V) Log.v(TAG, "Added TEXT part"); 2855326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 28565a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else if (part.mContentType != null && 28575a60e47497f21f64e6d79420dc4c56c1907df22akschulz part.mContentType.toUpperCase().contains("SMIL")){ 2858326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.SEQ, -1); 2859326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.CONTENT_TYPE, "application/smil"); 2860326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(part.mContentId != null) { 2861326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.CONTENT_ID, part.mContentId); 2862326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 2863326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.CONTENT_ID, "<smil_" + count + ">"); 2864326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2865326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(part.mContentLocation != null) { 2866326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.CONTENT_LOCATION, part.mContentLocation); 2867326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 2868326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.CONTENT_LOCATION, "smil_" + count + ".xml"); 2869326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2870326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 2871326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(part.mContentDisposition != null) 2872326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.CONTENT_DISPOSITION, part.mContentDisposition); 2873326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.FILENAME, "smil.xml"); 2874326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.NAME, "smil.xml"); 2875326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.TEXT, new String(part.mData, "UTF-8")); 2876326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 2877326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde uri = Uri.parse(Mms.CONTENT_URI+ "/" + handle + "/part"); 2878326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde uri = mResolver.insert(uri, values); 2879326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (V) Log.v(TAG, "Added SMIL part"); 2880326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 2881326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde }else /*VIDEO/AUDIO/IMAGE*/ { 2882326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde writeMmsDataPart(handle, part, count); 2883326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (V) Log.v(TAG, "Added OTHER part"); 2884326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2885326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (uri != null){ 28865a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (V) Log.v(TAG, "Added part with content-type: " + part.mContentType 28875a60e47497f21f64e6d79420dc4c56c1907df22akschulz + " to Uri: " + uri.toString()); 2888326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 288970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 2890fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2891fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } catch (UnsupportedEncodingException e) { 289270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz Log.w(TAG, e); 2893fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } catch (IOException e) { 289470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz Log.w(TAG, e); 2895fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2896fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2897fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.clear(); 2898326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Addr.CONTACT_ID, "null"); 2899326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Addr.ADDRESS, "insert-address-token"); 2900326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Addr.TYPE, BluetoothMapContent.MMS_FROM); 2901326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Addr.CHARSET, 106); 2902fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2903326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde uri = Uri.parse(Mms.CONTENT_URI + "/" + handle + "/addr"); 2904326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde uri = mResolver.insert(uri, values); 2905fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (uri != null && V){ 2906fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.v(TAG, " NEW URI " + uri.toString()); 2907fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2908fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2909fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie values.clear(); 2910326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Addr.CONTACT_ID, "null"); 2911326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Addr.ADDRESS, to_address); 2912326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Addr.TYPE, BluetoothMapContent.MMS_TO); 2913326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Addr.CHARSET, 106); 2914fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2915326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde uri = Uri.parse(Mms.CONTENT_URI + "/" + handle + "/addr"); 2916326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde uri = mResolver.insert(uri, values); 2917fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (uri != null && V){ 2918fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.v(TAG, " NEW URI " + uri.toString()); 2919fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2920fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return handle; 2921fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2922fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2923fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 292470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz private void writeMmsDataPart(long handle, MimePart part, int count) throws IOException{ 2925fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ContentValues values = new ContentValues(); 2926326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.MSG_ID, handle); 2927326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(part.mContentType != null) { 2928326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.CONTENT_TYPE, part.mContentType); 2929326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 2930326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.w(TAG, "MMS has no CONTENT_TYPE for part " + count); 2931326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2932326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(part.mContentId != null) { 2933326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.CONTENT_ID, part.mContentId); 2934326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 2935326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(part.mPartName != null) { 2936326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.CONTENT_ID, "<" + part.mPartName + ">"); 2937326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 2938326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.CONTENT_ID, "<part_" + count + ">"); 2939ed0c6ae1773ad1f4249fe3cf7447d7033195f222Ashwini Munigala } 2940ed0c6ae1773ad1f4249fe3cf7447d7033195f222Ashwini Munigala } 2941326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 2942326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(part.mContentLocation != null) { 2943326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.CONTENT_LOCATION, part.mContentLocation); 2944326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 2945326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(part.mPartName != null) { 2946326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.CONTENT_LOCATION, part.mPartName + ".dat"); 2947326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 2948326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.CONTENT_LOCATION, "part_" + count + ".dat"); 2949326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2950326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 2951326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(part.mContentDisposition != null) 2952326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.CONTENT_DISPOSITION, part.mContentDisposition); 2953326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(part.mPartName != null) { 2954326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.FILENAME, part.mPartName); 2955326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.NAME, part.mPartName); 2956326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 295770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz /* We must set at least one part identifier */ 2958326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.FILENAME, "part_" + count + ".dat"); 2959326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde values.put(Mms.Part.NAME, "part_" + count + ".dat"); 296070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 2961326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Uri partUri = Uri.parse(Mms.CONTENT_URI + "/" + handle + "/part"); 2962fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Uri res = mResolver.insert(partUri, values); 2963fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2964fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie // Add data to part 2965fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie OutputStream os = mResolver.openOutputStream(res); 2966326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde os.write(part.mData); 2967fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie os.close(); 2968fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 2969fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2970fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2971fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void sendMessage(PushMsgInfo msgInfo, String msgBody) { 2972fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2973fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie SmsManager smsMng = SmsManager.getDefault(); 2974fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ArrayList<String> parts = smsMng.divideMessage(msgBody); 2975fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie msgInfo.parts = parts.size(); 2976326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // We add a time stamp to differentiate delivery reports from each other for resent messages 2977326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde msgInfo.timestamp = Calendar.getInstance().getTime().getTime(); 2978326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde msgInfo.partsDelivered = 0; 2979326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde msgInfo.partsSent = 0; 2980fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2981fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ArrayList<PendingIntent> deliveryIntents = new ArrayList<PendingIntent>(msgInfo.parts); 2982fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ArrayList<PendingIntent> sentIntents = new ArrayList<PendingIntent>(msgInfo.parts); 2983fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 2984326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* We handle the SENT intent in the MAP service, as this object 2985326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * is destroyed at disconnect, hence if a disconnect occur while sending 2986326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * a message, there is no intent handler to move the message from outbox 2987326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * to the correct folder. 2988326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * The correct solution would be to create a service that will start based on 2989326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * the intent, if BT is turned off. */ 2990326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 2991cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta if (parts != null && parts.size() > 0) { 2992cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta for (int i = 0; i < msgInfo.parts; i++) { 2993cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta Intent intentDelivery, intentSent; 2994cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta 2995cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta intentDelivery = new Intent(ACTION_MESSAGE_DELIVERY, null); 2996cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta /* Add msgId and part number to ensure the intents are different, and we 2997cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta * thereby get an intent for each msg part. 2998cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta * setType is needed to create different intents for each message id/ time stamp, 2999cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta * as the extras are not used when comparing. */ 3000cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta intentDelivery.setType("message/" + Long.toString(msgInfo.id) + 3001cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta msgInfo.timestamp + i); 3002cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta intentDelivery.putExtra(EXTRA_MESSAGE_SENT_HANDLE, msgInfo.id); 3003cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta intentDelivery.putExtra(EXTRA_MESSAGE_SENT_TIMESTAMP, msgInfo.timestamp); 3004cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta PendingIntent pendingIntentDelivery = PendingIntent.getBroadcast(mContext, 0, 3005cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta intentDelivery, PendingIntent.FLAG_UPDATE_CURRENT); 3006cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta 3007cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta intentSent = new Intent(ACTION_MESSAGE_SENT, null); 3008cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta /* Add msgId and part number to ensure the intents are different, and we 3009cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta * thereby get an intent for each msg part. 3010cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta * setType is needed to create different intents for each message id/ time stamp, 3011cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta * as the extras are not used when comparing. */ 3012cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta intentSent.setType("message/" + Long.toString(msgInfo.id) + msgInfo.timestamp + i); 3013cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta intentSent.putExtra(EXTRA_MESSAGE_SENT_HANDLE, msgInfo.id); 3014cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta intentSent.putExtra(EXTRA_MESSAGE_SENT_URI, msgInfo.uri.toString()); 3015cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta intentSent.putExtra(EXTRA_MESSAGE_SENT_RETRY, msgInfo.retry); 3016cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta intentSent.putExtra(EXTRA_MESSAGE_SENT_TRANSPARENT, msgInfo.transparent); 3017cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta 3018cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta PendingIntent pendingIntentSent = PendingIntent.getBroadcast(mContext, 0, 3019cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta intentSent, PendingIntent.FLAG_UPDATE_CURRENT); 3020cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta 3021cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta // We use the same pending intent for all parts, but do not set the one shot flag. 3022cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta deliveryIntents.add(pendingIntentDelivery); 3023cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta sentIntents.add(pendingIntentSent); 3024cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta } 3025cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta 3026cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta Log.d(TAG, "sendMessage to " + msgInfo.phone); 3027cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta 3028cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta smsMng.sendMultipartTextMessage(msgInfo.phone, null, parts, sentIntents, 3029cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta deliveryIntents); 3030cd72c4dfe4db77c6df24db94f8d9a04efff7ab1dHemant Gupta } 3031fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 3032fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 3033fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private class SmsBroadcastReceiver extends BroadcastReceiver { 3034fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private final String[] ID_PROJECTION = new String[] { Sms._ID }; 3035326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private final Uri UPDATE_STATUS_URI = Uri.withAppendedPath(Sms.CONTENT_URI, "/status"); 3036fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 3037fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void register() { 3038400eaf8761223196a18b84247b066f0201226c3bHemant Gupta Handler handler = new Handler(Looper.getMainLooper()); 3039fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 3040fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie IntentFilter intentFilter = new IntentFilter(); 3041fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie intentFilter.addAction(ACTION_MESSAGE_DELIVERY); 3042326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde try{ 3043326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde intentFilter.addDataType("message/*"); 3044326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } catch (MalformedMimeTypeException e) { 3045326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.e(TAG, "Wrong mime type!!!", e); 3046326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 3047326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 3048fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mContext.registerReceiver(this, intentFilter, null, handler); 3049fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 3050fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 3051fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void unregister() { 3052fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie try { 3053fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mContext.unregisterReceiver(this); 3054fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } catch (IllegalArgumentException e) { 3055fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* do nothing */ 3056fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 3057fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 3058fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 3059fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie @Override 3060fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void onReceive(Context context, Intent intent) { 3061fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie String action = intent.getAction(); 3062326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde long handle = intent.getLongExtra(EXTRA_MESSAGE_SENT_HANDLE, -1); 3063fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie PushMsgInfo msgInfo = mPushMsgList.get(handle); 3064fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 3065fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.d(TAG, "onReceive: action" + action); 3066fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 3067fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (msgInfo == null) { 3068fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.d(TAG, "onReceive: no msgInfo found for handle " + handle); 3069fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return; 3070fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 3071fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 30724f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala if (action.equals(ACTION_MESSAGE_SENT)) { 30734f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala int result = intent.getIntExtra(EXTRA_MESSAGE_SENT_RESULT, 30744f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala Activity.RESULT_CANCELED); 30754f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala msgInfo.partsSent++; 30764f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala if(result != Activity.RESULT_OK) { 30774f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala /* If just one of the parts in the message fails, we need to send the 30784f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala * entire message again 30794f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala */ 30804f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala msgInfo.failedSent = true; 30814f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala } 30824f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala if(D) Log.d(TAG, "onReceive: msgInfo.partsSent = " + msgInfo.partsSent 30834f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala + ", msgInfo.parts = " + msgInfo.parts + " result = " + result); 30844f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala 30854f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala if (msgInfo.partsSent == msgInfo.parts) { 30864f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala actionMessageSent(context, intent, msgInfo); 30874f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala } 30884f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala } else if (action.equals(ACTION_MESSAGE_DELIVERY)) { 3089326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde long timestamp = intent.getLongExtra(EXTRA_MESSAGE_SENT_TIMESTAMP, 0); 3090326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde int status = -1; 3091326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(msgInfo.timestamp == timestamp) { 3092326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde msgInfo.partsDelivered++; 3093326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde byte[] pdu = intent.getByteArrayExtra("pdu"); 3094326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde String format = intent.getStringExtra("format"); 3095326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 3096326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde SmsMessage message = SmsMessage.createFromPdu(pdu, format); 3097326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (message == null) { 3098326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.d(TAG, "actionMessageDelivery: Can't get message from pdu"); 3099326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde return; 3100326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 3101326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde status = message.getStatus(); 3102326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(status != 0/*0 is success*/) { 3103326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde msgInfo.statusDelivered = status; 31045a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(D) Log.d(TAG, "msgInfo.statusDelivered = " + status); 31050ebd4e58920add6114b1f345b7d95e0709096fe3Ajay Panicker Sms.moveMessageToFolder(mContext, msgInfo.uri, Sms.MESSAGE_TYPE_FAILED, 0); 31060ebd4e58920add6114b1f345b7d95e0709096fe3Ajay Panicker } else { 31070ebd4e58920add6114b1f345b7d95e0709096fe3Ajay Panicker Sms.moveMessageToFolder(mContext, msgInfo.uri, Sms.MESSAGE_TYPE_SENT, 0); 3108326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 3109326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 3110fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (msgInfo.partsDelivered == msgInfo.parts) { 3111fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie actionMessageDelivery(context, intent, msgInfo); 3112fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 3113fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else { 3114fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.d(TAG, "onReceive: Unknown action " + action); 3115fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 3116fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 3117fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 31184f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala private void actionMessageSent(Context context, Intent intent, PushMsgInfo msgInfo) { 31194f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala /* As the MESSAGE_SENT intent is forwarded from the MAP service, we use the intent 31204f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala * to carry the result, as getResult() will not return the correct value. 31214f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala */ 31224f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala boolean delete = false; 31234f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala 31244f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala if(D) Log.d(TAG,"actionMessageSent(): msgInfo.failedSent = " + msgInfo.failedSent); 31254f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala 31264f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala msgInfo.sendInProgress = false; 31274f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala 31284f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala if (msgInfo.failedSent == false) { 31294f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala if(D) Log.d(TAG, "actionMessageSent: result OK"); 31304f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala if (msgInfo.transparent == 0) { 31314f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala if (!Sms.moveMessageToFolder(context, msgInfo.uri, 31324f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala Sms.MESSAGE_TYPE_SENT, 0)) { 31334f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala Log.w(TAG, "Failed to move " + msgInfo.uri + " to SENT"); 31344f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala } 31354f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala } else { 31364f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala delete = true; 31374f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala } 31384f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala 31394f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala Event evt = new Event(EVENT_TYPE_SENDING_SUCCESS, msgInfo.id, 31404f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala getSmsFolderName(Sms.MESSAGE_TYPE_SENT), null, mSmsType); 31414f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala sendEvent(evt); 31424f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala 31434f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala } else { 31444f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala if (msgInfo.retry == 1) { 31454f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala /* Notify failure, but keep message in outbox for resending */ 31464f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala msgInfo.resend = true; 31474f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala msgInfo.partsSent = 0; // Reset counter for the retry 31484f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala msgInfo.failedSent = false; 31494f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala Event evt = new Event(EVENT_TYPE_SENDING_FAILURE, msgInfo.id, 31504f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala getSmsFolderName(Sms.MESSAGE_TYPE_OUTBOX), null, mSmsType); 31514f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala sendEvent(evt); 31524f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala } else { 31534f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala if (msgInfo.transparent == 0) { 31544f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala if (!Sms.moveMessageToFolder(context, msgInfo.uri, 31554f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala Sms.MESSAGE_TYPE_FAILED, 0)) { 31564f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala Log.w(TAG, "Failed to move " + msgInfo.uri + " to FAILED"); 31574f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala } 31584f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala } else { 31594f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala delete = true; 31604f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala } 31614f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala 31624f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala Event evt = new Event(EVENT_TYPE_SENDING_FAILURE, msgInfo.id, 31634f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala getSmsFolderName(Sms.MESSAGE_TYPE_FAILED), null, mSmsType); 31644f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala sendEvent(evt); 31654f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala } 31664f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala } 31674f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala 31684f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala if (delete == true) { 31694f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala /* Delete from Observer message list to avoid delete notifications */ 31704f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala synchronized(getMsgListSms()) { 31714f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala getMsgListSms().remove(msgInfo.id); 31724f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala } 31734f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala 31744f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala /* Delete from DB */ 31754f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala mResolver.delete(msgInfo.uri, null, null); 31764f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala } 31774f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala } 31784f341a3ac7cdfd7c976a9eb59117542d50458398Ashwini Munigala 3179326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private void actionMessageDelivery(Context context, Intent intent, PushMsgInfo msgInfo) { 3180fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Uri messageUri = intent.getData(); 3181326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde msgInfo.sendInProgress = false; 3182fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 3183fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Cursor cursor = mResolver.query(msgInfo.uri, ID_PROJECTION, null, null, null); 3184fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 3185fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie try { 3186fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (cursor.moveToFirst()) { 3187fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int messageId = cursor.getInt(0); 3188fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 3189fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Uri updateUri = ContentUris.withAppendedId(UPDATE_STATUS_URI, messageId); 3190fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 31915a60e47497f21f64e6d79420dc4c56c1907df22akschulz if(D) Log.d(TAG, "actionMessageDelivery: uri=" + messageUri + ", status=" 31925a60e47497f21f64e6d79420dc4c56c1907df22akschulz + msgInfo.statusDelivered); 3193fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 3194fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie ContentValues contentValues = new ContentValues(2); 3195fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 3196326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde contentValues.put(Sms.STATUS, msgInfo.statusDelivered); 3197fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie contentValues.put(Inbox.DATE_SENT, System.currentTimeMillis()); 3198fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mResolver.update(updateUri, contentValues, null, null); 3199fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else { 3200fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.d(TAG, "Can't find message for status update: " + messageUri); 3201fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 3202fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } finally { 32035a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (cursor != null) cursor.close(); 3204fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 3205fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 3206326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (msgInfo.statusDelivered == 0) { 3207326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Event evt = new Event(EVENT_TYPE_DELEVERY_SUCCESS, msgInfo.id, 32085a60e47497f21f64e6d79420dc4c56c1907df22akschulz getSmsFolderName(Sms.MESSAGE_TYPE_SENT), null, mSmsType); 3209fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie sendEvent(evt); 3210fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } else { 32115a60e47497f21f64e6d79420dc4c56c1907df22akschulz Event evt = new Event(EVENT_TYPE_DELIVERY_FAILURE, msgInfo.id, 32125a60e47497f21f64e6d79420dc4c56c1907df22akschulz getSmsFolderName(Sms.MESSAGE_TYPE_SENT), null, mSmsType); 3213fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie sendEvent(evt); 3214fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 3215fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 3216fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mPushMsgList.remove(msgInfo.id); 3217fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 3218fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 3219fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 3220725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker private class CeBroadcastReceiver extends BroadcastReceiver { 3221725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker public void register() { 3222725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker UserManager manager = UserManager.get(mContext); 3223725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker if (manager == null || manager.isUserUnlocked()) { 3224725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker mStorageUnlocked = true; 3225725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker return; 3226725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker } 3227725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker 3228725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker Handler handler = new Handler(Looper.getMainLooper()); 3229725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker IntentFilter intentFilter = new IntentFilter(); 3230725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker intentFilter.addAction(Intent.ACTION_BOOT_COMPLETED); 3231725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker mContext.registerReceiver(this, intentFilter, null, handler); 3232725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker } 3233725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker 3234725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker public void unregister() { 3235725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker try { 3236725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker mContext.unregisterReceiver(this); 3237725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker } catch (IllegalArgumentException e) { 3238725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker /* do nothing */ 3239725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker } 3240725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker } 3241725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker 3242725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker public void onReceive(Context context, Intent intent) { 3243725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker String action = intent.getAction(); 3244725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker Log.d(TAG, "onReceive: action" + action); 3245725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker 3246725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker if (action.equals(Intent.ACTION_BOOT_COMPLETED)) { 3247725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker try { 3248725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker initMsgList(); 3249725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker } catch (RemoteException e) { 3250725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker Log.e(TAG, "Error initializing SMS/MMS message lists."); 3251725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker } 3252725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker 3253725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker for (String folder : FOLDER_SMS_MAP.values()) { 3254725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker Event evt = new Event(EVENT_TYPE_NEW, -1, folder, mSmsType); 3255725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker sendEvent(evt); 3256725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker } 3257725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker mStorageUnlocked = true; 3258725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker /* After unlock this BroadcastReceiver is never needed */ 3259725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker unregister(); 3260725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker } else { 3261725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker Log.d(TAG, "onReceive: Unknown action " + action); 3262725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker } 3263725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker } 3264725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker } 3265725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker 3266ed70219e41ba68196798dcbf75b782d13fb88603kschulz /** 3267ed70219e41ba68196798dcbf75b782d13fb88603kschulz * Handle MMS sent intents in disconnected(MNS) state, where we do not need to send any 3268ed70219e41ba68196798dcbf75b782d13fb88603kschulz * notifications. 3269ed70219e41ba68196798dcbf75b782d13fb88603kschulz * @param context The context to use for provider operations 3270ed70219e41ba68196798dcbf75b782d13fb88603kschulz * @param intent The intent received 3271ed70219e41ba68196798dcbf75b782d13fb88603kschulz * @param result The result 3272ed70219e41ba68196798dcbf75b782d13fb88603kschulz */ 3273ed70219e41ba68196798dcbf75b782d13fb88603kschulz static public void actionMmsSent(Context context, Intent intent, int result, 3274ed70219e41ba68196798dcbf75b782d13fb88603kschulz Map<Long, Msg> mmsMsgList) { 3275ed70219e41ba68196798dcbf75b782d13fb88603kschulz /* 3276ed70219e41ba68196798dcbf75b782d13fb88603kschulz * if transparent: 3277ed70219e41ba68196798dcbf75b782d13fb88603kschulz * delete message and send notification(regardless of result) 3278ed70219e41ba68196798dcbf75b782d13fb88603kschulz * else 3279ed70219e41ba68196798dcbf75b782d13fb88603kschulz * Result == Success: 3280ed70219e41ba68196798dcbf75b782d13fb88603kschulz * move to sent folder (will trigger notification) 3281ed70219e41ba68196798dcbf75b782d13fb88603kschulz * Result == Fail: 3282ed70219e41ba68196798dcbf75b782d13fb88603kschulz * move to outbox (send delivery fail notification) 3283ed70219e41ba68196798dcbf75b782d13fb88603kschulz */ 3284ed70219e41ba68196798dcbf75b782d13fb88603kschulz if(D) Log.d(TAG,"actionMmsSent()"); 3285ed70219e41ba68196798dcbf75b782d13fb88603kschulz int transparent = intent.getIntExtra(EXTRA_MESSAGE_SENT_TRANSPARENT, 0); 3286ed70219e41ba68196798dcbf75b782d13fb88603kschulz long handle = intent.getLongExtra(EXTRA_MESSAGE_SENT_HANDLE, -1); 3287ed70219e41ba68196798dcbf75b782d13fb88603kschulz if(handle < 0) { 3288ed70219e41ba68196798dcbf75b782d13fb88603kschulz Log.w(TAG, "Intent received for an invalid handle"); 3289ed70219e41ba68196798dcbf75b782d13fb88603kschulz return; 3290ed70219e41ba68196798dcbf75b782d13fb88603kschulz } 3291ed70219e41ba68196798dcbf75b782d13fb88603kschulz ContentResolver resolver = context.getContentResolver(); 3292ed70219e41ba68196798dcbf75b782d13fb88603kschulz if(transparent == 1) { 3293ed70219e41ba68196798dcbf75b782d13fb88603kschulz /* The specification is a bit unclear about the transparent flag. If it is set 3294ed70219e41ba68196798dcbf75b782d13fb88603kschulz * no copy of the message shall be kept in the send folder after the message 3295ed70219e41ba68196798dcbf75b782d13fb88603kschulz * was send, but in the case of a send error, it is unclear what to do. 3296ed70219e41ba68196798dcbf75b782d13fb88603kschulz * As it will not be transparent if we keep the message in any folder, 3297ed70219e41ba68196798dcbf75b782d13fb88603kschulz * we delete the message regardless of the result. 3298ed70219e41ba68196798dcbf75b782d13fb88603kschulz * If we however do have a MNS connection we need to send a notification. */ 3299ed70219e41ba68196798dcbf75b782d13fb88603kschulz Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, handle); 3300ed70219e41ba68196798dcbf75b782d13fb88603kschulz /* Delete from observer message list to avoid delete notifications */ 3301ed70219e41ba68196798dcbf75b782d13fb88603kschulz if(mmsMsgList != null) { 3302ed70219e41ba68196798dcbf75b782d13fb88603kschulz synchronized(mmsMsgList) { 3303ed70219e41ba68196798dcbf75b782d13fb88603kschulz mmsMsgList.remove(handle); 3304ed70219e41ba68196798dcbf75b782d13fb88603kschulz } 3305ed70219e41ba68196798dcbf75b782d13fb88603kschulz } 3306ed70219e41ba68196798dcbf75b782d13fb88603kschulz /* Delete message */ 3307ed70219e41ba68196798dcbf75b782d13fb88603kschulz if(D) Log.d(TAG,"Transparent in use - delete"); 3308ed70219e41ba68196798dcbf75b782d13fb88603kschulz resolver.delete(uri, null, null); 3309ed70219e41ba68196798dcbf75b782d13fb88603kschulz } else if (result == Activity.RESULT_OK) { 3310ed70219e41ba68196798dcbf75b782d13fb88603kschulz /* This will trigger a notification */ 3311ed70219e41ba68196798dcbf75b782d13fb88603kschulz moveMmsToFolder(handle, resolver, Mms.MESSAGE_BOX_SENT); 3312ed70219e41ba68196798dcbf75b782d13fb88603kschulz } else { 3313ed70219e41ba68196798dcbf75b782d13fb88603kschulz if(mmsMsgList != null) { 3314ed70219e41ba68196798dcbf75b782d13fb88603kschulz synchronized(mmsMsgList) { 3315ed70219e41ba68196798dcbf75b782d13fb88603kschulz Msg msg = mmsMsgList.get(handle); 3316ed70219e41ba68196798dcbf75b782d13fb88603kschulz if(msg != null) { 3317ed70219e41ba68196798dcbf75b782d13fb88603kschulz msg.type=Mms.MESSAGE_BOX_OUTBOX; 3318ed70219e41ba68196798dcbf75b782d13fb88603kschulz } 3319ed70219e41ba68196798dcbf75b782d13fb88603kschulz } 3320ed70219e41ba68196798dcbf75b782d13fb88603kschulz } 3321ed70219e41ba68196798dcbf75b782d13fb88603kschulz /* Hand further retries over to the MMS application */ 3322ed70219e41ba68196798dcbf75b782d13fb88603kschulz moveMmsToFolder(handle, resolver, Mms.MESSAGE_BOX_OUTBOX); 3323ed70219e41ba68196798dcbf75b782d13fb88603kschulz } 3324ed70219e41ba68196798dcbf75b782d13fb88603kschulz } 3325ed70219e41ba68196798dcbf75b782d13fb88603kschulz 3326326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde static public void actionMessageSentDisconnected(Context context, Intent intent, int result) { 3327ed70219e41ba68196798dcbf75b782d13fb88603kschulz TYPE type = TYPE.fromOrdinal( 3328ed70219e41ba68196798dcbf75b782d13fb88603kschulz intent.getIntExtra(EXTRA_MESSAGE_SENT_MSG_TYPE, TYPE.NONE.ordinal())); 3329ed70219e41ba68196798dcbf75b782d13fb88603kschulz if(type == TYPE.MMS) { 3330edb6da171b8b7a6f9d4aa5a773d734a464f1ec66Miao Chou actionMmsSent(context, intent, result, null); 3331ed70219e41ba68196798dcbf75b782d13fb88603kschulz } else { 3332edb6da171b8b7a6f9d4aa5a773d734a464f1ec66Miao Chou actionSmsSentDisconnected(context, intent, result); 3333ed70219e41ba68196798dcbf75b782d13fb88603kschulz } 3334ed70219e41ba68196798dcbf75b782d13fb88603kschulz } 3335ed70219e41ba68196798dcbf75b782d13fb88603kschulz 3336ed70219e41ba68196798dcbf75b782d13fb88603kschulz static public void actionSmsSentDisconnected(Context context, Intent intent, int result) { 3337edb6da171b8b7a6f9d4aa5a773d734a464f1ec66Miao Chou /* Check permission for message deletion. */ 3338edb6da171b8b7a6f9d4aa5a773d734a464f1ec66Miao Chou if ((Binder.getCallingPid() != Process.myPid()) || 3339edb6da171b8b7a6f9d4aa5a773d734a464f1ec66Miao Chou (context.checkCallingOrSelfPermission("android.Manifest.permission.WRITE_SMS") 3340edb6da171b8b7a6f9d4aa5a773d734a464f1ec66Miao Chou != PackageManager.PERMISSION_GRANTED)) { 3341edb6da171b8b7a6f9d4aa5a773d734a464f1ec66Miao Chou Log.w(TAG, "actionSmsSentDisconnected: Not allowed to delete SMS/MMS messages"); 3342edb6da171b8b7a6f9d4aa5a773d734a464f1ec66Miao Chou return; 3343edb6da171b8b7a6f9d4aa5a773d734a464f1ec66Miao Chou } 3344edb6da171b8b7a6f9d4aa5a773d734a464f1ec66Miao Chou 3345326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde boolean delete = false; 3346326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde //int retry = intent.getIntExtra(EXTRA_MESSAGE_SENT_RETRY, 0); 3347326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde int transparent = intent.getIntExtra(EXTRA_MESSAGE_SENT_TRANSPARENT, 0); 3348326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde String uriString = intent.getStringExtra(EXTRA_MESSAGE_SENT_URI); 3349326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(uriString == null) { 3350326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // Nothing we can do about it, just bail out 3351326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde return; 3352326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 3353326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Uri uri = Uri.parse(uriString); 3354326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 3355326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (result == Activity.RESULT_OK) { 3356326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.d(TAG, "actionMessageSentDisconnected: result OK"); 3357326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (transparent == 0) { 3358326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (!Sms.moveMessageToFolder(context, uri, 3359326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Sms.MESSAGE_TYPE_SENT, 0)) { 3360326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.d(TAG, "Failed to move " + uri + " to SENT"); 3361326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 3362326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 3363326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde delete = true; 3364326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 3365326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 3366326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /*if (retry == 1) { 3367326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde The retry feature only works while connected, else we fail the send, 33685a60e47497f21f64e6d79420dc4c56c1907df22akschulz * and move the message to failed, to let the user/app resend manually later. 3369326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else */{ 3370326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (transparent == 0) { 3371326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (!Sms.moveMessageToFolder(context, uri, 3372326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Sms.MESSAGE_TYPE_FAILED, 0)) { 3373326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.d(TAG, "Failed to move " + uri + " to FAILED"); 3374326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 3375326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 3376326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde delete = true; 3377326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 3378326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 3379326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 3380326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 3381edb6da171b8b7a6f9d4aa5a773d734a464f1ec66Miao Chou if (delete) { 3382326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* Delete from DB */ 3383326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde ContentResolver resolver = context.getContentResolver(); 3384edb6da171b8b7a6f9d4aa5a773d734a464f1ec66Miao Chou if (resolver != null) { 3385326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde resolver.delete(uri, null, null); 3386326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 3387326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.w(TAG, "Unable to get resolver"); 3388326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 3389326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 3390326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 3391326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 3392fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private void registerPhoneServiceStateListener() { 33935a60e47497f21f64e6d79420dc4c56c1907df22akschulz TelephonyManager tm = (TelephonyManager)mContext.getSystemService( 33945a60e47497f21f64e6d79420dc4c56c1907df22akschulz Context.TELEPHONY_SERVICE); 3395fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie tm.listen(mPhoneListener, PhoneStateListener.LISTEN_SERVICE_STATE); 3396fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 3397fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 3398fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private void unRegisterPhoneServiceStateListener() { 33995a60e47497f21f64e6d79420dc4c56c1907df22akschulz TelephonyManager tm = (TelephonyManager)mContext.getSystemService( 34005a60e47497f21f64e6d79420dc4c56c1907df22akschulz Context.TELEPHONY_SERVICE); 3401fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie tm.listen(mPhoneListener, PhoneStateListener.LISTEN_NONE); 3402fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 3403fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 3404fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private void resendPendingMessages() { 3405fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Send pending messages in outbox */ 3406fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie String where = "type = " + Sms.MESSAGE_TYPE_OUTBOX; 3407db8d8ae565b3db6a5e3187170dcb7b281a79f9daAjay Panicker UserManager manager = UserManager.get(mContext); 3408db8d8ae565b3db6a5e3187170dcb7b281a79f9daAjay Panicker if (manager == null || !manager.isUserUnlocked()) return; 34095a60e47497f21f64e6d79420dc4c56c1907df22akschulz Cursor c = mResolver.query(Sms.CONTENT_URI, SMS_PROJECTION, where, null, 34105a60e47497f21f64e6d79420dc4c56c1907df22akschulz null); 341128446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz try { 34125a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null && c.moveToFirst()) { 34135a60e47497f21f64e6d79420dc4c56c1907df22akschulz do { 34145a60e47497f21f64e6d79420dc4c56c1907df22akschulz long id = c.getLong(c.getColumnIndex(Sms._ID)); 34155a60e47497f21f64e6d79420dc4c56c1907df22akschulz String msgBody = c.getString(c.getColumnIndex(Sms.BODY)); 34165a60e47497f21f64e6d79420dc4c56c1907df22akschulz PushMsgInfo msgInfo = mPushMsgList.get(id); 34175a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (msgInfo == null || msgInfo.resend == false || 34185a60e47497f21f64e6d79420dc4c56c1907df22akschulz msgInfo.sendInProgress == true) { 34195a60e47497f21f64e6d79420dc4c56c1907df22akschulz continue; 34205a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 34215a60e47497f21f64e6d79420dc4c56c1907df22akschulz msgInfo.sendInProgress = true; 34225a60e47497f21f64e6d79420dc4c56c1907df22akschulz sendMessage(msgInfo, msgBody); 34235a60e47497f21f64e6d79420dc4c56c1907df22akschulz } while (c.moveToNext()); 342428446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } 342528446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } finally { 34265a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null) c.close(); 3427fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 34285a60e47497f21f64e6d79420dc4c56c1907df22akschulz 34295a60e47497f21f64e6d79420dc4c56c1907df22akschulz 3430fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 3431fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 3432fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private void failPendingMessages() { 3433fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Move pending messages from outbox to failed */ 3434fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie String where = "type = " + Sms.MESSAGE_TYPE_OUTBOX; 34355a60e47497f21f64e6d79420dc4c56c1907df22akschulz Cursor c = mResolver.query(Sms.CONTENT_URI, SMS_PROJECTION, where, null, 34365a60e47497f21f64e6d79420dc4c56c1907df22akschulz null); 343728446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz try { 34385a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null && c.moveToFirst()) { 34395a60e47497f21f64e6d79420dc4c56c1907df22akschulz do { 34405a60e47497f21f64e6d79420dc4c56c1907df22akschulz long id = c.getLong(c.getColumnIndex(Sms._ID)); 34415a60e47497f21f64e6d79420dc4c56c1907df22akschulz String msgBody = c.getString(c.getColumnIndex(Sms.BODY)); 34425a60e47497f21f64e6d79420dc4c56c1907df22akschulz PushMsgInfo msgInfo = mPushMsgList.get(id); 34435a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (msgInfo == null || msgInfo.resend == false) { 34445a60e47497f21f64e6d79420dc4c56c1907df22akschulz continue; 34455a60e47497f21f64e6d79420dc4c56c1907df22akschulz } 34465a60e47497f21f64e6d79420dc4c56c1907df22akschulz Sms.moveMessageToFolder(mContext, msgInfo.uri, 34475a60e47497f21f64e6d79420dc4c56c1907df22akschulz Sms.MESSAGE_TYPE_FAILED, 0); 34485a60e47497f21f64e6d79420dc4c56c1907df22akschulz } while (c.moveToNext()); 344928446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } 345028446a56718e80574ba7b81901fc5a1368bf5839Kim Schulz } finally { 34515a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (c != null) c.close(); 3452fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 34535a60e47497f21f64e6d79420dc4c56c1907df22akschulz 3454fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 3455fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 3456fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private void removeDeletedMessages() { 3457fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /* Remove messages from virtual "deleted" folder (thread_id -1) */ 3458326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mResolver.delete(Sms.CONTENT_URI, 3459fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie "thread_id = " + DELETED_THREAD_ID, null); 3460fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 3461fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 3462fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private PhoneStateListener mPhoneListener = new PhoneStateListener() { 3463fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie @Override 3464fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void onServiceStateChanged(ServiceState serviceState) { 3465fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie Log.d(TAG, "Phone service state change: " + serviceState.getState()); 3466fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (serviceState.getState() == ServiceState.STATE_IN_SERVICE) { 3467fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie resendPendingMessages(); 3468fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 3469fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 3470fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie }; 3471fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 3472fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void init() { 3473b6fdf260e28b4eb6b5cdb19f53710c0470ffcad2Hemant Gupta if (mSmsBroadcastReceiver != null) { 3474b6fdf260e28b4eb6b5cdb19f53710c0470ffcad2Hemant Gupta mSmsBroadcastReceiver.register(); 3475b6fdf260e28b4eb6b5cdb19f53710c0470ffcad2Hemant Gupta } 3476725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker 3477725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker if (mCeBroadcastReceiver != null) { 3478725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker mCeBroadcastReceiver.register(); 3479725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker } 3480725c70cfb004690027ded41f080bfe1bb17d2285Ajay Panicker 3481fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie registerPhoneServiceStateListener(); 3482326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mInitialized = true; 3483fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 3484fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 3485fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void deinit() { 3486326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mInitialized = false; 3487326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde unregisterObserver(); 3488b6fdf260e28b4eb6b5cdb19f53710c0470ffcad2Hemant Gupta if (mSmsBroadcastReceiver != null) { 3489b6fdf260e28b4eb6b5cdb19f53710c0470ffcad2Hemant Gupta mSmsBroadcastReceiver.unregister(); 3490b6fdf260e28b4eb6b5cdb19f53710c0470ffcad2Hemant Gupta } 3491fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie unRegisterPhoneServiceStateListener(); 3492fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie failPendingMessages(); 3493fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie removeDeletedMessages(); 3494fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 3495326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 3496326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde public boolean handleSmsSendIntent(Context context, Intent intent){ 3497ed70219e41ba68196798dcbf75b782d13fb88603kschulz TYPE type = TYPE.fromOrdinal( 3498ed70219e41ba68196798dcbf75b782d13fb88603kschulz intent.getIntExtra(EXTRA_MESSAGE_SENT_MSG_TYPE, TYPE.NONE.ordinal())); 3499ed70219e41ba68196798dcbf75b782d13fb88603kschulz if(type == TYPE.MMS) { 3500ed70219e41ba68196798dcbf75b782d13fb88603kschulz return handleMmsSendIntent(context, intent); 3501ed70219e41ba68196798dcbf75b782d13fb88603kschulz } else { 3502ed70219e41ba68196798dcbf75b782d13fb88603kschulz if(mInitialized) { 3503ed70219e41ba68196798dcbf75b782d13fb88603kschulz mSmsBroadcastReceiver.onReceive(context, intent); 3504ed70219e41ba68196798dcbf75b782d13fb88603kschulz return true; 3505ed70219e41ba68196798dcbf75b782d13fb88603kschulz } 3506326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 3507326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde return false; 3508326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 3509ed70219e41ba68196798dcbf75b782d13fb88603kschulz 3510ed70219e41ba68196798dcbf75b782d13fb88603kschulz public boolean handleMmsSendIntent(Context context, Intent intent){ 3511ed70219e41ba68196798dcbf75b782d13fb88603kschulz if(D) Log.w(TAG, "handleMmsSendIntent()"); 3512ed70219e41ba68196798dcbf75b782d13fb88603kschulz if(mMnsClient.isConnected() == false) { 3513ed70219e41ba68196798dcbf75b782d13fb88603kschulz // No need to handle notifications, just use default handling 3514ed70219e41ba68196798dcbf75b782d13fb88603kschulz if(D) Log.w(TAG, "MNS not connected - use static handling"); 3515ed70219e41ba68196798dcbf75b782d13fb88603kschulz return false; 3516ed70219e41ba68196798dcbf75b782d13fb88603kschulz } 3517ed70219e41ba68196798dcbf75b782d13fb88603kschulz long handle = intent.getLongExtra(EXTRA_MESSAGE_SENT_HANDLE, -1); 3518ed70219e41ba68196798dcbf75b782d13fb88603kschulz int result = intent.getIntExtra(EXTRA_MESSAGE_SENT_RESULT, Activity.RESULT_CANCELED); 3519ed70219e41ba68196798dcbf75b782d13fb88603kschulz actionMmsSent(context, intent, result, getMsgListMms()); 3520ed70219e41ba68196798dcbf75b782d13fb88603kschulz if(handle < 0) { 3521ed70219e41ba68196798dcbf75b782d13fb88603kschulz Log.w(TAG, "Intent received for an invalid handle"); 3522ed70219e41ba68196798dcbf75b782d13fb88603kschulz return true; 3523ed70219e41ba68196798dcbf75b782d13fb88603kschulz } 3524ed70219e41ba68196798dcbf75b782d13fb88603kschulz if(result != Activity.RESULT_OK) { 3525ed70219e41ba68196798dcbf75b782d13fb88603kschulz if(mObserverRegistered) { 3526ed70219e41ba68196798dcbf75b782d13fb88603kschulz Event evt = new Event(EVENT_TYPE_SENDING_FAILURE, handle, 3527ed70219e41ba68196798dcbf75b782d13fb88603kschulz getMmsFolderName(Mms.MESSAGE_BOX_OUTBOX), null, TYPE.MMS); 3528ed70219e41ba68196798dcbf75b782d13fb88603kschulz sendEvent(evt); 3529ed70219e41ba68196798dcbf75b782d13fb88603kschulz } 3530ed70219e41ba68196798dcbf75b782d13fb88603kschulz } else { 3531ed70219e41ba68196798dcbf75b782d13fb88603kschulz int transparent = intent.getIntExtra(EXTRA_MESSAGE_SENT_TRANSPARENT, 0); 3532ed70219e41ba68196798dcbf75b782d13fb88603kschulz if(transparent != 0) { 3533ed70219e41ba68196798dcbf75b782d13fb88603kschulz if(mObserverRegistered) { 3534ed70219e41ba68196798dcbf75b782d13fb88603kschulz Event evt = new Event(EVENT_TYPE_SENDING_SUCCESS, handle, 3535ed70219e41ba68196798dcbf75b782d13fb88603kschulz getMmsFolderName(Mms.MESSAGE_BOX_OUTBOX), null, TYPE.MMS); 3536ed70219e41ba68196798dcbf75b782d13fb88603kschulz sendEvent(evt); 3537ed70219e41ba68196798dcbf75b782d13fb88603kschulz } 3538ed70219e41ba68196798dcbf75b782d13fb88603kschulz } 3539ed70219e41ba68196798dcbf75b782d13fb88603kschulz } 3540ed70219e41ba68196798dcbf75b782d13fb88603kschulz return true; 3541ed70219e41ba68196798dcbf75b782d13fb88603kschulz } 3542ed70219e41ba68196798dcbf75b782d13fb88603kschulz 3543fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie} 3544