1526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen/* 2526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Copyright (C) 2007-2008 Esmertec AG. 3526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Copyright (C) 2007-2008 The Android Open Source Project 4526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 5526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Licensed under the Apache License, Version 2.0 (the "License"); 6526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * you may not use this file except in compliance with the License. 7526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * You may obtain a copy of the License at 8526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 9526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * http://www.apache.org/licenses/LICENSE-2.0 10526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 11526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Unless required by applicable law or agreed to in writing, software 12526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * distributed under the License is distributed on an "AS IS" BASIS, 13526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * See the License for the specific language governing permissions and 15526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * limitations under the License. 16526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 17526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 18526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenpackage com.google.android.mms.pdu; 19526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 20526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport com.google.android.mms.ContentType; 21526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport com.google.android.mms.InvalidHeaderValueException; 22526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport com.google.android.mms.MmsException; 23526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport com.google.android.mms.util.DownloadDrmHelper; 24526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport com.google.android.mms.util.DrmConvertSession; 25526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport com.google.android.mms.util.PduCache; 26526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport com.google.android.mms.util.PduCacheEntry; 27526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport com.google.android.mms.util.SqliteWrapper; 28526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 29526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.content.ContentResolver; 30526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.content.ContentUris; 31526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.content.ContentValues; 32526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.content.Context; 33526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.database.Cursor; 34526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.database.DatabaseUtils; 35526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.database.sqlite.SQLiteException; 36526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.drm.DrmManagerClient; 37526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.net.Uri; 38526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.provider.MediaStore; 39526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.provider.Telephony; 40526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.provider.Telephony.Mms; 41526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.provider.Telephony.MmsSms; 42526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.provider.Telephony.Threads; 43526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.provider.Telephony.Mms.Addr; 44526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.provider.Telephony.Mms.Part; 45526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.provider.Telephony.MmsSms.PendingMessages; 468c90b1263ad9ee3a29ec2af435779d095c5cacc7Tom Taylorimport android.telephony.SubscriptionManager; 47526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.telephony.PhoneNumberUtils; 48526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.telephony.TelephonyManager; 49526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.text.TextUtils; 50526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport android.util.Log; 51526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 52526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport java.io.ByteArrayOutputStream; 53526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport java.io.File; 54526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport java.io.FileNotFoundException; 55526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport java.io.IOException; 56526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport java.io.InputStream; 57526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport java.io.OutputStream; 58526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport java.io.UnsupportedEncodingException; 59526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport java.util.ArrayList; 60526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport java.util.HashMap; 61526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport java.util.HashSet; 62526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport java.util.Map; 63526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport java.util.Set; 64526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport java.util.Map.Entry; 65526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 66526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenimport com.google.android.mms.pdu.EncodedStringValue; 67526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 68526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen/** 69526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * This class is the high-level manager of PDU storage. 70526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 71526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wenpublic class PduPersister { 72526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final String TAG = "PduPersister"; 73526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final boolean DEBUG = false; 74526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final boolean LOCAL_LOGV = false; 75526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 76526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final long DUMMY_THREAD_ID = Long.MAX_VALUE; 77526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 78526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 79526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * The uri of temporary drm objects. 80526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 81526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen public static final String TEMPORARY_DRM_OBJECT_URI = 82526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen "content://mms/" + Long.MAX_VALUE + "/part"; 83526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 84526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Indicate that we transiently failed to process a MM. 85526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 86526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen public static final int PROC_STATUS_TRANSIENT_FAILURE = 1; 87526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 88526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Indicate that we permanently failed to process a MM. 89526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 90526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen public static final int PROC_STATUS_PERMANENTLY_FAILURE = 2; 91526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 92526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Indicate that we have successfully processed a MM. 93526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 94526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen public static final int PROC_STATUS_COMPLETED = 3; 95526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 96526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static PduPersister sPersister; 97526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final PduCache PDU_CACHE_INSTANCE; 98526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 99526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int[] ADDRESS_FIELDS = new int[] { 100526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduHeaders.BCC, 101526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduHeaders.CC, 102526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduHeaders.FROM, 103526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduHeaders.TO 104526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen }; 105526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 106526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final String[] PDU_PROJECTION = new String[] { 107526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms._ID, 108526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.MESSAGE_BOX, 109526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.THREAD_ID, 110526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.RETRIEVE_TEXT, 111526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.SUBJECT, 112526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.CONTENT_LOCATION, 113526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.CONTENT_TYPE, 114526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.MESSAGE_CLASS, 115526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.MESSAGE_ID, 116526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.RESPONSE_TEXT, 117526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.TRANSACTION_ID, 118526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.CONTENT_CLASS, 119526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.DELIVERY_REPORT, 120526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.MESSAGE_TYPE, 121526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.MMS_VERSION, 122526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.PRIORITY, 123526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.READ_REPORT, 124526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.READ_STATUS, 125526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.REPORT_ALLOWED, 126526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.RETRIEVE_STATUS, 127526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.STATUS, 128526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.DATE, 129526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.DELIVERY_TIME, 130526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.EXPIRY, 131526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.MESSAGE_SIZE, 132526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.SUBJECT_CHARSET, 133526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Mms.RETRIEVE_TEXT_CHARSET, 134526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen }; 135526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 136526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_ID = 0; 137526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_MESSAGE_BOX = 1; 138526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_THREAD_ID = 2; 139526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_RETRIEVE_TEXT = 3; 140526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_SUBJECT = 4; 141526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_CONTENT_LOCATION = 5; 142526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_CONTENT_TYPE = 6; 143526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_MESSAGE_CLASS = 7; 144526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_MESSAGE_ID = 8; 145526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_RESPONSE_TEXT = 9; 146526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_TRANSACTION_ID = 10; 147526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_CONTENT_CLASS = 11; 148526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_DELIVERY_REPORT = 12; 149526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_MESSAGE_TYPE = 13; 150526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_MMS_VERSION = 14; 151526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_PRIORITY = 15; 152526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_READ_REPORT = 16; 153526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_READ_STATUS = 17; 154526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_REPORT_ALLOWED = 18; 155526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_RETRIEVE_STATUS = 19; 156526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_STATUS = 20; 157526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_DATE = 21; 158526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_DELIVERY_TIME = 22; 159526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_EXPIRY = 23; 160526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_MESSAGE_SIZE = 24; 161526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_SUBJECT_CHARSET = 25; 162526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PDU_COLUMN_RETRIEVE_TEXT_CHARSET = 26; 163526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 164526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final String[] PART_PROJECTION = new String[] { 165526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Part._ID, 166526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Part.CHARSET, 167526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Part.CONTENT_DISPOSITION, 168526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Part.CONTENT_ID, 169526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Part.CONTENT_LOCATION, 170526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Part.CONTENT_TYPE, 171526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Part.FILENAME, 172526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Part.NAME, 173526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Part.TEXT 174526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen }; 175526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 176526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PART_COLUMN_ID = 0; 177526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PART_COLUMN_CHARSET = 1; 178526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PART_COLUMN_CONTENT_DISPOSITION = 2; 179526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PART_COLUMN_CONTENT_ID = 3; 180526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PART_COLUMN_CONTENT_LOCATION = 4; 181526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PART_COLUMN_CONTENT_TYPE = 5; 182526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PART_COLUMN_FILENAME = 6; 183526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PART_COLUMN_NAME = 7; 184526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final int PART_COLUMN_TEXT = 8; 185526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 186526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final HashMap<Uri, Integer> MESSAGE_BOX_MAP; 187526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // These map are used for convenience in persist() and load(). 188526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final HashMap<Integer, Integer> CHARSET_COLUMN_INDEX_MAP; 189526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final HashMap<Integer, Integer> ENCODED_STRING_COLUMN_INDEX_MAP; 190526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final HashMap<Integer, Integer> TEXT_STRING_COLUMN_INDEX_MAP; 191526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final HashMap<Integer, Integer> OCTET_COLUMN_INDEX_MAP; 192526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final HashMap<Integer, Integer> LONG_COLUMN_INDEX_MAP; 193526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final HashMap<Integer, String> CHARSET_COLUMN_NAME_MAP; 194526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final HashMap<Integer, String> ENCODED_STRING_COLUMN_NAME_MAP; 195526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final HashMap<Integer, String> TEXT_STRING_COLUMN_NAME_MAP; 196526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final HashMap<Integer, String> OCTET_COLUMN_NAME_MAP; 197526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static final HashMap<Integer, String> LONG_COLUMN_NAME_MAP; 198526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 199526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen static { 200526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen MESSAGE_BOX_MAP = new HashMap<Uri, Integer>(); 201526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen MESSAGE_BOX_MAP.put(Mms.Inbox.CONTENT_URI, Mms.MESSAGE_BOX_INBOX); 202526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen MESSAGE_BOX_MAP.put(Mms.Sent.CONTENT_URI, Mms.MESSAGE_BOX_SENT); 203526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen MESSAGE_BOX_MAP.put(Mms.Draft.CONTENT_URI, Mms.MESSAGE_BOX_DRAFTS); 204526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen MESSAGE_BOX_MAP.put(Mms.Outbox.CONTENT_URI, Mms.MESSAGE_BOX_OUTBOX); 205526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 206526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen CHARSET_COLUMN_INDEX_MAP = new HashMap<Integer, Integer>(); 207526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen CHARSET_COLUMN_INDEX_MAP.put(PduHeaders.SUBJECT, PDU_COLUMN_SUBJECT_CHARSET); 208526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen CHARSET_COLUMN_INDEX_MAP.put(PduHeaders.RETRIEVE_TEXT, PDU_COLUMN_RETRIEVE_TEXT_CHARSET); 209526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 210526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen CHARSET_COLUMN_NAME_MAP = new HashMap<Integer, String>(); 211526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen CHARSET_COLUMN_NAME_MAP.put(PduHeaders.SUBJECT, Mms.SUBJECT_CHARSET); 212526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen CHARSET_COLUMN_NAME_MAP.put(PduHeaders.RETRIEVE_TEXT, Mms.RETRIEVE_TEXT_CHARSET); 213526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 214526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Encoded string field code -> column index/name map. 215526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen ENCODED_STRING_COLUMN_INDEX_MAP = new HashMap<Integer, Integer>(); 216526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen ENCODED_STRING_COLUMN_INDEX_MAP.put(PduHeaders.RETRIEVE_TEXT, PDU_COLUMN_RETRIEVE_TEXT); 217526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen ENCODED_STRING_COLUMN_INDEX_MAP.put(PduHeaders.SUBJECT, PDU_COLUMN_SUBJECT); 218526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 219526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen ENCODED_STRING_COLUMN_NAME_MAP = new HashMap<Integer, String>(); 220526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen ENCODED_STRING_COLUMN_NAME_MAP.put(PduHeaders.RETRIEVE_TEXT, Mms.RETRIEVE_TEXT); 221526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen ENCODED_STRING_COLUMN_NAME_MAP.put(PduHeaders.SUBJECT, Mms.SUBJECT); 222526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 223526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Text string field code -> column index/name map. 224526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen TEXT_STRING_COLUMN_INDEX_MAP = new HashMap<Integer, Integer>(); 225526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.CONTENT_LOCATION, PDU_COLUMN_CONTENT_LOCATION); 226526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.CONTENT_TYPE, PDU_COLUMN_CONTENT_TYPE); 227526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.MESSAGE_CLASS, PDU_COLUMN_MESSAGE_CLASS); 228526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.MESSAGE_ID, PDU_COLUMN_MESSAGE_ID); 229526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.RESPONSE_TEXT, PDU_COLUMN_RESPONSE_TEXT); 230526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen TEXT_STRING_COLUMN_INDEX_MAP.put(PduHeaders.TRANSACTION_ID, PDU_COLUMN_TRANSACTION_ID); 231526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 232526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen TEXT_STRING_COLUMN_NAME_MAP = new HashMap<Integer, String>(); 233526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.CONTENT_LOCATION, Mms.CONTENT_LOCATION); 234526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.CONTENT_TYPE, Mms.CONTENT_TYPE); 235526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.MESSAGE_CLASS, Mms.MESSAGE_CLASS); 236526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.MESSAGE_ID, Mms.MESSAGE_ID); 237526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.RESPONSE_TEXT, Mms.RESPONSE_TEXT); 238526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen TEXT_STRING_COLUMN_NAME_MAP.put(PduHeaders.TRANSACTION_ID, Mms.TRANSACTION_ID); 239526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 240526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Octet field code -> column index/name map. 241526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen OCTET_COLUMN_INDEX_MAP = new HashMap<Integer, Integer>(); 242526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen OCTET_COLUMN_INDEX_MAP.put(PduHeaders.CONTENT_CLASS, PDU_COLUMN_CONTENT_CLASS); 243526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen OCTET_COLUMN_INDEX_MAP.put(PduHeaders.DELIVERY_REPORT, PDU_COLUMN_DELIVERY_REPORT); 244526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen OCTET_COLUMN_INDEX_MAP.put(PduHeaders.MESSAGE_TYPE, PDU_COLUMN_MESSAGE_TYPE); 245526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen OCTET_COLUMN_INDEX_MAP.put(PduHeaders.MMS_VERSION, PDU_COLUMN_MMS_VERSION); 246526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen OCTET_COLUMN_INDEX_MAP.put(PduHeaders.PRIORITY, PDU_COLUMN_PRIORITY); 247526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen OCTET_COLUMN_INDEX_MAP.put(PduHeaders.READ_REPORT, PDU_COLUMN_READ_REPORT); 248526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen OCTET_COLUMN_INDEX_MAP.put(PduHeaders.READ_STATUS, PDU_COLUMN_READ_STATUS); 249526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen OCTET_COLUMN_INDEX_MAP.put(PduHeaders.REPORT_ALLOWED, PDU_COLUMN_REPORT_ALLOWED); 250526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen OCTET_COLUMN_INDEX_MAP.put(PduHeaders.RETRIEVE_STATUS, PDU_COLUMN_RETRIEVE_STATUS); 251526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen OCTET_COLUMN_INDEX_MAP.put(PduHeaders.STATUS, PDU_COLUMN_STATUS); 252526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 253526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen OCTET_COLUMN_NAME_MAP = new HashMap<Integer, String>(); 254526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen OCTET_COLUMN_NAME_MAP.put(PduHeaders.CONTENT_CLASS, Mms.CONTENT_CLASS); 255526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen OCTET_COLUMN_NAME_MAP.put(PduHeaders.DELIVERY_REPORT, Mms.DELIVERY_REPORT); 256526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen OCTET_COLUMN_NAME_MAP.put(PduHeaders.MESSAGE_TYPE, Mms.MESSAGE_TYPE); 257526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen OCTET_COLUMN_NAME_MAP.put(PduHeaders.MMS_VERSION, Mms.MMS_VERSION); 258526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen OCTET_COLUMN_NAME_MAP.put(PduHeaders.PRIORITY, Mms.PRIORITY); 259526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen OCTET_COLUMN_NAME_MAP.put(PduHeaders.READ_REPORT, Mms.READ_REPORT); 260526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen OCTET_COLUMN_NAME_MAP.put(PduHeaders.READ_STATUS, Mms.READ_STATUS); 261526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen OCTET_COLUMN_NAME_MAP.put(PduHeaders.REPORT_ALLOWED, Mms.REPORT_ALLOWED); 262526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen OCTET_COLUMN_NAME_MAP.put(PduHeaders.RETRIEVE_STATUS, Mms.RETRIEVE_STATUS); 263526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen OCTET_COLUMN_NAME_MAP.put(PduHeaders.STATUS, Mms.STATUS); 264526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 265526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Long field code -> column index/name map. 266526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen LONG_COLUMN_INDEX_MAP = new HashMap<Integer, Integer>(); 267526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen LONG_COLUMN_INDEX_MAP.put(PduHeaders.DATE, PDU_COLUMN_DATE); 268526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen LONG_COLUMN_INDEX_MAP.put(PduHeaders.DELIVERY_TIME, PDU_COLUMN_DELIVERY_TIME); 269526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen LONG_COLUMN_INDEX_MAP.put(PduHeaders.EXPIRY, PDU_COLUMN_EXPIRY); 270526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen LONG_COLUMN_INDEX_MAP.put(PduHeaders.MESSAGE_SIZE, PDU_COLUMN_MESSAGE_SIZE); 271526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 272526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen LONG_COLUMN_NAME_MAP = new HashMap<Integer, String>(); 273526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen LONG_COLUMN_NAME_MAP.put(PduHeaders.DATE, Mms.DATE); 274526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen LONG_COLUMN_NAME_MAP.put(PduHeaders.DELIVERY_TIME, Mms.DELIVERY_TIME); 275526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen LONG_COLUMN_NAME_MAP.put(PduHeaders.EXPIRY, Mms.EXPIRY); 276526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen LONG_COLUMN_NAME_MAP.put(PduHeaders.MESSAGE_SIZE, Mms.MESSAGE_SIZE); 277526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 278526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PDU_CACHE_INSTANCE = PduCache.getInstance(); 279526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 280526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 281526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private final Context mContext; 282526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private final ContentResolver mContentResolver; 283526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private final DrmManagerClient mDrmManagerClient; 284526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private final TelephonyManager mTelephonyManager; 285526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 286526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private PduPersister(Context context) { 287526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen mContext = context; 288526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen mContentResolver = context.getContentResolver(); 289526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen mDrmManagerClient = new DrmManagerClient(context); 290526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen mTelephonyManager = (TelephonyManager)context 291526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen .getSystemService(Context.TELEPHONY_SERVICE); 292526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 293526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 294526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** Get(or create if not exist) an instance of PduPersister */ 295526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen public static PduPersister getPduPersister(Context context) { 296526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if ((sPersister == null)) { 297526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen sPersister = new PduPersister(context); 298526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else if (!context.equals(sPersister.mContext)) { 299526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen sPersister.release(); 300526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen sPersister = new PduPersister(context); 301526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 302526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 303526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return sPersister; 304526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 305526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 306526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private void setEncodedStringValueToHeaders( 307526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Cursor c, int columnIndex, 308526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduHeaders headers, int mapColumn) { 309526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String s = c.getString(columnIndex); 310526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if ((s != null) && (s.length() > 0)) { 311526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int charsetColumnIndex = CHARSET_COLUMN_INDEX_MAP.get(mapColumn); 312526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int charset = c.getInt(charsetColumnIndex); 313526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen EncodedStringValue value = new EncodedStringValue( 314526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen charset, getBytes(s)); 315526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen headers.setEncodedStringValue(value, mapColumn); 316526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 317526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 318526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 319526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private void setTextStringToHeaders( 320526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Cursor c, int columnIndex, 321526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduHeaders headers, int mapColumn) { 322526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String s = c.getString(columnIndex); 323526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (s != null) { 324526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen headers.setTextString(getBytes(s), mapColumn); 325526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 326526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 327526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 328526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private void setOctetToHeaders( 329526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Cursor c, int columnIndex, 330526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduHeaders headers, int mapColumn) throws InvalidHeaderValueException { 331526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (!c.isNull(columnIndex)) { 332526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int b = c.getInt(columnIndex); 333526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen headers.setOctet(b, mapColumn); 334526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 335526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 336526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 337526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private void setLongToHeaders( 338526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Cursor c, int columnIndex, 339526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduHeaders headers, int mapColumn) { 340526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (!c.isNull(columnIndex)) { 341526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long l = c.getLong(columnIndex); 342526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen headers.setLongInteger(l, mapColumn); 343526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 344526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 345526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 346526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private Integer getIntegerFromPartColumn(Cursor c, int columnIndex) { 347526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (!c.isNull(columnIndex)) { 348526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return c.getInt(columnIndex); 349526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 350526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 351526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 352526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 353526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private byte[] getByteArrayFromPartColumn(Cursor c, int columnIndex) { 354526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (!c.isNull(columnIndex)) { 355526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return getBytes(c.getString(columnIndex)); 356526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 357526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 358526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 359526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 360526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private PduPart[] loadParts(long msgId) throws MmsException { 361526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Cursor c = SqliteWrapper.query(mContext, mContentResolver, 362526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Uri.parse("content://mms/" + msgId + "/part"), 363526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PART_PROJECTION, null, null, null); 364526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 365526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduPart[] parts = null; 366526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 367526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 368526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if ((c == null) || (c.getCount() == 0)) { 369526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 370526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(TAG, "loadParts(" + msgId + "): no part to load."); 371526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 372526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return null; 373526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 374526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 375526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int partCount = c.getCount(); 376526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int partIdx = 0; 377526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen parts = new PduPart[partCount]; 378526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen while (c.moveToNext()) { 379526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduPart part = new PduPart(); 380526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Integer charset = getIntegerFromPartColumn( 381526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen c, PART_COLUMN_CHARSET); 382526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (charset != null) { 383526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen part.setCharset(charset); 384526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 385526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 386526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] contentDisposition = getByteArrayFromPartColumn( 387526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen c, PART_COLUMN_CONTENT_DISPOSITION); 388526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (contentDisposition != null) { 389526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen part.setContentDisposition(contentDisposition); 390526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 391526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 392526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] contentId = getByteArrayFromPartColumn( 393526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen c, PART_COLUMN_CONTENT_ID); 394526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (contentId != null) { 395526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen part.setContentId(contentId); 396526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 397526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 398526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] contentLocation = getByteArrayFromPartColumn( 399526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen c, PART_COLUMN_CONTENT_LOCATION); 400526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (contentLocation != null) { 401526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen part.setContentLocation(contentLocation); 402526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 403526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 404526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] contentType = getByteArrayFromPartColumn( 405526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen c, PART_COLUMN_CONTENT_TYPE); 406526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (contentType != null) { 407526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen part.setContentType(contentType); 408526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 409526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new MmsException("Content-Type must be set."); 410526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 411526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 412526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] fileName = getByteArrayFromPartColumn( 413526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen c, PART_COLUMN_FILENAME); 414526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (fileName != null) { 415526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen part.setFilename(fileName); 416526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 417526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 418526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] name = getByteArrayFromPartColumn( 419526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen c, PART_COLUMN_NAME); 420526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (name != null) { 421526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen part.setName(name); 422526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 423526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 424526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Construct a Uri for this part. 425526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long partId = c.getLong(PART_COLUMN_ID); 426526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Uri partURI = Uri.parse("content://mms/part/" + partId); 427526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen part.setDataUri(partURI); 428526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 429526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // For images/audio/video, we won't keep their data in Part 430526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // because their renderer accept Uri as source. 431526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String type = toIsoString(contentType); 432526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (!ContentType.isImageType(type) 433526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen && !ContentType.isAudioType(type) 434526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen && !ContentType.isVideoType(type)) { 435526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen ByteArrayOutputStream baos = new ByteArrayOutputStream(); 436526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen InputStream is = null; 437526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 438526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Store simple string values directly in the database instead of an 439526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // external file. This makes the text searchable and retrieval slightly 440526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // faster. 441526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (ContentType.TEXT_PLAIN.equals(type) || ContentType.APP_SMIL.equals(type) 442526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen || ContentType.TEXT_HTML.equals(type)) { 443526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String text = c.getString(PART_COLUMN_TEXT); 444526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte [] blob = new EncodedStringValue(text != null ? text : "") 445526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen .getTextString(); 446526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen baos.write(blob, 0, blob.length); 447526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 448526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 449526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 450526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen is = mContentResolver.openInputStream(partURI); 451526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 452526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] buffer = new byte[256]; 453526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int len = is.read(buffer); 454526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen while (len >= 0) { 455526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen baos.write(buffer, 0, len); 456526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen len = is.read(buffer); 457526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 458526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (IOException e) { 459526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.e(TAG, "Failed to load part data", e); 460526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen c.close(); 461526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new MmsException(e); 462526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } finally { 463526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (is != null) { 464526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 465526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen is.close(); 466526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (IOException e) { 467526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.e(TAG, "Failed to close stream", e); 468526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } // Ignore 469526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 470526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 471526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 472526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen part.setData(baos.toByteArray()); 473526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 474526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen parts[partIdx++] = part; 475526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 476526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } finally { 477526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (c != null) { 478526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen c.close(); 479526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 480526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 481526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 482526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return parts; 483526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 484526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 485526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private void loadAddress(long msgId, PduHeaders headers) { 486526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Cursor c = SqliteWrapper.query(mContext, mContentResolver, 487526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Uri.parse("content://mms/" + msgId + "/addr"), 488526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen new String[] { Addr.ADDRESS, Addr.CHARSET, Addr.TYPE }, 489526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen null, null, null); 490526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 491526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (c != null) { 492526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 493526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen while (c.moveToNext()) { 494526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String addr = c.getString(0); 495526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (!TextUtils.isEmpty(addr)) { 496526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int addrType = c.getInt(2); 497526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen switch (addrType) { 498526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.FROM: 499526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen headers.setEncodedStringValue( 500526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen new EncodedStringValue(c.getInt(1), getBytes(addr)), 501526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen addrType); 502526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 503526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.TO: 504526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.CC: 505526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.BCC: 506526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen headers.appendEncodedStringValue( 507526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen new EncodedStringValue(c.getInt(1), getBytes(addr)), 508526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen addrType); 509526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 510526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen default: 511526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.e(TAG, "Unknown address type: " + addrType); 512526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 513526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 514526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 515526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 516526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } finally { 517526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen c.close(); 518526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 519526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 520526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 521526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 522526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 523526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Load a PDU from storage by given Uri. 524526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 525526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param uri The Uri of the PDU to be loaded. 526526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @return A generic PDU object, it may be cast to dedicated PDU. 527526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @throws MmsException Failed to load some fields of a PDU. 528526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 529526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen public GenericPdu load(Uri uri) throws MmsException { 530526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen GenericPdu pdu = null; 531526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduCacheEntry cacheEntry = null; 532526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int msgBox = 0; 533526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long threadId = -1; 534526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 535526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen synchronized(PDU_CACHE_INSTANCE) { 536526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (PDU_CACHE_INSTANCE.isUpdating(uri)) { 537526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 538526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(TAG, "load: " + uri + " blocked by isUpdating()"); 539526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 540526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 541526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PDU_CACHE_INSTANCE.wait(); 542526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (InterruptedException e) { 543526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.e(TAG, "load: ", e); 544526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 545526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen cacheEntry = PDU_CACHE_INSTANCE.get(uri); 546526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (cacheEntry != null) { 547526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return cacheEntry.getPdu(); 548526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 549526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 550526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Tell the cache to indicate to other callers that this item 551526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // is currently being updated. 552526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PDU_CACHE_INSTANCE.setUpdating(uri, true); 553526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 554526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 555526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Cursor c = SqliteWrapper.query(mContext, mContentResolver, uri, 556526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PDU_PROJECTION, null, null, null); 557526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduHeaders headers = new PduHeaders(); 558526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Set<Entry<Integer, Integer>> set; 559526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long msgId = ContentUris.parseId(uri); 560526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 561526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 562526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if ((c == null) || (c.getCount() != 1) || !c.moveToFirst()) { 563526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new MmsException("Bad uri: " + uri); 564526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 565526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 566526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen msgBox = c.getInt(PDU_COLUMN_MESSAGE_BOX); 567526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen threadId = c.getLong(PDU_COLUMN_THREAD_ID); 568526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 569526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen set = ENCODED_STRING_COLUMN_INDEX_MAP.entrySet(); 570526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen for (Entry<Integer, Integer> e : set) { 571526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen setEncodedStringValueToHeaders( 572526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen c, e.getValue(), headers, e.getKey()); 573526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 574526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 575526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen set = TEXT_STRING_COLUMN_INDEX_MAP.entrySet(); 576526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen for (Entry<Integer, Integer> e : set) { 577526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen setTextStringToHeaders( 578526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen c, e.getValue(), headers, e.getKey()); 579526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 580526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 581526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen set = OCTET_COLUMN_INDEX_MAP.entrySet(); 582526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen for (Entry<Integer, Integer> e : set) { 583526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen setOctetToHeaders( 584526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen c, e.getValue(), headers, e.getKey()); 585526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 586526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 587526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen set = LONG_COLUMN_INDEX_MAP.entrySet(); 588526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen for (Entry<Integer, Integer> e : set) { 589526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen setLongToHeaders( 590526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen c, e.getValue(), headers, e.getKey()); 591526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 592526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } finally { 593526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (c != null) { 594526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen c.close(); 595526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 596526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 597526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 598526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Check whether 'msgId' has been assigned a valid value. 599526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (msgId == -1L) { 600526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new MmsException("Error! ID of the message: -1."); 601526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 602526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 603526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Load address information of the MM. 604526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen loadAddress(msgId, headers); 605526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 606526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int msgType = headers.getOctet(PduHeaders.MESSAGE_TYPE); 607526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduBody body = new PduBody(); 608526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 609526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // For PDU which type is M_retrieve.conf or Send.req, we should 610526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // load multiparts and put them into the body of the PDU. 611526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if ((msgType == PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF) 612526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen || (msgType == PduHeaders.MESSAGE_TYPE_SEND_REQ)) { 613526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduPart[] parts = loadParts(msgId); 614526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (parts != null) { 615526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int partsNum = parts.length; 616526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen for (int i = 0; i < partsNum; i++) { 617526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen body.addPart(parts[i]); 618526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 619526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 620526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 621526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 622526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen switch (msgType) { 623526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND: 624526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pdu = new NotificationInd(headers); 625526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 626526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_DELIVERY_IND: 627526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pdu = new DeliveryInd(headers); 628526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 629526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_READ_ORIG_IND: 630526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pdu = new ReadOrigInd(headers); 631526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 632526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF: 633526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pdu = new RetrieveConf(headers, body); 634526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 635526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_SEND_REQ: 636526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pdu = new SendReq(headers, body); 637526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 638526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_ACKNOWLEDGE_IND: 639526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pdu = new AcknowledgeInd(headers); 640526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 641526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_NOTIFYRESP_IND: 642526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pdu = new NotifyRespInd(headers); 643526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 644526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_READ_REC_IND: 645526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen pdu = new ReadRecInd(headers); 646526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 647526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_SEND_CONF: 648526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_FORWARD_REQ: 649526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_FORWARD_CONF: 650526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_MBOX_STORE_REQ: 651526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_MBOX_STORE_CONF: 652526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_REQ: 653526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_CONF: 654526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_REQ: 655526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_CONF: 656526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_REQ: 657526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_CONF: 658526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_MBOX_DESCR: 659526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_DELETE_REQ: 660526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_DELETE_CONF: 661526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_CANCEL_REQ: 662526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_CANCEL_CONF: 663526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new MmsException( 664526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen "Unsupported PDU type: " + Integer.toHexString(msgType)); 665526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 666526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen default: 667526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new MmsException( 668526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen "Unrecognized PDU type: " + Integer.toHexString(msgType)); 669526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 670526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } finally { 671526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen synchronized(PDU_CACHE_INSTANCE) { 672526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (pdu != null) { 673526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen assert(PDU_CACHE_INSTANCE.get(uri) == null); 674526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Update the cache entry with the real info 675526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen cacheEntry = new PduCacheEntry(pdu, msgBox, threadId); 676526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PDU_CACHE_INSTANCE.put(uri, cacheEntry); 677526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 678526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PDU_CACHE_INSTANCE.setUpdating(uri, false); 679526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PDU_CACHE_INSTANCE.notifyAll(); // tell anybody waiting on this entry to go ahead 680526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 681526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 682526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return pdu; 683526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 684526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 685526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private void persistAddress( 686526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long msgId, int type, EncodedStringValue[] array) { 687526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen ContentValues values = new ContentValues(3); 688526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 689526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen for (EncodedStringValue addr : array) { 690526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.clear(); // Clear all values first. 691526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Addr.ADDRESS, toIsoString(addr.getTextString())); 692526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Addr.CHARSET, addr.getCharacterSet()); 693526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Addr.TYPE, type); 694526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 695526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Uri uri = Uri.parse("content://mms/" + msgId + "/addr"); 696526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen SqliteWrapper.insert(mContext, mContentResolver, uri, values); 697526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 698526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 699526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 700526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private static String getPartContentType(PduPart part) { 701526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return part.getContentType() == null ? null : toIsoString(part.getContentType()); 702526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 703526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 704526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen public Uri persistPart(PduPart part, long msgId, HashMap<Uri, InputStream> preOpenedFiles) 705526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throws MmsException { 706526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Uri uri = Uri.parse("content://mms/" + msgId + "/part"); 707526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen ContentValues values = new ContentValues(8); 708526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 709526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int charset = part.getCharset(); 710526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (charset != 0 ) { 711526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Part.CHARSET, charset); 712526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 713526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 714526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String contentType = getPartContentType(part); 715526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (contentType != null) { 716526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // There is no "image/jpg" in Android (and it's an invalid mimetype). 717526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Change it to "image/jpeg" 718526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (ContentType.IMAGE_JPG.equals(contentType)) { 719526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen contentType = ContentType.IMAGE_JPEG; 720526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 721526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 722526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Part.CONTENT_TYPE, contentType); 723526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // To ensure the SMIL part is always the first part. 724526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (ContentType.APP_SMIL.equals(contentType)) { 725526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Part.SEQ, -1); 726526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 727526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 728526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new MmsException("MIME type of the part must be set."); 729526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 730526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 731526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (part.getFilename() != null) { 732526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String fileName = new String(part.getFilename()); 733526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Part.FILENAME, fileName); 734526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 735526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 736526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (part.getName() != null) { 737526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String name = new String(part.getName()); 738526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Part.NAME, name); 739526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 740526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 741526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Object value = null; 742526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (part.getContentDisposition() != null) { 743526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen value = toIsoString(part.getContentDisposition()); 744526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Part.CONTENT_DISPOSITION, (String) value); 745526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 746526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 747526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (part.getContentId() != null) { 748526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen value = toIsoString(part.getContentId()); 749526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Part.CONTENT_ID, (String) value); 750526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 751526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 752526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (part.getContentLocation() != null) { 753526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen value = toIsoString(part.getContentLocation()); 754526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Part.CONTENT_LOCATION, (String) value); 755526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 756526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 757526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Uri res = SqliteWrapper.insert(mContext, mContentResolver, uri, values); 758526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (res == null) { 759526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new MmsException("Failed to persist part, return null."); 760526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 761526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 762526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen persistData(part, res, contentType, preOpenedFiles); 763526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // After successfully store the data, we should update 764526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // the dataUri of the part. 765526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen part.setDataUri(res); 766526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 767526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return res; 768526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 769526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 770526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 771526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Save data of the part into storage. The source data may be given 772526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * by a byte[] or a Uri. If it's a byte[], directly save it 773526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * into storage, otherwise load source data from the dataUri and then 774526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * save it. If the data is an image, we may scale down it according 775526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * to user preference. 776526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 777526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param part The PDU part which contains data to be saved. 778526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param uri The URI of the part. 779526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param contentType The MIME type of the part. 780526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param preOpenedFiles if not null, a map of preopened InputStreams for the parts. 781526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @throws MmsException Cannot find source data or error occurred 782526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * while saving the data. 783526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 784526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private void persistData(PduPart part, Uri uri, 785526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String contentType, HashMap<Uri, InputStream> preOpenedFiles) 786526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throws MmsException { 787526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen OutputStream os = null; 788526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen InputStream is = null; 789526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen DrmConvertSession drmConvertSession = null; 790526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Uri dataUri = null; 791526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String path = null; 792526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 793526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 794526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] data = part.getData(); 795526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (ContentType.TEXT_PLAIN.equals(contentType) 796526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen || ContentType.APP_SMIL.equals(contentType) 797526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen || ContentType.TEXT_HTML.equals(contentType)) { 798526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen ContentValues cv = new ContentValues(); 799526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (data == null) { 800526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen data = new String("").getBytes(CharacterSets.DEFAULT_CHARSET_NAME); 801526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 802526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen cv.put(Telephony.Mms.Part.TEXT, new EncodedStringValue(data).getString()); 803526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (mContentResolver.update(uri, cv, null, null) != 1) { 804526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new MmsException("unable to update " + uri.toString()); 805526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 806526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 807526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen boolean isDrm = DownloadDrmHelper.isDrmConvertNeeded(contentType); 808526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (isDrm) { 809526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (uri != null) { 810526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 811526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen path = convertUriToPath(mContext, uri); 812526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 813526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(TAG, "drm uri: " + uri + " path: " + path); 814526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 815526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen File f = new File(path); 816526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long len = f.length(); 817526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 818526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(TAG, "drm path: " + path + " len: " + len); 819526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 820526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (len > 0) { 821526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // we're not going to re-persist and re-encrypt an already 822526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // converted drm file 823526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return; 824526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 825526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (Exception e) { 826526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.e(TAG, "Can't get file info for: " + part.getDataUri(), e); 827526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 828526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 829526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // We haven't converted the file yet, start the conversion 830526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen drmConvertSession = DrmConvertSession.open(mContext, contentType); 831526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (drmConvertSession == null) { 832526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new MmsException("Mimetype " + contentType + 833526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen " can not be converted."); 834526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 835526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 836526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // uri can look like: 837526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // content://mms/part/98 838526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen os = mContentResolver.openOutputStream(uri); 839526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (data == null) { 840526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen dataUri = part.getDataUri(); 841526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if ((dataUri == null) || (dataUri == uri)) { 842526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.w(TAG, "Can't find data for this part."); 843526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return; 844526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 845526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // dataUri can look like: 846526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // content://com.google.android.gallery3d.provider/picasa/item/5720646660183715586 847526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (preOpenedFiles != null && preOpenedFiles.containsKey(dataUri)) { 848526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen is = preOpenedFiles.get(dataUri); 849526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 850526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (is == null) { 851526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen is = mContentResolver.openInputStream(dataUri); 852526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 853526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 854526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 855526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(TAG, "Saving data to: " + uri); 856526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 857526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 858526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] buffer = new byte[8192]; 859526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen for (int len = 0; (len = is.read(buffer)) != -1; ) { 860526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (!isDrm) { 861526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen os.write(buffer, 0, len); 862526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 863526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] convertedData = drmConvertSession.convert(buffer, len); 864526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (convertedData != null) { 865526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen os.write(convertedData, 0, convertedData.length); 866526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 867526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new MmsException("Error converting drm data."); 868526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 869526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 870526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 871526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 872526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 873526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(TAG, "Saving data to: " + uri); 874526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 875526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (!isDrm) { 876526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen os.write(data); 877526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 878526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen dataUri = uri; 879526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] convertedData = drmConvertSession.convert(data, data.length); 880526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (convertedData != null) { 881526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen os.write(convertedData, 0, convertedData.length); 882526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 883526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new MmsException("Error converting drm data."); 884526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 885526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 886526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 887526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 888526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (FileNotFoundException e) { 889526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.e(TAG, "Failed to open Input/Output stream.", e); 890526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new MmsException(e); 891526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (IOException e) { 892526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.e(TAG, "Failed to read/write data.", e); 893526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new MmsException(e); 894526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } finally { 895526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (os != null) { 896526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 897526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen os.close(); 898526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (IOException e) { 899526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.e(TAG, "IOException while closing: " + os, e); 900526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } // Ignore 901526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 902526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (is != null) { 903526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 904526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen is.close(); 905526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (IOException e) { 906526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.e(TAG, "IOException while closing: " + is, e); 907526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } // Ignore 908526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 909526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (drmConvertSession != null) { 910526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen drmConvertSession.close(path); 911526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 912526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Reset the permissions on the encrypted part file so everyone has only read 913526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // permission. 914526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen File f = new File(path); 915526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen ContentValues values = new ContentValues(0); 916526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen SqliteWrapper.update(mContext, mContentResolver, 917526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Uri.parse("content://mms/resetFilePerm/" + f.getName()), 918526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values, null, null); 919526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 920526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 921526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 922526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 923526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 924526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * This method expects uri in the following format 925526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * content://media/<table_name>/<row_index> (or) 926526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * file://sdcard/test.mp4 927526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * http://test.com/test.mp4 928526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 929526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Here <table_name> shall be "video" or "audio" or "images" 930526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * <row_index> the index of the content in given table 931526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 932526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen static public String convertUriToPath(Context context, Uri uri) { 933526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String path = null; 934526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null != uri) { 935526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String scheme = uri.getScheme(); 936526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null == scheme || scheme.equals("") || 937526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen scheme.equals(ContentResolver.SCHEME_FILE)) { 938526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen path = uri.getPath(); 939526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 940526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else if (scheme.equals("http")) { 941526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen path = uri.toString(); 942526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 943526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else if (scheme.equals(ContentResolver.SCHEME_CONTENT)) { 944526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String[] projection = new String[] {MediaStore.MediaColumns.DATA}; 945526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Cursor cursor = null; 946526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 947526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen cursor = context.getContentResolver().query(uri, projection, null, 948526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen null, null); 949526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null == cursor || 0 == cursor.getCount() || !cursor.moveToFirst()) { 950526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new IllegalArgumentException("Given Uri could not be found" + 951526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen " in media store"); 952526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 953526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int pathIndex = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA); 954526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen path = cursor.getString(pathIndex); 955526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (SQLiteException e) { 956526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new IllegalArgumentException("Given Uri is not formatted in a way " + 957526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen "so that it can be found in media store."); 958526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } finally { 959526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (null != cursor) { 960526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen cursor.close(); 961526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 962526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 963526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 964526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new IllegalArgumentException("Given Uri scheme is not supported"); 965526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 966526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 967526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return path; 968526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 969526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 970526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private void updateAddress( 971526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long msgId, int type, EncodedStringValue[] array) { 972526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Delete old address information and then insert new ones. 973526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen SqliteWrapper.delete(mContext, mContentResolver, 974526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Uri.parse("content://mms/" + msgId + "/addr"), 975526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Addr.TYPE + "=" + type, null); 976526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 977526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen persistAddress(msgId, type, array); 978526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 979526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 980526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 981526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Update headers of a SendReq. 982526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 983526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param uri The PDU which need to be updated. 984526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param pdu New headers. 985526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @throws MmsException Bad URI or updating failed. 986526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 987526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen public void updateHeaders(Uri uri, SendReq sendReq) { 988526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen synchronized(PDU_CACHE_INSTANCE) { 989526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // If the cache item is getting updated, wait until it's done updating before 990526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // purging it. 991526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (PDU_CACHE_INSTANCE.isUpdating(uri)) { 992526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 993526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(TAG, "updateHeaders: " + uri + " blocked by isUpdating()"); 994526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 995526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 996526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PDU_CACHE_INSTANCE.wait(); 997526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (InterruptedException e) { 998526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.e(TAG, "updateHeaders: ", e); 999526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1000526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1001526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1002526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PDU_CACHE_INSTANCE.purge(uri); 1003526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1004526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen ContentValues values = new ContentValues(10); 1005526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] contentType = sendReq.getContentType(); 1006526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (contentType != null) { 1007526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Mms.CONTENT_TYPE, toIsoString(contentType)); 1008526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1009526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1010526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long date = sendReq.getDate(); 1011526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (date != -1) { 1012526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Mms.DATE, date); 1013526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1014526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1015526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int deliveryReport = sendReq.getDeliveryReport(); 1016526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (deliveryReport != 0) { 1017526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Mms.DELIVERY_REPORT, deliveryReport); 1018526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1019526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1020526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long expiry = sendReq.getExpiry(); 1021526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (expiry != -1) { 1022526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Mms.EXPIRY, expiry); 1023526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1024526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1025526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] msgClass = sendReq.getMessageClass(); 1026526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (msgClass != null) { 1027526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Mms.MESSAGE_CLASS, toIsoString(msgClass)); 1028526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1029526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1030526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int priority = sendReq.getPriority(); 1031526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (priority != 0) { 1032526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Mms.PRIORITY, priority); 1033526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1034526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1035526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int readReport = sendReq.getReadReport(); 1036526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (readReport != 0) { 1037526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Mms.READ_REPORT, readReport); 1038526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1039526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1040526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] transId = sendReq.getTransactionId(); 1041526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (transId != null) { 1042526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Mms.TRANSACTION_ID, toIsoString(transId)); 1043526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1044526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1045526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen EncodedStringValue subject = sendReq.getSubject(); 1046526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (subject != null) { 1047526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Mms.SUBJECT, toIsoString(subject.getTextString())); 1048526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Mms.SUBJECT_CHARSET, subject.getCharacterSet()); 1049526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 1050526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Mms.SUBJECT, ""); 1051526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1052526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1053526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long messageSize = sendReq.getMessageSize(); 1054526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (messageSize > 0) { 1055526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Mms.MESSAGE_SIZE, messageSize); 1056526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1057526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1058526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduHeaders headers = sendReq.getPduHeaders(); 1059526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen HashSet<String> recipients = new HashSet<String>(); 1060526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen for (int addrType : ADDRESS_FIELDS) { 1061526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen EncodedStringValue[] array = null; 1062526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (addrType == PduHeaders.FROM) { 1063526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen EncodedStringValue v = headers.getEncodedStringValue(addrType); 1064526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (v != null) { 1065526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen array = new EncodedStringValue[1]; 1066526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen array[0] = v; 1067526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1068526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 1069526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen array = headers.getEncodedStringValues(addrType); 1070526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1071526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1072526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (array != null) { 1073526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long msgId = ContentUris.parseId(uri); 1074526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen updateAddress(msgId, addrType, array); 1075526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (addrType == PduHeaders.TO) { 1076526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen for (EncodedStringValue v : array) { 1077526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (v != null) { 1078526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen recipients.add(v.getString()); 1079526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1080526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1081526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1082526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1083526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1084526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (!recipients.isEmpty()) { 1085526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long threadId = Threads.getOrCreateThreadId(mContext, recipients); 1086526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Mms.THREAD_ID, threadId); 1087526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1088526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1089526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen SqliteWrapper.update(mContext, mContentResolver, uri, values, null, null); 1090526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1091526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1092526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private void updatePart(Uri uri, PduPart part, HashMap<Uri, InputStream> preOpenedFiles) 1093526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throws MmsException { 1094526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen ContentValues values = new ContentValues(7); 1095526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1096526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int charset = part.getCharset(); 1097526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (charset != 0 ) { 1098526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Part.CHARSET, charset); 1099526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1100526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1101526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String contentType = null; 1102526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (part.getContentType() != null) { 1103526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen contentType = toIsoString(part.getContentType()); 1104526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Part.CONTENT_TYPE, contentType); 1105526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 1106526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new MmsException("MIME type of the part must be set."); 1107526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1108526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1109526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (part.getFilename() != null) { 1110526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String fileName = new String(part.getFilename()); 1111526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Part.FILENAME, fileName); 1112526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1113526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1114526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (part.getName() != null) { 1115526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String name = new String(part.getName()); 1116526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Part.NAME, name); 1117526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1118526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1119526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Object value = null; 1120526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (part.getContentDisposition() != null) { 1121526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen value = toIsoString(part.getContentDisposition()); 1122526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Part.CONTENT_DISPOSITION, (String) value); 1123526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1124526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1125526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (part.getContentId() != null) { 1126526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen value = toIsoString(part.getContentId()); 1127526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Part.CONTENT_ID, (String) value); 1128526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1129526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1130526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (part.getContentLocation() != null) { 1131526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen value = toIsoString(part.getContentLocation()); 1132526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Part.CONTENT_LOCATION, (String) value); 1133526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1134526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1135526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen SqliteWrapper.update(mContext, mContentResolver, uri, values, null, null); 1136526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1137526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Only update the data when: 1138526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // 1. New binary data supplied or 1139526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // 2. The Uri of the part is different from the current one. 1140526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if ((part.getData() != null) 1141526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen || (uri != part.getDataUri())) { 1142526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen persistData(part, uri, contentType, preOpenedFiles); 1143526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1144526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1145526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1146526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1147526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Update all parts of a PDU. 1148526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 1149526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param uri The PDU which need to be updated. 1150526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param body New message body of the PDU. 1151526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param preOpenedFiles if not null, a map of preopened InputStreams for the parts. 1152526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @throws MmsException Bad URI or updating failed. 1153526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1154526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen public void updateParts(Uri uri, PduBody body, HashMap<Uri, InputStream> preOpenedFiles) 1155526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throws MmsException { 1156526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 1157526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduCacheEntry cacheEntry; 1158526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen synchronized(PDU_CACHE_INSTANCE) { 1159526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (PDU_CACHE_INSTANCE.isUpdating(uri)) { 1160526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 1161526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(TAG, "updateParts: " + uri + " blocked by isUpdating()"); 1162526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1163526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 1164526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PDU_CACHE_INSTANCE.wait(); 1165526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (InterruptedException e) { 1166526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.e(TAG, "updateParts: ", e); 1167526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1168526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen cacheEntry = PDU_CACHE_INSTANCE.get(uri); 1169526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (cacheEntry != null) { 1170526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen ((MultimediaMessagePdu) cacheEntry.getPdu()).setBody(body); 1171526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1172526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1173526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Tell the cache to indicate to other callers that this item 1174526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // is currently being updated. 1175526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PDU_CACHE_INSTANCE.setUpdating(uri, true); 1176526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1177526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1178526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen ArrayList<PduPart> toBeCreated = new ArrayList<PduPart>(); 1179526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen HashMap<Uri, PduPart> toBeUpdated = new HashMap<Uri, PduPart>(); 1180526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1181526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int partsNum = body.getPartsNum(); 1182526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen StringBuilder filter = new StringBuilder().append('('); 1183526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen for (int i = 0; i < partsNum; i++) { 1184526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduPart part = body.getPart(i); 1185526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Uri partUri = part.getDataUri(); 1186526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if ((partUri == null) || !partUri.getAuthority().startsWith("mms")) { 1187526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen toBeCreated.add(part); 1188526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 1189526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen toBeUpdated.put(partUri, part); 1190526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1191526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Don't use 'i > 0' to determine whether we should append 1192526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // 'AND' since 'i = 0' may be skipped in another branch. 1193526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (filter.length() > 1) { 1194526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen filter.append(" AND "); 1195526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1196526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1197526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen filter.append(Part._ID); 1198526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen filter.append("!="); 1199526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen DatabaseUtils.appendEscapedSQLString(filter, partUri.getLastPathSegment()); 1200526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1201526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1202526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen filter.append(')'); 1203526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1204526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long msgId = ContentUris.parseId(uri); 1205526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1206526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Remove the parts which doesn't exist anymore. 1207526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen SqliteWrapper.delete(mContext, mContentResolver, 1208526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Uri.parse(Mms.CONTENT_URI + "/" + msgId + "/part"), 1209526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen filter.length() > 2 ? filter.toString() : null, null); 1210526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1211526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Create new parts which didn't exist before. 1212526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen for (PduPart part : toBeCreated) { 1213526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen persistPart(part, msgId, preOpenedFiles); 1214526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1215526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1216526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Update the modified parts. 1217526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen for (Map.Entry<Uri, PduPart> e : toBeUpdated.entrySet()) { 1218526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen updatePart(e.getKey(), e.getValue(), preOpenedFiles); 1219526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1220526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } finally { 1221526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen synchronized(PDU_CACHE_INSTANCE) { 1222526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PDU_CACHE_INSTANCE.setUpdating(uri, false); 1223526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PDU_CACHE_INSTANCE.notifyAll(); 1224526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1225526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1226526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1227526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1228526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1229526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Persist a PDU object to specific location in the storage. 1230526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 1231526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param pdu The PDU object to be stored. 1232526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param uri Where to store the given PDU object. 1233526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param createThreadId if true, this function may create a thread id for the recipients 1234526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param groupMmsEnabled if true, all of the recipients addressed in the PDU will be used 1235526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * to create the associated thread. When false, only the sender will be used in finding or 1236526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * creating the appropriate thread or conversation. 1237526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param preOpenedFiles if not null, a map of preopened InputStreams for the parts. 1238526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @return A Uri which can be used to access the stored PDU. 1239526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1240526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1241526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen public Uri persist(GenericPdu pdu, Uri uri, boolean createThreadId, boolean groupMmsEnabled, 1242526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen HashMap<Uri, InputStream> preOpenedFiles) 1243526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throws MmsException { 1244526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (uri == null) { 1245526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new MmsException("Uri may not be null."); 1246526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1247526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long msgId = -1; 1248526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 1249526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen msgId = ContentUris.parseId(uri); 1250526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (NumberFormatException e) { 1251526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // the uri ends with "inbox" or something else like that 1252526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1253526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen boolean existingUri = msgId != -1; 1254526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1255526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (!existingUri && MESSAGE_BOX_MAP.get(uri) == null) { 1256526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new MmsException( 1257526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen "Bad destination, must be one of " 1258526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen + "content://mms/inbox, content://mms/sent, " 1259526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen + "content://mms/drafts, content://mms/outbox, " 1260526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen + "content://mms/temp."); 1261526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1262526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen synchronized(PDU_CACHE_INSTANCE) { 1263526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // If the cache item is getting updated, wait until it's done updating before 1264526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // purging it. 1265526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (PDU_CACHE_INSTANCE.isUpdating(uri)) { 1266526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (LOCAL_LOGV) { 1267526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.v(TAG, "persist: " + uri + " blocked by isUpdating()"); 1268526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1269526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 1270526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PDU_CACHE_INSTANCE.wait(); 1271526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (InterruptedException e) { 1272526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.e(TAG, "persist1: ", e); 1273526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1274526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1275526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1276526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PDU_CACHE_INSTANCE.purge(uri); 1277526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1278526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduHeaders header = pdu.getPduHeaders(); 1279526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduBody body = null; 1280526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen ContentValues values = new ContentValues(); 1281526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Set<Entry<Integer, String>> set; 1282526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1283526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen set = ENCODED_STRING_COLUMN_NAME_MAP.entrySet(); 1284526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen for (Entry<Integer, String> e : set) { 1285526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int field = e.getKey(); 1286526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen EncodedStringValue encodedString = header.getEncodedStringValue(field); 1287526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (encodedString != null) { 1288526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String charsetColumn = CHARSET_COLUMN_NAME_MAP.get(field); 1289526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(e.getValue(), toIsoString(encodedString.getTextString())); 1290526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(charsetColumn, encodedString.getCharacterSet()); 1291526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1292526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1293526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1294526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen set = TEXT_STRING_COLUMN_NAME_MAP.entrySet(); 1295526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen for (Entry<Integer, String> e : set){ 1296526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen byte[] text = header.getTextString(e.getKey()); 1297526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (text != null) { 1298526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(e.getValue(), toIsoString(text)); 1299526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1300526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1301526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1302526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen set = OCTET_COLUMN_NAME_MAP.entrySet(); 1303526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen for (Entry<Integer, String> e : set){ 1304526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int b = header.getOctet(e.getKey()); 1305526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (b != 0) { 1306526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(e.getValue(), b); 1307526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1308526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1309526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1310526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen set = LONG_COLUMN_NAME_MAP.entrySet(); 1311526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen for (Entry<Integer, String> e : set){ 1312526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long l = header.getLongInteger(e.getKey()); 1313526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (l != -1L) { 1314526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(e.getValue(), l); 1315526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1316526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1317526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1318526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen HashMap<Integer, EncodedStringValue[]> addressMap = 1319526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen new HashMap<Integer, EncodedStringValue[]>(ADDRESS_FIELDS.length); 1320526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Save address information. 1321526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen for (int addrType : ADDRESS_FIELDS) { 1322526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen EncodedStringValue[] array = null; 1323526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (addrType == PduHeaders.FROM) { 1324526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen EncodedStringValue v = header.getEncodedStringValue(addrType); 1325526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (v != null) { 1326526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen array = new EncodedStringValue[1]; 1327526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen array[0] = v; 1328526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1329526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 1330526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen array = header.getEncodedStringValues(addrType); 1331526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1332526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen addressMap.put(addrType, array); 1333526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1334526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1335526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen HashSet<String> recipients = new HashSet<String>(); 1336526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int msgType = pdu.getMessageType(); 1337526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Here we only allocate thread ID for M-Notification.ind, 1338526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // M-Retrieve.conf and M-Send.req. 1339526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Some of other PDU types may be allocated a thread ID outside 1340526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // this scope. 1341526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if ((msgType == PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND) 1342526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen || (msgType == PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF) 1343526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen || (msgType == PduHeaders.MESSAGE_TYPE_SEND_REQ)) { 1344526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen switch (msgType) { 1345526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND: 1346526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF: 1347526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen loadRecipients(PduHeaders.FROM, recipients, addressMap, false); 1348526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1349526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // For received messages when group MMS is enabled, we want to associate this 1350526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // message with the thread composed of all the recipients -- all but our own 1351526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // number, that is. This includes the person who sent the 1352526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // message or the FROM field (above) in addition to the other people the message 1353526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // was addressed to or the TO field. Our own number is in that TO field and 1354526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // we have to ignore it in loadRecipients. 1355526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (groupMmsEnabled) { 1356526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen loadRecipients(PduHeaders.TO, recipients, addressMap, true); 1357089a13f65c9bac16543ec2270152649bb3c77127kschulz 1358526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Also load any numbers in the CC field to address group messaging 1359526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // compatibility issues with devices that place numbers in this field 1360526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // for group messages. 1361526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen loadRecipients(PduHeaders.CC, recipients, addressMap, true); 1362526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1363526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 1364526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen case PduHeaders.MESSAGE_TYPE_SEND_REQ: 1365526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen loadRecipients(PduHeaders.TO, recipients, addressMap, false); 1366526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen break; 1367526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1368526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long threadId = 0; 1369526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (createThreadId && !recipients.isEmpty()) { 1370526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Given all the recipients associated with this message, find (or create) the 1371526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // correct thread. 1372526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen threadId = Threads.getOrCreateThreadId(mContext, recipients); 1373526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1374526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Mms.THREAD_ID, threadId); 1375526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1376526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1377526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Save parts first to avoid inconsistent message is loaded 1378526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // while saving the parts. 1379526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long dummyId = System.currentTimeMillis(); // Dummy ID of the msg. 1380526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1381526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Figure out if this PDU is a text-only message 1382526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen boolean textOnly = true; 1383526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1384089a13f65c9bac16543ec2270152649bb3c77127kschulz // Sum up the total message size 1385089a13f65c9bac16543ec2270152649bb3c77127kschulz int messageSize = 0; 1386089a13f65c9bac16543ec2270152649bb3c77127kschulz 1387526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Get body if the PDU is a RetrieveConf or SendReq. 1388526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (pdu instanceof MultimediaMessagePdu) { 1389526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen body = ((MultimediaMessagePdu) pdu).getBody(); 1390526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Start saving parts if necessary. 1391526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (body != null) { 1392526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen int partsNum = body.getPartsNum(); 1393526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (partsNum > 2) { 1394526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // For a text-only message there will be two parts: 1-the SMIL, 2-the text. 1395526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Down a few lines below we're checking to make sure we've only got SMIL or 1396526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // text. We also have to check then we don't have more than two parts. 1397526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Otherwise, a slideshow with two text slides would be marked as textOnly. 1398526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen textOnly = false; 1399526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1400526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen for (int i = 0; i < partsNum; i++) { 1401526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PduPart part = body.getPart(i); 1402089a13f65c9bac16543ec2270152649bb3c77127kschulz messageSize += part.getDataLength(); 1403526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen persistPart(part, dummyId, preOpenedFiles); 1404526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1405526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // If we've got anything besides text/plain or SMIL part, then we've got 1406526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // an mms message with some other type of attachment. 1407526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String contentType = getPartContentType(part); 1408526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (contentType != null && !ContentType.APP_SMIL.equals(contentType) 1409526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen && !ContentType.TEXT_PLAIN.equals(contentType)) { 1410526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen textOnly = false; 1411526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1412526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1413526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1414526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1415526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Record whether this mms message is a simple plain text or not. This is a hint for the 1416526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // UI. 1417526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Mms.TEXT_ONLY, textOnly ? 1 : 0); 1418089a13f65c9bac16543ec2270152649bb3c77127kschulz // The message-size might already have been inserted when parsing the 1419089a13f65c9bac16543ec2270152649bb3c77127kschulz // PDU header. If not, then we insert the message size as well. 1420089a13f65c9bac16543ec2270152649bb3c77127kschulz if (values.getAsInteger(Mms.MESSAGE_SIZE) == null) { 1421089a13f65c9bac16543ec2270152649bb3c77127kschulz values.put(Mms.MESSAGE_SIZE, messageSize); 1422089a13f65c9bac16543ec2270152649bb3c77127kschulz } 1423526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1424526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Uri res = null; 1425526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (existingUri) { 1426526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen res = uri; 1427526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen SqliteWrapper.update(mContext, mContentResolver, res, values, null, null); 1428526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } else { 1429526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen res = SqliteWrapper.insert(mContext, mContentResolver, uri, values); 1430526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (res == null) { 1431526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new MmsException("persist() failed: return null."); 1432526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1433526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Get the real ID of the PDU and update all parts which were 1434526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // saved with the dummy ID. 1435526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen msgId = ContentUris.parseId(res); 1436526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1437526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1438526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values = new ContentValues(1); 1439526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Part.MSG_ID, msgId); 1440526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen SqliteWrapper.update(mContext, mContentResolver, 1441526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Uri.parse("content://mms/" + dummyId + "/part"), 1442526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values, null, null); 1443526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // We should return the longest URI of the persisted PDU, for 1444526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // example, if input URI is "content://mms/inbox" and the _ID of 1445526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // persisted PDU is '8', we should return "content://mms/inbox/8" 1446526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // instead of "content://mms/8". 1447526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // FIXME: Should the MmsProvider be responsible for this??? 1448526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (!existingUri) { 1449526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen res = Uri.parse(uri + "/" + msgId); 1450526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1451526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1452526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Save address information. 1453526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen for (int addrType : ADDRESS_FIELDS) { 1454526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen EncodedStringValue[] array = addressMap.get(addrType); 1455526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (array != null) { 1456526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen persistAddress(msgId, addrType, array); 1457526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1458526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1459526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1460526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return res; 1461526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1462526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1463526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1464526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * For a given address type, extract the recipients from the headers. 1465526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 1466526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param addressType can be PduHeaders.FROM, PduHeaders.TO or PduHeaders.CC 1467526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param recipients a HashSet that is loaded with the recipients from the FROM, TO or CC headers 1468526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param addressMap a HashMap of the addresses from the ADDRESS_FIELDS header 1469526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param excludeMyNumber if true, the number of this phone will be excluded from recipients 1470526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1471526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen private void loadRecipients(int addressType, HashSet<String> recipients, 1472526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen HashMap<Integer, EncodedStringValue[]> addressMap, boolean excludeMyNumber) { 1473526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen EncodedStringValue[] array = addressMap.get(addressType); 1474526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (array == null) { 1475526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return; 1476526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1477526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // If the TO recipients is only a single address, then we can skip loadRecipients when 1478526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // we're excluding our own number because we know that address is our own. 1479526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (excludeMyNumber && array.length == 1) { 1480526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return; 1481526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 14828c90b1263ad9ee3a29ec2af435779d095c5cacc7Tom Taylor final SubscriptionManager subscriptionManager = SubscriptionManager.from(mContext); 14838c90b1263ad9ee3a29ec2af435779d095c5cacc7Tom Taylor final Set<String> myPhoneNumbers = new HashSet<String>(); 14848c90b1263ad9ee3a29ec2af435779d095c5cacc7Tom Taylor if (excludeMyNumber) { 14858c90b1263ad9ee3a29ec2af435779d095c5cacc7Tom Taylor // Build a list of my phone numbers from the various sims. 14868c90b1263ad9ee3a29ec2af435779d095c5cacc7Tom Taylor for (int subid : subscriptionManager.getActiveSubscriptionIdList()) { 14878c90b1263ad9ee3a29ec2af435779d095c5cacc7Tom Taylor final String myNumber = mTelephonyManager.getLine1Number(subid); 14888c90b1263ad9ee3a29ec2af435779d095c5cacc7Tom Taylor if (myNumber != null) { 14898c90b1263ad9ee3a29ec2af435779d095c5cacc7Tom Taylor myPhoneNumbers.add(myNumber); 14908c90b1263ad9ee3a29ec2af435779d095c5cacc7Tom Taylor } 14918c90b1263ad9ee3a29ec2af435779d095c5cacc7Tom Taylor } 14928c90b1263ad9ee3a29ec2af435779d095c5cacc7Tom Taylor } 14938c90b1263ad9ee3a29ec2af435779d095c5cacc7Tom Taylor 1494526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen for (EncodedStringValue v : array) { 1495526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (v != null) { 14968c90b1263ad9ee3a29ec2af435779d095c5cacc7Tom Taylor final String number = v.getString(); 14978c90b1263ad9ee3a29ec2af435779d095c5cacc7Tom Taylor if (excludeMyNumber) { 14988c90b1263ad9ee3a29ec2af435779d095c5cacc7Tom Taylor for (final String myNumber : myPhoneNumbers) { 14998c90b1263ad9ee3a29ec2af435779d095c5cacc7Tom Taylor if (!PhoneNumberUtils.compare(number, myNumber) 15008c90b1263ad9ee3a29ec2af435779d095c5cacc7Tom Taylor && !recipients.contains(number)) { 15018c90b1263ad9ee3a29ec2af435779d095c5cacc7Tom Taylor // Only add numbers which aren't my own number. 15028c90b1263ad9ee3a29ec2af435779d095c5cacc7Tom Taylor recipients.add(number); 15038c90b1263ad9ee3a29ec2af435779d095c5cacc7Tom Taylor break; 15048c90b1263ad9ee3a29ec2af435779d095c5cacc7Tom Taylor } 15058c90b1263ad9ee3a29ec2af435779d095c5cacc7Tom Taylor } 15068c90b1263ad9ee3a29ec2af435779d095c5cacc7Tom Taylor } else if (!recipients.contains(number)){ 1507526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen recipients.add(number); 1508526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1509526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1510526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1511526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1512526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1513526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1514526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Move a PDU object from one location to another. 1515526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * 1516526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param from Specify the PDU object to be moved. 1517526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @param to The destination location, should be one of the following: 1518526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * "content://mms/inbox", "content://mms/sent", 1519526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * "content://mms/drafts", "content://mms/outbox", 1520526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * "content://mms/trash". 1521526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @return New Uri of the moved PDU. 1522526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * @throws MmsException Error occurred while moving the message. 1523526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1524526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen public Uri move(Uri from, Uri to) throws MmsException { 1525526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Check whether the 'msgId' has been assigned a valid value. 1526526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen long msgId = ContentUris.parseId(from); 1527526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (msgId == -1L) { 1528526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new MmsException("Error! ID of the message: -1."); 1529526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1530526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1531526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Get corresponding int value of destination box. 1532526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Integer msgBox = MESSAGE_BOX_MAP.get(to); 1533526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen if (msgBox == null) { 1534526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen throw new MmsException( 1535526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen "Bad destination, must be one of " 1536526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen + "content://mms/inbox, content://mms/sent, " 1537526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen + "content://mms/drafts, content://mms/outbox, " 1538526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen + "content://mms/temp."); 1539526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1540526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1541526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen ContentValues values = new ContentValues(1); 1542526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen values.put(Mms.MESSAGE_BOX, msgBox); 1543526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen SqliteWrapper.update(mContext, mContentResolver, from, values, null, null); 1544526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return ContentUris.withAppendedId(to, msgId); 1545526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1546526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1547526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1548526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Wrap a byte[] into a String. 1549526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1550526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen public static String toIsoString(byte[] bytes) { 1551526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 1552526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return new String(bytes, CharacterSets.MIMENAME_ISO_8859_1); 1553526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (UnsupportedEncodingException e) { 1554526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Impossible to reach here! 1555526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.e(TAG, "ISO_8859_1 must be supported!", e); 1556526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return ""; 1557526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1558526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1559526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1560526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1561526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Unpack a given String into a byte[]. 1562526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1563526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen public static byte[] getBytes(String data) { 1564526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen try { 1565526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return data.getBytes(CharacterSets.MIMENAME_ISO_8859_1); 1566526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } catch (UnsupportedEncodingException e) { 1567526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen // Impossible to reach here! 1568526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Log.e(TAG, "ISO_8859_1 must be supported!", e); 1569526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return new byte[0]; 1570526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1571526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1572526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1573526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1574526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Remove all objects in the temporary path. 1575526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1576526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen public void release() { 1577526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Uri uri = Uri.parse(TEMPORARY_DRM_OBJECT_URI); 1578526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen SqliteWrapper.delete(mContext, mContentResolver, uri, null, null); 1579526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1580526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1581526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen /** 1582526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen * Find all messages to be sent or downloaded before certain time. 1583526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen */ 1584526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen public Cursor getPendingMessages(long dueTime) { 1585526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen Uri.Builder uriBuilder = PendingMessages.CONTENT_URI.buildUpon(); 1586526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen uriBuilder.appendQueryParameter("protocol", "mms"); 1587526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1588526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String selection = PendingMessages.ERROR_TYPE + " < ?" 1589526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen + " AND " + PendingMessages.DUE_TIME + " <= ?"; 1590526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1591526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String[] selectionArgs = new String[] { 1592526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String.valueOf(MmsSms.ERR_TYPE_GENERIC_PERMANENT), 1593526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen String.valueOf(dueTime) 1594526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen }; 1595526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen 1596526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen return SqliteWrapper.query(mContext, mContentResolver, 1597526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen uriBuilder.build(), null, selection, selectionArgs, 1598526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen PendingMessages.DUE_TIME); 1599526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen } 1600526ecd1799a2fc467cfce114eae3578b42ccb786Ye Wen} 1601