ContactsProvider2.java revision 013a0d6b3d392fb49d4618f2527b2ed3fec7d34f
14f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton/* 24f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton * Copyright (C) 2009 The Android Open Source Project 34f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton * 44f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton * Licensed under the Apache License, Version 2.0 (the "License"); 54f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton * you may not use this file except in compliance with the License. 64f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton * You may obtain a copy of the License at 74f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton * 84f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton * http://www.apache.org/licenses/LICENSE-2.0 94f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton * 104f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton * Unless required by applicable law or agreed to in writing, software 114f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton * distributed under the License is distributed on an "AS IS" BASIS, 124f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton * See the License for the specific language governing permissions and 144f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton * limitations under the License 154f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton */ 164f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 1728f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millarpackage com.android.providers.contacts; 1828f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar 1967dde51ab932dc84d95a203b113989b13437f13dJeff Sharkeyimport com.android.internal.content.SyncStateContentProviderHelper; 2028f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millarimport com.android.providers.contacts.OpenHelper.AggregationExceptionColumns; 2128f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millarimport com.android.providers.contacts.OpenHelper.Clauses; 22d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikovimport com.android.providers.contacts.OpenHelper.ContactsColumns; 2328f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millarimport com.android.providers.contacts.OpenHelper.DataColumns; 2428f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millarimport com.android.providers.contacts.OpenHelper.GroupsColumns; 2528f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millarimport com.android.providers.contacts.OpenHelper.MimetypesColumns; 2611944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikovimport com.android.providers.contacts.OpenHelper.NameLookupColumns; 2767dde51ab932dc84d95a203b113989b13437f13dJeff Sharkeyimport com.android.providers.contacts.OpenHelper.PackagesColumns; 28d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikovimport com.android.providers.contacts.OpenHelper.PhoneColumns; 2928f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millarimport com.android.providers.contacts.OpenHelper.PhoneLookupColumns; 30d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikovimport com.android.providers.contacts.OpenHelper.RawContactsColumns; 3128f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millarimport com.android.providers.contacts.OpenHelper.Tables; 32e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikovimport com.google.android.collect.Lists; 33e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 34b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikovimport android.accounts.Account; 35caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikovimport android.accounts.AccountManager; 36c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikovimport android.app.SearchManager; 3735ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintanaimport android.content.ContentUris; 3867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkeyimport android.content.ContentValues; 3967dde51ab932dc84d95a203b113989b13437f13dJeff Sharkeyimport android.content.Context; 4035ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintanaimport android.content.Entity; 4167dde51ab932dc84d95a203b113989b13437f13dJeff Sharkeyimport android.content.EntityIterator; 423d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikovimport android.content.SharedPreferences; 4367dde51ab932dc84d95a203b113989b13437f13dJeff Sharkeyimport android.content.UriMatcher; 443d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikovimport android.content.SharedPreferences.Editor; 454f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamiltonimport android.database.Cursor; 46ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkeyimport android.database.DatabaseUtils; 47b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikovimport android.database.sqlite.SQLiteCursor; 484f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamiltonimport android.database.sqlite.SQLiteDatabase; 494f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamiltonimport android.database.sqlite.SQLiteQueryBuilder; 50c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millarimport android.database.sqlite.SQLiteStatement; 514f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamiltonimport android.net.Uri; 52b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikovimport android.os.RemoteException; 533d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikovimport android.preference.PreferenceManager; 54508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkeyimport android.provider.BaseColumns; 55de4c4d84028c6c6999c6d9277b54b661f207b992Evan Millarimport android.provider.ContactsContract; 563cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikovimport android.provider.Contacts.People; 57b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikovimport android.provider.ContactsContract.AggregationExceptions; 58de4c4d84028c6c6999c6d9277b54b661f207b992Evan Millarimport android.provider.ContactsContract.CommonDataKinds; 59d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikovimport android.provider.ContactsContract.Contacts; 60de4c4d84028c6c6999c6d9277b54b661f207b992Evan Millarimport android.provider.ContactsContract.Data; 61ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkeyimport android.provider.ContactsContract.Groups; 621f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkeyimport android.provider.ContactsContract.Presence; 63d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikovimport android.provider.ContactsContract.RawContacts; 643cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.BaseTypes; 65ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.Email; 66ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.GroupMembership; 673cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Im; 683cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Nickname; 693cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Organization; 70de4c4d84028c6c6999c6d9277b54b661f207b992Evan Millarimport android.provider.ContactsContract.CommonDataKinds.Phone; 714097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.StructuredName; 7267dde51ab932dc84d95a203b113989b13437f13dJeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.StructuredPostal; 73a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamiltonimport android.telephony.PhoneNumberUtils; 74a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamiltonimport android.text.TextUtils; 75c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikovimport android.util.Log; 764f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 777e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintanaimport java.util.ArrayList; 78b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikovimport java.util.HashMap; 794f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 804f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton/** 814f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton * Contacts content provider. The contract between this provider and applications 824f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton * is defined in {@link ContactsContract}. 834f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton */ 84de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikovpublic class ContactsProvider2 extends SQLiteContentProvider { 85caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov 86b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // TODO: clean up debug tag and rename this class 87b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private static final String TAG = "ContactsProvider ~~~~"; 884f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 89619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey // TODO: carefully prevent all incoming nested queries; they can be gaping security holes 90619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey // TODO: check for restricted flag during insert(), update(), and delete() calls 91619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 923cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov /** Default for the maximum number of returned aggregation suggestions. */ 933cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov private static final int DEFAULT_MAX_SUGGESTIONS = 5; 943cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 953d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov /** 963d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov * Shared preference key for the legacy contact import version. The need for a version 973d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov * as opposed to a boolean flag is that if we discover bugs in the contact import process, 983d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov * we can trigger re-import by incrementing the import version. 993d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov */ 1003d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov private static final String PREF_CONTACTS_IMPORTED = "contacts_imported_v1"; 1013d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov private static final int PREF_CONTACTS_IMPORT_VERSION = 1; 1023d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov 103a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 1044f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 105d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private static final String STREQUENT_ORDER_BY = Contacts.STARRED + " DESC, " 106d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.TIMES_CONTACTED + " DESC, " 107d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.DISPLAY_NAME + " ASC"; 108d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar private static final String STREQUENT_LIMIT = 109d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov "(SELECT COUNT(1) FROM " + Tables.CONTACTS + " WHERE " 110d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.STARRED + "=1) + 25"; 111d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov 112d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private static final int CONTACTS = 1000; 113d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private static final int CONTACTS_ID = 1001; 114d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private static final int CONTACTS_DATA = 1002; 115d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private static final int CONTACTS_SUMMARY = 1003; 1162815f58f72f109790585931f601a63ddc02536a5Evan Millar private static final int CONTACTS_SUMMARY_ID = 1005; 1172815f58f72f109790585931f601a63ddc02536a5Evan Millar private static final int CONTACTS_SUMMARY_FILTER = 1006; 1182815f58f72f109790585931f601a63ddc02536a5Evan Millar private static final int CONTACTS_SUMMARY_STREQUENT = 1007; 1192815f58f72f109790585931f601a63ddc02536a5Evan Millar private static final int CONTACTS_SUMMARY_STREQUENT_FILTER = 1008; 1202815f58f72f109790585931f601a63ddc02536a5Evan Millar private static final int CONTACTS_SUMMARY_GROUP = 1009; 1214f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 1225ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov private static final int RAW_CONTACTS = 2002; 1235ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov private static final int RAW_CONTACTS_ID = 2003; 1245ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov private static final int RAW_CONTACTS_DATA = 2004; 1254f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 1266bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov private static final int DATA = 3000; 1276bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov private static final int DATA_ID = 3001; 128ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar private static final int PHONES = 3002; 129ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar private static final int PHONES_FILTER = 3003; 1304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov private static final int EMAILS = 3004; 1314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov private static final int EMAILS_FILTER = 3005; 1324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov private static final int POSTALS = 3006; 133a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton 1346bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov private static final int PHONE_LOOKUP = 4000; 1356bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov 136b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov private static final int AGGREGATION_EXCEPTIONS = 6000; 137b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov private static final int AGGREGATION_EXCEPTION_ID = 6001; 138b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 1391f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey private static final int PRESENCE = 7000; 1401f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey private static final int PRESENCE_ID = 7001; 1411f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 14231b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov private static final int AGGREGATION_SUGGESTIONS = 8000; 14331b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov 144ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey private static final int GROUPS = 10000; 145ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey private static final int GROUPS_ID = 10001; 146ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey private static final int GROUPS_SUMMARY = 10003; 147ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 14835ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana private static final int SYNCSTATE = 11000; 14935ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 150c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov private static final int SEARCH_SUGGESTIONS = 12001; 151c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov private static final int SEARCH_SHORTCUT = 12002; 152c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 15367dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey private interface ContactsQuery { 1545ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String TABLE = Tables.RAW_CONTACTS; 1559261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana 15667dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String[] PROJECTION = new String[] { 1576cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContactsColumns.CONCRETE_ID, 1586cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.ACCOUNT_NAME, 1596cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.ACCOUNT_TYPE, 160ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey }; 161ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 1625ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final int RAW_CONTACT_ID = 0; 16367dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final int ACCOUNT_NAME = 1; 16467dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final int ACCOUNT_TYPE = 2; 16567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey } 16667dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey 167d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private interface DataRawContactsQuery { 1685ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String TABLE = Tables.DATA_JOIN_MIMETYPE_RAW_CONTACTS; 16967dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey 17067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String[] PROJECTION = new String[] { 1716cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContactsColumns.CONCRETE_ID, 1723cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov DataColumns.CONCRETE_ID, 173d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov RawContacts.CONTACT_ID, 1746cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.IS_RESTRICTED, 1753cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov Data.MIMETYPE, 176ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey }; 177ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 1785ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final int RAW_CONTACT_ID = 0; 17967dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final int DATA_ID = 1; 180d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final int CONTACT_ID = 2; 18167dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final int IS_RESTRICTED = 3; 18267dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final int MIMETYPE = 4; 18367dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey } 18467dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey 185d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private interface DataContactsQuery { 186d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String TABLE = Tables.DATA_JOIN_MIMETYPES_RAW_CONTACTS_CONTACTS; 18767dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey 18867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String[] PROJECTION = new String[] { 1896cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContactsColumns.CONCRETE_ID, 1903cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov DataColumns.CONCRETE_ID, 191d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov ContactsColumns.CONCRETE_ID, 1923cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov MimetypesColumns.CONCRETE_ID, 193ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey }; 194ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 195d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final int RAW_CONTACT_ID = 0; 19667dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final int DATA_ID = 1; 197d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final int CONTACT_ID = 2; 19867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final int MIMETYPE_ID = 3; 199ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 2001f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 2013cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov private interface DisplayNameQuery { 20267dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String TABLE = Tables.DATA_JOIN_MIMETYPES; 2033cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 2043cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public static final String[] COLUMNS = new String[] { 2053cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov MimetypesColumns.MIMETYPE, 2063cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov Data.IS_PRIMARY, 2073cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov Data.DATA2, 2083cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov StructuredName.DISPLAY_NAME, 2093cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov }; 2103cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 2113cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public static final int MIMETYPE = 0; 2123cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public static final int IS_PRIMARY = 1; 2133cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public static final int DATA2 = 2; 2143cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public static final int DISPLAY_NAME = 3; 2153cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 2163cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 2173cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov private interface DataQuery { 21867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String TABLE = Tables.DATA_JOIN_MIMETYPES; 2193cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 22088e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov public static final String[] CONCRETE_COLUMNS = new String[] { 2213cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov DataColumns.CONCRETE_ID, 2223cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov MimetypesColumns.MIMETYPE, 2235ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Data.RAW_CONTACT_ID, 2243cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov Data.IS_PRIMARY, 2253cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov Data.DATA2, 22688e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov }; 22788e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov 22888e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov public static final String[] COLUMNS = new String[] { 22988e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov Data._ID, 23088e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov MimetypesColumns.MIMETYPE, 23188e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov Data.RAW_CONTACT_ID, 23288e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov Data.IS_PRIMARY, 23388e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov Data.DATA2, 2343cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov }; 2353cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 2363cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public static final int ID = 0; 2373cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public static final int MIMETYPE = 1; 2385ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final int RAW_CONTACT_ID = 2; 2393cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public static final int IS_PRIMARY = 3; 24088e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov public static final int DATA2 = 4; 2413cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 2423cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 24320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov private interface DataIdQuery { 244321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana String[] COLUMNS = { Data._ID, Data.RAW_CONTACT_ID, Data.MIMETYPE }; 24520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 24620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov int _ID = 0; 247321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana int RAW_CONTACT_ID = 1; 248321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana int MIMETYPE = 2; 24920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 25020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 2513cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov // Higher number represents higher priority in choosing what data to use for the display name 2523cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov private static final int DISPLAY_NAME_PRIORITY_EMAIL = 1; 2533cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov private static final int DISPLAY_NAME_PRIORITY_PHONE = 2; 2543cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov private static final int DISPLAY_NAME_PRIORITY_ORGANIZATION = 3; 2553cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov private static final int DISPLAY_NAME_PRIORITY_STRUCTURED_NAME = 4; 2563cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 2573cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov private static final HashMap<String, Integer> sDisplayNamePriorities; 2583cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov static { 2593cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov sDisplayNamePriorities = new HashMap<String, Integer>(); 2603cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov sDisplayNamePriorities.put(StructuredName.CONTENT_ITEM_TYPE, 2613cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov DISPLAY_NAME_PRIORITY_STRUCTURED_NAME); 2623cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov sDisplayNamePriorities.put(Organization.CONTENT_ITEM_TYPE, 2633cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov DISPLAY_NAME_PRIORITY_ORGANIZATION); 2643cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov sDisplayNamePriorities.put(Phone.CONTENT_ITEM_TYPE, 2653cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov DISPLAY_NAME_PRIORITY_PHONE); 2663cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov sDisplayNamePriorities.put(Email.CONTENT_ITEM_TYPE, 2673cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov DISPLAY_NAME_PRIORITY_EMAIL); 2683cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 26931b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov 270caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov public static final String DEFAULT_ACCOUNT_TYPE = "com.google.GAIA"; 271caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov public static final String FEATURE_APPS_FOR_DOMAIN = "google_or_dasher"; 272caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov 2734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov /** Contains just the contacts columns 2744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * @deprecated*/ 2754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov @Deprecated 2764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov private static final HashMap<String, String> sDeprecatedContactsProjectionMap; 2774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 2784f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton private static final HashMap<String, String> sContactsProjectionMap; 2794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 2804a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 281d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov /** Contains the contact columns along with primary phone */ 282d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private static final HashMap<String, String> sContactsSummaryProjectionMap; 283d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov /** Contains just the contacts columns */ 284d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private static final HashMap<String, String> sRawContactsProjectionMap; 2854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 2864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov /** 2874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * Contains just the contacts columns 2884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * 2894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * @deprecated 2904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov */ 2914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov @Deprecated 2924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov private static final HashMap<String, String> sDeprecatedRawContactsProjectionMap; 2934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 2944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov /** 2954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * Contains just the data columns 2964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * 2974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * @deprecated 2984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov */ 2994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov @Deprecated 3004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov private static final HashMap<String, String> sDeprecatedDataGroupsProjectionMap; 3014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 3024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov /** Contains columns from the data view */ 3034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov private static final HashMap<String, String> sDataProjectionMap; 3044a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 3059261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana /** Contains the data and contacts columns, for joined tables */ 3060c83a3c4b6a9c8a0dfa0b3aa2af91b74d8e3304fEvan Millar private static final HashMap<String, String> sDataRawContactsGroupsProjectionMap; 307a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton /** Contains the data and contacts columns, for joined tables */ 3080c83a3c4b6a9c8a0dfa0b3aa2af91b74d8e3304fEvan Millar private static final HashMap<String, String> sDataRawContactsProjectionMap; 309ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey /** Contains the just the {@link Groups} columns */ 310ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey private static final HashMap<String, String> sGroupsProjectionMap; 311ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey /** Contains {@link Groups} columns along with summary details */ 312ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey private static final HashMap<String, String> sGroupsSummaryProjectionMap; 313373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov /** Contains the agg_exceptions columns */ 314b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov private static final HashMap<String, String> sAggregationExceptionsProjectionMap; 315373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov /** Contains Presence columns */ 316373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov private static final HashMap<String, String> sPresenceProjectionMap; 3177e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 318c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar /** Sql select statement that returns the contact id associated with a data record. */ 319d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private static final String sNestedRawContactIdSelect; 320c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar /** Sql select statement that returns the mimetype id associated with a data record. */ 321c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar private static final String sNestedMimetypeSelect; 322d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov /** Sql select statement that returns the contact id associated with a contact record. */ 323d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private static final String sNestedContactIdSelect; 324d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov /** Sql select statement that returns a list of contact ids associated with an contact record. */ 325c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar private static final String sNestedContactIdListSelect; 326c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar /** Sql where statement used to match all the data records that need to be updated when a new 327c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar * "primary" is selected.*/ 328c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar private static final String sSetPrimaryWhere; 329c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar /** Sql where statement used to match all the data records that need to be updated when a new 330c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar * "super primary" is selected.*/ 331c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar private static final String sSetSuperPrimaryWhere; 332b67163a1088f09c59f324350662eb18772fac6b6Evan Millar /** Sql where statement for filtering on groups. */ 333d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private static final String sContactsInGroupSelect; 334c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar /** Precompiled sql statement for setting a data record to the primary. */ 335c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar private SQLiteStatement mSetPrimaryStatement; 3363cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov /** Precompiled sql statement for setting a data record to the super primary. */ 337c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar private SQLiteStatement mSetSuperPrimaryStatement; 338d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov /** Precompiled sql statement for incrementing times contacted for an contact */ 339f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov private SQLiteStatement mLastTimeContactedUpdate; 3403cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov /** Precompiled sql statement for updating a contact display name */ 3413cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov private SQLiteStatement mContactDisplayNameUpdate; 34273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov /** Precompiled sql statement for marking a raw contact as dirty */ 34373776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov private SQLiteStatement mRawContactDirtyUpdate; 344a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 3454f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton static { 3464f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton // Contacts URI matching table 347a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton final UriMatcher matcher = sUriMatcher; 348d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "contacts", CONTACTS); 349d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "contacts/#", CONTACTS_ID); 350d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/data", CONTACTS_DATA); 351d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "contacts_summary", CONTACTS_SUMMARY); 352d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "contacts_summary/#", CONTACTS_SUMMARY_ID); 353d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "contacts_summary/filter/*", 354d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov CONTACTS_SUMMARY_FILTER); 355d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "contacts_summary/strequent/", 356d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov CONTACTS_SUMMARY_STREQUENT); 357d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "contacts_summary/strequent/filter/*", 358d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov CONTACTS_SUMMARY_STREQUENT_FILTER); 359d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "contacts_summary/group/*", 360d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov CONTACTS_SUMMARY_GROUP); 361d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/suggestions", 36231b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov AGGREGATION_SUGGESTIONS); 3635ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts", RAW_CONTACTS); 3645ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts/#", RAW_CONTACTS_ID); 3655ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts/#/data", RAW_CONTACTS_DATA); 366b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 3674f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton matcher.addURI(ContactsContract.AUTHORITY, "data", DATA); 3684f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton matcher.addURI(ContactsContract.AUTHORITY, "data/#", DATA_ID); 369ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar matcher.addURI(ContactsContract.AUTHORITY, "data/phones", PHONES); 370ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar matcher.addURI(ContactsContract.AUTHORITY, "data/phones/filter/*", PHONES_FILTER); 3714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "data/emails", EMAILS); 3724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "data/emails/filter/*", EMAILS_FILTER); 373ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar matcher.addURI(ContactsContract.AUTHORITY, "data/postals", POSTALS); 3741f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 375ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey matcher.addURI(ContactsContract.AUTHORITY, "groups", GROUPS); 376ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey matcher.addURI(ContactsContract.AUTHORITY, "groups/#", GROUPS_ID); 377ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey matcher.addURI(ContactsContract.AUTHORITY, "groups_summary", GROUPS_SUMMARY); 378ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 37935ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana matcher.addURI(ContactsContract.AUTHORITY, SyncStateContentProviderHelper.PATH, SYNCSTATE); 38035ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 381a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton matcher.addURI(ContactsContract.AUTHORITY, "phone_lookup/*", PHONE_LOOKUP); 382b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "aggregation_exceptions", 383b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov AGGREGATION_EXCEPTIONS); 384b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, "aggregation_exceptions/*", 385b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov AGGREGATION_EXCEPTION_ID); 3864f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 387bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar matcher.addURI(ContactsContract.AUTHORITY, "presence", PRESENCE); 388bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar matcher.addURI(ContactsContract.AUTHORITY, "presence/#", PRESENCE_ID); 3891f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 390c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, 391c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov SEARCH_SUGGESTIONS); 392c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", 393c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov SEARCH_SUGGESTIONS); 394c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov matcher.addURI(ContactsContract.AUTHORITY, SearchManager.SUGGEST_URI_PATH_SHORTCUT + "/#", 395c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov SEARCH_SHORTCUT); 396c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 3974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sContactsProjectionMap = new HashMap<String, String>(); 3984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sContactsProjectionMap.put(Contacts._ID, Contacts._ID); 3994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sContactsProjectionMap.put(Contacts.DISPLAY_NAME, Contacts.DISPLAY_NAME); 4004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sContactsProjectionMap.put(Contacts.LAST_TIME_CONTACTED, Contacts.LAST_TIME_CONTACTED); 4014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sContactsProjectionMap.put(Contacts.TIMES_CONTACTED, Contacts.TIMES_CONTACTED); 4024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sContactsProjectionMap.put(Contacts.STARRED, Contacts.STARRED); 4034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sContactsProjectionMap.put(Contacts.IN_VISIBLE_GROUP, Contacts.IN_VISIBLE_GROUP); 4044a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sContactsProjectionMap.put(Contacts.PHOTO_ID, Contacts.PHOTO_ID); 4054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sContactsProjectionMap.put(Contacts.CUSTOM_RINGTONE, Contacts.CUSTOM_RINGTONE); 406f992bfab334b760d36a053fc0b439382dcfb51adDmitri Plotnikov sContactsProjectionMap.put(Contacts.HAS_PHONE_NUMBER, Contacts.HAS_PHONE_NUMBER); 4074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sContactsProjectionMap.put(Contacts.SEND_TO_VOICEMAIL, Contacts.SEND_TO_VOICEMAIL); 4084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 4094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sContactsSummaryProjectionMap = new HashMap<String, String>(); 4104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sContactsSummaryProjectionMap.putAll(sContactsProjectionMap); 4114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sContactsSummaryProjectionMap.put(Contacts.PRESENCE_STATUS, 4124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov "MAX(" + Presence.PRESENCE_STATUS + ") AS " + Contacts.PRESENCE_STATUS); 4134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 414fec4e13316f2731d84394e5fa2f93af3febdc20cEvan Millar HashMap<String, String> columns; 4154f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 416d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov // Contacts projection map 4176bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov columns = new HashMap<String, String>(); 418d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov columns.put(Contacts._ID, "contacts._id AS _id"); 419d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov columns.put(Contacts.DISPLAY_NAME, ContactsColumns.CONCRETE_DISPLAY_NAME + " AS " 420d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.DISPLAY_NAME); 421d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov columns.put(Contacts.LAST_TIME_CONTACTED, ContactsColumns.CONCRETE_LAST_TIME_CONTACTED 422d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + " AS " + Contacts.LAST_TIME_CONTACTED); 423d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov columns.put(Contacts.TIMES_CONTACTED, ContactsColumns.CONCRETE_TIMES_CONTACTED + " AS " 424d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.TIMES_CONTACTED); 425d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov columns.put(Contacts.STARRED, ContactsColumns.CONCRETE_STARRED + " AS " 426d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.STARRED); 427d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov columns.put(Contacts.IN_VISIBLE_GROUP, Contacts.IN_VISIBLE_GROUP); 428d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov columns.put(Contacts.PHOTO_ID, Contacts.PHOTO_ID); 429d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov columns.put(Contacts.CUSTOM_RINGTONE, ContactsColumns.CONCRETE_CUSTOM_RINGTONE + " AS " 430d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.CUSTOM_RINGTONE); 431d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov columns.put(Contacts.SEND_TO_VOICEMAIL, ContactsColumns.CONCRETE_SEND_TO_VOICEMAIL 432d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + " AS " + Contacts.SEND_TO_VOICEMAIL); 4334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDeprecatedContactsProjectionMap = columns; 4346bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov 4351f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey columns = new HashMap<String, String>(); 4364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov columns.putAll(sDeprecatedContactsProjectionMap); 437c62855331805c2744a097ef6ea625652197bfb87Dmitri Plotnikov 4384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov// // Contacts primaries projection map. The overall presence status is 4394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov// // the most-present value, as indicated by the largest value. 4404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov// columns.put(Contacts.PRESENCE_STATUS, "MAX(" + Presence.PRESENCE_STATUS + ") AS " 4414a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov// + Contacts.PRESENCE_STATUS); 4424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov// columns.put(Contacts.PRIMARY_PHONE_TYPE, CommonDataKinds.Phone.TYPE); 4434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov// columns.put(Contacts.PRIMARY_PHONE_LABEL, CommonDataKinds.Phone.LABEL); 4444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov// columns.put(Contacts.PRIMARY_PHONE_NUMBER, CommonDataKinds.Phone.NUMBER); 4454a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov// sContactsSummaryProjectionMap = columns; 44600d71133c63c882fb41729ddc3a52f66fb155374Evan Millar 4476cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov // RawContacts projection map 4484f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton columns = new HashMap<String, String>(); 4495ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov columns.put(RawContacts._ID, Tables.RAW_CONTACTS + "." + RawContacts._ID + " AS _id"); 450d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov columns.put(RawContacts.CONTACT_ID, RawContacts.CONTACT_ID); 4516cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov columns.put(RawContacts.ACCOUNT_NAME, 4525ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov OpenHelper.RawContactsColumns.CONCRETE_ACCOUNT_NAME 4535ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " AS " + RawContacts.ACCOUNT_NAME); 4546cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov columns.put(RawContacts.ACCOUNT_TYPE, 4555ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov OpenHelper.RawContactsColumns.CONCRETE_ACCOUNT_TYPE 4565ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " AS " + RawContacts.ACCOUNT_TYPE); 4576cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov columns.put(RawContacts.SOURCE_ID, 4585ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov OpenHelper.RawContactsColumns.CONCRETE_SOURCE_ID 4595ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " AS " + RawContacts.SOURCE_ID); 4606cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov columns.put(RawContacts.VERSION, 4615ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov OpenHelper.RawContactsColumns.CONCRETE_VERSION 4625ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " AS " + RawContacts.VERSION); 4636cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov columns.put(RawContacts.DIRTY, 4645ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov OpenHelper.RawContactsColumns.CONCRETE_DIRTY 4655ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " AS " + RawContacts.DIRTY); 46633b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov columns.put(RawContacts.DELETED, 4675ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov OpenHelper.RawContactsColumns.CONCRETE_DELETED 4685ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " AS " + RawContacts.DELETED); 4693cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(RawContacts.TIMES_CONTACTED, 4703cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.TIMES_CONTACTED 4713cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov + " AS " + People.TIMES_CONTACTED); 4723cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(RawContacts.LAST_TIME_CONTACTED, 4733cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.LAST_TIME_CONTACTED 4743cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov + " AS " + People.LAST_TIME_CONTACTED); 4753cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(RawContacts.CUSTOM_RINGTONE, 4763cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.CUSTOM_RINGTONE 4773cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov + " AS " + People.CUSTOM_RINGTONE); 4783cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(RawContacts.SEND_TO_VOICEMAIL, 4793cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.SEND_TO_VOICEMAIL 4803cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov + " AS " + People.SEND_TO_VOICEMAIL); 4813cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(RawContacts.STARRED, 4823cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.STARRED 4833cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov + " AS " + People.STARRED); 4843cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE); 4853cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(RawContacts.SYNC1, 4863cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.SYNC1 + " AS " + RawContacts.SYNC1); 4873cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(RawContacts.SYNC2, 4883cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.SYNC2 + " AS " + RawContacts.SYNC2); 4893cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(RawContacts.SYNC3, 4903cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.SYNC3 + " AS " + RawContacts.SYNC3); 4913cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(RawContacts.SYNC4, 4923cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.SYNC4 + " AS " + RawContacts.SYNC4); 4934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDeprecatedRawContactsProjectionMap = columns; 4944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 4954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap = new HashMap<String, String>(); 4964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts._ID, RawContacts._ID); 4974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.CONTACT_ID, RawContacts.CONTACT_ID); 4984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.ACCOUNT_NAME, RawContacts.ACCOUNT_NAME); 4994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.ACCOUNT_TYPE, RawContacts.ACCOUNT_TYPE); 5004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.SOURCE_ID, RawContacts.SOURCE_ID); 5014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.VERSION, RawContacts.VERSION); 5024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.DIRTY, RawContacts.DIRTY); 5034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.DELETED, RawContacts.DELETED); 5044a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.TIMES_CONTACTED, RawContacts.TIMES_CONTACTED); 5054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.LAST_TIME_CONTACTED, 5064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov RawContacts.LAST_TIME_CONTACTED); 5074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.CUSTOM_RINGTONE, RawContacts.CUSTOM_RINGTONE); 5084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.SEND_TO_VOICEMAIL, RawContacts.SEND_TO_VOICEMAIL); 5094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.STARRED, RawContacts.STARRED); 5104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE); 5114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.SYNC1, RawContacts.SYNC1); 5124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.SYNC2, RawContacts.SYNC2); 5134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.SYNC3, RawContacts.SYNC3); 5144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sRawContactsProjectionMap.put(RawContacts.SYNC4, RawContacts.SYNC4); 5152815f58f72f109790585931f601a63ddc02536a5Evan Millar 5164f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton // Data projection map 5174f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton columns = new HashMap<String, String>(); 5185ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov columns.put(Data._ID, Tables.DATA + "." + Data._ID + " AS _id"); 5195ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov columns.put(Data.RAW_CONTACT_ID, Data.RAW_CONTACT_ID); 52067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey columns.put(Data.RES_PACKAGE, PackagesColumns.PACKAGE + " AS " + Data.RES_PACKAGE); 521508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey columns.put(Data.MIMETYPE, Data.MIMETYPE); 522c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar columns.put(Data.IS_PRIMARY, Data.IS_PRIMARY); 523c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar columns.put(Data.IS_SUPER_PRIMARY, Data.IS_SUPER_PRIMARY); 524f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana columns.put(Data.DATA_VERSION, Data.DATA_VERSION); 5257e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana columns.put(Data.DATA1, "data.data1 as data1"); 5267e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana columns.put(Data.DATA2, "data.data2 as data2"); 5277e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana columns.put(Data.DATA3, "data.data3 as data3"); 5287e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana columns.put(Data.DATA4, "data.data4 as data4"); 5297e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana columns.put(Data.DATA5, "data.data5 as data5"); 5307e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana columns.put(Data.DATA6, "data.data6 as data6"); 5317e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana columns.put(Data.DATA7, "data.data7 as data7"); 5327e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana columns.put(Data.DATA8, "data.data8 as data8"); 5337e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana columns.put(Data.DATA9, "data.data9 as data9"); 5347e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana columns.put(Data.DATA10, "data.data10 as data10"); 53567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey columns.put(Data.DATA11, "data.data11 as data11"); 53667dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey columns.put(Data.DATA12, "data.data12 as data12"); 53767dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey columns.put(Data.DATA13, "data.data13 as data13"); 53867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey columns.put(Data.DATA14, "data.data14 as data14"); 53967dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey columns.put(Data.DATA15, "data.data15 as data15"); 5403cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(Data.SYNC1, Tables.DATA + "." + Data.SYNC1 + " AS " + Data.SYNC1); 5413cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(Data.SYNC2, Tables.DATA + "." + Data.SYNC2 + " AS " + Data.SYNC2); 5423cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(Data.SYNC3, Tables.DATA + "." + Data.SYNC3 + " AS " + Data.SYNC3); 5433cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(Data.SYNC4, Tables.DATA + "." + Data.SYNC4 + " AS " + Data.SYNC4); 54467dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey columns.put(GroupMembership.GROUP_SOURCE_ID, GroupsColumns.CONCRETE_SOURCE_ID + " AS " 54567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey + GroupMembership.GROUP_SOURCE_ID); 54620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 54720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov // TODO: remove this projection 548d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar // Mappings used for backwards compatibility. 549d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar columns.put("number", Phone.NUMBER); 5504a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDeprecatedDataGroupsProjectionMap = columns; 5514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 5524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap = new HashMap<String, String>(); 5534a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data._ID, Data._ID); 5544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.RAW_CONTACT_ID, Data.RAW_CONTACT_ID); 5554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA_VERSION, Data.DATA_VERSION); 5564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.IS_PRIMARY, Data.IS_PRIMARY); 5574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.IS_SUPER_PRIMARY, Data.IS_SUPER_PRIMARY); 5584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.RES_PACKAGE, Data.RES_PACKAGE); 5594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.MIMETYPE, Data.MIMETYPE); 5604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA1, Data.DATA1); 5614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA2, Data.DATA2); 5624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA3, Data.DATA3); 5634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA4, Data.DATA4); 5644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA5, Data.DATA5); 5654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA6, Data.DATA6); 5664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA7, Data.DATA7); 5674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA8, Data.DATA8); 5684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA9, Data.DATA9); 5694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA10, Data.DATA10); 5704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA11, Data.DATA11); 5714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA12, Data.DATA12); 5724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA13, Data.DATA13); 5734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA14, Data.DATA14); 5744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.DATA15, Data.DATA15); 5754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.SYNC1, Data.SYNC1); 5764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.SYNC2, Data.SYNC2); 5774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.SYNC3, Data.SYNC3); 5784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Data.SYNC4, Data.SYNC4); 5794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(RawContacts.CONTACT_ID, RawContacts.CONTACT_ID); 5804a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(RawContacts.ACCOUNT_NAME, RawContacts.ACCOUNT_NAME); 5814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(RawContacts.ACCOUNT_TYPE, RawContacts.ACCOUNT_TYPE); 5824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(RawContacts.SOURCE_ID, RawContacts.SOURCE_ID); 5834a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(RawContacts.VERSION, RawContacts.VERSION); 5844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(RawContacts.DIRTY, RawContacts.DIRTY); 5854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Contacts.DISPLAY_NAME, Contacts.DISPLAY_NAME); 5864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Contacts.CUSTOM_RINGTONE, Contacts.CUSTOM_RINGTONE); 5874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Contacts.SEND_TO_VOICEMAIL, Contacts.SEND_TO_VOICEMAIL); 5884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Contacts.LAST_TIME_CONTACTED, Contacts.LAST_TIME_CONTACTED); 5894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Contacts.TIMES_CONTACTED, Contacts.TIMES_CONTACTED); 5904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Contacts.STARRED, Contacts.STARRED); 5914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(Contacts.PHOTO_ID, Contacts.PHOTO_ID); 5924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sDataProjectionMap.put(GroupMembership.GROUP_SOURCE_ID, GroupMembership.GROUP_SOURCE_ID); 593a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton 5949261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana // Data, groups and contacts projection map for joins. _id comes from the data table 595a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton columns = new HashMap<String, String>(); 5964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov columns.putAll(sDeprecatedRawContactsProjectionMap); 59799a9b5ec879f6cd6876f7f6b680b82d8304e6b92Dmitri Plotnikov columns.putAll(sDeprecatedDataGroupsProjectionMap); 598d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov columns.put(Data.RAW_CONTACT_ID, DataColumns.CONCRETE_RAW_CONTACT_ID); 5990c83a3c4b6a9c8a0dfa0b3aa2af91b74d8e3304fEvan Millar sDataRawContactsGroupsProjectionMap = columns; 6009261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana 6019261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana // Data and contacts projection map for joins. _id comes from the data table 6029261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana columns = new HashMap<String, String>(); 6030c83a3c4b6a9c8a0dfa0b3aa2af91b74d8e3304fEvan Millar columns.putAll(sDataRawContactsGroupsProjectionMap); 6049261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana columns.remove(GroupMembership.GROUP_SOURCE_ID); 6050c83a3c4b6a9c8a0dfa0b3aa2af91b74d8e3304fEvan Millar sDataRawContactsProjectionMap = columns; 6067e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 607ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey // Groups projection map 608ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey columns = new HashMap<String, String>(); 609ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey columns.put(Groups._ID, "groups._id AS _id"); 610035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana columns.put(Groups.ACCOUNT_NAME, Groups.ACCOUNT_NAME); 611035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana columns.put(Groups.ACCOUNT_TYPE, Groups.ACCOUNT_TYPE); 6129261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana columns.put(Groups.SOURCE_ID, Groups.SOURCE_ID); 6139261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana columns.put(Groups.DIRTY, Groups.DIRTY); 6149261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana columns.put(Groups.VERSION, Groups.VERSION); 61567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey columns.put(Groups.RES_PACKAGE, PackagesColumns.PACKAGE + " AS " + Groups.RES_PACKAGE); 616ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey columns.put(Groups.TITLE, Groups.TITLE); 61767dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey columns.put(Groups.TITLE_RES, Groups.TITLE_RES); 618ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey columns.put(Groups.GROUP_VISIBLE, Groups.GROUP_VISIBLE); 6193cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(Groups.SYSTEM_ID, Groups.SYSTEM_ID); 62094021b213e4db367f60b30fcbfe9019e28571784Fred Quintana columns.put(Groups.DELETED, Groups.DELETED); 6213cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(Groups.NOTES, Groups.NOTES); 6223cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(Groups.SYNC1, Tables.GROUPS + "." + Groups.SYNC1 + " AS " + Groups.SYNC1); 6233cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(Groups.SYNC2, Tables.GROUPS + "." + Groups.SYNC2 + " AS " + Groups.SYNC2); 6243cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(Groups.SYNC3, Tables.GROUPS + "." + Groups.SYNC3 + " AS " + Groups.SYNC3); 6253cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov columns.put(Groups.SYNC4, Tables.GROUPS + "." + Groups.SYNC4 + " AS " + Groups.SYNC4); 626ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey sGroupsProjectionMap = columns; 627ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 6286cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov // RawContacts and groups projection map 629ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey columns = new HashMap<String, String>(); 630ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey columns.putAll(sGroupsProjectionMap); 631ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 632d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov columns.put(Groups.SUMMARY_COUNT, "(SELECT COUNT(DISTINCT " + ContactsColumns.CONCRETE_ID 633d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + ") FROM " + Tables.DATA_JOIN_MIMETYPES_RAW_CONTACTS_CONTACTS + " WHERE " 634ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + Clauses.MIMETYPE_IS_GROUP_MEMBERSHIP + " AND " + Clauses.BELONGS_TO_GROUP 635ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + ") AS " + Groups.SUMMARY_COUNT); 636ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 637ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey columns.put(Groups.SUMMARY_WITH_PHONES, "(SELECT COUNT(DISTINCT " 638d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + ContactsColumns.CONCRETE_ID + ") FROM " 639d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Tables.DATA_JOIN_MIMETYPES_RAW_CONTACTS_CONTACTS + " WHERE " 640ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + Clauses.MIMETYPE_IS_GROUP_MEMBERSHIP + " AND " + Clauses.BELONGS_TO_GROUP 641f992bfab334b760d36a053fc0b439382dcfb51adDmitri Plotnikov + " AND " + Contacts.HAS_PHONE_NUMBER + ") AS " + Groups.SUMMARY_WITH_PHONES); 642ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 643ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey sGroupsSummaryProjectionMap = columns; 644ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 645b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov // Aggregate exception projection map 646b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov columns = new HashMap<String, String>(); 647b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov columns.put(AggregationExceptionColumns._ID, Tables.AGGREGATION_EXCEPTIONS + "._id AS _id"); 648b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov columns.put(AggregationExceptions.TYPE, AggregationExceptions.TYPE); 649d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov columns.put(AggregationExceptions.CONTACT_ID, 650d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov "raw_contacts1." + RawContacts.CONTACT_ID 651d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + " AS " + AggregationExceptions.CONTACT_ID); 6525ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov columns.put(AggregationExceptions.RAW_CONTACT_ID, AggregationExceptionColumns.RAW_CONTACT_ID2); 653b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov sAggregationExceptionsProjectionMap = columns; 654b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 655373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov 656373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov columns = new HashMap<String, String>(); 657373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov columns.put(Presence._ID, Presence._ID); 658373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov columns.put(Presence.RAW_CONTACT_ID, Presence.RAW_CONTACT_ID); 659373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov columns.put(Presence.DATA_ID, Presence.DATA_ID); 660373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov columns.put(Presence.IM_ACCOUNT, Presence.IM_ACCOUNT); 661373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov columns.put(Presence.IM_HANDLE, Presence.IM_HANDLE); 662373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov columns.put(Presence.IM_PROTOCOL, Presence.IM_PROTOCOL); 663373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov columns.put(Presence.PRESENCE_STATUS, Presence.PRESENCE_STATUS); 664373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov columns.put(Presence.PRESENCE_CUSTOM_STATUS, Presence.PRESENCE_CUSTOM_STATUS); 665373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov sPresenceProjectionMap = columns; 666373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov 667d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov sNestedRawContactIdSelect = "SELECT " + Data.RAW_CONTACT_ID + " FROM " + Tables.DATA + " WHERE " 668c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar + Data._ID + "=?"; 669c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar sNestedMimetypeSelect = "SELECT " + DataColumns.MIMETYPE_ID + " FROM " + Tables.DATA 670c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar + " WHERE " + Data._ID + "=?"; 671d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov sNestedContactIdSelect = "SELECT " + RawContacts.CONTACT_ID + " FROM " + Tables.RAW_CONTACTS 672d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + " WHERE " + RawContacts._ID + "=(" + sNestedRawContactIdSelect + ")"; 6735ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov sNestedContactIdListSelect = "SELECT " + RawContacts._ID + " FROM " + Tables.RAW_CONTACTS 674d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + " WHERE " + RawContacts.CONTACT_ID + "=(" + sNestedContactIdSelect + ")"; 675d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov sSetPrimaryWhere = Data.RAW_CONTACT_ID + "=(" + sNestedRawContactIdSelect + ") AND " 676c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar + DataColumns.MIMETYPE_ID + "=(" + sNestedMimetypeSelect + ")"; 6775ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov sSetSuperPrimaryWhere = Data.RAW_CONTACT_ID + " IN (" + sNestedContactIdListSelect + ") AND " 678c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar + DataColumns.MIMETYPE_ID + "=(" + sNestedMimetypeSelect + ")"; 6794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sContactsInGroupSelect = Contacts._ID + " IN " 6804a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + "(SELECT " + RawContacts.CONTACT_ID 6814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " FROM " + Tables.RAW_CONTACTS 6824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " WHERE " + RawContactsColumns.CONCRETE_ID + " IN " 6834a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + "(SELECT " + DataColumns.CONCRETE_RAW_CONTACT_ID 6844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " FROM " + Tables.DATA_JOIN_MIMETYPES 6854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " WHERE " + Data.MIMETYPE + "='" + GroupMembership.CONTENT_ITEM_TYPE 6864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + "' AND " + GroupMembership.GROUP_ROW_ID + "=" 6874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + "(SELECT " + Tables.GROUPS + "." + Groups._ID 6884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " FROM " + Tables.GROUPS 6894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " WHERE " + Groups.TITLE + "=?)))"; 6904f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 6914f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 6923cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov /** 6933cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov * Handles inserts and update for a specific Data type. 6943cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov */ 6953cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov private abstract class DataRowHandler { 6963cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 6973cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov protected final String mMimetype; 6983cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 6993cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public DataRowHandler(String mimetype) { 7003cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov mMimetype = mimetype; 7013cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 7023cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 7033cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov /** 7043cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov * Inserts a row into the {@link Data} table. 7053cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov */ 7065ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public long insert(SQLiteDatabase db, long rawContactId, ContentValues values) { 707e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov final long dataId = db.insert(Tables.DATA, null, values); 708e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 709e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov Integer primary = values.getAsInteger(Data.IS_PRIMARY); 710e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov if (primary != null && primary != 0) { 711e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov setIsPrimary(dataId); 712e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 713e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 7145ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov fixContactDisplayName(db, rawContactId); 715e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov return dataId; 7163cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 7173cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 7183cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov /** 7193cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov * Validates data and updates a {@link Data} row using the cursor, which contains 7203cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov * the current data. 7213cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov */ 7223cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public void update(SQLiteDatabase db, ContentValues values, Cursor cursor) { 7233cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov throw new UnsupportedOperationException(); 7243cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 7253cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 7263cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public int delete(SQLiteDatabase db, Cursor c) { 7273cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov long dataId = c.getLong(DataQuery.ID); 7285ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov long rawContactId = c.getLong(DataQuery.RAW_CONTACT_ID); 7293cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov boolean primary = c.getInt(DataQuery.IS_PRIMARY) != 0; 7303cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov int count = db.delete(Tables.DATA, Data._ID + "=" + dataId, null); 7313cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (count != 0 && primary) { 7325ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov fixPrimary(db, rawContactId); 7335ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov fixContactDisplayName(db, rawContactId); 7343cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 7353cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov return count; 7363cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 7373cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 7385ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov private void fixPrimary(SQLiteDatabase db, long rawContactId) { 7395ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov long newPrimaryId = findNewPrimaryDataId(db, rawContactId); 7403cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (newPrimaryId != -1) { 7413cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov ContactsProvider2.this.setIsPrimary(newPrimaryId); 7423cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 7433cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 7443cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 7455ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov protected long findNewPrimaryDataId(SQLiteDatabase db, long rawContactId) { 746e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov long primaryId = -1; 747e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov int primaryType = -1; 7485ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Cursor c = queryData(db, rawContactId); 7493cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov try { 750e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov while (c.moveToNext()) { 751e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov long dataId = c.getLong(DataQuery.ID); 752e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov int type = c.getInt(DataQuery.DATA2); 753e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov if (primaryType == -1 || getTypeRank(type) < getTypeRank(primaryType)) { 754e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov primaryId = dataId; 755e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov primaryType = type; 756e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 7573cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 7583cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } finally { 7593cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov c.close(); 7603cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 761e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov return primaryId; 762e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 763e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 764e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov /** 765e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov * Returns the rank of a specific record type to be used in determining the primary 766e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov * row. Lower number represents higher priority. 767e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov */ 768e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov protected int getTypeRank(int type) { 769e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov return 0; 7703cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 7713cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 7725ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov protected Cursor queryData(SQLiteDatabase db, long rawContactId) { 77388e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov return db.query(DataQuery.TABLE, DataQuery.CONCRETE_COLUMNS, Data.RAW_CONTACT_ID + "=" 7745ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + rawContactId + " AND " + MimetypesColumns.MIMETYPE + "='" + mMimetype + "'", 7753cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov null, null, null, null); 7763cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 7773cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 7785ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov protected void fixContactDisplayName(SQLiteDatabase db, long rawContactId) { 779e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov if (!sDisplayNamePriorities.containsKey(mMimetype)) { 780e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov return; 781e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 782e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 7833cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov String bestDisplayName = null; 78467dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Cursor c = db.query(DisplayNameQuery.TABLE, DisplayNameQuery.COLUMNS, 7855ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Data.RAW_CONTACT_ID + "=" + rawContactId, null, null, null, null); 7863cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov try { 7873cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov int maxPriority = -1; 7883cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov while (c.moveToNext()) { 7893cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov String mimeType = c.getString(DisplayNameQuery.MIMETYPE); 7903cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov boolean primary; 7913cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov String name; 7923cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 7933cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (StructuredName.CONTENT_ITEM_TYPE.equals(mimeType)) { 7943cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov name = c.getString(DisplayNameQuery.DISPLAY_NAME); 7953cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov primary = true; 7963cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } else { 7973cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov name = c.getString(DisplayNameQuery.DATA2); 7983cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov primary = (c.getInt(DisplayNameQuery.IS_PRIMARY) != 0); 7993cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 8003cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 8013cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (primary && name != null) { 8023cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov Integer priority = sDisplayNamePriorities.get(mimeType); 8033cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (priority != null && priority > maxPriority) { 8043cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov maxPriority = priority; 8053cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov bestDisplayName = name; 8063cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 8073cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 8083cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 8093cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 8103cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } finally { 8113cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov c.close(); 8123cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 8133cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 8145ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov ContactsProvider2.this.setDisplayName(rawContactId, bestDisplayName); 8153cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 8163cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 8173cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 8183cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public class CustomDataRowHandler extends DataRowHandler { 8193cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 8203cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public CustomDataRowHandler(String mimetype) { 8213cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov super(mimetype); 8223cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 8233cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 8243cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 8253cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public class StructuredNameRowHandler extends DataRowHandler { 8263cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 8273cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov private final NameSplitter mNameSplitter; 8283cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 8293cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public StructuredNameRowHandler(NameSplitter nameSplitter) { 8303cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov super(StructuredName.CONTENT_ITEM_TYPE); 8313cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov mNameSplitter = nameSplitter; 8323cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 8333cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 8343cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov @Override 8355ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public long insert(SQLiteDatabase db, long rawContactId, ContentValues values) { 8363cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov fixStructuredNameComponents(values); 8375ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov return super.insert(db, rawContactId, values); 8383cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 8393cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 8403cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov @Override 8413cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public void update(SQLiteDatabase db, ContentValues values, Cursor cursor) { 8423cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov // TODO Parse the full name if it has changed and replace pre-existing piece parts. 8433cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 8443cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 8453cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov /** 8463cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov * Parses the supplied display name, but only if the incoming values do not already contain 8473cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov * structured name parts. Also, if the display name is not provided, generate one by 8483cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov * concatenating first name and last name 8493cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov * 8503cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov * TODO see if the order of first and last names needs to be conditionally reversed for 8513cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov * some locales, e.g. China. 8523cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov */ 8533cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov private void fixStructuredNameComponents(ContentValues values) { 8543cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov String fullName = values.getAsString(StructuredName.DISPLAY_NAME); 8553cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (!TextUtils.isEmpty(fullName) 8563cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov && TextUtils.isEmpty(values.getAsString(StructuredName.PREFIX)) 8573cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov && TextUtils.isEmpty(values.getAsString(StructuredName.GIVEN_NAME)) 8583cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov && TextUtils.isEmpty(values.getAsString(StructuredName.MIDDLE_NAME)) 8593cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov && TextUtils.isEmpty(values.getAsString(StructuredName.FAMILY_NAME)) 8603cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov && TextUtils.isEmpty(values.getAsString(StructuredName.SUFFIX))) { 8613cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov NameSplitter.Name name = new NameSplitter.Name(); 8623cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov mNameSplitter.split(name, fullName); 8633cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 8643cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov values.put(StructuredName.PREFIX, name.getPrefix()); 8653cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov values.put(StructuredName.GIVEN_NAME, name.getGivenNames()); 8663cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov values.put(StructuredName.MIDDLE_NAME, name.getMiddleName()); 8673cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov values.put(StructuredName.FAMILY_NAME, name.getFamilyName()); 8683cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov values.put(StructuredName.SUFFIX, name.getSuffix()); 8693cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 8703cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 8713cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (TextUtils.isEmpty(fullName)) { 8723cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov String givenName = values.getAsString(StructuredName.GIVEN_NAME); 8733cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov String familyName = values.getAsString(StructuredName.FAMILY_NAME); 8743cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (TextUtils.isEmpty(givenName)) { 8753cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov fullName = familyName; 8763cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } else if (TextUtils.isEmpty(familyName)) { 8773cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov fullName = givenName; 8783cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } else { 8793cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov fullName = givenName + " " + familyName; 8803cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 8813cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 8823cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (!TextUtils.isEmpty(fullName)) { 8833cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov values.put(StructuredName.DISPLAY_NAME, fullName); 8843cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 8853cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 8863cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 8873cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 8883cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 8893cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public class CommonDataRowHandler extends DataRowHandler { 8903cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 8913cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov private final String mTypeColumn; 8923cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov private final String mLabelColumn; 8933cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 8943cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public CommonDataRowHandler(String mimetype, String typeColumn, String labelColumn) { 8953cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov super(mimetype); 8963cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov mTypeColumn = typeColumn; 8973cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov mLabelColumn = labelColumn; 8983cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 8993cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 9003cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov @Override 9015ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public long insert(SQLiteDatabase db, long rawContactId, ContentValues values) { 9023cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov int type; 9033cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov String label; 9043cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (values.containsKey(mTypeColumn)) { 9053cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov type = values.getAsInteger(mTypeColumn); 9063cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } else { 9073cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov type = BaseTypes.TYPE_CUSTOM; 9083cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9093cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (values.containsKey(mLabelColumn)) { 9103cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov label = values.getAsString(mLabelColumn); 9113cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } else { 9123cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov label = null; 9133cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9143cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 9153cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (type != BaseTypes.TYPE_CUSTOM && label != null) { 9167a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana throw new IllegalArgumentException(mLabelColumn + " value can only be specified with " 9173cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov + mTypeColumn + "=" + BaseTypes.TYPE_CUSTOM + "(custom)"); 9183cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9193cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 9203cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (type == BaseTypes.TYPE_CUSTOM && label == null) { 9217a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana throw new IllegalArgumentException(mLabelColumn + " value must be specified when " 9223cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov + mTypeColumn + "=" + BaseTypes.TYPE_CUSTOM + "(custom)"); 9233cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9243cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 9255ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov return super.insert(db, rawContactId, values); 9263cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9273cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 9283cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov @Override 9293cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public void update(SQLiteDatabase db, ContentValues values, Cursor cursor) { 9303cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov // TODO read the data and check the constraint 9313cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9323cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9333cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 9343cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public class OrganizationDataRowHandler extends CommonDataRowHandler { 9353cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 9363cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public OrganizationDataRowHandler() { 9373cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov super(Organization.CONTENT_ITEM_TYPE, Organization.TYPE, Organization.LABEL); 9383cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9393cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 9403cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov @Override 9415ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public long insert(SQLiteDatabase db, long rawContactId, ContentValues values) { 9425ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov long id = super.insert(db, rawContactId, values); 9435ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov fixContactDisplayName(db, rawContactId); 9443cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov return id; 9453cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9463cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 9473cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov @Override 9483cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov protected int getTypeRank(int type) { 9493cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov switch (type) { 9503cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov case Organization.TYPE_WORK: return 0; 9513cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov case Organization.TYPE_CUSTOM: return 1; 9523cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov case Organization.TYPE_OTHER: return 2; 9533cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov default: return 1000; 9543cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9553cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9563cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9573cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 958e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public class EmailDataRowHandler extends CommonDataRowHandler { 959e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 960e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public EmailDataRowHandler() { 961e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov super(Email.CONTENT_ITEM_TYPE, Email.TYPE, Email.LABEL); 962e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 963e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 964e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov @Override 9655ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public long insert(SQLiteDatabase db, long rawContactId, ContentValues values) { 9665ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov long id = super.insert(db, rawContactId, values); 9675ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov fixContactDisplayName(db, rawContactId); 968e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov return id; 969e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 970e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 971e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov @Override 972e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov protected int getTypeRank(int type) { 973e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov switch (type) { 974e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov case Email.TYPE_HOME: return 0; 975e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov case Email.TYPE_WORK: return 1; 976e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov case Email.TYPE_CUSTOM: return 2; 977e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov case Email.TYPE_OTHER: return 3; 978e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov default: return 1000; 979e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 980e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 981e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 982e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 9833cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public class PhoneDataRowHandler extends CommonDataRowHandler { 9843cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 9853cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public PhoneDataRowHandler() { 9863cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov super(Phone.CONTENT_ITEM_TYPE, Phone.TYPE, Phone.LABEL); 9873cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 9883cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 9893cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov @Override 9905ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public long insert(SQLiteDatabase db, long rawContactId, ContentValues values) { 991e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov ContentValues phoneValues = new ContentValues(); 992e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov String number = values.getAsString(Phone.NUMBER); 993e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov String normalizedNumber = null; 994e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov if (number != null) { 995e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov normalizedNumber = PhoneNumberUtils.getStrippedReversed(number); 996e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov values.put(PhoneColumns.NORMALIZED_NUMBER, normalizedNumber); 997e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 998e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 9995ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov long id = super.insert(db, rawContactId, values); 10003cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 1001e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov if (number != null) { 10025ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov phoneValues.put(PhoneLookupColumns.RAW_CONTACT_ID, rawContactId); 1003e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov phoneValues.put(PhoneLookupColumns.DATA_ID, id); 1004e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov phoneValues.put(PhoneLookupColumns.NORMALIZED_NUMBER, normalizedNumber); 1005e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov db.insert(Tables.PHONE_LOOKUP, null, phoneValues); 1006e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 10073cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 10083cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov return id; 10093cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 10103cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 10113cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov @Override 10123cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov protected int getTypeRank(int type) { 10133cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov switch (type) { 10143cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov case Phone.TYPE_MOBILE: return 0; 10153cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov case Phone.TYPE_WORK: return 1; 10163cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov case Phone.TYPE_HOME: return 2; 10173cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov case Phone.TYPE_PAGER: return 3; 10183cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov case Phone.TYPE_CUSTOM: return 4; 10193cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov case Phone.TYPE_OTHER: return 5; 10203cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov case Phone.TYPE_FAX_WORK: return 6; 10213cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov case Phone.TYPE_FAX_HOME: return 7; 10223cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov default: return 1000; 10233cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 10243cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 10253cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 10263cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 10273cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov private HashMap<String, DataRowHandler> mDataRowHandlers; 102853056d49d8adf5d1fe2d18cb60c3c26f281e7a6cDmitri Plotnikov private final ContactAggregationScheduler mAggregationScheduler; 10294f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton private OpenHelper mOpenHelper; 103031b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov 1031a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov private ContactAggregator mContactAggregator; 10324097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov private NameSplitter mNameSplitter; 1033f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov private LegacyApiSupport mLegacyApiSupport; 1034a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov private GlobalSearchSupport mGlobalSearchSupport; 1035a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 103620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov private ContentValues mValues = new ContentValues(); 103720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 103873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov private boolean mImportMode; 103973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov 1040de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov private boolean mScheduleAggregation; 1041de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov 1042a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public ContactsProvider2() { 104353056d49d8adf5d1fe2d18cb60c3c26f281e7a6cDmitri Plotnikov this(new ContactAggregationScheduler()); 1044a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 1045a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 1046a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov /** 1047a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov * Constructor for testing. 1048a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov */ 104953056d49d8adf5d1fe2d18cb60c3c26f281e7a6cDmitri Plotnikov /* package */ ContactsProvider2(ContactAggregationScheduler scheduler) { 105053056d49d8adf5d1fe2d18cb60c3c26f281e7a6cDmitri Plotnikov mAggregationScheduler = scheduler; 1051a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 10524f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 10534f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton @Override 10544f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton public boolean onCreate() { 1055de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov super.onCreate(); 105635ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 1057de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov final Context context = getContext(); 1058de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mOpenHelper = (OpenHelper)getOpenHelper(); 1059a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov mGlobalSearchSupport = new GlobalSearchSupport(this); 1060a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov mLegacyApiSupport = new LegacyApiSupport(context, mOpenHelper, this, mGlobalSearchSupport); 106153056d49d8adf5d1fe2d18cb60c3c26f281e7a6cDmitri Plotnikov mContactAggregator = new ContactAggregator(context, mOpenHelper, mAggregationScheduler); 1062a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 1063d51a83ac4f8032b62d9a23b90a8f43d6b7eb2dbbDmitri Plotnikov final SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 1064c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar mSetPrimaryStatement = db.compileStatement( 1065c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar "UPDATE " + Tables.DATA + " SET " + Data.IS_PRIMARY 1066c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar + "=(_id=?) WHERE " + sSetPrimaryWhere); 1067c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar mSetSuperPrimaryStatement = db.compileStatement( 1068c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar "UPDATE " + Tables.DATA + " SET " + Data.IS_SUPER_PRIMARY 1069c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar + "=(_id=?) WHERE " + sSetSuperPrimaryWhere); 10705ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov mLastTimeContactedUpdate = db.compileStatement("UPDATE " + Tables.RAW_CONTACTS + " SET " 10716cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov + RawContacts.TIMES_CONTACTED + "=" + RawContacts.TIMES_CONTACTED + "+1," 1072d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + RawContacts.LAST_TIME_CONTACTED + "=? WHERE " + RawContacts.CONTACT_ID + "=?"); 1073a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 10745ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov mContactDisplayNameUpdate = db.compileStatement("UPDATE " + Tables.RAW_CONTACTS + " SET " 10756cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov + RawContactsColumns.DISPLAY_NAME + "=? WHERE " + RawContacts._ID + "=?"); 10763cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 107773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov mRawContactDirtyUpdate = db.compileStatement("UPDATE " + Tables.RAW_CONTACTS + " SET " 107873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov + RawContacts.DIRTY + "=1 WHERE " + RawContacts._ID + "=?"); 107973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov 108028f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar mNameSplitter = new NameSplitter( 108128f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar context.getString(com.android.internal.R.string.common_name_prefixes), 108228f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar context.getString(com.android.internal.R.string.common_last_name_prefixes), 108328f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar context.getString(com.android.internal.R.string.common_name_suffixes), 108428f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar context.getString(com.android.internal.R.string.common_name_conjunctions)); 10854097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov 10863cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov mDataRowHandlers = new HashMap<String, DataRowHandler>(); 10873cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 1088e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov mDataRowHandlers.put(Email.CONTENT_ITEM_TYPE, new EmailDataRowHandler()); 10893cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov mDataRowHandlers.put(Im.CONTENT_ITEM_TYPE, 10903cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov new CommonDataRowHandler(Im.CONTENT_ITEM_TYPE, Im.TYPE, Im.LABEL)); 109167dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey mDataRowHandlers.put(Nickname.CONTENT_ITEM_TYPE, new CommonDataRowHandler( 109267dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey StructuredPostal.CONTENT_ITEM_TYPE, StructuredPostal.TYPE, StructuredPostal.LABEL)); 10933cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov mDataRowHandlers.put(Organization.CONTENT_ITEM_TYPE, new OrganizationDataRowHandler()); 10943cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov mDataRowHandlers.put(Phone.CONTENT_ITEM_TYPE, new PhoneDataRowHandler()); 109567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey mDataRowHandlers.put(Nickname.CONTENT_ITEM_TYPE, new CommonDataRowHandler( 109667dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Nickname.CONTENT_ITEM_TYPE, Nickname.TYPE, Nickname.LABEL)); 10973cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov mDataRowHandlers.put(StructuredName.CONTENT_ITEM_TYPE, 10983cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov new StructuredNameRowHandler(mNameSplitter)); 10993cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 11003d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov if (isLegacyContactImportNeeded()) { 11013d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov if (!importLegacyContacts()) { 11023d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov return false; 11033d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov } 11043d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov } 11051f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey return (db != null); 11064f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 11074f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 110831b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov /* Visible for testing */ 1109de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov @Override 111031b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov protected OpenHelper getOpenHelper(final Context context) { 111131b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov return OpenHelper.getInstance(context); 111231b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov } 111331b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov 1114013a0d6b3d392fb49d4618f2527b2ed3fec7d34fDmitri Plotnikov /* package */ NameSplitter getNameSplitter() { 1115013a0d6b3d392fb49d4618f2527b2ed3fec7d34fDmitri Plotnikov return mNameSplitter; 1116013a0d6b3d392fb49d4618f2527b2ed3fec7d34fDmitri Plotnikov } 1117013a0d6b3d392fb49d4618f2527b2ed3fec7d34fDmitri Plotnikov 11183d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov protected boolean isLegacyContactImportNeeded() { 11193d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); 11203d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov return prefs.getInt(PREF_CONTACTS_IMPORTED, 0) < PREF_CONTACTS_IMPORT_VERSION; 11213d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov } 11223d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov 11233d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov private boolean importLegacyContacts() { 1124013a0d6b3d392fb49d4618f2527b2ed3fec7d34fDmitri Plotnikov if (importLegacyContacts(getLegacyContactImporter(), true)) { 11253d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); 11263d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov Editor editor = prefs.edit(); 11273d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov editor.putInt(PREF_CONTACTS_IMPORTED, PREF_CONTACTS_IMPORT_VERSION); 11283d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov editor.commit(); 11293d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov return true; 11303d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov } else { 11313d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov return false; 11323d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov } 11333d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov } 11343d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov 11353d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov protected LegacyContactImporter getLegacyContactImporter() { 11363d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov return new LegacyContactImporter(getContext(), this); 11373d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov } 11383d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov 11393d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov /* Visible for testing */ 1140013a0d6b3d392fb49d4618f2527b2ed3fec7d34fDmitri Plotnikov /* package */ boolean importLegacyContacts(LegacyContactImporter importer, boolean aggregate) { 11413d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov mContactAggregator.setEnabled(false); 114273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov mImportMode = true; 11433d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov try { 11443d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov importer.importContacts(); 11453d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov mContactAggregator.setEnabled(true); 1146013a0d6b3d392fb49d4618f2527b2ed3fec7d34fDmitri Plotnikov if (aggregate) { 1147013a0d6b3d392fb49d4618f2527b2ed3fec7d34fDmitri Plotnikov mContactAggregator.run(); 1148013a0d6b3d392fb49d4618f2527b2ed3fec7d34fDmitri Plotnikov } 11493d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov return true; 11503d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov } catch (Throwable e) { 11513d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov Log.e(TAG, "Legacy contact import failed", e); 11523d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov return false; 115373776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov } finally { 115473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov mImportMode = false; 11553d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov } 11563d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov } 11573d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov 1158a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov @Override 1159a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov protected void finalize() throws Throwable { 1160a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov if (mContactAggregator != null) { 1161a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov mContactAggregator.quit(); 1162a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 1163a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 1164a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov super.finalize(); 1165a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 1166a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 1167a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov /** 1168a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov * Wipes all data from the contacts database. 1169a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov */ 1170a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov /* package */ void wipeData() { 1171a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov mOpenHelper.wipeData(); 1172a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 1173a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 11744f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton @Override 1175de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov protected void onTransactionComplete() { 1176de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov if (mScheduleAggregation) { 1177de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mScheduleAggregation = false; 1178de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mContactAggregator.schedule(); 1179de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov } 1180de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov super.onTransactionComplete(); 11814f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 11824f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 11833cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov private DataRowHandler getDataRowHandler(final String mimeType) { 11843cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov DataRowHandler handler = mDataRowHandlers.get(mimeType); 11853cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (handler == null) { 11863cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov handler = new CustomDataRowHandler(mimeType); 11873cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov mDataRowHandlers.put(mimeType, handler); 11883cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 11893cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov return handler; 11903cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 11913cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 11924f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton @Override 1193de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov protected Uri insertInTransaction(Uri uri, ContentValues values) { 1194a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton final int match = sUriMatcher.match(uri); 1195a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton long id = 0; 119635ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 1197a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton switch (match) { 119835ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana case SYNCSTATE: 1199de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov id = mOpenHelper.getSyncState().insert(mDb, values); 120035ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana break; 120135ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 1202d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov case CONTACTS: { 1203d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov insertContact(values); 12046bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov break; 12056bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov } 12066bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov 12075ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case RAW_CONTACTS: { 1208f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana final Account account = readAccountFromQueryParams(uri); 1209d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov id = insertRawContact(values, account); 1210a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton break; 1211a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton } 1212a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton 12135ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case RAW_CONTACTS_DATA: { 12145ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov values.put(Data.RAW_CONTACT_ID, uri.getPathSegments().get(1)); 121573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov id = insertData(values, shouldMarkRawContactAsDirty(uri)); 1216a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton break; 1217a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton } 1218a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton 1219a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton case DATA: { 122073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov id = insertData(values, shouldMarkRawContactAsDirty(uri)); 1221a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton break; 1222a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton } 1223a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton 1224ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey case GROUPS: { 1225ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey final Account account = readAccountFromQueryParams(uri); 122673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov id = insertGroup(values, account, shouldMarkGroupAsDirty(uri)); 1227ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey break; 1228ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 1229ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 12301f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey case PRESENCE: { 12311f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey id = insertPresence(values); 12321f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey break; 12331f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } 12341f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 1235a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton default: 1236f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov return mLegacyApiSupport.insert(uri, values); 1237a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton } 1238a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton 12397e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana if (id < 0) { 12407e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana return null; 12417e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 12427e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 1243de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov return ContentUris.withAppendedId(uri, id); 1244a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton } 1245a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton 1246a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton /** 1247035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana * If account is non-null then store it in the values. If the account is already 1248035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana * specified in the values then it must be consistent with the account, if it is non-null. 1249035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana * @param values the ContentValues to read from and update 1250035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana * @param account the explicitly provided Account 1251035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana * @return false if the accounts are inconsistent 12527e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana */ 1253035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana private boolean resolveAccount(ContentValues values, Account account) { 1254035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana // If either is specified then both must be specified. 12556cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov final String accountName = values.getAsString(RawContacts.ACCOUNT_NAME); 12566cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov final String accountType = values.getAsString(RawContacts.ACCOUNT_TYPE); 1257035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana if (!TextUtils.isEmpty(accountName) || !TextUtils.isEmpty(accountType)) { 1258035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana final Account valuesAccount = new Account(accountName, accountType); 1259035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana if (account != null && !valuesAccount.equals(account)) { 1260035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana return false; 1261035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana } 1262035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana account = valuesAccount; 1263035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana } 1264035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana if (account != null) { 12656cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov values.put(RawContacts.ACCOUNT_NAME, account.mName); 12666cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov values.put(RawContacts.ACCOUNT_TYPE, account.mType); 1267035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana } 1268035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana return true; 12697e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 12707e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 12717e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana /** 1272d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov * Inserts an item in the contacts table 12736bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov * 12746bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov * @param values the values for the new row 12756bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov * @return the row ID of the newly created row 12766bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov */ 1277d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private long insertContact(ContentValues values) { 1278de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov throw new UnsupportedOperationException("Aggregate contacts are created automatically"); 12796bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov } 12806bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov 12816bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov /** 1282a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton * Inserts an item in the contacts table 1283a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton * 1284a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton * @param values the values for the new row 1285f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana * @param account the account this contact should be associated with. may be null. 1286a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton * @return the row ID of the newly created row 1287a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton */ 1288d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private long insertRawContact(ContentValues values, Account account) { 12896bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov /* 12906bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov * The contact record is inserted in the contacts table, but it needs to 12916bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov * be processed by the aggregator before it will be returned by the 12926bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov * "aggregates" queries. 12936bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov */ 1294a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov ContentValues overriddenValues = new ContentValues(values); 1295d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov overriddenValues.putNull(RawContacts.CONTACT_ID); 1296f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana if (!resolveAccount(overriddenValues, account)) { 12977e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana return -1; 12987e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 12997e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 13003d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov if (values.containsKey(RawContacts.DELETED) 13013d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov && values.getAsInteger(RawContacts.DELETED) != 0) { 13023d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov overriddenValues.put(RawContacts.AGGREGATION_MODE, 13033d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov RawContacts.AGGREGATION_MODE_DISABLED); 13043d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov } 13053d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov 1306de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov return mDb.insert(Tables.RAW_CONTACTS, RawContacts.CONTACT_ID, overriddenValues); 1307a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton } 1308a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton 1309a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton /** 1310a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton * Inserts an item in the data table 1311a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton * 1312a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton * @param values the values for the new row 1313a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton * @return the row ID of the newly created row 1314a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton */ 131573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov private long insertData(ContentValues values, boolean markRawContactAsDirty) { 13166cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov int aggregationMode = RawContacts.AGGREGATION_MODE_DISABLED; 1317a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton long id = 0; 1318de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mValues.clear(); 1319de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mValues.putAll(values); 132067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey 1321de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov long rawContactId = mValues.getAsLong(Data.RAW_CONTACT_ID); 132220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 1323de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov // Replace package with internal mapping 1324de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov final String packageName = mValues.getAsString(Data.RES_PACKAGE); 1325de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov if (packageName != null) { 1326de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mValues.put(DataColumns.PACKAGE_ID, mOpenHelper.getPackageId(packageName)); 1327de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov } 1328de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mValues.remove(Data.RES_PACKAGE); 1329508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey 1330de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov // Replace mimetype with internal mapping 1331de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov final String mimeType = mValues.getAsString(Data.MIMETYPE); 1332de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov if (TextUtils.isEmpty(mimeType)) { 1333de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov throw new IllegalArgumentException(Data.MIMETYPE + " is required"); 1334de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov } 13354097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov 1336de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mValues.put(DataColumns.MIMETYPE_ID, mOpenHelper.getMimeTypeId(mimeType)); 1337de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mValues.remove(Data.MIMETYPE); 1338a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 1339de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov // TODO create GroupMembershipRowHandler and move this code there 1340de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov resolveGroupSourceIdInValues(rawContactId, mimeType, mDb, mValues, true /* isInsert */); 1341a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 1342de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov id = getDataRowHandler(mimeType).insert(mDb, rawContactId, mValues); 1343de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov if (markRawContactAsDirty) { 1344de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov setRawContactDirty(rawContactId); 1345a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton } 1346a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 1347de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov aggregationMode = mContactAggregator.markContactForAggregation(mDb, rawContactId); 1348de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov 1349f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov triggerAggregation(id, aggregationMode); 1350a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton return id; 13514f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 13524f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 13535ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov private void triggerAggregation(long rawContactId, int aggregationMode) { 1354f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov switch (aggregationMode) { 13556cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov case RawContacts.AGGREGATION_MODE_DEFAULT: 1356de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mScheduleAggregation = true; 1357f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov break; 1358f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov 13596cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov case RawContacts.AGGREGATION_MODE_IMMEDITATE: 1360de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mContactAggregator.aggregateContact(mDb, rawContactId); 1361f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov break; 1362f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov 13636cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov case RawContacts.AGGREGATION_MODE_DISABLED: 1364f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov // Do nothing 1365f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov break; 1366f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 1367f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 1368f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov 1369a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov /** 13705ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov * Returns the group id of the group with sourceId and the same account as rawContactId. 13719261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana * If the group doesn't already exist then it is first created, 13729261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana * @param db SQLiteDatabase to use for this operation 13735ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov * @param rawContactId the contact this group is associated with 13749261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana * @param sourceId the sourceIf of the group to query or create 13759261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana * @return the group id of the existing or created group 13769261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana * @throws IllegalArgumentException if the contact is not associated with an account 13779261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana * @throws IllegalStateException if a group needs to be created but the creation failed 13789261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana */ 13795ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov private long getOrMakeGroup(SQLiteDatabase db, long rawContactId, String sourceId) { 13809261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana Account account = null; 13816cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov Cursor c = db.query(ContactsQuery.TABLE, ContactsQuery.PROJECTION, RawContacts._ID + "=" 13825ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + rawContactId, null, null, null, null); 13839261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana try { 13849261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana if (c.moveToNext()) { 138567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey final String accountName = c.getString(ContactsQuery.ACCOUNT_NAME); 138667dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey final String accountType = c.getString(ContactsQuery.ACCOUNT_TYPE); 13879261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(accountType)) { 13889261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana account = new Account(accountName, accountType); 13899261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana } 13909261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana } 13919261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana } finally { 13929261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana c.close(); 13939261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana } 13949261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana if (account == null) { 13959261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana throw new IllegalArgumentException("if the groupmembership only " 13969261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + "has a sourceid the the contact must be associate with " 13979261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + "an account"); 13989261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana } 13999261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana 14009261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana // look up the group that contains this sourceId and has the same account name and type 14015ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov // as the contact refered to by rawContactId 14026cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov c = db.query(Tables.GROUPS, new String[]{RawContacts._ID}, 14039261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana Clauses.GROUP_HAS_ACCOUNT_AND_SOURCE_ID, 14049261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana new String[]{sourceId, account.mName, account.mType}, null, null, null); 14059261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana try { 14069261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana if (c.moveToNext()) { 14079261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana return c.getLong(0); 14089261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana } else { 14099261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana ContentValues groupValues = new ContentValues(); 14109261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana groupValues.put(Groups.ACCOUNT_NAME, account.mName); 14119261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana groupValues.put(Groups.ACCOUNT_TYPE, account.mType); 14129261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana groupValues.put(Groups.SOURCE_ID, sourceId); 14139261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana long groupId = db.insert(Tables.GROUPS, Groups.ACCOUNT_NAME, groupValues); 14149261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana if (groupId < 0) { 14159261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana throw new IllegalStateException("unable to create a new group with " 14169261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + "this sourceid: " + groupValues); 14179261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana } 14189261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana return groupId; 14199261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana } 14209261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana } finally { 14219261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana c.close(); 14229261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana } 14239261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana } 14249261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana 14259261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana /** 142620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov * Delete data row by row so that fixing of primaries etc work correctly. 142720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov */ 142873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov private int deleteData(String selection, String[] selectionArgs, 142973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov boolean markRawContactAsDirty) { 143020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov int count = 0; 143120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 1432de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov // Note that the query will return data according to the access restrictions, 1433de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov // so we don't need to worry about deleting data we don't have permission to read. 143488e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov Cursor c = query(Data.CONTENT_URI, DataQuery.COLUMNS, selection, selectionArgs, null); 1435de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov try { 1436de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov while(c.moveToNext()) { 143788e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov long rawContactId = c.getLong(DataQuery.RAW_CONTACT_ID); 143888e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov String mimeType = c.getString(DataQuery.MIMETYPE); 143988e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov count += getDataRowHandler(mimeType).delete(mDb, c); 144088e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov if (markRawContactAsDirty) { 144188e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov setRawContactDirty(rawContactId); 144288e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov } 144320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 144420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } finally { 1445de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov c.close(); 144620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 144720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 144820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov return count; 144920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 145020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 145188e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov /** 145288e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov * Delete a data row provided that it is one of the allowed mime types. 145388e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov */ 145420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov public int deleteData(long dataId, String[] allowedMimeTypes) { 1455f992bfab334b760d36a053fc0b439382dcfb51adDmitri Plotnikov 145688e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov // Note that the query will return data according to the access restrictions, 145788e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov // so we don't need to worry about deleting data we don't have permission to read. 145888e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov Cursor c = query(Data.CONTENT_URI, DataQuery.COLUMNS, Data._ID + "=" + dataId, null, null); 1459f992bfab334b760d36a053fc0b439382dcfb51adDmitri Plotnikov 146020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov try { 146120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov if (!c.moveToFirst()) { 146220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov return 0; 146320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 146420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 146520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov String mimeType = c.getString(DataQuery.MIMETYPE); 146620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov boolean valid = false; 146720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov for (int i = 0; i < allowedMimeTypes.length; i++) { 146820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov if (TextUtils.equals(mimeType, allowedMimeTypes[i])) { 146920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov valid = true; 147020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov break; 147120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 147220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 147320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 147420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov if (!valid) { 14757a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana throw new IllegalArgumentException("Data type mismatch: expected " 147620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov + Lists.newArrayList(allowedMimeTypes)); 147720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 147820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 147988e5f4d32aa9cd3af0ac9654de479f1b8113f712Dmitri Plotnikov return getDataRowHandler(mimeType).delete(mDb, c); 148020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } finally { 148120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov c.close(); 148220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 148320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 148420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 148520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov /** 1486ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey * Inserts an item in the groups table 1487ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey */ 148873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov private long insertGroup(ContentValues values, Account account, boolean markAsDirty) { 1489ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey ContentValues overriddenValues = new ContentValues(values); 1490ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey if (!resolveAccount(overriddenValues, account)) { 1491ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey return -1; 1492ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 1493ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 1494ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey // Replace package with internal mapping 149567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey final String packageName = overriddenValues.getAsString(Groups.RES_PACKAGE); 149667dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey if (packageName != null) { 149767dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey overriddenValues.put(GroupsColumns.PACKAGE_ID, mOpenHelper.getPackageId(packageName)); 149867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey } 149967dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey overriddenValues.remove(Groups.RES_PACKAGE); 1500ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 150173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov if (markAsDirty) { 150273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov overriddenValues.put(Groups.DIRTY, 1); 150373776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov } 150473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov 1505de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov return mDb.insert(Tables.GROUPS, Groups.TITLE, overriddenValues); 1506ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 1507ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 1508ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey /** 15091f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey * Inserts a presence update. 15101f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey */ 151170b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov public long insertPresence(ContentValues values) { 15121f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey final String handle = values.getAsString(Presence.IM_HANDLE); 15131f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey final String protocol = values.getAsString(Presence.IM_PROTOCOL); 15141f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey if (TextUtils.isEmpty(handle) || TextUtils.isEmpty(protocol)) { 15151f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey throw new IllegalArgumentException("IM_PROTOCOL and IM_HANDLE are required"); 15161f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } 15171f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 15181f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey // TODO: generalize to allow other providers to match against email 1519a01e50cb1a5dd21293f8a8fe43f3fe0bf6349164Jeff Sharkey boolean matchEmail = Im.PROTOCOL_GOOGLE_TALK == Integer.parseInt(protocol); 15201f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 152170b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov StringBuilder selection = new StringBuilder(); 15221f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey String[] selectionArgs; 15231f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey if (matchEmail) { 152470b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov selection.append("(" + Clauses.WHERE_IM_MATCHES + ") OR (" 152570b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov + Clauses.WHERE_EMAIL_MATCHES + ")"); 15261f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey selectionArgs = new String[] { protocol, handle, handle }; 15271f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } else { 152870b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov selection.append(Clauses.WHERE_IM_MATCHES); 15291f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey selectionArgs = new String[] { protocol, handle }; 15301f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } 15311f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 153270b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov if (values.containsKey(Presence.DATA_ID)) { 153370b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov selection.append(" AND " + DataColumns.CONCRETE_ID + "=") 153470b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov .append(values.getAsLong(Presence.DATA_ID)); 153570b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov } 153670b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov 15375ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov if (values.containsKey(Presence.RAW_CONTACT_ID)) { 1538d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov selection.append(" AND " + DataColumns.CONCRETE_RAW_CONTACT_ID + "=") 15395ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov .append(values.getAsLong(Presence.RAW_CONTACT_ID)); 154070b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov } 154170b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov 154200ec508630251d6c6e3746469c9428f5a8cd5996Jeff Sharkey selection.append(" AND ").append(getContactsRestrictions()); 154370b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov 15441f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey long dataId = -1; 15455ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov long rawContactId = -1; 154670b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov 15471f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey Cursor cursor = null; 15481f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey try { 1549de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov cursor = mDb.query(DataContactsQuery.TABLE, DataContactsQuery.PROJECTION, 155070b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov selection.toString(), selectionArgs, null, null, null); 15511f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey if (cursor.moveToFirst()) { 155267dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey dataId = cursor.getLong(DataContactsQuery.DATA_ID); 15535ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov rawContactId = cursor.getLong(DataContactsQuery.RAW_CONTACT_ID); 15541f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } else { 15551f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey // No contact found, return a null URI 15561f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey return -1; 15571f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } 15581f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } finally { 155931b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov if (cursor != null) { 156031b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov cursor.close(); 156131b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov } 15621f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } 15631f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 15641f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey values.put(Presence.DATA_ID, dataId); 15655ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov values.put(Presence.RAW_CONTACT_ID, rawContactId); 15661f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 15671f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey // Insert the presence update 1568de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov long presenceId = mDb.replace(Tables.PRESENCE, null, values); 15691f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey return presenceId; 15701f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } 15711f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 15724f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton @Override 1573de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov protected int deleteInTransaction(Uri uri, String selection, String[] selectionArgs) { 1574508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey final int match = sUriMatcher.match(uri); 1575508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey switch (match) { 157635ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana case SYNCSTATE: 1577de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov return mOpenHelper.getSyncState().delete(mDb, selection, selectionArgs); 157835ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 1579d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov case CONTACTS_ID: { 1580d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov long contactId = ContentUris.parseId(uri); 15816bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov 1582d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov // Remove references to the contact first 15836bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov ContentValues values = new ContentValues(); 1584d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov values.putNull(RawContacts.CONTACT_ID); 1585de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mDb.update(Tables.RAW_CONTACTS, values, 1586d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov RawContacts.CONTACT_ID + "=" + contactId, null); 15876bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov 1588de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov return mDb.delete(Tables.CONTACTS, BaseColumns._ID + "=" + contactId, null); 15896bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov } 15906bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov 15915ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case RAW_CONTACTS_ID: { 159233b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov return deleteRawContact(uri); 1593508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey } 1594508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey 159520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov case DATA: { 159673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov return deleteData(selection, selectionArgs, shouldMarkRawContactAsDirty(uri)); 159720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 159820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 1599508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey case DATA_ID: { 1600508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey long dataId = ContentUris.parseId(uri); 1601f992bfab334b760d36a053fc0b439382dcfb51adDmitri Plotnikov return deleteData(Data._ID + "=" + dataId, null, shouldMarkRawContactAsDirty(uri)); 1602ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 1603ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 1604ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey case GROUPS_ID: { 160594021b213e4db367f60b30fcbfe9019e28571784Fred Quintana return deleteGroup(uri); 1606508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey } 1607508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey 16081f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey case PRESENCE: { 1609de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov return mDb.delete(Tables.PRESENCE, null, null); 16101f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } 16111f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 1612508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey default: 16133cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov return mLegacyApiSupport.delete(uri, selection, selectionArgs); 1614508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey } 16154f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 16164f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 161794021b213e4db367f60b30fcbfe9019e28571784Fred Quintana private int deleteGroup(Uri uri) { 161894021b213e4db367f60b30fcbfe9019e28571784Fred Quintana final String flag = uri.getQueryParameter(Groups.DELETE_PERMANENTLY); 161994021b213e4db367f60b30fcbfe9019e28571784Fred Quintana final boolean permanently = flag != null && "true".equals(flag.toLowerCase()); 162073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov boolean markAsDirty = shouldMarkGroupAsDirty(uri); 162173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov return deleteGroup(ContentUris.parseId(uri), markAsDirty, permanently); 162294021b213e4db367f60b30fcbfe9019e28571784Fred Quintana } 162394021b213e4db367f60b30fcbfe9019e28571784Fred Quintana 162473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov private int deleteGroup(long groupId, boolean markAsDirty, boolean permanently) { 162594021b213e4db367f60b30fcbfe9019e28571784Fred Quintana final long groupMembershipMimetypeId = mOpenHelper 162694021b213e4db367f60b30fcbfe9019e28571784Fred Quintana .getMimeTypeId(GroupMembership.CONTENT_ITEM_TYPE); 1627de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mDb.delete(Tables.DATA, DataColumns.MIMETYPE_ID + "=" 162894021b213e4db367f60b30fcbfe9019e28571784Fred Quintana + groupMembershipMimetypeId + " AND " + GroupMembership.GROUP_ROW_ID + "=" 162994021b213e4db367f60b30fcbfe9019e28571784Fred Quintana + groupId, null); 163094021b213e4db367f60b30fcbfe9019e28571784Fred Quintana 163194021b213e4db367f60b30fcbfe9019e28571784Fred Quintana try { 163294021b213e4db367f60b30fcbfe9019e28571784Fred Quintana if (permanently) { 1633de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov return mDb.delete(Tables.GROUPS, Groups._ID + "=" + groupId, null); 163494021b213e4db367f60b30fcbfe9019e28571784Fred Quintana } else { 163594021b213e4db367f60b30fcbfe9019e28571784Fred Quintana mValues.clear(); 163694021b213e4db367f60b30fcbfe9019e28571784Fred Quintana mValues.put(Groups.DELETED, 1); 163773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov if (markAsDirty) { 163873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov mValues.put(Groups.DIRTY, 1); 163973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov } 1640de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov return mDb.update(Tables.GROUPS, mValues, Groups._ID + "=" + groupId, null); 164194021b213e4db367f60b30fcbfe9019e28571784Fred Quintana } 164294021b213e4db367f60b30fcbfe9019e28571784Fred Quintana } finally { 164394021b213e4db367f60b30fcbfe9019e28571784Fred Quintana mOpenHelper.updateAllVisible(); 164494021b213e4db367f60b30fcbfe9019e28571784Fred Quintana } 164594021b213e4db367f60b30fcbfe9019e28571784Fred Quintana } 164694021b213e4db367f60b30fcbfe9019e28571784Fred Quintana 164733b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov private int deleteRawContact(Uri uri) { 16487a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana final String flag = uri.getQueryParameter(RawContacts.DELETE_PERMANENTLY); 16497a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana final boolean permanently = flag != null && "true".equals(flag.toLowerCase()); 16507a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana final long rawContactId = ContentUris.parseId(uri); 16517a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana return deleteRawContact(rawContactId, permanently); 165233b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov } 165333b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov 16545ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public int deleteRawContact(long rawContactId, boolean permanently) { 1655c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov // TODO delete aggregation exceptions 1656c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov mOpenHelper.removeContactIfSingleton(rawContactId); 165733b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov if (permanently) { 1658de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mDb.delete(Tables.PRESENCE, Presence.RAW_CONTACT_ID + "=" + rawContactId, null); 1659de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov return mDb.delete(Tables.RAW_CONTACTS, RawContacts._ID + "=" + rawContactId, null); 166033b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov } else { 166111944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov 166211944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov // Clear out data used for aggregation - this deleted contact should not be aggregated 166311944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov mDb.execSQL("DELETE FROM " + Tables.NAME_LOOKUP + " WHERE " 166411944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov + NameLookupColumns.RAW_CONTACT_ID + "=" + rawContactId); 166511944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov 166633b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov mValues.clear(); 166794021b213e4db367f60b30fcbfe9019e28571784Fred Quintana mValues.put(RawContacts.DELETED, 1); 1668c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov mValues.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_DISABLED); 1669c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov mValues.putNull(RawContacts.CONTACT_ID); 167073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov mValues.put(RawContacts.DIRTY, 1); 16715ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov return updateRawContact(rawContactId, mValues, null, null); 167233b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov } 167333b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov } 167433b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov 1675f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana private static Account readAccountFromQueryParams(Uri uri) { 16766cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov final String name = uri.getQueryParameter(RawContacts.ACCOUNT_NAME); 16776cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov final String type = uri.getQueryParameter(RawContacts.ACCOUNT_TYPE); 1678f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana if (TextUtils.isEmpty(name) || TextUtils.isEmpty(type)) { 1679f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana return null; 1680f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana } 1681f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana return new Account(name, type); 1682f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana } 1683f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana 16844f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton @Override 1685de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov protected int updateInTransaction(Uri uri, ContentValues values, String selection, 1686de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov String[] selectionArgs) { 168735ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana int count = 0; 168800d71133c63c882fb41729ddc3a52f66fb155374Evan Millar 168900d71133c63c882fb41729ddc3a52f66fb155374Evan Millar final int match = sUriMatcher.match(uri); 169000d71133c63c882fb41729ddc3a52f66fb155374Evan Millar switch(match) { 169135ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana case SYNCSTATE: 1692de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov return mOpenHelper.getSyncState().update(mDb, values, selection, selectionArgs); 169335ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 1694d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov // TODO(emillar): We will want to disallow editing the contacts table at some point. 1695d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov case CONTACTS: { 1696de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov count = mDb.update(Tables.CONTACTS, values, selection, selectionArgs); 169700d71133c63c882fb41729ddc3a52f66fb155374Evan Millar break; 169800d71133c63c882fb41729ddc3a52f66fb155374Evan Millar } 169900d71133c63c882fb41729ddc3a52f66fb155374Evan Millar 1700d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov case CONTACTS_ID: { 1701de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov count = updateContactData(ContentUris.parseId(uri), values); 1702c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar break; 1703c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar } 1704c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar 170520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov case DATA: { 170673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov count = updateData(uri, values, selection, selectionArgs, 170773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov shouldMarkRawContactAsDirty(uri)); 170820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov break; 170920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 1710c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar 171120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov case DATA_ID: { 171273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov count = updateData(uri, values, selection, selectionArgs, 171373776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov shouldMarkRawContactAsDirty(uri)); 171400d71133c63c882fb41729ddc3a52f66fb155374Evan Millar break; 171500d71133c63c882fb41729ddc3a52f66fb155374Evan Millar } 17167e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 17175ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case RAW_CONTACTS: { 171873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov 171973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov // TODO: security checks 1720de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov count = mDb.update(Tables.RAW_CONTACTS, values, selection, selectionArgs); 17217e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana break; 17227e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 17237e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 17245ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case RAW_CONTACTS_ID: { 172533b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov long rawContactId = ContentUris.parseId(uri); 172633b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov count = updateRawContact(rawContactId, values, selection, selectionArgs); 17277e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana break; 17287e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 17297e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 1730ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey case GROUPS: { 1731de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov count = updateGroups(values, selection, selectionArgs, 173273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov shouldMarkGroupAsDirty(uri)); 1733ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey break; 1734ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 1735ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 1736ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey case GROUPS_ID: { 1737ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey long groupId = ContentUris.parseId(uri); 173873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov String selectionWithId = (Groups._ID + "=" + groupId + " ") 173973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov + (selection == null ? "" : " AND " + selection); 1740de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov count = updateGroups(values, selectionWithId, selectionArgs, 174173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov shouldMarkGroupAsDirty(uri)); 1742ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey break; 1743ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 1744ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 1745127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov case AGGREGATION_EXCEPTIONS: { 1746de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov count = updateAggregationException(mDb, values); 1747b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov break; 1748b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov } 1749b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 17507e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana default: 1751f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov return mLegacyApiSupport.update(uri, values, selection, selectionArgs); 175200d71133c63c882fb41729ddc3a52f66fb155374Evan Millar } 175300d71133c63c882fb41729ddc3a52f66fb155374Evan Millar 175400d71133c63c882fb41729ddc3a52f66fb155374Evan Millar return count; 17554f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 17564f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 1757de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov private int updateGroups(ContentValues values, String selectionWithId, 175873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov String[] selectionArgs, boolean markAsDirty) { 175973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov 176073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov ContentValues updatedValues; 176173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov if (markAsDirty) { 176273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov updatedValues = mValues; 176373776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov updatedValues.clear(); 176473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov updatedValues.putAll(values); 176573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov updatedValues.put(Groups.DIRTY, 1); 176673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov } else { 176773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov updatedValues = values; 176873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov } 176973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov 1770de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov int count = mDb.update(Tables.GROUPS, values, selectionWithId, selectionArgs); 177194021b213e4db367f60b30fcbfe9019e28571784Fred Quintana 177294021b213e4db367f60b30fcbfe9019e28571784Fred Quintana // If changing visibility, then update contacts 177394021b213e4db367f60b30fcbfe9019e28571784Fred Quintana if (values.containsKey(Groups.GROUP_VISIBLE)) { 177494021b213e4db367f60b30fcbfe9019e28571784Fred Quintana mOpenHelper.updateAllVisible(); 177594021b213e4db367f60b30fcbfe9019e28571784Fred Quintana } 177694021b213e4db367f60b30fcbfe9019e28571784Fred Quintana return count; 177794021b213e4db367f60b30fcbfe9019e28571784Fred Quintana } 177894021b213e4db367f60b30fcbfe9019e28571784Fred Quintana 17795ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov private int updateRawContact(long rawContactId, ContentValues values, String selection, 178033b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov String[] selectionArgs) { 178173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov 178273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov // TODO: security checks 17835ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov String selectionWithId = (RawContacts._ID + " = " + rawContactId + " ") 178433b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov + (selection == null ? "" : " AND " + selection); 1785de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov return mDb.update(Tables.RAW_CONTACTS, values, selectionWithId, selectionArgs); 178633b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov } 178733b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov 1788321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana private int updateData(Uri uri, ContentValues values, String selection, 178973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov String[] selectionArgs, boolean markRawContactAsDirty) { 179020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov int count = 0; 1791de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov 1792de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov // Note that the query will return data according to the access restrictions, 1793de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov // so we don't need to worry about updating data we don't have permission to read. 1794de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov Cursor c = query(uri, DataIdQuery.COLUMNS, selection, selectionArgs, null); 179520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov try { 1796de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov while(c.moveToNext()) { 1797de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov final long dataId = c.getLong(DataIdQuery._ID); 1798de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov final long rawContactId = c.getLong(DataIdQuery.RAW_CONTACT_ID); 1799de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov final String mimetype = c.getString(DataIdQuery.MIMETYPE); 1800de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov count += updateData(dataId, rawContactId, mimetype, values, 1801de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov markRawContactAsDirty); 180220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 180320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } finally { 1804de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov c.close(); 180520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 180620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 180720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov return count; 180820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 180920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 181073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov private int updateData(long dataId, long rawContactId, String mimeType, ContentValues values, 181173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov boolean markRawContactAsDirty) { 181220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov mValues.clear(); 181320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov mValues.putAll(values); 181420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov mValues.remove(Data._ID); 18155ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov mValues.remove(Data.RAW_CONTACT_ID); 181620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov mValues.remove(Data.MIMETYPE); 181720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 181820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov String packageName = values.getAsString(Data.RES_PACKAGE); 181920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov if (packageName != null) { 182020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov mValues.remove(Data.RES_PACKAGE); 182120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov mValues.put(DataColumns.PACKAGE_ID, mOpenHelper.getPackageId(packageName)); 182220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 182320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 182470b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov boolean containsIsSuperPrimary = mValues.containsKey(Data.IS_SUPER_PRIMARY); 182570b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov boolean containsIsPrimary = mValues.containsKey(Data.IS_PRIMARY); 182620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 182720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov // Remove primary or super primary values being set to 0. This is disallowed by the 182820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov // content provider. 182970b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov if (containsIsSuperPrimary && mValues.getAsInteger(Data.IS_SUPER_PRIMARY) == 0) { 183020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov containsIsSuperPrimary = false; 183170b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov mValues.remove(Data.IS_SUPER_PRIMARY); 183220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 183370b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov if (containsIsPrimary && mValues.getAsInteger(Data.IS_PRIMARY) == 0) { 183420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov containsIsPrimary = false; 183570b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov mValues.remove(Data.IS_PRIMARY); 183620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 183720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 183820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov if (containsIsSuperPrimary) { 183920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov setIsSuperPrimary(dataId); 184020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov setIsPrimary(dataId); 184120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 184220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov // Now that we've taken care of setting these, remove them from "values". 184370b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov mValues.remove(Data.IS_SUPER_PRIMARY); 184420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov if (containsIsPrimary) { 184570b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov mValues.remove(Data.IS_PRIMARY); 184620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 184720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } else if (containsIsPrimary) { 184820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov setIsPrimary(dataId); 184920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 185020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov // Now that we've taken care of setting this, remove it from "values". 185170b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov mValues.remove(Data.IS_PRIMARY); 185220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 185320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 185473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov // TODO create GroupMembershipRowHandler and move this code there 1855de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov resolveGroupSourceIdInValues(rawContactId, mimeType, mDb, mValues, false /* isInsert */); 1856321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana 185770b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov if (mValues.size() > 0) { 1858de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mDb.update(Tables.DATA, mValues, Data._ID + " = " + dataId, null); 185973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov if (markRawContactAsDirty) { 186073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov setRawContactDirty(rawContactId); 186173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov } 186273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov 186373776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov return 1; 186420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 186520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov return 0; 186620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov } 186720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov 1868321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana private void resolveGroupSourceIdInValues(long rawContactId, String mimeType, SQLiteDatabase db, 1869321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana ContentValues values, boolean isInsert) { 1870321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana if (GroupMembership.CONTENT_ITEM_TYPE.equals(mimeType)) { 1871321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana boolean containsGroupSourceId = values.containsKey(GroupMembership.GROUP_SOURCE_ID); 1872321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana boolean containsGroupId = values.containsKey(GroupMembership.GROUP_ROW_ID); 1873321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana if (containsGroupSourceId && containsGroupId) { 1874321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana throw new IllegalArgumentException( 1875321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana "you are not allowed to set both the GroupMembership.GROUP_SOURCE_ID " 1876321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana + "and GroupMembership.GROUP_ROW_ID"); 1877321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana } 1878321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana 1879321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana if (!containsGroupSourceId && !containsGroupId) { 1880321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana if (isInsert) { 1881321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana throw new IllegalArgumentException( 1882321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana "you must set exactly one of GroupMembership.GROUP_SOURCE_ID " 1883321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana + "and GroupMembership.GROUP_ROW_ID"); 1884321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana } else { 1885321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana return; 1886321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana } 1887321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana } 1888321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana 1889321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana if (containsGroupSourceId) { 1890321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana final String sourceId = values.getAsString(GroupMembership.GROUP_SOURCE_ID); 1891321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana final long groupId = getOrMakeGroup(db, rawContactId, sourceId); 1892321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana values.remove(GroupMembership.GROUP_SOURCE_ID); 1893321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana values.put(GroupMembership.GROUP_ROW_ID, groupId); 1894321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana } 1895321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana } 1896321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana } 1897321afd997c985f150a13e0a5538e2a12b755b217Fred Quintana 1898de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov private int updateContactData(long contactId, ContentValues values) { 1899d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov 1900d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov // First update all constituent contacts 1901f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov ContentValues optionValues = new ContentValues(5); 19026cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov OpenHelper.copyStringValue(optionValues, RawContacts.CUSTOM_RINGTONE, 1903d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov values, Contacts.CUSTOM_RINGTONE); 19046cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov OpenHelper.copyLongValue(optionValues, RawContacts.SEND_TO_VOICEMAIL, 1905d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov values, Contacts.SEND_TO_VOICEMAIL); 19066cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov OpenHelper.copyLongValue(optionValues, RawContacts.LAST_TIME_CONTACTED, 1907d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov values, Contacts.LAST_TIME_CONTACTED); 19086cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov OpenHelper.copyLongValue(optionValues, RawContacts.TIMES_CONTACTED, 1909d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov values, Contacts.TIMES_CONTACTED); 19106cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov OpenHelper.copyLongValue(optionValues, RawContacts.STARRED, 1911d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov values, Contacts.STARRED); 1912d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov 1913d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov // Nothing to update - just return 1914d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov if (optionValues.size() == 0) { 1915d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov return 0; 1916d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov } 1917d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov 1918de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov mDb.update(Tables.RAW_CONTACTS, optionValues, 1919d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov RawContacts.CONTACT_ID + "=" + contactId, null); 1920de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov return mDb.update(Tables.CONTACTS, values, Contacts._ID + "=" + contactId, null); 1921f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 1922d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov 1923d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public void updateContactTime(long contactId, long lastTimeContacted) { 1924f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov mLastTimeContactedUpdate.bindLong(1, lastTimeContacted); 1925d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov mLastTimeContactedUpdate.bindLong(2, contactId); 1926f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov mLastTimeContactedUpdate.execute(); 1927d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov } 1928d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov 19295ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov private static class RawContactPair { 19305ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov final long rawContactId1; 19315ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov final long rawContactId2; 1932127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov 1933127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov /** 19345ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov * Constructor that ensures that this.rawContactId1 < this.rawContactId2 1935127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov */ 19365ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public RawContactPair(long rawContactId1, long rawContactId2) { 19375ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov if (rawContactId1 < rawContactId2) { 19385ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov this.rawContactId1 = rawContactId1; 19395ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov this.rawContactId2 = rawContactId2; 1940127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov } else { 19415ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov this.rawContactId2 = rawContactId1; 19425ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov this.rawContactId1 = rawContactId2; 1943127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov } 1944127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov } 1945127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov } 194680c457131bd22afe34828d1a5d15e90bb5f43375Dmitri Plotnikov 1947127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov private int updateAggregationException(SQLiteDatabase db, ContentValues values) { 1948127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov int exceptionType = values.getAsInteger(AggregationExceptions.TYPE); 1949d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov long contactId = values.getAsInteger(AggregationExceptions.CONTACT_ID); 19505ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov long rawContactId = values.getAsInteger(AggregationExceptions.RAW_CONTACT_ID); 195180c457131bd22afe34828d1a5d15e90bb5f43375Dmitri Plotnikov 19523cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov // First, we build a list of rawContactID-rawContactID pairs for the given contact. 19535ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov ArrayList<RawContactPair> pairs = new ArrayList<RawContactPair>(); 1954d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Cursor c = db.query(ContactsQuery.TABLE, ContactsQuery.PROJECTION, RawContacts.CONTACT_ID 1955d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + "=" + contactId, null, null, null, null); 1956127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov try { 1957127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov while (c.moveToNext()) { 19585ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov long aggregatedContactId = c.getLong(ContactsQuery.RAW_CONTACT_ID); 19595ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov if (aggregatedContactId != rawContactId) { 19605ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov pairs.add(new RawContactPair(aggregatedContactId, rawContactId)); 1961e2e0ba75ce239f0f5481cdef9082daebf8fc2d35Dmitri Plotnikov } 1962b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov } 1963b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov } finally { 1964b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov c.close(); 1965b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov } 1966127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov 1967127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov // Now we iterate through all contact pairs to see if we need to insert/delete/update 1968127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov // the corresponding exception 1969127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov ContentValues exceptionValues = new ContentValues(3); 1970127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov exceptionValues.put(AggregationExceptions.TYPE, exceptionType); 19715ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov for (RawContactPair pair : pairs) { 1972127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov final String whereClause = 19735ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov AggregationExceptionColumns.RAW_CONTACT_ID1 + "=" + pair.rawContactId1 + " AND " 19745ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + AggregationExceptionColumns.RAW_CONTACT_ID2 + "=" + pair.rawContactId2; 1975127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov if (exceptionType == AggregationExceptions.TYPE_AUTOMATIC) { 1976127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov db.delete(Tables.AGGREGATION_EXCEPTIONS, whereClause, null); 1977127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov } else { 19785ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov exceptionValues.put(AggregationExceptionColumns.RAW_CONTACT_ID1, pair.rawContactId1); 19795ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov exceptionValues.put(AggregationExceptionColumns.RAW_CONTACT_ID2, pair.rawContactId2); 1980127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov db.replace(Tables.AGGREGATION_EXCEPTIONS, AggregationExceptions._ID, 1981127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov exceptionValues); 1982127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov } 1983127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov } 1984127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov 1985de955f25491cdc0e826ea5c7d4cd0e93cb970fb7Dmitri Plotnikov int aggregationMode = mContactAggregator.markContactForAggregation(mDb, rawContactId); 19866cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov if (aggregationMode != RawContacts.AGGREGATION_MODE_DISABLED) { 19875ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov mContactAggregator.aggregateContact(db, rawContactId); 1988f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov if (exceptionType == AggregationExceptions.TYPE_AUTOMATIC 1989f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov || exceptionType == AggregationExceptions.TYPE_KEEP_OUT) { 1990d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov mContactAggregator.updateAggregateData(contactId); 1991f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 19927a39bf269294a8130ddd463460b9b36cf4ff74a8Dmitri Plotnikov } 1993127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov 1994127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov // The return value is fake - we just confirm that we made a change, not count actual 1995127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov // rows changed. 1996127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov return 1; 1997b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov } 1998b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 1999619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey /** 2000619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey * Test if a {@link String} value appears in the given list. 2001619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey */ 2002619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey private boolean isContained(String[] array, String value) { 2003bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar if (array != null) { 2004bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar for (String test : array) { 2005bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar if (value.equals(test)) { 2006bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar return true; 2007bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar } 2008619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 2009619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 2010619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey return false; 2011619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 2012619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 2013619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey /** 2014619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey * Test if a {@link String} value appears in the given list, and add to the 2015619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey * array if the value doesn't already appear. 2016619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey */ 2017619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey private String[] assertContained(String[] array, String value) { 201800ec508630251d6c6e3746469c9428f5a8cd5996Jeff Sharkey if (array != null && !isContained(array, value)) { 2019619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey String[] newArray = new String[array.length + 1]; 2020619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey System.arraycopy(array, 0, newArray, 0, array.length); 2021619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey newArray[array.length] = value; 2022619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey array = newArray; 2023619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 2024619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey return array; 2025619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 2026619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 20274f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton @Override 20284f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, 20294f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton String sortOrder) { 20304f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton final SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 203135ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 2032d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); 20331f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey String groupBy = null; 2034c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov String limit = getLimit(uri); 2035c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 2036619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey // TODO: Consider writing a test case for RestrictionExceptions when you 2037619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey // write a new query() block to make sure it protects restricted data. 2038a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton final int match = sUriMatcher.match(uri); 20394f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton switch (match) { 204035ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana case SYNCSTATE: 204135ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana return mOpenHelper.getSyncState().query(db, projection, selection, selectionArgs, 204235ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana sortOrder); 204335ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 2044d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov case CONTACTS: { 20454a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getContactView()); 2046d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov qb.setProjectionMap(sContactsProjectionMap); 2047619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey break; 2048619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 2049619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 2050d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov case CONTACTS_ID: { 20514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov long contactId = ContentUris.parseId(uri); 20524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getContactView()); 2053d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov qb.setProjectionMap(sContactsProjectionMap); 20544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(Contacts._ID + "=" + contactId); 20556bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov break; 20566bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov } 20576bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov 2058d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov case CONTACTS_SUMMARY: { 2059619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey // TODO: join into social status tables 20604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getContactSummaryView()); 2061d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov qb.setProjectionMap(sContactsSummaryProjectionMap); 20624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov groupBy = Contacts._ID; 20631f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey break; 20641f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } 20651f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 2066d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov case CONTACTS_SUMMARY_ID: { 2067619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey // TODO: join into social status tables 20684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov long contactId = ContentUris.parseId(uri); 20694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getContactSummaryView()); 2070d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov qb.setProjectionMap(sContactsSummaryProjectionMap); 20714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov groupBy = Contacts._ID; 20724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(Contacts._ID + "=" + contactId); 20731f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey break; 20741f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } 20751f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 2076d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov case CONTACTS_SUMMARY_FILTER: { 20774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getContactSummaryView()); 2078d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov qb.setProjectionMap(sContactsSummaryProjectionMap); 20794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov groupBy = Contacts._ID; 20804a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 2081ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar if (uri.getPathSegments().size() > 2) { 20824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String filterParam = uri.getLastPathSegment(); 20834a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov StringBuilder sb = new StringBuilder(); 20844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sb.append("raw_contact_id IN "); 20854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov appendRawContactsByFilterAsNestedQuery(sb, filterParam, null); 20864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(sb.toString()); 2087ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar } 2088ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar break; 2089ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar } 2090ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar 2091d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov case CONTACTS_SUMMARY_STREQUENT_FILTER: 2092d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov case CONTACTS_SUMMARY_STREQUENT: { 20934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String filterSql = null; 2094d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov if (match == CONTACTS_SUMMARY_STREQUENT_FILTER 2095d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar && uri.getPathSegments().size() > 3) { 20964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String filterParam = uri.getLastPathSegment(); 20974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov StringBuilder sb = new StringBuilder(); 20984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sb.append("raw_contact_id IN "); 20994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov appendRawContactsByFilterAsNestedQuery(sb, filterParam, null); 21004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov filterSql = sb.toString(); 21014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 21024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 21034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov // Build the first query for starred 21044a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getContactSummaryView()); 21054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setProjectionMap(sContactsSummaryProjectionMap); 21064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov if (filterSql != null) { 21074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(filterSql); 2108d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar } 2109d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov final String starredQuery = qb.buildQuery(projection, Contacts.STARRED + "=1", 21104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov null, Contacts._ID, null, null, null); 2111d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar 2112d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar // Build the second query for frequent 2113d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar qb = new SQLiteQueryBuilder(); 21144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getContactSummaryView()); 2115d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov qb.setProjectionMap(sContactsSummaryProjectionMap); 21164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov if (filterSql != null) { 21174a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(filterSql); 2118d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar } 2119d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar final String frequentQuery = qb.buildQuery(projection, 2120d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.TIMES_CONTACTED + " > 0 AND (" + Contacts.STARRED 2121d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + " = 0 OR " + Contacts.STARRED + " IS NULL)", 21224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov null, Contacts._ID, null, null, null); 2123d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar 2124d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar // Put them together 2125d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar final String query = qb.buildUnionQuery(new String[] {starredQuery, frequentQuery}, 2126d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar STREQUENT_ORDER_BY, STREQUENT_LIMIT); 21274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov Cursor c = db.rawQuery(query, null); 21284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov if (c != null) { 2129d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar c.setNotificationUri(getContext().getContentResolver(), 2130d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar ContactsContract.AUTHORITY_URI); 2131d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar } 2132d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar return c; 2133d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar } 2134d3b76e00699679c519adc1c1770cd28ee6ae7aa3Evan Millar 2135d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov case CONTACTS_SUMMARY_GROUP: { 21364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getContactSummaryView()); 2137d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov qb.setProjectionMap(sContactsSummaryProjectionMap); 2138b67163a1088f09c59f324350662eb18772fac6b6Evan Millar if (uri.getPathSegments().size() > 2) { 21394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(sContactsInGroupSelect); 21404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov selectionArgs = insertSelectionArg(selectionArgs, uri.getLastPathSegment()); 2141b67163a1088f09c59f324350662eb18772fac6b6Evan Millar } 21424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov groupBy = Contacts._ID; 2143b67163a1088f09c59f324350662eb18772fac6b6Evan Millar break; 2144b67163a1088f09c59f324350662eb18772fac6b6Evan Millar } 2145b67163a1088f09c59f324350662eb18772fac6b6Evan Millar 2146d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov case CONTACTS_DATA: { 21474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov long contactId = Long.parseLong(uri.getPathSegments().get(1)); 21484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 21494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getDataView()); 21504a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setProjectionMap(sDataProjectionMap); 21514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov appendAccountFromParameter(qb, uri); 21524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(" AND " + RawContacts.CONTACT_ID + "=" + contactId); 21536bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov break; 21546bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov } 215500d71133c63c882fb41729ddc3a52f66fb155374Evan Millar 21564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov case PHONES: { 21574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getDataView()); 21584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setProjectionMap(sDataProjectionMap); 21594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(Data.MIMETYPE + " = '" + Phone.CONTENT_ITEM_TYPE + "'"); 21602815f58f72f109790585931f601a63ddc02536a5Evan Millar break; 21612815f58f72f109790585931f601a63ddc02536a5Evan Millar } 21622815f58f72f109790585931f601a63ddc02536a5Evan Millar 2163ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar case PHONES_FILTER: { 21644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getDataView()); 21654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setProjectionMap(sDataProjectionMap); 2166ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar qb.appendWhere(Data.MIMETYPE + " = '" + Phone.CONTENT_ITEM_TYPE + "'"); 2167ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar if (uri.getPathSegments().size() > 2) { 21684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String filterParam = uri.getLastPathSegment(); 21694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov StringBuilder sb = new StringBuilder(); 21704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov sb.append(Data.RAW_CONTACT_ID + " IN "); 21714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov appendRawContactsByFilterAsNestedQuery(sb, filterParam, null); 21724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(" AND " + sb); 2173ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar } 2174ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar break; 2175ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar } 2176ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 21774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov case EMAILS: { 21784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getDataView()); 21794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setProjectionMap(sDataProjectionMap); 21804a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(Data.MIMETYPE + " = '" + Email.CONTENT_ITEM_TYPE + "'"); 21814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov break; 21824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 21834a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 21844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov case EMAILS_FILTER: { 21854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getDataView()); 21864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setProjectionMap(sDataProjectionMap); 21874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(Data.MIMETYPE + " = '" + Email.CONTENT_ITEM_TYPE + "'"); 21884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov if (uri.getPathSegments().size() > 2) { 21894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(" AND " + CommonDataKinds.Email.DATA + "="); 21904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhereEscapeString(uri.getLastPathSegment()); 21914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 2192ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar break; 2193ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar } 2194ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar 2195ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar case POSTALS: { 21964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getDataView()); 21974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setProjectionMap(sDataProjectionMap); 21984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(Data.MIMETYPE + " = '" + StructuredPostal.CONTENT_ITEM_TYPE + "'"); 2199ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar break; 2200ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar } 2201ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar 22025ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case RAW_CONTACTS: { 22034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getRawContactView()); 2204d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov qb.setProjectionMap(sRawContactsProjectionMap); 22054f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton break; 22064f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 22074f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 22085ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case RAW_CONTACTS_ID: { 22095ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov long rawContactId = ContentUris.parseId(uri); 22104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getRawContactView()); 2211d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov qb.setProjectionMap(sRawContactsProjectionMap); 22124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(RawContacts._ID + "=" + rawContactId); 22134f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton break; 22144f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 22154f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 22165ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case RAW_CONTACTS_DATA: { 22175ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov long rawContactId = Long.parseLong(uri.getPathSegments().get(1)); 22184a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getDataView()); 22194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setProjectionMap(sDataProjectionMap); 22204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(Data.RAW_CONTACT_ID + "=" + rawContactId); 2221e17c303827c5be8107dcd4a8b64333f349b688f5Jeff Sharkey break; 2222e17c303827c5be8107dcd4a8b64333f349b688f5Jeff Sharkey } 2223e17c303827c5be8107dcd4a8b64333f349b688f5Jeff Sharkey 2224e17c303827c5be8107dcd4a8b64333f349b688f5Jeff Sharkey case DATA: { 22254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getDataView()); 22264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setProjectionMap(sDataProjectionMap); 22274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov appendAccountFromParameter(qb, uri); 2228e17c303827c5be8107dcd4a8b64333f349b688f5Jeff Sharkey break; 2229e17c303827c5be8107dcd4a8b64333f349b688f5Jeff Sharkey } 2230e17c303827c5be8107dcd4a8b64333f349b688f5Jeff Sharkey 22314f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton case DATA_ID: { 22324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setTables(mOpenHelper.getDataView()); 22334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.setProjectionMap(sDataProjectionMap); 22344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(Data._ID + "=" + ContentUris.parseId(uri)); 22354f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton break; 22364f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 22374f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 2238a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton case PHONE_LOOKUP: { 22394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 22404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov // TODO: optimize this query returning fewer fields and using an int mimetype 2241619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey // TODO: filter query based on callingUid 2242a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton if (TextUtils.isEmpty(sortOrder)) { 2243a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton // Default the sort order to something reasonable so we get consistent 2244a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton // results when callers don't request an ordering 22455ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov sortOrder = Data.RAW_CONTACT_ID; 2246a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton } 2247a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton 2248a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton final String number = uri.getLastPathSegment(); 224911944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov OpenHelper.buildPhoneLookupQuery(qb, number, true /* join mimetype */); 22500c83a3c4b6a9c8a0dfa0b3aa2af91b74d8e3304fEvan Millar qb.setProjectionMap(sDataRawContactsProjectionMap); 2251a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton break; 2252a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton } 2253a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton 2254ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey case GROUPS: { 2255ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey qb.setTables(Tables.GROUPS_JOIN_PACKAGES); 2256ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey qb.setProjectionMap(sGroupsProjectionMap); 2257ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey break; 2258ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 2259ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 2260ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey case GROUPS_ID: { 2261ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey long groupId = ContentUris.parseId(uri); 2262ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey qb.setTables(Tables.GROUPS_JOIN_PACKAGES); 2263ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey qb.setProjectionMap(sGroupsProjectionMap); 2264ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey qb.appendWhere(GroupsColumns.CONCRETE_ID + "=" + groupId); 2265ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey break; 2266ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 2267ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 2268ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey case GROUPS_SUMMARY: { 226999a9b5ec879f6cd6876f7f6b680b82d8304e6b92Dmitri Plotnikov qb.setTables(Tables.GROUPS_JOIN_PACKAGES); 2270ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey qb.setProjectionMap(sGroupsSummaryProjectionMap); 2271ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey groupBy = GroupsColumns.CONCRETE_ID; 2272ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey break; 2273ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 2274ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 2275b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov case AGGREGATION_EXCEPTIONS: { 22765ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov qb.setTables(Tables.AGGREGATION_EXCEPTIONS_JOIN_RAW_CONTACTS); 2277b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov qb.setProjectionMap(sAggregationExceptionsProjectionMap); 2278b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov break; 2279b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov } 2280b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 228131b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov case AGGREGATION_SUGGESTIONS: { 2282d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov long contactId = Long.parseLong(uri.getPathSegments().get(1)); 228331b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov final int maxSuggestions; 2284d659078547c329b58f90d8809910a845d913dbc6Dmitri Plotnikov if (limit != null) { 2285d659078547c329b58f90d8809910a845d913dbc6Dmitri Plotnikov maxSuggestions = Integer.parseInt(limit); 228631b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov } else { 228731b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov maxSuggestions = DEFAULT_MAX_SUGGESTIONS; 228831b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov } 228931b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov 2290d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov return mContactAggregator.queryAggregationSuggestions(contactId, projection, 2291d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov sContactsProjectionMap, maxSuggestions); 229231b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov } 229331b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov 22945ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case PRESENCE: { 2295373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov qb.setTables(Tables.PRESENCE); 2296373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov qb.setProjectionMap(sPresenceProjectionMap); 22975ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov break; 22985ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov } 22995ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov 23005ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case PRESENCE_ID: { 2301373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov qb.setTables(Tables.PRESENCE); 2302373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov qb.setProjectionMap(sPresenceProjectionMap); 2303373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov qb.appendWhere(Presence._ID + "=" + ContentUris.parseId(uri)); 23045ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov break; 23055ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov } 23065ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov 2307c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov case SEARCH_SUGGESTIONS: { 2308a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov return mGlobalSearchSupport.handleSearchSuggestionsQuery(db, uri, limit); 2309c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov } 2310c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 2311c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov case SEARCH_SHORTCUT: { 2312c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov // TODO 2313c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov break; 2314c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov } 2315c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 23164f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton default: 2317f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov return mLegacyApiSupport.query(uri, projection, selection, selectionArgs, 2318c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov sortOrder, limit); 23194f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 23204f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 23214f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton // Perform the query and set the notification uri 23221f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey final Cursor c = qb.query(db, projection, selection, selectionArgs, 2323bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar groupBy, null, sortOrder, limit); 23244f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton if (c != null) { 23254f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton c.setNotificationUri(getContext().getContentResolver(), ContactsContract.AUTHORITY_URI); 23264f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 23274f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton return c; 23284f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 23294f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton 23304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov private void appendAccountFromParameter(SQLiteQueryBuilder qb, Uri uri) { 23314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov final String accountName = uri.getQueryParameter(RawContacts.ACCOUNT_NAME); 23324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov final String accountType = uri.getQueryParameter(RawContacts.ACCOUNT_TYPE); 23334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov if (!TextUtils.isEmpty(accountName)) { 23344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere(RawContacts.ACCOUNT_NAME + "=" 23354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + DatabaseUtils.sqlEscapeString(accountName) + " AND " 23364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.ACCOUNT_TYPE + "=" 23374a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + DatabaseUtils.sqlEscapeString(accountType)); 23384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } else { 23394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov qb.appendWhere("1"); 23404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 23414a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 23424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 23437e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana /** 2344c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov * Gets the value of the "limit" URI query parameter. 2345c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov * 2346c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov * @return A string containing a non-negative integer, or <code>null</code> if 2347c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov * the parameter is not set, or is set to an invalid value. 2348c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov */ 2349c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov private String getLimit(Uri url) { 2350c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov String limitParam = url.getQueryParameter("limit"); 2351c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov if (limitParam == null) { 2352c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov return null; 2353c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov } 2354c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov // make sure that the limit is a non-negative integer 2355c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov try { 2356c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov int l = Integer.parseInt(limitParam); 2357c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov if (l < 0) { 2358c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov Log.w(TAG, "Invalid limit parameter: " + limitParam); 2359c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov return null; 2360c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov } 2361c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov return String.valueOf(l); 2362c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov } catch (NumberFormatException ex) { 2363c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov Log.w(TAG, "Invalid limit parameter: " + limitParam); 2364c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov return null; 2365c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov } 2366c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov } 2367c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 236800ec508630251d6c6e3746469c9428f5a8cd5996Jeff Sharkey String getContactsRestrictions() { 23694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov if (mOpenHelper.hasRestrictedAccess()) { 237070b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov return "1"; 237170b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov } else { 23726cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov return RawContacts.IS_RESTRICTED + "=0"; 237370b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov } 237470b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov } 237570b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov 237670b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov public String getContactsRestrictionExceptionAsNestedQuery(String contactIdColumn) { 23774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov if (mOpenHelper.hasRestrictedAccess()) { 237870b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov return "1"; 237967dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey } else { 23805ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov return "(SELECT " + RawContacts.IS_RESTRICTED + " FROM " + Tables.RAW_CONTACTS 23815ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " WHERE " + RawContactsColumns.CONCRETE_ID + "=" + contactIdColumn + ")=0"; 2382619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 2383619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 2384619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 2385619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey /** 23867e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana * An implementation of EntityIterator that joins the contacts and data tables 23877e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana * and consumes all the data rows for a contact in order to build the Entity for a contact. 23887e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana */ 23897e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana private static class ContactsEntityIterator implements EntityIterator { 23907e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana private final Cursor mEntityCursor; 23917e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana private volatile boolean mIsClosed; 23927e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 23937e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana private static final String[] DATA_KEYS = new String[]{ 23947a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA1, 23957a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA2, 23967a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA3, 23977a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA4, 23987a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA5, 23997a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA6, 24007a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA7, 24017a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA8, 24027a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA9, 24037a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA10, 24047a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA11, 24057a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA12, 24067a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA13, 24077a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA14, 24087a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA15, 24097a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.SYNC1, 24107a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.SYNC2, 24117a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.SYNC3, 24127a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.SYNC4}; 24137e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 24147e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana private static final String[] PROJECTION = new String[]{ 24156cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.ACCOUNT_NAME, 24166cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.ACCOUNT_TYPE, 24176cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.SOURCE_ID, 24186cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.VERSION, 24196cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.DIRTY, 24207a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data._ID, 24217a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.RES_PACKAGE, 24227a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.MIMETYPE, 24237a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA1, 24247a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA2, 24257a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA3, 24267a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA4, 24277a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA5, 24287a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA6, 24297a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA7, 24307a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA8, 24317a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA9, 24327a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA10, 24337a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA11, 24347a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA12, 24357a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA13, 24367a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA14, 24377a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA15, 24387a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.SYNC1, 24397a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.SYNC2, 24407a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.SYNC3, 24417a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.SYNC4, 24427a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.RAW_CONTACT_ID, 24437a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.IS_PRIMARY, 24447a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Data.DATA_VERSION, 24457a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana GroupMembership.GROUP_SOURCE_ID, 24467a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana RawContacts.SYNC1, 24477a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana RawContacts.SYNC2, 24487a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana RawContacts.SYNC3, 244994021b213e4db367f60b30fcbfe9019e28571784Fred Quintana RawContacts.SYNC4, 245094021b213e4db367f60b30fcbfe9019e28571784Fred Quintana RawContacts.DELETED}; 2451035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana 2452035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana private static final int COLUMN_ACCOUNT_NAME = 0; 2453035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana private static final int COLUMN_ACCOUNT_TYPE = 1; 2454035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana private static final int COLUMN_SOURCE_ID = 2; 2455035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana private static final int COLUMN_VERSION = 3; 2456035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana private static final int COLUMN_DIRTY = 4; 2457035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana private static final int COLUMN_DATA_ID = 5; 245867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey private static final int COLUMN_RES_PACKAGE = 6; 245967dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey private static final int COLUMN_MIMETYPE = 7; 246067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey private static final int COLUMN_DATA1 = 8; 24617a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana private static final int COLUMN_RAW_CONTACT_ID = 27; 24627a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana private static final int COLUMN_IS_PRIMARY = 28; 24637a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana private static final int COLUMN_DATA_VERSION = 29; 24647a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana private static final int COLUMN_GROUP_SOURCE_ID = 30; 24657a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana private static final int COLUMN_SYNC1 = 31; 24667a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana private static final int COLUMN_SYNC2 = 32; 24677a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana private static final int COLUMN_SYNC3 = 33; 24687a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana private static final int COLUMN_SYNC4 = 34; 246994021b213e4db367f60b30fcbfe9019e28571784Fred Quintana private static final int COLUMN_DELETED = 35; 24707e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 24717e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana public ContactsEntityIterator(ContactsProvider2 provider, String contactsIdString, Uri uri, 24727e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana String selection, String[] selectionArgs, String sortOrder) { 24737e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana mIsClosed = false; 24747e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 24757e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana final String updatedSortOrder = (sortOrder == null) 24767a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana ? Data.RAW_CONTACT_ID 24777a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana : (Data.RAW_CONTACT_ID + "," + sortOrder); 24787e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 24797e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana final SQLiteDatabase db = provider.mOpenHelper.getReadableDatabase(); 24807e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana final SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); 2481226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana qb.setTables(Tables.CONTACT_ENTITIES); 24827e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana if (contactsIdString != null) { 24835ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov qb.appendWhere(Data.RAW_CONTACT_ID + "=" + contactsIdString); 24847e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 24856cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov final String accountName = uri.getQueryParameter(RawContacts.ACCOUNT_NAME); 24866cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov final String accountType = uri.getQueryParameter(RawContacts.ACCOUNT_TYPE); 2487035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana if (!TextUtils.isEmpty(accountName)) { 24886cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov qb.appendWhere(RawContacts.ACCOUNT_NAME + "=" 2489035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana + DatabaseUtils.sqlEscapeString(accountName) + " AND " 24906cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov + RawContacts.ACCOUNT_TYPE + "=" 2491035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana + DatabaseUtils.sqlEscapeString(accountType)); 2492035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana } 24937e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana mEntityCursor = qb.query(db, PROJECTION, selection, selectionArgs, 24947e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana null, null, updatedSortOrder); 24957e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana mEntityCursor.moveToFirst(); 24967e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 24977e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 24987e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana public void close() { 24997e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana if (mIsClosed) { 25007e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana throw new IllegalStateException("closing when already closed"); 25017e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 25027e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana mIsClosed = true; 25037e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana mEntityCursor.close(); 25047e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 25057e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 25067e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana public boolean hasNext() throws RemoteException { 25077e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana if (mIsClosed) { 25087e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana throw new IllegalStateException("calling hasNext() when the iterator is closed"); 25097e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 25107e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 25117e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana return !mEntityCursor.isAfterLast(); 25127e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 25137e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 25147e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana public Entity next() throws RemoteException { 25157e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana if (mIsClosed) { 25167e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana throw new IllegalStateException("calling next() when the iterator is closed"); 25177e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 25187e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana if (!hasNext()) { 25197e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana throw new IllegalStateException("you may only call next() if hasNext() is true"); 25207e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 25217e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 25227e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana final SQLiteCursor c = (SQLiteCursor) mEntityCursor; 25237e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 25247a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana final long rawContactId = c.getLong(COLUMN_RAW_CONTACT_ID); 25257e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 25267e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana // we expect the cursor is already at the row we need to read from 25277e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana ContentValues contactValues = new ContentValues(); 25286cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov contactValues.put(RawContacts.ACCOUNT_NAME, c.getString(COLUMN_ACCOUNT_NAME)); 25296cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov contactValues.put(RawContacts.ACCOUNT_TYPE, c.getString(COLUMN_ACCOUNT_TYPE)); 25305ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov contactValues.put(RawContacts._ID, rawContactId); 25316cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov contactValues.put(RawContacts.DIRTY, c.getLong(COLUMN_DIRTY)); 25326cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov contactValues.put(RawContacts.VERSION, c.getLong(COLUMN_VERSION)); 25336cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov contactValues.put(RawContacts.SOURCE_ID, c.getString(COLUMN_SOURCE_ID)); 25347a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana contactValues.put(RawContacts.SYNC1, c.getString(COLUMN_SYNC1)); 25357a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana contactValues.put(RawContacts.SYNC2, c.getString(COLUMN_SYNC2)); 25367a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana contactValues.put(RawContacts.SYNC3, c.getString(COLUMN_SYNC3)); 25377a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana contactValues.put(RawContacts.SYNC4, c.getString(COLUMN_SYNC4)); 253894021b213e4db367f60b30fcbfe9019e28571784Fred Quintana contactValues.put(RawContacts.DELETED, c.getLong(COLUMN_DELETED)); 25397e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana Entity contact = new Entity(contactValues); 25407e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 25417e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana // read data rows until the contact id changes 25427e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana do { 25437a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana if (rawContactId != c.getLong(COLUMN_RAW_CONTACT_ID)) { 25447e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana break; 25457e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 25467e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana // add the data to to the contact 25477e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana ContentValues dataValues = new ContentValues(); 25487a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana dataValues.put(Data._ID, c.getString(COLUMN_DATA_ID)); 25497a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana dataValues.put(Data.RES_PACKAGE, c.getString(COLUMN_RES_PACKAGE)); 25507a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana dataValues.put(Data.MIMETYPE, c.getString(COLUMN_MIMETYPE)); 25517a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana dataValues.put(Data.IS_PRIMARY, c.getString(COLUMN_IS_PRIMARY)); 25527a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana dataValues.put(Data.DATA_VERSION, c.getLong(COLUMN_DATA_VERSION)); 25539261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana if (!c.isNull(COLUMN_GROUP_SOURCE_ID)) { 25549261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana dataValues.put(GroupMembership.GROUP_SOURCE_ID, 25559261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana c.getString(COLUMN_GROUP_SOURCE_ID)); 25569261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana } 25577a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana dataValues.put(Data.DATA_VERSION, c.getLong(COLUMN_DATA_VERSION)); 25587a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana for (int i = 0; i < DATA_KEYS.length; i++) { 25597e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana final int columnIndex = i + COLUMN_DATA1; 25607e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana String key = DATA_KEYS[i]; 25617e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana if (c.isNull(columnIndex)) { 25627e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana // don't put anything 25637e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } else if (c.isLong(columnIndex)) { 25647e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana dataValues.put(key, c.getLong(columnIndex)); 25657e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } else if (c.isFloat(columnIndex)) { 25667e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana dataValues.put(key, c.getFloat(columnIndex)); 25677e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } else if (c.isString(columnIndex)) { 25687e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana dataValues.put(key, c.getString(columnIndex)); 25697e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } else if (c.isBlob(columnIndex)) { 25707e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana dataValues.put(key, c.getBlob(columnIndex)); 25717e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 25727e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 25737e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana contact.addSubValue(Data.CONTENT_URI, dataValues); 25747e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } while (mEntityCursor.moveToNext()); 25757e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 25767e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana return contact; 25777e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 25787e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 25797e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 2580226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana /** 2581226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana * An implementation of EntityIterator that joins the contacts and data tables 2582226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana * and consumes all the data rows for a contact in order to build the Entity for a contact. 2583226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana */ 2584226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private static class GroupsEntityIterator implements EntityIterator { 2585226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private final Cursor mEntityCursor; 2586226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private volatile boolean mIsClosed; 2587226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 2588226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private static final String[] PROJECTION = new String[]{ 2589226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana Groups._ID, 2590226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana Groups.ACCOUNT_NAME, 2591226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana Groups.ACCOUNT_TYPE, 2592226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana Groups.SOURCE_ID, 2593226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana Groups.DIRTY, 2594226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana Groups.VERSION, 2595226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana Groups.RES_PACKAGE, 2596226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana Groups.TITLE, 2597226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana Groups.TITLE_RES, 25987a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Groups.GROUP_VISIBLE, 25997a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Groups.SYNC1, 26007a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Groups.SYNC2, 26017a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Groups.SYNC3, 26027a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Groups.SYNC4, 26037a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Groups.SYSTEM_ID, 260494021b213e4db367f60b30fcbfe9019e28571784Fred Quintana Groups.NOTES, 260594021b213e4db367f60b30fcbfe9019e28571784Fred Quintana Groups.DELETED}; 2606226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 2607226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private static final int COLUMN_ID = 0; 2608226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private static final int COLUMN_ACCOUNT_NAME = 1; 2609226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private static final int COLUMN_ACCOUNT_TYPE = 2; 2610226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private static final int COLUMN_SOURCE_ID = 3; 2611226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private static final int COLUMN_DIRTY = 4; 2612226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private static final int COLUMN_VERSION = 5; 2613226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private static final int COLUMN_RES_PACKAGE = 6; 2614226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private static final int COLUMN_TITLE = 7; 2615226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private static final int COLUMN_TITLE_RES = 8; 2616226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana private static final int COLUMN_GROUP_VISIBLE = 9; 26177a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana private static final int COLUMN_SYNC1 = 10; 26187a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana private static final int COLUMN_SYNC2 = 11; 26197a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana private static final int COLUMN_SYNC3 = 12; 26207a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana private static final int COLUMN_SYNC4 = 13; 26217a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana private static final int COLUMN_SYSTEM_ID = 14; 26227a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana private static final int COLUMN_NOTES = 15; 262394021b213e4db367f60b30fcbfe9019e28571784Fred Quintana private static final int COLUMN_DELETED = 16; 2624226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 2625226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana public GroupsEntityIterator(ContactsProvider2 provider, String groupIdString, Uri uri, 2626226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana String selection, String[] selectionArgs, String sortOrder) { 2627226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana mIsClosed = false; 2628226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 2629226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana final String updatedSortOrder = (sortOrder == null) 2630226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana ? Groups._ID 2631226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana : (Groups._ID + "," + sortOrder); 2632226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 2633226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana final SQLiteDatabase db = provider.mOpenHelper.getReadableDatabase(); 2634226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana final SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); 2635226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana qb.setTables(Tables.GROUPS_JOIN_PACKAGES); 2636226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana qb.setProjectionMap(sGroupsProjectionMap); 2637226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana if (groupIdString != null) { 2638226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana qb.appendWhere(Groups._ID + "=" + groupIdString); 2639226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana } 2640226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana final String accountName = uri.getQueryParameter(Groups.ACCOUNT_NAME); 2641226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana final String accountType = uri.getQueryParameter(Groups.ACCOUNT_TYPE); 2642226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana if (!TextUtils.isEmpty(accountName)) { 2643226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana qb.appendWhere(Groups.ACCOUNT_NAME + "=" 2644226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana + DatabaseUtils.sqlEscapeString(accountName) + " AND " 2645226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana + Groups.ACCOUNT_TYPE + "=" 2646226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana + DatabaseUtils.sqlEscapeString(accountType)); 2647226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana } 2648226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana mEntityCursor = qb.query(db, PROJECTION, selection, selectionArgs, 2649226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana null, null, updatedSortOrder); 2650226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana mEntityCursor.moveToFirst(); 2651226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana } 2652226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 2653226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana public void close() { 2654226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana if (mIsClosed) { 2655226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana throw new IllegalStateException("closing when already closed"); 2656226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana } 2657226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana mIsClosed = true; 2658226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana mEntityCursor.close(); 2659226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana } 2660226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 2661226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana public boolean hasNext() throws RemoteException { 2662226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana if (mIsClosed) { 2663226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana throw new IllegalStateException("calling hasNext() when the iterator is closed"); 2664226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana } 2665226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 2666226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana return !mEntityCursor.isAfterLast(); 2667226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana } 2668226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 2669226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana public Entity next() throws RemoteException { 2670226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana if (mIsClosed) { 2671226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana throw new IllegalStateException("calling next() when the iterator is closed"); 2672226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana } 2673226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana if (!hasNext()) { 2674226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana throw new IllegalStateException("you may only call next() if hasNext() is true"); 2675226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana } 2676226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 2677226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana final SQLiteCursor c = (SQLiteCursor) mEntityCursor; 2678226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 2679226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana final long groupId = c.getLong(COLUMN_ID); 2680226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 2681226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana // we expect the cursor is already at the row we need to read from 2682226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana ContentValues groupValues = new ContentValues(); 2683226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana groupValues.put(Groups.ACCOUNT_NAME, c.getString(COLUMN_ACCOUNT_NAME)); 2684226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana groupValues.put(Groups.ACCOUNT_TYPE, c.getString(COLUMN_ACCOUNT_TYPE)); 2685226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana groupValues.put(Groups._ID, groupId); 2686226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana groupValues.put(Groups.DIRTY, c.getLong(COLUMN_DIRTY)); 2687226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana groupValues.put(Groups.VERSION, c.getLong(COLUMN_VERSION)); 2688226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana groupValues.put(Groups.SOURCE_ID, c.getString(COLUMN_SOURCE_ID)); 2689226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana groupValues.put(Groups.RES_PACKAGE, c.getString(COLUMN_RES_PACKAGE)); 2690226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana groupValues.put(Groups.TITLE, c.getString(COLUMN_TITLE)); 2691226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana groupValues.put(Groups.TITLE_RES, c.getString(COLUMN_TITLE_RES)); 2692226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana groupValues.put(Groups.GROUP_VISIBLE, c.getLong(COLUMN_GROUP_VISIBLE)); 26937a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana groupValues.put(Groups.SYNC1, c.getString(COLUMN_SYNC1)); 26947a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana groupValues.put(Groups.SYNC2, c.getString(COLUMN_SYNC2)); 26957a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana groupValues.put(Groups.SYNC3, c.getString(COLUMN_SYNC3)); 26967a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana groupValues.put(Groups.SYNC4, c.getString(COLUMN_SYNC4)); 26977a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana groupValues.put(Groups.SYSTEM_ID, c.getString(COLUMN_SYSTEM_ID)); 269894021b213e4db367f60b30fcbfe9019e28571784Fred Quintana groupValues.put(Groups.DELETED, c.getLong(COLUMN_DELETED)); 26997a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana groupValues.put(Groups.NOTES, c.getString(COLUMN_NOTES)); 2700226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana Entity group = new Entity(groupValues); 2701226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 2702226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana mEntityCursor.moveToNext(); 2703226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 2704226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana return group; 2705226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana } 2706226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana } 2707226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 2708a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov @Override 27097e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana public EntityIterator queryEntities(Uri uri, String selection, String[] selectionArgs, 27107e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana String sortOrder) { 27117e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana final int match = sUriMatcher.match(uri); 27127e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana switch (match) { 27135ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case RAW_CONTACTS: 27145ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case RAW_CONTACTS_ID: 27157e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana String contactsIdString = null; 27165ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov if (match == RAW_CONTACTS_ID) { 27177e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana contactsIdString = uri.getPathSegments().get(1); 27187e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 27197e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 27207e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana return new ContactsEntityIterator(this, contactsIdString, 27217e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana uri, selection, selectionArgs, sortOrder); 2722226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana case GROUPS: 2723226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana case GROUPS_ID: 2724226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana String idString = null; 2725226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana if (match == GROUPS_ID) { 2726226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana idString = uri.getPathSegments().get(1); 2727226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana } 2728226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 2729226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana return new GroupsEntityIterator(this, idString, 2730226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana uri, selection, selectionArgs, sortOrder); 27317e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana default: 27327e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana throw new UnsupportedOperationException("Unknown uri: " + uri); 27337e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 27347e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana } 27357e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 27364f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton @Override 27374f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton public String getType(Uri uri) { 2738a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton final int match = sUriMatcher.match(uri); 27394f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton switch (match) { 2740d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov case CONTACTS: return Contacts.CONTENT_TYPE; 2741d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov case CONTACTS_ID: return Contacts.CONTENT_ITEM_TYPE; 27425ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case RAW_CONTACTS: return RawContacts.CONTENT_TYPE; 27435ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov case RAW_CONTACTS_ID: return RawContacts.CONTENT_ITEM_TYPE; 2744508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey case DATA_ID: 27456bc8c0d15f4eacd2e92e9064c88cdf0659524a0eDmitri Plotnikov final SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 2746508f57ee336c20583400b48b614bd3d57ca849ecJeff Sharkey long dataId = ContentUris.parseId(uri); 2747b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return mOpenHelper.getDataMimeType(dataId); 274831b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov case AGGREGATION_EXCEPTIONS: return AggregationExceptions.CONTENT_TYPE; 274931b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov case AGGREGATION_EXCEPTION_ID: return AggregationExceptions.CONTENT_ITEM_TYPE; 2750d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov case AGGREGATION_SUGGESTIONS: return Contacts.CONTENT_TYPE; 2751c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov case SEARCH_SUGGESTIONS: 2752c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov return SearchManager.SUGGEST_MIME_TYPE; 2753c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov case SEARCH_SHORTCUT: 2754c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov return SearchManager.SHORTCUT_MIME_TYPE; 27554f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 2756a36c566037b4bb05f035d0c2cfd8b51386d7a8a6Jeff Hamilton throw new UnsupportedOperationException("Unknown uri: " + uri); 27574f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton } 27587e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 27595ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov private void setDisplayName(long rawContactId, String displayName) { 27603cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov if (displayName != null) { 27613cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov mContactDisplayNameUpdate.bindString(1, displayName); 27623cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } else { 27633cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov mContactDisplayNameUpdate.bindNull(1); 27643cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 27655ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov mContactDisplayNameUpdate.bindLong(2, rawContactId); 27663cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov mContactDisplayNameUpdate.execute(); 27673cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov } 27683cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov 276973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov /** 277073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov * Checks the {@link Data#MARK_AS_DIRTY} query parameter. 277173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov * 277273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov * Returns true if the parameter is missing or is either "true" or "1". 277373776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov */ 277473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov private boolean shouldMarkRawContactAsDirty(Uri uri) { 277573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov if (mImportMode) { 277673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov return false; 277773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov } 277873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov 277973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov String param = uri.getQueryParameter(Data.MARK_AS_DIRTY); 278073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov return param == null || (!param.equalsIgnoreCase("false") && !param.equals("0")); 278173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov } 278273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov 278373776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov /** 278473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov * Sets the {@link RawContacts#DIRTY} for the specified raw contact. 278573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov */ 278673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov private void setRawContactDirty(long rawContactId) { 278773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov mRawContactDirtyUpdate.bindLong(1, rawContactId); 278873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov mRawContactDirtyUpdate.execute(); 278973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov } 279073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov 279173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov /** 279273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov * Checks the {@link Groups#MARK_AS_DIRTY} query parameter. 279373776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov * 279473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov * Returns true if the parameter is missing or is either "true" or "1". 279573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov */ 279673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov private boolean shouldMarkGroupAsDirty(Uri uri) { 279773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov if (mImportMode) { 279873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov return false; 279973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov } 280073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov 280173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov String param = uri.getQueryParameter(Groups.MARK_AS_DIRTY); 280273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov return param == null || (!param.equalsIgnoreCase("false") && !param.equals("0")); 280373776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov } 280473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov 2805c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar /* 2806c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar * Sets the given dataId record in the "data" table to primary, and resets all data records of 2807c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar * the same mimetype and under the same contact to not be primary. 2808c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar * 2809c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar * @param dataId the id of the data record to be set to primary. 2810c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar */ 2811c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar private void setIsPrimary(long dataId) { 2812c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar mSetPrimaryStatement.bindLong(1, dataId); 2813c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar mSetPrimaryStatement.bindLong(2, dataId); 2814c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar mSetPrimaryStatement.bindLong(3, dataId); 2815c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar mSetPrimaryStatement.execute(); 2816c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar } 2817c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar 2818c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar /* 2819c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar * Sets the given dataId record in the "data" table to "super primary", and resets all data 2820c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar * records of the same mimetype and under the same aggregate to not be "super primary". 2821c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar * 2822c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar * @param dataId the id of the data record to be set to primary. 2823c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar */ 2824c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar private void setIsSuperPrimary(long dataId) { 2825c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar mSetSuperPrimaryStatement.bindLong(1, dataId); 2826c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar mSetSuperPrimaryStatement.bindLong(2, dataId); 2827c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar mSetSuperPrimaryStatement.bindLong(3, dataId); 2828c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar mSetSuperPrimaryStatement.execute(); 2829c0834a81ef469e6ee7e72ce34a8a02855a162858Evan Millar } 2830ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar 28315ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public String getRawContactsByFilterAsNestedQuery(String filterParam) { 2832c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov StringBuilder sb = new StringBuilder(); 2833c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov appendRawContactsByFilterAsNestedQuery(sb, filterParam, null); 2834c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov return sb.toString(); 2835c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov } 2836c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 2837a908fb5f39aa2021662a6cc317cc7e4db2d8bfb0Dmitri Plotnikov public void appendRawContactsByFilterAsNestedQuery(StringBuilder sb, String filterParam, 2838c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov String limit) { 2839c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov sb.append("(SELECT DISTINCT raw_contact_id FROM name_lookup WHERE normalized_name GLOB '"); 2840c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov sb.append(NameNormalizer.normalize(filterParam)); 2841c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov sb.append("*'"); 2842c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov if (limit != null) { 2843c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov sb.append(" LIMIT ").append(limit); 2844c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov } 2845c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov sb.append(")"); 2846ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar } 2847ea0ec7120315589eaafb45d88ff872abbde35e38Evan Millar 28484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov /** 28494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * Inserts an argument at the beginning of the selection arg list. 28504a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov */ 28514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov private String[] insertSelectionArg(String[] selectionArgs, String arg) { 2852b67163a1088f09c59f324350662eb18772fac6b6Evan Millar if (selectionArgs == null) { 2853b67163a1088f09c59f324350662eb18772fac6b6Evan Millar return new String[] {arg}; 2854b67163a1088f09c59f324350662eb18772fac6b6Evan Millar } else { 2855b67163a1088f09c59f324350662eb18772fac6b6Evan Millar int newLength = selectionArgs.length + 1; 2856b67163a1088f09c59f324350662eb18772fac6b6Evan Millar String[] newSelectionArgs = new String[newLength]; 28574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov newSelectionArgs[0] = arg; 28584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov System.arraycopy(selectionArgs, 0, newSelectionArgs, 1, selectionArgs.length); 2859b67163a1088f09c59f324350662eb18772fac6b6Evan Millar return newSelectionArgs; 2860b67163a1088f09c59f324350662eb18772fac6b6Evan Millar } 2861b67163a1088f09c59f324350662eb18772fac6b6Evan Millar } 2862caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov 2863caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov protected Account getDefaultAccount() { 2864caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov AccountManager accountManager = AccountManager.get(getContext()); 2865caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov try { 2866caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov Account[] accounts = accountManager.blockingGetAccountsWithTypeAndFeatures( 2867caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov DEFAULT_ACCOUNT_TYPE, new String[] {FEATURE_APPS_FOR_DOMAIN}); 2868caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov if (accounts != null && accounts.length > 0) { 2869caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov return accounts[0]; 2870caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov } 2871caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov } catch (Throwable e) { 2872caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov throw new RuntimeException("Cannot determine the default account " 2873caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov + "for contacts compatibility", e); 2874caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov } 2875caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov throw new RuntimeException("Cannot determine the default account " 2876caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov + "for contacts compatibility"); 2877caa1cf4ef062f163ac5e370cebc0e47b5ae7460eDmitri Plotnikov } 28784f864360c24bd26c111bf38a035e8e2d2609e84aJeff Hamilton} 2879