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; 31785f9214b0da4bacf4c78ae90f08c535ab04c5a5Tom Taylorimport android.os.Bundle; 3243f9fb234aabe569b342af78bdaf85effbd85f10Amith Yamasaniimport android.os.UserHandle; 337236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.provider.BaseColumns; 3486b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wenimport android.provider.Telephony; 357236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.provider.Telephony.CanonicalAddressesColumns; 367236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.provider.Telephony.Mms; 377236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.provider.Telephony.MmsSms; 38e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wenimport android.provider.Telephony.MmsSms.PendingMessages; 397236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.provider.Telephony.Sms; 40e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wenimport android.provider.Telephony.Sms.Conversations; 417236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.provider.Telephony.Threads; 427236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.provider.Telephony.ThreadsColumns; 437236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.text.TextUtils; 447236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectimport android.util.Log; 457236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 46b1bae65bf18dc22762cf7b8210fdad836b3e4ee5Tom Taylorimport com.google.android.mms.pdu.PduHeaders; 477236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 4886b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wenimport java.io.FileDescriptor; 4986b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wenimport java.io.PrintWriter; 50e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wenimport java.util.Arrays; 51e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wenimport java.util.HashSet; 52e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wenimport java.util.List; 53e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wenimport java.util.Set; 54e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wen 557236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project/** 567236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * This class provides the ability to query the MMS and SMS databases 577236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * at the same time, mixing messages from both in a single thread 587236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * (A.K.A. conversation). 597236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * 607236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * A virtual column, MmsSms.TYPE_DISCRIMINATOR_COLUMN, may be 617236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * requested in the projection for a query. Its value is either "mms" 627236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * or "sms", depending on whether the message represented by the row 637236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * is an MMS message or an SMS message, respectively. 647236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * 657236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * This class also provides the ability to find out what addresses 667236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * participated in a particular thread. It doesn't support updates 677236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * for either of these. 687236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * 697236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * This class provides a way to allocate and retrieve thread IDs. 707236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * This is done atomically through a query. There is no insert URI 717236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * for this. 727236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * 737236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Finally, this class provides a way to delete or update all messages 747236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * in a thread. 757236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 767236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Projectpublic class MmsSmsProvider extends ContentProvider { 777236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final UriMatcher URI_MATCHER = 787236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project new UriMatcher(UriMatcher.NO_MATCH); 797236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String LOG_TAG = "MmsSmsProvider"; 80816e934a43bf705835bdb24503a85a14c4861991Tom Taylor private static final boolean DEBUG = false; 817236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 827236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String NO_DELETES_INSERTS_OR_UPDATES = 837236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project "MmsSmsProvider does not support deletes, inserts, or updates for this URI."; 84f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_CONVERSATIONS = 0; 85f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_CONVERSATIONS_MESSAGES = 1; 86f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_CONVERSATIONS_RECIPIENTS = 2; 87f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_MESSAGES_BY_PHONE = 3; 88f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_THREAD_ID = 4; 89f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_CANONICAL_ADDRESS = 5; 90f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_PENDING_MSG = 6; 91f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_COMPLETE_CONVERSATIONS = 7; 92f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_UNDELIVERED_MSG = 8; 93f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_CONVERSATIONS_SUBJECT = 9; 94f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_NOTIFICATIONS = 10; 95f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_OBSOLETE_THREADS = 11; 96f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_DRAFT = 12; 97f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_CANONICAL_ADDRESSES = 13; 98f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private static final int URI_SEARCH = 14; 998e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner private static final int URI_SEARCH_SUGGEST = 15; 1008e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner private static final int URI_FIRST_LOCKED_MESSAGE_ALL = 16; 1018e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner private static final int URI_FIRST_LOCKED_MESSAGE_BY_THREAD_ID = 17; 1026a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner private static final int URI_MESSAGE_ID_TO_THREAD = 18; 1037236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1047236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 1057236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * the name of the table that is used to store the queue of 1067236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * messages(both MMS and SMS) to be sent/downloaded. 1077236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 1087236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project public static final String TABLE_PENDING_MSG = "pending_msgs"; 1097236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1101ecf192c60625c5227336430ee36705c13ae06e2Wei Huang /** 1111ecf192c60625c5227336430ee36705c13ae06e2Wei Huang * the name of the table that is used to store the canonical addresses for both SMS and MMS. 1121ecf192c60625c5227336430ee36705c13ae06e2Wei Huang */ 1131ecf192c60625c5227336430ee36705c13ae06e2Wei Huang private static final String TABLE_CANONICAL_ADDRESSES = "canonical_addresses"; 1141ecf192c60625c5227336430ee36705c13ae06e2Wei Huang 11515156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor /** 11615156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor * the name of the table that is used to store the conversation threads. 11715156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor */ 11815156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor static final String TABLE_THREADS = "threads"; 11915156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor 1207236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // These constants are used to construct union queries across the 1217236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // MMS and SMS base tables. 1227236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1237236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // These are the columns that appear in both the MMS ("pdu") and 1247236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // SMS ("sms") message tables. 1257236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String[] MMS_SMS_COLUMNS = 126cfb8bbdc3932473966d043fbd72b6c067933f2c1Ye Wen { BaseColumns._ID, Mms.DATE, Mms.DATE_SENT, Mms.READ, Mms.THREAD_ID, Mms.LOCKED, 12772b147363200ff3f0bc467f23579042bd800ff13Wink Saville Mms.SUBSCRIPTION_ID }; 1287236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1297236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // These are the columns that appear only in the MMS message 1307236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // table. 1317236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String[] MMS_ONLY_COLUMNS = { 1327236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Mms.CONTENT_CLASS, Mms.CONTENT_LOCATION, Mms.CONTENT_TYPE, 1337236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Mms.DELIVERY_REPORT, Mms.EXPIRY, Mms.MESSAGE_CLASS, Mms.MESSAGE_ID, 1347236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Mms.MESSAGE_SIZE, Mms.MESSAGE_TYPE, Mms.MESSAGE_BOX, Mms.PRIORITY, 1357236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Mms.READ_STATUS, Mms.RESPONSE_STATUS, Mms.RESPONSE_TEXT, 1367236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Mms.RETRIEVE_STATUS, Mms.RETRIEVE_TEXT_CHARSET, Mms.REPORT_ALLOWED, 1377236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Mms.READ_REPORT, Mms.STATUS, Mms.SUBJECT, Mms.SUBJECT_CHARSET, 138f88d1d6733158144e9e0c87f29b446068edf0507Tom Taylor Mms.TRANSACTION_ID, Mms.MMS_VERSION, Mms.TEXT_ONLY }; 1397236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1407236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // These are the columns that appear only in the SMS message 1417236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // table. 1427236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String[] SMS_ONLY_COLUMNS = 1437236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project { "address", "body", "person", "reply_path_present", 144ddf267c20a697f66b8238538fb6ad31507724692Tom Taylor "service_center", "status", "subject", "type", "error_code" }; 1457236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1467236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // These are all the columns that appear in the "threads" table. 1477236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String[] THREADS_COLUMNS = { 1487236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project BaseColumns._ID, 1497236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project ThreadsColumns.DATE, 1507236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project ThreadsColumns.RECIPIENT_IDS, 1517236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project ThreadsColumns.MESSAGE_COUNT 1527236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project }; 1537236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1541ecf192c60625c5227336430ee36705c13ae06e2Wei Huang private static final String[] CANONICAL_ADDRESSES_COLUMNS_1 = 1551ecf192c60625c5227336430ee36705c13ae06e2Wei Huang new String[] { CanonicalAddressesColumns.ADDRESS }; 1561ecf192c60625c5227336430ee36705c13ae06e2Wei Huang 1571ecf192c60625c5227336430ee36705c13ae06e2Wei Huang private static final String[] CANONICAL_ADDRESSES_COLUMNS_2 = 1581ecf192c60625c5227336430ee36705c13ae06e2Wei Huang new String[] { CanonicalAddressesColumns._ID, 1591ecf192c60625c5227336430ee36705c13ae06e2Wei Huang CanonicalAddressesColumns.ADDRESS }; 1601ecf192c60625c5227336430ee36705c13ae06e2Wei Huang 1617236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // These are all the columns that appear in the MMS and SMS 1627236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // message tables. 1637236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String[] UNION_COLUMNS = 1647236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project new String[MMS_SMS_COLUMNS.length 1657236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project + MMS_ONLY_COLUMNS.length 1667236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project + SMS_ONLY_COLUMNS.length]; 1677236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1687236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // These are all the columns that appear in the MMS table. 1697236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final Set<String> MMS_COLUMNS = new HashSet<String>(); 1707236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1717236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // These are all the columns that appear in the SMS table. 1727236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final Set<String> SMS_COLUMNS = new HashSet<String>(); 1737236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1747236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String VND_ANDROID_DIR_MMS_SMS = 1757236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project "vnd.android-dir/mms-sms"; 1767236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1777236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String[] ID_PROJECTION = { BaseColumns._ID }; 1787236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1797236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String[] EMPTY_STRING_ARRAY = new String[0]; 1807236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1813e1cba826743423642635cc7b03abe292470f4c4Tom Taylor private static final String[] SEARCH_STRING = new String[1]; 1823e1cba826743423642635cc7b03abe292470f4c4Tom Taylor private static final String SEARCH_QUERY = "SELECT snippet(words, '', ' ', '', 1, 1) as " + 1833e1cba826743423642635cc7b03abe292470f4c4Tom Taylor "snippet FROM words WHERE index_text MATCH ? ORDER BY snippet LIMIT 50;"; 1843e1cba826743423642635cc7b03abe292470f4c4Tom Taylor 1857236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String SMS_CONVERSATION_CONSTRAINT = "(" + 1867236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Sms.TYPE + " != " + Sms.MESSAGE_TYPE_DRAFT + ")"; 1877236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 1887236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String MMS_CONVERSATION_CONSTRAINT = "(" + 1897236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Mms.MESSAGE_BOX + " != " + Mms.MESSAGE_BOX_DRAFTS + " AND (" + 1907236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Mms.MESSAGE_TYPE + " = " + PduHeaders.MESSAGE_TYPE_SEND_REQ + " OR " + 1917236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Mms.MESSAGE_TYPE + " = " + PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF + " OR " + 1927236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Mms.MESSAGE_TYPE + " = " + PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND + "))"; 1937236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 19472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen private static String getTextSearchQuery(String smsTable, String pduTable) { 19572f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen // Search on the words table but return the rows from the corresponding sms table 19672f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen final String smsQuery = "SELECT " 19772f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + smsTable + "._id AS _id," 19872f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "thread_id," 19972f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "address," 20072f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "body," 20172f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "date," 20272f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "date_sent," 20372f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "index_text," 20472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "words._id " 20572f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "FROM " + smsTable + ",words " 20672f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "WHERE (index_text MATCH ? " 20772f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "AND " + smsTable + "._id=words.source_id " 20872f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "AND words.table_to_use=1)"; 20972f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen 21072f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen // Search on the words table but return the rows from the corresponding parts table 21172f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen final String mmsQuery = "SELECT " 21272f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + pduTable + "._id," 21372f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "thread_id," 21472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "addr.address," 21572f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "part.text AS body," 21672f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + pduTable + ".date," 21772f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + pduTable + ".date_sent," 21872f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "index_text," 21972f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "words._id " 22072f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "FROM " + pduTable + ",part,addr,words " 22172f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "WHERE ((part.mid=" + pduTable + "._id) " 22272f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "AND (addr.msg_id=" + pduTable + "._id) " 22372f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "AND (addr.type=" + PduHeaders.TO + ") " 22472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "AND (part.ct='text/plain') " 22572f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "AND (index_text MATCH ?) " 22672f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "AND (part._id = words.source_id) " 22772f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "AND (words.table_to_use=2))"; 22872f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen 22972f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen // This code queries the sms and mms tables and returns a unified result set 23072f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen // of text matches. We query the sms table which is pretty simple. We also 23172f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen // query the pdu, part and addr table to get the mms result. Note we're 23272f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen // using a UNION so we have to have the same number of result columns from 23372f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen // both queries. 23472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen return smsQuery + " UNION " + mmsQuery + " " 23572f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "GROUP BY thread_id " 23672f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "ORDER BY thread_id ASC, date DESC"; 23772f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen } 23801c75ba95b875674a83128defc6b267e522db346Chen Mike 2397236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static final String AUTHORITY = "mms-sms"; 2407236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 2417236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project static { 2427236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI(AUTHORITY, "conversations", URI_CONVERSATIONS); 2437236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI(AUTHORITY, "complete-conversations", URI_COMPLETE_CONVERSATIONS); 2447236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 2457236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // In these patterns, "#" is the thread ID. 2467236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI( 2477236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project AUTHORITY, "conversations/#", URI_CONVERSATIONS_MESSAGES); 2487236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI( 2497236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project AUTHORITY, "conversations/#/recipients", 2507236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_CONVERSATIONS_RECIPIENTS); 2517236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 2527236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI( 2537236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project AUTHORITY, "conversations/#/subject", 2547236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_CONVERSATIONS_SUBJECT); 2557236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 2567236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // URI for deleting obsolete threads. 2577236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI(AUTHORITY, "conversations/obsolete", URI_OBSOLETE_THREADS); 2587236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 2597236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI( 2607236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project AUTHORITY, "messages/byphone/*", 2617236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MESSAGES_BY_PHONE); 2627236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 2637236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // In this pattern, two query parameter names are expected: 2647236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // "subject" and "recipient." Multiple "recipient" parameters 2657236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // may be present. 2667236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI(AUTHORITY, "threadID", URI_THREAD_ID); 2677236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 2687236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // Use this pattern to query the canonical address by given ID. 2697236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI(AUTHORITY, "canonical-address/#", URI_CANONICAL_ADDRESS); 2707236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 27137e4424493bb364eac8ae07c3d5fce52bebf735dFicus Kirkpatrick // Use this pattern to query all canonical addresses. 27237e4424493bb364eac8ae07c3d5fce52bebf735dFicus Kirkpatrick URI_MATCHER.addURI(AUTHORITY, "canonical-addresses", URI_CANONICAL_ADDRESSES); 273f0a9e90721310bed023a9ff1f176f1b5e05a14f7Mark Wagner 27466d373c4797c53207e8f1ea97f3dc5541f390152Mark Wagner URI_MATCHER.addURI(AUTHORITY, "search", URI_SEARCH); 2758e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner URI_MATCHER.addURI(AUTHORITY, "searchSuggest", URI_SEARCH_SUGGEST); 27637e4424493bb364eac8ae07c3d5fce52bebf735dFicus Kirkpatrick 2777236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // In this pattern, two query parameters may be supplied: 2787236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // "protocol" and "message." For example: 2797236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // content://mms-sms/pending? 2807236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // -> Return all pending messages; 2817236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // content://mms-sms/pending?protocol=sms 2827236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // -> Only return pending SMs; 2837236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // content://mms-sms/pending?protocol=mms&message=1 2847236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // -> Return the the pending MM which ID equals '1'. 2857236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // 2867236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI(AUTHORITY, "pending", URI_PENDING_MSG); 2877236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 2887236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // Use this pattern to get a list of undelivered messages. 2897236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI(AUTHORITY, "undelivered", URI_UNDELIVERED_MSG); 2907236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 2917236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // Use this pattern to see what delivery status reports (for 2927236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project // both MMS and SMS) have not been delivered to the user. 2937236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI(AUTHORITY, "notifications", URI_NOTIFICATIONS); 2947236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 2957236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project URI_MATCHER.addURI(AUTHORITY, "draft", URI_DRAFT); 296f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor 297f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor URI_MATCHER.addURI(AUTHORITY, "locked", URI_FIRST_LOCKED_MESSAGE_ALL); 298f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor 299f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor URI_MATCHER.addURI(AUTHORITY, "locked/#", URI_FIRST_LOCKED_MESSAGE_BY_THREAD_ID); 300f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor 3016a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner URI_MATCHER.addURI(AUTHORITY, "messageIdToThread", URI_MESSAGE_ID_TO_THREAD); 3027236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project initializeColumnSets(); 3037236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 3047236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 3057236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private SQLiteOpenHelper mOpenHelper; 3067236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 307845a9163dffcbd1073930b8b334df27728418201Daisuke Miyakawa private boolean mUseStrictPhoneNumberComparation; 308845a9163dffcbd1073930b8b334df27728418201Daisuke Miyakawa 309785f9214b0da4bacf4c78ae90f08c535ab04c5a5Tom Taylor private static final String METHOD_IS_RESTORING = "is_restoring"; 310785f9214b0da4bacf4c78ae90f08c535ab04c5a5Tom Taylor private static final String IS_RESTORING_KEY = "restoring"; 311785f9214b0da4bacf4c78ae90f08c535ab04c5a5Tom Taylor 3127236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project @Override 3137236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project public boolean onCreate() { 314b2ce2d37bc6efc0c37d8cee925d3ad65a01ea4bfYe Wen setAppOps(AppOpsManager.OP_READ_SMS, AppOpsManager.OP_WRITE_SMS); 3155a3194d943854ec3c2ec5df18a95a5b04ab5efa1Ji Yang mOpenHelper = MmsSmsDatabaseHelper.getInstanceForCe(getContext()); 316845a9163dffcbd1073930b8b334df27728418201Daisuke Miyakawa mUseStrictPhoneNumberComparation = 317845a9163dffcbd1073930b8b334df27728418201Daisuke Miyakawa getContext().getResources().getBoolean( 318845a9163dffcbd1073930b8b334df27728418201Daisuke Miyakawa com.android.internal.R.bool.config_use_strict_phone_number_comparation); 3192d3a779b41d5a553c8615a906ee97da29907313eRoman Sorokin TelephonyBackupAgent.DeferredSmsMmsRestoreService.startIfFilesExist(getContext()); 3207236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return true; 3217236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 3227236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 3237236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project @Override 3247236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project public Cursor query(Uri uri, String[] projection, 3257236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String selection, String[] selectionArgs, String sortOrder) { 32672f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen // First check if restricted views of the "sms" and "pdu" tables should be used based on the 32772f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen // caller's identity. Only system, phone or the default sms app can have full access 32872f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen // of sms/mms data. For other apps, we present a restricted view which only contains sent 32972f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen // or received messages, without wap pushes. 33072f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen final boolean accessRestricted = ProviderUtil.isAccessRestricted( 33172f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen getContext(), getCallingPackage(), Binder.getCallingUid()); 33272f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen final String pduTable = MmsProvider.getPduTable(accessRestricted); 33372f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen final String smsTable = SmsProvider.getSmsTable(accessRestricted); 33472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen 3357236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 3367236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Cursor cursor = null; 33772f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen final int match = URI_MATCHER.match(uri); 33872f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen switch (match) { 3397236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_COMPLETE_CONVERSATIONS: 34072f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen cursor = getCompleteConversations(projection, selection, sortOrder, smsTable, 34172f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen pduTable); 3427236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 3437236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_CONVERSATIONS: 3447236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String simple = uri.getQueryParameter("simple"); 3457236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if ((simple != null) && simple.equals("true")) { 3467236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String threadType = uri.getQueryParameter("thread_type"); 3477236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (!TextUtils.isEmpty(threadType)) { 3487236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selection = concatSelections( 3497236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selection, Threads.TYPE + "=" + threadType); 3507236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 3517236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project cursor = getSimpleConversations( 3527236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project projection, selection, selectionArgs, sortOrder); 3537236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } else { 3547236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project cursor = getConversations( 35572f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen projection, selection, sortOrder, smsTable, pduTable); 3567236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 3577236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 3587236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_CONVERSATIONS_MESSAGES: 359f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor cursor = getConversationMessages(uri.getPathSegments().get(1), projection, 36072f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen selection, sortOrder, smsTable, pduTable); 3617236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 3627236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_CONVERSATIONS_RECIPIENTS: 3637236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project cursor = getConversationById( 3647236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project uri.getPathSegments().get(1), projection, selection, 3657236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selectionArgs, sortOrder); 3667236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 3677236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_CONVERSATIONS_SUBJECT: 3687236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project cursor = getConversationById( 3697236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project uri.getPathSegments().get(1), projection, selection, 3707236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selectionArgs, sortOrder); 3717236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 3727236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_MESSAGES_BY_PHONE: 3737236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project cursor = getMessagesByPhoneNumber( 37472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen uri.getPathSegments().get(2), projection, selection, sortOrder, smsTable, 37572f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen pduTable); 3767236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 3777236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_THREAD_ID: 3787236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project List<String> recipients = uri.getQueryParameters("recipient"); 3797236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 3807236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project cursor = getThreadId(recipients); 3817236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 3827236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_CANONICAL_ADDRESS: { 3837236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String extraSelection = "_id=" + uri.getPathSegments().get(1); 3847236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String finalSelection = TextUtils.isEmpty(selection) 3857236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project ? extraSelection : extraSelection + " AND " + selection; 3861ecf192c60625c5227336430ee36705c13ae06e2Wei Huang cursor = db.query(TABLE_CANONICAL_ADDRESSES, 3871ecf192c60625c5227336430ee36705c13ae06e2Wei Huang CANONICAL_ADDRESSES_COLUMNS_1, 3881ecf192c60625c5227336430ee36705c13ae06e2Wei Huang finalSelection, 3891ecf192c60625c5227336430ee36705c13ae06e2Wei Huang selectionArgs, 3901ecf192c60625c5227336430ee36705c13ae06e2Wei Huang null, null, 3911ecf192c60625c5227336430ee36705c13ae06e2Wei Huang sortOrder); 3927236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 3937236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 39437e4424493bb364eac8ae07c3d5fce52bebf735dFicus Kirkpatrick case URI_CANONICAL_ADDRESSES: 3951ecf192c60625c5227336430ee36705c13ae06e2Wei Huang cursor = db.query(TABLE_CANONICAL_ADDRESSES, 3961ecf192c60625c5227336430ee36705c13ae06e2Wei Huang CANONICAL_ADDRESSES_COLUMNS_2, 3971ecf192c60625c5227336430ee36705c13ae06e2Wei Huang selection, 3981ecf192c60625c5227336430ee36705c13ae06e2Wei Huang selectionArgs, 3991ecf192c60625c5227336430ee36705c13ae06e2Wei Huang null, null, 4001ecf192c60625c5227336430ee36705c13ae06e2Wei Huang sortOrder); 40137e4424493bb364eac8ae07c3d5fce52bebf735dFicus Kirkpatrick break; 4028e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner case URI_SEARCH_SUGGEST: { 4033e1cba826743423642635cc7b03abe292470f4c4Tom Taylor SEARCH_STRING[0] = uri.getQueryParameter("pattern") + '*' ; 4049e1fd44679b2de6df6af2c1e8b6bf191e799f4a9Mark Wagner 4059e1fd44679b2de6df6af2c1e8b6bf191e799f4a9Mark Wagner // find the words which match the pattern using the snippet function. The 4069e1fd44679b2de6df6af2c1e8b6bf191e799f4a9Mark Wagner // snippet function parameters mainly describe how to format the result. 4079e1fd44679b2de6df6af2c1e8b6bf191e799f4a9Mark Wagner // See http://www.sqlite.org/fts3.html#section_4_2 for details. 4088e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner if ( sortOrder != null 4098e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner || selection != null 4108e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner || selectionArgs != null 4118e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner || projection != null) { 4128e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner throw new IllegalArgumentException( 4138e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner "do not specify sortOrder, selection, selectionArgs, or projection" + 4148e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner "with this query"); 4158e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner } 4168e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner 4173e1cba826743423642635cc7b03abe292470f4c4Tom Taylor cursor = db.rawQuery(SEARCH_QUERY, SEARCH_STRING); 4188e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner break; 4198e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner } 4206a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner case URI_MESSAGE_ID_TO_THREAD: { 4216a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner // Given a message ID and an indicator for SMS vs. MMS return 4226a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner // the thread id of the corresponding thread. 4236a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner try { 4246a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner long id = Long.parseLong(uri.getQueryParameter("row_id")); 4256a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner switch (Integer.parseInt(uri.getQueryParameter("table_to_use"))) { 4266a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner case 1: // sms 4276a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner cursor = db.query( 42872f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen smsTable, 4296a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner new String[] { "thread_id" }, 4306a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner "_id=?", 4316a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner new String[] { String.valueOf(id) }, 4326a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner null, 4336a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner null, 4346a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner null); 4356a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner break; 4366a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner case 2: // mms 43772f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String mmsQuery = "SELECT thread_id " 43872f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "FROM " + pduTable + ",part " 43972f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "WHERE ((part.mid=" + pduTable + "._id) " 44072f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + "AND " + "(part._id=?))"; 4416a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner cursor = db.rawQuery(mmsQuery, new String[] { String.valueOf(id) }); 4426a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner break; 4436a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner } 4446a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner } catch (NumberFormatException ex) { 4456a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner // ignore... return empty cursor 4466a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner } 4476a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner break; 4486a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner } 4498e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner case URI_SEARCH: { 45087bfe142b5c163e19fb9e60d558bbeb513ca150cTom Taylor if ( sortOrder != null 45187bfe142b5c163e19fb9e60d558bbeb513ca150cTom Taylor || selection != null 45287bfe142b5c163e19fb9e60d558bbeb513ca150cTom Taylor || selectionArgs != null 453f0a9e90721310bed023a9ff1f176f1b5e05a14f7Mark Wagner || projection != null) { 454f0a9e90721310bed023a9ff1f176f1b5e05a14f7Mark Wagner throw new IllegalArgumentException( 455f0a9e90721310bed023a9ff1f176f1b5e05a14f7Mark Wagner "do not specify sortOrder, selection, selectionArgs, or projection" + 456f0a9e90721310bed023a9ff1f176f1b5e05a14f7Mark Wagner "with this query"); 45766d373c4797c53207e8f1ea97f3dc5541f390152Mark Wagner } 45887bfe142b5c163e19fb9e60d558bbeb513ca150cTom Taylor 4598e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner String searchString = uri.getQueryParameter("pattern") + "*"; 4608e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner 4618e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner try { 46272f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen cursor = db.rawQuery(getTextSearchQuery(smsTable, pduTable), 46372f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen new String[] { searchString, searchString }); 4648e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner } catch (Exception ex) { 4658e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner Log.e(LOG_TAG, "got exception: " + ex.toString()); 4668e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner } 46766d373c4797c53207e8f1ea97f3dc5541f390152Mark Wagner break; 4688e5ee782690175e9cfb9a37f600f207b952ba8a6Mark Wagner } 4697236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_PENDING_MSG: { 4707236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String protoName = uri.getQueryParameter("protocol"); 4717236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String msgId = uri.getQueryParameter("message"); 4727236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project int proto = TextUtils.isEmpty(protoName) ? -1 4737236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project : (protoName.equals("sms") ? MmsSms.SMS_PROTO : MmsSms.MMS_PROTO); 4747236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 4757236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String extraSelection = (proto != -1) ? 4767236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project (PendingMessages.PROTO_TYPE + "=" + proto) : " 0=0 "; 4777236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (!TextUtils.isEmpty(msgId)) { 4787236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project extraSelection += " AND " + PendingMessages.MSG_ID + "=" + msgId; 4797236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 4807236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 4817236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String finalSelection = TextUtils.isEmpty(selection) 4827236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project ? extraSelection : ("(" + extraSelection + ") AND " + selection); 4837236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String finalOrder = TextUtils.isEmpty(sortOrder) 4847236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project ? PendingMessages.DUE_TIME : sortOrder; 4857236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project cursor = db.query(TABLE_PENDING_MSG, null, 4867236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project finalSelection, selectionArgs, null, null, finalOrder); 4877236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 4887236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 4897236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_UNDELIVERED_MSG: { 4907236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project cursor = getUndeliveredMessages(projection, selection, 49172f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen selectionArgs, sortOrder, smsTable, pduTable); 4927236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 4937236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 4947236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_DRAFT: { 49572f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen cursor = getDraftThread(projection, selection, sortOrder, smsTable, pduTable); 4967236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 4977236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 498f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor case URI_FIRST_LOCKED_MESSAGE_BY_THREAD_ID: { 499f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor long threadId; 500f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor try { 501f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor threadId = Long.parseLong(uri.getLastPathSegment()); 502f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor } catch (NumberFormatException e) { 503f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor Log.e(LOG_TAG, "Thread ID must be a long."); 504f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor break; 505f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor } 506f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor cursor = getFirstLockedMessage(projection, "thread_id=" + Long.toString(threadId), 50772f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen sortOrder, smsTable, pduTable); 508f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor break; 509f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor } 510f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor case URI_FIRST_LOCKED_MESSAGE_ALL: { 51172f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen cursor = getFirstLockedMessage( 51272f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen projection, selection, sortOrder, smsTable, pduTable); 513f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor break; 514f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor } 5157236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project default: 5167236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project throw new IllegalStateException("Unrecognized URI:" + uri); 5177236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 5187236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 5195926996da70fff9275e948d1cf8a0f17b52a5e14Tom Taylor if (cursor != null) { 5205926996da70fff9275e948d1cf8a0f17b52a5e14Tom Taylor cursor.setNotificationUri(getContext().getContentResolver(), MmsSms.CONTENT_URI); 5215926996da70fff9275e948d1cf8a0f17b52a5e14Tom Taylor } 5227236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return cursor; 5237236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 5247236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 5257236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 5267236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Return the canonical address ID for this address. 5277236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 5287236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private long getSingleAddressId(String address) { 5297236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project boolean isEmail = Mms.isEmailAddress(address); 530e8a24ddaa58295f173fbf37fe3c0acb0d8569118Tom Taylor boolean isPhoneNumber = Mms.isPhoneNumber(address); 531e8a24ddaa58295f173fbf37fe3c0acb0d8569118Tom Taylor 532e8a24ddaa58295f173fbf37fe3c0acb0d8569118Tom Taylor // We lowercase all email addresses, but not addresses that aren't numbers, because 533e8a24ddaa58295f173fbf37fe3c0acb0d8569118Tom Taylor // that would incorrectly turn an address such as "My Vodafone" into "my vodafone" 534e8a24ddaa58295f173fbf37fe3c0acb0d8569118Tom Taylor // and the thread title would be incorrect when displayed in the UI. 5357236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String refinedAddress = isEmail ? address.toLowerCase() : address; 536e8a24ddaa58295f173fbf37fe3c0acb0d8569118Tom Taylor 537c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang String selection = "address=?"; 538c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang String[] selectionArgs; 53914595cbe9045755a5aa2bd28989c147c4709268cWei Huang long retVal = -1L; 540c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang 541e8a24ddaa58295f173fbf37fe3c0acb0d8569118Tom Taylor if (!isPhoneNumber) { 542c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang selectionArgs = new String[] { refinedAddress }; 543c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang } else { 54401c75ba95b875674a83128defc6b267e522db346Chen Mike selection += " OR PHONE_NUMBERS_EQUAL(address, ?, " + 54501c75ba95b875674a83128defc6b267e522db346Chen Mike (mUseStrictPhoneNumberComparation ? 1 : 0) + ")"; 546c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang selectionArgs = new String[] { refinedAddress, refinedAddress }; 547c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang } 548c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang 5497236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Cursor cursor = null; 5507236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 5517236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project try { 5527236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 5537236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project cursor = db.query( 5547236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project "canonical_addresses", ID_PROJECTION, 5557236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selection, selectionArgs, null, null, null); 5567236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 5577236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (cursor.getCount() == 0) { 5587236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project ContentValues contentValues = new ContentValues(1); 5597236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project contentValues.put(CanonicalAddressesColumns.ADDRESS, refinedAddress); 5607236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 5617236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project db = mOpenHelper.getWritableDatabase(); 56214595cbe9045755a5aa2bd28989c147c4709268cWei Huang retVal = db.insert("canonical_addresses", 5637236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project CanonicalAddressesColumns.ADDRESS, contentValues); 56414595cbe9045755a5aa2bd28989c147c4709268cWei Huang 565ea59f86662471e682f880b4916ce7588803f5605Wink Saville Log.d(LOG_TAG, "getSingleAddressId: insert new canonical_address for " + 566ea59f86662471e682f880b4916ce7588803f5605Wink Saville /*address*/ "xxxxxx" + ", _id=" + retVal); 56714595cbe9045755a5aa2bd28989c147c4709268cWei Huang 56814595cbe9045755a5aa2bd28989c147c4709268cWei Huang return retVal; 5697236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 5707236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 5717236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (cursor.moveToFirst()) { 57214595cbe9045755a5aa2bd28989c147c4709268cWei Huang retVal = cursor.getLong(cursor.getColumnIndexOrThrow(BaseColumns._ID)); 5737236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 5747236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } finally { 5757236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (cursor != null) { 5767236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project cursor.close(); 5777236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 5787236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 5797236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 58014595cbe9045755a5aa2bd28989c147c4709268cWei Huang return retVal; 5817236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 5827236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 5837236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 5847236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Return the canonical address IDs for these addresses. 5857236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 5867236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private Set<Long> getAddressIds(List<String> addresses) { 5877236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Set<Long> result = new HashSet<Long>(addresses.size()); 5887236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 5897236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project for (String address : addresses) { 5907236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (!address.equals(PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR)) { 5917236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project long id = getSingleAddressId(address); 5927236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (id != -1L) { 5937236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project result.add(id); 5947236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } else { 59514595cbe9045755a5aa2bd28989c147c4709268cWei Huang Log.e(LOG_TAG, "getAddressIds: address ID not found for " + address); 5967236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 5977236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 5987236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 5997236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return result; 6007236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 6017236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 6027236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 6037236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Return a sorted array of the given Set of Longs. 6047236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 6057236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private long[] getSortedSet(Set<Long> numbers) { 6067236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project int size = numbers.size(); 6077236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project long[] result = new long[size]; 6087236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project int i = 0; 6097236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 6107236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project for (Long number : numbers) { 6117236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project result[i++] = number; 6127236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 61314595cbe9045755a5aa2bd28989c147c4709268cWei Huang 61414595cbe9045755a5aa2bd28989c147c4709268cWei Huang if (size > 1) { 61514595cbe9045755a5aa2bd28989c147c4709268cWei Huang Arrays.sort(result); 61614595cbe9045755a5aa2bd28989c147c4709268cWei Huang } 61714595cbe9045755a5aa2bd28989c147c4709268cWei Huang 6187236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return result; 6197236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 6207236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 6217236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 6227236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Return a String of the numbers in the given array, in order, 6237236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * separated by spaces. 6247236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 6257236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private String getSpaceSeparatedNumbers(long[] numbers) { 6267236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project int size = numbers.length; 6277236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project StringBuilder buffer = new StringBuilder(); 6287236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 6297236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project for (int i = 0; i < size; i++) { 6307236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (i != 0) { 6317236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project buffer.append(' '); 6327236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 6337236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project buffer.append(numbers[i]); 6347236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 6357236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return buffer.toString(); 6367236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 6377236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 6387236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 6397236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Insert a record for a new thread. 6407236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 6417236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private void insertThread(String recipientIds, int numberOfRecipients) { 6427236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project ContentValues values = new ContentValues(4); 6437236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 6447236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project long date = System.currentTimeMillis(); 6457236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project values.put(ThreadsColumns.DATE, date - date % 1000); 6467236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project values.put(ThreadsColumns.RECIPIENT_IDS, recipientIds); 6477236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (numberOfRecipients > 1) { 6487236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project values.put(Threads.TYPE, Threads.BROADCAST_THREAD); 6497236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 6507236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project values.put(ThreadsColumns.MESSAGE_COUNT, 0); 6517236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 65215156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor long result = mOpenHelper.getWritableDatabase().insert(TABLE_THREADS, null, values); 65314595cbe9045755a5aa2bd28989c147c4709268cWei Huang Log.d(LOG_TAG, "insertThread: created new thread_id " + result + 654ea59f86662471e682f880b4916ce7588803f5605Wink Saville " for recipientIds " + /*recipientIds*/ "xxxxxxx"); 65514595cbe9045755a5aa2bd28989c147c4709268cWei Huang 65643f9fb234aabe569b342af78bdaf85effbd85f10Amith Yamasani getContext().getContentResolver().notifyChange(MmsSms.CONTENT_URI, null, true, 65743f9fb234aabe569b342af78bdaf85effbd85f10Amith Yamasani UserHandle.USER_ALL); 6587236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 6597236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 66014595cbe9045755a5aa2bd28989c147c4709268cWei Huang private static final String THREAD_QUERY = 66114595cbe9045755a5aa2bd28989c147c4709268cWei Huang "SELECT _id FROM threads " + "WHERE recipient_ids=?"; 66214595cbe9045755a5aa2bd28989c147c4709268cWei Huang 6637236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 6647236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Return the thread ID for this list of 6657236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * recipients IDs. If no thread exists with this ID, create 6667236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * one and return it. Callers should always use 6677236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Threads.getThreadId to access this information. 6687236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 6697236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private synchronized Cursor getThreadId(List<String> recipients) { 67014595cbe9045755a5aa2bd28989c147c4709268cWei Huang Set<Long> addressIds = getAddressIds(recipients); 67114595cbe9045755a5aa2bd28989c147c4709268cWei Huang String recipientIds = ""; 672c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang 6735926996da70fff9275e948d1cf8a0f17b52a5e14Tom Taylor if (addressIds.size() == 0) { 6745926996da70fff9275e948d1cf8a0f17b52a5e14Tom Taylor Log.e(LOG_TAG, "getThreadId: NO receipients specified -- NOT creating thread", 6755926996da70fff9275e948d1cf8a0f17b52a5e14Tom Taylor new Exception()); 6765926996da70fff9275e948d1cf8a0f17b52a5e14Tom Taylor return null; 6775926996da70fff9275e948d1cf8a0f17b52a5e14Tom Taylor } else if (addressIds.size() == 1) { 6785926996da70fff9275e948d1cf8a0f17b52a5e14Tom Taylor // optimize for size==1, which should be most of the cases 67914595cbe9045755a5aa2bd28989c147c4709268cWei Huang for (Long addressId : addressIds) { 68014595cbe9045755a5aa2bd28989c147c4709268cWei Huang recipientIds = Long.toString(addressId); 68114595cbe9045755a5aa2bd28989c147c4709268cWei Huang } 68214595cbe9045755a5aa2bd28989c147c4709268cWei Huang } else { 68314595cbe9045755a5aa2bd28989c147c4709268cWei Huang recipientIds = getSpaceSeparatedNumbers(getSortedSet(addressIds)); 68414595cbe9045755a5aa2bd28989c147c4709268cWei Huang } 6857236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 68614595cbe9045755a5aa2bd28989c147c4709268cWei Huang if (Log.isLoggable(LOG_TAG, Log.VERBOSE)) { 687ea59f86662471e682f880b4916ce7588803f5605Wink Saville Log.d(LOG_TAG, "getThreadId: recipientIds (selectionArgs) =" + 688ea59f86662471e682f880b4916ce7588803f5605Wink Saville /*recipientIds*/ "xxxxxxx"); 689b4ac04f7bd9d4f16ec181f368c42f89c96f83f55Tom Taylor } 69014595cbe9045755a5aa2bd28989c147c4709268cWei Huang 69114595cbe9045755a5aa2bd28989c147c4709268cWei Huang String[] selectionArgs = new String[] { recipientIds }; 69215156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor 6937236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 69415156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor db.beginTransaction(); 69515156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor Cursor cursor = null; 69615156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor try { 69715156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor // Find the thread with the given recipients 69815156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor cursor = db.rawQuery(THREAD_QUERY, selectionArgs); 6997236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 70015156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor if (cursor.getCount() == 0) { 70115156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor // No thread with those recipients exists, so create the thread. 70215156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor cursor.close(); 70314595cbe9045755a5aa2bd28989c147c4709268cWei Huang 70415156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor Log.d(LOG_TAG, "getThreadId: create new thread_id for recipients " + 70515156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor /*recipients*/ "xxxxxxxx"); 70615156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor insertThread(recipientIds, recipients.size()); 70714595cbe9045755a5aa2bd28989c147c4709268cWei Huang 70815156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor // The thread was just created, now find it and return it. 70915156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor cursor = db.rawQuery(THREAD_QUERY, selectionArgs); 71015156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor } 71115156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor db.setTransactionSuccessful(); 71215156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor } catch (Throwable ex) { 71315156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor Log.e(LOG_TAG, ex.getMessage(), ex); 71415156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor } finally { 71515156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor db.endTransaction(); 7167236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 7176a917909c55d1535f8d5a213a4dadf19bc79b1b8Mark Wagner 71815156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor if (cursor != null && cursor.getCount() > 1) { 71914595cbe9045755a5aa2bd28989c147c4709268cWei Huang Log.w(LOG_TAG, "getThreadId: why is cursorCount=" + cursor.getCount()); 72069e6ffada415d44c72d908ad9e152da51b190642Tom Taylor } 7217236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return cursor; 7227236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 7237236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 7247236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static String concatSelections(String selection1, String selection2) { 7257236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (TextUtils.isEmpty(selection1)) { 7267236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return selection2; 7277236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } else if (TextUtils.isEmpty(selection2)) { 7287236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return selection1; 7297236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } else { 7307236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return selection1 + " AND " + selection2; 7317236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 7327236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 7337236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 7347236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 7357236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * If a null projection is given, return the union of all columns 7367236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * in both the MMS and SMS messages tables. Otherwise, return the 7377236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * given projection. 7387236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 7397236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static String[] handleNullMessageProjection( 7407236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] projection) { 7417236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return projection == null ? UNION_COLUMNS : projection; 7427236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 7437236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 7447236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 7457236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * If a null projection is given, return the set of all columns in 7467236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * the threads table. Otherwise, return the given projection. 7477236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 7487236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static String[] handleNullThreadsProjection( 7497236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] projection) { 7507236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return projection == null ? THREADS_COLUMNS : projection; 7517236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 7527236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 7537236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 7547236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * If a null sort order is given, return "normalized_date ASC". 7557236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Otherwise, return the given sort order. 7567236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 7577236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static String handleNullSortOrder (String sortOrder) { 7587236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return sortOrder == null ? "normalized_date ASC" : sortOrder; 7597236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 7607236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 7617236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 7627236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Return existing threads in the database. 7637236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 7647236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private Cursor getSimpleConversations(String[] projection, String selection, 7657236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] selectionArgs, String sortOrder) { 76615156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor return mOpenHelper.getReadableDatabase().query(TABLE_THREADS, projection, 7677236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selection, selectionArgs, null, null, " date DESC"); 7687236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 7697236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 7707236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 7717236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Return the thread which has draft in both MMS and SMS. 7727236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * 7737236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Use this query: 7747236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * 7757236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * SELECT ... 7767236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * FROM (SELECT _id, thread_id, ... 7777236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * FROM pdu 7787236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * WHERE msg_box = 3 AND ... 7797236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * UNION 7807236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * SELECT _id, thread_id, ... 7817236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * FROM sms 7827236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * WHERE type = 3 AND ... 7837236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * ) 7847236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * ; 7857236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 7867236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private Cursor getDraftThread(String[] projection, String selection, 78772f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String sortOrder, String smsTable, String pduTable) { 7887236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] innerProjection = new String[] {BaseColumns._ID, Conversations.THREAD_ID}; 7897236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder(); 7907236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder(); 7917236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 79272f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen mmsQueryBuilder.setTables(pduTable); 79372f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen smsQueryBuilder.setTables(smsTable); 7947236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 7957236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery( 7967236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerProjection, 7977236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MMS_COLUMNS, 1, "mms", 7987236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project concatSelections(selection, Mms.MESSAGE_BOX + "=" + Mms.MESSAGE_BOX_DRAFTS), 799f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor null, null); 8007236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String smsSubQuery = smsQueryBuilder.buildUnionSubQuery( 8017236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerProjection, 8027236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SMS_COLUMNS, 1, "sms", 8037236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project concatSelections(selection, Sms.TYPE + "=" + Sms.MESSAGE_TYPE_DRAFT), 804f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor null, null); 8057236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder(); 8067236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8077236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project unionQueryBuilder.setDistinct(true); 8087236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8097236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String unionQuery = unionQueryBuilder.buildUnionQuery( 8107236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project new String[] { mmsSubQuery, smsSubQuery }, null, null); 8117236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8127236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder outerQueryBuilder = new SQLiteQueryBuilder(); 8137236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8147236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project outerQueryBuilder.setTables("(" + unionQuery + ")"); 8157236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8167236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String outerQuery = outerQueryBuilder.buildQuery( 817f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor projection, null, null, null, sortOrder, null); 8187236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8197236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return mOpenHelper.getReadableDatabase().rawQuery(outerQuery, EMPTY_STRING_ARRAY); 8207236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 8217236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8227236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 8237236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Return the most recent message in each conversation in both MMS 8247236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * and SMS. 8257236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * 8267236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Use this query: 8277236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * 8287236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * SELECT ... 8297236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * FROM (SELECT thread_id AS tid, date * 1000 AS normalized_date, ... 8307236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * FROM pdu 8317236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * WHERE msg_box != 3 AND ... 8327236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * GROUP BY thread_id 8337236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * HAVING date = MAX(date) 8347236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * UNION 8357236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * SELECT thread_id AS tid, date AS normalized_date, ... 8367236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * FROM sms 8377236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * WHERE ... 8387236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * GROUP BY thread_id 8397236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * HAVING date = MAX(date)) 8407236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * GROUP BY tid 8417236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * HAVING normalized_date = MAX(normalized_date); 8427236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * 8437236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * The msg_box != 3 comparisons ensure that we don't include draft 8447236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * messages. 8457236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 8467236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private Cursor getConversations(String[] projection, String selection, 84772f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String sortOrder, String smsTable, String pduTable) { 8487236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder(); 8497236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder(); 8507236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 85172f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen mmsQueryBuilder.setTables(pduTable); 85272f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen smsQueryBuilder.setTables(smsTable); 8537236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8547236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] columns = handleNullMessageProjection(projection); 8557236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] innerMmsProjection = makeProjectionWithDateAndThreadId( 8567236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project UNION_COLUMNS, 1000); 8577236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] innerSmsProjection = makeProjectionWithDateAndThreadId( 8587236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project UNION_COLUMNS, 1); 8597236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery( 8607236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerMmsProjection, 8617236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MMS_COLUMNS, 1, "mms", 862f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor concatSelections(selection, MMS_CONVERSATION_CONSTRAINT), 8637236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project "thread_id", "date = MAX(date)"); 8647236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String smsSubQuery = smsQueryBuilder.buildUnionSubQuery( 8657236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerSmsProjection, 8667236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SMS_COLUMNS, 1, "sms", 867f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor concatSelections(selection, SMS_CONVERSATION_CONSTRAINT), 8687236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project "thread_id", "date = MAX(date)"); 8697236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder(); 8707236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8717236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project unionQueryBuilder.setDistinct(true); 8727236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8737236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String unionQuery = unionQueryBuilder.buildUnionQuery( 8747236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project new String[] { mmsSubQuery, smsSubQuery }, null, null); 8757236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8767236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder outerQueryBuilder = new SQLiteQueryBuilder(); 8777236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8787236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project outerQueryBuilder.setTables("(" + unionQuery + ")"); 8797236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8807236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String outerQuery = outerQueryBuilder.buildQuery( 881f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor columns, null, "tid", 8827236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project "normalized_date = MAX(normalized_date)", sortOrder, null); 8837236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8847236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return mOpenHelper.getReadableDatabase().rawQuery(outerQuery, EMPTY_STRING_ARRAY); 8857236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 8867236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 8877236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 888f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor * Return the first locked message found in the union of MMS 889f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor * and SMS messages. 890f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor * 891f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor * Use this query: 892f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor * 893816e934a43bf705835bdb24503a85a14c4861991Tom Taylor * SELECT _id FROM pdu GROUP BY _id HAVING locked=1 UNION SELECT _id FROM sms GROUP 894816e934a43bf705835bdb24503a85a14c4861991Tom Taylor * BY _id HAVING locked=1 LIMIT 1 895f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor * 896816e934a43bf705835bdb24503a85a14c4861991Tom Taylor * We limit by 1 because we're only interested in knowing if 897f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor * there is *any* locked message, not the actual messages themselves. 898f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor */ 899f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor private Cursor getFirstLockedMessage(String[] projection, String selection, 90072f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String sortOrder, String smsTable, String pduTable) { 901f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder(); 902f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder(); 903f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor 90472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen mmsQueryBuilder.setTables(pduTable); 90572f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen smsQueryBuilder.setTables(smsTable); 906f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor 907816e934a43bf705835bdb24503a85a14c4861991Tom Taylor String[] idColumn = new String[] { BaseColumns._ID }; 908816e934a43bf705835bdb24503a85a14c4861991Tom Taylor 909f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor // NOTE: buildUnionSubQuery *ignores* selectionArgs 910f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery( 911816e934a43bf705835bdb24503a85a14c4861991Tom Taylor MmsSms.TYPE_DISCRIMINATOR_COLUMN, idColumn, 912816e934a43bf705835bdb24503a85a14c4861991Tom Taylor null, 1, "mms", 913f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor selection, 914816e934a43bf705835bdb24503a85a14c4861991Tom Taylor BaseColumns._ID, "locked=1"); 915816e934a43bf705835bdb24503a85a14c4861991Tom Taylor 916f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor String smsSubQuery = smsQueryBuilder.buildUnionSubQuery( 917816e934a43bf705835bdb24503a85a14c4861991Tom Taylor MmsSms.TYPE_DISCRIMINATOR_COLUMN, idColumn, 918816e934a43bf705835bdb24503a85a14c4861991Tom Taylor null, 1, "sms", 919f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor selection, 920816e934a43bf705835bdb24503a85a14c4861991Tom Taylor BaseColumns._ID, "locked=1"); 921816e934a43bf705835bdb24503a85a14c4861991Tom Taylor 922f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder(); 923f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor 924f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor unionQueryBuilder.setDistinct(true); 925f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor 926f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor String unionQuery = unionQueryBuilder.buildUnionQuery( 927816e934a43bf705835bdb24503a85a14c4861991Tom Taylor new String[] { mmsSubQuery, smsSubQuery }, null, "1"); 928f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor 929816e934a43bf705835bdb24503a85a14c4861991Tom Taylor Cursor cursor = mOpenHelper.getReadableDatabase().rawQuery(unionQuery, EMPTY_STRING_ARRAY); 930f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor 931f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor if (DEBUG) { 932816e934a43bf705835bdb24503a85a14c4861991Tom Taylor Log.v("MmsSmsProvider", "getFirstLockedMessage query: " + unionQuery); 933816e934a43bf705835bdb24503a85a14c4861991Tom Taylor Log.v("MmsSmsProvider", "cursor count: " + cursor.getCount()); 934f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor } 935816e934a43bf705835bdb24503a85a14c4861991Tom Taylor return cursor; 936f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor } 937f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor 938f0a7f15a4e5ef5a1d9cb5bb509cbbaac80b1297dTom Taylor /** 9397236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Return every message in each conversation in both MMS 9407236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * and SMS. 9417236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 9427236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private Cursor getCompleteConversations(String[] projection, 94372f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String selection, String sortOrder, String smsTable, String pduTable) { 94472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String unionQuery = buildConversationQuery(projection, selection, sortOrder, smsTable, 94572f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen pduTable); 9467236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 9477236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return mOpenHelper.getReadableDatabase().rawQuery(unionQuery, EMPTY_STRING_ARRAY); 9487236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 9497236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 9507236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 9517236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Add normalized date and thread_id to the list of columns for an 9527236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * inner projection. This is necessary so that the outer query 9537236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * can have access to these columns even if the caller hasn't 9547236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * requested them in the result. 9557236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 9567236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private String[] makeProjectionWithDateAndThreadId( 9577236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] projection, int dateMultiple) { 9587236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project int projectionSize = projection.length; 9597236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] result = new String[projectionSize + 2]; 9607236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 9617236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project result[0] = "thread_id AS tid"; 9627236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project result[1] = "date * " + dateMultiple + " AS normalized_date"; 9637236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project for (int i = 0; i < projectionSize; i++) { 9647236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project result[i + 2] = projection[i]; 9657236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 9667236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return result; 9677236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 9687236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 9697236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 9707236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Return the union of MMS and SMS messages for this thread ID. 9717236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 9727236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private Cursor getConversationMessages( 9737236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String threadIdString, String[] projection, String selection, 97472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String sortOrder, String smsTable, String pduTable) { 9757236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project try { 9767236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Long.parseLong(threadIdString); 9777236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } catch (NumberFormatException exception) { 9787236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Log.e(LOG_TAG, "Thread ID must be a Long."); 9797236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return null; 9807236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 9817236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 9827236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String finalSelection = concatSelections( 9837236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selection, "thread_id = " + threadIdString); 98472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String unionQuery = buildConversationQuery(projection, finalSelection, sortOrder, smsTable, 98572f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen pduTable); 9867236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 9877236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return mOpenHelper.getReadableDatabase().rawQuery(unionQuery, EMPTY_STRING_ARRAY); 9887236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 9897236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 9907236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 9917236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Return the union of MMS and SMS messages whose recipients 9927236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * included this phone number. 9937236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * 9947236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Use this query: 9957236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * 9967236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * SELECT ... 997670c495b6e0489569f60a38a79770dd4ac44500awhliang * FROM pdu, (SELECT msg_id AS address_msg_id 9987236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * FROM addr 999c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang * WHERE (address='<phoneNumber>' OR 1000c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang * PHONE_NUMBERS_EQUAL(addr.address, '<phoneNumber>', 1/0))) 10017236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * AS matching_addresses 1002670c495b6e0489569f60a38a79770dd4ac44500awhliang * WHERE pdu._id = matching_addresses.address_msg_id 10037236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * UNION 10047236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * SELECT ... 10057236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * FROM sms 1006c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang * WHERE (address='<phoneNumber>' OR PHONE_NUMBERS_EQUAL(sms.address, '<phoneNumber>', 1/0)); 10077236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 10087236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private Cursor getMessagesByPhoneNumber( 10097236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String phoneNumber, String[] projection, String selection, 101072f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String sortOrder, String smsTable, String pduTable) { 10117236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String escapedPhoneNumber = DatabaseUtils.sqlEscapeString(phoneNumber); 10127236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String finalMmsSelection = 10137236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project concatSelections( 10147236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selection, 101572f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen pduTable + "._id = matching_addresses.address_msg_id"); 10167236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String finalSmsSelection = 10177236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project concatSelections( 10187236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selection, 1019c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang "(address=" + escapedPhoneNumber + " OR PHONE_NUMBERS_EQUAL(address, " + 1020845a9163dffcbd1073930b8b334df27728418201Daisuke Miyakawa escapedPhoneNumber + 1021c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang (mUseStrictPhoneNumberComparation ? ", 1))" : ", 0))")); 10227236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder(); 10237236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder(); 10247236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 10257236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project mmsQueryBuilder.setDistinct(true); 10267236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project smsQueryBuilder.setDistinct(true); 10277236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project mmsQueryBuilder.setTables( 102872f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen pduTable + 1029670c495b6e0489569f60a38a79770dd4ac44500awhliang ", (SELECT msg_id AS address_msg_id " + 1030c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang "FROM addr WHERE (address=" + escapedPhoneNumber + 1031c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang " OR PHONE_NUMBERS_EQUAL(addr.address, " + 1032845a9163dffcbd1073930b8b334df27728418201Daisuke Miyakawa escapedPhoneNumber + 1033c818d636af8c4f3d8a0d332634d1e73a5215d06bWei Huang (mUseStrictPhoneNumberComparation ? ", 1))) " : ", 0))) ") + 10347236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project "AS matching_addresses"); 103572f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen smsQueryBuilder.setTables(smsTable); 10367236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 10377236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] columns = handleNullMessageProjection(projection); 10387236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery( 10397236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MmsSms.TYPE_DISCRIMINATOR_COLUMN, columns, MMS_COLUMNS, 1040f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor 0, "mms", finalMmsSelection, null, null); 10417236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String smsSubQuery = smsQueryBuilder.buildUnionSubQuery( 10427236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MmsSms.TYPE_DISCRIMINATOR_COLUMN, columns, SMS_COLUMNS, 1043f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor 0, "sms", finalSmsSelection, null, null); 10447236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder(); 10457236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 10467236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project unionQueryBuilder.setDistinct(true); 10477236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 10487236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String unionQuery = unionQueryBuilder.buildUnionQuery( 10497236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project new String[] { mmsSubQuery, smsSubQuery }, sortOrder, null); 10507236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 10517236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return mOpenHelper.getReadableDatabase().rawQuery(unionQuery, EMPTY_STRING_ARRAY); 10527236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 10537236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 10547236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 10557236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Return the conversation of certain thread ID. 10567236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 10577236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private Cursor getConversationById( 10587236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String threadIdString, String[] projection, String selection, 10597236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] selectionArgs, String sortOrder) { 10607236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project try { 10617236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Long.parseLong(threadIdString); 10627236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } catch (NumberFormatException exception) { 10637236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Log.e(LOG_TAG, "Thread ID must be a Long."); 10647236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return null; 10657236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 10667236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 10677236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String extraSelection = "_id=" + threadIdString; 10687236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String finalSelection = concatSelections(selection, extraSelection); 10697236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder(); 10707236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] columns = handleNullThreadsProjection(projection); 10717236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 10727236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project queryBuilder.setDistinct(true); 107315156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor queryBuilder.setTables(TABLE_THREADS); 10747236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return queryBuilder.query( 10757236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project mOpenHelper.getReadableDatabase(), columns, finalSelection, 10767236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selectionArgs, sortOrder, null, null); 10777236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 10787236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 107972f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen private static String joinPduAndPendingMsgTables(String pduTable) { 108072f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen return pduTable + " LEFT JOIN " + TABLE_PENDING_MSG 108172f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen + " ON " + pduTable + "._id = pending_msgs.msg_id"; 10827236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 10837236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 108472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen private static String[] createMmsProjection(String[] old, String pduTable) { 10857236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] newProjection = new String[old.length]; 10867236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project for (int i = 0; i < old.length; i++) { 10877236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (old[i].equals(BaseColumns._ID)) { 108872f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen newProjection[i] = pduTable + "._id"; 10897236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } else { 10907236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project newProjection[i] = old[i]; 10917236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 10927236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 10937236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return newProjection; 10947236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 10957236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 10967236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private Cursor getUndeliveredMessages( 10977236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] projection, String selection, String[] selectionArgs, 109872f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String sortOrder, String smsTable, String pduTable) { 109972f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String[] mmsProjection = createMmsProjection(projection, pduTable); 11007236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11017236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder(); 11027236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder(); 11037236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 110472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen mmsQueryBuilder.setTables(joinPduAndPendingMsgTables(pduTable)); 110572f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen smsQueryBuilder.setTables(smsTable); 11067236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11077236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String finalMmsSelection = concatSelections( 11087236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selection, Mms.MESSAGE_BOX + " = " + Mms.MESSAGE_BOX_OUTBOX); 11097236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String finalSmsSelection = concatSelections( 11107236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selection, "(" + Sms.TYPE + " = " + Sms.MESSAGE_TYPE_OUTBOX 11117236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project + " OR " + Sms.TYPE + " = " + Sms.MESSAGE_TYPE_FAILED 11127236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project + " OR " + Sms.TYPE + " = " + Sms.MESSAGE_TYPE_QUEUED + ")"); 11137236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11147236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] smsColumns = handleNullMessageProjection(projection); 11157236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] mmsColumns = handleNullMessageProjection(mmsProjection); 11167236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] innerMmsProjection = makeProjectionWithDateAndThreadId( 11177236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project mmsColumns, 1000); 11187236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] innerSmsProjection = makeProjectionWithDateAndThreadId( 11197236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project smsColumns, 1); 11207236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11217236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Set<String> columnsPresentInTable = new HashSet<String>(MMS_COLUMNS); 112272f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen columnsPresentInTable.add(pduTable + "._id"); 11237236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project columnsPresentInTable.add(PendingMessages.ERROR_TYPE); 11247236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery( 11257236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerMmsProjection, 1126f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor columnsPresentInTable, 1, "mms", finalMmsSelection, 11277236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project null, null); 11287236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String smsSubQuery = smsQueryBuilder.buildUnionSubQuery( 11297236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerSmsProjection, 1130f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor SMS_COLUMNS, 1, "sms", finalSmsSelection, 11317236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project null, null); 11327236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder(); 11337236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11347236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project unionQueryBuilder.setDistinct(true); 11357236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11367236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String unionQuery = unionQueryBuilder.buildUnionQuery( 11377236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project new String[] { smsSubQuery, mmsSubQuery }, null, null); 11387236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11397236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder outerQueryBuilder = new SQLiteQueryBuilder(); 11407236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11417236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project outerQueryBuilder.setTables("(" + unionQuery + ")"); 11427236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11437236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String outerQuery = outerQueryBuilder.buildQuery( 1144f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor smsColumns, null, null, null, sortOrder, null); 11457236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11467236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return mOpenHelper.getReadableDatabase().rawQuery(outerQuery, EMPTY_STRING_ARRAY); 11477236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 11487236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11497236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 11507236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Add normalized date to the list of columns for an inner 11517236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * projection. 11527236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 11537236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static String[] makeProjectionWithNormalizedDate( 11547236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] projection, int dateMultiple) { 11557236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project int projectionSize = projection.length; 11567236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] result = new String[projectionSize + 1]; 11577236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11587236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project result[0] = "date * " + dateMultiple + " AS normalized_date"; 11597236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project System.arraycopy(projection, 0, result, 1, projectionSize); 11607236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return result; 11617236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 11627236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11637236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static String buildConversationQuery(String[] projection, 116472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String selection, String sortOrder, String smsTable, String pduTable) { 116572f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String[] mmsProjection = createMmsProjection(projection, pduTable); 11667236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11677236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder(); 11687236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder(); 11697236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11707236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project mmsQueryBuilder.setDistinct(true); 11717236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project smsQueryBuilder.setDistinct(true); 117272f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen mmsQueryBuilder.setTables(joinPduAndPendingMsgTables(pduTable)); 117372f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen smsQueryBuilder.setTables(smsTable); 11747236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11757236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] smsColumns = handleNullMessageProjection(projection); 11767236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] mmsColumns = handleNullMessageProjection(mmsProjection); 11777236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] innerMmsProjection = makeProjectionWithNormalizedDate(mmsColumns, 1000); 11787236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] innerSmsProjection = makeProjectionWithNormalizedDate(smsColumns, 1); 11797236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11807236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Set<String> columnsPresentInTable = new HashSet<String>(MMS_COLUMNS); 118172f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen columnsPresentInTable.add(pduTable + "._id"); 11827236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project columnsPresentInTable.add(PendingMessages.ERROR_TYPE); 11837236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11847236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String mmsSelection = concatSelections(selection, 11857236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Mms.MESSAGE_BOX + " != " + Mms.MESSAGE_BOX_DRAFTS); 11867236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery( 11877236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerMmsProjection, 11887236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project columnsPresentInTable, 0, "mms", 11897236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project concatSelections(mmsSelection, MMS_CONVERSATION_CONSTRAINT), 1190f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor null, null); 11917236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String smsSubQuery = smsQueryBuilder.buildUnionSubQuery( 11927236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MmsSms.TYPE_DISCRIMINATOR_COLUMN, innerSmsProjection, SMS_COLUMNS, 11937236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 0, "sms", concatSelections(selection, SMS_CONVERSATION_CONSTRAINT), 1194f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor null, null); 11957236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder(); 11967236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11977236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project unionQueryBuilder.setDistinct(true); 11987236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 11997236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String unionQuery = unionQueryBuilder.buildUnionQuery( 12007236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project new String[] { smsSubQuery, mmsSubQuery }, 12017236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project handleNullSortOrder(sortOrder), null); 12027236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 12037236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteQueryBuilder outerQueryBuilder = new SQLiteQueryBuilder(); 12047236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 12057236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project outerQueryBuilder.setTables("(" + unionQuery + ")"); 12067236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 12077236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return outerQueryBuilder.buildQuery( 1208f008a619299d15bab78b989aef301d97a3930ca3Tom Taylor smsColumns, null, null, null, sortOrder, null); 12097236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 12107236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 12117236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project @Override 12127236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project public String getType(Uri uri) { 12137236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return VND_ANDROID_DIR_MMS_SMS; 12147236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 12157236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 12167236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project @Override 12177236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project public int delete(Uri uri, String selection, 12187236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String[] selectionArgs) { 12197236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 12207236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Context context = getContext(); 12217236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project int affectedRows = 0; 1222f0a9e90721310bed023a9ff1f176f1b5e05a14f7Mark Wagner 12237236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project switch(URI_MATCHER.match(uri)) { 12247236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_CONVERSATIONS_MESSAGES: 12257236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project long threadId; 12267236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project try { 12277236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project threadId = Long.parseLong(uri.getLastPathSegment()); 12287236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } catch (NumberFormatException e) { 12297236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Log.e(LOG_TAG, "Thread ID must be a long."); 12307236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 12317236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 12327236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project affectedRows = deleteConversation(uri, selection, selectionArgs); 12337236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MmsSmsDatabaseHelper.updateThread(db, threadId); 12347236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 12357236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_CONVERSATIONS: 12367236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project affectedRows = MmsProvider.deleteMessages(context, db, 12377236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selection, selectionArgs, uri) 12387236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project + db.delete("sms", selection, selectionArgs); 1239c2bd355a1ebb364c76576c81fb19a1d5e5a7b2a5Snild Dolkow // Intentionally don't pass the selection variable to updateThreads. 124087bfe142b5c163e19fb9e60d558bbeb513ca150cTom Taylor // When we pass in "locked=0" there, the thread will get excluded from 124187bfe142b5c163e19fb9e60d558bbeb513ca150cTom Taylor // the selection and not get updated. 1242c2bd355a1ebb364c76576c81fb19a1d5e5a7b2a5Snild Dolkow MmsSmsDatabaseHelper.updateThreads(db, null, null); 12437236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 12447236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_OBSOLETE_THREADS: 124515156cd6afcc7ed57ac7be40ef2d32a615e83599Tom Taylor affectedRows = db.delete(TABLE_THREADS, 12464b14c35e9e44d5df2b5340141f2b24bab351c603Tom Taylor "_id NOT IN (SELECT DISTINCT thread_id FROM sms where thread_id NOT NULL " + 12474b14c35e9e44d5df2b5340141f2b24bab351c603Tom Taylor "UNION SELECT DISTINCT thread_id FROM pdu where thread_id NOT NULL)", null); 12487236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 12497236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project default: 1250b91bcae9fa009787f165591fd7fc4c8f2f2dfd99Tom Taylor throw new UnsupportedOperationException(NO_DELETES_INSERTS_OR_UPDATES + uri); 12517236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 12527236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 12537236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (affectedRows > 0) { 125443f9fb234aabe569b342af78bdaf85effbd85f10Amith Yamasani context.getContentResolver().notifyChange(MmsSms.CONTENT_URI, null, true, 125543f9fb234aabe569b342af78bdaf85effbd85f10Amith Yamasani UserHandle.USER_ALL); 12567236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 12577236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return affectedRows; 12587236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 12597236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 12607236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 12617236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Delete the conversation with the given thread ID. 12627236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 12637236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private int deleteConversation(Uri uri, String selection, String[] selectionArgs) { 12647236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String threadId = uri.getLastPathSegment(); 12657236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 12667236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 12677236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String finalSelection = concatSelections(selection, "thread_id = " + threadId); 12687236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return MmsProvider.deleteMessages(getContext(), db, finalSelection, 12697236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project selectionArgs, uri) 12707236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project + db.delete("sms", finalSelection, selectionArgs); 12717236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 12727236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 12737236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project @Override 12747236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project public Uri insert(Uri uri, ContentValues values) { 1275b91bcae9fa009787f165591fd7fc4c8f2f2dfd99Tom Taylor if (URI_MATCHER.match(uri) == URI_PENDING_MSG) { 1276b91bcae9fa009787f165591fd7fc4c8f2f2dfd99Tom Taylor SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 1277b91bcae9fa009787f165591fd7fc4c8f2f2dfd99Tom Taylor long rowId = db.insert(TABLE_PENDING_MSG, null, values); 1278b91bcae9fa009787f165591fd7fc4c8f2f2dfd99Tom Taylor return Uri.parse(uri + "/" + rowId); 1279b91bcae9fa009787f165591fd7fc4c8f2f2dfd99Tom Taylor } 1280b91bcae9fa009787f165591fd7fc4c8f2f2dfd99Tom Taylor throw new UnsupportedOperationException(NO_DELETES_INSERTS_OR_UPDATES + uri); 12817236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 12827236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 12837236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project @Override 12847236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project public int update(Uri uri, ContentValues values, 12857236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String selection, String[] selectionArgs) { 1286e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wen final int callerUid = Binder.getCallingUid(); 128772f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen final String callerPkg = getCallingPackage(); 12887236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 12897236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project int affectedRows = 0; 12907236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project switch(URI_MATCHER.match(uri)) { 12917236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_CONVERSATIONS_MESSAGES: 12927236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String threadIdString = uri.getPathSegments().get(1); 12937236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project affectedRows = updateConversation(threadIdString, values, 129472f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen selection, selectionArgs, callerUid, callerPkg); 12957236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 12961ecf192c60625c5227336430ee36705c13ae06e2Wei Huang 12977236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project case URI_PENDING_MSG: 12987236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project affectedRows = db.update(TABLE_PENDING_MSG, values, selection, null); 12997236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project break; 13001ecf192c60625c5227336430ee36705c13ae06e2Wei Huang 13011ecf192c60625c5227336430ee36705c13ae06e2Wei Huang case URI_CANONICAL_ADDRESS: { 13021ecf192c60625c5227336430ee36705c13ae06e2Wei Huang String extraSelection = "_id=" + uri.getPathSegments().get(1); 13031ecf192c60625c5227336430ee36705c13ae06e2Wei Huang String finalSelection = TextUtils.isEmpty(selection) 13041ecf192c60625c5227336430ee36705c13ae06e2Wei Huang ? extraSelection : extraSelection + " AND " + selection; 13051ecf192c60625c5227336430ee36705c13ae06e2Wei Huang 13061ecf192c60625c5227336430ee36705c13ae06e2Wei Huang affectedRows = db.update(TABLE_CANONICAL_ADDRESSES, values, finalSelection, null); 13071ecf192c60625c5227336430ee36705c13ae06e2Wei Huang break; 13081ecf192c60625c5227336430ee36705c13ae06e2Wei Huang } 13091ecf192c60625c5227336430ee36705c13ae06e2Wei Huang 131082fc72b94a54eb3c70bcfbb1effd9b3a9b775af9Ye Wen case URI_CONVERSATIONS: { 131182fc72b94a54eb3c70bcfbb1effd9b3a9b775af9Ye Wen final ContentValues finalValues = new ContentValues(1); 131282fc72b94a54eb3c70bcfbb1effd9b3a9b775af9Ye Wen if (values.containsKey(Threads.ARCHIVED)) { 131382fc72b94a54eb3c70bcfbb1effd9b3a9b775af9Ye Wen // Only allow update archived 131482fc72b94a54eb3c70bcfbb1effd9b3a9b775af9Ye Wen finalValues.put(Threads.ARCHIVED, values.getAsBoolean(Threads.ARCHIVED)); 131582fc72b94a54eb3c70bcfbb1effd9b3a9b775af9Ye Wen } 131682fc72b94a54eb3c70bcfbb1effd9b3a9b775af9Ye Wen affectedRows = db.update(TABLE_THREADS, finalValues, selection, selectionArgs); 131782fc72b94a54eb3c70bcfbb1effd9b3a9b775af9Ye Wen break; 131882fc72b94a54eb3c70bcfbb1effd9b3a9b775af9Ye Wen } 131982fc72b94a54eb3c70bcfbb1effd9b3a9b775af9Ye Wen 13207236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project default: 13217236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project throw new UnsupportedOperationException( 1322b91bcae9fa009787f165591fd7fc4c8f2f2dfd99Tom Taylor NO_DELETES_INSERTS_OR_UPDATES + uri); 13237236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 13247236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 13257236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project if (affectedRows > 0) { 13267236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project getContext().getContentResolver().notifyChange( 132743f9fb234aabe569b342af78bdaf85effbd85f10Amith Yamasani MmsSms.CONTENT_URI, null, true, UserHandle.USER_ALL); 13287236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 13297236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return affectedRows; 13307236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 13317236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 133272f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen private int updateConversation(String threadIdString, ContentValues values, String selection, 133372f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen String[] selectionArgs, int callerUid, String callerPkg) { 13347236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project try { 13357236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Long.parseLong(threadIdString); 13367236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } catch (NumberFormatException exception) { 13377236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Log.e(LOG_TAG, "Thread ID must be a Long."); 13387236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return 0; 1339e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wen 1340e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wen } 1341e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wen if (ProviderUtil.shouldRemoveCreator(values, callerUid)) { 1342e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wen // CREATOR should not be changed by non-SYSTEM/PHONE apps 134372f135589e5d705bcac4a3db3019e4d9d2d04d36Ye Wen Log.w(LOG_TAG, callerPkg + " tries to update CREATOR"); 1344e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wen // Sms.CREATOR and Mms.CREATOR are same. But let's do this 1345e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wen // twice in case the names may differ in the future 1346e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wen values.remove(Sms.CREATOR); 1347e07acb9f6a77d9753900224a4caefd5a8aec97eeYe Wen values.remove(Mms.CREATOR); 13487236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 13497236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 13507236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SQLiteDatabase db = mOpenHelper.getWritableDatabase(); 13517236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project String finalSelection = concatSelections(selection, "thread_id=" + threadIdString); 13527236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project return db.update(MmsProvider.TABLE_PDU, values, finalSelection, selectionArgs) 13537236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project + db.update("sms", values, finalSelection, selectionArgs); 13547236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 13557236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 13567236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project /** 13577236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * Construct Sets of Strings containing exactly the columns 13587236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * present in each table. We will use this when constructing 13597236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project * UNION queries across the MMS and SMS tables. 13607236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project */ 13617236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project private static void initializeColumnSets() { 13627236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project int commonColumnCount = MMS_SMS_COLUMNS.length; 13637236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project int mmsOnlyColumnCount = MMS_ONLY_COLUMNS.length; 13647236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project int smsOnlyColumnCount = SMS_ONLY_COLUMNS.length; 13657236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project Set<String> unionColumns = new HashSet<String>(); 13667236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 13677236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project for (int i = 0; i < commonColumnCount; i++) { 13687236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MMS_COLUMNS.add(MMS_SMS_COLUMNS[i]); 13697236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SMS_COLUMNS.add(MMS_SMS_COLUMNS[i]); 13707236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project unionColumns.add(MMS_SMS_COLUMNS[i]); 13717236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 13727236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project for (int i = 0; i < mmsOnlyColumnCount; i++) { 13737236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project MMS_COLUMNS.add(MMS_ONLY_COLUMNS[i]); 13747236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project unionColumns.add(MMS_ONLY_COLUMNS[i]); 13757236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 13767236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project for (int i = 0; i < smsOnlyColumnCount; i++) { 13777236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project SMS_COLUMNS.add(SMS_ONLY_COLUMNS[i]); 13787236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project unionColumns.add(SMS_ONLY_COLUMNS[i]); 13797236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 13807236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project 13817236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project int i = 0; 13827236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project for (String columnName : unionColumns) { 13837236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project UNION_COLUMNS[i++] = columnName; 13847236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 13857236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project } 138686b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wen 138786b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wen @Override 138886b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wen public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 138986b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wen // Dump default SMS app 139086b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wen String defaultSmsApp = Telephony.Sms.getDefaultSmsPackage(getContext()); 139186b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wen if (TextUtils.isEmpty(defaultSmsApp)) { 139286b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wen defaultSmsApp = "None"; 139386b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wen } 139486b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wen writer.println("Default SMS app: " + defaultSmsApp); 139586b8a2cfb7558ec500b4de46bac3d873eaf6028fYe Wen } 1396785f9214b0da4bacf4c78ae90f08c535ab04c5a5Tom Taylor 1397785f9214b0da4bacf4c78ae90f08c535ab04c5a5Tom Taylor @Override 1398785f9214b0da4bacf4c78ae90f08c535ab04c5a5Tom Taylor public Bundle call(String method, String arg, Bundle extras) { 1399785f9214b0da4bacf4c78ae90f08c535ab04c5a5Tom Taylor if (METHOD_IS_RESTORING.equals(method)) { 1400785f9214b0da4bacf4c78ae90f08c535ab04c5a5Tom Taylor Bundle result = new Bundle(); 1401785f9214b0da4bacf4c78ae90f08c535ab04c5a5Tom Taylor result.putBoolean(IS_RESTORING_KEY, TelephonyBackupAgent.getIsRestoring()); 1402785f9214b0da4bacf4c78ae90f08c535ab04c5a5Tom Taylor return result; 1403785f9214b0da4bacf4c78ae90f08c535ab04c5a5Tom Taylor } 1404785f9214b0da4bacf4c78ae90f08c535ab04c5a5Tom Taylor Log.w(LOG_TAG, "Ignored unsupported " + method + " call"); 1405785f9214b0da4bacf4c78ae90f08c535ab04c5a5Tom Taylor return null; 1406785f9214b0da4bacf4c78ae90f08c535ab04c5a5Tom Taylor } 14077236c3ad7ff01dd5ece14a2cabbf5ce3a570d793The Android Open Source Project} 1408