17236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project/* 27236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 37236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * 47236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 57236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * you may not use this file except in compliance with the License. 67236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * You may obtain a copy of the License at 77236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * 87236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 97236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * 107236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 117236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 127236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * See the License for the specific language governing permissions and 147236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * limitations under the License. 157236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 167236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 177236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectpackage com.android.providers.telephony; 187236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 19f27792fb80c6f533a250ec75867c9f2351ff9f04Dianne Hackbornimport android.app.AppOpsManager; 207236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.content.ContentProvider; 217236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.content.ContentValues; 227236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.content.Context; 237236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.content.UriMatcher; 247236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.database.Cursor; 257236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.database.DatabaseUtils; 267236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.database.sqlite.SQLiteDatabase; 277236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.database.sqlite.SQLiteOpenHelper; 287236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.database.sqlite.SQLiteQueryBuilder; 297236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.net.Uri; 30e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wenimport android.os.Binder; 3143f9fb234aabe569b342af78bdaf85effbd85f10Amith Yamasaniimport android.os.UserHandle; 327236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.provider.BaseColumns; 3386b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wenimport android.provider.Telephony; 347236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.provider.Telephony.CanonicalAddressesColumns; 357236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.provider.Telephony.Mms; 367236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.provider.Telephony.MmsSms; 37e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wenimport android.provider.Telephony.MmsSms.PendingMessages; 387236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.provider.Telephony.Sms; 39e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wenimport android.provider.Telephony.Sms.Conversations; 407236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.provider.Telephony.Threads; 417236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.provider.Telephony.ThreadsColumns; 427236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.text.TextUtils; 437236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.util.Log; 447236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 45b1bae65bf18dc22762cf7b8210fdad836b3e4ee5Tom Taylorimport com.google.android.mms.pdu.PduHeaders; 467236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 4786b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wenimport java.io.FileDescriptor; 4886b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wenimport java.io.PrintWriter; 49e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wenimport java.util.Arrays; 50e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wenimport java.util.HashSet; 51e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wenimport java.util.List; 52e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wenimport java.util.Set; 53e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wen 547236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project/** 557236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * This class provides the ability to query the MMS and SMS databases 567236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * at the same time, mixing messages from both in a single thread 577236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * (A.K.A. conversation). 587236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * 597236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * A virtual column, MmsSms.TYPE_DISCRIMINATOR_COLUMN, may be 607236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * requested in the projection for a query. Its value is either "mms" 617236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * or "sms", depending on whether the message represented by the row 627236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * is an MMS message or an SMS message, respectively. 637236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * 647236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * This class also provides the ability to find out what addresses 657236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * participated in a particular thread. It doesn't support updates 667236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * for either of these. 677236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * 687236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * This class provides a way to allocate and retrieve thread IDs. 697236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * This is done atomically through a query. There is no insert URI 707236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * for this. 717236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * 727236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Finally, this class provides a way to delete or update all messages 737236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * in a thread. 747236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 757236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectpublic class MmsSmsProvider extends ContentProvider { 767236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final UriMatcher URI_MATCHER = 777236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project new UriMatcher(UriMatcher.NO_MATCH); 787236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String LOG_TAG = "MmsSmsProvider"; 79816e934a43bf705835bdb24503a85a14c4861991Tom Taylor private static final boolean DEBUG = false; 807236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 817236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String NO_DELETES_INSERTS_OR_UPDATES = 827236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project "MmsSmsProvider does not support deletes, inserts, or updates for this URI."; 83f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_CONVERSATIONS = 0; 84f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_CONVERSATIONS_MESSAGES = 1; 85f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_CONVERSATIONS_RECIPIENTS = 2; 86f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_MESSAGES_BY_PHONE = 3; 87f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_THREAD_ID = 4; 88f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_CANONICAL_ADDRESS = 5; 89f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_PENDING_MSG = 6; 90f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_COMPLETE_CONVERSATIONS = 7; 91f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_UNDELIVERED_MSG = 8; 92f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_CONVERSATIONS_SUBJECT = 9; 93f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_NOTIFICATIONS = 10; 94f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_OBSOLETE_THREADS = 11; 95f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_DRAFT = 12; 96f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_CANONICAL_ADDRESSES = 13; 97f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_SEARCH = 14; 988e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner private static final int URI_SEARCH_SUGGEST = 15; 998e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner private static final int URI_FIRST_LOCKED_MESSAGE_ALL = 16; 1008e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner private static final int URI_FIRST_LOCKED_MESSAGE_BY_THREAD_ID = 17; 1016a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner private static final int URI_MESSAGE_ID_TO_THREAD = 18; 1027236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1037236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 1047236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * the name of the table that is used to store the queue of 1057236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * messages(both MMS and SMS) to be sent/downloaded. 1067236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 1077236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project public static final String TABLE_PENDING_MSG = "pending_msgs"; 1087236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1091ecf192c60625c5227336430ee36705c13ae06e2Wei Huang /** 1101ecf192c60625c5227336430ee36705c13ae06e2Wei Huang * the name of the table that is used to store the canonical addresses for both SMS and MMS. 1111ecf192c60625c5227336430ee36705c13ae06e2Wei Huang */ 1121ecf192c60625c5227336430ee36705c13ae06e2Wei Huang private static final String TABLE_CANONICAL_ADDRESSES = "canonical_addresses"; 1131ecf192c60625c5227336430ee36705c13ae06e2Wei Huang 11415156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor /** 11515156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor * the name of the table that is used to store the conversation threads. 11615156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor */ 11715156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor static final String TABLE_THREADS = "threads"; 11815156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor 1197236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // These constants are used to construct union queries across the 1207236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // MMS and SMS base tables. 1217236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1227236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // These are the columns that appear in both the MMS ("pdu") and 1237236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // SMS ("sms") message tables. 1247236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String[] MMS_SMS_COLUMNS = 125cfb8bbdc3932473966d043fbd72b6c067933f2c1Ye Wen { BaseColumns._ID, Mms.DATE, Mms.DATE_SENT, Mms.READ, Mms.THREAD_ID, Mms.LOCKED, 12672b147363200ff3f0bc467f23579042bd800ff13Wink Saville Mms.SUBSCRIPTION_ID }; 1277236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1287236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // These are the columns that appear only in the MMS message 1297236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // table. 1307236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String[] MMS_ONLY_COLUMNS = { 1317236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Mms.CONTENT_CLASS, Mms.CONTENT_LOCATION, Mms.CONTENT_TYPE, 1327236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Mms.DELIVERY_REPORT, Mms.EXPIRY, Mms.MESSAGE_CLASS, Mms.MESSAGE_ID, 1337236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Mms.MESSAGE_SIZE, Mms.MESSAGE_TYPE, Mms.MESSAGE_BOX, Mms.PRIORITY, 1347236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Mms.READ_STATUS, Mms.RESPONSE_STATUS, Mms.RESPONSE_TEXT, 1357236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Mms.RETRIEVE_STATUS, Mms.RETRIEVE_TEXT_CHARSET, Mms.REPORT_ALLOWED, 1367236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Mms.READ_REPORT, Mms.STATUS, Mms.SUBJECT, Mms.SUBJECT_CHARSET, 137f88d1d6733158144e9e0c87f29b446068edf0507Tom Taylor Mms.TRANSACTION_ID, Mms.MMS_VERSION, Mms.TEXT_ONLY }; 1387236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1397236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // These are the columns that appear only in the SMS message 1407236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // table. 1417236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String[] SMS_ONLY_COLUMNS = 1427236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project { "address", "body", "person", "reply_path_present", 143ddf267c20a697f66b8238538fb6ad31507724692Tom Taylor "service_center", "status", "subject", "type", "error_code" }; 1447236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1457236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // These are all the columns that appear in the "threads" table. 1467236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String[] THREADS_COLUMNS = { 1477236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project BaseColumns._ID, 1487236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project ThreadsColumns.DATE, 1497236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project ThreadsColumns.RECIPIENT_IDS, 1507236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project ThreadsColumns.MESSAGE_COUNT 1517236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project }; 1527236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1531ecf192c60625c5227336430ee36705c13ae06e2Wei Huang private static final String[] CANONICAL_ADDRESSES_COLUMNS_1 = 1541ecf192c60625c5227336430ee36705c13ae06e2Wei Huang new String[] { CanonicalAddressesColumns.ADDRESS }; 1551ecf192c60625c5227336430ee36705c13ae06e2Wei Huang 1561ecf192c60625c5227336430ee36705c13ae06e2Wei Huang private static final String[] CANONICAL_ADDRESSES_COLUMNS_2 = 1571ecf192c60625c5227336430ee36705c13ae06e2Wei Huang new String[] { CanonicalAddressesColumns._ID, 1581ecf192c60625c5227336430ee36705c13ae06e2Wei Huang CanonicalAddressesColumns.ADDRESS }; 1591ecf192c60625c5227336430ee36705c13ae06e2Wei Huang 1607236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // These are all the columns that appear in the MMS and SMS 1617236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // message tables. 1627236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String[] UNION_COLUMNS = 1637236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project new String[MMS_SMS_COLUMNS.length 1647236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project + MMS_ONLY_COLUMNS.length 1657236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project + SMS_ONLY_COLUMNS.length]; 1667236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1677236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // These are all the columns that appear in the MMS table. 1687236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final Set<String> MMS_COLUMNS = new HashSet<String>(); 1697236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1707236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // These are all the columns that appear in the SMS table. 1717236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final Set<String> SMS_COLUMNS = new HashSet<String>(); 1727236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1737236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String VND_ANDROID_DIR_MMS_SMS = 1747236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project "vnd.android-dir/mms-sms"; 1757236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1767236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String[] ID_PROJECTION = { BaseColumns._ID }; 1777236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1787236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String[] EMPTY_STRING_ARRAY = new String[0]; 1797236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1803e1cba826743423642635cc7b03abe292470f4c4Tom Taylor private static final String[] SEARCH_STRING = new String[1]; 1813e1cba826743423642635cc7b03abe292470f4c4Tom Taylor private static final String SEARCH_QUERY = "SELECT snippet(words, '', ' ', '', 1, 1) as " + 1823e1cba826743423642635cc7b03abe292470f4c4Tom Taylor "snippet FROM words WHERE index_text MATCH ? ORDER BY snippet LIMIT 50;"; 1833e1cba826743423642635cc7b03abe292470f4c4Tom Taylor 1847236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String SMS_CONVERSATION_CONSTRAINT = "(" + 1857236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Sms.TYPE + " != " + Sms.MESSAGE_TYPE_DRAFT + ")"; 1867236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1877236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String MMS_CONVERSATION_CONSTRAINT = "(" + 1887236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Mms.MESSAGE_BOX + " != " + Mms.MESSAGE_BOX_DRAFTS + " AND (" + 1897236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Mms.MESSAGE_TYPE + " = " + PduHeaders.MESSAGE_TYPE_SEND_REQ + " OR " + 1907236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Mms.MESSAGE_TYPE + " = " + PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF + " OR " + 1917236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Mms.MESSAGE_TYPE + " = " + PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND + "))"; 1927236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 19372f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen private static String getTextSearchQuery(String smsTable, String pduTable) { 19472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen // Search on the words table but return the rows from the corresponding sms table 19572f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen final String smsQuery = "SELECT " 19672f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + smsTable + "._id AS _id," 19772f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "thread_id," 19872f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "address," 19972f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "body," 20072f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "date," 20172f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "date_sent," 20272f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "index_text," 20372f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "words._id " 20472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "FROM " + smsTable + ",words " 20572f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "WHERE (index_text MATCH ? " 20672f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "AND " + smsTable + "._id=words.source_id " 20772f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "AND words.table_to_use=1)"; 20872f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen 20972f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen // Search on the words table but return the rows from the corresponding parts table 21072f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen final String mmsQuery = "SELECT " 21172f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + pduTable + "._id," 21272f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "thread_id," 21372f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "addr.address," 21472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "part.text AS body," 21572f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + pduTable + ".date," 21672f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + pduTable + ".date_sent," 21772f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "index_text," 21872f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "words._id " 21972f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "FROM " + pduTable + ",part,addr,words " 22072f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "WHERE ((part.mid=" + pduTable + "._id) " 22172f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "AND (addr.msg_id=" + pduTable + "._id) " 22272f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "AND (addr.type=" + PduHeaders.TO + ") " 22372f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "AND (part.ct='text/plain') " 22472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "AND (index_text MATCH ?) " 22572f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "AND (part._id = words.source_id) " 22672f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "AND (words.table_to_use=2))"; 22772f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen 22872f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen // This code queries the sms and mms tables and returns a unified result set 22972f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen // of text matches. We query the sms table which is pretty simple. We also 23072f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen // query the pdu, part and addr table to get the mms result. Note we're 23172f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen // using a UNION so we have to have the same number of result columns from 23272f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen // both queries. 23372f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen return smsQuery + " UNION " + mmsQuery + " " 23472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "GROUP BY thread_id " 23572f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "ORDER BY thread_id ASC, date DESC"; 23672f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen } 23701c75ba95b875674a83128defc6b267e522db346Chen Mike 2387236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String AUTHORITY = "mms-sms"; 2397236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 2407236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project static { 2417236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI(AUTHORITY, "conversations", URI_CONVERSATIONS); 2427236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI(AUTHORITY, "complete-conversations", URI_COMPLETE_CONVERSATIONS); 2437236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 2447236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // In these patterns, "#" is the thread ID. 2457236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI( 2467236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project AUTHORITY, "conversations/#", URI_CONVERSATIONS_MESSAGES); 2477236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI( 2487236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project AUTHORITY, "conversations/#/recipients", 2497236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_CONVERSATIONS_RECIPIENTS); 2507236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 2517236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI( 2527236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project AUTHORITY, "conversations/#/subject", 2537236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_CONVERSATIONS_SUBJECT); 2547236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 2557236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // URI for deleting obsolete threads. 2567236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI(AUTHORITY, "conversations/obsolete", URI_OBSOLETE_THREADS); 2577236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 2587236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI( 2597236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project AUTHORITY, "messages/byphone/*", 2607236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MESSAGES_BY_PHONE); 2617236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 2627236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // In this pattern, two query parameter names are expected: 2637236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // "subject" and "recipient." Multiple "recipient" parameters 2647236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // may be present. 2657236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI(AUTHORITY, "threadID", URI_THREAD_ID); 2667236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 2677236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // Use this pattern to query the canonical address by given ID. 2687236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI(AUTHORITY, "canonical-address/#", URI_CANONICAL_ADDRESS); 2697236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 27037e4424493bb364eac8ae07c3d5fce52bebf735dFicus Kirkpatrick // Use this pattern to query all canonical addresses. 27137e4424493bb364eac8ae07c3d5fce52bebf735dFicus Kirkpatrick URI_MATCHER.addURI(AUTHORITY, "canonical-addresses", URI_CANONICAL_ADDRESSES); 272f0a9e90721310bed023a9ff1f176f1b5e05a14f7Mark Wagner 27366d373c4797c53207e8f1ea97f3dc5541f390152Mark Wagner URI_MATCHER.addURI(AUTHORITY, "search", URI_SEARCH); 2748e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner URI_MATCHER.addURI(AUTHORITY, "searchSuggest", URI_SEARCH_SUGGEST); 27537e4424493bb364eac8ae07c3d5fce52bebf735dFicus Kirkpatrick 2767236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // In this pattern, two query parameters may be supplied: 2777236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // "protocol" and "message." For example: 2787236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // content://mms-sms/pending? 2797236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // -> Return all pending messages; 2807236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // content://mms-sms/pending?protocol=sms 2817236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // -> Only return pending SMs; 2827236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // content://mms-sms/pending?protocol=mms&message=1 2837236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // -> Return the the pending MM which ID equals '1'. 2847236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // 2857236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI(AUTHORITY, "pending", URI_PENDING_MSG); 2867236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 2877236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // Use this pattern to get a list of undelivered messages. 2887236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI(AUTHORITY, "undelivered", URI_UNDELIVERED_MSG); 2897236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 2907236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // Use this pattern to see what delivery status reports (for 2917236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // both MMS and SMS) have not been delivered to the user. 2927236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI(AUTHORITY, "notifications", URI_NOTIFICATIONS); 2937236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 2947236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI(AUTHORITY, "draft", URI_DRAFT); 295f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor 296f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor URI_MATCHER.addURI(AUTHORITY, "locked", URI_FIRST_LOCKED_MESSAGE_ALL); 297f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor 298f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor URI_MATCHER.addURI(AUTHORITY, "locked/#", URI_FIRST_LOCKED_MESSAGE_BY_THREAD_ID); 299f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor 3006a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner URI_MATCHER.addURI(AUTHORITY, "messageIdToThread", URI_MESSAGE_ID_TO_THREAD); 3017236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project initializeColumnSets(); 3027236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 3037236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 3047236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private SQLiteOpenHelper mOpenHelper; 3057236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 306845a9163dffcbd1073930b8b334df27728418201Daisuke Miyakawa private boolean mUseStrictPhoneNumberComparation; 307845a9163dffcbd1073930b8b334df27728418201Daisuke Miyakawa 3087236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project @Override 3097236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project public boolean onCreate() { 310b2ce2d37bc6efc0c37d8cee925d3ad65a01ea4bfYe Wen setAppOps(AppOpsManager.OP_READ_SMS, AppOpsManager.OP_WRITE_SMS); 3115a3194d943854ec3c2ec5df18a95a5b04ab5efa1Ji Yang mOpenHelper = MmsSmsDatabaseHelper.getInstanceForCe(getContext()); 312845a9163dffcbd1073930b8b334df27728418201Daisuke Miyakawa mUseStrictPhoneNumberComparation = 313845a9163dffcbd1073930b8b334df27728418201Daisuke Miyakawa getContext().getResources().getBoolean( 314845a9163dffcbd1073930b8b334df27728418201Daisuke Miyakawa com.android.internal.R.bool.config_use_strict_phone_number_comparation); 3152d3a779b41d5a553c8615a906ee97da29907313eRoman Sorokin TelephonyBackupAgent.DeferredSmsMmsRestoreService.startIfFilesExist(getContext()); 3167236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return true; 3177236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 3187236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 3197236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project @Override 3207236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project public Cursor query(Uri uri, String[] projection, 3217236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String selection, String[] selectionArgs, String sortOrder) { 32272f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen // First check if restricted views of the "sms" and "pdu" tables should be used based on the 32372f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen // caller's identity. Only system, phone or the default sms app can have full access 32472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen // of sms/mms data. For other apps, we present a restricted view which only contains sent 32572f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen // or received messages, without wap pushes. 32672f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen final boolean accessRestricted = ProviderUtil.isAccessRestricted( 32772f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen getContext(), getCallingPackage(), Binder.getCallingUid()); 32872f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen final String pduTable = MmsProvider.getPduTable(accessRestricted); 32972f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen final String smsTable = SmsProvider.getSmsTable(accessRestricted); 33072f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen 3317236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 3327236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Cursor cursor = null; 33372f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen final int match = URI_MATCHER.match(uri); 33472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen switch (match) { 3357236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_COMPLETE_CONVERSATIONS: 33672f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen cursor = getCompleteConversations(projection, selection, sortOrder, smsTable, 33772f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen pduTable); 3387236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 3397236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_CONVERSATIONS: 3407236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String simple = uri.getQueryParameter("simple"); 3417236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if ((simple != null) && simple.equals("true")) { 3427236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String threadType = uri.getQueryParameter("thread_type"); 3437236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (!TextUtils.isEmpty(threadType)) { 3447236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selection = concatSelections( 3457236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selection, Threads.TYPE + "=" + threadType); 3467236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 3477236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project cursor = getSimpleConversations( 3487236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project projection, selection, selectionArgs, sortOrder); 3497236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } else { 3507236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project cursor = getConversations( 35172f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen projection, selection, sortOrder, smsTable, pduTable); 3527236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 3537236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 3547236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_CONVERSATIONS_MESSAGES: 355f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor cursor = getConversationMessages(uri.getPathSegments().get(1), projection, 35672f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen selection, sortOrder, smsTable, pduTable); 3577236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 3587236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_CONVERSATIONS_RECIPIENTS: 3597236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project cursor = getConversationById( 3607236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project uri.getPathSegments().get(1), projection, selection, 3617236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selectionArgs, sortOrder); 3627236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 3637236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_CONVERSATIONS_SUBJECT: 3647236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project cursor = getConversationById( 3657236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project uri.getPathSegments().get(1), projection, selection, 3667236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selectionArgs, sortOrder); 3677236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 3687236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_MESSAGES_BY_PHONE: 3697236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project cursor = getMessagesByPhoneNumber( 37072f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen uri.getPathSegments().get(2), projection, selection, sortOrder, smsTable, 37172f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen pduTable); 3727236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 3737236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_THREAD_ID: 3747236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project List<String> recipients = uri.getQueryParameters("recipient"); 3757236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 3767236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project cursor = getThreadId(recipients); 3777236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 3787236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_CANONICAL_ADDRESS: { 3797236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String extraSelection = "_id=" + uri.getPathSegments().get(1); 3807236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String finalSelection = TextUtils.isEmpty(selection) 3817236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project ? extraSelection : extraSelection + " AND " + selection; 3821ecf192c60625c5227336430ee36705c13ae06e2Wei Huang cursor = db.query(TABLE_CANONICAL_ADDRESSES, 3831ecf192c60625c5227336430ee36705c13ae06e2Wei Huang CANONICAL_ADDRESSES_COLUMNS_1, 3841ecf192c60625c5227336430ee36705c13ae06e2Wei Huang finalSelection, 3851ecf192c60625c5227336430ee36705c13ae06e2Wei Huang selectionArgs, 3861ecf192c60625c5227336430ee36705c13ae06e2Wei Huang null, null, 3871ecf192c60625c5227336430ee36705c13ae06e2Wei Huang sortOrder); 3887236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 3897236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 39037e4424493bb364eac8ae07c3d5fce52bebf735dFicus Kirkpatrick case URI_CANONICAL_ADDRESSES: 3911ecf192c60625c5227336430ee36705c13ae06e2Wei Huang cursor = db.query(TABLE_CANONICAL_ADDRESSES, 3921ecf192c60625c5227336430ee36705c13ae06e2Wei Huang CANONICAL_ADDRESSES_COLUMNS_2, 3931ecf192c60625c5227336430ee36705c13ae06e2Wei Huang selection, 3941ecf192c60625c5227336430ee36705c13ae06e2Wei Huang selectionArgs, 3951ecf192c60625c5227336430ee36705c13ae06e2Wei Huang null, null, 3961ecf192c60625c5227336430ee36705c13ae06e2Wei Huang sortOrder); 39737e4424493bb364eac8ae07c3d5fce52bebf735dFicus Kirkpatrick break; 3988e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner case URI_SEARCH_SUGGEST: { 3993e1cba826743423642635cc7b03abe292470f4c4Tom Taylor SEARCH_STRING[0] = uri.getQueryParameter("pattern") + '*' ; 4009e1fd44679b2de6df6af2c1e8b6bf191e799f4a9Mark Wagner 4019e1fd44679b2de6df6af2c1e8b6bf191e799f4a9Mark Wagner // find the words which match the pattern using the snippet function. The 4029e1fd44679b2de6df6af2c1e8b6bf191e799f4a9Mark Wagner // snippet function parameters mainly describe how to format the result. 4039e1fd44679b2de6df6af2c1e8b6bf191e799f4a9Mark Wagner // See http://www.sqlite.org/fts3.html#section_4_2 for details. 4048e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner if ( sortOrder != null 4058e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner || selection != null 4068e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner || selectionArgs != null 4078e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner || projection != null) { 4088e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner throw new IllegalArgumentException( 4098e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner "do not specify sortOrder, selection, selectionArgs, or projection" + 4108e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner "with this query"); 4118e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner } 4128e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner 4133e1cba826743423642635cc7b03abe292470f4c4Tom Taylor cursor = db.rawQuery(SEARCH_QUERY, SEARCH_STRING); 4148e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner break; 4158e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner } 4166a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner case URI_MESSAGE_ID_TO_THREAD: { 4176a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner // Given a message ID and an indicator for SMS vs. MMS return 4186a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner // the thread id of the corresponding thread. 4196a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner try { 4206a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner long id = Long.parseLong(uri.getQueryParameter("row_id")); 4216a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner switch (Integer.parseInt(uri.getQueryParameter("table_to_use"))) { 4226a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner case 1: // sms 4236a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner cursor = db.query( 42472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen smsTable, 4256a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner new String[] { "thread_id" }, 4266a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner "_id=?", 4276a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner new String[] { String.valueOf(id) }, 4286a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner null, 4296a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner null, 4306a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner null); 4316a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner break; 4326a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner case 2: // mms 43372f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String mmsQuery = "SELECT thread_id " 43472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "FROM " + pduTable + ",part " 43572f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "WHERE ((part.mid=" + pduTable + "._id) " 43672f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "AND " + "(part._id=?))"; 4376a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner cursor = db.rawQuery(mmsQuery, new String[] { String.valueOf(id) }); 4386a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner break; 4396a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner } 4406a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner } catch (NumberFormatException ex) { 4416a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner // ignore... return empty cursor 4426a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner } 4436a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner break; 4446a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner } 4458e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner case URI_SEARCH: { 44687bfe142b5c163e19fb9e60d558bbeb513ca150cTom Taylor if ( sortOrder != null 44787bfe142b5c163e19fb9e60d558bbeb513ca150cTom Taylor || selection != null 44887bfe142b5c163e19fb9e60d558bbeb513ca150cTom Taylor || selectionArgs != null 449f0a9e90721310bed023a9ff1f176f1b5e05a14f7Mark Wagner || projection != null) { 450f0a9e90721310bed023a9ff1f176f1b5e05a14f7Mark Wagner throw new IllegalArgumentException( 451f0a9e90721310bed023a9ff1f176f1b5e05a14f7Mark Wagner "do not specify sortOrder, selection, selectionArgs, or projection" + 452f0a9e90721310bed023a9ff1f176f1b5e05a14f7Mark Wagner "with this query"); 45366d373c4797c53207e8f1ea97f3dc5541f390152Mark Wagner } 45487bfe142b5c163e19fb9e60d558bbeb513ca150cTom Taylor 4558e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner String searchString = uri.getQueryParameter("pattern") + "*"; 4568e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner 4578e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner try { 45872f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen cursor = db.rawQuery(getTextSearchQuery(smsTable, pduTable), 45972f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen new String[] { searchString, searchString }); 4608e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner } catch (Exception ex) { 4618e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner Log.e(LOG_TAG, "got exception: " + ex.toString()); 4628e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner } 46366d373c4797c53207e8f1ea97f3dc5541f390152Mark Wagner break; 4648e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner } 4657236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_PENDING_MSG: { 4667236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String protoName = uri.getQueryParameter("protocol"); 4677236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String msgId = uri.getQueryParameter("message"); 4687236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project int proto = TextUtils.isEmpty(protoName) ? -1 4697236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project : (protoName.equals("sms") ? MmsSms.SMS_PROTO : MmsSms.MMS_PROTO); 4707236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 4717236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String extraSelection = (proto != -1) ? 4727236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project (PendingMessages.PROTO_TYPE + "=" + proto) : " 0=0 "; 4737236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (!TextUtils.isEmpty(msgId)) { 4747236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project extraSelection += " AND " + PendingMessages.MSG_ID + "=" + msgId; 4757236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 4767236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 4777236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String finalSelection = TextUtils.isEmpty(selection) 4787236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project ? extraSelection : ("(" + extraSelection + ") AND " + selection); 4797236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String finalOrder = TextUtils.isEmpty(sortOrder) 4807236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project ? PendingMessages.DUE_TIME : sortOrder; 4817236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project cursor = db.query(TABLE_PENDING_MSG, null, 4827236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project finalSelection, selectionArgs, null, null, finalOrder); 4837236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 4847236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 4857236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_UNDELIVERED_MSG: { 4867236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project cursor = getUndeliveredMessages(projection, selection, 48772f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen selectionArgs, sortOrder, smsTable, pduTable); 4887236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 4897236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 4907236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_DRAFT: { 49172f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen cursor = getDraftThread(projection, selection, sortOrder, smsTable, pduTable); 4927236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 4937236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 494f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor case URI_FIRST_LOCKED_MESSAGE_BY_THREAD_ID: { 495f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor long threadId; 496f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor try { 497f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor threadId = Long.parseLong(uri.getLastPathSegment()); 498f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor } catch (NumberFormatException e) { 499f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor Log.e(LOG_TAG, "Thread ID must be a long."); 500f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor break; 501f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor } 502f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor cursor = getFirstLockedMessage(projection, "thread_id=" + Long.toString(threadId), 50372f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen sortOrder, smsTable, pduTable); 504f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor break; 505f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor } 506f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor case URI_FIRST_LOCKED_MESSAGE_ALL: { 50772f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen cursor = getFirstLockedMessage( 50872f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen projection, selection, sortOrder, smsTable, pduTable); 509f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor break; 510f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor } 5117236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project default: 5127236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project throw new IllegalStateException("Unrecognized URI:" + uri); 5137236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 5147236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 5155926996da70fff9275e948d1cf8a0f17b52a5e14Tom Taylor if (cursor != null) { 5165926996da70fff9275e948d1cf8a0f17b52a5e14Tom Taylor cursor.setNotificationUri(getContext().getContentResolver(), MmsSms.CONTENT_URI); 5175926996da70fff9275e948d1cf8a0f17b52a5e14Tom Taylor } 5187236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return cursor; 5197236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 5207236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 5217236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 5227236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Return the canonical address ID for this address. 5237236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 5247236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private long getSingleAddressId(String address) { 5257236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project boolean isEmail = Mms.isEmailAddress(address); 526e8a24ddaa58295f173fbf37fe3c0acb0d8569118Tom Taylor boolean isPhoneNumber = Mms.isPhoneNumber(address); 527e8a24ddaa58295f173fbf37fe3c0acb0d8569118Tom Taylor 528e8a24ddaa58295f173fbf37fe3c0acb0d8569118Tom Taylor // We lowercase all email addresses, but not addresses that aren't numbers, because 529e8a24ddaa58295f173fbf37fe3c0acb0d8569118Tom Taylor // that would incorrectly turn an address such as "My Vodafone" into "my vodafone" 530e8a24ddaa58295f173fbf37fe3c0acb0d8569118Tom Taylor // and the thread title would be incorrect when displayed in the UI. 5317236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String refinedAddress = isEmail ? address.toLowerCase() : address; 532e8a24ddaa58295f173fbf37fe3c0acb0d8569118Tom Taylor 533c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang String selection = "address=?"; 534c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang String[] selectionArgs; 53514595cbe9045755a5aa2bd28989c147c4709268cWei Huang long retVal = -1L; 536c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang 537e8a24ddaa58295f173fbf37fe3c0acb0d8569118Tom Taylor if (!isPhoneNumber) { 538c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang selectionArgs = new String[] { refinedAddress }; 539c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang } else { 54001c75ba95b875674a83128defc6b267e522db346Chen Mike selection += " OR PHONE_NUMBERS_EQUAL(address, ?, " + 54101c75ba95b875674a83128defc6b267e522db346Chen Mike (mUseStrictPhoneNumberComparation ? 1 : 0) + ")"; 542c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang selectionArgs = new String[] { refinedAddress, refinedAddress }; 543c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang } 544c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang 5457236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Cursor cursor = null; 5467236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 5477236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project try { 5487236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 5497236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project cursor = db.query( 5507236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project "canonical_addresses", ID_PROJECTION, 5517236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selection, selectionArgs, null, null, null); 5527236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 5537236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (cursor.getCount() == 0) { 5547236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project ContentValues contentValues = new ContentValues(1); 5557236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project contentValues.put(CanonicalAddressesColumns.ADDRESS, refinedAddress); 5567236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 5577236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project db = mOpenHelper.getWritableDatabase(); 55814595cbe9045755a5aa2bd28989c147c4709268cWei Huang retVal = db.insert("canonical_addresses", 5597236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project CanonicalAddressesColumns.ADDRESS, contentValues); 56014595cbe9045755a5aa2bd28989c147c4709268cWei Huang 561ea59f86662471e682f880b4916ce7588803f5605Wink Saville Log.d(LOG_TAG, "getSingleAddressId: insert new canonical_address for " + 562ea59f86662471e682f880b4916ce7588803f5605Wink Saville /*address*/ "xxxxxx" + ", _id=" + retVal); 56314595cbe9045755a5aa2bd28989c147c4709268cWei Huang 56414595cbe9045755a5aa2bd28989c147c4709268cWei Huang return retVal; 5657236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 5667236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 5677236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (cursor.moveToFirst()) { 56814595cbe9045755a5aa2bd28989c147c4709268cWei Huang retVal = cursor.getLong(cursor.getColumnIndexOrThrow(BaseColumns._ID)); 5697236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 5707236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } finally { 5717236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (cursor != null) { 5727236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project cursor.close(); 5737236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 5747236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 5757236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 57614595cbe9045755a5aa2bd28989c147c4709268cWei Huang return retVal; 5777236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 5787236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 5797236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 5807236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Return the canonical address IDs for these addresses. 5817236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 5827236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private Set<Long> getAddressIds(List<String> addresses) { 5837236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Set<Long> result = new HashSet<Long>(addresses.size()); 5847236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 5857236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project for (String address : addresses) { 5867236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (!address.equals(PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR)) { 5877236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project long id = getSingleAddressId(address); 5887236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (id != -1L) { 5897236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project result.add(id); 5907236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } else { 59114595cbe9045755a5aa2bd28989c147c4709268cWei Huang Log.e(LOG_TAG, "getAddressIds: address ID not found for " + address); 5927236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 5937236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 5947236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 5957236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return result; 5967236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 5977236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 5987236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 5997236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Return a sorted array of the given Set of Longs. 6007236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 6017236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private long[] getSortedSet(Set<Long> numbers) { 6027236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project int size = numbers.size(); 6037236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project long[] result = new long[size]; 6047236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project int i = 0; 6057236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 6067236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project for (Long number : numbers) { 6077236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project result[i++] = number; 6087236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 60914595cbe9045755a5aa2bd28989c147c4709268cWei Huang 61014595cbe9045755a5aa2bd28989c147c4709268cWei Huang if (size > 1) { 61114595cbe9045755a5aa2bd28989c147c4709268cWei Huang Arrays.sort(result); 61214595cbe9045755a5aa2bd28989c147c4709268cWei Huang } 61314595cbe9045755a5aa2bd28989c147c4709268cWei Huang 6147236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return result; 6157236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 6167236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 6177236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 6187236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Return a String of the numbers in the given array, in order, 6197236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * separated by spaces. 6207236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 6217236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private String getSpaceSeparatedNumbers(long[] numbers) { 6227236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project int size = numbers.length; 6237236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project StringBuilder buffer = new StringBuilder(); 6247236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 6257236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project for (int i = 0; i < size; i++) { 6267236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (i != 0) { 6277236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project buffer.append(' '); 6287236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 6297236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project buffer.append(numbers[i]); 6307236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 6317236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return buffer.toString(); 6327236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 6337236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 6347236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 6357236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Insert a record for a new thread. 6367236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 6377236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private void insertThread(String recipientIds, int numberOfRecipients) { 6387236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project ContentValues values = new ContentValues(4); 6397236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 6407236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project long date = System.currentTimeMillis(); 6417236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project values.put(ThreadsColumns.DATE, date - date % 1000); 6427236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project values.put(ThreadsColumns.RECIPIENT_IDS, recipientIds); 6437236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (numberOfRecipients > 1) { 6447236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project values.put(Threads.TYPE, Threads.BROADCAST_THREAD); 6457236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 6467236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project values.put(ThreadsColumns.MESSAGE_COUNT, 0); 6477236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 64815156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor long result = mOpenHelper.getWritableDatabase().insert(TABLE_THREADS, null, values); 64914595cbe9045755a5aa2bd28989c147c4709268cWei Huang Log.d(LOG_TAG, "insertThread: created new thread_id " + result + 650ea59f86662471e682f880b4916ce7588803f5605Wink Saville " for recipientIds " + /*recipientIds*/ "xxxxxxx"); 65114595cbe9045755a5aa2bd28989c147c4709268cWei Huang 65243f9fb234aabe569b342af78bdaf85effbd85f10Amith Yamasani getContext().getContentResolver().notifyChange(MmsSms.CONTENT_URI, null, true, 65343f9fb234aabe569b342af78bdaf85effbd85f10Amith Yamasani UserHandle.USER_ALL); 6547236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 6557236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 65614595cbe9045755a5aa2bd28989c147c4709268cWei Huang private static final String THREAD_QUERY = 65714595cbe9045755a5aa2bd28989c147c4709268cWei Huang "SELECT _id FROM threads " + "WHERE recipient_ids=?"; 65814595cbe9045755a5aa2bd28989c147c4709268cWei Huang 6597236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 6607236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Return the thread ID for this list of 6617236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * recipients IDs. If no thread exists with this ID, create 6627236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * one and return it. Callers should always use 6637236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Threads.getThreadId to access this information. 6647236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 6657236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private synchronized Cursor getThreadId(List<String> recipients) { 66614595cbe9045755a5aa2bd28989c147c4709268cWei Huang Set<Long> addressIds = getAddressIds(recipients); 66714595cbe9045755a5aa2bd28989c147c4709268cWei Huang String recipientIds = ""; 668c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang 6695926996da70fff9275e948d1cf8a0f17b52a5e14Tom Taylor if (addressIds.size() == 0) { 6705926996da70fff9275e948d1cf8a0f17b52a5e14Tom Taylor Log.e(LOG_TAG, "getThreadId: NO receipients specified -- NOT creating thread", 6715926996da70fff9275e948d1cf8a0f17b52a5e14Tom Taylor new Exception()); 6725926996da70fff9275e948d1cf8a0f17b52a5e14Tom Taylor return null; 6735926996da70fff9275e948d1cf8a0f17b52a5e14Tom Taylor } else if (addressIds.size() == 1) { 6745926996da70fff9275e948d1cf8a0f17b52a5e14Tom Taylor // optimize for size==1, which should be most of the cases 67514595cbe9045755a5aa2bd28989c147c4709268cWei Huang for (Long addressId : addressIds) { 67614595cbe9045755a5aa2bd28989c147c4709268cWei Huang recipientIds = Long.toString(addressId); 67714595cbe9045755a5aa2bd28989c147c4709268cWei Huang } 67814595cbe9045755a5aa2bd28989c147c4709268cWei Huang } else { 67914595cbe9045755a5aa2bd28989c147c4709268cWei Huang recipientIds = getSpaceSeparatedNumbers(getSortedSet(addressIds)); 68014595cbe9045755a5aa2bd28989c147c4709268cWei Huang } 6817236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 68214595cbe9045755a5aa2bd28989c147c4709268cWei Huang if (Log.isLoggable(LOG_TAG, Log.VERBOSE)) { 683ea59f86662471e682f880b4916ce7588803f5605Wink Saville Log.d(LOG_TAG, "getThreadId: recipientIds (selectionArgs) =" + 684ea59f86662471e682f880b4916ce7588803f5605Wink Saville /*recipientIds*/ "xxxxxxx"); 685b4ac04f7bd9d4f16ec181f368c42f89c96f83f55Tom Taylor } 68614595cbe9045755a5aa2bd28989c147c4709268cWei Huang 68714595cbe9045755a5aa2bd28989c147c4709268cWei Huang String[] selectionArgs = new String[] { recipientIds }; 68815156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor 6897236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 69015156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor db.beginTransaction(); 69115156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor Cursor cursor = null; 69215156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor try { 69315156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor // Find the thread with the given recipients 69415156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor cursor = db.rawQuery(THREAD_QUERY, selectionArgs); 6957236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 69615156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor if (cursor.getCount() == 0) { 69715156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor // No thread with those recipients exists, so create the thread. 69815156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor cursor.close(); 69914595cbe9045755a5aa2bd28989c147c4709268cWei Huang 70015156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor Log.d(LOG_TAG, "getThreadId: create new thread_id for recipients " + 70115156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor /*recipients*/ "xxxxxxxx"); 70215156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor insertThread(recipientIds, recipients.size()); 70314595cbe9045755a5aa2bd28989c147c4709268cWei Huang 70415156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor // The thread was just created, now find it and return it. 70515156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor cursor = db.rawQuery(THREAD_QUERY, selectionArgs); 70615156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor } 70715156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor db.setTransactionSuccessful(); 70815156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor } catch (Throwable ex) { 70915156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor Log.e(LOG_TAG, ex.getMessage(), ex); 71015156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor } finally { 71115156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor db.endTransaction(); 7127236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 7136a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner 71415156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor if (cursor != null && cursor.getCount() > 1) { 71514595cbe9045755a5aa2bd28989c147c4709268cWei Huang Log.w(LOG_TAG, "getThreadId: why is cursorCount=" + cursor.getCount()); 71669e6ffada415d44c72d908ad9e152da51b190642Tom Taylor } 7177236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return cursor; 7187236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 7197236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 7207236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static String concatSelections(String selection1, String selection2) { 7217236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (TextUtils.isEmpty(selection1)) { 7227236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return selection2; 7237236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } else if (TextUtils.isEmpty(selection2)) { 7247236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return selection1; 7257236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } else { 7267236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return selection1 + " AND " + selection2; 7277236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 7287236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 7297236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 7307236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 7317236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * If a null projection is given, return the union of all columns 7327236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * in both the MMS and SMS messages tables. Otherwise, return the 7337236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * given projection. 7347236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 7357236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static String[] handleNullMessageProjection( 7367236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] projection) { 7377236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return projection == null ? UNION_COLUMNS : projection; 7387236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 7397236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 7407236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 7417236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * If a null projection is given, return the set of all columns in 7427236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * the threads table. Otherwise, return the given projection. 7437236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 7447236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static String[] handleNullThreadsProjection( 7457236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] projection) { 7467236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return projection == null ? THREADS_COLUMNS : projection; 7477236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 7487236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 7497236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 7507236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * If a null sort order is given, return "normalized_date ASC". 7517236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Otherwise, return the given sort order. 7527236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 7537236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static String handleNullSortOrder (String sortOrder) { 7547236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return sortOrder == null ? "normalized_date ASC" : sortOrder; 7557236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 7567236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 7577236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 7587236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Return existing threads in the database. 7597236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 7607236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private Cursor getSimpleConversations(String[] projection, String selection, 7617236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] selectionArgs, String sortOrder) { 76215156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor return mOpenHelper.getReadableDatabase().query(TABLE_THREADS, projection, 7637236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selection, selectionArgs, null, null, " date DESC"); 7647236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 7657236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 7667236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 7677236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Return the thread which has draft in both MMS and SMS. 7687236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * 7697236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Use this query: 7707236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * 7717236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * SELECT ... 7727236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * FROM (SELECT _id, thread_id, ... 7737236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * FROM pdu 7747236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * WHERE msg_box = 3 AND ... 7757236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * UNION 7767236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * SELECT _id, thread_id, ... 7777236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * FROM sms 7787236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * WHERE type = 3 AND ... 7797236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * ) 7807236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * ; 7817236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 7827236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private Cursor getDraftThread(String[] projection, String selection, 78372f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String sortOrder, String smsTable, String pduTable) { 7847236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] innerProjection = new String[] {BaseColumns._ID, Conversations.THREAD_ID}; 7857236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder(); 7867236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder(); 7877236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 78872f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen mmsQueryBuilder.setTables(pduTable); 78972f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen smsQueryBuilder.setTables(smsTable); 7907236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 7917236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery( 7927236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerProjection, 7937236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MMS_COLUMNS, 1, "mms", 7947236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project concatSelections(selection, Mms.MESSAGE_BOX + "=" + Mms.MESSAGE_BOX_DRAFTS), 795f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor null, null); 7967236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String smsSubQuery = smsQueryBuilder.buildUnionSubQuery( 7977236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerProjection, 7987236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SMS_COLUMNS, 1, "sms", 7997236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project concatSelections(selection, Sms.TYPE + "=" + Sms.MESSAGE_TYPE_DRAFT), 800f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor null, null); 8017236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder(); 8027236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8037236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project unionQueryBuilder.setDistinct(true); 8047236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8057236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String unionQuery = unionQueryBuilder.buildUnionQuery( 8067236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project new String[] { mmsSubQuery, smsSubQuery }, null, null); 8077236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8087236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder outerQueryBuilder = new SQLiteQueryBuilder(); 8097236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8107236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project outerQueryBuilder.setTables("(" + unionQuery + ")"); 8117236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8127236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String outerQuery = outerQueryBuilder.buildQuery( 813f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor projection, null, null, null, sortOrder, null); 8147236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8157236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return mOpenHelper.getReadableDatabase().rawQuery(outerQuery, EMPTY_STRING_ARRAY); 8167236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 8177236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8187236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 8197236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Return the most recent message in each conversation in both MMS 8207236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * and SMS. 8217236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * 8227236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Use this query: 8237236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * 8247236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * SELECT ... 8257236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * FROM (SELECT thread_id AS tid, date * 1000 AS normalized_date, ... 8267236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * FROM pdu 8277236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * WHERE msg_box != 3 AND ... 8287236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * GROUP BY thread_id 8297236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * HAVING date = MAX(date) 8307236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * UNION 8317236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * SELECT thread_id AS tid, date AS normalized_date, ... 8327236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * FROM sms 8337236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * WHERE ... 8347236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * GROUP BY thread_id 8357236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * HAVING date = MAX(date)) 8367236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * GROUP BY tid 8377236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * HAVING normalized_date = MAX(normalized_date); 8387236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * 8397236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * The msg_box != 3 comparisons ensure that we don't include draft 8407236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * messages. 8417236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 8427236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private Cursor getConversations(String[] projection, String selection, 84372f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String sortOrder, String smsTable, String pduTable) { 8447236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder(); 8457236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder(); 8467236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 84772f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen mmsQueryBuilder.setTables(pduTable); 84872f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen smsQueryBuilder.setTables(smsTable); 8497236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8507236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] columns = handleNullMessageProjection(projection); 8517236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] innerMmsProjection = makeProjectionWithDateAndThreadId( 8527236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project UNION_COLUMNS, 1000); 8537236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] innerSmsProjection = makeProjectionWithDateAndThreadId( 8547236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project UNION_COLUMNS, 1); 8557236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery( 8567236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerMmsProjection, 8577236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MMS_COLUMNS, 1, "mms", 858f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor concatSelections(selection, MMS_CONVERSATION_CONSTRAINT), 8597236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project "thread_id", "date = MAX(date)"); 8607236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String smsSubQuery = smsQueryBuilder.buildUnionSubQuery( 8617236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerSmsProjection, 8627236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SMS_COLUMNS, 1, "sms", 863f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor concatSelections(selection, SMS_CONVERSATION_CONSTRAINT), 8647236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project "thread_id", "date = MAX(date)"); 8657236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder(); 8667236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8677236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project unionQueryBuilder.setDistinct(true); 8687236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8697236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String unionQuery = unionQueryBuilder.buildUnionQuery( 8707236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project new String[] { mmsSubQuery, smsSubQuery }, null, null); 8717236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8727236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder outerQueryBuilder = new SQLiteQueryBuilder(); 8737236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8747236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project outerQueryBuilder.setTables("(" + unionQuery + ")"); 8757236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8767236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String outerQuery = outerQueryBuilder.buildQuery( 877f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor columns, null, "tid", 8787236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project "normalized_date = MAX(normalized_date)", sortOrder, null); 8797236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8807236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return mOpenHelper.getReadableDatabase().rawQuery(outerQuery, EMPTY_STRING_ARRAY); 8817236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 8827236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8837236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 884f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor * Return the first locked message found in the union of MMS 885f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor * and SMS messages. 886f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor * 887f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor * Use this query: 888f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor * 889816e934a43bf705835bdb24503a85a14c4861991Tom Taylor * SELECT _id FROM pdu GROUP BY _id HAVING locked=1 UNION SELECT _id FROM sms GROUP 890816e934a43bf705835bdb24503a85a14c4861991Tom Taylor * BY _id HAVING locked=1 LIMIT 1 891f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor * 892816e934a43bf705835bdb24503a85a14c4861991Tom Taylor * We limit by 1 because we're only interested in knowing if 893f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor * there is *any* locked message, not the actual messages themselves. 894f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor */ 895f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private Cursor getFirstLockedMessage(String[] projection, String selection, 89672f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String sortOrder, String smsTable, String pduTable) { 897f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder(); 898f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder(); 899f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor 90072f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen mmsQueryBuilder.setTables(pduTable); 90172f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen smsQueryBuilder.setTables(smsTable); 902f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor 903816e934a43bf705835bdb24503a85a14c4861991Tom Taylor String[] idColumn = new String[] { BaseColumns._ID }; 904816e934a43bf705835bdb24503a85a14c4861991Tom Taylor 905f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor // NOTE: buildUnionSubQuery *ignores* selectionArgs 906f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery( 907816e934a43bf705835bdb24503a85a14c4861991Tom Taylor MmsSms.TYPE_DISCRIMINATOR_COLUMN, idColumn, 908816e934a43bf705835bdb24503a85a14c4861991Tom Taylor null, 1, "mms", 909f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor selection, 910816e934a43bf705835bdb24503a85a14c4861991Tom Taylor BaseColumns._ID, "locked=1"); 911816e934a43bf705835bdb24503a85a14c4861991Tom Taylor 912f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor String smsSubQuery = smsQueryBuilder.buildUnionSubQuery( 913816e934a43bf705835bdb24503a85a14c4861991Tom Taylor MmsSms.TYPE_DISCRIMINATOR_COLUMN, idColumn, 914816e934a43bf705835bdb24503a85a14c4861991Tom Taylor null, 1, "sms", 915f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor selection, 916816e934a43bf705835bdb24503a85a14c4861991Tom Taylor BaseColumns._ID, "locked=1"); 917816e934a43bf705835bdb24503a85a14c4861991Tom Taylor 918f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder(); 919f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor 920f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor unionQueryBuilder.setDistinct(true); 921f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor 922f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor String unionQuery = unionQueryBuilder.buildUnionQuery( 923816e934a43bf705835bdb24503a85a14c4861991Tom Taylor new String[] { mmsSubQuery, smsSubQuery }, null, "1"); 924f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor 925816e934a43bf705835bdb24503a85a14c4861991Tom Taylor Cursor cursor = mOpenHelper.getReadableDatabase().rawQuery(unionQuery, EMPTY_STRING_ARRAY); 926f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor 927f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor if (DEBUG) { 928816e934a43bf705835bdb24503a85a14c4861991Tom Taylor Log.v("MmsSmsProvider", "getFirstLockedMessage query: " + unionQuery); 929816e934a43bf705835bdb24503a85a14c4861991Tom Taylor Log.v("MmsSmsProvider", "cursor count: " + cursor.getCount()); 930f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor } 931816e934a43bf705835bdb24503a85a14c4861991Tom Taylor return cursor; 932f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor } 933f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor 934f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor /** 9357236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Return every message in each conversation in both MMS 9367236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * and SMS. 9377236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 9387236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private Cursor getCompleteConversations(String[] projection, 93972f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String selection, String sortOrder, String smsTable, String pduTable) { 94072f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String unionQuery = buildConversationQuery(projection, selection, sortOrder, smsTable, 94172f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen pduTable); 9427236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 9437236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return mOpenHelper.getReadableDatabase().rawQuery(unionQuery, EMPTY_STRING_ARRAY); 9447236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 9457236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 9467236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 9477236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Add normalized date and thread_id to the list of columns for an 9487236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * inner projection. This is necessary so that the outer query 9497236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * can have access to these columns even if the caller hasn't 9507236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * requested them in the result. 9517236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 9527236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private String[] makeProjectionWithDateAndThreadId( 9537236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] projection, int dateMultiple) { 9547236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project int projectionSize = projection.length; 9557236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] result = new String[projectionSize + 2]; 9567236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 9577236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project result[0] = "thread_id AS tid"; 9587236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project result[1] = "date * " + dateMultiple + " AS normalized_date"; 9597236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project for (int i = 0; i < projectionSize; i++) { 9607236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project result[i + 2] = projection[i]; 9617236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 9627236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return result; 9637236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 9647236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 9657236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 9667236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Return the union of MMS and SMS messages for this thread ID. 9677236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 9687236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private Cursor getConversationMessages( 9697236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String threadIdString, String[] projection, String selection, 97072f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String sortOrder, String smsTable, String pduTable) { 9717236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project try { 9727236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Long.parseLong(threadIdString); 9737236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } catch (NumberFormatException exception) { 9747236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Log.e(LOG_TAG, "Thread ID must be a Long."); 9757236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return null; 9767236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 9777236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 9787236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String finalSelection = concatSelections( 9797236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selection, "thread_id = " + threadIdString); 98072f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String unionQuery = buildConversationQuery(projection, finalSelection, sortOrder, smsTable, 98172f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen pduTable); 9827236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 9837236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return mOpenHelper.getReadableDatabase().rawQuery(unionQuery, EMPTY_STRING_ARRAY); 9847236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 9857236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 9867236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 9877236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Return the union of MMS and SMS messages whose recipients 9887236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * included this phone number. 9897236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * 9907236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Use this query: 9917236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * 9927236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * SELECT ... 993670c495b6e0489569f60a38a79770dd4ac44500awhliang * FROM pdu, (SELECT msg_id AS address_msg_id 9947236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * FROM addr 995c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang * WHERE (address='<phoneNumber>' OR 996c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang * PHONE_NUMBERS_EQUAL(addr.address, '<phoneNumber>', 1/0))) 9977236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * AS matching_addresses 998670c495b6e0489569f60a38a79770dd4ac44500awhliang * WHERE pdu._id = matching_addresses.address_msg_id 9997236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * UNION 10007236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * SELECT ... 10017236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * FROM sms 1002c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang * WHERE (address='<phoneNumber>' OR PHONE_NUMBERS_EQUAL(sms.address, '<phoneNumber>', 1/0)); 10037236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 10047236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private Cursor getMessagesByPhoneNumber( 10057236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String phoneNumber, String[] projection, String selection, 100672f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String sortOrder, String smsTable, String pduTable) { 10077236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String escapedPhoneNumber = DatabaseUtils.sqlEscapeString(phoneNumber); 10087236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String finalMmsSelection = 10097236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project concatSelections( 10107236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selection, 101172f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen pduTable + "._id = matching_addresses.address_msg_id"); 10127236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String finalSmsSelection = 10137236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project concatSelections( 10147236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selection, 1015c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang "(address=" + escapedPhoneNumber + " OR PHONE_NUMBERS_EQUAL(address, " + 1016845a9163dffcbd1073930b8b334df27728418201Daisuke Miyakawa escapedPhoneNumber + 1017c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang (mUseStrictPhoneNumberComparation ? ", 1))" : ", 0))")); 10187236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder(); 10197236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder(); 10207236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 10217236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project mmsQueryBuilder.setDistinct(true); 10227236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project smsQueryBuilder.setDistinct(true); 10237236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project mmsQueryBuilder.setTables( 102472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen pduTable + 1025670c495b6e0489569f60a38a79770dd4ac44500awhliang ", (SELECT msg_id AS address_msg_id " + 1026c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang "FROM addr WHERE (address=" + escapedPhoneNumber + 1027c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang " OR PHONE_NUMBERS_EQUAL(addr.address, " + 1028845a9163dffcbd1073930b8b334df27728418201Daisuke Miyakawa escapedPhoneNumber + 1029c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang (mUseStrictPhoneNumberComparation ? ", 1))) " : ", 0))) ") + 10307236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project "AS matching_addresses"); 103172f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen smsQueryBuilder.setTables(smsTable); 10327236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 10337236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] columns = handleNullMessageProjection(projection); 10347236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery( 10357236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MmsSms.TYPE_DISCRIMINATOR_COLUMN, columns, MMS_COLUMNS, 1036f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor 0, "mms", finalMmsSelection, null, null); 10377236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String smsSubQuery = smsQueryBuilder.buildUnionSubQuery( 10387236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MmsSms.TYPE_DISCRIMINATOR_COLUMN, columns, SMS_COLUMNS, 1039f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor 0, "sms", finalSmsSelection, null, null); 10407236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder(); 10417236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 10427236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project unionQueryBuilder.setDistinct(true); 10437236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 10447236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String unionQuery = unionQueryBuilder.buildUnionQuery( 10457236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project new String[] { mmsSubQuery, smsSubQuery }, sortOrder, null); 10467236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 10477236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return mOpenHelper.getReadableDatabase().rawQuery(unionQuery, EMPTY_STRING_ARRAY); 10487236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 10497236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 10507236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 10517236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Return the conversation of certain thread ID. 10527236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 10537236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private Cursor getConversationById( 10547236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String threadIdString, String[] projection, String selection, 10557236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] selectionArgs, String sortOrder) { 10567236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project try { 10577236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Long.parseLong(threadIdString); 10587236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } catch (NumberFormatException exception) { 10597236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Log.e(LOG_TAG, "Thread ID must be a Long."); 10607236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return null; 10617236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 10627236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 10637236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String extraSelection = "_id=" + threadIdString; 10647236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String finalSelection = concatSelections(selection, extraSelection); 10657236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder(); 10667236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] columns = handleNullThreadsProjection(projection); 10677236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 10687236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project queryBuilder.setDistinct(true); 106915156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor queryBuilder.setTables(TABLE_THREADS); 10707236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return queryBuilder.query( 10717236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project mOpenHelper.getReadableDatabase(), columns, finalSelection, 10727236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selectionArgs, sortOrder, null, null); 10737236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 10747236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 107572f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen private static String joinPduAndPendingMsgTables(String pduTable) { 107672f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen return pduTable + " LEFT JOIN " + TABLE_PENDING_MSG 107772f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + " ON " + pduTable + "._id = pending_msgs.msg_id"; 10787236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 10797236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 108072f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen private static String[] createMmsProjection(String[] old, String pduTable) { 10817236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] newProjection = new String[old.length]; 10827236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project for (int i = 0; i < old.length; i++) { 10837236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (old[i].equals(BaseColumns._ID)) { 108472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen newProjection[i] = pduTable + "._id"; 10857236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } else { 10867236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project newProjection[i] = old[i]; 10877236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 10887236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 10897236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return newProjection; 10907236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 10917236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 10927236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private Cursor getUndeliveredMessages( 10937236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] projection, String selection, String[] selectionArgs, 109472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String sortOrder, String smsTable, String pduTable) { 109572f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String[] mmsProjection = createMmsProjection(projection, pduTable); 10967236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 10977236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder(); 10987236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder(); 10997236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 110072f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen mmsQueryBuilder.setTables(joinPduAndPendingMsgTables(pduTable)); 110172f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen smsQueryBuilder.setTables(smsTable); 11027236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11037236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String finalMmsSelection = concatSelections( 11047236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selection, Mms.MESSAGE_BOX + " = " + Mms.MESSAGE_BOX_OUTBOX); 11057236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String finalSmsSelection = concatSelections( 11067236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selection, "(" + Sms.TYPE + " = " + Sms.MESSAGE_TYPE_OUTBOX 11077236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project + " OR " + Sms.TYPE + " = " + Sms.MESSAGE_TYPE_FAILED 11087236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project + " OR " + Sms.TYPE + " = " + Sms.MESSAGE_TYPE_QUEUED + ")"); 11097236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11107236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] smsColumns = handleNullMessageProjection(projection); 11117236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] mmsColumns = handleNullMessageProjection(mmsProjection); 11127236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] innerMmsProjection = makeProjectionWithDateAndThreadId( 11137236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project mmsColumns, 1000); 11147236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] innerSmsProjection = makeProjectionWithDateAndThreadId( 11157236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project smsColumns, 1); 11167236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11177236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Set<String> columnsPresentInTable = new HashSet<String>(MMS_COLUMNS); 111872f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen columnsPresentInTable.add(pduTable + "._id"); 11197236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project columnsPresentInTable.add(PendingMessages.ERROR_TYPE); 11207236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery( 11217236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerMmsProjection, 1122f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor columnsPresentInTable, 1, "mms", finalMmsSelection, 11237236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project null, null); 11247236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String smsSubQuery = smsQueryBuilder.buildUnionSubQuery( 11257236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerSmsProjection, 1126f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor SMS_COLUMNS, 1, "sms", finalSmsSelection, 11277236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project null, null); 11287236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder(); 11297236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11307236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project unionQueryBuilder.setDistinct(true); 11317236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11327236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String unionQuery = unionQueryBuilder.buildUnionQuery( 11337236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project new String[] { smsSubQuery, mmsSubQuery }, null, null); 11347236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11357236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder outerQueryBuilder = new SQLiteQueryBuilder(); 11367236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11377236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project outerQueryBuilder.setTables("(" + unionQuery + ")"); 11387236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11397236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String outerQuery = outerQueryBuilder.buildQuery( 1140f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor smsColumns, null, null, null, sortOrder, null); 11417236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11427236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return mOpenHelper.getReadableDatabase().rawQuery(outerQuery, EMPTY_STRING_ARRAY); 11437236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 11447236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11457236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 11467236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Add normalized date to the list of columns for an inner 11477236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * projection. 11487236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 11497236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static String[] makeProjectionWithNormalizedDate( 11507236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] projection, int dateMultiple) { 11517236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project int projectionSize = projection.length; 11527236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] result = new String[projectionSize + 1]; 11537236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11547236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project result[0] = "date * " + dateMultiple + " AS normalized_date"; 11557236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project System.arraycopy(projection, 0, result, 1, projectionSize); 11567236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return result; 11577236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 11587236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11597236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static String buildConversationQuery(String[] projection, 116072f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String selection, String sortOrder, String smsTable, String pduTable) { 116172f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String[] mmsProjection = createMmsProjection(projection, pduTable); 11627236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11637236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder(); 11647236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder(); 11657236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11667236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project mmsQueryBuilder.setDistinct(true); 11677236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project smsQueryBuilder.setDistinct(true); 116872f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen mmsQueryBuilder.setTables(joinPduAndPendingMsgTables(pduTable)); 116972f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen smsQueryBuilder.setTables(smsTable); 11707236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11717236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] smsColumns = handleNullMessageProjection(projection); 11727236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] mmsColumns = handleNullMessageProjection(mmsProjection); 11737236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] innerMmsProjection = makeProjectionWithNormalizedDate(mmsColumns, 1000); 11747236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] innerSmsProjection = makeProjectionWithNormalizedDate(smsColumns, 1); 11757236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11767236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Set<String> columnsPresentInTable = new HashSet<String>(MMS_COLUMNS); 117772f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen columnsPresentInTable.add(pduTable + "._id"); 11787236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project columnsPresentInTable.add(PendingMessages.ERROR_TYPE); 11797236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11807236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String mmsSelection = concatSelections(selection, 11817236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Mms.MESSAGE_BOX + " != " + Mms.MESSAGE_BOX_DRAFTS); 11827236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery( 11837236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerMmsProjection, 11847236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project columnsPresentInTable, 0, "mms", 11857236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project concatSelections(mmsSelection, MMS_CONVERSATION_CONSTRAINT), 1186f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor null, null); 11877236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String smsSubQuery = smsQueryBuilder.buildUnionSubQuery( 11887236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerSmsProjection, SMS_COLUMNS, 11897236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 0, "sms", concatSelections(selection, SMS_CONVERSATION_CONSTRAINT), 1190f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor null, null); 11917236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder(); 11927236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11937236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project unionQueryBuilder.setDistinct(true); 11947236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11957236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String unionQuery = unionQueryBuilder.buildUnionQuery( 11967236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project new String[] { smsSubQuery, mmsSubQuery }, 11977236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project handleNullSortOrder(sortOrder), null); 11987236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11997236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder outerQueryBuilder = new SQLiteQueryBuilder(); 12007236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 12017236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project outerQueryBuilder.setTables("(" + unionQuery + ")"); 12027236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 12037236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return outerQueryBuilder.buildQuery( 1204f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor smsColumns, null, null, null, sortOrder, null); 12057236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 12067236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 12077236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project @Override 12087236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project public String getType(Uri uri) { 12097236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return VND_ANDROID_DIR_MMS_SMS; 12107236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 12117236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 12127236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project @Override 12137236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project public int delete(Uri uri, String selection, 12147236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] selectionArgs) { 12157236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 12167236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Context context = getContext(); 12177236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project int affectedRows = 0; 1218f0a9e90721310bed023a9ff1f176f1b5e05a14f7Mark Wagner 12197236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project switch(URI_MATCHER.match(uri)) { 12207236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_CONVERSATIONS_MESSAGES: 12217236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project long threadId; 12227236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project try { 12237236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project threadId = Long.parseLong(uri.getLastPathSegment()); 12247236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } catch (NumberFormatException e) { 12257236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Log.e(LOG_TAG, "Thread ID must be a long."); 12267236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 12277236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 12287236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project affectedRows = deleteConversation(uri, selection, selectionArgs); 12297236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MmsSmsDatabaseHelper.updateThread(db, threadId); 12307236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 12317236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_CONVERSATIONS: 12327236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project affectedRows = MmsProvider.deleteMessages(context, db, 12337236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selection, selectionArgs, uri) 12347236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project + db.delete("sms", selection, selectionArgs); 1235c2bd355a1ebb364c76576c81fb19a1d5e5a7b2a5Snild Dolkow // Intentionally don't pass the selection variable to updateThreads. 123687bfe142b5c163e19fb9e60d558bbeb513ca150cTom Taylor // When we pass in "locked=0" there, the thread will get excluded from 123787bfe142b5c163e19fb9e60d558bbeb513ca150cTom Taylor // the selection and not get updated. 1238c2bd355a1ebb364c76576c81fb19a1d5e5a7b2a5Snild Dolkow MmsSmsDatabaseHelper.updateThreads(db, null, null); 12397236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 12407236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_OBSOLETE_THREADS: 124115156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor affectedRows = db.delete(TABLE_THREADS, 12424b14c35e9e44d5df2b5340141f2b24bab351c603Tom Taylor "_id NOT IN (SELECT DISTINCT thread_id FROM sms where thread_id NOT NULL " + 12434b14c35e9e44d5df2b5340141f2b24bab351c603Tom Taylor "UNION SELECT DISTINCT thread_id FROM pdu where thread_id NOT NULL)", null); 12447236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 12457236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project default: 1246b91bcae9fa009787f165591fd7fc4c8f2f2dfd99Tom Taylor throw new UnsupportedOperationException(NO_DELETES_INSERTS_OR_UPDATES + uri); 12477236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 12487236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 12497236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (affectedRows > 0) { 125043f9fb234aabe569b342af78bdaf85effbd85f10Amith Yamasani context.getContentResolver().notifyChange(MmsSms.CONTENT_URI, null, true, 125143f9fb234aabe569b342af78bdaf85effbd85f10Amith Yamasani UserHandle.USER_ALL); 12527236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 12537236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return affectedRows; 12547236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 12557236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 12567236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 12577236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Delete the conversation with the given thread ID. 12587236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 12597236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private int deleteConversation(Uri uri, String selection, String[] selectionArgs) { 12607236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String threadId = uri.getLastPathSegment(); 12617236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 12627236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 12637236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String finalSelection = concatSelections(selection, "thread_id = " + threadId); 12647236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return MmsProvider.deleteMessages(getContext(), db, finalSelection, 12657236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selectionArgs, uri) 12667236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project + db.delete("sms", finalSelection, selectionArgs); 12677236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 12687236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 12697236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project @Override 12707236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project public Uri insert(Uri uri, ContentValues values) { 1271b91bcae9fa009787f165591fd7fc4c8f2f2dfd99Tom Taylor if (URI_MATCHER.match(uri) == URI_PENDING_MSG) { 1272b91bcae9fa009787f165591fd7fc4c8f2f2dfd99Tom Taylor SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 1273b91bcae9fa009787f165591fd7fc4c8f2f2dfd99Tom Taylor long rowId = db.insert(TABLE_PENDING_MSG, null, values); 1274b91bcae9fa009787f165591fd7fc4c8f2f2dfd99Tom Taylor return Uri.parse(uri + "/" + rowId); 1275b91bcae9fa009787f165591fd7fc4c8f2f2dfd99Tom Taylor } 1276b91bcae9fa009787f165591fd7fc4c8f2f2dfd99Tom Taylor throw new UnsupportedOperationException(NO_DELETES_INSERTS_OR_UPDATES + uri); 12777236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 12787236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 12797236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project @Override 12807236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project public int update(Uri uri, ContentValues values, 12817236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String selection, String[] selectionArgs) { 1282e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wen final int callerUid = Binder.getCallingUid(); 128372f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen final String callerPkg = getCallingPackage(); 12847236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 12857236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project int affectedRows = 0; 12867236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project switch(URI_MATCHER.match(uri)) { 12877236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_CONVERSATIONS_MESSAGES: 12887236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String threadIdString = uri.getPathSegments().get(1); 12897236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project affectedRows = updateConversation(threadIdString, values, 129072f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen selection, selectionArgs, callerUid, callerPkg); 12917236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 12921ecf192c60625c5227336430ee36705c13ae06e2Wei Huang 12937236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_PENDING_MSG: 12947236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project affectedRows = db.update(TABLE_PENDING_MSG, values, selection, null); 12957236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 12961ecf192c60625c5227336430ee36705c13ae06e2Wei Huang 12971ecf192c60625c5227336430ee36705c13ae06e2Wei Huang case URI_CANONICAL_ADDRESS: { 12981ecf192c60625c5227336430ee36705c13ae06e2Wei Huang String extraSelection = "_id=" + uri.getPathSegments().get(1); 12991ecf192c60625c5227336430ee36705c13ae06e2Wei Huang String finalSelection = TextUtils.isEmpty(selection) 13001ecf192c60625c5227336430ee36705c13ae06e2Wei Huang ? extraSelection : extraSelection + " AND " + selection; 13011ecf192c60625c5227336430ee36705c13ae06e2Wei Huang 13021ecf192c60625c5227336430ee36705c13ae06e2Wei Huang affectedRows = db.update(TABLE_CANONICAL_ADDRESSES, values, finalSelection, null); 13031ecf192c60625c5227336430ee36705c13ae06e2Wei Huang break; 13041ecf192c60625c5227336430ee36705c13ae06e2Wei Huang } 13051ecf192c60625c5227336430ee36705c13ae06e2Wei Huang 130682fc72b94a54eb3c70bcfbb1effd9b3a9b775af9Ye Wen case URI_CONVERSATIONS: { 130782fc72b94a54eb3c70bcfbb1effd9b3a9b775af9Ye Wen final ContentValues finalValues = new ContentValues(1); 130882fc72b94a54eb3c70bcfbb1effd9b3a9b775af9Ye Wen if (values.containsKey(Threads.ARCHIVED)) { 130982fc72b94a54eb3c70bcfbb1effd9b3a9b775af9Ye Wen // Only allow update archived 131082fc72b94a54eb3c70bcfbb1effd9b3a9b775af9Ye Wen finalValues.put(Threads.ARCHIVED, values.getAsBoolean(Threads.ARCHIVED)); 131182fc72b94a54eb3c70bcfbb1effd9b3a9b775af9Ye Wen } 131282fc72b94a54eb3c70bcfbb1effd9b3a9b775af9Ye Wen affectedRows = db.update(TABLE_THREADS, finalValues, selection, selectionArgs); 131382fc72b94a54eb3c70bcfbb1effd9b3a9b775af9Ye Wen break; 131482fc72b94a54eb3c70bcfbb1effd9b3a9b775af9Ye Wen } 131582fc72b94a54eb3c70bcfbb1effd9b3a9b775af9Ye Wen 13167236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project default: 13177236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project throw new UnsupportedOperationException( 1318b91bcae9fa009787f165591fd7fc4c8f2f2dfd99Tom Taylor NO_DELETES_INSERTS_OR_UPDATES + uri); 13197236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 13207236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 13217236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (affectedRows > 0) { 13227236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project getContext().getContentResolver().notifyChange( 132343f9fb234aabe569b342af78bdaf85effbd85f10Amith Yamasani MmsSms.CONTENT_URI, null, true, UserHandle.USER_ALL); 13247236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 13257236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return affectedRows; 13267236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 13277236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 132872f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen private int updateConversation(String threadIdString, ContentValues values, String selection, 132972f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String[] selectionArgs, int callerUid, String callerPkg) { 13307236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project try { 13317236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Long.parseLong(threadIdString); 13327236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } catch (NumberFormatException exception) { 13337236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Log.e(LOG_TAG, "Thread ID must be a Long."); 13347236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return 0; 1335e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wen 1336e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wen } 1337e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wen if (ProviderUtil.shouldRemoveCreator(values, callerUid)) { 1338e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wen // CREATOR should not be changed by non-SYSTEM/PHONE apps 133972f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen Log.w(LOG_TAG, callerPkg + " tries to update CREATOR"); 1340e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wen // Sms.CREATOR and Mms.CREATOR are same. But let's do this 1341e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wen // twice in case the names may differ in the future 1342e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wen values.remove(Sms.CREATOR); 1343e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wen values.remove(Mms.CREATOR); 13447236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 13457236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 13467236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 13477236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String finalSelection = concatSelections(selection, "thread_id=" + threadIdString); 13487236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return db.update(MmsProvider.TABLE_PDU, values, finalSelection, selectionArgs) 13497236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project + db.update("sms", values, finalSelection, selectionArgs); 13507236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 13517236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 13527236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 13537236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Construct Sets of Strings containing exactly the columns 13547236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * present in each table. We will use this when constructing 13557236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * UNION queries across the MMS and SMS tables. 13567236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 13577236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static void initializeColumnSets() { 13587236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project int commonColumnCount = MMS_SMS_COLUMNS.length; 13597236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project int mmsOnlyColumnCount = MMS_ONLY_COLUMNS.length; 13607236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project int smsOnlyColumnCount = SMS_ONLY_COLUMNS.length; 13617236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Set<String> unionColumns = new HashSet<String>(); 13627236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 13637236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project for (int i = 0; i < commonColumnCount; i++) { 13647236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MMS_COLUMNS.add(MMS_SMS_COLUMNS[i]); 13657236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SMS_COLUMNS.add(MMS_SMS_COLUMNS[i]); 13667236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project unionColumns.add(MMS_SMS_COLUMNS[i]); 13677236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 13687236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project for (int i = 0; i < mmsOnlyColumnCount; i++) { 13697236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MMS_COLUMNS.add(MMS_ONLY_COLUMNS[i]); 13707236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project unionColumns.add(MMS_ONLY_COLUMNS[i]); 13717236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 13727236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project for (int i = 0; i < smsOnlyColumnCount; i++) { 13737236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SMS_COLUMNS.add(SMS_ONLY_COLUMNS[i]); 13747236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project unionColumns.add(SMS_ONLY_COLUMNS[i]); 13757236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 13767236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 13777236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project int i = 0; 13787236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project for (String columnName : unionColumns) { 13797236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project UNION_COLUMNS[i++] = columnName; 13807236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 13817236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 138286b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wen 138386b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wen @Override 138486b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wen public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 138586b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wen // Dump default SMS app 138686b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wen String defaultSmsApp = Telephony.Sms.getDefaultSmsPackage(getContext()); 138786b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wen if (TextUtils.isEmpty(defaultSmsApp)) { 138886b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wen defaultSmsApp = "None"; 138986b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wen } 139086b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wen writer.println("Default SMS app: " + defaultSmsApp); 139186b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wen } 13927236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project} 1393